From 5503b6cff56d876b4a88046cb7810cf83155dea1 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Thu, 14 Nov 2019 10:11:25 +0530 Subject: [PATCH] fix(Task): Do not create/schedule task after project end (#19184) * fix: do not create/schedule task after project end * fix: check difference between dates * fix: check project date * fix: task creation * fix: tests --- .../doctype/crop_cycle/crop_cycle.py | 14 +++++------ erpnext/projects/doctype/task/task.py | 25 +++++++++++++++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py index bb9045ca81..3e51933df7 100644 --- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py +++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py @@ -51,27 +51,25 @@ class CropCycle(Document): self.create_task(disease_doc.treatment_task, self.name, start_date) def create_project(self, period, crop_tasks): - project = frappe.new_doc("Project") - project.update({ + project = frappe.get_doc({ + "doctype": "Project", "project_name": self.title, "expected_start_date": self.start_date, "expected_end_date": add_days(self.start_date, period - 1) - }) - project.insert() + }).insert() return project.name def create_task(self, crop_tasks, project_name, start_date): for crop_task in crop_tasks: - task = frappe.new_doc("Task") - task.update({ + frappe.get_doc({ + "doctype": "Task", "subject": crop_task.get("task_name"), "priority": crop_task.get("priority"), "project": project_name, "exp_start_date": add_days(start_date, crop_task.get("start_day") - 1), "exp_end_date": add_days(start_date, crop_task.get("end_day") - 1) - }) - task.insert() + }).insert() def reload_linked_analysis(self): linked_doctypes = ['Soil Texture', 'Soil Analysis', 'Plant Analysis'] diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index 90e9f05f22..54fce8d6db 100755 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -10,6 +10,7 @@ from frappe import _, throw from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate from frappe.utils.nestedset import NestedSet from frappe.desk.form.assign_to import close_all_assignments, clear +from frappe.utils import date_diff class CircularReferenceError(frappe.ValidationError): pass class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass @@ -28,16 +29,29 @@ class Task(NestedSet): def validate(self): self.validate_dates() + self.validate_parent_project_dates() self.validate_progress() self.validate_status() self.update_depends_on() def validate_dates(self): if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date): - frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'")) + frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \ + frappe.bold("Expected End Date"))) if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): - frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'")) + frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \ + frappe.bold("Actual End Date"))) + + def validate_parent_project_dates(self): + if not self.project or frappe.flags.in_test: + return + + expected_end_date = getdate(frappe.db.get_value("Project", self.project, "expected_end_date")) + + if expected_end_date: + validate_project_dates(expected_end_date, self, "exp_start_date", "exp_end_date", "Expected") + validate_project_dates(expected_end_date, self, "act_start_date", "act_end_date", "Actual") def validate_status(self): if self.status!=self.get_db_value("status") and self.status == "Completed": @@ -255,3 +269,10 @@ def add_multiple_tasks(data, parent): def on_doctype_update(): frappe.db.add_index("Task", ["lft", "rgt"]) + +def validate_project_dates(project_end_date, task, task_start, task_end, actual_or_expected_date): + if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0: + frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date)) + + if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0: + frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date)) \ No newline at end of file