From edc93ab6aae421bdec9bcb5dc1a385af169fc279 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Thu, 13 Oct 2022 12:00:30 +0530 Subject: [PATCH 1/2] fix: pricing rule item group uom Handle use case where pricing rule is applied on item group and user have selected UOM. pricing rule was applied on all UOM's even after specifying UOM. i have added condition in sql to fix this. --- erpnext/accounts/doctype/pricing_rule/utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index 1f29d732ba5..11ae540efa2 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -121,6 +121,12 @@ def _get_pricing_rules(apply_on, args, values): values["variant_of"] = args.variant_of elif apply_on_field == "item_group": item_conditions = _get_tree_conditions(args, "Item Group", child_doc, False) + if args.get("uom", None): + item_conditions += ( + " and ({child_doc}.uom='{item_uom}' or IFNULL({child_doc}.uom, '')='')".format( + child_doc=child_doc, item_uom=args.get("uom") + ) + ) conditions += get_other_conditions(conditions, values, args) warehouse_conditions = _get_tree_conditions(args, "Warehouse", "`tabPricing Rule`") From 935f31eff924e4266fe16fc0f4eb776e4ae53214 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Tue, 1 Nov 2022 12:55:46 +0530 Subject: [PATCH 2/2] fix: test cases added for item group --- .../doctype/pricing_rule/test_pricing_rule.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index fbe567824f2..1f7672c9d86 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -710,6 +710,132 @@ class TestPricingRule(unittest.TestCase): item.delete() + def test_item_group_price_with_blank_uom_pricing_rule(self): + group = frappe.get_doc(doctype="Item Group", item_group_name="_Test Pricing Rule Item Group") + group.save() + properties = { + "item_code": "Item with Group Blank UOM", + "item_group": "_Test Pricing Rule Item Group", + "stock_uom": "Nos", + "sales_uom": "Box", + "uoms": [dict(uom="Box", conversion_factor=10)], + } + item = make_item(properties=properties) + + make_item_price("Item with Group Blank UOM", "_Test Price List", 100) + + pricing_rule_record = { + "doctype": "Pricing Rule", + "title": "_Test Item with Group Blank UOM Rule", + "apply_on": "Item Group", + "item_groups": [ + { + "item_group": "_Test Pricing Rule Item Group", + } + ], + "selling": 1, + "currency": "INR", + "rate_or_discount": "Rate", + "rate": 101, + "company": "_Test Company", + } + rule = frappe.get_doc(pricing_rule_record) + rule.insert() + + si = create_sales_invoice( + do_not_save=True, item_code="Item with Group Blank UOM", uom="Box", conversion_factor=10 + ) + si.selling_price_list = "_Test Price List" + si.save() + + # If UOM is blank consider it as stock UOM and apply pricing_rule on all UOM. + # rate is 101, Selling UOM is Box that have conversion_factor of 10 so 101 * 10 = 1010 + self.assertEqual(si.items[0].price_list_rate, 1010) + self.assertEqual(si.items[0].rate, 1010) + + si.delete() + + si = create_sales_invoice(do_not_save=True, item_code="Item with Group Blank UOM", uom="Nos") + si.selling_price_list = "_Test Price List" + si.save() + + # UOM is blank so consider it as stock UOM and apply pricing_rule on all UOM. + # rate is 101, Selling UOM is Nos that have conversion_factor of 1 so 101 * 1 = 101 + self.assertEqual(si.items[0].price_list_rate, 101) + self.assertEqual(si.items[0].rate, 101) + + si.delete() + rule.delete() + frappe.get_doc("Item Price", {"item_code": "Item with Group Blank UOM"}).delete() + item.delete() + group.delete() + + def test_item_group_price_with_selling_uom_pricing_rule(self): + group = frappe.get_doc(doctype="Item Group", item_group_name="_Test Pricing Rule Item Group UOM") + group.save() + properties = { + "item_code": "Item with Group UOM other than Stock", + "item_group": "_Test Pricing Rule Item Group UOM", + "stock_uom": "Nos", + "sales_uom": "Box", + "uoms": [dict(uom="Box", conversion_factor=10)], + } + item = make_item(properties=properties) + + make_item_price("Item with Group UOM other than Stock", "_Test Price List", 100) + + pricing_rule_record = { + "doctype": "Pricing Rule", + "title": "_Test Item with Group UOM other than Stock Rule", + "apply_on": "Item Group", + "item_groups": [ + { + "item_group": "_Test Pricing Rule Item Group UOM", + "uom": "Box", + } + ], + "selling": 1, + "currency": "INR", + "rate_or_discount": "Rate", + "rate": 101, + "company": "_Test Company", + } + rule = frappe.get_doc(pricing_rule_record) + rule.insert() + + si = create_sales_invoice( + do_not_save=True, + item_code="Item with Group UOM other than Stock", + uom="Box", + conversion_factor=10, + ) + si.selling_price_list = "_Test Price List" + si.save() + + # UOM is Box so apply pricing_rule only on Box UOM. + # Selling UOM is Box and as both UOM are same no need to multiply by conversion_factor. + self.assertEqual(si.items[0].price_list_rate, 101) + self.assertEqual(si.items[0].rate, 101) + + si.delete() + + si = create_sales_invoice( + do_not_save=True, item_code="Item with Group UOM other than Stock", uom="Nos" + ) + si.selling_price_list = "_Test Price List" + si.save() + + # UOM is Box so pricing_rule won't apply as selling_uom is Nos. + # As Pricing Rule is not applied price of 100 will be fetched from Item Price List. + self.assertEqual(si.items[0].price_list_rate, 100) + self.assertEqual(si.items[0].rate, 100) + + si.delete() + rule.delete() + frappe.get_doc("Item Price", {"item_code": "Item with Group UOM other than Stock"}).delete() + item.delete() + group.delete() + def test_pricing_rule_for_different_currency(self): make_item("Test Sanitizer Item")