feat: Optionally allow rejected quality inspection on submission

This commit is contained in:
marination 2021-06-21 16:18:35 +05:30
parent 4b32ccb124
commit 49ec0e5ac3
3 changed files with 77 additions and 31 deletions

View File

@ -356,42 +356,68 @@ class StockController(AccountsController):
}, update_modified) }, update_modified)
def validate_inspection(self): def validate_inspection(self):
'''Checks if quality inspection is set for Items that require inspection. """Checks if quality inspection is set/ is valid for Items that require inspection."""
On submit, throw an exception''' inspection_fieldname_map = {
inspection_required_fieldname = None "Purchase Receipt": "inspection_required_before_purchase",
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]: "Purchase Invoice": "inspection_required_before_purchase",
inspection_required_fieldname = "inspection_required_before_purchase" "Sales Invoice": "inspection_required_before_delivery",
elif self.doctype in ["Delivery Note", "Sales Invoice"]: "Delivery Note": "inspection_required_before_delivery"
inspection_required_fieldname = "inspection_required_before_delivery" }
inspection_required_fieldname = inspection_fieldname_map.get(self.doctype)
# return if inspection is not required on document level
if ((not inspection_required_fieldname and self.doctype != "Stock Entry") or if ((not inspection_required_fieldname and self.doctype != "Stock Entry") or
(self.doctype == "Stock Entry" and not self.inspection_required) or (self.doctype == "Stock Entry" and not self.inspection_required) or
(self.doctype in ["Sales Invoice", "Purchase Invoice"] and not self.update_stock)): (self.doctype in ["Sales Invoice", "Purchase Invoice"] and not self.update_stock)):
return return
for d in self.get('items'): for row in self.get('items'):
qa_required = False qi_required = False
if (inspection_required_fieldname and not d.quality_inspection and if (inspection_required_fieldname and frappe.db.get_value("Item", row.item_code, inspection_required_fieldname)):
frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)): qi_required = True
qa_required = True elif self.doctype == "Stock Entry" and row.t_warehouse:
elif self.doctype == "Stock Entry" and not d.quality_inspection and d.t_warehouse: qi_required = True # inward stock needs inspection
qa_required = True
if self.docstatus == 1 and d.quality_inspection:
qa_doc = frappe.get_doc("Quality Inspection", d.quality_inspection)
if qa_doc.docstatus == 0:
link = frappe.utils.get_link_to_form('Quality Inspection', d.quality_inspection)
frappe.throw(_("Quality Inspection: {0} is not submitted for the item: {1} in row {2}").format(link, d.item_code, d.idx), QualityInspectionNotSubmittedError)
if qa_doc.status != 'Accepted': if qi_required: # validate row only if inspection is required on item level
frappe.throw(_("Row {0}: Quality Inspection rejected for item {1}") self.validate_qi_presence(row)
.format(d.idx, d.item_code), QualityInspectionRejectedError) if self.docstatus == 1:
elif qa_required : self.validate_qi_submission(row)
action = frappe.get_doc('Stock Settings').action_if_quality_inspection_is_not_submitted self.validate_qi_rejection(row)
if self.docstatus==1 and action == 'Stop':
frappe.throw(_("Quality Inspection required for Item {0} to submit").format(frappe.bold(d.item_code)), def validate_qi_presence(self, row):
exc=QualityInspectionRequiredError) """Check if QI is present on row level. Warn on save and stop on submit if missing."""
else: if not row.quality_inspection:
frappe.msgprint(_("Create Quality Inspection for Item {0}").format(frappe.bold(d.item_code))) msg = _(f"Row #{row.idx}: Quality Inspection is required for Item {frappe.bold(row.item_code)}")
if self.docstatus == 1:
frappe.throw(msg, title=_("Inspection Required"), exc=QualityInspectionRequiredError)
else:
frappe.msgprint(msg, title=_("Inspection Required"), indicator="blue")
def validate_qi_submission(self, row):
"""Check if QI is submitted on row level, during submission"""
action = frappe.get_doc('Stock Settings').action_if_quality_inspection_is_not_submitted or "Stop"
qa_docstatus = frappe.db.get_value("Quality Inspection", row.quality_inspection, "docstatus")
if not qa_docstatus == 1:
link = frappe.utils.get_link_to_form('Quality Inspection', row.quality_inspection)
msg = _(f"Row #{row.idx}: Quality Inspection {link} is not submitted for the item: {row.item_code}")
if action == "Stop":
frappe.throw(msg, title=_("Inspection Submission"), exc=QualityInspectionNotSubmittedError)
else:
frappe.msgprint(msg, alert=True)
def validate_qi_rejection(self, row):
"""Check if QI is rejected on row level, during submission"""
action = frappe.get_doc('Stock Settings').action_if_quality_inspection_is_rejected or "Stop"
qa_status = frappe.db.get_value("Quality Inspection", row.quality_inspection, "status")
if qa_status == "Rejected":
link = frappe.utils.get_link_to_form('Quality Inspection', row.quality_inspection)
msg = _(f"Row #{row.idx}: Quality Inspection was rejected for item {row.item_code}")
if action == "Stop":
frappe.throw(msg, title=_("Inspection Rejected"), exc=QualityInspectionRejectedError)
else:
frappe.msgprint(msg, alert=True, indicator="orange")
def update_blanket_order(self): def update_blanket_order(self):
blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order])) blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order]))

View File

@ -307,6 +307,7 @@
"fieldname": "quality_inspection", "fieldname": "quality_inspection",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Quality Inspection", "label": "Quality Inspection",
"no_copy": 1,
"options": "Quality Inspection" "options": "Quality Inspection"
}, },
{ {
@ -548,7 +549,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2021-02-11 13:47:50.158754", "modified": "2021-06-21 16:03:18.834880",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Entry Detail", "name": "Stock Entry Detail",

View File

@ -23,7 +23,10 @@
"allow_negative_stock", "allow_negative_stock",
"show_barcode_field", "show_barcode_field",
"clean_description_html", "clean_description_html",
"quality_inspection_settings_section",
"action_if_quality_inspection_is_not_submitted", "action_if_quality_inspection_is_not_submitted",
"column_break_21",
"action_if_quality_inspection_is_rejected",
"section_break_7", "section_break_7",
"automatically_set_serial_nos_based_on_fifo", "automatically_set_serial_nos_based_on_fifo",
"set_qty_in_transactions_based_on_serial_no_input", "set_qty_in_transactions_based_on_serial_no_input",
@ -264,6 +267,22 @@
{ {
"fieldname": "column_break_31", "fieldname": "column_break_31",
"fieldtype": "Column Break" "fieldtype": "Column Break"
},
{
"fieldname": "quality_inspection_settings_section",
"fieldtype": "Section Break",
"label": "Quality Inspection Settings"
},
{
"fieldname": "column_break_21",
"fieldtype": "Column Break"
},
{
"default": "Stop",
"fieldname": "action_if_quality_inspection_is_rejected",
"fieldtype": "Select",
"label": "Action If Quality Inspection Is Rejected",
"options": "Stop\nWarn"
} }
], ],
"icon": "icon-cog", "icon": "icon-cog",
@ -271,7 +290,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2021-04-30 17:27:42.709231", "modified": "2021-06-21 16:17:42.159829",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Settings", "name": "Stock Settings",