diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 250f7c70c7a..99b7b3337be 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -2343,6 +2343,12 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe fieldname: "batch_no", label: __("Batch No"), hidden: true + }, + { + fieldtype: "Data", + fieldname: "child_row_reference", + label: __("Child Row Reference"), + hidden: true } ] } @@ -2389,14 +2395,14 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe if (this.has_inspection_required(item)) { let dialog_items = dialog.fields_dict.items; dialog_items.df.data.push({ - "docname": item.name, "item_code": item.item_code, "item_name": item.item_name, "qty": item.qty, "description": item.description, "serial_no": item.serial_no, "batch_no": item.batch_no, - "sample_size": item.sample_quantity + "sample_size": item.sample_quantity, + "child_row_reference": item.name, }); dialog_items.grid.refresh(); } diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.json b/erpnext/stock/doctype/quality_inspection/quality_inspection.json index 103207f6762..cc9aae927c9 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.json +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.json @@ -15,6 +15,7 @@ "inspection_type", "reference_type", "reference_name", + "child_row_reference", "section_break_7", "item_code", "item_serial_no", @@ -238,6 +239,15 @@ "fieldname": "manual_inspection", "fieldtype": "Check", "label": "Manual Inspection" + }, + { + "fieldname": "child_row_reference", + "fieldtype": "Data", + "hidden": 1, + "label": "Child Row Reference", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "icon": "fa fa-search", @@ -245,7 +255,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-03-27 13:10:28.680815", + "modified": "2024-12-30 19:08:16.611192", "modified_by": "Administrator", "module": "Stock", "name": "Quality Inspection", diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py index 6890256dc04..d3b5e65ea9f 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py @@ -29,6 +29,7 @@ class QualityInspection(Document): amended_from: DF.Link | None batch_no: DF.Link | None bom_no: DF.Link | None + child_row_reference: DF.Data | None description: DF.SmallText | None inspected_by: DF.Link inspection_type: DF.Literal["", "Incoming", "Outgoing", "In Process"] @@ -74,6 +75,64 @@ class QualityInspection(Document): self.inspect_and_set_status() self.validate_inspection_required() + self.set_child_row_reference() + + def set_child_row_reference(self): + if self.child_row_reference: + return + + if not (self.reference_type and self.reference_name): + return + + doctype = self.reference_type + " Item" + if self.reference_type == "Stock Entry": + doctype = "Stock Entry Detail" + + child_row_references = frappe.get_all( + doctype, + filters={"parent": self.reference_name, "item_code": self.item_code}, + pluck="name", + ) + + if not child_row_references: + return + + if len(child_row_references) == 1: + self.child_row_reference = child_row_references[0] + else: + self.distribute_child_row_reference(child_row_references) + + def distribute_child_row_reference(self, child_row_references): + quality_inspections = frappe.get_all( + "Quality Inspection", + filters={ + "reference_name": self.reference_name, + "item_code": self.item_code, + "docstatus": ("<", 2), + }, + fields=["name", "child_row_reference", "docstatus"], + order_by="child_row_reference desc", + ) + + for row in quality_inspections: + if not child_row_references: + break + + if row.child_row_reference and row.child_row_reference in child_row_references: + child_row_references.remove(row.child_row_reference) + continue + + if row.docstatus == 1: + continue + + if row.name == self.name: + self.child_row_reference = child_row_references[0] + else: + frappe.db.set_value( + "Quality Inspection", row.name, "child_row_reference", child_row_references[0] + ) + + child_row_references.remove(child_row_references[0]) def validate_inspection_required(self): if self.reference_type in ["Purchase Receipt", "Purchase Invoice"] and not frappe.get_cached_value( @@ -157,35 +216,38 @@ class QualityInspection(Document): ) else: - args = [quality_inspection, self.modified, self.reference_name, self.item_code] doctype = self.reference_type + " Item" if self.reference_type == "Stock Entry": doctype = "Stock Entry Detail" - if self.reference_type and self.reference_name: - conditions = "" + if doctype and self.reference_name: + child_doc = frappe.qb.DocType(doctype) + + query = ( + frappe.qb.update(child_doc) + .set(child_doc.quality_inspection, quality_inspection) + .where( + (child_doc.parent == self.reference_name) & (child_doc.item_code == self.item_code) + ) + ) + if self.batch_no and self.docstatus == 1: - conditions += " and t1.batch_no = %s" - args.append(self.batch_no) + query = query.where(child_doc.batch_no == self.batch_no) if self.docstatus == 2: # if cancel, then remove qi link wherever same name - conditions += " and t1.quality_inspection = %s" - args.append(self.name) + query = query.where(child_doc.quality_inspection == self.name) - frappe.db.sql( - f""" - UPDATE - `tab{doctype}` t1, `tab{self.reference_type}` t2 - SET - t1.quality_inspection = %s, t2.modified = %s - WHERE - t1.parent = %s - and t1.item_code = %s - and t1.parent = t2.name - {conditions} - """, - args, + if self.child_row_reference: + query = query.where(child_doc.name == self.child_row_reference) + + query.run() + + frappe.db.set_value( + self.reference_type, + self.reference_name, + "modified", + self.modified, ) def inspect_and_set_status(self):