Merge pull request #28533 from GangaManoj/product-bundle-fixes
fix: misc minor Product Bundle fixes
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 769e066..aa83726 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -302,6 +302,109 @@
enable_calculate_bundle_price(enable=0)
+ def test_product_bundle_price_calculation_for_multiple_product_bundles_when_calculate_bundle_price_is_checked(self):
+ from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ make_item("_Test Product Bundle 1", {"is_stock_item": 0})
+ make_item("_Test Product Bundle 2", {"is_stock_item": 0})
+ make_item("_Test Bundle Item 1", {"is_stock_item": 1})
+ make_item("_Test Bundle Item 2", {"is_stock_item": 1})
+ make_item("_Test Bundle Item 3", {"is_stock_item": 1})
+
+ make_product_bundle("_Test Product Bundle 1",
+ ["_Test Bundle Item 1", "_Test Bundle Item 2"])
+ make_product_bundle("_Test Product Bundle 2",
+ ["_Test Bundle Item 2", "_Test Bundle Item 3"])
+
+ enable_calculate_bundle_price()
+
+ item_list = [
+ {
+ "item_code": "_Test Product Bundle 1",
+ "warehouse": "",
+ "qty": 1,
+ "rate": 400,
+ "delivered_by_supplier": 1,
+ "supplier": '_Test Supplier'
+ },
+ {
+ "item_code": "_Test Product Bundle 2",
+ "warehouse": "",
+ "qty": 1,
+ "rate": 400,
+ "delivered_by_supplier": 1,
+ "supplier": '_Test Supplier'
+ }
+ ]
+
+ quotation = make_quotation(item_list=item_list, do_not_submit=1)
+ quotation.packed_items[0].rate = 100
+ quotation.packed_items[1].rate = 200
+ quotation.packed_items[2].rate = 200
+ quotation.packed_items[3].rate = 300
+ quotation.save()
+
+ expected_values = [300, 500]
+
+ for item in quotation.items:
+ self.assertEqual(item.amount, expected_values[item.idx-1])
+
+ enable_calculate_bundle_price(enable=0)
+
+ def test_packed_items_indices_are_reset_when_product_bundle_is_deleted_from_items_table(self):
+ from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ make_item("_Test Product Bundle 1", {"is_stock_item": 0})
+ make_item("_Test Product Bundle 2", {"is_stock_item": 0})
+ make_item("_Test Product Bundle 3", {"is_stock_item": 0})
+ make_item("_Test Bundle Item 1", {"is_stock_item": 1})
+ make_item("_Test Bundle Item 2", {"is_stock_item": 1})
+ make_item("_Test Bundle Item 3", {"is_stock_item": 1})
+
+ make_product_bundle("_Test Product Bundle 1",
+ ["_Test Bundle Item 1", "_Test Bundle Item 2"])
+ make_product_bundle("_Test Product Bundle 2",
+ ["_Test Bundle Item 2", "_Test Bundle Item 3"])
+ make_product_bundle("_Test Product Bundle 3",
+ ["_Test Bundle Item 3", "_Test Bundle Item 1"])
+
+ item_list = [
+ {
+ "item_code": "_Test Product Bundle 1",
+ "warehouse": "",
+ "qty": 1,
+ "rate": 400,
+ "delivered_by_supplier": 1,
+ "supplier": '_Test Supplier'
+ },
+ {
+ "item_code": "_Test Product Bundle 2",
+ "warehouse": "",
+ "qty": 1,
+ "rate": 400,
+ "delivered_by_supplier": 1,
+ "supplier": '_Test Supplier'
+ },
+ {
+ "item_code": "_Test Product Bundle 3",
+ "warehouse": "",
+ "qty": 1,
+ "rate": 400,
+ "delivered_by_supplier": 1,
+ "supplier": '_Test Supplier'
+ }
+ ]
+
+ quotation = make_quotation(item_list=item_list, do_not_submit=1)
+ del quotation.items[1]
+ quotation.save()
+
+ for id, item in enumerate(quotation.packed_items):
+ expected_index = id + 1
+ self.assertEqual(item.idx, expected_index)
+
test_records = frappe.get_test_records('Quotation')
def enable_calculate_bundle_price(enable=1):
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 47b8ebd..1c24825 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -925,6 +925,7 @@
"supplier",
"pricing_rules"
],
+ "condition": lambda doc: doc.parent_item in items_to_map
}
}, target_doc, set_missing_values)
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index 3f73093..e4091c4 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -108,9 +108,32 @@
packed_items = doc.get("packed_items")
doc.set("packed_items", [])
+
for d in packed_items:
if d not in delete_list:
- doc.append("packed_items", d)
+ add_item_to_packing_list(doc, d)
+
+def add_item_to_packing_list(doc, packed_item):
+ doc.append("packed_items", {
+ 'parent_item': packed_item.parent_item,
+ 'item_code': packed_item.item_code,
+ 'item_name': packed_item.item_name,
+ 'uom': packed_item.uom,
+ 'qty': packed_item.qty,
+ 'rate': packed_item.rate,
+ 'conversion_factor': packed_item.conversion_factor,
+ 'description': packed_item.description,
+ 'warehouse': packed_item.warehouse,
+ 'batch_no': packed_item.batch_no,
+ 'actual_batch_qty': packed_item.actual_batch_qty,
+ 'serial_no': packed_item.serial_no,
+ 'target_warehouse': packed_item.target_warehouse,
+ 'actual_qty': packed_item.actual_qty,
+ 'projected_qty': packed_item.projected_qty,
+ 'incoming_rate': packed_item.incoming_rate,
+ 'prevdoc_doctype': packed_item.prevdoc_doctype,
+ 'parent_detail_docname': packed_item.parent_detail_docname
+ })
def update_product_bundle_price(doc, parent_items):
"""Updates the prices of Product Bundles based on the rates of the Items in the bundle."""
@@ -128,7 +151,8 @@
else:
update_parent_item_price(doc, parent_items[parent_items_index][0], bundle_price)
- bundle_price = 0
+ bundle_item_rate = bundle_item.rate if bundle_item.rate else 0
+ bundle_price = bundle_item.qty * bundle_item_rate
parent_items_index += 1
# for the last product bundle