diff --git a/erpnext/selling/doctype/product_bundle/test_product_bundle.py b/erpnext/selling/doctype/product_bundle/test_product_bundle.py index 97297e23f90..fa268c295a4 100644 --- a/erpnext/selling/doctype/product_bundle/test_product_bundle.py +++ b/erpnext/selling/doctype/product_bundle/test_product_bundle.py @@ -103,6 +103,38 @@ class TestProductBundle(ERPNextTestSuite): bundle.items[0].qty = 99 self.assertRaises(frappe.exceptions.UpdateAfterSubmitError, bundle.save) + def test_disabled_bundle_is_not_resolved(self): + bundle = make_product_bundle(self.parent, ["_Test PB Child A"]) + + bundle.disabled = 1 + bundle.save() + self.assertIsNone(get_active_product_bundle(self.parent)) + + # disabling parks the version without ceding the active slot, so re-enabling + # restores resolution without re-activation + self.assertEqual(frappe.db.get_value("Product Bundle", bundle.name, "is_active"), 1) + bundle.disabled = 0 + bundle.save() + self.assertEqual(get_active_product_bundle(self.parent), bundle.name) + + def test_item_where_used_report_shows_disabled_flag(self): + from erpnext.stock.report.item_where_used.item_where_used import execute + + bundle = make_product_bundle(self.parent, ["_Test PB Child A"]) + bundle.disabled = 1 + bundle.save() + + _, component_rows = execute({"item": "_Test PB Child A", "section": "Where Used"}) + rows = [r for r in component_rows if r.document_name == bundle.name] + self.assertTrue(rows) + self.assertEqual(rows[0].disabled, 1) + self.assertEqual(rows[0].is_active, 1) + + _, parent_rows = execute({"item": self.parent, "section": "References"}) + rows = [r for r in parent_rows if r.document_name == bundle.name] + self.assertTrue(rows) + self.assertEqual(rows[0].disabled, 1) + def test_child_cannot_be_active_bundle(self): make_product_bundle(self.parent, ["_Test PB Child A"]) outer = make_item("_Test PB Outer", {"is_stock_item": 0, "is_sales_item": 1}).name diff --git a/erpnext/stock/doctype/packed_item/test_packed_item.py b/erpnext/stock/doctype/packed_item/test_packed_item.py index 29be9893b93..98c5dc6a008 100644 --- a/erpnext/stock/doctype/packed_item/test_packed_item.py +++ b/erpnext/stock/doctype/packed_item/test_packed_item.py @@ -165,6 +165,29 @@ class TestPackedItem(ERPNextTestSuite): self.assertEqual(so.items[0].product_bundle, v1) self.assertEqual(sorted(pi.item_code for pi in so.packed_items), sorted(self.bundle_items)) + def test_disabled_bundle_blocks_transaction(self): + "A row that explicitly references a disabled version cannot be saved." + from erpnext.selling.doctype.product_bundle.product_bundle import get_active_product_bundle + + version = get_active_product_bundle(self.bundle) + so = make_sales_order(item_code=self.bundle, qty=1, warehouse=self.warehouse, do_not_submit=True) + self.assertEqual(so.items[0].product_bundle, version) + + frappe.db.set_value("Product Bundle", version, "disabled", 1) + self.assertRaises(frappe.ValidationError, so.save) + + def test_disabled_bundle_is_not_packed(self): + "Without an explicit version, a disabled bundle is not treated as a bundle at all." + from erpnext.selling.doctype.product_bundle.product_bundle import get_active_product_bundle + + version = get_active_product_bundle(self.bundle2) + frappe.db.set_value("Product Bundle", version, "disabled", 1) + + so = make_sales_order(item_code=self.bundle2, qty=1, warehouse=self.warehouse, do_not_submit=True) + self.assertEqual(so.items[0].is_product_bundle, 0) + self.assertFalse(so.items[0].product_bundle) + self.assertFalse(so.get("packed_items")) + @ERPNextTestSuite.change_settings("Selling Settings", {"allow_multiple_items": 1}) def test_recurring_bundle_item(self): "Test impact on packed items if same bundle item is added and removed."