diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 75eb02855c..2f7af7196d 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -389,5 +389,22 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } }); cur_frm.add_fetch('project_name', 'cost_center', 'cost_center'); -var tname = cur_frm.cscript.tname; -var fname = cur_frm.cscript.fname; + +erpnext.buying.get_default_bom = function(frm) { + $.each(frm.doc[frm.cscript.fname] || [], function(i, d) { + if (d.item_code && d.bom === "") { + return frappe.call({ + type: "GET", + method: "erpnext.stock.get_item_details.get_default_bom", + args: { + "item_code": d.item_code, + }, + callback: function(r) { + if(r) { + frappe.model.set_value(d.doctype, d.name, "bom", r.message); + } + } + }) + } + }); +} diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index aab48a2239..e712995c55 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -109,7 +109,6 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( var row = frappe.get_doc(cdt, cdn); this.frm.script_manager.copy_from_first_row("po_details", row, ["schedule_date"]); } - }); // for backward compatibility: combine new and previous states @@ -135,6 +134,17 @@ cur_frm.fields_dict['po_details'].grid.get_field('project_name').get_query = fun } } +cur_frm.fields_dict['po_details'].grid.get_field('bom').get_query = function(doc, cdt, cdn) { + var d = locals[cdt][cdn] + return { + filters: [ + ['BOM', 'item', '=', d.item_code], + ['BOM', 'is_active', '=', '1'], + ['BOM', 'docstatus', '=', '1'] + ] + } +} + cur_frm.cscript.get_last_purchase_rate = function(doc, cdt, cdn){ return $c_obj(doc, 'get_last_purchase_rate', '', function(r, rt) { refresh_field(cur_frm.cscript.fname); @@ -219,3 +229,11 @@ cur_frm.cscript.send_sms = function() { cur_frm.cscript.schedule_date = function(doc, cdt, cdn) { cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "schedule_date"); } + +frappe.provide("erpnext.buying"); + +frappe.ui.form.on("Purchase Order", "is_subcontracted", function(frm) { + if (frm.doc.is_subcontracted === "Yes") { + erpnext.buying.get_default_bom(frm); + } +}); diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 0adc981f86..23fd162d9f 100755 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -380,6 +380,16 @@ "print_hide": 1, "read_only": 1 }, + { + "fieldname": "bom", + "fieldtype": "Link", + "label": "BOM", + "no_copy": 1, + "options": "BOM", + "permlevel": 0, + "precision": "", + "print_hide": 1 + }, { "fieldname": "stock_qty", "fieldtype": "Float", @@ -445,7 +455,7 @@ ], "idx": 1, "istable": 1, - "modified": "2014-09-09 05:35:36.346557", + "modified": "2014-11-07 15:09:45.530230", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 09a9c3e9fa..0f7e2ba7b1 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -212,10 +212,19 @@ class BuyingController(StockController): if not self.is_subcontracted and self.sub_contracted_items: frappe.throw(_("Please enter 'Is Subcontracted' as Yes or No")) - if self.doctype == "Purchase Receipt" and self.is_subcontracted=="Yes" \ - and not self.supplier_warehouse: + if self.is_subcontracted == "Yes": + if self.doctype == "Purchase Receipt" and not self.supplier_warehouse: frappe.throw(_("Supplier Warehouse mandatory for sub-contracted Purchase Receipt")) + for item in self.get(self.fname): + if item in self.sub_contracted_items and not item.bom: + frappe.throw(_("Please select BOM in BOM field for Item {0}").format(item.item_code)) + + else: + for item in self.get(self.fname): + if item.bom: + item.bom = None + def create_raw_materials_supplied(self, raw_material_table): if self.is_subcontracted=="Yes": parent_items = [] @@ -236,7 +245,7 @@ class BuyingController(StockController): item.rm_supp_cost = 0.0 def update_raw_materials_supplied(self, item, raw_material_table, rm_supplied_idx): - bom_items = self.get_items_from_default_bom(item.item_code) + bom_items = self.get_items_from_bom(item.item_code, item.bom) raw_materials_cost = 0 for bom_item in bom_items: @@ -309,15 +318,16 @@ class BuyingController(StockController): if d not in delete_list: self.append(raw_material_table, d) - def get_items_from_default_bom(self, item_code): + def get_items_from_bom(self, item_code, bom): bom_items = frappe.db.sql("""select t2.item_code, ifnull(t2.qty, 0) / ifnull(t1.quantity, 1) as qty_consumed_per_unit, t2.rate, t2.stock_uom, t2.name, t2.description from `tabBOM` t1, `tabBOM Item` t2 - where t2.parent = t1.name and t1.item = %s and t1.is_default = 1 - and t1.docstatus = 1 and t1.is_active = 1""", item_code, as_dict=1) + where t2.parent = t1.name and t1.item = %s + and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s""", (item_code, bom), as_dict=1) + if not bom_items: - msgprint(_("No default BOM exists for Item {0}").format(item_code), raise_exception=1) + msgprint(_("Specified BOM {0} does not exist for Item {1}").format(bom, item_code), raise_exception=1) return bom_items @@ -358,3 +368,4 @@ class BuyingController(StockController): if not d.conversion_factor: frappe.throw(_("Row {0}: Conversion Factor is mandatory")) d.stock_qty = flt(d.qty) * flt(d.conversion_factor) + diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 632d42c26e..fc2d1b30f3 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -161,6 +161,17 @@ cur_frm.fields_dict.purchase_receipt_details.grid.get_field("qa_no").get_query = } } +cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('bom').get_query = function(doc, cdt, cdn) { + var d = locals[cdt][cdn] + return { + filters: [ + ['BOM', 'item', '=', d.item_code], + ['BOM', 'is_active', '=', '1'], + ['BOM', 'docstatus', '=', '1'] + ] + } +} + cur_frm.cscript.on_submit = function(doc, cdt, cdn) { if(cint(frappe.boot.notification_settings.purchase_receipt)) cur_frm.email_doc(frappe.boot.notification_settings.purchase_receipt_message); @@ -171,3 +182,10 @@ cur_frm.cscript.send_sms = function() { var sms_man = new SMSManager(cur_frm.doc); } +frappe.provide("erpnext.buying"); + +frappe.ui.form.on("Purchase Receipt", "is_subcontracted", function(frm) { + if (frm.doc.is_subcontracted === "Yes") { + erpnext.buying.get_default_bom(frm); + } +}); diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json index da237ad3e7..c13f34cb6a 100755 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -399,6 +399,16 @@ "fieldtype": "Column Break", "permlevel": 0 }, + { + "fieldname": "bom", + "fieldtype": "Link", + "label": "BOM", + "no_copy": 1, + "options": "BOM", + "permlevel": 0, + "precision": "", + "print_hide": 1 + }, { "fieldname": "serial_no", "fieldtype": "Text", @@ -549,7 +559,7 @@ ], "idx": 1, "istable": 1, - "modified": "2014-09-09 05:35:38.908372", + "modified": "2014-11-07 15:54:08.266918", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 0789a332c3..5fe8b14b9c 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -68,6 +68,9 @@ def get_item_details(args): out.schedule_date = out.lead_time_date = add_days(args.transaction_date, item.lead_time_days) + if args.get("is_subcontracted") == "Yes": + out.bom = get_default_bom(args.item_code) + return out def process_args(args): @@ -381,3 +384,12 @@ def get_price_list_currency_and_exchange_rate(args): "price_list_currency": price_list_currency, "plc_conversion_rate": plc_conversion_rate } + +@frappe.whitelist() +def get_default_bom(item_code=None): + if item_code: + bom = frappe.db.get_value("BOM", {"docstatus": 1, "is_default": 1, "is_active": 1, "item": item_code}) + if bom: + return bom + else: + frappe.throw(_("No default BOM exists for Item {0}").format(item_code))