mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-20 13:14:03 +00:00
fix: exclude non-stock item's tax value from stock valuation
(cherry picked from commit 13e1f84eb1)
This commit is contained in:
committed by
Mergify
parent
3243e4237a
commit
3d6c7f4512
@@ -417,20 +417,21 @@ class BuyingController(SubcontractingController):
|
||||
stock_and_asset_items_qty, stock_and_asset_items_amount = 0, 0
|
||||
last_item_idx = 1
|
||||
for d in self.get("items"):
|
||||
if d.item_code and d.item_code in stock_and_asset_items:
|
||||
if d.item_code:
|
||||
stock_and_asset_items_qty += flt(d.qty)
|
||||
stock_and_asset_items_amount += flt(d.base_net_amount)
|
||||
|
||||
last_item_idx = d.idx
|
||||
|
||||
tax_accounts, total_valuation_amount, total_actual_tax_amount = self.get_tax_details()
|
||||
remaining_amount = total_actual_tax_amount
|
||||
|
||||
for i, item in enumerate(self.get("items")):
|
||||
if item.item_code and (item.qty or item.get("rejected_qty")):
|
||||
item_tax_amount, actual_tax_amount = 0.0, 0.0
|
||||
if i == (last_item_idx - 1):
|
||||
item_tax_amount = total_valuation_amount
|
||||
actual_tax_amount = total_actual_tax_amount
|
||||
actual_tax_amount = remaining_amount
|
||||
else:
|
||||
# calculate item tax amount
|
||||
item_tax_amount = self.get_item_tax_amount(item, tax_accounts)
|
||||
@@ -443,7 +444,8 @@ class BuyingController(SubcontractingController):
|
||||
stock_and_asset_items_amount,
|
||||
stock_and_asset_items_qty,
|
||||
)
|
||||
total_actual_tax_amount -= actual_tax_amount
|
||||
|
||||
remaining_amount -= actual_tax_amount
|
||||
|
||||
# This code is required here to calculate the correct valuation for stock items
|
||||
if item.item_code not in stock_and_asset_items:
|
||||
|
||||
@@ -1333,6 +1333,73 @@ class TestPurchaseReceipt(ERPNextTestSuite):
|
||||
|
||||
pr.delete()
|
||||
|
||||
def test_valuation_tax_distribution_with_non_stock_item(self):
|
||||
"""A "Valuation and Total" tax is distributed across all items by net amount, but only
|
||||
stock/asset items can carry valuation. For a document with 2 stock items + 1 service
|
||||
item (each net 100) and a 30 valuation tax, each item's share is 10; only the two stock
|
||||
items capitalize their share (20 total), so the non-stock item's 10 share must not be
|
||||
capitalized onto the stock items."""
|
||||
company = "_Test Company with perpetual inventory"
|
||||
warehouse = "Stores - TCP1"
|
||||
|
||||
stock_item1 = make_item(properties={"is_stock_item": 1}).name
|
||||
stock_item2 = make_item(properties={"is_stock_item": 1}).name
|
||||
service_item = make_item(properties={"is_stock_item": 0}).name
|
||||
|
||||
pr = frappe.new_doc("Purchase Receipt")
|
||||
pr.company = company
|
||||
pr.supplier = "_Test Supplier"
|
||||
pr.currency = "INR"
|
||||
# Order matters: stock, service, stock (service item in the middle)
|
||||
for code in (stock_item1, service_item, stock_item2):
|
||||
pr.append(
|
||||
"items",
|
||||
{
|
||||
"item_code": code,
|
||||
"qty": 1,
|
||||
"rate": 100,
|
||||
"warehouse": warehouse,
|
||||
"cost_center": "Main - TCP1",
|
||||
"expense_account": "Cost of Goods Sold - TCP1",
|
||||
},
|
||||
)
|
||||
|
||||
pr.append(
|
||||
"taxes",
|
||||
{
|
||||
"charge_type": "Actual",
|
||||
"account_head": "_Test Account Shipping Charges - TCP1",
|
||||
"category": "Valuation and Total",
|
||||
"cost_center": "Main - TCP1",
|
||||
"description": "Valuation Tax",
|
||||
"tax_amount": 30,
|
||||
},
|
||||
)
|
||||
|
||||
pr.insert()
|
||||
|
||||
# 30 tax / 300 net = 10 per item. The two stock items capitalize 10 each; the service
|
||||
# item's 10 share is excluded from valuation (not dumped onto the stock items).
|
||||
self.assertAlmostEqual(pr.items[0].item_tax_amount, 10.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[1].item_tax_amount, 0.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[2].item_tax_amount, 10.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[0].valuation_rate, 110.0, places=2)
|
||||
self.assertAlmostEqual(pr.items[2].valuation_rate, 110.0, places=2)
|
||||
|
||||
pr.submit()
|
||||
|
||||
gl_entries = get_gl_entries("Purchase Receipt", pr.name, skip_cancelled=True, as_dict=True)
|
||||
gl_map = {row.account: row for row in gl_entries}
|
||||
|
||||
warehouse_account = get_warehouse_account_map(company)
|
||||
stock_account = warehouse_account[warehouse]["account"]
|
||||
|
||||
# Stock asset = 200 (goods) + 20 (stock items' share of the valuation tax)
|
||||
self.assertAlmostEqual(gl_map[stock_account].debit, 220.0, places=2)
|
||||
self.assertAlmostEqual(gl_map["Stock Received But Not Billed - TCP1"].credit, 200.0, places=2)
|
||||
# Only the stock items' share (20) is capitalized; the service item's 10 is excluded
|
||||
self.assertAlmostEqual(gl_map["_Test Account Shipping Charges - TCP1"].credit, 20.0, places=2)
|
||||
|
||||
def test_po_to_pi_and_po_to_pr_worflow_full(self):
|
||||
"""Test following behaviour:
|
||||
- Create PO
|
||||
|
||||
Reference in New Issue
Block a user