mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-09 15:29:30 +00:00
fix: user not able to set valuation rate zero in stock reco (#58800)
* fix: user not able to set valuation rate zero in stock reco
* fix: wrong difference amount when valuation rate is zero
* fix: blank valuation rate should not be treated as a change
(cherry picked from commit e85e300f8f)
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
This commit is contained in:
@@ -532,7 +532,10 @@ class StockReconciliation(StockController):
|
||||
|
||||
rate_precision = item.precision("valuation_rate")
|
||||
rate = flt(item_dict.get("rate"), rate_precision)
|
||||
valuation_rate = flt(item.valuation_rate, rate_precision) if item.valuation_rate else None
|
||||
# an unset rate means "keep the current one", an explicit zero is a real revaluation
|
||||
valuation_rate = (
|
||||
flt(item.valuation_rate, rate_precision) if item.valuation_rate not in ("", None) else None
|
||||
)
|
||||
if (
|
||||
(item.qty is None or item.qty == item_dict.get("qty"))
|
||||
and (valuation_rate is None or valuation_rate == rate)
|
||||
@@ -575,7 +578,10 @@ class StockReconciliation(StockController):
|
||||
amount_precision = item.precision("amount")
|
||||
|
||||
new_qty = flt(item.qty, qty_precision)
|
||||
new_valuation_rate = flt(item.valuation_rate or item_dict.get("rate"))
|
||||
# an explicitly set zero rate is a real revaluation, don't fall back to the current rate
|
||||
new_valuation_rate = flt(
|
||||
item.valuation_rate if item.valuation_rate not in ("", None) else item_dict.get("rate")
|
||||
)
|
||||
|
||||
current_qty = flt(item_dict.get("qty"), qty_precision)
|
||||
current_valuation_rate = flt(item_dict.get("rate"))
|
||||
|
||||
@@ -27,6 +27,7 @@ from erpnext.stock.tests.test_utils import StockTestMixin
|
||||
from erpnext.stock.utils import (
|
||||
get_combine_datetime,
|
||||
get_incoming_rate,
|
||||
get_stock_balance,
|
||||
get_stock_value_on,
|
||||
get_valuation_method,
|
||||
)
|
||||
@@ -1588,6 +1589,85 @@ class TestStockReconciliation(ERPNextTestSuite, StockTestMixin):
|
||||
self.assertEqual(sr.difference_amount, 100 * -1)
|
||||
self.assertTrue(sr.items[0].qty == 0)
|
||||
|
||||
def test_difference_amount_for_zero_valuation_rate(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
item_code = self.make_item("Test Item Stock Reco Zero Valuation Rate").name
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
|
||||
make_stock_entry(item_code=item_code, target=warehouse, qty=5, basic_rate=100)
|
||||
|
||||
sr = create_stock_reconciliation(
|
||||
item_code=item_code, warehouse=warehouse, qty=5, rate=0, do_not_save=1
|
||||
)
|
||||
sr.items[0].allow_zero_valuation_rate = 1
|
||||
sr.save()
|
||||
|
||||
# qty is unchanged, the stock is revalued from 5 x 100 to 5 x 0
|
||||
self.assertEqual(sr.items[0].current_valuation_rate, 100)
|
||||
self.assertEqual(sr.items[0].valuation_rate, 0)
|
||||
self.assertEqual(sr.difference_amount, -500)
|
||||
|
||||
sr.submit()
|
||||
sr.reload()
|
||||
|
||||
self.assertEqual(sr.difference_amount, -500)
|
||||
self.assertEqual(
|
||||
frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{"voucher_no": sr.name, "is_cancelled": 0},
|
||||
"stock_value_difference",
|
||||
),
|
||||
-500,
|
||||
)
|
||||
|
||||
def test_no_change_row_removed_when_valuation_rate_is_blank(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
item_code = self.make_item("Test Item Stock Reco Blank Valuation Rate").name
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
|
||||
make_stock_entry(item_code=item_code, target=warehouse, qty=5, basic_rate=100)
|
||||
|
||||
sr = create_stock_reconciliation(
|
||||
item_code=item_code, warehouse=warehouse, qty=5, rate=None, do_not_save=1
|
||||
)
|
||||
|
||||
# a blank rate means "keep the current rate", so nothing changed on this row
|
||||
self.assertRaises(EmptyStockReconciliationItemsError, sr.save)
|
||||
|
||||
def test_set_existing_stock_valuation_to_zero(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
item_code = self.make_item("Test Item Stock Reco Set Valuation Zero").name
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
|
||||
make_stock_entry(item_code=item_code, target=warehouse, qty=10, basic_rate=50)
|
||||
|
||||
sr = create_stock_reconciliation(
|
||||
item_code=item_code, warehouse=warehouse, qty=10, rate=0, do_not_save=1
|
||||
)
|
||||
sr.items[0].allow_zero_valuation_rate = 1
|
||||
|
||||
# only the rate changes, the row must not be dropped as "no change"
|
||||
sr.save()
|
||||
self.assertEqual(len(sr.items), 1)
|
||||
|
||||
sr.submit()
|
||||
|
||||
sle = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{"voucher_no": sr.name, "is_cancelled": 0},
|
||||
["qty_after_transaction", "valuation_rate", "stock_value"],
|
||||
as_dict=True,
|
||||
)
|
||||
|
||||
self.assertEqual(sle.qty_after_transaction, 10)
|
||||
self.assertEqual(sle.valuation_rate, 0)
|
||||
self.assertEqual(sle.stock_value, 0)
|
||||
|
||||
self.assertEqual(get_stock_balance(item_code, warehouse, with_valuation_rate=True), (10, 0.0))
|
||||
|
||||
def test_stock_reco_recalculate_qty_for_backdated_entry(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
Reference in New Issue
Block a user