mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-12 03:15:07 +00:00
fix: correct item valuation when "Deduct" is used in Purchase Invoice and Receipt.
(cherry picked from commit e68f149d3a)
# Conflicts:
# erpnext/controllers/buying_controller.py
This commit is contained in:
@@ -401,6 +401,57 @@ class BuyingController(SubcontractingController):
|
||||
|
||||
update_regional_item_valuation_rate(self)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
def get_tax_details(self):
|
||||
tax_accounts = []
|
||||
total_valuation_amount = 0.0
|
||||
total_actual_tax_amount = 0.0
|
||||
|
||||
for d in self.get("taxes"):
|
||||
if d.category not in ["Valuation", "Valuation and Total"]:
|
||||
continue
|
||||
|
||||
amount = flt(d.base_tax_amount_after_discount_amount) * (
|
||||
-1 if d.get("add_deduct_tax") == "Deduct" else 1
|
||||
)
|
||||
|
||||
if d.charge_type == "On Net Total":
|
||||
total_valuation_amount += amount
|
||||
tax_accounts.append(d.account_head)
|
||||
else:
|
||||
total_actual_tax_amount += amount
|
||||
|
||||
return tax_accounts, total_valuation_amount, total_actual_tax_amount
|
||||
|
||||
def get_item_tax_amount(self, item, tax_accounts):
|
||||
item_tax_amount = 0.0
|
||||
if item.item_tax_rate:
|
||||
tax_details = json.loads(item.item_tax_rate)
|
||||
for account, rate in tax_details.items():
|
||||
if account not in tax_accounts:
|
||||
continue
|
||||
|
||||
net_rate = item.base_net_amount
|
||||
if item.sales_incoming_rate:
|
||||
net_rate = item.qty * item.sales_incoming_rate
|
||||
|
||||
item_tax_amount += flt(net_rate) * flt(rate) / 100
|
||||
|
||||
return item_tax_amount
|
||||
|
||||
def get_item_actual_tax_amount(
|
||||
self, item, actual_tax_amount, stock_and_asset_items_amount, stock_and_asset_items_qty
|
||||
):
|
||||
item_proportion = (
|
||||
flt(item.base_net_amount) / stock_and_asset_items_amount
|
||||
if stock_and_asset_items_amount
|
||||
else flt(item.qty) / stock_and_asset_items_qty
|
||||
)
|
||||
|
||||
return flt(item_proportion * actual_tax_amount, self.precision("item_tax_amount", item))
|
||||
|
||||
>>>>>>> e68f149d3a (fix: correct item valuation when "Deduct" is used in Purchase Invoice and Receipt.)
|
||||
def set_incoming_rate(self):
|
||||
"""
|
||||
Override item rate with incoming rate for internal stock transfer
|
||||
|
||||
@@ -1217,6 +1217,65 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
|
||||
pr.cancel()
|
||||
|
||||
def test_item_valuation_with_deduct_valuation_and_total_tax(self):
|
||||
pr = make_purchase_receipt(
|
||||
company="_Test Company with perpetual inventory",
|
||||
warehouse="Stores - TCP1",
|
||||
supplier_warehouse="Work In Progress - TCP1",
|
||||
qty=5,
|
||||
rate=100,
|
||||
do_not_save=1,
|
||||
)
|
||||
|
||||
pr.append(
|
||||
"taxes",
|
||||
{
|
||||
"charge_type": "Actual",
|
||||
"add_deduct_tax": "Deduct",
|
||||
"account_head": "_Test Account Shipping Charges - TCP1",
|
||||
"category": "Valuation and Total",
|
||||
"cost_center": "Main - TCP1",
|
||||
"description": "Valuation Discount",
|
||||
"tax_amount": 20,
|
||||
},
|
||||
)
|
||||
|
||||
pr.insert()
|
||||
|
||||
self.assertAlmostEqual(pr.items[0].item_tax_amount, -20.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[0].valuation_rate, 96.0, places=2)
|
||||
|
||||
pr.delete()
|
||||
|
||||
pr = make_purchase_receipt(
|
||||
company="_Test Company with perpetual inventory",
|
||||
warehouse="Stores - TCP1",
|
||||
supplier_warehouse="Work In Progress - TCP1",
|
||||
qty=5,
|
||||
rate=100,
|
||||
do_not_save=1,
|
||||
)
|
||||
|
||||
pr.append(
|
||||
"taxes",
|
||||
{
|
||||
"charge_type": "On Net Total",
|
||||
"add_deduct_tax": "Deduct",
|
||||
"account_head": "_Test Account Shipping Charges - TCP1",
|
||||
"category": "Valuation and Total",
|
||||
"cost_center": "Main - TCP1",
|
||||
"description": "Valuation Discount",
|
||||
"rate": 10,
|
||||
},
|
||||
)
|
||||
|
||||
pr.insert()
|
||||
|
||||
self.assertAlmostEqual(pr.items[0].item_tax_amount, -50.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[0].valuation_rate, 90.0, places=2)
|
||||
|
||||
pr.delete()
|
||||
|
||||
def test_po_to_pi_and_po_to_pr_worflow_full(self):
|
||||
"""Test following behaviour:
|
||||
- Create PO
|
||||
|
||||
Reference in New Issue
Block a user