Browse Source

Fetch actual stock and rate in stock entry as per fifo

develop
nabinhait 14 years ago
parent
commit
e79f87c5f7
  1. BIN
      material_management/__init__.pyc
  2. BIN
      material_management/doctype/__init__.pyc
  3. BIN
      material_management/doctype/bin/__init__.pyc
  4. BIN
      material_management/doctype/bin/bin.pyc
  5. BIN
      material_management/doctype/stock_entry/__init__.pyc
  6. BIN
      material_management/doctype/stock_entry/stock_entry.pyc
  7. 429
      material_management/doctype/stock_entry/stock_entry.py~
  8. BIN
      material_management/doctype/stock_entry_detail/__init__.pyc
  9. BIN
      material_management/doctype/stock_ledger/__init__.pyc
  10. BIN
      material_management/doctype/stock_ledger/stock_ledger.pyc
  11. BIN
      material_management/doctype/stock_ledger_entry/__init__.pyc
  12. BIN
      material_management/doctype/stock_ledger_entry/stock_ledger_entry.pyc
  13. BIN
      material_management/doctype/valuation_control/__init__.pyc
  14. BIN
      material_management/doctype/valuation_control/valuation_control.pyc
  15. 87
      material_management/doctype/valuation_control/valuation_control.py~
  16. BIN
      material_management/doctype/warehouse/__init__.pyc
  17. BIN
      material_management/doctype/warehouse/warehouse.pyc

BIN
material_management/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/bin/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/bin/bin.pyc

Binary file not shown.

BIN
material_management/doctype/stock_entry/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/stock_entry/stock_entry.pyc

Binary file not shown.

429
material_management/doctype/stock_entry/stock_entry.py~

@ -0,0 +1,429 @@
# Please edit this list and import only required elements
import webnotes
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists, delete_doc
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
from webnotes import session, form, is_testing, msgprint, errprint
set = webnotes.conn.set
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
in_transaction = webnotes.conn.in_transaction
convert_to_lists = webnotes.conn.convert_to_lists
# -----------------------------------------------------------------------------------------
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.item_dict = {}
self.fname = 'mtn_details'
# Autoname
# ---------
def autoname(self):
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
# get item details
# ----------------
def get_item_details(self, arg):
arg, actual_qty, in_rate = eval(arg), 0, 0
item = sql("select stock_uom, description, item_name from `tabItem` where name = %s and (ifnull(end_of_life,'')='' or end_of_life ='0000-00-00' or end_of_life > now())", (arg.get('item_code')), as_dict = 1)
if not item:
msgprint("Item is not active", raise_exception=1)
if arg.get('warehouse'):
actual_qty = self.get_as_on_stock(arg.get('item_code'), arg.get('warehouse'), self.doc.posting_date, self.doc.posting_time)
in_rate = self.get_incoming_rate(arg.get('item_code'), arg.get('warehouse'), self.doc.posting_date, self.doc.posting_time, arg.get('transfer_qty'), arg.get('serial_no')) or 0
ret = {
'uom' : item and item[0]['stock_uom'] or '',
'stock_uom' : item and item[0]['stock_uom'] or '',
'description' : item and item[0]['description'] or '',
'item_name' : item and item[0]['item_name'] or '',
'actual_qty' : actual_qty,
'qty' : 0,
'transfer_qty' : 0,
'incoming_rate' : in_rate,
'conversion_factor' : 1,
'batch_no' : ''
}
return str(ret)
# Get UOM Details
# ----------------
def get_uom_details(self, arg = ''):
arg, ret = eval(arg), {}
uom = sql("select conversion_factor from `tabUOM Conversion Detail` where parent = %s and uom = %s", (arg['item_code'],arg['uom']), as_dict = 1)
if not uom:
msgprint("There is no Conversion Factor for UOM '%s' in Item '%s'" % (arg['uom'], arg['item_code']))
ret = {'uom' : ''}
else:
ret = {
'conversion_factor' : flt(uom[0]['conversion_factor']),
'transfer_qty' : flt(arg['qty']) * flt(uom[0]['conversion_factor']),
}
return str(ret)
# get stock and incoming rate on posting date
# ---------------------------------------------
def get_stock_and_rate(self, bom_no = ''):
for d in getlist(self.doclist, 'mtn_details'):
# assign parent warehouse
d.s_warehouse = cstr(d.s_warehouse) or self.doc.purpose != 'Production Order' and self.doc.from_warehouse or ''
d.t_warehouse = cstr(d.t_warehouse) or self.doc.purpose != 'Production Order' and self.doc.to_warehouse or ''
# get current stock at source warehouse
d.actual_qty = d.s_warehouse and self.get_as_on_stock(d.item_code, d.s_warehouse, self.doc.posting_date, self.doc.posting_time) or 0
# get incoming rate
if not flt(d.incoming_rate):
msgprint(1)
d.incoming_rate = self.get_incoming_rate(d.item_code, d.s_warehouse, self.doc.posting_date, self.doc.posting_time, d.transfer_qty, d.serial_no, d.fg_item, bom_no)
# Get stock qty on any date
# ---------------------------
def get_as_on_stock(self, item, wh, dt, tm):
bin = sql("select name from tabBin where item_code = %s and warehouse = %s", (item, wh))
bin_id = bin and bin[0][0] or ''
prev_sle = get_obj('Bin', bin_id).get_prev_sle(dt, tm)
qty = flt(prev_sle.get('bin_aqat', 0))
return qty
# Get incoming rate
# -------------------
def get_incoming_rate(self, item, wh, dt, tm, qty = 0, serial_no = '', fg_item = 'No', bom_no = ''):
msgprint(wh)
in_rate = 0
if fg_item == 'Yes':
# re-calculate cost for production item from bom
get_obj('BOM Control').calculate_cost(bom_no)
in_rate = get_value('Bill Of Materials', bom_no, 'cost_as_per_mar')
elif wh:
msgprint(1)
in_rate = get_obj('Valuation Control').get_incoming_rate(dt, tm, item, wh, qty, serial_no)
return in_rate
# makes dict of unique items with it's qty
#-----------------------------------------
def make_items_dict(self, items_list):
# items_list = [[item_name, qty]]
for i in items_list:
if self.item_dict.has_key(i[0]):
self.item_dict[i[0]][0] = flt(self.item_dict[i[0]][0]) + flt(i[1])
else:
self.item_dict[i[0]] = [flt(i[1]), cstr(i[2]), cstr(i[3])]
def get_raw_materials(self,pro_obj):
# get all items from flat bom except, child items of sub-contracted and sub assembly items and sub assembly items itself.
flat_bom_items = sql("select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom from `tabFlat BOM Detail` where parent = '%s' and parent_bom = '%s' and is_pro_applicable = 'No' and docstatus < 2 group by item_code" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no)))
self.make_items_dict(flat_bom_items)
if pro_obj.doc.consider_sa_items == 'Yes':
# get all Sub Assembly items only from flat bom
fl_bom_sa_items = sql("select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom from `tabFlat BOM Detail` where parent = '%s' and parent_bom != '%s' and is_pro_applicable = 'Yes' and docstatus < 2 group by item_code" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no)))
self.make_items_dict(fl_bom_sa_items)
if pro_obj.doc.consider_sa_items == 'No':
# get all sub assembly childs only from flat bom
fl_bom_sa_child_item = sql("select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom from `tabFlat BOM Detail` where parent = '%s' and parent_bom in (select distinct parent_bom from `tabFlat BOM Detail` where parent = '%s' and parent_bom != '%s' and is_pro_applicable = 'Yes' and docstatus < 2 ) and is_pro_applicable = 'No' and docstatus < 2 group by item_code" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no)))
self.make_items_dict(fl_bom_sa_child_item)
def add_to_stock_entry_detail(self, pro_obj, item_dict, fg_item = 0):
sw, tw = '', ''
if self.doc.process == 'Material Transfer':
tw = cstr(pro_obj.doc.wip_warehouse)
if self.doc.process == 'Backflush':
tw = fg_item and cstr(pro_obj.doc.fg_warehouse) or ''
if not fg_item: sw = cstr(pro_obj.doc.wip_warehouse)
for d in item_dict:
se_child = addchild(self.doc, 'mtn_details', 'Stock Entry Detail', 0, self.doclist)
se_child.s_warehouse = sw
se_child.t_warehouse = tw
se_child.fg_item = fg_item
se_child.item_code = cstr(d)
se_child.description = item_dict[d][1]
se_child.uom = item_dict[d][2]
se_child.stock_uom = item_dict[d][2]
se_child.reqd_qty = flt(item_dict[d][0])
se_child.qty = flt(item_dict[d][0])
se_child.transfer_qty = flt(item_dict[d][0])
se_child.conversion_factor = 1.00
# get items
#------------------
def get_items(self):
pro_obj = self.doc.production_order and get_obj('Production Order', self.doc.production_order) or ''
self.validate_for_production_order(pro_obj)
self.get_raw_materials(pro_obj)
self.doc.clear_table(self.doclist, 'mtn_details', 1)
self.add_to_stock_entry_detail(pro_obj, self.item_dict)
if self.doc.process == 'Backflush':
item_dict = {cstr(pro_obj.doc.production_item) : [self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom]}
self.add_to_stock_entry_detail(pro_obj, item_dict, fg_item = 1)
def validate_transfer_qty(self):
for d in getlist(self.doclist, 'mtn_details'):
if flt(d.transfer_qty) <= 0:
msgprint("Transfer Quantity can not be less than or equal to zero at Row No " + cstr(d.idx))
raise Exception
if d.s_warehouse:
if flt(d.transfer_qty) > flt(d.actual_qty):
msgprint("Transfer Quantity is more than Available Qty at Row No " + cstr(d.idx))
raise Exception
def calc_amount(self):
total_amount = 0
for d in getlist(self.doclist, 'mtn_details'):
d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
total_amount += flt(d.amount)
self.doc.total_amount = flt(total_amount)
def add_to_values(self, d, wh, qty, is_cancelled):
self.values.append({
'item_code' : d.item_code,
'warehouse' : wh,
'transaction_date' : self.doc.transfer_date,
'posting_date' : self.doc.posting_date,
'posting_time' : self.doc.posting_time,
'voucher_type' : 'Stock Entry',
'voucher_no' : self.doc.name,
'voucher_detail_no' : d.name,
'actual_qty' : qty,
'incoming_rate' : flt(d.incoming_rate) or 0,
'stock_uom' : d.stock_uom,
'company' : self.doc.company,
'fiscal_year' : self.doc.fiscal_year,
'is_cancelled' : (is_cancelled ==1) and 'Yes' or 'No',
'batch_no' : d.batch_no,
'serial_no' : d.serial_no
})
def update_stock_ledger(self, is_cancelled=0):
self.values = []
for d in getlist(self.doclist, 'mtn_details'):
if cstr(d.s_warehouse):
self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled)
if cstr(d.t_warehouse):
self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
def validate_for_production_order(self, pro_obj):
if self.doc.purpose == 'Production Order' or self.doc.process or self.doc.production_order or flt(self.doc.fg_completed_qty):
if self.doc.purpose != 'Production Order':
msgprint("Purpose should be 'Production Order'.")
raise Exception
if not self.doc.process:
msgprint("Process Field is mandatory.")
raise Exception
if self.doc.process == 'Backflush' and not flt(self.doc.fg_completed_qty):
msgprint("FG Completed Qty is mandatory as the process selected is 'Backflush'")
raise Exception
if self.doc.process == 'Material Transfer' and flt(self.doc.fg_completed_qty):
msgprint("FG Completed Qty should be zero. As the Process selected is 'Material Transfer'.")
raise Exception
if not self.doc.production_order:
msgprint("Production Order field is mandatory")
raise Exception
if flt(pro_obj.doc.qty) < flt(pro_obj.doc.produced_qty) + flt(self.doc.fg_completed_qty) :
msgprint("error:Already Produced Qty for %s is %s and maximum allowed Qty is %s" % (pro_obj.doc.production_item, cstr(pro_obj.doc.produced_qty) or 0.00 , cstr(pro_obj.doc.qty)))
raise Exception
# Validate
# ------------------
def validate(self):
sl_obj = get_obj("Stock Ledger", "Stock Ledger")
sl_obj.scrub_serial_nos(self)
sl_obj.validate_serial_no(self, 'mtn_details')
pro_obj = ''
if self.doc.production_order:
pro_obj = get_obj('Production Order', self.doc.production_order)
self.validate_for_production_order(pro_obj)
self.validate_incoming_rate()
self.validate_warehouse(pro_obj)
self.get_stock_and_rate(pro_obj and pro_obj.doc.bom_no or '')
self.calc_amount()
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
# If target warehouse exists, incoming rate is mandatory
# --------------------------------------------------------
def validate_incoming_rate(self):
for d in getlist(self.doclist, 'mtn_details'):
if not flt(d.incoming_rate) and d.t_warehouse:
msgprint("Rate is mandatory for Item: %s at row %s" % (d.item_code, d.idx), raise_exception=1)
# Validate warehouse
# -----------------------------------
def validate_warehouse(self, pro_obj):
fg_qty = 0
for d in getlist(self.doclist, 'mtn_details'):
if not d.s_warehouse and not d.t_warehouse:
d.s_warehouse = self.doc.from_warehouse
d.t_warehouse = self.doc.to_warehouse
if not (d.s_warehouse or d.t_warehouse):
msgprint("Atleast one warehouse is mandatory for Stock Entry ")
raise Exception
if d.s_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.s_warehouse):
msgprint("Invalid Warehouse: %s" % self.doc.s_warehouse)
raise Exception
if d.t_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.t_warehouse):
msgprint("Invalid Warehouse: %s" % self.doc.t_warehouse)
raise Exception
if d.s_warehouse == d.t_warehouse:
msgprint("Source and Target Warehouse Cannot be Same.")
raise Exception
if self.doc.purpose == 'Material Issue':
if not cstr(d.s_warehouse):
msgprint("Source Warehouse is Mandatory for Purpose => 'Material Issue'")
raise Exception
if cstr(d.t_warehouse):
msgprint("Target Warehouse is not Required for Purpose => 'Material Issue'")
raise Exception
if self.doc.purpose == 'Material Transfer':
if not cstr(d.s_warehouse) or not cstr(d.t_warehouse):
msgprint("Source Warehouse and Target Warehouse both are Mandatory for Purpose => 'Material Transfer'")
raise Exception
if self.doc.purpose == 'Material Receipt':
if not cstr(d.t_warehouse):
msgprint("Target Warehouse is Mandatory for Purpose => 'Material Receipt'")
raise Exception
if cstr(d.s_warehouse):
msgprint("Source Warehouse is not Required for Purpose => 'Material Receipt'")
raise Exception
if self.doc.process == 'Material Transfer':
if cstr(d.t_warehouse) != (pro_obj.doc.wip_warehouse):
msgprint(" Target Warehouse should be same as WIP Warehouse %s in Production Order %s at Row No %s" % (cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)) )
raise Exception
if not cstr(d.s_warehouse):
msgprint("Please Enter Source Warehouse at Row No %s is mandatory." % (cstr(d.idx)))
raise Exception
if self.doc.process == 'Backflush':
if flt(d.fg_item):
if cstr(pro_obj.doc.production_item) != cstr(d.item_code):
msgprint("Item %s in Stock Entry Detail as Row No %s do not match with Item %s in Production Order %s" % (cstr(d.item_code), cstr(d.idx), cstr(pro_obj.doc.production_item), cstr(pro_obj.doc.name)))
raise Exception
fg_qty = flt(fg_qty) + flt(d.transfer_qty)
if cstr(d.t_warehouse) != cstr(pro_obj.doc.fg_warehouse):
msgprint("As Item %s is FG Item. Target Warehouse should be same as FG Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.fg_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
raise Exception
if cstr(d.s_warehouse):
msgprint("As Item %s is a FG Item. There should be no Source Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
raise Exception
if not flt(d.fg_item):
if cstr(d.t_warehouse):
msgprint("As Item %s is not a FG Item. There should no Tareget Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
raise Exception
if cstr(d.s_warehouse) != cstr(pro_obj.doc.wip_warehouse):
msgprint("As Item %s is Raw Material. Source Warehouse should be same as WIP Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
raise Exception
d.save()
if self.doc.fg_completed_qty and flt(self.doc.fg_completed_qty) != flt(fg_qty):
msgprint("The Total of FG Qty %s in Stock Entry Detail do not match with FG Completed Qty %s" % (flt(fg_qty), flt(self.doc.fg_completed_qty)))
raise Exception
def update_production_order(self, is_submit):
if self.doc.production_order:
pro_obj = get_obj("Production Order", self.doc.production_order)
if flt(pro_obj.doc.docstatus) != 1:
msgprint("One cannot do any transaction against Production Order : %s, as it's not submitted" % (pro_obj.doc.name))
raise Exception
if pro_obj.doc.status == 'Stopped':
msgprint("One cannot do any transaction against Production Order : %s, as it's status is 'Stopped'" % (pro_obj.doc.name))
raise Exception
if getdate(pro_obj.doc.posting_date) > getdate(self.doc.posting_date):
msgprint("Posting Date of Stock Entry cannot be before Posting Date of Production Order "+ cstr(self.doc.production_order))
raise Exception
if self.doc.process == 'Backflush':
pro_obj.doc.produced_qty = flt(pro_obj.doc.produced_qty) + (is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty)
get_obj('Warehouse', pro_obj.doc.fg_warehouse).update_bin(0, 0, 0, 0, (is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty), pro_obj.doc.production_item, now())
pro_obj.doc.status = (flt(pro_obj.doc.qty) == flt(pro_obj.doc.produced_qty)) and 'Completed' or 'In Process'
pro_obj.doc.save()
# Create / Update Serial No
# ----------------------------------
def update_serial_no(self, is_submit):
sl_obj = get_obj('Stock Ledger')
for d in getlist(self.doclist, 'mtn_details'):
if d.serial_no:
serial_nos = sl_obj.get_sr_no_list(d.serial_no)
for x in serial_nos:
serial_no = x.strip()
if d.s_warehouse:
sl_obj.update_serial_delivery_details(self, d, serial_no, is_submit)
if d.t_warehouse:
sl_obj.update_serial_purchase_details(self, d, serial_no, is_submit, (self.doc.purpose in ['Material Transfer', 'Sales Return']) and 1 or 0)
if self.doc.purpose == 'Purchase Return':
delete_doc("Serial No", serial_no)
# On Submit
# ------------------
def on_submit(self):
self.validate_transfer_qty()
# Check for Approving Authority
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.total_amount)
self.update_serial_no(1)
self.update_stock_ledger(0)
# update Production Order
self.update_production_order(1)
# On Cancel
# -------------------
def on_cancel(self):
self.update_serial_no(0)
self.update_stock_ledger(1)
# update Production Order
self.update_production_order(0)
def get_cust_values(self):
tbl = self.doc.delivery_note_no and 'Delivery Note' or 'Receivable Voucher'
record_name = self.doc.delivery_note_no or self.doc.sales_invoice_no
res = sql("select customer,customer_name, customer_address from `tab%s` where name = '%s'" % (tbl, record_name))
ret = {
'customer' : res and res[0][0] or '',
'customer_name' : res and res[0][1] or '',
'customer_address' : res and res[0][2] or ''}
return str(ret)
def get_cust_addr(self):
res = sql("select customer_name,address from `tabCustomer` where name = '%s'"%self.doc.customer)
ret = {
'customer_name' : res and res[0][0] or '',
'customer_address' : res and res[0][1] or ''}
return str(ret)
def get_supp_values(self):
res = sql("select supplier,supplier_name,supplier_address from `tabPurchase Receipt` where name = '%s'"%self.doc.purchase_receipt_no)
ret = {
'supplier' : res and res[0][0] or '',
'supplier_name' :res and res[0][1] or '',
'supplier_address' : res and res[0][2] or ''}
return str(ret)
def get_supp_addr(self):
res = sql("select supplier_name,address from `tabSupplier` where name = '%s'"%self.doc.supplier)
ret = {
'supplier_name' : res and res[0][0] or '',
'supplier_address' : res and res[0][1] or ''}
return str(ret)

BIN
material_management/doctype/stock_entry_detail/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/stock_ledger/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/stock_ledger/stock_ledger.pyc

Binary file not shown.

BIN
material_management/doctype/stock_ledger_entry/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/stock_ledger_entry/stock_ledger_entry.pyc

Binary file not shown.

BIN
material_management/doctype/valuation_control/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/valuation_control/valuation_control.pyc

Binary file not shown.

87
material_management/doctype/valuation_control/valuation_control.py~

@ -0,0 +1,87 @@
# Please edit this list and import only required elements
import webnotes
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
from webnotes import session, form, is_testing, msgprint, errprint
set = webnotes.conn.set
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
in_transaction = webnotes.conn.in_transaction
convert_to_lists = webnotes.conn.convert_to_lists
# -----------------------------------------------------------------------------------------
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
# Get FIFO Rate from Stack
# -------------------------
def get_fifo_rate(self, fcfs_stack, qty):
fcfs_val = 0
withdraw = flt(qty)
while withdraw:
batch = fcfs_stack[0]
if batch[0] <= withdraw:
# not enough or exactly same qty in current batch, clear batch
withdraw -= batch[0]
fcfs_val += (flt(batch[0]) * flt(batch[1]))
fcfs_stack.pop(0)
else:
# all from current batch
fcfs_val += (flt(withdraw) * flt(batch[1]))
batch[0] -= withdraw
withdraw = 0
fcfs_rate = flt(fcfs_val) / flt(qty)
return fcfs_rate
# --------------------------------
# get serializable inventory rate
# --------------------------------
def get_serializable_inventory_rate(self, serial_no):
sr_nos = get_obj("Stock Ledger").get_sr_no_list(serial_no)
tot = 0
for s in sr_nos:
serial_no = s.strip()
tot += flt(get_value('Serial No', serial_no, 'purchase_rate'))
return tot / len(sr_nos)
# ---------------------
# get valuation method
# ---------------------
def get_valuation_method(self, item_code):
val_method = webnotes.conn.get_value('Item', item_code, 'valuation_method')
if not val_method:
val_method = get_defaults().get('valuation_method', 'FIFO')
return val_method
# Get Incoming Rate based on valuation method
# --------------------------------------------
def get_incoming_rate(self, posting_date, posting_time, item, warehouse, qty = 0, serial_no = ''):
msgprint(1)
in_rate = 0
val_method = self.get_valuation_method(item)
bin_obj = get_obj('Warehouse',warehouse).get_bin(item)
if serial_no:
in_rate = self.get_serializable_inventory_rate(serial_no)
elif val_method == 'FIFO':
in_rate = 0
if qty:
prev_sle = bin_obj.get_prev_sle(posting_date, posting_time)
msgprint(prev_sle)
fcfs_stack = eval(prev_sle.get('fcfs_stack', '[]') or '[]')
msgprint(fcfs_stack)
in_rate = fcfs_stack and self.get_fifo_rate(fcfs_stack, qty) or 0
msgprint(in_rate)
elif val_method == 'Moving Average':
prev_sle = bin_obj.get_prev_sle(posting_date, posting_time)
in_rate = prev_sle and prev_sle.get('valuation_rate', 0) or 0
return in_rate

BIN
material_management/doctype/warehouse/__init__.pyc

Binary file not shown.

BIN
material_management/doctype/warehouse/warehouse.pyc

Binary file not shown.
Loading…
Cancel
Save