refactor: get incoming fifo/lifo rate functions
Re-use same logic for computing incoming rate.
This commit is contained in:
parent
97e18a1cd0
commit
61c5ad44d3
@ -9,6 +9,7 @@ from frappe import _
|
||||
from frappe.utils import cstr, flt, get_link_to_form, nowdate, nowtime
|
||||
|
||||
import erpnext
|
||||
from erpnext.stock.valuation import FIFOValuation, LIFOValuation
|
||||
|
||||
|
||||
class InvalidWarehouseCompany(frappe.ValidationError): pass
|
||||
@ -228,10 +229,10 @@ def get_incoming_rate(args, raise_error_if_no_rate=True):
|
||||
else:
|
||||
valuation_method = get_valuation_method(args.get("item_code"))
|
||||
previous_sle = get_previous_sle(args)
|
||||
if valuation_method == 'FIFO':
|
||||
if valuation_method in ('FIFO', 'LIFO'):
|
||||
if previous_sle:
|
||||
previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]') or '[]')
|
||||
in_rate = get_fifo_rate(previous_stock_queue, args.get("qty") or 0) if previous_stock_queue else 0
|
||||
in_rate = _get_fifo_lifo_rate(previous_stock_queue, args.get("qty") or 0, valuation_method) if previous_stock_queue else 0
|
||||
elif valuation_method == 'Moving Average':
|
||||
in_rate = previous_sle.get('valuation_rate') or 0
|
||||
|
||||
@ -261,29 +262,25 @@ def get_valuation_method(item_code):
|
||||
|
||||
def get_fifo_rate(previous_stock_queue, qty):
|
||||
"""get FIFO (average) Rate from Queue"""
|
||||
if flt(qty) >= 0:
|
||||
total = sum(f[0] for f in previous_stock_queue)
|
||||
return sum(flt(f[0]) * flt(f[1]) for f in previous_stock_queue) / flt(total) if total else 0.0
|
||||
else:
|
||||
available_qty_for_outgoing, outgoing_cost = 0, 0
|
||||
qty_to_pop = abs(flt(qty))
|
||||
while qty_to_pop and previous_stock_queue:
|
||||
batch = previous_stock_queue[0]
|
||||
if 0 < batch[0] <= qty_to_pop:
|
||||
# if batch qty > 0
|
||||
# not enough or exactly same qty in current batch, clear batch
|
||||
available_qty_for_outgoing += flt(batch[0])
|
||||
outgoing_cost += flt(batch[0]) * flt(batch[1])
|
||||
qty_to_pop -= batch[0]
|
||||
previous_stock_queue.pop(0)
|
||||
else:
|
||||
# all from current batch
|
||||
available_qty_for_outgoing += flt(qty_to_pop)
|
||||
outgoing_cost += flt(qty_to_pop) * flt(batch[1])
|
||||
batch[0] -= qty_to_pop
|
||||
qty_to_pop = 0
|
||||
return _get_fifo_lifo_rate(previous_stock_queue, qty, "FIFO")
|
||||
|
||||
return outgoing_cost / available_qty_for_outgoing
|
||||
def get_lifo_rate(previous_stock_queue, qty):
|
||||
"""get LIFO (average) Rate from Queue"""
|
||||
return _get_fifo_lifo_rate(previous_stock_queue, qty, "LIFO")
|
||||
|
||||
|
||||
def _get_fifo_lifo_rate(previous_stock_queue, qty, method):
|
||||
ValuationKlass = LIFOValuation if method == "LIFO" else FIFOValuation
|
||||
|
||||
stock_queue = ValuationKlass(previous_stock_queue)
|
||||
if flt(qty) >= 0:
|
||||
total_qty, total_value = stock_queue.get_total_stock_and_value()
|
||||
return total_value / total_qty if total_qty else 0.0
|
||||
else:
|
||||
popped_bins = stock_queue.remove_stock(abs(flt(qty)))
|
||||
|
||||
total_qty, total_value = ValuationKlass(popped_bins).get_total_stock_and_value()
|
||||
return total_value / total_qty if total_qty else 0.0
|
||||
|
||||
def get_valid_serial_nos(sr_nos, qty=0, item_code=''):
|
||||
"""split serial nos, validate and return list of valid serial nos"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user