refactor: use queue difference instead of actual values

This commit is contained in:
Ankush Menat
2022-02-19 20:58:36 +05:30
committed by Ankush Menat
parent aba7a7ce4e
commit b534fee2c7
3 changed files with 24 additions and 19 deletions

View File

@@ -19,7 +19,7 @@ from erpnext.stock.utils import (
get_or_make_bin, get_or_make_bin,
get_valuation_method, get_valuation_method,
) )
from erpnext.stock.valuation import FIFOValuation, LIFOValuation from erpnext.stock.valuation import FIFOValuation, LIFOValuation, round_off_if_near_zero
class NegativeStockError(frappe.ValidationError): pass class NegativeStockError(frappe.ValidationError): pass
@@ -465,7 +465,6 @@ class update_entries_after(object):
self.wh_data.stock_value = flt(self.wh_data.qty_after_transaction) * flt(self.wh_data.valuation_rate) self.wh_data.stock_value = flt(self.wh_data.qty_after_transaction) * flt(self.wh_data.valuation_rate)
else: else:
self.update_queue_values(sle) self.update_queue_values(sle)
self.wh_data.qty_after_transaction += flt(sle.actual_qty)
# rounding as per precision # rounding as per precision
self.wh_data.stock_value = flt(self.wh_data.stock_value, self.precision) self.wh_data.stock_value = flt(self.wh_data.stock_value, self.precision)
@@ -706,11 +705,15 @@ class update_entries_after(object):
actual_qty = flt(sle.actual_qty) actual_qty = flt(sle.actual_qty)
outgoing_rate = flt(sle.outgoing_rate) outgoing_rate = flt(sle.outgoing_rate)
self.wh_data.qty_after_transaction = round_off_if_near_zero(self.wh_data.qty_after_transaction + actual_qty)
if self.valuation_method == "LIFO": if self.valuation_method == "LIFO":
stock_queue = LIFOValuation(self.wh_data.stock_queue) stock_queue = LIFOValuation(self.wh_data.stock_queue)
else: else:
stock_queue = FIFOValuation(self.wh_data.stock_queue) stock_queue = FIFOValuation(self.wh_data.stock_queue)
_prev_qty, prev_stock_value = stock_queue.get_total_stock_and_value()
if actual_qty > 0: if actual_qty > 0:
stock_queue.add_stock(qty=actual_qty, rate=incoming_rate) stock_queue.add_stock(qty=actual_qty, rate=incoming_rate)
else: else:
@@ -723,17 +726,19 @@ class update_entries_after(object):
stock_queue.remove_stock(qty=abs(actual_qty), outgoing_rate=outgoing_rate, rate_generator=rate_generator) stock_queue.remove_stock(qty=abs(actual_qty), outgoing_rate=outgoing_rate, rate_generator=rate_generator)
stock_qty, stock_value = stock_queue.get_total_stock_and_value() _qty, stock_value = stock_queue.get_total_stock_and_value()
stock_value_difference = stock_value - prev_stock_value
self.wh_data.stock_queue = stock_queue.state self.wh_data.stock_queue = stock_queue.state
self.wh_data.stock_value = stock_value self.wh_data.stock_value = round_off_if_near_zero(self.wh_data.stock_value + stock_value_difference)
if stock_qty:
self.wh_data.valuation_rate = stock_value / stock_qty
if not self.wh_data.stock_queue: if not self.wh_data.stock_queue:
self.wh_data.stock_queue.append([0, sle.incoming_rate or sle.outgoing_rate or self.wh_data.valuation_rate]) self.wh_data.stock_queue.append([0, sle.incoming_rate or sle.outgoing_rate or self.wh_data.valuation_rate])
if self.wh_data.qty_after_transaction:
self.wh_data.valuation_rate = self.wh_data.stock_value / self.wh_data.qty_after_transaction
def update_batched_values(self, sle): def update_batched_values(self, sle):
incoming_rate = flt(sle.incoming_rate) incoming_rate = flt(sle.incoming_rate)
actual_qty = flt(sle.actual_qty) actual_qty = flt(sle.actual_qty)

View File

@@ -7,7 +7,7 @@ from hypothesis import strategies as st
from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
from erpnext.stock.valuation import FIFOValuation, LIFOValuation, _round_off_if_near_zero from erpnext.stock.valuation import FIFOValuation, LIFOValuation, round_off_if_near_zero
from erpnext.tests.utils import ERPNextTestCase from erpnext.tests.utils import ERPNextTestCase
qty_gen = st.floats(min_value=-1e6, max_value=1e6) qty_gen = st.floats(min_value=-1e6, max_value=1e6)
@@ -113,11 +113,11 @@ class TestFIFOValuation(unittest.TestCase):
self.assertTotalQty(0) self.assertTotalQty(0)
def test_rounding_off_near_zero(self): def test_rounding_off_near_zero(self):
self.assertEqual(_round_off_if_near_zero(0), 0) self.assertEqual(round_off_if_near_zero(0), 0)
self.assertEqual(_round_off_if_near_zero(1), 1) self.assertEqual(round_off_if_near_zero(1), 1)
self.assertEqual(_round_off_if_near_zero(-1), -1) self.assertEqual(round_off_if_near_zero(-1), -1)
self.assertEqual(_round_off_if_near_zero(-1e-8), 0) self.assertEqual(round_off_if_near_zero(-1e-8), 0)
self.assertEqual(_round_off_if_near_zero(1e-8), 0) self.assertEqual(round_off_if_near_zero(1e-8), 0)
def test_totals(self): def test_totals(self):
self.queue.add_stock(1, 10) self.queue.add_stock(1, 10)

View File

@@ -34,7 +34,7 @@ class BinWiseValuation(ABC):
total_qty += flt(qty) total_qty += flt(qty)
total_value += flt(qty) * flt(rate) total_value += flt(qty) * flt(rate)
return _round_off_if_near_zero(total_qty), _round_off_if_near_zero(total_value) return round_off_if_near_zero(total_qty), round_off_if_near_zero(total_value)
def __repr__(self): def __repr__(self):
return str(self.state) return str(self.state)
@@ -136,7 +136,7 @@ class FIFOValuation(BinWiseValuation):
fifo_bin = self.queue[index] fifo_bin = self.queue[index]
if qty >= fifo_bin[QTY]: if qty >= fifo_bin[QTY]:
# consume current bin # consume current bin
qty = _round_off_if_near_zero(qty - fifo_bin[QTY]) qty = round_off_if_near_zero(qty - fifo_bin[QTY])
to_consume = self.queue.pop(index) to_consume = self.queue.pop(index)
consumed_bins.append(list(to_consume)) consumed_bins.append(list(to_consume))
@@ -148,7 +148,7 @@ class FIFOValuation(BinWiseValuation):
break break
else: else:
# qty found in current bin consume it and exit # qty found in current bin consume it and exit
fifo_bin[QTY] = _round_off_if_near_zero(fifo_bin[QTY] - qty) fifo_bin[QTY] = round_off_if_near_zero(fifo_bin[QTY] - qty)
consumed_bins.append([qty, fifo_bin[RATE]]) consumed_bins.append([qty, fifo_bin[RATE]])
qty = 0 qty = 0
@@ -231,7 +231,7 @@ class LIFOValuation(BinWiseValuation):
stock_bin = self.stack[index] stock_bin = self.stack[index]
if qty >= stock_bin[QTY]: if qty >= stock_bin[QTY]:
# consume current bin # consume current bin
qty = _round_off_if_near_zero(qty - stock_bin[QTY]) qty = round_off_if_near_zero(qty - stock_bin[QTY])
to_consume = self.stack.pop(index) to_consume = self.stack.pop(index)
consumed_bins.append(list(to_consume)) consumed_bins.append(list(to_consume))
@@ -243,14 +243,14 @@ class LIFOValuation(BinWiseValuation):
break break
else: else:
# qty found in current bin consume it and exit # qty found in current bin consume it and exit
stock_bin[QTY] = _round_off_if_near_zero(stock_bin[QTY] - qty) stock_bin[QTY] = round_off_if_near_zero(stock_bin[QTY] - qty)
consumed_bins.append([qty, stock_bin[RATE]]) consumed_bins.append([qty, stock_bin[RATE]])
qty = 0 qty = 0
return consumed_bins return consumed_bins
def _round_off_if_near_zero(number: float, precision: int = 7) -> float: def round_off_if_near_zero(number: float, precision: int = 7) -> float:
"""Rounds off the number to zero only if number is close to zero for decimal """Rounds off the number to zero only if number is close to zero for decimal
specified in precision. Precision defaults to 7. specified in precision. Precision defaults to 7.
""" """