[fix] [cleanup] fixes while testing and code cleanup

This commit is contained in:
Nabin Hait
2013-07-11 17:49:18 +05:30
parent 1ac928ed5c
commit cfecd2bc16
39 changed files with 197 additions and 409 deletions

View File

@@ -17,9 +17,8 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import add_days, cstr, flt
from webnotes.utils import cstr, flt
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint, _
from buying.utils import get_last_purchase_details
@@ -32,46 +31,11 @@ class DocType(BuyingController):
self.doc = doc
self.doclist = doclist
self.chk_tol_for_list = ['Material Request - Purchase Order', 'Purchase Order - Purchase Receipt', 'Purchase Order - Purchase Invoice']
self.update_qty = {
'Material Request - Purchase Order': 'ordered_qty',
'Purchase Order - Purchase Receipt': 'received_qty',
'Purchase Order - Purchase Invoice': 'billed_qty',
'Purchase Receipt - Purchase Invoice': 'billed_qty'
}
self.update_percent_field = {
'Material Request - Purchase Order': 'per_ordered',
'Purchase Order - Purchase Receipt': 'per_received',
'Purchase Order - Purchase Invoice': 'per_billed',
'Purchase Receipt - Purchase Invoice': 'per_billed'
}
# used in validation for items and update_prevdoc_detail
self.doctype_dict = {
'Material Request': 'Material Request Item',
'Purchase Order': 'Purchase Order Item',
'Purchase Receipt': 'Purchase Receipt Item'
}
self.next_dt_detail = {
'ordered_qty' : 'Purchase Order Item',
'billed_qty' : 'Purchase Invoice Item',
'received_qty': 'Purchase Receipt Item'
}
self.msg = []
def is_item_table_empty(self, obj):
if not len(obj.doclist.get({"parentfield": obj.fname})):
msgprint(_("Hey there! You need to put at least one item in \
the item table."), raise_exception=True)
# Client Trigger functions
#------------------------------------------------------------------------------------------------
# Get Supplier Details
def get_supplier_details(self, name = ''):
details = sql("select supplier_name,address from `tabSupplier` where name = '%s' and docstatus != 2" %(name), as_dict = 1)
if details:
@@ -94,8 +58,6 @@ class DocType(BuyingController):
ret = { 'projected_qty' : bin and flt(bin[0]['projected_qty']) or 0 }
return ret
# --- Last Purchase Rate related methods ---
def update_last_purchase_rate(self, obj, is_submit):
"""updates last_purchase_rate in item table for each item"""
@@ -146,8 +108,6 @@ class DocType(BuyingController):
d.purchase_ref_rate = d.purchase_rate = d.import_ref_rate \
= d.import_rate = item_last_purchase_rate
# validate for same items and validate is_stock_item , is_purchase_item also validate uom and conversion factor
def validate_for_items(self, obj):
check_list, chk_dupl_itm=[],[]
for d in getlist( obj.doclist, obj.fname):
@@ -159,7 +119,7 @@ class DocType(BuyingController):
# udpate with latest quantities
bin = sql("select projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0, 'billed_qty': 0}
f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0}
if d.doctype == 'Purchase Receipt Item':
f_lst.pop('received_qty')
for x in f_lst :
@@ -206,36 +166,7 @@ class DocType(BuyingController):
Please change any of the field value to enter the item twice.""" % d.item_code, raise_exception = 1)
else:
chk_dupl_itm.append(f)
# Check for Stopped status
def check_for_stopped_status(self, doctype, docname):
stopped = sql("select name from `tab%s` where name = '%s' and status = 'Stopped'" %
( doctype, docname))
if stopped:
msgprint("One cannot do any transaction against %s : %s, it's status is 'Stopped'" %
( doctype, docname), raise_exception=1)
# Check Docstatus of Next DocType on Cancel AND of Previous DocType on Submit
def check_docstatus(self, check, doctype, docname , detail_doctype = ''):
if check == 'Next':
# Convention := doctype => Next Doctype, docname = current_docname , detail_doctype = Next Doctype Detail Table
submitted = sql("select t1.name from `tab%s` t1,`tab%s` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % ( doctype, detail_doctype, docname))
if submitted:
msgprint(cstr(doctype) + " : " + cstr(submitted[0][0]) + " has already been submitted !")
raise Exception
if check == 'Previous':
# Convention := doctype => Previous Doctype, docname = Previous Docname
submitted = sql("select name from `tab%s` where docstatus = 1 and name = '%s'" % (doctype, docname))
if not submitted:
msgprint(cstr(doctype) + " : " + cstr(submitted[0][0]) + " not submitted !")
raise Exception
# Update Ref Doc
# =======================================================
def get_qty(self,curr_doctype,ref_tab_fname,ref_tab_dn,ref_doc_tname, transaction, curr_parent_name):
# Get total Quantities of current doctype (eg. PR) except for qty of this transaction
#------------------------------
@@ -252,112 +183,35 @@ class DocType(BuyingController):
max_qty = sql("select qty from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn))
max_qty = max_qty and flt(max_qty[0][0]) or 0
return cstr(qty)+'~~~'+cstr(max_qty)
return cstr(qty)+'~~~'+cstr(max_qty)
def check_for_stopped_status(self, doctype, docname):
stopped = sql("select name from `tab%s` where name = '%s' and status = 'Stopped'" %
( doctype, docname))
if stopped:
msgprint("One cannot do any transaction against %s : %s, it's status is 'Stopped'" %
( doctype, docname), raise_exception=1)
def check_docstatus(self, check, doctype, docname , detail_doctype = ''):
if check == 'Next':
submitted = sql("""select t1.name from `tab%s` t1,`tab%s` t2
where t1.name = t2.parent and t2.prevdoc_docname = %s and t1.docstatus = 1"""
% (doctype, detail_doctype, '%s'), docname)
if submitted:
msgprint(cstr(doctype) + ": " + cstr(submitted[0][0])
+ _(" has already been submitted."), raise_exception=1)
def update_refdoc_qty(self, curr_qty, curr_doctype, ref_dn, ref_dt, ref_tab_fname, ref_tab_dn, transaction, item_code, is_submit, curr_parent_doctype, curr_parent_name):
# Get Quantity
#------------------------------
curr_ref_qty = self.get_qty(curr_doctype,ref_tab_fname,ref_tab_dn,self.doctype_dict[ref_dt], transaction, curr_parent_name)
qty, max_qty, max_qty_plus_tol = flt(curr_ref_qty.split('~~~')[0]), flt(curr_ref_qty.split('~~~')[1]), flt(curr_ref_qty.split('~~~')[1])
# Qty above Tolerance should be allowed only once.
# But there is special case for Transaction 'Material Request-Purhcase Order' that there should be no restriction
# One can create any no. of PO against same Material Request!!!
if qty >= max_qty and is_submit and flt(curr_qty) > 0:
reason = (curr_parent_doctype == 'Purchase Order') and 'Ordered' or (curr_parent_doctype == 'Purchase Receipt') and 'Received' or (curr_parent_doctype == 'Purchase Invoice') and 'Billed'
msgprint("Error: Item Code : '%s' of '%s' is already %s." %(item_code,ref_dn,reason))
raise Exception
#check if tolerance added in item master
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
if not(tolerance):
tolerance = flt(webnotes.conn.get_value('Stock Settings',None,'tolerance') or 0)
if is_submit:
qty = qty + flt(curr_qty)
# Calculate max_qty_plus_tol i.e. max_qty with tolerance
#-----------------------------------------------------------------
if transaction in self.chk_tol_for_list:
max_qty_plus_tol = max_qty * (1 + (flt(tolerance)/ 100))
if max_qty_plus_tol < qty:
reason = (curr_parent_doctype == 'Purchase Order') and 'Ordered' or (curr_parent_doctype == 'Purchase Receipt') and 'Received' or (curr_parent_doctype == 'Purchase Invoice') and 'Billed'
msg = "error: Already %s Qty for %s is %s and \
maximum allowed Qty is %s [against %s: %s]" % \
(cstr(reason), item_code,
cstr(flt(qty) - flt(curr_qty)) , cstr(max_qty_plus_tol),
cstr(ref_dt), cstr(ref_dn))
msgprint(msg, raise_exception=1)
# Update qty
#------------------
sql("update `tab%s` set %s = '%s',modified = now() where name = '%s'" % (self.doctype_dict[ref_dt],self.update_qty[transaction] , flt(qty), ref_tab_dn))
def update_ref_doctype_dict(self, curr_qty, curr_doctype, ref_dn, ref_dt, ref_tab_fname, ref_tab_dn, transaction, item_code, is_submit, curr_parent_doctype, curr_parent_name):
# update qty
self.update_refdoc_qty( curr_qty, curr_doctype, ref_dn, ref_dt, ref_tab_fname, ref_tab_dn, transaction, item_code, is_submit, curr_parent_doctype, curr_parent_name)
# append distinct ref_dn in doctype_dict
if not self.ref_doctype_dict.has_key(ref_dn) and self.update_percent_field.has_key(transaction):
self.ref_doctype_dict[ref_dn] = [ ref_dt, self.doctype_dict[ref_dt],transaction]
# update prevdoc detail
# --------------------
def update_prevdoc_detail(self, obj, is_submit):
import math
self.ref_doctype_dict= {}
for d in getlist(obj.doclist, obj.fname):
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname:
transaction = cstr(d.prevdoc_doctype) + ' - ' + cstr(obj.doc.doctype)
curr_qty = (transaction == 'Material Request - Purchase Order') and flt(d.qty) * flt(d.conversion_factor) or flt(d.qty)
self.update_ref_doctype_dict( flt(curr_qty), d.doctype, d.prevdoc_docname, d.prevdoc_doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, transaction, d.item_code, is_submit, obj.doc.doctype, obj.doc.name)
# for payable voucher
if d.fields.has_key('purchase_order') and d.purchase_order:
curr_qty = sql("select sum(qty) from `tabPurchase Invoice Item` where po_detail = '%s' and parent = '%s'" % (cstr(d.po_detail), cstr(obj.doc.name)))
curr_qty = curr_qty and flt(curr_qty[0][0]) or 0
self.update_ref_doctype_dict( curr_qty, d.doctype, d.purchase_order, 'Purchase Order', 'po_detail', d.po_detail, 'Purchase Order - ' + cstr(obj.doc.doctype), d.item_code, is_submit, obj.doc.doctype, obj.doc.name)
if d.fields.has_key('purchase_receipt') and d.purchase_receipt:
self.update_ref_doctype_dict( flt(d.qty), d.doctype, d.purchase_receipt, 'Purchase Receipt', 'pr_detail', d.pr_detail, 'Purchase Receipt - ' + cstr(obj.doc.doctype), d.item_code, is_submit, obj.doc.doctype, obj.doc.name)
for ref_dn in self.ref_doctype_dict:
# Calculate percentage
#----------------------
ref_doc_obj = get_obj(self.ref_doctype_dict[ref_dn][0],ref_dn,with_children = 1)
count = 0
percent = 0
for d in getlist(ref_doc_obj.doclist,ref_doc_obj.fname):
ref_qty = d.fields[self.update_qty[self.ref_doctype_dict[ref_dn][2]]]
if flt(d.qty) - flt(ref_qty) <= 0:
percent += 100
else:
percent += (flt(ref_qty)/flt(d.qty) * 100)
count += 1
percent_complete = math.floor(flt(percent)/ flt(count))
# update percent complete and modified
#-------------------------------------
sql("update `tab%s` set %s = '%s', modified = '%s' where name = '%s'" % (self.ref_doctype_dict[ref_dn][0], self.update_percent_field[self.ref_doctype_dict[ref_dn][2]], percent_complete, obj.doc.modified, ref_dn))
def validate_fiscal_year(self, fiscal_year, transaction_date, dn):
fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%fiscal_year)
ysd=fy and fy[0][0] or ""
yed=add_days(str(ysd),365)
if str(transaction_date) < str(ysd) or str(transaction_date) > str(yed):
msgprint("'%s' Not Within The Fiscal Year"%(dn))
raise Exception
if check == 'Previous':
submitted = sql("""select name from `tab%s`
where docstatus = 1 and name = %s"""% (doctype, '%s'), docname)
if not submitted:
msgprint(cstr(doctype) + ": " + cstr(submitted[0][0])
+ _(" not submitted"), raise_exception=1)
def get_rate(self, arg, obj):
arg = eval(arg)
rate = sql("select account_type, tax_rate from `tabAccount` where name = '%s'" %(arg['account_head']), as_dict=1)
rate = sql("select account_type, tax_rate from `tabAccount` where name = %s"
, (arg['account_head']), as_dict=1)
return {'rate': rate and (rate[0]['account_type'] == 'Tax' \
and not arg['charge_type'] == 'Actual') and flt(rate[0]['tax_rate']) or 0 }
@@ -365,5 +219,6 @@ class DocType(BuyingController):
def get_prevdoc_date(self, obj):
for d in getlist(obj.doclist, obj.fname):
if d.prevdoc_doctype and d.prevdoc_docname:
dt = sql("select transaction_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname))
dt = sql("select transaction_date from `tab%s` where name = %s"
% (d.prevdoc_doctype, '%s'), (d.prevdoc_docname))
d.prevdoc_date = dt and dt[0][0].strftime('%Y-%m-%d') or ''

View File

@@ -31,12 +31,21 @@ class DocType(BuyingController):
self.doclist = doclist
self.tname = 'Purchase Order Item'
self.fname = 'po_details'
self.status_updater = [{
'source_dt': 'Purchase Order Item',
'target_dt': 'Material Request Item',
'join_field': 'prevdoc_detail_docname',
'target_field': 'ordered_qty',
'target_parent_dt': 'Material Request',
'target_parent_field': 'per_ordered',
'target_ref_field': 'qty',
'source_field': 'qty',
'percent_join_field': 'prevdoc_docname',
}]
def validate(self):
super(DocType, self).validate()
self.validate_fiscal_year()
if not self.doc.status:
self.doc.status = "Draft"
@@ -53,9 +62,6 @@ class DocType(BuyingController):
self.validate_for_subcontracting()
self.update_raw_materials_supplied("po_raw_material_details")
def validate_fiscal_year(self):
get_obj(dt = 'Purchase Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'PO Date')
def validate_with_previous_doc(self):
super(DocType, self).validate_with_previous_doc(self.tname, {
"Supplier Quotation": {
@@ -157,27 +163,18 @@ class DocType(BuyingController):
purchase_controller = webnotes.get_obj("Purchase Common")
purchase_controller.is_item_table_empty(self)
# Step 1 :=> Update Previous Doc i.e. update pending_qty and Status accordingly
purchase_controller.update_prevdoc_detail(self, is_submit = 1)
# Step 2 :=> Update Bin
self.update_prevdoc_status()
self.update_bin(is_submit = 1, is_stopped = 0)
# Step 3 :=> Check For Approval Authority
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total)
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,
self.doc.company, self.doc.grand_total)
# Step 5 :=> Update last purchase rate
purchase_controller.update_last_purchase_rate(self, is_submit = 1)
# Step 6 :=> Set Status
webnotes.conn.set(self.doc,'status','Submitted')
def on_cancel(self):
pc_obj = get_obj(dt = 'Purchase Common')
# Check if PO status is stopped
pc_obj.check_for_stopped_status(cstr(self.doc.doctype), cstr(self.doc.name))
pc_obj = get_obj(dt = 'Purchase Common')
self.check_for_stopped_status(pc_obj)
# Check if Purchase Receipt has been submitted against current Purchase Order
@@ -190,7 +187,7 @@ class DocType(BuyingController):
raise Exception
webnotes.conn.set(self.doc,'status','Cancelled')
pc_obj.update_prevdoc_detail(self,is_submit = 0)
self.update_prevdoc_status()
self.update_bin( is_submit = 0, is_stopped = 0)
pc_obj.update_last_purchase_rate(self, is_submit = 0)

View File

@@ -32,7 +32,7 @@ class TestPurchaseOrder(unittest.TestCase):
po = webnotes.bean("Purchase Order", po.doc.name)
po.submit()
pr = make_purchase_receipt(po.doc.name)
pr[0]["supplier_warehouse"] = "_Test Warehouse 1"
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
self.assertEquals(len(pr), len(test_records[0]))
@@ -100,7 +100,7 @@ test_records = [
"qty": 10.0,
"import_rate": 500.0,
"amount": 5000.0,
"warehouse": "_Test Warehouse",
"warehouse": "_Test Warehouse - _TC",
"stock_uom": "Nos",
"uom": "_Test UOM",
"schedule_date": "2013-03-01"

View File

@@ -34,7 +34,6 @@ class DocType(BuyingController):
utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped",
"Cancelled"])
self.validate_fiscal_year()
self.validate_common()
self.validate_with_previous_doc()
@@ -49,10 +48,6 @@ class DocType(BuyingController):
def on_trash(self):
pass
def validate_fiscal_year(self):
get_obj(dt = 'Purchase Common').validate_fiscal_year( \
self.doc.fiscal_year, self.doc.transaction_date, 'Quotation Date')
def validate_with_previous_doc(self):
super(DocType, self).validate_with_previous_doc(self.tname, {

View File

@@ -70,7 +70,7 @@ test_records = [
"qty": 10.0,
"import_rate": 500.0,
"amount": 5000.0,
"warehouse": "_Test Warehouse",
"warehouse": "_Test Warehouse - _TC",
"uom": "_Test UOM",
}
],