From 075f6ea0d56fe6a41fb5c5e50679390994796903 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 4 Nov 2019 19:41:04 +0530 Subject: [PATCH 1/5] feat: Provision to fetch items from BOM in Stock Entry Items are populated in child table and amounts are calculated Warehouse Fields in popup toggle based on Stock Entry Type --- erpnext/manufacturing/doctype/bom/bom.py | 1 + .../stock/doctype/stock_entry/stock_entry.js | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 225ae29429..d02dd59d13 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -599,6 +599,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite item.image, bom.project, item.stock_uom, + item.item_group, item.allow_alternative_item, item_default.default_warehouse, item_default.expense_account as expense_account, diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 0b023024f9..cee09e78c6 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -181,6 +181,12 @@ frappe.ui.form.on('Stock Entry', { } } + if (frm.doc.docstatus === 0) { + frm.add_custom_button(__('Bill of Materials'), function(){ + frm.events.get_items_from_bom(frm); + }, __("Get items from")); + } + if (frm.doc.docstatus===0) { frm.add_custom_button(__('Purchase Invoice'), function() { erpnext.utils.map_current_doc({ @@ -387,6 +393,73 @@ frappe.ui.form.on('Stock Entry', { } }, + get_items_from_bom: function(frm) { + let filters = function(){ + return {filters: { docstatus:1 }}; + } + + let fields = [ + {"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"), + options:"BOM", reqd: 1, get_query: filters()}, + {"fieldname":"source_warehouse", "fieldtype":"Link", "label":__("Source Warehouse"), + options:"Warehouse"}, + {"fieldname":"target_warehouse", "fieldtype":"Link", "label":__("Target Warehouse"), + options:"Warehouse"}, + {"fieldname":"qty", "fieldtype":"Float", "label":__("Quantity"), + reqd: 1, "default": 1}, + {"fieldname":"fetch_exploded", "fieldtype":"Check", + "label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1}, + {"fieldname":"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"} + ] + if (frm.doc.stock_entry_type == 'Material Issue'){ + fields.splice(2,1); + } + else if(frm.doc.stock_entry_type == 'Material Receipt'){ + fields.splice(1,1); + } + + let d = new frappe.ui.Dialog({ + title: __("Get Items from BOM"), + fields: fields + }); + d.get_input("fetch").on("click", function() { + let values = d.get_values(); + if(!values) return; + values["company"] = frm.doc.company; + if(!frm.doc.company) frappe.throw(__("Company field is required")); + frappe.call({ + method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items", + args: values, + callback: function(r) { + if (!r.message) { + frappe.throw(__("BOM does not contain any stock item")); + } else { + erpnext.utils.remove_empty_first_row(frm, "items"); + $.each(r.message, function(i, item) { + let d = frappe.model.add_child(cur_frm.doc, "Stock Entry Detail", "items"); + d.item_code = item.item_code; + d.item_name = item.item_name; + d.item_group = item.item_group; + d.s_warehouse = values.source_warehouse; + d.t_warehouse = values.target_warehouse; + d.uom = item.stock_uom; + d.stock_uom = item.stock_uom; + d.conversion_factor = 1; + d.qty = item.qty; + d.expense_account = item.expense_account; + d.project = item.project; + frm.events.set_basic_rate(frm, d.doctype, d.name); + }); + } + d.hide(); + refresh_field("items"); + } + }); + + }); + d.show(); + }, + calculate_basic_amount: function(frm, item) { item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate), precision("basic_amount", item)); From a076bddd833e6ec82fbfdf87cbbe0bbee3147368 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 15 Nov 2019 12:03:06 +0530 Subject: [PATCH 2/5] fix: Show 'Bill of Materials' custom button conditionally --- .../stock/doctype/stock_entry/stock_entry.js | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index cee09e78c6..bb85ef0c48 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -181,12 +181,6 @@ frappe.ui.form.on('Stock Entry', { } } - if (frm.doc.docstatus === 0) { - frm.add_custom_button(__('Bill of Materials'), function(){ - frm.events.get_items_from_bom(frm); - }, __("Get items from")); - } - if (frm.doc.docstatus===0) { frm.add_custom_button(__('Purchase Invoice'), function() { erpnext.utils.map_current_doc({ @@ -257,6 +251,17 @@ frappe.ui.form.on('Stock Entry', { frm.trigger("setup_quality_inspection"); }, + stock_entry_type: function(frm){ + frm.remove_custom_button('Bill of Materials', "Get items from"); + + if (frm.doc.docstatus === 0 && ['Material Issue','Material Receipt', + 'Material Transfer','Send to Subcontractor'].includes(frm.doc.purpose)) { + frm.add_custom_button(__('Bill of Materials'), function(){ + frm.events.get_items_from_bom(frm); + }, __("Get items from")); + } + }, + purpose: function(frm) { frm.trigger('validate_purpose_consumption'); frm.fields_dict.items.grid.refresh(); @@ -411,10 +416,10 @@ frappe.ui.form.on('Stock Entry', { "label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1}, {"fieldname":"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"} ] - if (frm.doc.stock_entry_type == 'Material Issue'){ + if (frm.doc.purpose == 'Material Issue'){ fields.splice(2,1); } - else if(frm.doc.stock_entry_type == 'Material Receipt'){ + else if(frm.doc.purpose == 'Material Receipt'){ fields.splice(1,1); } From e537cda0620f1be820afc9328857160693332d1a Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 20 Nov 2019 12:38:58 +0530 Subject: [PATCH 3/5] fix: Added conditional check for conversion factor --- erpnext/stock/doctype/stock_entry/stock_entry.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index bb85ef0c48..6c82c8b6b2 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -254,11 +254,11 @@ frappe.ui.form.on('Stock Entry', { stock_entry_type: function(frm){ frm.remove_custom_button('Bill of Materials', "Get items from"); - if (frm.doc.docstatus === 0 && ['Material Issue','Material Receipt', - 'Material Transfer','Send to Subcontractor'].includes(frm.doc.purpose)) { - frm.add_custom_button(__('Bill of Materials'), function(){ - frm.events.get_items_from_bom(frm); - }, __("Get items from")); + if (frm.doc.docstatus === 0 && + ['Material Issue', 'Material Receipt', 'Material Transfer', 'Send to Subcontractor'].includes(frm.doc.purpose)) { + frm.add_custom_button(__('Bill of Materials'), function() { + frm.events.get_items_from_bom(frm); + }, __("Get items from")); } }, @@ -449,7 +449,7 @@ frappe.ui.form.on('Stock Entry', { d.t_warehouse = values.target_warehouse; d.uom = item.stock_uom; d.stock_uom = item.stock_uom; - d.conversion_factor = 1; + d.conversion_factor = item.conversion_factor ? item.conversion_factor : 1; d.qty = item.qty; d.expense_account = item.expense_account; d.project = item.project; From 737d8a1e260027a16cc1e6bb5d42717372dbec1d Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 25 Nov 2019 09:42:08 +0530 Subject: [PATCH 4/5] fix: Added comments --- erpnext/stock/doctype/stock_entry/stock_entry.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 6c82c8b6b2..96e74ccca1 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -416,9 +416,12 @@ frappe.ui.form.on('Stock Entry', { "label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1}, {"fieldname":"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"} ] + + //Exclude field 'Target Warehouse' in case of Material Issue if (frm.doc.purpose == 'Material Issue'){ fields.splice(2,1); } + //Exclude field 'Source Warehouse' in case of Material Receipt else if(frm.doc.purpose == 'Material Receipt'){ fields.splice(1,1); } From be88d0f8a359c7e2ff8b40e5a3eb34014ff497dd Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 3 Dec 2019 18:13:39 +0530 Subject: [PATCH 5/5] fix: Custom button conditionally visible in draft condition as well --- .../stock/doctype/stock_entry/stock_entry.js | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 96e74ccca1..5c8efcbc01 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -238,6 +238,8 @@ frappe.ui.form.on('Stock Entry', { }, __("Get items from")); } + frm.events.show_bom_custom_button(frm); + if (frm.doc.company) { frm.trigger("toggle_display_account_head"); } @@ -253,13 +255,7 @@ frappe.ui.form.on('Stock Entry', { stock_entry_type: function(frm){ frm.remove_custom_button('Bill of Materials', "Get items from"); - - if (frm.doc.docstatus === 0 && - ['Material Issue', 'Material Receipt', 'Material Transfer', 'Send to Subcontractor'].includes(frm.doc.purpose)) { - frm.add_custom_button(__('Bill of Materials'), function() { - frm.events.get_items_from_bom(frm); - }, __("Get items from")); - } + frm.events.show_bom_custom_button(frm); }, purpose: function(frm) { @@ -398,6 +394,15 @@ frappe.ui.form.on('Stock Entry', { } }, + show_bom_custom_button: function(frm){ + if (frm.doc.docstatus === 0 && + ['Material Issue', 'Material Receipt', 'Material Transfer', 'Send to Subcontractor'].includes(frm.doc.purpose)) { + frm.add_custom_button(__('Bill of Materials'), function() { + frm.events.get_items_from_bom(frm); + }, __("Get items from")); + } + }, + get_items_from_bom: function(frm) { let filters = function(){ return {filters: { docstatus:1 }}; @@ -417,11 +422,11 @@ frappe.ui.form.on('Stock Entry', { {"fieldname":"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"} ] - //Exclude field 'Target Warehouse' in case of Material Issue + // Exclude field 'Target Warehouse' in case of Material Issue if (frm.doc.purpose == 'Material Issue'){ fields.splice(2,1); } - //Exclude field 'Source Warehouse' in case of Material Receipt + // Exclude field 'Source Warehouse' in case of Material Receipt else if(frm.doc.purpose == 'Material Receipt'){ fields.splice(1,1); }