diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 2615b31782..7b5339b4f0 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -121,9 +121,11 @@ frappe.ui.form.on("BOM", { freeze: true, args: { update_parent: true, - from_child_bom:false + from_child_bom:false, + save: false }, callback: function(r) { + refresh_field("items"); if(!r.exc) frm.refresh_fields(); } }); diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 54ffa06912..57a1cc2593 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -8,6 +8,7 @@ from frappe import _ from erpnext.setup.utils import get_exchange_rate from frappe.website.website_generator import WebsiteGenerator from erpnext.stock.get_item_details import get_conversion_factor +from erpnext.stock.get_item_details import get_price_list_rate import functools @@ -109,7 +110,11 @@ class BOM(WebsiteGenerator): "item_name": item.item_name, "bom_no": item.bom_no, "stock_qty": item.stock_qty, - "include_item_in_manufacturing": item.include_item_in_manufacturing + "include_item_in_manufacturing": item.include_item_in_manufacturing, + "qty": item.qty, + "uom": item.uom, + "stock_uom": item.stock_uom, + "conversion_factor": item.conversion_factor }) for r in ret: if not item.get(r): @@ -141,7 +146,7 @@ class BOM(WebsiteGenerator): 'uom' : item and args['stock_uom'] or '', 'conversion_factor': 1, 'bom_no' : args['bom_no'], - 'rate' : rate / self.conversion_rate if self.conversion_rate else rate, + 'rate' : rate, 'qty' : args.get("qty") or args.get("stock_qty") or 1, 'stock_qty' : args.get("qty") or args.get("stock_qty") or 1, 'base_rate' : rate, @@ -173,35 +178,56 @@ class BOM(WebsiteGenerator): elif self.rm_cost_as_per == "Price List": if not self.buying_price_list: frappe.throw(_("Please select Price List")) - rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list, - "item_code": arg["item_code"]}, "price_list_rate") or 0.0 - - price_list_currency = frappe.db.get_value("Price List", - self.buying_price_list, "currency") - if price_list_currency != self.company_currency(): - rate = flt(rate * self.conversion_rate) + args = frappe._dict({ + "doctype": "BOM", + "price_list": self.buying_price_list, + "qty": arg.get("qty"), + "uom": arg.get("uom") or arg.get("stock_uom"), + "stock_uom": arg.get("stock_uom"), + "transaction_type": "buying", + "company": self.company, + "currency": self.currency, + "conversion_rate": self.conversion_rate or 1, + "conversion_factor": arg.get("conversion_factor") or 1, + "plc_conversion_rate": 1 + }) + item_doc = frappe.get_doc("Item", arg.get("item_code")) + out = frappe._dict() + get_price_list_rate(args, item_doc, out) + rate = out.price_list_rate if not rate: - frappe.msgprint(_("{0} not found for Item {1}") - .format(self.rm_cost_as_per, arg["item_code"]), alert=True) + if self.rm_cost_as_per == "Price List": + frappe.msgprint(_("Price not found for item {0} and price list {1}") + .format(arg["item_code"], self.buying_price_list), alert=True) + else: + frappe.msgprint(_("{0} not found for item {1}") + .format(self.rm_cost_as_per, arg["item_code"]), alert=True) return flt(rate) - def update_cost(self, update_parent=True, from_child_bom=False): + def update_cost(self, update_parent=True, from_child_bom=False, save=True): if self.docstatus == 2: return existing_bom_cost = self.total_cost for d in self.get("items"): - rate = self.get_rm_rate({"item_code": d.item_code, "bom_no": d.bom_no}) - if rate: - d.rate = rate * flt(d.conversion_factor) / flt(self.conversion_rate) + d.rate = self.get_rm_rate({ + "item_code": d.item_code, + "bom_no": d.bom_no, + "qty": d.qty, + "uom": d.uom, + "stock_uom": d.stock_uom, + "conversion_factor": d.conversion_factor + }) + d.amount = flt(d.rate) * flt(d.qty) if self.docstatus == 1: self.flags.ignore_validate_update_after_submit = True self.calculate_cost() - self.save() + if save: + self.save() self.update_exploded_items() # update parent BOMs diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json index 8d4d69b09a..754540eb6b 100644 --- a/erpnext/manufacturing/doctype/bom_item/bom_item.json +++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json @@ -1023,6 +1023,71 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "operation", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Item operation", + "length": 0, + "no_copy": 0, + "options": "Operation", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_alternative_item", + "fieldtype": "Check", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Alternative Item", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 } ], "has_web_view": 0, @@ -1035,7 +1100,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-12-28 16:38:56.529079", + "modified": "2018-11-23 15:05:55.187136", "modified_by": "Administrator", "module": "Manufacturing", "name": "BOM Item", diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 9dd9bebb4d..4ef8b2e8be 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -441,6 +441,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ weight_per_unit: item.weight_per_unit, weight_uom: item.weight_uom, uom : item.uom, + stock_uom: item.stock_uom, pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '', cost_center: item.cost_center } diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index fa2d2afce6..0c7d066216 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -120,7 +120,7 @@ class Gstr1Report(object): and customer in ('{0}')""".format("', '".join([frappe.db.escape(c.name) for c in customers])) if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"): - b2c_limit = frappe.db.get_single_value('GSt Settings', 'b2c_limit') + b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit') if not b2c_limit: frappe.throw(_("Please set B2C Limit in GST Settings.")) @@ -201,7 +201,7 @@ class Gstr1Report(object): if unidentified_gst_accounts: frappe.msgprint(_("Following accounts might be selected in GST Settings:") + "
" + "
".join(unidentified_gst_accounts), alert=True) - + # Build itemised tax for export invoices where tax table is blank for invoice, items in iteritems(self.invoice_items): if invoice not in self.items_based_on_tax_rate \ diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index bbea9043a3..9db04cd0ab 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -370,6 +370,8 @@ def get_price_list_rate(args, item_doc, out): meta = frappe.get_meta(args.parenttype or args.doctype) if meta.get_field("currency") or args.get('currency'): + pl_details = get_price_list_currency_and_exchange_rate(args) + args.update(pl_details) validate_price_list(args) if meta.get_field("currency") and args.price_list: validate_conversion_rate(args, meta) @@ -554,9 +556,10 @@ def validate_conversion_rate(args, meta): validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate, meta.get_label("plc_conversion_rate"), args.company) - args.plc_conversion_rate = flt(args.plc_conversion_rate, - get_field_precision(meta.get_field("plc_conversion_rate"), - frappe._dict({"fields": args}))) + if meta.get_field("plc_conversion_rate"): + args.plc_conversion_rate = flt(args.plc_conversion_rate, + get_field_precision(meta.get_field("plc_conversion_rate"), + frappe._dict({"fields": args}))) def get_party_item_code(args, item_doc, out): if args.transaction_type=="selling" and args.customer: @@ -792,7 +795,7 @@ def get_price_list_uom_dependant(price_list): if not result: throw(_("Price List {0} is disabled or does not exist").format(price_list)) - return result.price_not_uom_dependant + return not result.price_not_uom_dependant def get_price_list_currency_and_exchange_rate(args):