stock reco fixes with testcases

This commit is contained in:
Nabin Hait
2013-01-11 19:25:46 +05:30
parent 4dc7caadf2
commit ac53b11969
12 changed files with 245 additions and 269 deletions

View File

@@ -31,18 +31,34 @@ class DocType:
self.doc = doc
self.doclist = doclist
def validate(self):
if not self.doc.stock_uom:
self.doc.stock_uom = webnotes.conn.get_value('Item', self.doc.item_code, 'stock_uom')
if not self.doc.warehouse_type:
self.doc.warehouse_type = webnotes.conn.get_value("Warehouse", self.doc.warehouse,
"warehouse_type")
self.validate_mandatory()
self.doc.projected_qty = flt(self.doc.actual_qty) + flt(self.doc.ordered_qty) + \
flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
def validate_mandatory(self):
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
for f in qf:
if (not self.doc.fields.has_key(f)) or (not self.doc.fields[f]):
self.doc.fields[f] = 0.0
def update_stock(self, args):
from stock.stock_ledger import update_entries_after
if not args.get("posting_date"):
posting_date = nowdate()
self.update_qty(args)
if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
if args.get("actual_qty"):
from stock.stock_ledger import update_entries_after
if not args.get("posting_date"):
posting_date = nowdate()
# update valuation and qty after transaction for post dated entry
update_entries_after({
"item_code": self.doc.item_code,
@@ -53,8 +69,8 @@ class DocType:
def update_qty(self, args):
# update the stock values (for current quantities)
self.doc.actual_qty = flt(self.doc.actual_qty) + flt(args.get("actual_qty", 0))
self.doc.ordered_qty = flt(self.doc.ordered_qty) + flt(args.get("ordered_qty", 0))
self.doc.actual_qty = flt(self.doc.actual_qty) + flt(args.get("actual_qty"))
self.doc.ordered_qty = flt(self.doc.ordered_qty) + flt(args.get("ordered_qty"))
self.doc.reserved_qty = flt(self.doc.reserved_qty) + flt(args.get("reserved_qty"))
self.doc.indented_qty = flt(self.doc.indented_qty) + flt(args.get("indented_qty"))
self.doc.planned_qty = flt(self.doc.planned_qty) + flt(args.get("planned_qty"))
@@ -63,6 +79,10 @@ class DocType:
flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
self.doc.save()
if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
def get_first_sle(self):
sle = sql("""
@@ -75,111 +95,6 @@ class DocType:
""", (self.doc.item_code, self.doc.warehouse), as_dict=1)
return sle and sle[0] or None
# def get_serialized_inventory_values(self, val_rate, in_rate, opening_qty, \
# actual_qty, is_cancelled, serial_nos):
# """
# get serialized inventory values
# """
# if flt(in_rate) < 0: # wrong incoming rate
# in_rate = val_rate
# elif flt(in_rate) == 0 or flt(actual_qty) < 0:
# # In case of delivery/stock issue, get average purchase rate
# # of serial nos of current entry
# in_rate = flt(sql("""select ifnull(avg(purchase_rate), 0)
# from `tabSerial No` where name in (%s)""" % (serial_nos))[0][0])
#
# if in_rate and val_rate == 0: # First entry
# val_rate = in_rate
# # val_rate is same as previous entry if val_rate is negative
# # Otherwise it will be calculated as per moving average
# elif opening_qty + actual_qty > 0 and ((opening_qty * val_rate) + \
# (actual_qty * in_rate)) > 0:
# val_rate = ((opening_qty *val_rate) + (actual_qty * in_rate)) / \
# (opening_qty + actual_qty)
# return val_rate, in_rate
#
# def get_moving_average_inventory_values(self, val_rate, in_rate, opening_qty, actual_qty, is_cancelled):
# if flt(in_rate) == 0 or flt(actual_qty) < 0:
# # In case of delivery/stock issue in_rate = 0 or wrong incoming rate
# in_rate = val_rate
#
# # val_rate is same as previous entry if :
# # 1. actual qty is negative(delivery note / stock entry)
# # 2. cancelled entry
# # 3. val_rate is negative
# # Otherwise it will be calculated as per moving average
# if actual_qty > 0 and (opening_qty + actual_qty) > 0 and is_cancelled == 'No' \
# and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0:
# opening_qty = opening_qty > 0 and opening_qty or 0
# val_rate = ((opening_qty *val_rate) + (actual_qty * in_rate)) / \
# (opening_qty + actual_qty)
# elif (opening_qty + actual_qty) <= 0:
# val_rate = 0
# return val_rate, in_rate
#
# def get_fifo_inventory_values(self, in_rate, actual_qty):
# # add batch to fcfs balance
# if actual_qty > 0:
# self.fcfs_bal.append([flt(actual_qty), flt(in_rate)])
#
# # remove from fcfs balance
# else:
# incoming_cost = 0
# withdraw = flt(abs(actual_qty))
# while withdraw:
# if not self.fcfs_bal:
# break # nothing in store
#
# batch = self.fcfs_bal[0]
#
# if batch[0] <= withdraw:
# # not enough or exactly same qty in current batch, clear batch
# incoming_cost += flt(batch[1])*flt(batch[0])
# withdraw -= batch[0]
# self.fcfs_bal.pop(0)
#
#
# else:
# # all from current batch
# incoming_cost += flt(batch[1])*flt(withdraw)
# batch[0] -= withdraw
# withdraw = 0
#
# in_rate = incoming_cost / flt(abs(actual_qty))
#
# fcfs_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
# fcfs_qty = sum([flt(d[0]) for d in self.fcfs_bal])
# val_rate = fcfs_qty and fcfs_val / fcfs_qty or 0
#
# return val_rate, in_rate
#
# def get_valuation_rate(self, val_method, serial_nos, val_rate, in_rate, stock_val, cqty, s):
# if serial_nos:
# val_rate, in_rate = self.get_serialized_inventory_values( \
# val_rate, in_rate, opening_qty = cqty, actual_qty = s['actual_qty'], \
# is_cancelled = s['is_cancelled'], serial_nos = serial_nos)
# elif val_method == 'Moving Average':
# val_rate, in_rate = self.get_moving_average_inventory_values( \
# val_rate, in_rate, opening_qty = cqty, actual_qty = s['actual_qty'], \
# is_cancelled = s['is_cancelled'])
# elif val_method == 'FIFO':
# val_rate, in_rate = self.get_fifo_inventory_values(in_rate, \
# actual_qty = s['actual_qty'])
# return val_rate, in_rate
# def get_stock_value(self, val_method, cqty, val_rate, serial_nos):
# if serial_nos:
# stock_val = flt(val_rate) * flt(cqty)
# elif val_method == 'Moving Average':
# stock_val = flt(cqty) > 0 and flt(val_rate) * flt(cqty) or 0
# elif val_method == 'FIFO':
# stock_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
# return stock_val
def reorder_item(self,doc_type,doc_name):
""" Reorder item if stock reaches reorder level"""
@@ -246,12 +161,3 @@ class DocType:
msg="""A Purchase Request has been raised
for item %s: %s on %s """ % (doc_type, doc_name, nowdate())
sendmail(email_list, subject='Auto Purchase Request Generation Notification', msg = msg)
def validate(self):
self.validate_mandatory()
def validate_mandatory(self):
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
for f in qf:
if (not self.doc.fields.has_key(f)) or (not self.doc.fields[f]):
self.doc.fields[f] = 0.0