mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-02 01:04:36 +00:00
fix: skip stock expense GL entries for non-stock items (#57518)
* fix: skip stock expense gl entries for non stock items (cherry picked from commit 747f4df778dca45cf044c02f0e933d3b230b8334) * test: use a leaf expense account for the service item invoice
This commit is contained in:
@@ -356,7 +356,14 @@ class BuyingController(SubcontractingController):
|
||||
if self.doctype == "Purchase Invoice" and not self.update_stock:
|
||||
return
|
||||
|
||||
stock_items = self.get_stock_items()
|
||||
|
||||
for row in self.items:
|
||||
# A service item holds no stock value, so there is nothing to book against it - and it
|
||||
# must not make the expense accounts mandatory either.
|
||||
if row.item_code not in stock_items:
|
||||
continue
|
||||
|
||||
details = self.get_validated_purchase_expense_details(row.item_code)
|
||||
if not details:
|
||||
continue
|
||||
@@ -365,6 +372,10 @@ class BuyingController(SubcontractingController):
|
||||
if row.landed_cost_voucher_amount:
|
||||
amount -= flt(row.landed_cost_voucher_amount, row.precision("base_amount"))
|
||||
|
||||
if not amount:
|
||||
# GL Entry rejects a row with neither a debit nor a credit.
|
||||
continue
|
||||
|
||||
self.add_gl_entry(
|
||||
gl_entries=gl_entries,
|
||||
account=details.purchase_expense_account,
|
||||
|
||||
@@ -897,6 +897,12 @@ class StockController(AccountsController):
|
||||
self.append_expenses_added_to_stock_pair(gl_list, item_code, amount, item_row)
|
||||
|
||||
def append_expenses_added_to_stock_pair(self, gl_list, item_code, amount, item_row):
|
||||
# A service item holds no stock value, so there is nothing to book against it - and it must
|
||||
# not make the expense accounts mandatory either. A zero pair would be rejected by GL Entry
|
||||
# anyway, which needs a debit or a credit on every row.
|
||||
if not amount or not frappe.get_cached_value("Item", item_code, "is_stock_item"):
|
||||
return
|
||||
|
||||
fields = ("expenses_added_to_stock_account", "expenses_added_to_stock_contra_account")
|
||||
details = get_expenses_added_to_stock_accounts(item_code, self.company)
|
||||
|
||||
|
||||
@@ -174,3 +174,38 @@ class TestExpensesAddedToStock(ERPNextTestSuite):
|
||||
rate=100,
|
||||
company=COMPANY,
|
||||
)
|
||||
|
||||
def test_service_item_books_nothing_on_purchase_invoice_with_update_stock(self):
|
||||
"""A service item carries no stock value, so booking it produced a GL row with neither a
|
||||
debit nor a credit, which GL Entry rejects outright."""
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
|
||||
service_item = make_item(properties={"is_stock_item": 0}).name
|
||||
|
||||
pi = make_purchase_invoice(
|
||||
company=COMPANY,
|
||||
warehouse=WAREHOUSE,
|
||||
item_code=service_item,
|
||||
qty=1,
|
||||
rate=500,
|
||||
update_stock=1,
|
||||
expense_account="Cost of Goods Sold - TCP1",
|
||||
cost_center="Main - TCP1",
|
||||
)
|
||||
|
||||
self.assertEqual(pi.docstatus, 1)
|
||||
|
||||
_balances, debits, credits = self.get_gl_balances("Purchase Invoice", pi.name)
|
||||
self.assertEqual(debits[self.eats_account], 0)
|
||||
self.assertEqual(credits[self.eats_contra_account], 0)
|
||||
|
||||
booked = frappe.get_all(
|
||||
"GL Entry",
|
||||
filters={
|
||||
"voucher_type": "Purchase Invoice",
|
||||
"voucher_no": pi.name,
|
||||
"is_cancelled": 0,
|
||||
"account": self.purchase_expense_account,
|
||||
},
|
||||
)
|
||||
self.assertFalse(booked)
|
||||
|
||||
Reference in New Issue
Block a user