mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-05 21:29:11 +00:00
Maintain negative stock balance if balance qty is negative
This commit is contained in:
@@ -106,18 +106,19 @@ def update_entries_after(args, verbose=1):
|
||||
stock_queue = [[qty_after_transaction, valuation_rate]]
|
||||
else:
|
||||
if valuation_method == "Moving Average":
|
||||
valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate)
|
||||
if flt(sle.actual_qty) > 0:
|
||||
valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate)
|
||||
else:
|
||||
valuation_rate = get_fifo_values(qty_after_transaction, sle, stock_queue)
|
||||
|
||||
|
||||
qty_after_transaction += flt(sle.actual_qty)
|
||||
|
||||
# get stock value
|
||||
if sle.serial_no:
|
||||
stock_value = qty_after_transaction * valuation_rate
|
||||
elif valuation_method == "Moving Average":
|
||||
stock_value = (qty_after_transaction > 0) and \
|
||||
(qty_after_transaction * valuation_rate) or 0
|
||||
stock_value = qty_after_transaction * valuation_rate
|
||||
else:
|
||||
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
||||
|
||||
@@ -256,64 +257,73 @@ def get_moving_average_values(qty_after_transaction, sle, valuation_rate):
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
|
||||
if not incoming_rate:
|
||||
# In case of delivery/stock issue in_rate = 0 or wrong incoming rate
|
||||
# If wrong incoming rate
|
||||
incoming_rate = valuation_rate
|
||||
|
||||
elif qty_after_transaction < 0:
|
||||
elif qty_after_transaction < 0 and not valuation_rate:
|
||||
# if negative stock, take current valuation rate as incoming rate
|
||||
valuation_rate = incoming_rate
|
||||
|
||||
new_stock_qty = qty_after_transaction + actual_qty
|
||||
new_stock_value = qty_after_transaction * valuation_rate + actual_qty * incoming_rate
|
||||
new_stock_qty = abs(qty_after_transaction) + actual_qty
|
||||
new_stock_value = (abs(qty_after_transaction) * valuation_rate) + (actual_qty * incoming_rate)
|
||||
|
||||
if new_stock_qty > 0 and new_stock_value > 0:
|
||||
if new_stock_qty:
|
||||
valuation_rate = new_stock_value / flt(new_stock_qty)
|
||||
elif new_stock_qty <= 0:
|
||||
valuation_rate = 0.0
|
||||
|
||||
# NOTE: val_rate is same as previous entry if new stock value is negative
|
||||
|
||||
return valuation_rate
|
||||
return abs(valuation_rate)
|
||||
|
||||
def get_fifo_values(qty_after_transaction, sle, stock_queue):
|
||||
incoming_rate = flt(sle.incoming_rate)
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
if not stock_queue:
|
||||
stock_queue.append([0, 0])
|
||||
|
||||
intialize_stock_queue(stock_queue, sle.item_code, sle.warehouse)
|
||||
|
||||
if actual_qty > 0:
|
||||
if stock_queue[-1][0] > 0:
|
||||
stock_queue.append([actual_qty, incoming_rate])
|
||||
else:
|
||||
qty = stock_queue[-1][0] + actual_qty
|
||||
stock_queue[-1] = [qty, qty > 0 and incoming_rate or 0]
|
||||
if qty == 0:
|
||||
stock_queue.pop(-1)
|
||||
else:
|
||||
stock_queue[-1] = [qty, incoming_rate]
|
||||
else:
|
||||
incoming_cost = 0
|
||||
qty_to_pop = abs(actual_qty)
|
||||
while qty_to_pop:
|
||||
if not stock_queue:
|
||||
stock_queue.append([0, 0])
|
||||
intialize_stock_queue(stock_queue, sle.item_code, sle.warehouse)
|
||||
|
||||
batch = 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
|
||||
incoming_cost += flt(batch[0]) * flt(batch[1])
|
||||
qty_to_pop -= batch[0]
|
||||
# print qty_to_pop, batch
|
||||
|
||||
if qty_to_pop >= batch[0]:
|
||||
# consume current batch
|
||||
qty_to_pop = qty_to_pop - batch[0]
|
||||
stock_queue.pop(0)
|
||||
if not stock_queue and qty_to_pop:
|
||||
# stock finished, qty still remains to be withdrawn
|
||||
# negative stock, keep in as a negative batch
|
||||
stock_queue.append([-qty_to_pop, batch[1]])
|
||||
break
|
||||
|
||||
else:
|
||||
# all from current batch
|
||||
incoming_cost += flt(qty_to_pop) * flt(batch[1])
|
||||
batch[0] -= qty_to_pop
|
||||
# qty found in current batch
|
||||
# consume it and exit
|
||||
batch[0] = batch[0] - qty_to_pop
|
||||
qty_to_pop = 0
|
||||
|
||||
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
||||
stock_qty = sum((flt(batch[0]) for batch in stock_queue))
|
||||
|
||||
valuation_rate = stock_qty and (stock_value / flt(stock_qty)) or 0
|
||||
valuation_rate = (stock_value / flt(stock_qty)) if stock_qty else 0
|
||||
|
||||
return valuation_rate
|
||||
return abs(valuation_rate)
|
||||
|
||||
def intialize_stock_queue(stock_queue, item_code, warehouse):
|
||||
if not stock_queue:
|
||||
from erpnext.controllers.stock_controller import get_valuation_rate
|
||||
estimated_val_rate = get_valuation_rate(item_code, warehouse)
|
||||
stock_queue.append([0, estimated_val_rate])
|
||||
|
||||
def _raise_exceptions(args, verbose=1):
|
||||
deficiency = min(e["diff"] for e in _exceptions)
|
||||
|
||||
Reference in New Issue
Block a user