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_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:title",
|
"autoname": "field:title",
|
||||||
@ -71,6 +72,7 @@
|
|||||||
"section_break_13",
|
"section_break_13",
|
||||||
"threshold_percentage",
|
"threshold_percentage",
|
||||||
"priority",
|
"priority",
|
||||||
|
"condition",
|
||||||
"column_break_66",
|
"column_break_66",
|
||||||
"apply_multiple_pricing_rules",
|
"apply_multiple_pricing_rules",
|
||||||
"apply_discount_on_rate",
|
"apply_discount_on_rate",
|
||||||
@ -550,11 +552,18 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Promotional Scheme",
|
"label": "Promotional Scheme",
|
||||||
"options": "Promotional Scheme"
|
"options": "Promotional Scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Simple Python Expression, Example: territory != 'All Territories'",
|
||||||
|
"fieldname": "condition",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Condition"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-12-18 17:29:22.957077",
|
"links": [],
|
||||||
|
"modified": "2020-08-26 12:24:44.740734",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Pricing Rule",
|
"name": "Pricing Rule",
|
||||||
|
@ -6,9 +6,10 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
import copy
|
import copy
|
||||||
|
import re
|
||||||
|
|
||||||
from frappe import throw, _
|
from frappe import throw, _
|
||||||
from frappe.utils import flt, cint, getdate
|
from frappe.utils import flt, cint, getdate
|
||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
@ -30,6 +31,7 @@ class PricingRule(Document):
|
|||||||
self.validate_max_discount()
|
self.validate_max_discount()
|
||||||
self.validate_price_list_with_currency()
|
self.validate_price_list_with_currency()
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
|
self.validate_condition()
|
||||||
|
|
||||||
if not self.margin_type: self.margin_rate_or_amount = 0.0
|
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):
|
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"))
|
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()
|
@frappe.whitelist()
|
||||||
|
@ -429,7 +429,34 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
|
|
||||||
self.assertTrue(details)
|
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):
|
def make_pricing_rule(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|
||||||
@ -448,7 +475,8 @@ def make_pricing_rule(**args):
|
|||||||
"discount_percentage": args.discount_percentage or 0.0,
|
"discount_percentage": args.discount_percentage or 0.0,
|
||||||
"rate": args.rate or 0.0,
|
"rate": args.rate or 0.0,
|
||||||
"margin_type": args.margin_type,
|
"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()
|
apply_on = doc.apply_on.replace(' ', '_').lower()
|
||||||
|
@ -37,6 +37,8 @@ def get_pricing_rules(args, doc=None):
|
|||||||
|
|
||||||
rules = []
|
rules = []
|
||||||
|
|
||||||
|
pricing_rules = filter_pricing_rule_based_on_condition(pricing_rules, doc)
|
||||||
|
|
||||||
if not pricing_rules: return []
|
if not pricing_rules: return []
|
||||||
|
|
||||||
if apply_multiple_pricing_rules(pricing_rules):
|
if apply_multiple_pricing_rules(pricing_rules):
|
||||||
@ -51,6 +53,23 @@ def get_pricing_rules(args, doc=None):
|
|||||||
|
|
||||||
return rules
|
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):
|
def _get_pricing_rules(apply_on, args, values):
|
||||||
apply_on_field = frappe.scrub(apply_on)
|
apply_on_field = frappe.scrub(apply_on)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user