mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-03 05:28:27 +00:00
Merge pull request #41721 from blaggacao/fix/distributed-discounts
fix: distributed discounts on si
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
"column_break_19",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"section_break1",
|
||||
"rate",
|
||||
@@ -847,6 +848,12 @@
|
||||
{
|
||||
"fieldname": "column_break_ciit",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
|
||||
@@ -39,6 +39,7 @@ class POSInvoiceItem(SalesInvoiceItem):
|
||||
description: DF.TextEditor
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
dn_detail: DF.Data | None
|
||||
enable_deferred_revenue: DF.Check
|
||||
expense_account: DF.Link | None
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"column_break_30",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"sec_break2",
|
||||
"rate",
|
||||
@@ -838,7 +839,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "section_break_26",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -969,6 +970,12 @@
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
|
||||
@@ -34,6 +34,7 @@ class PurchaseInvoiceItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
enable_deferred_expense: DF.Check
|
||||
expense_account: DF.Link | None
|
||||
from_warehouse: DF.Link | None
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"column_break_19",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"section_break1",
|
||||
"rate",
|
||||
@@ -253,7 +254,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -922,12 +923,18 @@
|
||||
{
|
||||
"fieldname": "column_break_ytgd",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-05-23 16:36:18.970862",
|
||||
"modified": "2024-06-02 06:14:40.009020",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -45,6 +45,7 @@ class SalesInvoiceItem(Document):
|
||||
discount_account: DF.Link | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
dn_detail: DF.Data | None
|
||||
enable_deferred_revenue: DF.Check
|
||||
expense_account: DF.Link | None
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"column_break_28",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"sec_break2",
|
||||
"rate",
|
||||
@@ -782,7 +783,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -922,13 +923,19 @@
|
||||
"label": "Job Card",
|
||||
"options": "Job Card",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:12:24.979325",
|
||||
"modified": "2024-06-02 06:20:10.508290",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -37,6 +37,7 @@ class PurchaseOrderItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
expected_delivery_date: DF.Date | None
|
||||
expense_account: DF.Link | None
|
||||
fg_item: DF.Link | None
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"price_list_rate",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"col_break_price_list",
|
||||
"base_price_list_rate",
|
||||
"sec_break1",
|
||||
@@ -565,13 +566,19 @@
|
||||
{
|
||||
"fieldname": "dimension_col_break",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:10:49.490628",
|
||||
"modified": "2024-06-02 06:22:17.864822",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
@@ -26,6 +26,7 @@ class SupplierQuotationItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
expected_delivery_date: DF.Date | None
|
||||
image: DF.Attach | None
|
||||
is_free_item: DF.Check
|
||||
|
||||
@@ -1654,8 +1654,11 @@ class AccountsController(TransactionBase):
|
||||
and self.get("discount_amount")
|
||||
and self.get("additional_discount_account")
|
||||
):
|
||||
amount = item.amount
|
||||
base_amount = item.base_amount
|
||||
amount += item.distributed_discount_amount
|
||||
base_amount += flt(
|
||||
item.distributed_discount_amount * self.get("conversion_rate"),
|
||||
item.precision("distributed_discount_amount"),
|
||||
)
|
||||
|
||||
return amount, base_amount
|
||||
|
||||
|
||||
@@ -684,6 +684,9 @@ class calculate_taxes_and_totals:
|
||||
)
|
||||
|
||||
item.net_amount = flt(item.net_amount - distributed_amount, item.precision("net_amount"))
|
||||
item.distributed_discount_amount = flt(
|
||||
distributed_amount, item.precision("distributed_discount_amount")
|
||||
)
|
||||
net_total += item.net_amount
|
||||
|
||||
# discount amount rounding loss adjustment if no taxes
|
||||
@@ -700,6 +703,10 @@ class calculate_taxes_and_totals:
|
||||
item.net_amount = flt(
|
||||
item.net_amount + discount_amount_loss, item.precision("net_amount")
|
||||
)
|
||||
item.distributed_discount_amount = flt(
|
||||
distributed_amount + discount_amount_loss,
|
||||
item.precision("distributed_discount_amount"),
|
||||
)
|
||||
|
||||
item.net_rate = (
|
||||
flt(item.net_amount / item.qty, item.precision("net_rate")) if item.qty else 0
|
||||
|
||||
61
erpnext/controllers/tests/test_distributed_discount.py
Normal file
61
erpnext/controllers/tests/test_distributed_discount.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||
from erpnext.controllers.taxes_and_totals import calculate_taxes_and_totals
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
|
||||
|
||||
class TestTaxesAndTotals(AccountsTestMixin, FrappeTestCase):
|
||||
def test_distributed_discount_amount(self):
|
||||
so = make_sales_order(do_not_save=1)
|
||||
so.apply_discount_on = "Net Total"
|
||||
so.discount_amount = 100
|
||||
so.items[0].qty = 5
|
||||
so.items[0].rate = 100
|
||||
so.append("items", so.items[0].as_dict())
|
||||
so.items[1].qty = 5
|
||||
so.items[1].rate = 200
|
||||
so.save()
|
||||
|
||||
calculate_taxes_and_totals(so)
|
||||
|
||||
self.assertAlmostEqual(so.items[0].distributed_discount_amount, 33.33, places=2)
|
||||
self.assertAlmostEqual(so.items[1].distributed_discount_amount, 66.67, places=2)
|
||||
self.assertAlmostEqual(so.items[0].net_amount, 466.67, places=2)
|
||||
self.assertAlmostEqual(so.items[1].net_amount, 933.33, places=2)
|
||||
self.assertEqual(so.total, 1500)
|
||||
self.assertEqual(so.net_total, 1400)
|
||||
self.assertEqual(so.grand_total, 1400)
|
||||
|
||||
def test_distributed_discount_amount_with_taxes(self):
|
||||
so = make_sales_order(do_not_save=1)
|
||||
so.apply_discount_on = "Grand Total"
|
||||
so.discount_amount = 100
|
||||
so.items[0].qty = 5
|
||||
so.items[0].rate = 100
|
||||
so.append("items", so.items[0].as_dict())
|
||||
so.items[1].qty = 5
|
||||
so.items[1].rate = 200
|
||||
so.append(
|
||||
"taxes",
|
||||
{
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"included_in_print_rate": True,
|
||||
"rate": 10,
|
||||
},
|
||||
)
|
||||
so.save()
|
||||
|
||||
calculate_taxes_and_totals(so)
|
||||
|
||||
# like in test_distributed_discount_amount, but reduced by the included tax
|
||||
self.assertAlmostEqual(so.items[0].distributed_discount_amount, 33.33 / 1.1, places=2)
|
||||
self.assertAlmostEqual(so.items[1].distributed_discount_amount, 66.67 / 1.1, places=2)
|
||||
self.assertAlmostEqual(so.items[0].net_amount, 466.67 / 1.1, places=2)
|
||||
self.assertAlmostEqual(so.items[1].net_amount, 933.33 / 1.1, places=2)
|
||||
self.assertEqual(so.total, 1500)
|
||||
self.assertAlmostEqual(so.net_total, 1272.73, places=2)
|
||||
self.assertEqual(so.grand_total, 1400)
|
||||
@@ -34,6 +34,7 @@
|
||||
"column_break_18",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"section_break1",
|
||||
"rate",
|
||||
@@ -235,7 +236,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -662,12 +663,18 @@
|
||||
"label": "Has Alternative Item",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:10:31.183320",
|
||||
"modified": "2024-06-02 06:21:09.508680",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Item",
|
||||
|
||||
@@ -32,6 +32,7 @@ class QuotationItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
gross_profit: DF.Currency
|
||||
has_alternative_item: DF.Check
|
||||
image: DF.Attach | None
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"column_break_19",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"section_break_simple1",
|
||||
"rate",
|
||||
@@ -280,7 +281,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -905,12 +906,18 @@
|
||||
"label": "Is Stock Item",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:10:37.177978",
|
||||
"modified": "2024-06-02 06:13:40.597947",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order Item",
|
||||
|
||||
@@ -38,6 +38,7 @@ class SalesOrderItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
ensure_delivery_based_on_produced_serial_no: DF.Check
|
||||
grant_commission: DF.Check
|
||||
gross_profit: DF.Currency
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"column_break_19",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"section_break_1",
|
||||
"rate",
|
||||
@@ -274,7 +275,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -907,13 +908,19 @@
|
||||
{
|
||||
"fieldname": "column_break_rxvc",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:06:50.061877",
|
||||
"modified": "2024-06-02 06:18:38.491763",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
|
||||
@@ -36,6 +36,7 @@ class DeliveryNoteItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Float
|
||||
distributed_discount_amount: DF.Currency
|
||||
dn_detail: DF.Data | None
|
||||
expense_account: DF.Link | None
|
||||
grant_commission: DF.Check
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"column_break_37",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"distributed_discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"sec_break1",
|
||||
"rate",
|
||||
@@ -911,7 +912,7 @@
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
|
||||
"collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount || doc.distributed_discount_amount",
|
||||
"fieldname": "discount_and_margin_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
@@ -1135,6 +1136,12 @@
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "distributed_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Distributed Discount Amount",
|
||||
"options": "currency"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
|
||||
@@ -36,6 +36,7 @@ class PurchaseReceiptItem(Document):
|
||||
description: DF.TextEditor | None
|
||||
discount_amount: DF.Currency
|
||||
discount_percentage: DF.Percent
|
||||
distributed_discount_amount: DF.Currency
|
||||
expense_account: DF.Link | None
|
||||
from_warehouse: DF.Link | None
|
||||
has_item_scanned: DF.Check
|
||||
|
||||
Reference in New Issue
Block a user