Skip to content

Commit

Permalink
fix: Discount and taxes in return document should follow the referenc…
Browse files Browse the repository at this point in the history
…e document (#41911)

* fix: Discount and taxes in return document should follow the reference document

* fix: Ignore Pricing rule on debit/credit note if created against PI/SI with test cases

* fix: linter issue
  • Loading branch information
nabinhait committed Aug 1, 2024
1 parent fb2aa7d commit 2811984
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 4 deletions.
65 changes: 65 additions & 0 deletions erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

import frappe

from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.get_item_details import get_item_details
Expand Down Expand Up @@ -1311,6 +1313,69 @@ def test_validation_on_mixed_condition_with_recursion(self):
pricing_rule.is_recursive = True
self.assertRaises(frappe.ValidationError, pricing_rule.save)

def test_ignore_pricing_rule_for_credit_note(self):
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule")
pricing_rule = make_pricing_rule(
discount_percentage=20,
selling=1,
buying=1,
priority=1,
title="_Test Pricing Rule",
)

si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", qty=1)
item = si.items[0]
si.submit()
self.assertEqual(item.discount_percentage, 20)
self.assertEqual(item.rate, 80)

# change discount on pricing rule
pricing_rule.discount_percentage = 30
pricing_rule.save()

credit_note = make_return_doc(si.doctype, si.name)
credit_note.save()
self.assertEqual(credit_note.ignore_pricing_rule, 1)
self.assertEqual(credit_note.pricing_rules, [])
self.assertEqual(credit_note.items[0].discount_percentage, 20)
self.assertEqual(credit_note.items[0].rate, 80)
self.assertEqual(credit_note.items[0].pricing_rules, None)

credit_note.delete()
si.cancel()

def test_ignore_pricing_rule_for_debit_note(self):
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule")
pricing_rule = make_pricing_rule(
discount_percentage=20,
buying=1,
priority=1,
title="_Test Pricing Rule",
)

pi = make_purchase_invoice(do_not_submit=True, supplier="_Test Supplier 1", qty=1)
item = pi.items[0]
pi.submit()
self.assertEqual(item.discount_percentage, 20)
self.assertEqual(item.rate, 40)

# change discount on pricing rule
pricing_rule.discount_percentage = 30
pricing_rule.save()

# create debit note from purchase invoice
debit_note = make_return_doc(pi.doctype, pi.name)
debit_note.save()

self.assertEqual(debit_note.ignore_pricing_rule, 1)
self.assertEqual(debit_note.pricing_rules, [])
self.assertEqual(debit_note.items[0].discount_percentage, 20)
self.assertEqual(debit_note.items[0].rate, 40)
self.assertEqual(debit_note.items[0].pricing_rules, None)

debit_note.delete()
pi.cancel()


test_dependencies = ["Campaign"]

Expand Down
7 changes: 4 additions & 3 deletions erpnext/controllers/accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class InvalidQtyError(frappe.ValidationError):
"brand",
"stock_uom",
"is_fixed_asset",
"item_tax_rate",
"pricing_rules",
"weight_per_unit",
"weight_uom",
Expand Down Expand Up @@ -743,7 +742,6 @@ def set_missing_item_details(self, for_validate=False):
args["is_subcontracted"] = self.is_subcontracted

ret = get_item_details(args, self, for_validate=for_validate, overwrite_warehouse=False)

for fieldname, value in ret.items():
if item.meta.get_field(fieldname) and value is not None:
if item.get(fieldname) is None or fieldname in force_item_fields:
Expand All @@ -753,7 +751,10 @@ def set_missing_item_details(self, for_validate=False):
fieldname
):
item.set(fieldname, value)

elif fieldname == "item_tax_rate" and not (
self.get("is_return") and self.get("return_against")
):
item.set(fieldname, value)
elif fieldname == "serial_no":
# Ensure that serial numbers are matched against Stock UOM
item_conversion_factor = item.get("conversion_factor") or 1.0
Expand Down
3 changes: 3 additions & 0 deletions erpnext/controllers/sales_and_purchase_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None, return_agai
def set_missing_values(source, target):
doc = frappe.get_doc(target)
doc.is_return = 1
doc.ignore_pricing_rule = 1
doc.pricing_rules = []
doc.return_against = source.name
doc.set_warehouse = ""
if doctype == "Sales Invoice" or doctype == "POS Invoice":
Expand Down Expand Up @@ -478,6 +480,7 @@ def update_serial_batch_no(source_doc, target_doc, source_parent, item_details,

def update_item(source_doc, target_doc, source_parent):
target_doc.qty = -1 * source_doc.qty
target_doc.pricing_rules = None
if doctype in ["Purchase Receipt", "Subcontracting Receipt"]:
returned_qty_map = get_returned_qty_map_for_row(
source_parent.name, source_parent.supplier, source_doc.name, doctype
Expand Down
4 changes: 3 additions & 1 deletion erpnext/controllers/taxes_and_totals.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ def calculate_tax_withholding_net_total(self):
self.doc.base_tax_withholding_net_total = sum_base_net_amount

def validate_item_tax_template(self):
if self.doc.get("is_return") and self.doc.get("return_against"):
return

for item in self._items:
if item.item_code and item.get("item_tax_template"):
item_doc = frappe.get_cached_doc("Item", item.item_code)
Expand Down Expand Up @@ -242,7 +245,6 @@ def initialize_taxes(self):
"tax_fraction_for_current_item",
"grand_total_fraction_for_current_item",
]

if tax.charge_type != "Actual" and not (
self.discount_amount_applied and self.doc.apply_discount_on == "Grand Total"
):
Expand Down
2 changes: 2 additions & 0 deletions erpnext/public/js/controllers/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -1988,6 +1988,8 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
let item_rates = {};
let item_tax_templates = {};

if (me.frm.doc.is_return && me.frm.doc.return_against) return;

$.each(this.frm.doc.items || [], function(i, item) {
if (item.item_code) {
// Use combination of name and item code in case same item is added multiple times
Expand Down

0 comments on commit 2811984

Please sign in to comment.