[fixes] raise if selects product bundle as sub item in another product bundle.
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3023a9f..7f563dd 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -881,7 +881,8 @@
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 363d334..c8a7167 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -14,6 +14,7 @@
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 @@
"""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 7160eb4..8f35de5 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -45,19 +45,21 @@
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 @@
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 @@
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 @@
})
return out
-
+
\ No newline at end of file