mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-05 14:38:26 +00:00
Merge pull request #45750 from mihir-kandoi/st20447
feat: added option to enforce free item qty in pricing rule
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
"column_break_42",
|
"column_break_42",
|
||||||
"free_item_uom",
|
"free_item_uom",
|
||||||
"round_free_qty",
|
"round_free_qty",
|
||||||
|
"dont_enforce_free_item_qty",
|
||||||
"is_recursive",
|
"is_recursive",
|
||||||
"recurse_for",
|
"recurse_for",
|
||||||
"apply_recursion_over",
|
"apply_recursion_over",
|
||||||
@@ -643,12 +644,19 @@
|
|||||||
"fieldname": "has_priority",
|
"fieldname": "has_priority",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Has Priority"
|
"label": "Has Priority"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.price_or_product_discount == 'Product'",
|
||||||
|
"fieldname": "dont_enforce_free_item_qty",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Don't Enforce Free Item Qty"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-09-16 18:14:51.314765",
|
"modified": "2025-02-17 18:15:39.824639",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Pricing Rule",
|
"name": "Pricing Rule",
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class PricingRule(Document):
|
|||||||
disable: DF.Check
|
disable: DF.Check
|
||||||
discount_amount: DF.Currency
|
discount_amount: DF.Currency
|
||||||
discount_percentage: DF.Float
|
discount_percentage: DF.Float
|
||||||
|
dont_enforce_free_item_qty: DF.Check
|
||||||
for_price_list: DF.Link | None
|
for_price_list: DF.Link | None
|
||||||
free_item: DF.Link | None
|
free_item: DF.Link | None
|
||||||
free_item_rate: DF.Currency
|
free_item_rate: DF.Currency
|
||||||
@@ -645,7 +646,7 @@ def remove_pricing_rule_for_item(pricing_rules, item_details, item_code=None, ra
|
|||||||
if pricing_rule.margin_type in ["Percentage", "Amount"]:
|
if pricing_rule.margin_type in ["Percentage", "Amount"]:
|
||||||
item_details.margin_rate_or_amount = 0.0
|
item_details.margin_rate_or_amount = 0.0
|
||||||
item_details.margin_type = None
|
item_details.margin_type = None
|
||||||
elif pricing_rule.get("free_item"):
|
elif pricing_rule.get("free_item") and not pricing_rule.get("dont_enforce_free_item_qty"):
|
||||||
item_details.remove_free_item = (
|
item_details.remove_free_item = (
|
||||||
item_code if pricing_rule.get("same_item") else pricing_rule.get("free_item")
|
item_code if pricing_rule.get("same_item") else pricing_rule.get("free_item")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -438,6 +438,54 @@ class TestPricingRule(IntegrationTestCase):
|
|||||||
self.assertEqual(so.items[1].is_free_item, 1)
|
self.assertEqual(so.items[1].is_free_item, 1)
|
||||||
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
||||||
|
|
||||||
|
def test_dont_enforce_free_item_qty(self):
|
||||||
|
# this test is only for testing non-enforcement as all other tests in this file already test with enforcement
|
||||||
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule")
|
||||||
|
test_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Pricing Rule",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"currency": "USD",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selling": 1,
|
||||||
|
"rate_or_discount": "Discount Percentage",
|
||||||
|
"rate": 0,
|
||||||
|
"min_qty": 0,
|
||||||
|
"max_qty": 7,
|
||||||
|
"discount_percentage": 17.5,
|
||||||
|
"price_or_product_discount": "Product",
|
||||||
|
"same_item": 0,
|
||||||
|
"free_item": "_Test Item 2",
|
||||||
|
"free_qty": 1,
|
||||||
|
"company": "_Test Company",
|
||||||
|
}
|
||||||
|
pricing_rule = frappe.get_doc(test_record.copy()).insert()
|
||||||
|
|
||||||
|
# With enforcement
|
||||||
|
so = make_sales_order(item_code="_Test Item", qty=1, do_not_submit=True)
|
||||||
|
self.assertEqual(so.items[1].is_free_item, 1)
|
||||||
|
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
||||||
|
|
||||||
|
# Test 1 : Saving a document with an item with pricing list without it's corresponding free item will cause it the free item to be refetched on save
|
||||||
|
so.items.pop(1)
|
||||||
|
so.save()
|
||||||
|
so.reload()
|
||||||
|
self.assertEqual(len(so.items), 2)
|
||||||
|
|
||||||
|
# Without enforcement
|
||||||
|
pricing_rule.dont_enforce_free_item_qty = 1
|
||||||
|
pricing_rule.save()
|
||||||
|
|
||||||
|
# Test 2 : Deleted free item will not be fetched again on save without enforcement
|
||||||
|
so.items.pop(1)
|
||||||
|
so.save()
|
||||||
|
so.reload()
|
||||||
|
self.assertEqual(len(so.items), 1)
|
||||||
|
|
||||||
def test_cumulative_pricing_rule(self):
|
def test_cumulative_pricing_rule(self):
|
||||||
frappe.delete_doc_if_exists("Pricing Rule", "_Test Cumulative Pricing Rule")
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Cumulative Pricing Rule")
|
||||||
test_record = {
|
test_record = {
|
||||||
@@ -1461,6 +1509,7 @@ def make_pricing_rule(**args):
|
|||||||
"discount_amount": args.discount_amount or 0.0,
|
"discount_amount": args.discount_amount or 0.0,
|
||||||
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0,
|
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0,
|
||||||
"has_priority": args.has_priority or 0,
|
"has_priority": args.has_priority or 0,
|
||||||
|
"enforce_free_item_qty": args.dont_enforce_free_item_qty or 0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -713,7 +713,10 @@ def apply_pricing_rule_for_free_items(doc, pricing_rule_args):
|
|||||||
args.pop((item.item_code, item.pricing_rules))
|
args.pop((item.item_code, item.pricing_rules))
|
||||||
|
|
||||||
for free_item in args.values():
|
for free_item in args.values():
|
||||||
doc.append("items", free_item)
|
if doc.is_new() or not frappe.get_value(
|
||||||
|
"Pricing Rule", free_item["pricing_rules"], "dont_enforce_free_item_qty"
|
||||||
|
):
|
||||||
|
doc.append("items", free_item)
|
||||||
|
|
||||||
|
|
||||||
def get_pricing_rule_items(pr_doc, other_items=False) -> list:
|
def get_pricing_rule_items(pr_doc, other_items=False) -> list:
|
||||||
|
|||||||
@@ -1251,6 +1251,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
"is_recursive": 1,
|
"is_recursive": 1,
|
||||||
"recurse_for": 2,
|
"recurse_for": 2,
|
||||||
"free_qty": 1,
|
"free_qty": 1,
|
||||||
|
"dont_enforce_free_item_qty": 0,
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"customer": "_Test Customer",
|
"customer": "_Test Customer",
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user