Merge branch 'develop' into fix-pricing-rule-item-group-uom
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index fbe5678..1f7672c 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 @@
 
 		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")
 
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 4c78d72..f87fecf 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -127,6 +127,12 @@
 				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`")