From 2ea2146b343d13e4cc230e4d1ab8924f997e2b15 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:27:19 +0530 Subject: [PATCH] fix: update Maintenance Schedule status on Maintenance Visit submit (backport #39167) (#39185) * fix: make `Sales Person` non-mandatory (cherry picked from commit 4d56f725fe23495fa2392be01545c5d2fa8889b3) * fix: update Maintenance Schedule status on Maintenance Visit submit (cherry picked from commit cd293a5173aaec693afee23e9b874b1db649a267) # Conflicts: # erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py # erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.py * chore: `conflicts` --------- Co-authored-by: s-aga-r --- .../maintenance_schedule.py | 48 +++++++++------ .../maintenance_visit/maintenance_visit.py | 59 +++++++++++++++---- .../maintenance_visit_purpose.json | 15 ++++- 3 files changed, 89 insertions(+), 33 deletions(-) diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py index 95e2d694a58..8e4af3ac172 100644 --- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py @@ -80,7 +80,7 @@ class MaintenanceSchedule(TransactionBase): self.update_amc_date(serial_nos, d.end_date) no_email_sp = [] - if d.sales_person not in email_map: + if d.sales_person and d.sales_person not in email_map: sp = frappe.get_doc("Sales Person", d.sales_person) try: email_map[d.sales_person] = sp.get_email_id() @@ -94,12 +94,11 @@ class MaintenanceSchedule(TransactionBase): ).format(self.owner, "
" + "
".join(no_email_sp)) ) - scheduled_date = frappe.db.sql( - """select scheduled_date from - `tabMaintenance Schedule Detail` where sales_person=%s and item_code=%s and - parent=%s""", - (d.sales_person, d.item_code, self.name), - as_dict=1, + scheduled_date = frappe.db.get_all( + "Maintenance Schedule Detail", + {"parent": self.name, "item_code": d.item_code}, + ["scheduled_date"], + as_list=False, ) for key in scheduled_date: @@ -195,8 +194,6 @@ class MaintenanceSchedule(TransactionBase): throw(_("Please select Start Date and End Date for Item {0}").format(d.item_code)) elif not d.no_of_visits: throw(_("Please mention no of visits required")) - elif not d.sales_person: - throw(_("Please select a Sales Person for item: {0}").format(d.item_name)) if getdate(d.start_date) >= getdate(d.end_date): throw(_("Start date should be less than end date for Item {0}").format(d.item_code)) @@ -392,16 +389,28 @@ def get_serial_nos_from_schedule(item_code, schedule=None): def make_maintenance_visit(source_name, target_doc=None, item_name=None, s_id=None): from frappe.model.mapper import get_mapped_doc + def condition(doc): + if s_id: + return doc.name == s_id + elif item_name: + return doc.item_name == item_name + + return True + def update_status_and_detail(source, target, parent): target.maintenance_type = "Scheduled" - target.maintenance_schedule_detail = s_id def update_serial(source, target, parent): - serial_nos = get_serial_nos(target.serial_no) - if len(serial_nos) == 1: - target.serial_no = serial_nos[0] - else: - target.serial_no = "" + if source.item_reference: + if serial_nos := frappe.db.get_value( + "Maintenance Schedule Item", source.item_reference, "serial_no" + ): + serial_nos = serial_nos.split("\n") + + if len(serial_nos) == 1: + target.serial_no = serial_nos[0] + else: + target.serial_no = "" doclist = get_mapped_doc( "Maintenance Schedule", @@ -413,10 +422,13 @@ def make_maintenance_visit(source_name, target_doc=None, item_name=None, s_id=No "validation": {"docstatus": ["=", 1]}, "postprocess": update_status_and_detail, }, - "Maintenance Schedule Item": { + "Maintenance Schedule Detail": { "doctype": "Maintenance Visit Purpose", - "condition": lambda doc: doc.item_name == item_name if item_name else True, - "field_map": {"sales_person": "service_person"}, + "condition": condition, + "field_map": { + "sales_person": "service_person", + "name": "maintenance_schedule_detail", + }, "postprocess": update_serial, }, }, diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py index 0d319bf7424..a0974e99040 100644 --- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py +++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py @@ -23,20 +23,39 @@ class MaintenanceVisit(TransactionBase): frappe.throw(_("Add Items in the Purpose Table"), title=_("Purposes Required")) def validate_maintenance_date(self): - if self.maintenance_type == "Scheduled" and self.maintenance_schedule_detail: - item_ref = frappe.db.get_value( - "Maintenance Schedule Detail", self.maintenance_schedule_detail, "item_reference" - ) - if item_ref: - start_date, end_date = frappe.db.get_value( - "Maintenance Schedule Item", item_ref, ["start_date", "end_date"] + if self.maintenance_type == "Scheduled": + if self.maintenance_schedule_detail: + item_ref = frappe.db.get_value( + "Maintenance Schedule Detail", self.maintenance_schedule_detail, "item_reference" ) - if get_datetime(self.mntc_date) < get_datetime(start_date) or get_datetime( - self.mntc_date - ) > get_datetime(end_date): - frappe.throw( - _("Date must be between {0} and {1}").format(format_date(start_date), format_date(end_date)) + if item_ref: + start_date, end_date = frappe.db.get_value( + "Maintenance Schedule Item", item_ref, ["start_date", "end_date"] ) + if get_datetime(self.mntc_date) < get_datetime(start_date) or get_datetime( + self.mntc_date + ) > get_datetime(end_date): + frappe.throw( + _("Date must be between {0} and {1}").format(format_date(start_date), format_date(end_date)) + ) + else: + for purpose in self.purposes: + if purpose.maintenance_schedule_detail: + item_ref = frappe.db.get_value( + "Maintenance Schedule Detail", purpose.maintenance_schedule_detail, "item_reference" + ) + if item_ref: + start_date, end_date = frappe.db.get_value( + "Maintenance Schedule Item", item_ref, ["start_date", "end_date"] + ) + if get_datetime(self.mntc_date) < get_datetime(start_date) or get_datetime( + self.mntc_date + ) > get_datetime(end_date): + frappe.throw( + _("Date must be between {0} and {1}").format( + format_date(start_date), format_date(end_date) + ) + ) def validate(self): self.validate_serial_no() @@ -49,6 +68,7 @@ class MaintenanceVisit(TransactionBase): if not cancel: status = self.completion_status actual_date = self.mntc_date + if self.maintenance_schedule_detail: frappe.db.set_value( "Maintenance Schedule Detail", self.maintenance_schedule_detail, "completion_status", status @@ -56,6 +76,21 @@ class MaintenanceVisit(TransactionBase): frappe.db.set_value( "Maintenance Schedule Detail", self.maintenance_schedule_detail, "actual_date", actual_date ) + else: + for purpose in self.purposes: + if purpose.maintenance_schedule_detail: + frappe.db.set_value( + "Maintenance Schedule Detail", + purpose.maintenance_schedule_detail, + "completion_status", + status, + ) + frappe.db.set_value( + "Maintenance Schedule Detail", + purpose.maintenance_schedule_detail, + "actual_date", + actual_date, + ) def update_customer_issue(self, flag): if not self.maintenance_schedule: diff --git a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json index ba053555531..a5a63c4c4de 100644 --- a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json +++ b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json @@ -17,7 +17,8 @@ "work_details", "work_done", "prevdoc_doctype", - "prevdoc_docname" + "prevdoc_docname", + "maintenance_schedule_detail" ], "fields": [ { @@ -49,6 +50,8 @@ "options": "Serial No" }, { + "fetch_from": "item_code.description", + "fetch_if_empty": 1, "fieldname": "description", "fieldtype": "Text Editor", "in_list_view": 1, @@ -56,7 +59,6 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "print_width": "300px", - "reqd": 1, "width": "300px" }, { @@ -103,12 +105,19 @@ { "fieldname": "section_break_6", "fieldtype": "Section Break" + }, + { + "fieldname": "maintenance_schedule_detail", + "fieldtype": "Data", + "hidden": 1, + "label": "Maintenance Schedule Detail", + "options": "Maintenance Schedule Detail" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2023-02-27 11:09:33.114458", + "modified": "2024-01-05 21:46:53.239830", "modified_by": "Administrator", "module": "Maintenance", "name": "Maintenance Visit Purpose",