Merge pull request #17215 from nabinhait/project-task-opt-tests
perf: Project task optimization
This commit is contained in:
@@ -522,8 +522,13 @@ frappe.ui.form.on("Purchase Invoice", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
if(frm.doc.__onload && !frm.doc.__onload.supplier_tds) {
|
if(frm.doc.__onload) {
|
||||||
me.frm.set_df_property("apply_tds", "read_only", 1);
|
if(frm.doc.supplier) {
|
||||||
|
frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0;
|
||||||
|
}
|
||||||
|
if(!frm.doc.__onload.supplier_tds) {
|
||||||
|
frm.set_df_property("apply_tds", "read_only", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||||
|
|||||||
@@ -789,9 +789,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
for d in self.items:
|
for d in self.items:
|
||||||
if d.project and d.project not in project_list:
|
if d.project and d.project not in project_list:
|
||||||
project = frappe.get_doc("Project", d.project)
|
project = frappe.get_doc("Project", d.project)
|
||||||
project.flags.dont_sync_tasks = True
|
|
||||||
project.update_purchase_costing()
|
project.update_purchase_costing()
|
||||||
project.save()
|
project.db_update()
|
||||||
project_list.append(d.project)
|
project_list.append(d.project)
|
||||||
|
|
||||||
def validate_supplier_invoice(self):
|
def validate_supplier_invoice(self):
|
||||||
|
|||||||
@@ -1022,9 +1022,8 @@ class SalesInvoice(SellingController):
|
|||||||
def update_project(self):
|
def update_project(self):
|
||||||
if self.project:
|
if self.project:
|
||||||
project = frappe.get_doc("Project", self.project)
|
project = frappe.get_doc("Project", self.project)
|
||||||
project.flags.dont_sync_tasks = True
|
|
||||||
project.update_billed_amount()
|
project.update_billed_amount()
|
||||||
project.save()
|
project.db_update()
|
||||||
|
|
||||||
|
|
||||||
def verify_payment_amount_is_positive(self):
|
def verify_payment_amount_is_positive(self):
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class AccountsController(TransactionBase):
|
|||||||
return self.__company_currency
|
return self.__company_currency
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
|
if self.get("__onload"):
|
||||||
self.get("__onload").make_payment_via_journal_entry \
|
self.get("__onload").make_payment_via_journal_entry \
|
||||||
= frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
|
= frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class TestEmployeeOnboarding(unittest.TestCase):
|
|||||||
|
|
||||||
# complete the task
|
# complete the task
|
||||||
project = frappe.get_doc('Project', onboarding.project)
|
project = frappe.get_doc('Project', onboarding.project)
|
||||||
|
project.load_tasks()
|
||||||
project.tasks[0].status = 'Closed'
|
project.tasks[0].status = 'Closed'
|
||||||
project.save()
|
project.save()
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ test_dependencies = ["Employee Onboarding"]
|
|||||||
|
|
||||||
class TestEmployeeSeparation(unittest.TestCase):
|
class TestEmployeeSeparation(unittest.TestCase):
|
||||||
def test_employee_separation(self):
|
def test_employee_separation(self):
|
||||||
employee = get_employee()
|
employee = frappe.db.get_value("Employee", {"status": "Active"})
|
||||||
separation = frappe.new_doc('Employee Separation')
|
separation = frappe.new_doc('Employee Separation')
|
||||||
separation.employee = employee.name
|
separation.employee = employee
|
||||||
separation.company = '_Test Company'
|
separation.company = '_Test Company'
|
||||||
separation.append('activities', {
|
separation.append('activities', {
|
||||||
'activity_name': 'Deactivate Employee',
|
'activity_name': 'Deactivate Employee',
|
||||||
@@ -24,6 +24,3 @@ class TestEmployeeSeparation(unittest.TestCase):
|
|||||||
self.assertEqual(separation.docstatus, 1)
|
self.assertEqual(separation.docstatus, 1)
|
||||||
separation.cancel()
|
separation.cancel()
|
||||||
self.assertEqual(separation.project, "")
|
self.assertEqual(separation.project, "")
|
||||||
|
|
||||||
def get_employee():
|
|
||||||
return frappe.get_doc('Employee', {'employee_name': 'Test Researcher'})
|
|
||||||
@@ -13,19 +13,23 @@ test_dependencies = ['Employee']
|
|||||||
class TestExpenseClaim(unittest.TestCase):
|
class TestExpenseClaim(unittest.TestCase):
|
||||||
def test_total_expense_claim_for_project(self):
|
def test_total_expense_claim_for_project(self):
|
||||||
frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
|
frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
|
||||||
|
frappe.db.sql("""delete from `tabProject Task` where parent = "_Test Project 1" """)
|
||||||
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
|
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
|
||||||
|
frappe.db.sql("delete from `tabExpense Claim` where project='_Test Project 1'")
|
||||||
|
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
"project_name": "_Test Project 1",
|
"project_name": "_Test Project 1",
|
||||||
"doctype": "Project",
|
"doctype": "Project",
|
||||||
"tasks" :
|
}).save()
|
||||||
[{ "title": "_Test Project Task 1", "status": "Open" }]
|
|
||||||
|
task = frappe.get_doc({
|
||||||
|
"doctype": "Task",
|
||||||
|
"subject": "_Test Project Task 1",
|
||||||
|
"project": "_Test Project 1"
|
||||||
}).save()
|
}).save()
|
||||||
|
|
||||||
task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
|
task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
|
||||||
payable_account = get_payable_account("Wind Power LLC")
|
payable_account = get_payable_account("Wind Power LLC")
|
||||||
|
|
||||||
make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name)
|
make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name)
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
|
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
|
||||||
@@ -103,9 +107,10 @@ def get_payable_account(company):
|
|||||||
return frappe.get_cached_value('Company', company, 'default_payable_account')
|
return frappe.get_cached_value('Company', company, 'default_payable_account')
|
||||||
|
|
||||||
def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None):
|
def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None):
|
||||||
|
employee = frappe.db.get_value("Employee", {"status": "Active"})
|
||||||
expense_claim = frappe.get_doc({
|
expense_claim = frappe.get_doc({
|
||||||
"doctype": "Expense Claim",
|
"doctype": "Expense Claim",
|
||||||
"employee": "_T-Employee-00001",
|
"employee": employee,
|
||||||
"payable_account": payable_account,
|
"payable_account": payable_account,
|
||||||
"approval_status": "Approved",
|
"approval_status": "Approved",
|
||||||
"company": company,
|
"company": company,
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ class Project(Document):
|
|||||||
|
|
||||||
self.update_costing()
|
self.update_costing()
|
||||||
|
|
||||||
def __setup__(self):
|
def before_print(self):
|
||||||
self.onload()
|
self.onload()
|
||||||
|
|
||||||
def load_tasks(self):
|
def load_tasks(self):
|
||||||
"""Load `tasks` from the database"""
|
"""Load `tasks` from the database"""
|
||||||
|
project_task_custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task"}, "fieldname")
|
||||||
|
|
||||||
self.tasks = []
|
self.tasks = []
|
||||||
for task in self.get_tasks():
|
for task in self.get_tasks():
|
||||||
task_map = {
|
task_map = {
|
||||||
@@ -47,7 +49,7 @@ class Project(Document):
|
|||||||
"task_weight": task.task_weight
|
"task_weight": task.task_weight
|
||||||
}
|
}
|
||||||
|
|
||||||
self.map_custom_fields(task, task_map)
|
self.map_custom_fields(task, task_map, project_task_custom_fields)
|
||||||
|
|
||||||
self.append("tasks", task_map)
|
self.append("tasks", task_map)
|
||||||
|
|
||||||
@@ -149,7 +151,7 @@ class Project(Document):
|
|||||||
"task_weight": t.task_weight
|
"task_weight": t.task_weight
|
||||||
})
|
})
|
||||||
|
|
||||||
self.map_custom_fields(t, task)
|
self.map_custom_fields(t, task, custom_fields)
|
||||||
|
|
||||||
task.flags.ignore_links = True
|
task.flags.ignore_links = True
|
||||||
task.flags.from_project = True
|
task.flags.from_project = True
|
||||||
@@ -173,10 +175,6 @@ class Project(Document):
|
|||||||
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
|
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
|
||||||
self.deleted_task_list.append(t.name)
|
self.deleted_task_list.append(t.name)
|
||||||
|
|
||||||
def update_costing_and_percentage_complete(self):
|
|
||||||
self.update_percent_complete()
|
|
||||||
self.update_costing()
|
|
||||||
|
|
||||||
def is_row_updated(self, row, existing_task_data, fields):
|
def is_row_updated(self, row, existing_task_data, fields):
|
||||||
if self.get("__islocal") or not existing_task_data: return True
|
if self.get("__islocal") or not existing_task_data: return True
|
||||||
|
|
||||||
@@ -186,10 +184,8 @@ class Project(Document):
|
|||||||
if row.get(field) != d.get(field):
|
if row.get(field) != d.get(field):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def map_custom_fields(self, source, target):
|
def map_custom_fields(self, source, target, custom_fields):
|
||||||
project_task_custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task"}, "fieldname")
|
for field in custom_fields:
|
||||||
|
|
||||||
for field in project_task_custom_fields:
|
|
||||||
target.update({
|
target.update({
|
||||||
field.fieldname: source.get(field.fieldname)
|
field.fieldname: source.get(field.fieldname)
|
||||||
})
|
})
|
||||||
@@ -197,8 +193,6 @@ class Project(Document):
|
|||||||
def update_project(self):
|
def update_project(self):
|
||||||
self.update_percent_complete()
|
self.update_percent_complete()
|
||||||
self.update_costing()
|
self.update_costing()
|
||||||
self.flags.dont_sync_tasks = True
|
|
||||||
self.save(ignore_permissions=True)
|
|
||||||
|
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
if self.sales_order:
|
if self.sales_order:
|
||||||
@@ -233,6 +227,7 @@ class Project(Document):
|
|||||||
self.status = "Completed"
|
self.status = "Completed"
|
||||||
elif not self.status == "Cancelled":
|
elif not self.status == "Cancelled":
|
||||||
self.status = "Open"
|
self.status = "Open"
|
||||||
|
self.db_update()
|
||||||
|
|
||||||
def update_costing(self):
|
def update_costing(self):
|
||||||
from_time_sheet = frappe.db.sql("""select
|
from_time_sheet = frappe.db.sql("""select
|
||||||
@@ -246,7 +241,7 @@ class Project(Document):
|
|||||||
from_expense_claim = frappe.db.sql("""select
|
from_expense_claim = frappe.db.sql("""select
|
||||||
sum(total_sanctioned_amount) as total_sanctioned_amount
|
sum(total_sanctioned_amount) as total_sanctioned_amount
|
||||||
from `tabExpense Claim` where project = %s
|
from `tabExpense Claim` where project = %s
|
||||||
and docstatus = 1""", self.name, as_dict=1)[0]
|
and docstatus = 1""", self.name, as_dict=1, debug=1)[0]
|
||||||
|
|
||||||
self.actual_start_date = from_time_sheet.start_date
|
self.actual_start_date = from_time_sheet.start_date
|
||||||
self.actual_end_date = from_time_sheet.end_date
|
self.actual_end_date = from_time_sheet.end_date
|
||||||
@@ -260,6 +255,7 @@ class Project(Document):
|
|||||||
self.update_sales_amount()
|
self.update_sales_amount()
|
||||||
self.update_billed_amount()
|
self.update_billed_amount()
|
||||||
self.calculate_gross_margin()
|
self.calculate_gross_margin()
|
||||||
|
self.db_update()
|
||||||
|
|
||||||
def calculate_gross_margin(self):
|
def calculate_gross_margin(self):
|
||||||
expense_amount = (flt(self.total_costing_amount) + flt(self.total_expense_claim)
|
expense_amount = (flt(self.total_costing_amount) + flt(self.total_expense_claim)
|
||||||
@@ -313,7 +309,7 @@ class Project(Document):
|
|||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.delete_task()
|
self.delete_task()
|
||||||
self.load_tasks()
|
self.load_tasks()
|
||||||
self.update_costing_and_percentage_complete()
|
self.update_project()
|
||||||
self.update_dependencies_on_duplicated_project()
|
self.update_dependencies_on_duplicated_project()
|
||||||
|
|
||||||
def delete_task(self):
|
def delete_task(self):
|
||||||
|
|||||||
@@ -202,9 +202,8 @@ class SalesOrder(SellingController):
|
|||||||
|
|
||||||
if self.project:
|
if self.project:
|
||||||
project = frappe.get_doc("Project", self.project)
|
project = frappe.get_doc("Project", self.project)
|
||||||
project.flags.dont_sync_tasks = True
|
|
||||||
project.update_sales_amount()
|
project.update_sales_amount()
|
||||||
project.save()
|
project.db_update()
|
||||||
|
|
||||||
def check_credit_limit(self):
|
def check_credit_limit(self):
|
||||||
# if bypass credit limit check is set to true (1) at sales order level,
|
# if bypass credit limit check is set to true (1) at sales order level,
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ def make_purchase_invoice(source_name, target_doc=None):
|
|||||||
|
|
||||||
doc = frappe.get_doc(target)
|
doc = frappe.get_doc(target)
|
||||||
doc.ignore_pricing_rule = 1
|
doc.ignore_pricing_rule = 1
|
||||||
|
doc.run_method("onload")
|
||||||
doc.run_method("set_missing_values")
|
doc.run_method("set_missing_values")
|
||||||
doc.run_method("calculate_taxes_and_totals")
|
doc.run_method("calculate_taxes_and_totals")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user