From 7433b971060a671971af0c23e64efd4dab951799 Mon Sep 17 00:00:00 2001 From: 18alantom <2.alan.tom@gmail.com> Date: Thu, 24 Jun 2021 15:05:52 +0530 Subject: [PATCH] refactor: shift auto entry of is process loss check, update validations --- erpnext/manufacturing/doctype/bom/bom.js | 45 ++++++++++++++++++------ erpnext/manufacturing/doctype/bom/bom.py | 22 +++++++++--- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index a5ce8c6195..dd437dd555 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -379,9 +379,6 @@ erpnext.bom.BomController = class BomController extends erpnext.TransactionContr child.bom_no = ''; } - if (scrap_items) { - set_is_process_loss(doc, cdt, cdn) - } get_bom_material_detail(doc, cdt, cdn, scrap_items); } @@ -450,9 +447,10 @@ var get_bom_material_detail = function(doc, cdt, cdn, scrap_items) { callback: function(r) { d = locals[cdt][cdn]; if (d.is_process_loss) { - r.message.rate = 0 - r.message.base_rate = 0 + r.message.rate = 0; + r.message.base_rate = 0; } + $.extend(d, r.message); refresh_field("items"); refresh_field("scrap_items"); @@ -661,12 +659,37 @@ frappe.ui.form.on("BOM", "with_operations", function(frm) { if(!cint(frm.doc.with_operations)) { frm.set_value("operations", []); } + toggle_operations(frm); }); -function set_is_process_loss(doc, cdt, cdn) { - const row = locals[cdt][cdn] - if (row.item_code === doc.item) { - row.is_process_loss = 1 - frappe.msgprint(__("Item:") + ` ${row.item_code} ` + __("set as process loss.")) - } +frappe.ui.form.on("BOM Scrap Item", { + item_code(frm, cdt, cdn) { + const { item_code } = locals[cdt][cdn]; + if (item_code === frm.doc.item) { + locals[cdt][cdn].is_process_loss = 1; + trigger_process_loss_qty_prompt(frm, cdt, cdn, item_code) + } + }, +}); + +function trigger_process_loss_qty_prompt(frm, cdt, cdn, item_code) { + frappe.prompt( + { + fieldname: "percent", + fieldtype: "Percent", + label: __("% Finished Item Quantity"), + description: + __("Set quantity of process loss item:") + + ` ${item_code} ` + + __("as a percentage of finished item quantity"), + }, + (data) => { + const row = locals[cdt][cdn]; + row.stock_qty = (frm.doc.quantity * data.percent) / 100; + row.qty = row.stock_qty / (row.conversion_factor ?? 1); + refresh_field("scrap_items"); + }, + __("Set Process Loss Item Quantity"), + __("Set Quantity") + ); } diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index de0c521cf5..b90d54dea5 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -695,11 +695,25 @@ class BOM(WebsiteGenerator): def validate_scrap_items(self): for item in self.scrap_items: if item.item_code == self.item and not item.is_process_loss: - frappe.throw(_('Item:') + f' {item.item_code} ' +\ - _('in Scrap/Loss Items table should have Is Process Loss checked.')) + frappe.throw(_('Scrap/Loss Item:') + f' {frappe.bold(item.item_code)} ' +\ + _('should have') + ' ' + frappe.bold(_('Is Process Loss')) + ' ' + ('checked.')) elif item.item_code != self.item and item.is_process_loss: - frappe.throw(_('Item:') + f' {item.item_code} ' +\ - _('in Scrap/Loss Items table should not have Is Process Loss checked.')) + frappe.throw(_('Scrap/Loss Item:') + f' {frappe.bold(item.item_code)} ' +\ + _('should not have') + ' ' + frappe.bold(_('Is Process Loss')) + ' ' + ('checked.')) + + stock_uom = item.stock_uom + must_be_whole_number = frappe.get_value("UOM", stock_uom, "must_be_whole_number") + if item.is_process_loss and must_be_whole_number: + frappe.throw(_('Item:') + f' {frappe.bold(item.item_code)} ' +\ + _('with Stock UOM:') + f' {frappe.bold(stock_uom)} '+\ + _('cannot be a Scrap/Loss Item.')) + + if item.is_process_loss and (item.stock_qty >= self.quantity): + frappe.throw(_('Scrap/Loss Item:') + f' {item.item_code} ' +\ + _('should have') +' '+frappe.bold(_('Qty')) +\ + ' ' + _('less than finished goods') + ' ' +\ + frappe.bold(_('Quantity.'))) + def get_bom_item_rate(args, bom_doc): if bom_doc.rm_cost_as_per == 'Valuation Rate':