From 3fbf3ce852b3f2f662beb464cfe9b9c5e26d455c Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 9 Mar 2016 15:31:04 +0530 Subject: [PATCH] [fixes] raise if selects product bundle as sub item in another product bundle. --- erpnext/public/js/controllers/transaction.js | 3 +- .../doctype/product_bundle/product_bundle.py | 8 +++- erpnext/stock/get_item_details.py | 44 +++++-------------- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 3023a9f1a2e..7f563ddd269 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -881,7 +881,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ set_gross_profit: function(item) { if (this.frm.doc.doctype == "Sales Order" && item.valuation_rate) { - item.gross_profit = flt((((item.rate - item.valuation_rate) * item.qty) * (this.frm.doc.conversion_rate || 1)), precision("amount", item)); + rate = flt(item.rate) * flt(this.frm.doc.conversion_rate || 1); + item.gross_profit = flt(((rate - item.valuation_rate) * item.qty), precision("amount", item)); } } }); diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.py b/erpnext/selling/doctype/product_bundle/product_bundle.py index 363d334f22f..c8a71677f93 100644 --- a/erpnext/selling/doctype/product_bundle/product_bundle.py +++ b/erpnext/selling/doctype/product_bundle/product_bundle.py @@ -14,6 +14,7 @@ class ProductBundle(Document): def validate(self): self.validate_main_item() + self.validate_child_items() from erpnext.utilities.transaction_base import validate_uom_is_integer validate_uom_is_integer(self, "uom", "qty") @@ -21,7 +22,12 @@ class ProductBundle(Document): """Validates, main Item is not a stock item""" if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"): frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code)) - + + def validate_child_items(self): + for item in self.items: + if frappe.db.exists("Product Bundle", item.item_code): + frappe.throw(_("Child Item should not be a Product Bundle. Please remove item `{0}` and save").format(item.item_code)) + def get_new_item_code(doctype, txt, searchfield, start, page_len, filters): from erpnext.controllers.queries import get_match_cond diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 7160eb4c6f3..8f35de54ac3 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -45,19 +45,21 @@ def get_item_details(args): if out.get("warehouse"): out.update(get_bin_details(args.item_code, out.warehouse)) - if is_item_product_bundle(args.item_code): - bundled_items = get_bundled_items(args.item_code) + if frappe.db.exists("Product Bundle", args.item_code): valuation_rate = 0.0 - - for item in bundled_items: - valuation_rate += flt(get_valuation_rate(item.item_code, out).get("valuation_rate") * item.qty) + bundled_items = frappe.get_doc("Product Bundle", args.item_code) + + for bundle_item in bundled_items.items: + valuation_rate += \ + flt(get_valuation_rate(bundle_item.item_code, out.get("warehouse")).get("valuation_rate") \ + * bundle_item.qty) out.update({ "valuation_rate": valuation_rate }) - + else: - out.update(get_valuation_rate(args.item_code, out)) + out.update(get_valuation_rate(args.item_code, out.get("warehouse"))) get_price_list_rate(args, item_doc, out) @@ -483,11 +485,9 @@ def get_default_bom(item_code=None): else: frappe.throw(_("No default BOM exists for Item {0}").format(item_code)) -def get_valuation_rate(item_code, out): +def get_valuation_rate(item_code, warehouse=None): item = frappe.get_doc("Item", item_code) if item.is_stock_item: - warehouse = out.get("warehouse") - if not warehouse: warehouse = item.default_warehouse @@ -503,29 +503,7 @@ def get_valuation_rate(item_code, out): return {"valuation_rate": valuation_rate[0][0] or 0.0} else: return {"valuation_rate": 0.0} - -def is_item_product_bundle(item_code): - if frappe.db.get_value("Product Bundle", item_code): - return True - return False - -def get_bundled_items(item_code, bundled_items=None): - if not bundled_items: - bundled_items = [] - - doc = frappe.get_doc("Product Bundle", item_code) - - for item in doc.items: - if is_item_product_bundle(item.item_code): - get_bundled_items(item.item_code, bundled_items) - - bundled_items.append(frappe._dict({ - "item_code": item.item_code, - "qty": item.qty - })) - return bundled_items - def get_gross_profit(out): if out.valuation_rate: out.update({ @@ -533,4 +511,4 @@ def get_gross_profit(out): }) return out - + \ No newline at end of file