Merge pull request #23014 from abhishekbalam/pricing_rule_on_condition
feat(Accounts): Add Condition Field In Pricing Rule
This commit is contained in:
commit
c837b5f48c
@ -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",
|
||||
|
@ -6,9 +6,10 @@ from __future__ import unicode_literals
|
||||
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 @@ class PricingRule(Document):
|
||||
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 @@ class PricingRule(Document):
|
||||
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()
|
||||
|
@ -429,7 +429,34 @@ class TestPricingRule(unittest.TestCase):
|
||||
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 @@ def make_pricing_rule(**args):
|
||||
"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()
|
||||
|
@ -37,6 +37,8 @@ def get_pricing_rules(args, doc=None):
|
||||
|
||||
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 @@ def get_pricing_rules(args, doc=None):
|
||||
|
||||
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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user