Merge branch 'master' of github.com:webnotes/erpnext
Conflicts: index.html
This commit is contained in:
commit
f8b01097ac
@ -232,15 +232,11 @@ class DocType(TransactionBase):
|
||||
# Validate Acc Head of Supplier and Credit To Account entered
|
||||
# ------------------------------------------------------------
|
||||
def check_for_acc_head_of_supplier(self):
|
||||
acc_head = sql("select name from `tabAccount` where name = %s", (cstr(self.doc.supplier) + " - " + self.get_company_abbr()))
|
||||
if self.doc.supplier:
|
||||
if acc_head and acc_head[0][0]:
|
||||
if not cstr(acc_head[0][0]) == cstr(self.doc.credit_to):
|
||||
msgprint("Credit To: %s do not match with Supplier: %s for Company: %s i.e. %s" %(self.doc.credit_to,self.doc.supplier,self.doc.company,cstr(acc_head[0][0])))
|
||||
raise Exception, "Validation Error "
|
||||
if not acc_head:
|
||||
msgprint("Supplier %s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
|
||||
raise Exception, "Validation Error "
|
||||
if self.doc.supplier and self.doc.credit_to:
|
||||
acc_head = sql("select master_name from `tabAccount` where name = %s", self.doc.credit_to)
|
||||
|
||||
if (acc_head and cstr(acc_head[0][0]) != cstr(self.doc.credit_to)) or (not acc_head and (self.doc.credit_to != cstr(self.doc.supplier) + " - " + self.get_company_abbr())):
|
||||
msgprint("Credit To: %s do not match with Supplier: %s for Company: %s.\n If both correctly entered, please select Master Type and Master Name in account master." %(self.doc.credit_to,self.doc.supplier,self.doc.company), raise_exception=1)
|
||||
|
||||
# Check for Stopped PO
|
||||
# ---------------------
|
||||
|
@ -74,6 +74,9 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) {
|
||||
// -------
|
||||
cur_frm.cscript.refresh = function(doc, dt, dn) {
|
||||
|
||||
cur_frm.cscript.is_opening(doc, dt, dn);
|
||||
cur_frm.cscript.hide_fields(doc, cdt, cdn);
|
||||
|
||||
// Show / Hide button
|
||||
cur_frm.clear_custom_buttons();
|
||||
|
||||
@ -90,8 +93,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) {
|
||||
}
|
||||
else
|
||||
hide_field('Repair Outstanding Amt');
|
||||
cur_frm.cscript.is_opening(doc, dt, dn);
|
||||
cur_frm.cscript.hide_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
//fetch retail transaction related fields
|
||||
|
@ -31,6 +31,8 @@ class DocType:
|
||||
def get_modules(self):
|
||||
rl = webnotes.user.get_roles()
|
||||
ml = sql("select distinct t1.name, t1.module_icon, t1.module_label, t1.module_desc, t1.module_page from `tabModule Def` t1, `tabModule Def Role` t2 where t2.role in ('%s') and t1.disabled !='Yes' and ifnull(t1.is_hidden, 'No') != 'Yes' and t1.name = t2.parent order by t1.module_seq asc" % "','".join(rl), as_dict=1)
|
||||
webnotes.response['login_url'] = session['data'].get('login_from', '')
|
||||
|
||||
return ml
|
||||
|
||||
def get_module_details(self,m):
|
||||
@ -48,8 +50,6 @@ class DocType:
|
||||
AND t2.role IN ("%s")
|
||||
AND ifnull(standard,"No")="No"''' % (m, '", "'.join(webnotes.user.get_roles())), as_dict=1)
|
||||
|
||||
ret['login_url'] = session['data'].get('login_from', '')
|
||||
|
||||
return ret
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,13 +1,20 @@
|
||||
cur_frm.add_fetch('employee', 'company', 'company');
|
||||
|
||||
cur_frm.cscript.onload = function(doc,cdt,cdn){
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(doc.employee) cur_frm.cscript.employee(doc,cdt,cdn);
|
||||
if(doc.amended_from && doc.__islocal) cur_frm.cscript.refresh_appraisal_details(doc, cdt, cdn);
|
||||
if(!doc.status)
|
||||
set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(doc.amended_from && doc.__islocal)
|
||||
cur_frm.cscript.refresh_appraisal_details(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc,cdt,cdn){
|
||||
if(doc.employee)
|
||||
cur_frm.cscript.employee(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc,cdt,cdn){
|
||||
if(user == doc.kra_approver && doc.status == 'Submitted') unhide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
|
||||
if(user == doc.kra_approver && doc.status == 'Submitted')
|
||||
unhide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
|
||||
else hide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
|
||||
|
||||
if(!doc.docstatus) unhide_field('Fetch Template');
|
||||
|
@ -46,7 +46,7 @@ class DocType:
|
||||
self.check_mandatory()
|
||||
|
||||
cond = ''
|
||||
for f in ['company', 'branch', 'department', 'designation', 'grade', 'employment_type']:
|
||||
for f in ['company', 'branch', 'department', 'designation', 'grade']:
|
||||
if self.doc.fields.get(f):
|
||||
cond += " and t1." + f + " = '" + self.doc.fields.get(f) + "'"
|
||||
|
||||
|
@ -5,18 +5,19 @@
|
||||
{
|
||||
'creation': '2011-08-11 16:40:04',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-08-25 12:02:57',
|
||||
'modified': '2011-11-07 10:47:32',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': '1314179318',
|
||||
'_last_update': '1314253977',
|
||||
'allow_copy': 1,
|
||||
'allow_email': 1,
|
||||
'allow_print': 1,
|
||||
'colour': 'White:FFF',
|
||||
'default_print_format': 'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': 'Other',
|
||||
'issingle': 1,
|
||||
@ -24,7 +25,7 @@
|
||||
'name': '__common__',
|
||||
'section_style': 'Simple',
|
||||
'show_in_menu': 1,
|
||||
'version': 29
|
||||
'version': 30
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
@ -59,21 +60,18 @@
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 1,
|
||||
'role': 'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 2,
|
||||
'role': 'HR User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 3,
|
||||
'role': 'HR Manager'
|
||||
},
|
||||
|
||||
@ -82,7 +80,6 @@
|
||||
'colour': 'White:FFF',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'HTML',
|
||||
'idx': 1,
|
||||
'label': 'Document Description',
|
||||
'options': '<div class="field_description">You can generate multiple salary slips based on the selected criteria, submit and mail those to the employee directly from here</div>'
|
||||
},
|
||||
@ -90,15 +87,13 @@
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 2
|
||||
'fieldtype': 'Section Break'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 3,
|
||||
'width': '50%'
|
||||
},
|
||||
|
||||
@ -107,7 +102,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'company',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 4,
|
||||
'label': 'Company',
|
||||
'options': 'link:Company',
|
||||
'reqd': 1
|
||||
@ -118,7 +112,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'branch',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 5,
|
||||
'label': 'Branch',
|
||||
'options': 'Branch'
|
||||
},
|
||||
@ -128,7 +121,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'department',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 6,
|
||||
'label': 'Department',
|
||||
'options': 'Department'
|
||||
},
|
||||
@ -138,7 +130,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'designation',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 7,
|
||||
'label': 'Designation',
|
||||
'options': 'Designation'
|
||||
},
|
||||
@ -147,7 +138,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 8,
|
||||
'width': '50%'
|
||||
},
|
||||
|
||||
@ -156,28 +146,16 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'grade',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 9,
|
||||
'label': 'Grade',
|
||||
'options': 'link:Grade'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'employment_type',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 10,
|
||||
'label': 'Employment Type',
|
||||
'options': 'link:Employment Type'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': 'White:FFF',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'fiscal_year',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 11,
|
||||
'label': 'Fiscal Year',
|
||||
'options': 'link:Fiscal Year',
|
||||
'reqd': 1
|
||||
@ -189,7 +167,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'month',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 12,
|
||||
'label': 'Month',
|
||||
'options': '\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12',
|
||||
'reqd': 1
|
||||
@ -202,22 +179,19 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'send_email',
|
||||
'fieldtype': 'Check',
|
||||
'idx': 13,
|
||||
'label': 'Send Email'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 14
|
||||
'fieldtype': 'Section Break'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 15,
|
||||
'width': '50%'
|
||||
},
|
||||
|
||||
@ -227,7 +201,6 @@
|
||||
'description': 'Creates salary slip for above mentioned criteria.',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'idx': 16,
|
||||
'label': 'Create Salary Slip',
|
||||
'trigger': 'Client'
|
||||
},
|
||||
@ -236,7 +209,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 17,
|
||||
'width': '25%'
|
||||
},
|
||||
|
||||
@ -246,7 +218,6 @@
|
||||
'description': 'Submit all salary slips for the above selected criteria',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'idx': 18,
|
||||
'label': 'Submit Salary Slip',
|
||||
'trigger': 'Client'
|
||||
},
|
||||
@ -255,7 +226,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 19,
|
||||
'width': '25%'
|
||||
},
|
||||
|
||||
@ -265,7 +235,6 @@
|
||||
'description': 'Create Bank Voucher for the total salary paid for the above selected criteria',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'idx': 20,
|
||||
'label': 'Make Bank Voucher',
|
||||
'trigger': 'Client'
|
||||
},
|
||||
@ -273,15 +242,13 @@
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 21
|
||||
'fieldtype': 'Section Break'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'HTML',
|
||||
'idx': 22,
|
||||
'label': 'Activity Log'
|
||||
}
|
||||
]
|
@ -344,8 +344,7 @@ def execute(patch_no):
|
||||
bin = sql("select name from tabBin")
|
||||
for b in bin:
|
||||
bobj = get_obj('Bin',b[0])
|
||||
prev_sle = bobj.get_prev_sle(posting_date = '2011-09-01', posting_time = '01:00')
|
||||
bobj.update_item_valuation(posting_date = '2011-09-01', posting_time = '01:00', prev_sle = prev_sle)
|
||||
bobj.update_entries_after(posting_date = '2011-09-01', posting_time = '01:00')
|
||||
elif patch_no == 368:
|
||||
from webnotes.utils import nestedset
|
||||
t = [
|
||||
|
5
erpnext/patches/reload_bom.py
Normal file
5
erpnext/patches/reload_bom.py
Normal file
@ -0,0 +1,5 @@
|
||||
def execute():
|
||||
import webnotes
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
|
||||
reload_doc('production', 'doctype', 'bill_of_materials')
|
6
erpnext/patches/reload_flat_bom.py
Normal file
6
erpnext/patches/reload_flat_bom.py
Normal file
@ -0,0 +1,6 @@
|
||||
def execute():
|
||||
from webnotes.modules import webnotes
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
|
||||
reload_doc('production', 'doctype', 'flat_bom_detail')
|
||||
reload_doc('production', 'doctype', 'bom_material')
|
8
erpnext/patches/sal_man_patch.py
Normal file
8
erpnext/patches/sal_man_patch.py
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
def execute():
|
||||
import webnotes
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
reload_doc('hr', 'doctype', 'salary_manager')
|
||||
sql("delete from `tabDocField` where parent = 'Salary Manager' and fieldname = 'employment_type'")
|
@ -32,9 +32,10 @@ class DocType:
|
||||
|
||||
#----------- Client Trigger function ----------
|
||||
def get_item_detail(self, item_code):
|
||||
item = sql("select description from `tabItem` where (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and name = %s",item_code , as_dict =1)
|
||||
item = sql("select description, stock_uom from `tabItem` where (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and name = %s",item_code , as_dict =1)
|
||||
ret={
|
||||
'description' : item and item[0]['description'] or ''
|
||||
'description' : item and item[0]['description'] or '',
|
||||
'uom' : item and item[0]['stock_uom'] or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
@ -411,8 +412,8 @@ class DocType:
|
||||
if val_method == 'FIFO':
|
||||
if warehouse:
|
||||
bin_obj = get_obj('Warehouse',warehouse).get_bin(item_code)
|
||||
prev_sle = bin_obj.get_prev_sle('',nowdate(), (now().split(' ')[1])[:-3])
|
||||
fcfs_stack = prev_sle and (prev_sle[0][3] and eval(prev_sle[0][3]) or []) or []
|
||||
prev_sle = bin_obj.get_prev_sle(nowdate(), (now().split(' ')[1])[:-3])
|
||||
fcfs_stack = prev_sle and prev_sle['fcfs_stack'] and eval(prev_sle['fcfs_stack']) or []
|
||||
else:
|
||||
prev_sle = sql("select fcfs_stack from `tabStock Ledger Entry` where item_code = '%s' and posting_date <= '%s' order by posting_date DESC, posting_time DESC, name DESC limit 1" % (item_code, nowdate()))
|
||||
fcfs_stack = prev_sle and (prev_sle[0][0] and eval(prev_sle[0][0]) or []) or []
|
||||
@ -499,20 +500,11 @@ class DocType:
|
||||
def get_child_flat_bom_items(self, item, d):
|
||||
|
||||
child_flat_bom_items=[]
|
||||
# if item and (item[0]['is_sub_contracted_item'] == 'Yes' or item[0]['is_pro_applicable'] == 'Yes'):
|
||||
|
||||
child_flat_bom_items = sql("select fbom.item_code, fbom.description, fbom.qty_consumed_per_unit, fbom.stock_uom, fbom.moving_avg_rate, fbom.last_purchase_rate, fbom.standard_rate, '%s' as parent_bom, fbom.bom_mat_no, 'No' as is_pro_applicable from `tabFlat BOM Detail` fbom,`tabBill Of Materials` bom where fbom.parent=bom.name and fbom.parent = '%s' and fbom.is_pro_applicable = 'No' and bom.docstatus = 1" % ( d.bom_no, cstr(d.bom_no)))
|
||||
self.cur_flat_bom_items.append([d.item_code, d.description, flt(d.qty), d.stock_uom, flt(d.moving_avg_rate), flt(d.amount_as_per_mar), flt(d.last_purchase_rate), flt(d.amount_as_per_lpr), flt(d.standard_rate), flt(d.amount_as_per_sr), flt(d.qty_consumed_per_unit), (item[0]['is_sub_contracted_item'] == 'Yes') and d.parent or d.bom_no, d.name, (item[0]['is_sub_contracted_item'] == 'Yes') and 'No' or 'Yes'])
|
||||
return child_flat_bom_items
|
||||
|
||||
# else:
|
||||
# child_flat_bom_items = sql("select item_code, description, qty_consumed_per_unit, stock_uom, moving_avg_rate, last_purchase_rate, standard_rate, if(parent_bom = '%s', '%s', parent_bom) as parent_bom, bom_mat_no, is_pro_applicable from `tabFlat BOM Detail` where parent = '%s' and docstatus = 1" % ( d.bom_no, d.parent, cstr(d.bom_no)))
|
||||
|
||||
# if not child_flat_bom_items:
|
||||
# msgprint("Please Submit Child BOM := %s first." % cstr(d.bom_no))
|
||||
# raise Exception
|
||||
# else:"""
|
||||
|
||||
|
||||
# Get Current Flat BOM Items
|
||||
# -----------------------------
|
||||
|
@ -5,14 +5,14 @@
|
||||
{
|
||||
'creation': '2010-08-08 17:08:52',
|
||||
'docstatus': 0,
|
||||
'modified': '2010-12-20 17:27:58',
|
||||
'modified_by': 'umair@iwebnotes.com',
|
||||
'modified': '2011-11-09 12:47:50',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': '1309508837',
|
||||
'_last_update': '1319016431',
|
||||
'allow_attach': 0,
|
||||
'allow_copy': 0,
|
||||
'allow_email': 0,
|
||||
@ -20,6 +20,7 @@
|
||||
'allow_rename': 0,
|
||||
'allow_trash': 1,
|
||||
'colour': 'White:FFF',
|
||||
'default_print_format': 'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': 'Master',
|
||||
'hide_heading': 0,
|
||||
@ -35,7 +36,7 @@
|
||||
'server_code_error': ' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': '%(item)s',
|
||||
'version': 170
|
||||
'version': 171
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
@ -49,6 +50,7 @@
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': 'Bill Of Materials',
|
||||
@ -68,7 +70,6 @@
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 1,
|
||||
'permlevel': 0,
|
||||
'role': 'System Manager',
|
||||
'submit': 1,
|
||||
@ -77,10 +78,13 @@
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 2,
|
||||
'permlevel': 1,
|
||||
'role': 'System Manager'
|
||||
'role': 'System Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
@ -88,7 +92,6 @@
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 3,
|
||||
'permlevel': 0,
|
||||
'role': 'Production Manager',
|
||||
'submit': 1,
|
||||
@ -97,10 +100,13 @@
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 4,
|
||||
'permlevel': 1,
|
||||
'role': 'Production Manager'
|
||||
'role': 'Production Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
@ -108,7 +114,6 @@
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 5,
|
||||
'permlevel': 0,
|
||||
'role': 'Production User',
|
||||
'submit': 1,
|
||||
@ -117,10 +122,13 @@
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 6,
|
||||
'permlevel': 1,
|
||||
'role': 'Production User'
|
||||
'role': 'Production User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
@ -128,7 +136,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'trash_reason',
|
||||
'fieldtype': 'Small Text',
|
||||
'idx': 1,
|
||||
'label': 'Trash Reason',
|
||||
'oldfieldname': 'trash_reason',
|
||||
'oldfieldtype': 'Small Text',
|
||||
@ -139,7 +146,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'HTML',
|
||||
'idx': 2,
|
||||
'label': 'TreeView1',
|
||||
'oldfieldtype': 'HTML',
|
||||
'options': '<div style=\'border: 1px solid #CCF; padding: 8px;margin-bottom: 8px;\'><div class=\'link_type\' onclick=\'loadpage("Bill of Materials"); \'>Go To BOM Tree View</div></div>',
|
||||
@ -150,7 +156,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 3,
|
||||
'oldfieldtype': 'Section Break',
|
||||
'options': 'Simple',
|
||||
'permlevel': 0
|
||||
@ -162,7 +167,6 @@
|
||||
'colour': 'White:FFF',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'idx': 4,
|
||||
'label': 'Set as Default BOM',
|
||||
'oldfieldtype': 'Button',
|
||||
'permlevel': 0,
|
||||
@ -173,7 +177,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 5,
|
||||
'oldfieldtype': 'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
@ -185,7 +188,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'hidden': 1,
|
||||
'idx': 6,
|
||||
'label': 'Activate BOM',
|
||||
'oldfieldtype': 'Button',
|
||||
'permlevel': 0,
|
||||
@ -199,7 +201,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'hidden': 1,
|
||||
'idx': 7,
|
||||
'label': 'Inactivate BOM',
|
||||
'oldfieldtype': 'Button',
|
||||
'permlevel': 0,
|
||||
@ -210,7 +211,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 8,
|
||||
'label': 'Details',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -223,7 +223,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'item',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 9,
|
||||
'in_filter': 1,
|
||||
'label': 'Item',
|
||||
'oldfieldname': 'item',
|
||||
@ -240,7 +239,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'description',
|
||||
'fieldtype': 'Text',
|
||||
'idx': 10,
|
||||
'label': 'Description',
|
||||
'oldfieldname': 'description',
|
||||
'oldfieldtype': 'Text',
|
||||
@ -255,7 +253,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'quantity',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 11,
|
||||
'label': 'Quantity',
|
||||
'oldfieldname': 'quantity',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -263,13 +260,22 @@
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'uom',
|
||||
'fieldtype': 'Select',
|
||||
'label': 'UOM',
|
||||
'options': 'link:UOM',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': 'White:FFF',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'is_active',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 12,
|
||||
'label': 'Is Active',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': 'is_active',
|
||||
@ -285,7 +291,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'is_default',
|
||||
'fieldtype': 'Check',
|
||||
'idx': 13,
|
||||
'label': 'Is Default',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': 'is_default',
|
||||
@ -299,7 +304,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'project_name',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 14,
|
||||
'in_filter': 1,
|
||||
'label': 'Project Name',
|
||||
'oldfieldname': 'project_name',
|
||||
@ -313,7 +317,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 15,
|
||||
'label': 'Operations',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -326,7 +329,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'bom_operations',
|
||||
'fieldtype': 'Table',
|
||||
'idx': 16,
|
||||
'label': 'BOM Operations',
|
||||
'oldfieldname': 'bom_operations',
|
||||
'oldfieldtype': 'Table',
|
||||
@ -338,7 +340,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 17,
|
||||
'label': 'Materials',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -351,7 +352,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'bom_materials',
|
||||
'fieldtype': 'Table',
|
||||
'idx': 18,
|
||||
'label': 'BOM Material',
|
||||
'oldfieldname': 'bom_materials',
|
||||
'oldfieldtype': 'Table',
|
||||
@ -363,7 +363,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 19,
|
||||
'label': 'Costing',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -375,7 +374,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'remarks',
|
||||
'fieldtype': 'Text',
|
||||
'idx': 20,
|
||||
'label': 'Remarks',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': 'remarks',
|
||||
@ -388,7 +386,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'cost_as_per_mar',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 21,
|
||||
'label': 'Cost As Per Valuation Rate',
|
||||
'oldfieldname': 'cost_as_per_mar',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -400,7 +397,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'cost_as_per_lpr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 22,
|
||||
'label': 'Cost As Per LPR',
|
||||
'oldfieldname': 'cost_as_per_lpr',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -412,7 +408,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'cost_as_per_sr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 23,
|
||||
'label': 'Cost As Per SR',
|
||||
'oldfieldname': 'cost_as_per_sr',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -425,7 +420,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'cost_as_on',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 24,
|
||||
'label': 'Cost as on',
|
||||
'oldfieldname': 'cost_as_on',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -437,7 +431,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'dir_mat_as_per_mar',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 25,
|
||||
'label': 'Direct Material As Per Valuation',
|
||||
'oldfieldname': 'dir_mat_as_per_mar',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -449,7 +442,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'dir_mat_as_per_lpr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 26,
|
||||
'label': 'Direct Material As Per LPR',
|
||||
'oldfieldname': 'dir_mat_as_per_lpr',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -461,7 +453,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'dir_mat_as_per_sr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 27,
|
||||
'label': 'Direct Material As Per SR',
|
||||
'oldfieldname': 'dir_mat_as_per_sr',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -473,7 +464,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'operating_cost',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 28,
|
||||
'label': 'Operating Cost',
|
||||
'oldfieldname': 'operating_cost',
|
||||
'oldfieldtype': 'Currency',
|
||||
@ -485,7 +475,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'maintained_by',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 29,
|
||||
'label': 'Maintained By',
|
||||
'oldfieldname': 'maintained_by',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -497,7 +486,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'hidden': 1,
|
||||
'idx': 30,
|
||||
'label': 'BOM Report',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -508,7 +496,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'hidden': 0,
|
||||
'idx': 31,
|
||||
'label': 'Flat BOM',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -522,7 +509,6 @@
|
||||
'fieldname': 'flat_bom_details',
|
||||
'fieldtype': 'Table',
|
||||
'hidden': 0,
|
||||
'idx': 32,
|
||||
'label': 'Flat BOM Detail',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': 'flat_bom_details',
|
||||
|
@ -329,11 +329,11 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'qty_consumed_per_unit',
|
||||
'fieldtype': 'Currency',
|
||||
'fieldtype': 'Float',
|
||||
'idx': 21,
|
||||
'label': 'Qty Consumed Per Unit',
|
||||
'oldfieldname': 'qty_consumed_per_unit',
|
||||
'oldfieldtype': 'Currency',
|
||||
'oldfieldtype': 'Float',
|
||||
'permlevel': 1
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -5,8 +5,8 @@
|
||||
{
|
||||
'creation': '2010-08-08 17:09:02',
|
||||
'docstatus': 0,
|
||||
'modified': '2010-09-20 14:06:57',
|
||||
'modified_by': 'umair@iwebnotes.com',
|
||||
'modified': '2011-11-10 14:21:40',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'jai@webnotestech.com'
|
||||
},
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
{
|
||||
'autoname': 'FBD/.######',
|
||||
'colour': 'White:FFF',
|
||||
'default_print_format': 'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': 'Production',
|
||||
@ -22,7 +23,7 @@
|
||||
'section_style': 'Simple',
|
||||
'server_code_error': ' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 15
|
||||
'version': 18
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
@ -46,7 +47,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'item_code',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 1,
|
||||
'label': 'Item Code',
|
||||
'oldfieldname': 'item_code',
|
||||
'oldfieldtype': 'Link',
|
||||
@ -58,7 +58,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'description',
|
||||
'fieldtype': 'Text',
|
||||
'idx': 2,
|
||||
'label': 'Description',
|
||||
'oldfieldname': 'description',
|
||||
'oldfieldtype': 'Text',
|
||||
@ -70,7 +69,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'moving_avg_rate',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 5,
|
||||
'label': 'Valuation Rate',
|
||||
'oldfieldname': 'moving_avg_rate',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -81,7 +79,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'amount_as_per_mar',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 6,
|
||||
'label': 'Amount As Per Valuation Rate',
|
||||
'oldfieldname': 'amount_as_per_mar',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -92,7 +89,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'last_purchase_rate',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 7,
|
||||
'label': 'Last Purchase Rate',
|
||||
'oldfieldname': 'last_purchase_rate',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -103,7 +99,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'amount_as_per_lpr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 8,
|
||||
'label': 'Amount As Per LPR',
|
||||
'oldfieldname': 'amount_as_per_lpr',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -114,7 +109,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'qty',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 9,
|
||||
'label': 'Qty',
|
||||
'oldfieldname': 'qty',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -125,7 +119,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'standard_rate',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 9,
|
||||
'label': 'Standard Rate',
|
||||
'oldfieldname': 'standard_rate',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -136,7 +129,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'amount_as_per_sr',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 10,
|
||||
'label': 'Amount As Per SR',
|
||||
'oldfieldname': 'amount_as_per_sr',
|
||||
'oldfieldtype': 'Currency'
|
||||
@ -146,11 +138,10 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'qty_consumed_per_unit',
|
||||
'fieldtype': 'Currency',
|
||||
'idx': 11,
|
||||
'fieldtype': 'Float',
|
||||
'label': 'Qty Consumed Per Unit',
|
||||
'oldfieldname': 'qty_consumed_per_unit',
|
||||
'oldfieldtype': 'Currency'
|
||||
'oldfieldtype': 'Float'
|
||||
},
|
||||
|
||||
# DocField
|
||||
@ -158,12 +149,10 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'stock_uom',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 12,
|
||||
'label': 'Stock UOM',
|
||||
'oldfieldname': 'stock_uom',
|
||||
'oldfieldtype': 'Link',
|
||||
'options': 'UOM',
|
||||
'search_index': 0
|
||||
'options': 'UOM'
|
||||
},
|
||||
|
||||
# DocField
|
||||
@ -172,7 +161,6 @@
|
||||
'fieldname': 'flat_bom_no',
|
||||
'fieldtype': 'Data',
|
||||
'hidden': 1,
|
||||
'idx': 12,
|
||||
'label': 'Flat BOM No',
|
||||
'oldfieldname': 'flat_bom_no',
|
||||
'oldfieldtype': 'Data'
|
||||
@ -184,7 +172,6 @@
|
||||
'fieldname': 'bom_mat_no',
|
||||
'fieldtype': 'Data',
|
||||
'hidden': 0,
|
||||
'idx': 13,
|
||||
'label': 'BOM Mat No',
|
||||
'oldfieldname': 'bom_mat_no',
|
||||
'oldfieldtype': 'Data'
|
||||
@ -196,7 +183,6 @@
|
||||
'fieldname': 'parent_bom',
|
||||
'fieldtype': 'Link',
|
||||
'hidden': 0,
|
||||
'idx': 14,
|
||||
'label': 'Parent BOM',
|
||||
'oldfieldname': 'parent_bom',
|
||||
'oldfieldtype': 'Link'
|
||||
@ -207,11 +193,10 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'is_pro_applicable',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 15,
|
||||
'label': 'Is PRO Applicable',
|
||||
'oldfieldname': 'is_pro_applicable',
|
||||
'oldfieldtype': 'Select',
|
||||
'options': '\nYes\nNo',
|
||||
'reqd': 0
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -101,7 +101,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
|
||||
self.save_stock_entry('Material Transfer')
|
||||
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
|
||||
tn = self.submit_stock_entry(mtn)
|
||||
mtn = self.submit_stock_entry(mtn)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
@ -202,8 +202,54 @@ class TestStockEntry(unittest.TestCase):
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 10]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def test_entries_on_same_datetime(self):
|
||||
print "Test Case: Multiple entries on same datetime, cancel first one"
|
||||
|
||||
# submitted 1st MR
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
# submitted 2nd MR
|
||||
for each in stock_entry.mr1:
|
||||
each.save(1)
|
||||
for t in stock_entry.mr1[1:]:
|
||||
sql("update `tabStock Entry Detail` set parent = '%s' where name = '%s'" % (stock_entry.mr1[0].name, t.name))
|
||||
|
||||
mr1 = get_obj('Stock Entry', stock_entry.mr1[0].name, with_children=1)
|
||||
mr1 = self.submit_stock_entry(mr1)
|
||||
|
||||
|
||||
# submitted MTN
|
||||
self.save_stock_entry('Material Transfer')
|
||||
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
|
||||
mtn = self.submit_stock_entry(mtn)
|
||||
|
||||
# cancel prev MR
|
||||
mr.on_cancel()
|
||||
mr.doc.cancel_reason = "testing"
|
||||
mr.doc.docstatus = 2
|
||||
mr.doc.save()
|
||||
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('entries_on_same_datetime'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':0, 'item_code':'it', 'warehouse':'wh1'},
|
||||
{'doctype':'Bin', 'actual_qty':5, 'item_code':'it', 'warehouse':'wh2'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 0],
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh2', 'status': 'In Store', 'docstatus': 0}, 5]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def save_stock_entry(self, t):
|
||||
if t == 'Material Receipt':
|
||||
@ -373,8 +419,58 @@ class TestStockEntry(unittest.TestCase):
|
||||
'ifnull(bin_aqat, 0)': 0,
|
||||
'ifnull(valuation_rate, 0)': 0,
|
||||
"ifnull(is_cancelled, 'No')": 'Yes'
|
||||
}],
|
||||
'entries_on_same_datetime': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': 10,
|
||||
'bin_aqat': 10,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': -10,
|
||||
'ifnull(bin_aqat, 0)': 0,
|
||||
'ifnull(valuation_rate, 0)': 0,
|
||||
"ifnull(is_cancelled, 'No')": 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr1[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 400,
|
||||
'is_cancelled': 'No'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': -5,
|
||||
'bin_aqat': 0,
|
||||
'valuation_rate': 400,
|
||||
'is_cancelled': 'No'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh2',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}]
|
||||
|
||||
}
|
||||
|
||||
return expected_sle[action]
|
||||
|
34
erpnext/sandbox/testdata/stock_entry.py
vendored
34
erpnext/sandbox/testdata/stock_entry.py
vendored
@ -34,6 +34,38 @@ mr = [
|
||||
)
|
||||
]
|
||||
|
||||
mr1 = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Receipt',
|
||||
'name': 'mr1'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'mr1',
|
||||
'item_code' : 'it',
|
||||
't_warehouse' : 'wh1',
|
||||
'qty' : 5,
|
||||
'transfer_qty' : 5,
|
||||
'incoming_rate': 400,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno11, srno12, srno13, srno14, srno15'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
# Material Transfer
|
||||
#--------------------
|
||||
|
||||
@ -43,7 +75,7 @@ mtn = [
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '13:00',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Transfer',
|
||||
|
@ -56,6 +56,14 @@ pscript.startup_make_sidebar = function() {
|
||||
// menu
|
||||
var ml = r.message;
|
||||
|
||||
// login-file
|
||||
if(r.login_url){
|
||||
login_file = 'http://' + r.login_url;
|
||||
}
|
||||
else if(pscript.is_erpnext_saas) {
|
||||
login_file = 'https://www.erpnext.com';
|
||||
}
|
||||
|
||||
// clear
|
||||
page_body.left_sidebar.innerHTML = '';
|
||||
|
||||
@ -292,13 +300,6 @@ SidebarItem.prototype.show_items = function() {
|
||||
}
|
||||
}
|
||||
|
||||
if(r.login_url){
|
||||
login_file = 'http://' + r.login_url;
|
||||
}
|
||||
else if(pscript.is_erpnext_saas) {
|
||||
login_file = 'https://www.erpnext.com';
|
||||
}
|
||||
|
||||
|
||||
$(me.items_area).slideDown();
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
# 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
|
||||
from webnotes.utils import cint, cstr, flt, nowdate
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import msgprint
|
||||
|
||||
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
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
@ -39,19 +32,13 @@ class DocType:
|
||||
self.doc.save()
|
||||
|
||||
|
||||
# update valuation for post dated entry
|
||||
if actual_qty:
|
||||
# check actual qty with total number of serial no
|
||||
if serial_no:
|
||||
self.check_qty_with_serial_no()
|
||||
|
||||
prev_sle = self.get_prev_sle(dt, posting_time, sle_id)
|
||||
cqty = flt(prev_sle.get('bin_aqat', 0))
|
||||
# Block if actual qty becomes negative
|
||||
if (flt(cqty) + flt(actual_qty)) < 0 and flt(actual_qty) < 0 and is_cancelled == 'No':
|
||||
msgprint('Not enough quantity (requested: %s, current: %s) for Item <b>%s</b> in Warehouse <b>%s</b> as on %s %s' % (flt(actual_qty), flt(cqty), self.doc.item_code, self.doc.warehouse, dt, posting_time), raise_exception = 1)
|
||||
|
||||
self.update_item_valuation(sle_id, dt, posting_time, serial_no, prev_sle)
|
||||
|
||||
# update valuation and qty after transaction for post dated entry
|
||||
self.update_entries_after(dt, posting_time)
|
||||
|
||||
def check_qty_with_serial_no(self):
|
||||
"""
|
||||
@ -59,11 +46,19 @@ class DocType:
|
||||
Temporary validation added on: 18-07-2011
|
||||
"""
|
||||
if sql("select name from `tabItem` where ifnull(has_serial_no, 'No') = 'Yes' and name = '%s'" % self.doc.item_code):
|
||||
sr_count = sql("select count(name) from `tabSerial No` where item_code = '%s' and warehouse = '%s' and status ='In Store' and docstatus != 2" % (self.doc.item_code, self.doc.warehouse))[0][0]
|
||||
sr_count = sql("""select count(name) from `tabSerial No`
|
||||
where item_code = '%s' and warehouse = '%s'
|
||||
and status ='In Store' and docstatus != 2
|
||||
""" % (self.doc.item_code, self.doc.warehouse))[0][0]
|
||||
|
||||
if sr_count != self.doc.actual_qty:
|
||||
msg = "Actual Qty(%s) in Bin is mismatched with total number(%s) of serial no in store for item: '%s' and warehouse: '%s'" % (self.doc.actual_qty, sr_count, self.doc.item_code, self.doc.warehouse)
|
||||
msg = """Actual Qty(%s) in Bin is mismatched with total number(%s) of serial no in store
|
||||
for item: '%s' and warehouse: '%s'""" % \
|
||||
(self.doc.actual_qty, sr_count, self.doc.item_code, self.doc.warehouse)
|
||||
|
||||
if getattr(webnotes.defs,'admin_email_notification',1):
|
||||
sendmail(['developers@iwebnotes.com'], sender='automail@webnotestech.com', subject='Serial No Count vs Bin Actual Qty', parts=[['text/plain', msg]])
|
||||
sendmail(['developers@iwebnotes.com'], sender='automail@webnotestech.com', \
|
||||
subject='Serial No Count vs Bin Actual Qty', parts=[['text/plain', msg]])
|
||||
msgprint(msg, raise_exception=1)
|
||||
|
||||
# --------------------------------
|
||||
@ -81,29 +76,19 @@ class DocType:
|
||||
""", (self.doc.item_code, self.doc.warehouse), as_dict=1)
|
||||
return sle and sle[0] or None
|
||||
|
||||
# --------------------------------
|
||||
# get previous stock ledger entry
|
||||
# --------------------------------
|
||||
|
||||
def get_prev_sle(self, posting_date, posting_time, sle_id = ''):
|
||||
# this function will only be called for a live entry
|
||||
# for which the "name" will be the latest (even for the same timestamp)
|
||||
# and even for a back-dated entry
|
||||
# hence there cannot be any "backdated entries" with a name greater than the
|
||||
# current one
|
||||
def get_prev_sle(self, posting_date = '1900-01-01', posting_time = '12:00', sle_id = ''):
|
||||
"""
|
||||
get the last sle on or before the current time-bucket,
|
||||
to get actual qty before transaction, this function
|
||||
is called from various transaction like stock entry, reco etc
|
||||
"""
|
||||
|
||||
# if there are multiple entries on this timestamp, then the last one will be with
|
||||
# the last "name"
|
||||
# else, the last entry will be the highest name at the previous timestamp
|
||||
# hence, the double sort on timestamp and name should be sufficient condition
|
||||
# to get the last sle
|
||||
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and name != %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and name != %s
|
||||
and timestamp(posting_date, posting_time) <= timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) desc, name desc
|
||||
limit 1
|
||||
@ -112,25 +97,49 @@ class DocType:
|
||||
return sle and sle[0] or {}
|
||||
|
||||
|
||||
def get_sle_prev_timebucket(self, posting_date = '1900-01-01', posting_time = '12:00'):
|
||||
"""get previous stock ledger entry before current time-bucket"""
|
||||
# get the last sle before the current time-bucket, so that all values
|
||||
# are reposted from the current time-bucket onwards.
|
||||
# this is necessary because at the time of cancellation, there may be
|
||||
# entries between the cancelled entries in the same time-bucket
|
||||
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and timestamp(posting_date, posting_time) < timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) desc, name desc
|
||||
limit 1
|
||||
""", (self.doc.item_code, self.doc.warehouse, posting_date, posting_time), as_dict=1)
|
||||
|
||||
return sle and sle[0] or {}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------------------------------
|
||||
# validate negative stock (validate if stock is going -ve in between for back dated entries will consider only is_cancel = 'No' entries)
|
||||
# --------------------------------------------------------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------
|
||||
def validate_negative_stock(self, cqty, s):
|
||||
"""
|
||||
validate negative stock for entries current datetime onwards
|
||||
will not consider cancelled entries
|
||||
"""
|
||||
diff = cqty + s['actual_qty']
|
||||
if diff < 0 and (abs(diff) > 0.0001) and s['is_cancelled'] != 'Yes':
|
||||
if diff < 0 and (abs(diff) > 0.0001) and s['is_cancelled'] == 'No':
|
||||
msgprint("""
|
||||
Negative stock error:
|
||||
Cannot complete this transaction because stock will
|
||||
become negative (%s) in future transaction for Item
|
||||
<b>%s</b> in Warehouse <b>%s</b> on <b>%s %s</b>""" % \
|
||||
(str(diff), self.doc.item_code, self.doc.warehouse,
|
||||
s['posting_date'], s['posting_time']), raise_exception=1)
|
||||
become negative (%s) for Item <b>%s</b> in Warehouse
|
||||
<b>%s</b> on <b>%s %s</b> in Transaction %s %s""" % \
|
||||
(str(diff), self.doc.item_code, self.doc.warehouse, \
|
||||
s['posting_date'], s['posting_time'], s['voucher_type'], s['voucher_no']), \
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
# ------------------------------------
|
||||
# get serialized inventory values
|
||||
# ------------------------------------
|
||||
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: # In case of delivery/stock issue, get average purchase rate of serial nos of current entry
|
||||
@ -222,11 +231,16 @@ class DocType:
|
||||
stock_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
|
||||
return stock_val
|
||||
|
||||
# ----------------------
|
||||
# update item valuation
|
||||
# ----------------------
|
||||
def update_item_valuation(self, sle_id=None, posting_date=None, posting_time=None, serial_no=None, prev_sle=None):
|
||||
# no sle given, start from the first one (for repost)
|
||||
def update_entries_after(self, posting_date, posting_time):
|
||||
"""
|
||||
update valution rate and qty after transaction
|
||||
from the current time-bucket onwards
|
||||
"""
|
||||
|
||||
# Get prev sle
|
||||
prev_sle = self.get_sle_prev_timebucket(posting_date, posting_time)
|
||||
|
||||
# if no prev sle, start from the first one (for repost)
|
||||
if not prev_sle:
|
||||
cqty, cval, val_rate, self.fcfs_bal = 0, 0, 0, []
|
||||
|
||||
@ -237,11 +251,11 @@ class DocType:
|
||||
val_rate = flt(prev_sle.get('valuation_rate', 0))
|
||||
self.fcfs_bal = eval(prev_sle.get('fcfs_stack', '[]') or '[]')
|
||||
|
||||
val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code) # get valuation method
|
||||
# get valuation method
|
||||
val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code)
|
||||
|
||||
# recalculate the balances for all stock ledger entries
|
||||
# after this one (so that the corrected balance will reflect
|
||||
# correctly in all entries after this one)
|
||||
# after the prev sle
|
||||
sll = sql("""
|
||||
select *
|
||||
from `tabStock Ledger Entry`
|
||||
@ -250,30 +264,32 @@ class DocType:
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and timestamp(posting_date, posting_time) > timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) asc, name asc""", \
|
||||
(self.doc.item_code, self.doc.warehouse, posting_date, posting_time), as_dict = 1)
|
||||
(self.doc.item_code, self.doc.warehouse, \
|
||||
prev_sle.get('posting_date','1900-01-01'), prev_sle.get('posting_time', '12:00')), as_dict = 1)
|
||||
|
||||
# if in live entry - update the values of the current sle
|
||||
if sle_id:
|
||||
sll = sql("select * from `tabStock Ledger Entry` where name=%s and ifnull(is_cancelled, 'No') = 'No'", sle_id, as_dict=1) + sll
|
||||
for s in sll:
|
||||
for sle in sll:
|
||||
# block if stock level goes negative on any date
|
||||
self.validate_negative_stock(cqty, s)
|
||||
self.validate_negative_stock(cqty, sle)
|
||||
|
||||
stock_val, in_rate = 0, s['incoming_rate'] # IN
|
||||
serial_nos = s["serial_no"] and ("'"+"', '".join(cstr(s["serial_no"]).split('\n')) + "'") or ''
|
||||
stock_val, in_rate = 0, sle['incoming_rate'] # IN
|
||||
serial_nos = sle["serial_no"] and ("'"+"', '".join(cstr(sle["serial_no"]).split('\n')) \
|
||||
+ "'") or ''
|
||||
|
||||
# Get valuation rate
|
||||
val_rate, stock_val = self.get_valuation_rate(val_method, serial_nos, val_rate, in_rate, stock_val, cqty, s)
|
||||
val_rate, stock_val = self.get_valuation_rate(val_method, serial_nos, \
|
||||
val_rate, in_rate, stock_val, cqty, sle)
|
||||
|
||||
# Qty upto the sle
|
||||
cqty += s['actual_qty']
|
||||
cqty += sle['actual_qty']
|
||||
|
||||
# Stock Value upto the sle
|
||||
stock_val = self.get_stock_value(val_method, cqty, stock_val, serial_nos)
|
||||
# update current sle --> will it be good to update incoming rate in sle for outgoing stock entry?????
|
||||
|
||||
# update current sle --> will it be good to update incoming rate in sle
|
||||
# for outgoing stock entry?????
|
||||
sql("""update `tabStock Ledger Entry`
|
||||
set bin_aqat=%s, valuation_rate=%s, fcfs_stack=%s, stock_value=%s
|
||||
where name=%s""", (cqty, flt(val_rate), cstr(self.fcfs_bal), stock_val, s['name']))
|
||||
where name=%s""", (cqty, flt(val_rate), cstr(self.fcfs_bal), stock_val, sle['name']))
|
||||
|
||||
# update the bin
|
||||
if sll:
|
||||
|
@ -86,9 +86,9 @@ class DocType:
|
||||
d.save()
|
||||
sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
|
||||
|
||||
bin_name = sql("select t1.name, t2.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
|
||||
bin_name = sql("select t1.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
|
||||
if bin_name and bin_name[0][0]:
|
||||
obj = get_obj('Bin', bin_name[0][0]).update_item_valuation(bin_name[0][1], bin_name[0][2], bin_name[0][3])
|
||||
obj = get_obj('Bin', bin_name[0][0]).update_entries_after(bin_name[0][1], bin_name[0][2])
|
||||
|
||||
# now distribute the taxes among the PRs
|
||||
for lc in getlist(self.doclist, 'landed_cost_details'):
|
||||
@ -140,11 +140,11 @@ class DocType:
|
||||
d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
|
||||
d.save()
|
||||
sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
|
||||
bin_name = sql("select t1.name, t2.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
|
||||
bin_name = sql("select t1.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
|
||||
|
||||
# update valuation of the item
|
||||
if bin_name and bin_name[0][0]:
|
||||
obj = get_obj('Bin', bin_name[0][0]).update_item_valuation(bin_name[0][1], bin_name[0][2], bin_name[0][3])
|
||||
obj = get_obj('Bin', bin_name[0][0]).update_entries_after(bin_name[0][1], bin_name[0][2])
|
||||
|
||||
def add_deduct_taxes(self, ocd, oc, tax_amount, total_amount, total, prev_total, f=1):
|
||||
ocd[oc].total_amount = flt(tax_amount.toFixed(2))
|
||||
|
@ -121,19 +121,46 @@ class DocType:
|
||||
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)
|
||||
"""
|
||||
get all items from flat bom except
|
||||
child items of sub-contracted and sub assembly items
|
||||
and sub assembly items itself.
|
||||
"""
|
||||
|
||||
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)))
|
||||
# Get all raw materials considering SA items as raw materials,
|
||||
# so no childs of SA items
|
||||
|
||||
fl_bom_sa_items = sql("""
|
||||
select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom
|
||||
from `tabBOM Material`
|
||||
where parent = '%s' 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)))
|
||||
|
||||
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
|
||||
#select item_code,ifnull(sum(qty_consumed_per_unit),0)*'%s' as qty,description,stock_uom from ( select distinct fb.name,fb.description,fb.item_code,fb.qty_consumed_per_unit,fb.stock_uom from `tabFlat BOM Detail` fb,`tabBOM Material` bm where bm.parent=fb.parent_bom and bm.docstatus<2 and fb.is_pro_applicable='Yes' and fb.docstatus<2 and fb.parent='%s' and bm.bom_no is null)a group by item_code,stock_uom
|
||||
fl_bom_sa_child_item = sql("select item_code,ifnull(sum(qty_consumed_per_unit),0)*'%s' as qty,description,stock_uom from ( select distinct fb.name,fb.description,fb.item_code,fb.qty_consumed_per_unit,fb.stock_uom from `tabFlat BOM Detail` fb,`tabBOM Material` bm where bm.parent=fb.parent_bom and bm.docstatus<2 and fb.is_pro_applicable='Yes' and fb.docstatus<2 and fb.parent='%s' and bm.bom_no is null)a group by item_code,stock_uom" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no)))
|
||||
# get all raw materials with sub assembly childs
|
||||
|
||||
fl_bom_sa_child_item = sql("""
|
||||
select
|
||||
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,description,stock_uom
|
||||
from
|
||||
(
|
||||
select distinct fb.name, fb.description, fb.item_code, fb.qty_consumed_per_unit, fb.stock_uom
|
||||
from `tabFlat BOM Detail` fb,`tabItem` it
|
||||
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No'
|
||||
and fb.docstatus<2 and fb.parent=%s
|
||||
) a
|
||||
group by item_code,stock_uom
|
||||
""" , ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) \
|
||||
or flt(pro_obj.doc.qty), 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):
|
||||
@ -179,11 +206,10 @@ class DocType:
|
||||
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
|
||||
|
||||
if d.s_warehouse and 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'):
|
||||
|
@ -131,18 +131,18 @@ class DocType:
|
||||
update item valuation in previous date and also on post date if no qty diff
|
||||
"""
|
||||
|
||||
self.update_item_valuation_pre_date(d)
|
||||
self.update_entries_pre_date(d)
|
||||
|
||||
if not flt(d[self.label['qty']]) and not flt(d[self.label['actual_qty']]):
|
||||
# seems like a special condition when there is no actual quanitity but there is a rate, may be only for setting a rate!
|
||||
self.make_sl_entry(1,d,1)
|
||||
self.make_sl_entry(1,d,-1)
|
||||
elif not qty_diff:
|
||||
self.update_item_valuation_post_date(d)
|
||||
self.update_entries_post_date(d)
|
||||
|
||||
# update valuation rate as csv file in all sle before reconciliation date
|
||||
# ------------------------------------------------------------------------
|
||||
def update_item_valuation_pre_date(self, d):
|
||||
def update_entries_pre_date(self, d):
|
||||
mar = flt(d[self.label['mar']])
|
||||
|
||||
# previous sle
|
||||
@ -168,15 +168,12 @@ class DocType:
|
||||
|
||||
# Update item valuation in all sle after the reconcliation date
|
||||
# ---------------------------------------------------------
|
||||
def update_item_valuation_post_date(self, d):
|
||||
def update_entries_post_date(self, d):
|
||||
bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d[self.label['item_code']], d[self.label['warehouse']]))
|
||||
bin_obj = get_obj('Bin', bin[0][0])
|
||||
|
||||
# prev sle
|
||||
prev_sle = bin_obj.get_prev_sle(self.doc.reconciliation_date,self.doc.reconciliation_time)
|
||||
|
||||
# update valuation in sle posted after reconciliation datetime
|
||||
bin_obj.update_item_valuation(posting_date = self.doc.reconciliation_date, posting_time = self.doc.reconciliation_time, prev_sle = prev_sle)
|
||||
bin_obj.update_entries_after(posting_date = self.doc.reconciliation_date, posting_time = self.doc.reconciliation_time)
|
||||
|
||||
# --------------
|
||||
# make sl entry
|
||||
|
@ -85,7 +85,7 @@ class DocType:
|
||||
for w in wh:
|
||||
bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (self.doc.item_code, w[0]))
|
||||
if bin and bin[0][0]:
|
||||
get_obj("Bin", bin[0][0]).update_item_valuation(sle_id = '', posting_date = '', posting_time = '')
|
||||
get_obj("Bin", bin[0][0]).update_entries_after(posting_date = '', posting_time = '')
|
||||
|
||||
# acknowledge user
|
||||
msgprint("Item Valuation Updated Successfully.")
|
||||
|
@ -68,7 +68,7 @@ class DocType:
|
||||
bl = sql("select name from tabBin where warehouse=%s", self.doc.name)
|
||||
for b in bl:
|
||||
bobj = get_obj('Bin',b[0])
|
||||
bobj.update_item_valuation(posting_date = '2000-01-01', posting_time = '12:00')
|
||||
bobj.update_entries_after(posting_date = '0000-00-00', posting_time = '00:00')
|
||||
|
||||
sql("COMMIT")
|
||||
sql("START TRANSACTION")
|
||||
|
@ -88,7 +88,7 @@ class DocType:
|
||||
bin_act_qty = flt(bin_obj.doc.actual_qty)
|
||||
try:
|
||||
# udpate actual qty and item valuation
|
||||
bin_obj.update_item_valuation('', '2000-01-01', '00:00')
|
||||
bin_obj.update_entries_after('0000-00-00', '00:00')
|
||||
# get bin qty
|
||||
qty_dict = self.get_bin_qty(bin_obj.doc.warehouse, bin_obj.doc.item_code)
|
||||
|
||||
|
@ -79,4 +79,4 @@ throw new SyntaxError('JSON.parse');};}}());wn.versions.check();wn.require("lib/
|
||||
</div>
|
||||
<script>wn.require('js/app.js');</script>
|
||||
<div id="dialog_back"></div>
|
||||
</body>
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user