Merge branch 'develop' into pricing_rule_on_condition
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 29d8378..c681c89 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:title",
@@ -71,6 +72,7 @@
"section_break_13",
"threshold_percentage",
"priority",
+ "condition",
"column_break_66",
"apply_multiple_pricing_rules",
"apply_discount_on_rate",
@@ -550,11 +552,18 @@
"fieldtype": "Link",
"label": "Promotional Scheme",
"options": "Promotional Scheme"
+ },
+ {
+ "description": "Simple Python Expression, Example: territory != 'All Territories'",
+ "fieldname": "condition",
+ "fieldtype": "Code",
+ "label": "Condition"
}
],
"icon": "fa fa-gift",
"idx": 1,
- "modified": "2019-12-18 17:29:22.957077",
+ "links": [],
+ "modified": "2020-08-26 12:24:44.740734",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index aa6194c..454776e 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -6,9 +6,10 @@
import frappe
import json
import copy
+import re
+
from frappe import throw, _
from frappe.utils import flt, cint, getdate
-
from frappe.model.document import Document
from six import string_types
@@ -30,6 +31,7 @@
self.validate_max_discount()
self.validate_price_list_with_currency()
self.validate_dates()
+ self.validate_condition()
if not self.margin_type: self.margin_rate_or_amount = 0.0
@@ -140,6 +142,10 @@
if self.valid_from and self.valid_upto and getdate(self.valid_from) > getdate(self.valid_upto):
frappe.throw(_("Valid from date must be less than valid upto date"))
+ def validate_condition(self):
+ if self.condition and ("=" in self.condition) and re.match("""[\w\.:_]+\s*={1}\s*[\w\.@'"]+""", self.condition):
+ frappe.throw(_("Invalid condition expression"))
+
#--------------------------------------------------------------------------------
@frappe.whitelist()
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 2bf0b72..3555ca8 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -429,7 +429,34 @@
details = get_item_details(args)
self.assertTrue(details)
-
+
+ def test_pricing_rule_for_condition(self):
+ frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule")
+
+ make_pricing_rule(selling=1, margin_type="Percentage", \
+ condition="customer=='_Test Customer 1' and is_return==0", discount_percentage=10)
+
+ # Incorrect Customer and Correct is_return value
+ si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 2", is_return=0)
+ si.items[0].price_list_rate = 1000
+ si.submit()
+ item = si.items[0]
+ self.assertEquals(item.rate, 100)
+
+ # Correct Customer and Incorrect is_return value
+ si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", is_return=1, qty=-1)
+ si.items[0].price_list_rate = 1000
+ si.submit()
+ item = si.items[0]
+ self.assertEquals(item.rate, 100)
+
+ # Correct Customer and correct is_return value
+ si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", is_return=0)
+ si.items[0].price_list_rate = 1000
+ si.submit()
+ item = si.items[0]
+ self.assertEquals(item.rate, 900)
+
def make_pricing_rule(**args):
args = frappe._dict(args)
@@ -448,7 +475,8 @@
"discount_percentage": args.discount_percentage or 0.0,
"rate": args.rate or 0.0,
"margin_type": args.margin_type,
- "margin_rate_or_amount": args.margin_rate_or_amount or 0.0
+ "margin_rate_or_amount": args.margin_rate_or_amount or 0.0,
+ "condition": args.condition or ''
})
apply_on = doc.apply_on.replace(' ', '_').lower()
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 53b0cf7b..25840d4 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -37,6 +37,8 @@
rules = []
+ pricing_rules = filter_pricing_rule_based_on_condition(pricing_rules, doc)
+
if not pricing_rules: return []
if apply_multiple_pricing_rules(pricing_rules):
@@ -51,6 +53,23 @@
return rules
+def filter_pricing_rule_based_on_condition(pricing_rules, doc=None):
+ filtered_pricing_rules = []
+ if doc:
+ for pricing_rule in pricing_rules:
+ if pricing_rule.condition:
+ try:
+ if frappe.safe_eval(pricing_rule.condition, None, doc.as_dict()):
+ filtered_pricing_rules.append(pricing_rule)
+ except:
+ pass
+ else:
+ filtered_pricing_rules.append(pricing_rule)
+ else:
+ filtered_pricing_rules = pricing_rules
+
+ return filtered_pricing_rules
+
def _get_pricing_rules(apply_on, args, values):
apply_on_field = frappe.scrub(apply_on)