reserved warehouse in so and delivery warehouse in dn can be different

This commit is contained in:
Nabin Hait 2012-06-25 18:06:37 +05:30
parent c6fc345f35
commit a5e972dd89
3 changed files with 76 additions and 53 deletions

View File

@ -359,44 +359,62 @@ class DocType(TransactionBase):
} }
return ret return ret
# --------------
# get item list
# --------------
def get_item_list(self, obj, is_stopped): def get_item_list(self, obj, is_stopped):
"""get item list"""
il = [] il = []
for d in getlist(obj.doclist,obj.fname): for d in getlist(obj.doclist,obj.fname):
reserved_qty = 0 # used for delivery note reserved_wh, reserved_qty = '', 0 # used for delivery note
qty = flt(d.qty) qty = flt(d.qty)
if is_stopped: if is_stopped:
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0 qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
if d.prevdoc_doctype == 'Sales Order': # used in delivery note to reduce reserved_qty if d.prevdoc_doctype == 'Sales Order':
# used in delivery note to reduce reserved_qty
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12. # Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
# But in this case reserved qty should only be reduced by 10 and not 12. # But in this case reserved qty should only be reduced by 10 and not 12.
tot_qty, max_qty, tot_amt, max_amt = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Sales Order Item', obj.doc.name, obj.doc.doctype) tot_qty, max_qty, tot_amt, max_amt, reserved_wh = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, obj.doc.name, obj.doc.doctype)
if((flt(tot_qty) + flt(qty) > flt(max_qty))): if((flt(tot_qty) + flt(qty) > flt(max_qty))):
reserved_qty = -(flt(max_qty)-flt(tot_qty)) reserved_qty = -(flt(max_qty)-flt(tot_qty))
else: else:
reserved_qty = - flt(qty) reserved_qty = - flt(qty)
warehouse = (obj.fname == "sales_order_details") and d.reserved_warehouse or d.warehouse if obj.doc.doctype == 'Sales Order':
reserved_wh = d.reserved_warehouse
if self.has_sales_bom(d.item_code): if self.has_sales_bom(d.item_code):
for p in getlist(obj.doclist, 'packing_details'): for p in getlist(obj.doclist, 'packing_details'):
#if p.parent_item == d.item_code: -- this fails when item with same name appears more than once in delivery note item table
if p.parent_detail_docname == d.name: if p.parent_detail_docname == d.name:
# the packing details table's qty is already multiplied with parent's qty # the packing details table's qty is already multiplied with parent's qty
il.append([warehouse, p.item_code, flt(p.qty), (flt(p.qty)/qty)*(reserved_qty), p.uom, p.batch_no, p.serial_no]) il.append({
'warehouse': d.warehouse,
'reserved_warehouse': reserved_wh,
'item_code': p.item_code,
'qty': flt(p.qty),
'reserved_qty': (flt(p.qty)/qty)*(reserved_qty),
'uom': p.uom,
'batch_no': p.batch_no,
'serial_no': p.serial_no
})
else: else:
il.append([warehouse, d.item_code, qty, reserved_qty, d.stock_uom, d.batch_no, d.serial_no]) il.append({
'warehouse': d.warehouse,
'reserved_warehouse': reserved_wh,
'item_code': d.item_code,
'qty': qty,
'reserved_qty': reserved_qty,
'uom': d.stock_uom,
'batch_no': d.batch_no,
'serial_no': d.serial_no
})
return il return il
# ---------------------------------------------------------------------------------------------
# get qty, amount already billed or delivered against curr line item for current doctype def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name, curr_parent_doctype):
# For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV """ Get qty, amount already billed or delivered against curr line item for current doctype
# --------------------------------------------------------------------------------------------- For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV
def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, ref_doc_tname, curr_parent_name, curr_parent_doctype): """
#Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction #Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction
if curr_parent_doctype == 'Installation Note': if curr_parent_doctype == 'Installation Note':
curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
@ -406,10 +424,9 @@ class DocType(TransactionBase):
qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0 qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0
# get total qty of ref doctype # get total qty of ref doctype
ref_det = webnotes.conn.sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn)) so_det = webnotes.conn.sql("select qty, amount, reserved_warehouse from `tabSales Order Item` where name = '%s' and docstatus = 1"% ref_tab_dn)
max_qty, max_amt = ref_det and flt(ref_det[0][0]) or 0, ref_det and flt(ref_det[0][1]) or 0 max_qty, max_amt, res_wh = so_det and flt(so_det[0][0]) or 0, so_det and flt(so_det[0][1]) or 0, so_det and cstr(so_det[0][2]) or ''
return qty, max_qty, amt, max_amt, res_wh
return qty, max_qty, amt, max_amt
# Make Packing List from Sales BOM # Make Packing List from Sales BOM

View File

@ -457,12 +457,15 @@ class DocType(TransactionBase):
# =============================================================================================== # ===============================================================================================
def update_stock_ledger(self, update_stock, clear = 0): def update_stock_ledger(self, update_stock, clear = 0):
for d in self.get_item_list(clear): for d in self.get_item_list(clear):
stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d[1]),as_dict = 1) # stock ledger will be updated only if it is a stock item stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d['item_code']),as_dict = 1)
# stock ledger will be updated only if it is a stock item
if stock_item and stock_item[0]['is_stock_item'] == "Yes": if stock_item and stock_item[0]['is_stock_item'] == "Yes":
if not d[0]: if not d['reserved_warehouse']:
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1]) msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d['item_code'])
raise Exception raise Exception
bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin( 0, flt(update_stock) * flt(d['qty']), \
0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype,\
doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
# Gets Items from packing list # Gets Items from packing list
#================================= #=================================

View File

@ -297,13 +297,13 @@ class DocType(TransactionBase):
# check if same item, warehouse present in prevdoc # check if same item, warehouse present in prevdoc
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def validate_items_with_prevdoc(self, d): def validate_items_with_prevdoc(self, d):
if d.prevdoc_doctype == 'Sales Order': prev_item_dt = (d.prevdoc_doctype == 'Sales Order') and 'Sales Order Item' or 'Purchase Receipt Item'
data = sql("select item_code, reserved_warehouse from `tabSales Order Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) data = sql("select item_code from `tab%s` where parent = '%s' and name = '%s'"\
if d.prevdoc_doctype == 'Purchase Receipt': % (prev_item_dt, d.prevdoc_docname, d.prevdoc_detail_docname))
data = sql("select item_code, rejected_warehouse from `tabPurchase Receipt Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) if not data or data[0][0] != d.item_code:
if not data or data[0][0] != d.item_code or data[0][1] != d.warehouse: msgprint("Item: %s is not matching with Sales Order: %s. Sales Order might be modified after \
msgprint("Item: %s / Warehouse: %s is not matching with Sales Order: %s. Sales Order might be modified after fetching data from it. Please delete items and fetch again." % (d.item_code, d.warehouse, d.prevdoc_docname)) fetching data from it. Please delete items and fetch again." \
raise Exception % (d.item_code, d.prevdoc_docname), raise_exception=1)
# ********* UPDATE CURRENT STOCK ***************************** # ********* UPDATE CURRENT STOCK *****************************
@ -413,16 +413,19 @@ class DocType(TransactionBase):
def update_stock_ledger(self, update_stock, is_stopped = 0): def update_stock_ledger(self, update_stock, is_stopped = 0):
self.values = [] self.values = []
for d in self.get_item_list(is_stopped): for d in self.get_item_list(is_stopped):
stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d[1]), as_dict = 1) # stock ledger will be updated only if it is a stock item stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d['item_code']), as_dict = 1) # stock ledger will be updated only if it is a stock item
if stock_item[0]['is_stock_item'] == "Yes": if stock_item[0]['is_stock_item'] == "Yes":
if not d[0]: if not d['warehouse']:
msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d[1]) msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d['item_code'])
raise Exception raise Exception
if d[3] < 0 : if d['reserved_qty'] < 0 :
# Reduce Reserved Qty from warehouse # Reduce reserved qty from reserved warehouse mentioned in so
bin = get_obj('Warehouse', d[0]).update_bin(0, flt(update_stock) * flt(d[3]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin(0, flt(update_stock) * flt(d['reserved_qty']), \
0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype, \
doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
# Reduce actual qty from warehouse # Reduce actual qty from warehouse
self.make_sl_entry(d, d[0], - flt(d[2]) , 0, update_stock) self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values) get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
@ -434,7 +437,7 @@ class DocType(TransactionBase):
# ********************** Make Stock Entry ************************************ # ********************** Make Stock Entry ************************************
def make_sl_entry(self, d, wh, qty, in_value, update_stock): def make_sl_entry(self, d, wh, qty, in_value, update_stock):
self.values.append({ self.values.append({
'item_code' : d[1], 'item_code' : d['item_code'],
'warehouse' : wh, 'warehouse' : wh,
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
'posting_date' : self.doc.posting_date, 'posting_date' : self.doc.posting_date,
@ -443,13 +446,13 @@ class DocType(TransactionBase):
'voucher_no' : self.doc.name, 'voucher_no' : self.doc.name,
'voucher_detail_no' : '', 'voucher_detail_no' : '',
'actual_qty' : qty, 'actual_qty' : qty,
'stock_uom' : d[4], 'stock_uom' : d['uom'],
'incoming_rate' : in_value, 'incoming_rate' : in_value,
'company' : self.doc.company, 'company' : self.doc.company,
'fiscal_year' : self.doc.fiscal_year, 'fiscal_year' : self.doc.fiscal_year,
'is_cancelled' : (update_stock==1) and 'No' or 'Yes', 'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
'batch_no' : d[5], 'batch_no' : d['batch_no'],
'serial_no' : d[6] 'serial_no' : d['serial_no']
}) })