[fix] pricing rule for variant, if rule for template available, use it
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index fcc1f92..cd6bcf4 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -97,10 +97,10 @@
args = json.loads(args)
args = frappe._dict(args)
-
+
if not args.transaction_type:
set_transaction_type(args)
-
+
# list of dictionaries
out = []
@@ -142,7 +142,7 @@
customer = frappe.db.get_value("Customer", args.customer, ["customer_group", "territory"])
if customer:
args.customer_group, args.territory = customer
-
+
args.supplier = args.supplier_type = None
elif args.supplier and not args.supplier_type:
@@ -186,7 +186,7 @@
return condition
- conditions = ""
+ conditions = item_variant_condition = ""
values = {"item_code": args.get("item_code"), "brand": args.get("brand")}
for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
@@ -211,16 +211,26 @@
values['transaction_date'] = args.get('transaction_date')
item_group_condition = _get_tree_conditions("Item Group", False)
- if item_group_condition: item_group_condition = " or " + item_group_condition
+ if item_group_condition:
+ item_group_condition = " or " + item_group_condition
+
+ # load variant of if not defined
+ if "variant_of" not in args:
+ args.variant_of = frappe.db.get_value("Item", args.item_code, "variant_of")
+
+ if args.variant_of:
+ item_variant_condition = ' or item_code=%(variant_of)s '
+ values['variant_of'] = args.variant_of
return frappe.db.sql("""select * from `tabPricing Rule`
- where (item_code=%(item_code)s {item_group_condition} or brand=%(brand)s)
+ where (item_code=%(item_code)s {item_variant_condition} {item_group_condition} or brand=%(brand)s)
and docstatus < 2 and disable = 0
and {transaction_type} = 1 {conditions}
order by priority desc, name desc""".format(
- item_group_condition=item_group_condition,
- transaction_type= args.transaction_type,
- conditions=conditions), values, as_dict=1)
+ item_group_condition = item_group_condition,
+ item_variant_condition = item_variant_condition,
+ transaction_type = args.transaction_type,
+ conditions = conditions), values, as_dict=1)
def filter_pricing_rules(args, pricing_rules):
# filter for qty
@@ -228,6 +238,11 @@
pricing_rules = filter(lambda x: (flt(args.get("qty"))>=flt(x.min_qty)
and (flt(args.get("qty"))<=x.max_qty if x.max_qty else True)), pricing_rules)
+ # add variant_of property in pricing rule
+ for p in pricing_rules:
+ if p.item_code and args.variant_of:
+ p.variant_of = args.variant_of
+
# find pricing rule with highest priority
if pricing_rules:
max_priority = max([cint(p.priority) for p in pricing_rules])
@@ -239,7 +254,7 @@
"supplier", "supplier_type", "campaign", "sales_partner"]
if len(pricing_rules) > 1:
- for field_set in [["item_code", "item_group", "brand"],
+ for field_set in [["item_code", "variant_of", "item_group", "brand"],
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
remaining_fields = list(set(all_fields) - set(field_set))
if if_all_rules_same(pricing_rules, remaining_fields):
@@ -253,8 +268,7 @@
or pricing_rules
if len(pricing_rules) > 1:
- frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \
- conflict by assigning priority. Price Rules: {0}")
+ frappe.throw(_("Multiple Price Rules exists with same criteria, please resolve conflict by assigning priority. Price Rules: {0}")
.format("\n".join([d.name for d in pricing_rules])), MultiplePricingRuleConflict)
elif pricing_rules:
return pricing_rules[0]
@@ -281,10 +295,10 @@
def set_transaction_type(args):
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
args.transaction_type = "selling"
- elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",
+ elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",
"Purchase Receipt", "Purchase Invoice"):
args.transaction_type = "buying"
elif args.customer:
args.transaction_type = "selling"
else:
- args.transaction_type = "buying"
\ No newline at end of file
+ args.transaction_type = "buying"
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index bdd7431..d8d74bc 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -41,12 +41,12 @@
})
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10)
-
+
prule = frappe.get_doc(test_record.copy())
prule.applicable_for = "Customer"
prule.title = "_Test Pricing Rule for Customer"
self.assertRaises(MandatoryError, prule.insert)
-
+
prule.customer = "_Test Customer"
prule.discount_percentage = 20
prule.insert()
@@ -59,7 +59,7 @@
prule.title = "_Test Pricing Rule for Item Group"
prule.discount_percentage = 15
prule.insert()
-
+
args.customer = "_Test Customer 1"
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10)
@@ -85,3 +85,73 @@
self.assertEquals(details.get("discount_percentage"), 15)
frappe.db.sql("delete from `tabPricing Rule`")
+
+ def test_pricing_rule_for_variants(self):
+ from erpnext.stock.get_item_details import get_item_details
+ from frappe import MandatoryError
+
+ frappe.db.sql("delete from `tabPricing Rule`")
+
+ if not frappe.db.exists("Item", "Test Variant PRT"):
+ frappe.get_doc({
+ "doctype": "Item",
+ "item_code": "Test Variant PRT",
+ "item_name": "Test Variant PRT",
+ "description": "Test Variant PRT",
+ "item_group": "_Test Item Group",
+ "is_stock_item": 1,
+ "variant_of": "_Test Variant Item",
+ "default_warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "_Test UOM",
+ "attributes": [
+ {
+ "attribute": "Test Size",
+ "attribute_value": "Medium"
+ }
+ ],
+ }).insert()
+
+ frappe.get_doc({
+ "doctype": "Pricing Rule",
+ "title": "_Test Pricing Rule 1",
+ "apply_on": "Item Code",
+ "item_code": "_Test Variant Item",
+ "selling": 1,
+ "price_or_discount": "Discount Percentage",
+ "price": 0,
+ "discount_percentage": 7.5,
+ "company": "_Test Company"
+ }).insert()
+
+ args = frappe._dict({
+ "item_code": "Test Variant PRT",
+ "company": "_Test Company",
+ "price_list": "_Test Price List",
+ "currency": "_Test Currency",
+ "doctype": "Sales Order",
+ "conversion_rate": 1,
+ "price_list_currency": "_Test Currency",
+ "plc_conversion_rate": 1,
+ "order_type": "Sales",
+ "customer": "_Test Customer",
+ "name": None
+ })
+
+ details = get_item_details(args)
+ self.assertEquals(details.get("discount_percentage"), 7.5)
+
+ # add a new pricing rule for that item code, it should take priority
+ frappe.get_doc({
+ "doctype": "Pricing Rule",
+ "title": "_Test Pricing Rule 2",
+ "apply_on": "Item Code",
+ "item_code": "Test Variant PRT",
+ "selling": 1,
+ "price_or_discount": "Discount Percentage",
+ "price": 0,
+ "discount_percentage": 17.5,
+ "company": "_Test Company"
+ }).insert()
+
+ details = get_item_details(args)
+ self.assertEquals(details.get("discount_percentage"), 17.5)
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index b1d441c..0146f38 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -26,6 +26,7 @@
"options": "Item",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 0,
"report_hide": 0,
@@ -50,6 +51,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -71,6 +73,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -95,6 +98,7 @@
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 0,
"report_hide": 0,
@@ -107,18 +111,20 @@
{
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 0,
+ "collapsible": 1,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -143,6 +149,7 @@
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "300px",
"read_only": 0,
"report_hide": 0,
@@ -167,6 +174,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -190,6 +198,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -214,6 +223,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -236,6 +246,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -260,6 +271,7 @@
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 0,
"report_hide": 0,
@@ -287,6 +299,7 @@
"options": "currency",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -314,6 +327,7 @@
"oldfieldtype": "Float",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 0,
"report_hide": 0,
@@ -337,6 +351,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -362,6 +377,7 @@
"options": "UOM",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -389,6 +405,7 @@
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -412,6 +429,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -437,6 +455,7 @@
"options": "currency",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 0,
"report_hide": 0,
@@ -462,6 +481,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -487,6 +507,7 @@
"options": "currency",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -513,6 +534,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -534,6 +556,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -559,6 +582,7 @@
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -584,6 +608,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -609,6 +634,7 @@
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 1,
"report_hide": 0,
@@ -635,6 +661,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -658,6 +685,7 @@
"options": "Pricing Rule",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -680,6 +708,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -705,6 +734,7 @@
"options": "DocType",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 1,
"report_hide": 0,
@@ -732,6 +762,7 @@
"options": "prevdoc_doctype",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 1,
"report_hide": 0,
@@ -758,6 +789,7 @@
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 1,
"reqd": 0,
@@ -779,6 +811,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -803,6 +836,7 @@
"oldfieldtype": "Check",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 1,
"reqd": 0,
@@ -829,6 +863,7 @@
"options": "Item Group",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -854,6 +889,7 @@
"options": "Brand",
"permlevel": 0,
"print_hide": 1,
+ "print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 1,
"report_hide": 0,
@@ -873,7 +909,8 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2015-11-16 06:29:55.206667",
+ "menu_index": 0,
+ "modified": "2016-02-08 08:02:06.257910",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",