mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-13 06:31:48 +00:00
fix: update stock variance account logic which defaults to default expense (#57656)
* fix(stock): update stock variance account logic which defaults to default expense account set in company * test: add regression test for purchase invoice stock adjustment account fallback --------- Co-authored-by: Afsal Syed <afsalsyed12@gmail.com>
This commit is contained in:
committed by
GitHub
parent
624a236f88
commit
d09c04a623
@@ -1380,7 +1380,20 @@ class PurchaseInvoice(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if flt(stock_amount, net_amt_precision) != flt(warehouse_debit_amount, net_amt_precision):
|
if flt(stock_amount, net_amt_precision) != flt(warehouse_debit_amount, net_amt_precision):
|
||||||
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
stock_asset_rbnb = (
|
||||||
|
self.get_company_default("asset_received_but_not_billed", ignore_validation=True)
|
||||||
|
if item.is_fixed_asset
|
||||||
|
else self.get_company_default("stock_received_but_not_billed", ignore_validation=True)
|
||||||
|
)
|
||||||
|
fallback_account = (
|
||||||
|
(item.expense_account or stock_asset_rbnb)
|
||||||
|
if self.is_return
|
||||||
|
else (stock_asset_rbnb or item.expense_account)
|
||||||
|
)
|
||||||
|
cost_of_goods_sold_account = (
|
||||||
|
self.get_company_default("default_expense_account", ignore_validation=True)
|
||||||
|
or fallback_account
|
||||||
|
)
|
||||||
stock_adjustment_amt = stock_amount - warehouse_debit_amount
|
stock_adjustment_amt = stock_amount - warehouse_debit_amount
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
@@ -1405,7 +1418,20 @@ class PurchaseInvoice(BuyingController):
|
|||||||
and warehouse_debit_amount
|
and warehouse_debit_amount
|
||||||
!= flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
|
!= flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
|
||||||
):
|
):
|
||||||
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
stock_asset_rbnb = (
|
||||||
|
self.get_company_default("asset_received_but_not_billed", ignore_validation=True)
|
||||||
|
if item.is_fixed_asset
|
||||||
|
else self.get_company_default("stock_received_but_not_billed", ignore_validation=True)
|
||||||
|
)
|
||||||
|
fallback_account = (
|
||||||
|
(item.expense_account or stock_asset_rbnb)
|
||||||
|
if self.is_return
|
||||||
|
else (stock_asset_rbnb or item.expense_account)
|
||||||
|
)
|
||||||
|
cost_of_goods_sold_account = (
|
||||||
|
self.get_company_default("default_expense_account", ignore_validation=True)
|
||||||
|
or fallback_account
|
||||||
|
)
|
||||||
stock_amount = flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
|
stock_amount = flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
|
||||||
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
||||||
|
|
||||||
|
|||||||
@@ -1490,6 +1490,96 @@ class TestPurchaseInvoice(ERPNextTestSuite, StockTestMixin):
|
|||||||
)
|
)
|
||||||
frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", original_account)
|
frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", original_account)
|
||||||
|
|
||||||
|
def test_stock_adjustment_account_fallbacks_when_default_expense_account_unset(self):
|
||||||
|
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import PurchaseInvoice
|
||||||
|
|
||||||
|
class StockAdjustmentInvoice:
|
||||||
|
company = "_Test Company"
|
||||||
|
conversion_rate = 1
|
||||||
|
update_stock = 1
|
||||||
|
is_internal_supplier = 0
|
||||||
|
return_against = None
|
||||||
|
project = None
|
||||||
|
|
||||||
|
def __init__(self, is_return, defaults):
|
||||||
|
self.is_return = is_return
|
||||||
|
self.defaults = defaults
|
||||||
|
|
||||||
|
def get(self, fieldname):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_company_default(self, fieldname, ignore_validation=False):
|
||||||
|
return self.defaults.get(fieldname)
|
||||||
|
|
||||||
|
def get_gl_dict(self, args, *unused_args, **unused_kwargs):
|
||||||
|
return frappe._dict(args)
|
||||||
|
|
||||||
|
def make_invoice(is_return, defaults):
|
||||||
|
return StockAdjustmentInvoice(is_return, defaults)
|
||||||
|
|
||||||
|
def make_item(is_fixed_asset=0, expense_account="Item Expense - _TC"):
|
||||||
|
return frappe._dict(
|
||||||
|
{
|
||||||
|
"name": "row-1",
|
||||||
|
"warehouse": "Stores - _TC",
|
||||||
|
"valuation_rate": 10,
|
||||||
|
"qty": 10,
|
||||||
|
"conversion_factor": 1,
|
||||||
|
"base_net_amount": 100,
|
||||||
|
"item_tax_amount": 0,
|
||||||
|
"landed_cost_voucher_amount": 0,
|
||||||
|
"sales_incoming_rate": 0,
|
||||||
|
"is_fixed_asset": is_fixed_asset,
|
||||||
|
"expense_account": expense_account,
|
||||||
|
"cost_center": "Main - _TC",
|
||||||
|
"project": None,
|
||||||
|
"precision": lambda fieldname: 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
"default_expense_account": None,
|
||||||
|
"stock_received_but_not_billed": "Stock Received But Not Billed - _TC",
|
||||||
|
"asset_received_but_not_billed": "Asset Received But Not Billed - _TC",
|
||||||
|
}
|
||||||
|
test_cases = (
|
||||||
|
(
|
||||||
|
"company default expense",
|
||||||
|
0,
|
||||||
|
make_item(),
|
||||||
|
{**defaults, "default_expense_account": "Default Expense - _TC"},
|
||||||
|
"Default Expense - _TC",
|
||||||
|
),
|
||||||
|
("stock rbnb", 0, make_item(), defaults, "Stock Received But Not Billed - _TC"),
|
||||||
|
(
|
||||||
|
"asset rbnb",
|
||||||
|
0,
|
||||||
|
make_item(is_fixed_asset=1),
|
||||||
|
defaults,
|
||||||
|
"Asset Received But Not Billed - _TC",
|
||||||
|
),
|
||||||
|
("return item expense", 1, make_item(), defaults, "Item Expense - _TC"),
|
||||||
|
(
|
||||||
|
"return without item expense",
|
||||||
|
1,
|
||||||
|
make_item(expense_account=None),
|
||||||
|
defaults,
|
||||||
|
"Stock Received But Not Billed - _TC",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for label, is_return, item, company_defaults, expected_account in test_cases:
|
||||||
|
with self.subTest(label=label):
|
||||||
|
invoice = make_invoice(is_return, company_defaults)
|
||||||
|
gl_entries = []
|
||||||
|
PurchaseInvoice.make_stock_adjustment_entry(
|
||||||
|
invoice, gl_entries, item, {(item.name, item.warehouse): 90}, "INR"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(gl_entries[0].account, expected_account)
|
||||||
|
self.assertEqual(gl_entries[0].debit, 10)
|
||||||
|
self.assertEqual(gl_entries[0].debit_in_transaction_currency, 10)
|
||||||
|
|
||||||
@ERPNextTestSuite.change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
|
@ERPNextTestSuite.change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
|
||||||
def test_purchase_invoice_advance_taxes(self):
|
def test_purchase_invoice_advance_taxes(self):
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
|
|||||||
Reference in New Issue
Block a user