diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index 121cdcb8c7ec..df2a0f8141a1 100644 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -456,8 +456,8 @@ def get_employees_who_have_birthday_today(date_today=None): def send_employee_anniversary_notification(): - date_today = getdate() - + today = getdate() + employees = get_employees_who_have_anniversary_today(date_today) for name in employees: doc = frappe.get_doc("Employee", name) diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js index ab00ccd35169..62f9ecff8ee1 100644 --- a/erpnext/projects/doctype/project/project.js +++ b/erpnext/projects/doctype/project/project.js @@ -31,6 +31,7 @@ erpnext.projects.ProjectController = class ProjectController extends crm.QuickCo this.make_vehicle_checklist(); this.make_customer_request_checklist(); this.make_customer_vehicle_selector(); + this.make_document_checklist(); this.set_sales_data_html(); this.set_service_advisor_from_user(); this.setup_vehicle_panel_fields(); @@ -571,12 +572,31 @@ erpnext.projects.ProjectController = class ProjectController extends crm.QuickCo } } + make_document_checklist() { + if (this.frm.fields_dict.document_checklist_html) { + var is_read_only = cint(this.frm.doc.__onload && this.frm.doc.__onload.cant_change_fields && this.frm.doc.__onload.cant_change_fields.document_checklist); + + this.frm.document_checklist_editor = erpnext.vehicles.make_vehicle_checklist(this.frm, + 'document_checklist', + this.frm.fields_dict.document_checklist_html.wrapper, + this.frm.doc.__onload && this.frm.doc.__onload.default_document_checklist_items, + is_read_only, + __("Document Checklist")); + } + } + refresh_customer_request_checklist() { if (this.frm.customer_request_checklist_editor) { this.frm.customer_request_checklist_editor.refresh(); } } + render_document_checklist() { + if (this.frm.document_checklist_editor) { + this.frm.document_checklist_editor.render_checklist(); + } + } + make_customer_vehicle_selector() { if (this.frm.fields_dict.customer_vehicle_selector_html) { this.frm.customer_vehicle_selector = erpnext.vehicles.make_customer_vehicle_selector(this.frm, @@ -619,7 +639,10 @@ erpnext.projects.ProjectController = class ProjectController extends crm.QuickCo }, callback: function (r) { if (!r.exc) { - return me.frm.set_value(r.message); + return frappe.run_serially([ + () => me.frm.set_value(r.message), + () => me.render_document_checklist(), + ]); } } }); diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 65b81fee0595..08e307d4e132 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -15,7 +15,7 @@ from erpnext.controllers.status_updater import StatusUpdaterERP from erpnext.projects.doctype.project_status.project_status import get_auto_project_status, set_manual_project_status,\ get_valid_manual_project_status_names, is_manual_project_status, validate_project_status_for_transaction -from erpnext.projects.doctype.project_workshop.project_workshop import get_project_workshop_details +from erpnext.projects.doctype.project_workshop.project_workshop import get_project_workshop_details, get_project_workshop_document_checklist_items from erpnext.vehicles.vehicle_checklist import get_default_vehicle_checklist_items, set_missing_checklist from erpnext.vehicles.doctype.vehicle_log.vehicle_log import get_customer_vehicle_selector_data from frappe.model.meta import get_field_precision @@ -59,6 +59,7 @@ def onload(self): self.set_onload('activity_summary', self.get_activity_summary()) self.set_onload('default_vehicle_checklist_items', get_default_vehicle_checklist_items('vehicle_checklist')) self.set_onload('default_customer_request_checklist_items', get_default_vehicle_checklist_items('customer_request_checklist')) + self.set_onload('default_documents_checklist_items', get_project_workshop_document_checklist_items(self.project_workshop)) self.set_onload('cant_change_fields', self.get_cant_change_fields()) self.set_onload('valid_manual_project_status_names', get_valid_manual_project_status_names(self)) self.set_onload('is_manual_project_status', is_manual_project_status(self.project_status)) @@ -498,6 +499,15 @@ def validate_insurance_details(self): if not self.get('insurance_loss_no') and self.ready_to_close == 1: frappe.throw(_("Insurance Loss # is missing")) + def set_mandatory_items_check(self): + unchecked_items = [ + d.checklist_item for d in self.document_checklist + if d.is_mandatory and not d.checklist_item_checked + ] + + if unchecked_items and self.ready_to_close == 1: + frappe.throw(_("These mandatory items are not checked: {}").format(', '.join(unchecked_items))) + def reopen_status(self, update=True): self.ready_to_close = 0 self.ready_to_close_dt = None @@ -1604,6 +1614,7 @@ def set_project_ready_to_close(project): project.set_ready_to_close(update=True) project.validate_insurance_details() + project.set_mandatory_items_check() project.set_status(update=True) project.update_vehicle_booking_order_pdi_status() project.notify_update() diff --git a/erpnext/projects/doctype/project_workshop/project_workshop.json b/erpnext/projects/doctype/project_workshop/project_workshop.json index 44ef2b13c341..39a13930775a 100644 --- a/erpnext/projects/doctype/project_workshop/project_workshop.json +++ b/erpnext/projects/doctype/project_workshop/project_workshop.json @@ -10,7 +10,8 @@ "workshop_name", "service_manager", "section_break_3", - "default_cost_centers" + "default_cost_centers", + "document_checklist" ], "fields": [ { @@ -35,10 +36,16 @@ "fieldtype": "Table", "label": "Default Cost Centers", "options": "Default Cost Center" + }, + { + "fieldname": "document_checklist", + "fieldtype": "Table", + "label": "Document Checklist", + "options": "Vehicle Checklist Item" } ], "links": [], - "modified": "2023-10-31 15:28:52.930477", + "modified": "2024-09-04 13:05:45.869493", "modified_by": "Administrator", "module": "Projects", "name": "Project Workshop", diff --git a/erpnext/projects/doctype/project_workshop/project_workshop.py b/erpnext/projects/doctype/project_workshop/project_workshop.py index 39f788969947..8ba90ce8d69d 100644 --- a/erpnext/projects/doctype/project_workshop/project_workshop.py +++ b/erpnext/projects/doctype/project_workshop/project_workshop.py @@ -24,4 +24,19 @@ def get_project_workshop_details(project_workshop, company): out.service_manager = doc.service_manager out.cost_center = doc.get_default_cost_center(company) + out.document_checklist = [] + checklist = get_project_workshop_document_checklist_items(project_workshop) + for item in checklist: + out.document_checklist.append({'checklist_item': item.checklist_item, 'checklist_item_checked': 0, "is_mandatory": item.is_mandatory}) + return out + + +@frappe.whitelist() +def get_project_workshop_document_checklist_items(project_workshop): + if not project_workshop: + return [] + + workshop_doc = frappe.get_cached_doc("Project Workshop", project_workshop) + checklist_items = [d for d in workshop_doc.get('document_checklist')] + return checklist_items diff --git a/erpnext/vehicles/doctype/vehicle_checklist_item/vehicle_checklist_item.json b/erpnext/vehicles/doctype/vehicle_checklist_item/vehicle_checklist_item.json index 46c4efd22e82..161320a4e34a 100644 --- a/erpnext/vehicles/doctype/vehicle_checklist_item/vehicle_checklist_item.json +++ b/erpnext/vehicles/doctype/vehicle_checklist_item/vehicle_checklist_item.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2022-01-22 01:23:04.488781", "doctype": "DocType", "editable_grid": 1, @@ -6,7 +7,8 @@ "field_order": [ "checklist_item", "checklist_item_checked", - "is_custom_checklist_item" + "is_custom_checklist_item", + "is_mandatory" ], "fields": [ { @@ -27,10 +29,17 @@ "fieldname": "is_custom_checklist_item", "fieldtype": "Check", "label": "Is Custom Checklist Item" + }, + { + "default": "0", + "fieldname": "is_mandatory", + "fieldtype": "Check", + "label": "Is Mandatory" } ], "istable": 1, - "modified": "2022-01-22 14:06:57.660110", + "links": [], + "modified": "2024-09-16 16:23:35.850191", "modified_by": "Administrator", "module": "Vehicles", "name": "Vehicle Checklist Item", @@ -39,5 +48,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/vehicles/vehicle_checklist.js b/erpnext/vehicles/vehicle_checklist.js index 6d91f7db9702..34398509b489 100644 --- a/erpnext/vehicles/vehicle_checklist.js +++ b/erpnext/vehicles/vehicle_checklist.js @@ -17,7 +17,7 @@ erpnext.vehicles.VehicleChecklistEditor = Class.extend({ me.checklist_wrapper = $(`
`).appendTo(me.wrapper); me.left_container = $(`
`).appendTo(me.checklist_wrapper); me.right_container = $(`
`).appendTo(me.checklist_wrapper); - me.buttons_container = $(`
`).appendTo(me.wrapper); + me.buttons_container = $(`
`).appendTo(me.wrapper); me.empty_checklist_container = $(`
`).appendTo(me.wrapper); me.frm = frm; @@ -26,10 +26,10 @@ erpnext.vehicles.VehicleChecklistEditor = Class.extend({ me.default_checklist_items = default_items || []; var checklist_items = me.get_checklist_items(); - if (checklist_items && checklist_items.length) { - me.render_checklist(); - } else { + if (!checklist_items?.length && ['vehicle_checklist', 'customer_request_checklist'].includes(parentfield)) { me.load_items_and_render(); + } else { + me.render_checklist(); } me.bind(); @@ -59,6 +59,27 @@ erpnext.vehicles.VehicleChecklistEditor = Class.extend({ }); }, + get_project_workshop_details() { + var me = this; + if (me.frm.doc.project_workshop) { + return frappe.call({ + method: "erpnext.projects.doctype.project_workshop.project_workshop.get_project_workshop_details", + args: { + project_workshop: me.frm.doc.project_workshop, + company: me.frm.doc.company, + }, + callback: function (r) { + if (!r.exc) { + return frappe.run_serially([ + () => me.frm.set_value(r.message), + () => me.render_checklist(), + ]); + } + } + }); + } + }, + set_from_default_checklist_items: function () { var me = this; if (me.can_write()) { @@ -257,7 +278,14 @@ erpnext.vehicles.VehicleChecklistEditor = Class.extend({ }, on_reset_checklist: function () { - frappe.confirm(__("Are you sure you want to reset the vehicle checklist?"), () => this.load_items_and_render()); + var parentfield = this.parentfield; + frappe.confirm(__("Are you sure you want to reset the vehicle checklist?"), () => { + if (['vehicle_checklist', 'customer_request_checklist'].includes(parentfield)){ + this.load_items_and_render(); + } else { + this.get_project_workshop_details(); + } + }); }, get_checklist_items: function () {