Merge pull request #32 from nabinhait/master
Small issues fixed
diff --git a/patches/patch.py b/patches/patch.py
index 2fbffd8..e84200f 100644
--- a/patches/patch.py
+++ b/patches/patch.py
@@ -1,7 +1,7 @@
# REMEMBER to update this
# ========================
-last_patch = 332
+last_patch = 334
#-------------------------------------------
@@ -1343,3 +1343,12 @@
p.add_permission('Lease Agreement', 'Accounts Manager', 1, read = 1)
elif patch_no == 332:
sql("update `tabDocField` set permlevel=1, hidden = 1 where parent = 'Bulk Rename Tool' and fieldname = 'file_list'")
+ elif patch_no == 333:
+ sql("update `tabDocPerm` set create =1 where role = 'Accounts Manager' and parent = 'Lease Agreement'")
+
+ p = get_obj('Patch Util')
+ p.add_permission('DocType Mapper', 'System Manager', 0, read = 1, write=1, create=1)
+ p.add_permission('Role', 'System Manager', 0, read = 1, write=1, create=1)
+ p.add_permission('Print Format', 'System Manager', 0, read = 1, write=1, create=1)
+ elif patch_no == 334:
+ reload_doc('knowledge_base', 'doctype', 'answer')
diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
index 25dd960..7a1af22 100644
--- a/selling/doctype/sales_common/sales_common.py
+++ b/selling/doctype/sales_common/sales_common.py
@@ -329,6 +329,28 @@
il.append([warehouse, d.item_code, qty, reserved_qty, d.stock_uom, d.batch_no, d.serial_no])
return il
+ # ---------------------------------------------------------------------------------------------
+ # 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
+ if curr_parent_doctype == 'Installation Note':
+ curr_det = 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))
+ qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
+ else:
+ curr_det = sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
+ 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
+ ref_det = sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, 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
+
+ return qty, max_qty, amt, max_amt
+
+
+
+
# -----------------------
# add packing list items
@@ -458,26 +480,6 @@
def update_prevdoc_detail(self, is_submit, obj):
StatusUpdater(obj, is_submit).update()
- # ---------------------------------------------------------------------------------------------
- # 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
- if curr_parent_doctype == 'Installation Note':
- curr_det = 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))
- qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
- else:
- curr_det = sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
- 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
- ref_det = sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, 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
-
- return qty, max_qty, amt, max_amt
-
-
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 11842fb..9dee82e 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -19,470 +19,470 @@
from utilities.transaction_base import TransactionBase
class DocType(TransactionBase):
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
- self.tname = 'Sales Order Detail'
- self.fname = 'sales_order_details'
- self.person_tname = 'Target Detail'
- self.partner_tname = 'Partner Target Detail'
- self.territory_tname = 'Territory Target Detail'
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+ self.tname = 'Sales Order Detail'
+ self.fname = 'sales_order_details'
+ self.person_tname = 'Target Detail'
+ self.partner_tname = 'Partner Target Detail'
+ self.territory_tname = 'Territory Target Detail'
# Autoname
# ===============
- def autoname(self):
- self.doc.name = make_autoname(self.doc.naming_series+'.#####')
+ def autoname(self):
+ self.doc.name = make_autoname(self.doc.naming_series+'.#####')
-
+
# DOCTYPE TRIGGER FUNCTIONS
# =============================
- # Pull Quotation Details
- # -----------------------
- def pull_quotation_details(self):
- self.doc.clear_table(self.doclist, 'other_charges')
- self.doc.clear_table(self.doclist, 'sales_order_details')
- self.doc.clear_table(self.doclist, 'sales_team')
- self.doc.clear_table(self.doclist, 'tc_details')
- if self.doc.quotation_no:
- get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Detail', 'Sales Order Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]")
- else:
- msgprint("Please select Quotation whose details need to pull")
+ # Pull Quotation Details
+ # -----------------------
+ def pull_quotation_details(self):
+ self.doc.clear_table(self.doclist, 'other_charges')
+ self.doc.clear_table(self.doclist, 'sales_order_details')
+ self.doc.clear_table(self.doclist, 'sales_team')
+ self.doc.clear_table(self.doclist, 'tc_details')
+ if self.doc.quotation_no:
+ get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Detail', 'Sales Order Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]")
+ else:
+ msgprint("Please select Quotation whose details need to pull")
- return cstr(self.doc.quotation_no)
-
- #pull project customer
- #-------------------------
- def pull_project_customer(self):
- res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
- if res:
- get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]")
-
-
- # Get Customer Details
- # ---------------------
- #def get_customer_details(self):
- # sales_com_obj = get_obj('Sales Common')
- # sales_com_obj.get_customer_details(self)
- # sales_com_obj.get_shipping_details(self)
+ return cstr(self.doc.quotation_no)
+
+ #pull project customer
+ #-------------------------
+ def pull_project_customer(self):
+ res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
+ if res:
+ get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]")
+
+
+ # Get Customer Details
+ # ---------------------
+ #def get_customer_details(self):
+ # sales_com_obj = get_obj('Sales Common')
+ # sales_com_obj.get_customer_details(self)
+ # sales_com_obj.get_shipping_details(self)
- # Get contact person details based on customer selected
- # ------------------------------------------------------
- def get_contact_details(self):
- get_obj('Sales Common').get_contact_details(self,0)
+ # Get contact person details based on customer selected
+ # ------------------------------------------------------
+ def get_contact_details(self):
+ get_obj('Sales Common').get_contact_details(self,0)
- # Get Commission rate of Sales Partner
- # -------------------------------------
- def get_comm_rate(self, sales_partner):
- return get_obj('Sales Common').get_comm_rate(sales_partner, self)
+ # Get Commission rate of Sales Partner
+ # -------------------------------------
+ def get_comm_rate(self, sales_partner):
+ return get_obj('Sales Common').get_comm_rate(sales_partner, self)
- # Clear Sales Order Details Table
- # --------------------------------
- def clear_sales_order_details(self):
- self.doc.clear_table(self.doclist, 'sales_order_details')
-
+ # Clear Sales Order Details Table
+ # --------------------------------
+ def clear_sales_order_details(self):
+ self.doc.clear_table(self.doclist, 'sales_order_details')
+
# SALES ORDER DETAILS TRIGGER FUNCTIONS
# ================================================================================
- # Get Item Details
- # ----------------
- def get_item_details(self, item_code):
- return get_obj('Sales Common').get_item_details(item_code, self)
+ # Get Item Details
+ # ----------------
+ def get_item_details(self, item_code):
+ return get_obj('Sales Common').get_item_details(item_code, self)
- # Re-calculates Basic Rate & amount based on Price List Selected
- # --------------------------------------------------------------
- def get_adj_percent(self, arg=''):
- get_obj('Sales Common').get_adj_percent(self)
+ # Re-calculates Basic Rate & amount based on Price List Selected
+ # --------------------------------------------------------------
+ def get_adj_percent(self, arg=''):
+ get_obj('Sales Common').get_adj_percent(self)
- # Get projected qty of item based on warehouse selected
- # -----------------------------------------------------
- def get_available_qty(self,args):
- args = eval(args)
- tot_avail_qty = sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
- ret = {
- 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0,
- 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0
- }
- return cstr(ret)
-
-
+ # Get projected qty of item based on warehouse selected
+ # -----------------------------------------------------
+ def get_available_qty(self,args):
+ args = eval(args)
+ tot_avail_qty = sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
+ ret = {
+ 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0,
+ 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0
+ }
+ return cstr(ret)
+
+
# OTHER CHARGES TRIGGER FUNCTIONS
# ====================================================================================
-
- # Get Tax rate if account type is TAX
- # ------------------------------------
- def get_rate(self,arg):
- return get_obj('Sales Common').get_rate(arg)
+
+ # Get Tax rate if account type is TAX
+ # ------------------------------------
+ def get_rate(self,arg):
+ return get_obj('Sales Common').get_rate(arg)
- # Load Default Charges
- # ----------------------------------------------------------
- def load_default_taxes(self):
- return get_obj('Sales Common').load_default_taxes(self)
+ # Load Default Charges
+ # ----------------------------------------------------------
+ def load_default_taxes(self):
+ return get_obj('Sales Common').load_default_taxes(self)
- # Pull details from other charges master (Get Other Charges)
- # ----------------------------------------------------------
- def get_other_charges(self):
- return get_obj('Sales Common').get_other_charges(self)
+ # Pull details from other charges master (Get Other Charges)
+ # ----------------------------------------------------------
+ def get_other_charges(self):
+ return get_obj('Sales Common').get_other_charges(self)
# GET TERMS & CONDITIONS
# =====================================================================================
- def get_tc_details(self):
- return get_obj('Sales Common').get_tc_details(self)
+ def get_tc_details(self):
+ return get_obj('Sales Common').get_tc_details(self)
#check if maintenance schedule already generated
#============================================
- def check_maintenance_schedule(self):
- nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name)
- nm = nm and nm[0][0] or ''
-
- if not nm:
- return cstr('No')
+ def check_maintenance_schedule(self):
+ nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name)
+ nm = nm and nm[0][0] or ''
+
+ if not nm:
+ return cstr('No')
#check if maintenance visit already generated
#============================================
- def check_maintenance_visit(self):
- nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name)
- nm = nm and nm[0][0] or ''
-
- if not nm:
- return cstr('No')
+ def check_maintenance_visit(self):
+ nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name)
+ nm = nm and nm[0][0] or ''
+
+ if not nm:
+ return cstr('No')
# VALIDATE
# =====================================================================================
- # Fiscal Year Validation
- # ----------------------
- def validate_fiscal_year(self):
- get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date')
-
- # Validate values with reference document
- #----------------------------------------
- def validate_reference_value(self):
- get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name)
+ # Fiscal Year Validation
+ # ----------------------
+ def validate_fiscal_year(self):
+ get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date')
+
+ # Validate values with reference document
+ #----------------------------------------
+ def validate_reference_value(self):
+ get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name)
- # Validate Mandatory
- # -------------------
- def validate_mandatory(self):
- # validate transaction date v/s delivery date
- if self.doc.delivery_date:
- if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date):
- msgprint("Expected Delivery Date cannot be before Sales Order Date")
- raise Exception
+ # Validate Mandatory
+ # -------------------
+ def validate_mandatory(self):
+ # validate transaction date v/s delivery date
+ if self.doc.delivery_date:
+ if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date):
+ msgprint("Expected Delivery Date cannot be before Sales Order Date")
+ raise Exception
- # Validate P.O Date
- # ------------------
- def validate_po_date(self):
- # validate p.o date v/s delivery date
- if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) >= getdate(self.doc.delivery_date):
- msgprint("Expected Delivery Date cannot be before Purchase Order Date")
- raise Exception
- # amendment date is necessary if document is amended
- if self.doc.amended_from and not self.doc.amendment_date:
- msgprint("Please Enter Amendment Date")
- raise Exception
-
- # Validations of Details Table
- # -----------------------------
- def validate_for_items(self):
- check_list,flag = [],0
- chk_dupl_itm = []
- # Sales Order Details Validations
- for d in getlist(self.doclist, 'sales_order_details'):
- if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname):
- flag = 1
- if d.prevdoc_docname:
- if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date):
- msgprint("Sales Order Date cannot be before Quotation Date")
- raise Exception
- # validates whether quotation no in doctype and in table is same
- if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no):
- msgprint("Items in table does not belong to the Quotation No mentioned.")
- raise Exception
+ # Validate P.O Date
+ # ------------------
+ def validate_po_date(self):
+ # validate p.o date v/s delivery date
+ if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) >= getdate(self.doc.delivery_date):
+ msgprint("Expected Delivery Date cannot be before Purchase Order Date")
+ raise Exception
+ # amendment date is necessary if document is amended
+ if self.doc.amended_from and not self.doc.amendment_date:
+ msgprint("Please Enter Amendment Date")
+ raise Exception
+
+ # Validations of Details Table
+ # -----------------------------
+ def validate_for_items(self):
+ check_list,flag = [],0
+ chk_dupl_itm = []
+ # Sales Order Details Validations
+ for d in getlist(self.doclist, 'sales_order_details'):
+ if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname):
+ flag = 1
+ if d.prevdoc_docname:
+ if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date):
+ msgprint("Sales Order Date cannot be before Quotation Date")
+ raise Exception
+ # validates whether quotation no in doctype and in table is same
+ if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no):
+ msgprint("Items in table does not belong to the Quotation No mentioned.")
+ raise Exception
- # validates whether item is not entered twice
- e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or '']
- f = [d.item_code, d.description]
+ # validates whether item is not entered twice
+ e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or '']
+ f = [d.item_code, d.description]
- #check item is stock item
- st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
+ #check item is stock item
+ st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
- if st_itm and st_itm[0][0] == 'Yes':
- if e in check_list:
- msgprint("Item %s has been entered twice." % d.item_code)
- else:
- check_list.append(e)
- elif st_itm and st_itm[0][0]== 'No':
- if f in chk_dupl_itm:
- msgprint("Item %s has been entered twice." % d.item_code)
- else:
- chk_dupl_itm.append(f)
+ if st_itm and st_itm[0][0] == 'Yes':
+ if e in check_list:
+ msgprint("Item %s has been entered twice." % d.item_code)
+ else:
+ check_list.append(e)
+ elif st_itm and st_itm[0][0]== 'No':
+ if f in chk_dupl_itm:
+ msgprint("Item %s has been entered twice." % d.item_code)
+ else:
+ chk_dupl_itm.append(f)
- # used for production plan
- d.transaction_date = self.doc.transaction_date
- d.delivery_date = self.doc.delivery_date
+ # used for production plan
+ d.transaction_date = self.doc.transaction_date
+ d.delivery_date = self.doc.delivery_date
- # gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item)
- tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse))
- d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
-
- if flag == 0:
- msgprint("There are no items of the quotation selected.")
- raise Exception
+ # gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item)
+ tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse))
+ d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
+
+ if flag == 0:
+ msgprint("There are no items of the quotation selected.")
+ raise Exception
- # validate sales/ service item against order type
- #----------------------------------------------------
- def validate_sales_mntc_item(self):
- if self.doc.order_type == 'Maintenance':
- item_field = 'is_service_item'
- order_type = 'Maintenance Order'
- item_type = 'service item'
- else :
- item_field = 'is_sales_item'
- order_type = 'Sales Order'
- item_type = 'sales item'
-
- for d in getlist(self.doclist, 'sales_order_details'):
- res = sql("select %s from `tabItem` where name='%s'"% (item_field,d.item_code))
- res = res and res[0][0] or 'No'
-
- if res == 'No':
- msgprint("You can not select non "+item_type+" "+d.item_code+" in "+order_type)
- raise Exception
-
- # validate sales/ maintenance quotation against order type
- #------------------------------------------------------------------
- def validate_sales_mntc_quotation(self):
- for d in getlist(self.doclist, 'sales_order_details'):
- if d.prevdoc_docname:
- res = sql("select order_type from `tabQuotation` where name=%s", (d.prevdoc_docname))
- res = res and res[0][0] or ''
-
- if self.doc.order_type== 'Maintenance' and res != 'Maintenance':
- msgprint("You can not select non Maintenance Quotation against Maintenance Order")
- raise Exception
- elif self.doc.order_type != 'Maintenance' and res == 'Maintenance':
- msgprint("You can not select non Sales Quotation against Sales Order")
- raise Exception
+ # validate sales/ service item against order type
+ #----------------------------------------------------
+ def validate_sales_mntc_item(self):
+ if self.doc.order_type == 'Maintenance':
+ item_field = 'is_service_item'
+ order_type = 'Maintenance Order'
+ item_type = 'service item'
+ else :
+ item_field = 'is_sales_item'
+ order_type = 'Sales Order'
+ item_type = 'sales item'
+
+ for d in getlist(self.doclist, 'sales_order_details'):
+ res = sql("select %s from `tabItem` where name='%s'"% (item_field,d.item_code))
+ res = res and res[0][0] or 'No'
+
+ if res == 'No':
+ msgprint("You can not select non "+item_type+" "+d.item_code+" in "+order_type)
+ raise Exception
+
+ # validate sales/ maintenance quotation against order type
+ #------------------------------------------------------------------
+ def validate_sales_mntc_quotation(self):
+ for d in getlist(self.doclist, 'sales_order_details'):
+ if d.prevdoc_docname:
+ res = sql("select order_type from `tabQuotation` where name=%s", (d.prevdoc_docname))
+ res = res and res[0][0] or ''
+
+ if self.doc.order_type== 'Maintenance' and res != 'Maintenance':
+ msgprint("You can not select non Maintenance Quotation against Maintenance Order")
+ raise Exception
+ elif self.doc.order_type != 'Maintenance' and res == 'Maintenance':
+ msgprint("You can not select non Sales Quotation against Sales Order")
+ raise Exception
- #do not allow sales item/quotation in maintenance order and service item/quotation in sales order
- #-----------------------------------------------------------------------------------------------
- def validate_order_type(self):
- #validate delivery date
- if self.doc.order_type != 'Maintenance' and not self.doc.delivery_date:
- msgprint("Please enter 'Expected Delivery Date'")
- raise Exception
-
- self.validate_sales_mntc_quotation()
- self.validate_sales_mntc_item()
+ #do not allow sales item/quotation in maintenance order and service item/quotation in sales order
+ #-----------------------------------------------------------------------------------------------
+ def validate_order_type(self):
+ #validate delivery date
+ if self.doc.order_type != 'Maintenance' and not self.doc.delivery_date:
+ msgprint("Please enter 'Expected Delivery Date'")
+ raise Exception
+
+ self.validate_sales_mntc_quotation()
+ self.validate_sales_mntc_item()
- #check for does customer belong to same project as entered..
- #-------------------------------------------------------------------------------------------------
- def validate_proj_cust(self):
- if self.doc.project_name and self.doc.customer_name:
- res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
- if not res:
- msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name))
- raise Exception
-
+ #check for does customer belong to same project as entered..
+ #-------------------------------------------------------------------------------------------------
+ def validate_proj_cust(self):
+ if self.doc.project_name and self.doc.customer_name:
+ res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
+ if not res:
+ msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name))
+ raise Exception
+
- # Validate
- # ---------
- def validate(self):
- self.validate_fiscal_year()
- self.validate_order_type()
- self.validate_mandatory()
- self.validate_proj_cust()
- self.validate_po_date()
- #self.validate_reference_value()
- self.validate_for_items()
- sales_com_obj = get_obj(dt = 'Sales Common')
- sales_com_obj.check_active_sales_items(self)
- sales_com_obj.check_conversion_rate(self)
+ # Validate
+ # ---------
+ def validate(self):
+ self.validate_fiscal_year()
+ self.validate_order_type()
+ self.validate_mandatory()
+ self.validate_proj_cust()
+ self.validate_po_date()
+ #self.validate_reference_value()
+ self.validate_for_items()
+ sales_com_obj = get_obj(dt = 'Sales Common')
+ sales_com_obj.check_active_sales_items(self)
+ sales_com_obj.check_conversion_rate(self)
- # verify whether rate is not greater than max_discount
- sales_com_obj.validate_max_discount(self,'sales_order_details')
- # this is to verify that the allocated % of sales persons is 100%
- sales_com_obj.get_allocated_sum(self)
- sales_com_obj.make_packing_list(self,'sales_order_details')
-
- # get total in words
- dcc = TransactionBase().get_company_currency(self.doc.company)
- self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
- self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
-
- # set SO status
- self.doc.status='Draft'
- if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
- if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
-
+ # verify whether rate is not greater than max_discount
+ sales_com_obj.validate_max_discount(self,'sales_order_details')
+ # this is to verify that the allocated % of sales persons is 100%
+ sales_com_obj.get_allocated_sum(self)
+ sales_com_obj.make_packing_list(self,'sales_order_details')
+
+ # get total in words
+ dcc = TransactionBase().get_company_currency(self.doc.company)
+ self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
+ self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
+
+ # set SO status
+ self.doc.status='Draft'
+ if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
+ if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
+
# ON SUBMIT
# ===============================================================================================
- # Checks Quotation Status
- # ------------------------
- def check_prev_docstatus(self):
- for d in getlist(self.doclist, 'sales_order_details'):
- cancel_quo = sql("select name from `tabQuotation` where docstatus = 2 and name = '%s'" % d.prevdoc_docname)
- if cancel_quo:
- msgprint("Quotation :" + cstr(cancel_quo[0][0]) + " is already cancelled !")
- raise Exception , "Validation Error. "
-
- def update_enquiry_status(self, prevdoc, flag):
- enq = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Detail` t2 where t2.parent = t1.name and t1.name=%s", prevdoc)
- if enq:
- sql("update `tabEnquiry` set status = %s where name=%s",(flag,enq[0][0]))
+ # Checks Quotation Status
+ # ------------------------
+ def check_prev_docstatus(self):
+ for d in getlist(self.doclist, 'sales_order_details'):
+ cancel_quo = sql("select name from `tabQuotation` where docstatus = 2 and name = '%s'" % d.prevdoc_docname)
+ if cancel_quo:
+ msgprint("Quotation :" + cstr(cancel_quo[0][0]) + " is already cancelled !")
+ raise Exception , "Validation Error. "
+
+ def update_enquiry_status(self, prevdoc, flag):
+ enq = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Detail` t2 where t2.parent = t1.name and t1.name=%s", prevdoc)
+ if enq:
+ sql("update `tabEnquiry` set status = %s where name=%s",(flag,enq[0][0]))
- #update status of quotation, enquiry
- #----------------------------------------
- def update_prevdoc_status(self, flag):
- for d in getlist(self.doclist, 'sales_order_details'):
- if d.prevdoc_docname:
- if flag=='submit':
- sql("update `tabQuotation` set status = 'Order Confirmed' where name=%s",d.prevdoc_docname)
-
- #update enquiry
- self.update_enquiry_status(d.prevdoc_docname, 'Order Confirmed')
- elif flag == 'cancel':
- chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Detail` t2 where t2.parent = t1.name and t2.prevdoc_docname=%s and t1.name!=%s and t1.docstatus=1", (d.prevdoc_docname,self.doc.name))
- if not chk:
- sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname)
-
- #update enquiry
- self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
-
- # Submit
- # -------
- def on_submit(self):
- self.check_prev_docstatus()
- self.update_stock_ledger(update_stock = 1)
- self.set_sms_msg(1)
- # update customer's last sales order no.
- update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer))
- get_obj('Sales Common').check_credit(self,self.doc.grand_total)
-
- # Check for Approving Authority
- get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
-
- #update prevdoc status
- self.update_prevdoc_status('submit')
- # set SO status
- set(self.doc, 'status', 'Submitted')
-
- # on submit notification
- if self.doc.email_id:
- get_obj('Notification Control').notify_contact('Sales Order',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-
+ #update status of quotation, enquiry
+ #----------------------------------------
+ def update_prevdoc_status(self, flag):
+ for d in getlist(self.doclist, 'sales_order_details'):
+ if d.prevdoc_docname:
+ if flag=='submit':
+ sql("update `tabQuotation` set status = 'Order Confirmed' where name=%s",d.prevdoc_docname)
+
+ #update enquiry
+ self.update_enquiry_status(d.prevdoc_docname, 'Order Confirmed')
+ elif flag == 'cancel':
+ chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Detail` t2 where t2.parent = t1.name and t2.prevdoc_docname=%s and t1.name!=%s and t1.docstatus=1", (d.prevdoc_docname,self.doc.name))
+ if not chk:
+ sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname)
+
+ #update enquiry
+ self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
+
+ # Submit
+ # -------
+ def on_submit(self):
+ self.check_prev_docstatus()
+ self.update_stock_ledger(update_stock = 1)
+ self.set_sms_msg(1)
+ # update customer's last sales order no.
+ update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer))
+ get_obj('Sales Common').check_credit(self,self.doc.grand_total)
+
+ # Check for Approving Authority
+ get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
+
+ #update prevdoc status
+ self.update_prevdoc_status('submit')
+ # set SO status
+ set(self.doc, 'status', 'Submitted')
+
+ # on submit notification
+ if self.doc.email_id:
+ get_obj('Notification Control').notify_contact('Sales Order',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
+
# ON CANCEL
# ===============================================================================================
- def on_cancel(self):
- # Cannot cancel stopped SO
- if self.doc.status == 'Stopped':
- msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name))
- raise Exception
- self.check_nextdoc_docstatus()
- self.update_stock_ledger(update_stock = -1)
- self.set_sms_msg()
-
- #update prevdoc status
- self.update_prevdoc_status('cancel')
-
- # ::::::::: SET SO STATUS ::::::::::
- set(self.doc, 'status', 'Cancelled')
-
- # CHECK NEXT DOCSTATUS
- # does not allow to cancel document if DN or RV made against it is SUBMITTED
- # ----------------------------------------------------------------------------
- def check_nextdoc_docstatus(self):
- # Checks Delivery Note
- submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Detail` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
- if submit_dn:
- msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
- # Checks Receivable Voucher
- submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name))
- if submit_rv:
- msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
- #check maintenance schedule
- submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
- if submit_ms:
- msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
- submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
- if submit_mv:
- msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
+ def on_cancel(self):
+ # Cannot cancel stopped SO
+ if self.doc.status == 'Stopped':
+ msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name))
+ raise Exception
+ self.check_nextdoc_docstatus()
+ self.update_stock_ledger(update_stock = -1)
+ self.set_sms_msg()
+
+ #update prevdoc status
+ self.update_prevdoc_status('cancel')
+
+ # ::::::::: SET SO STATUS ::::::::::
+ set(self.doc, 'status', 'Cancelled')
+
+ # CHECK NEXT DOCSTATUS
+ # does not allow to cancel document if DN or RV made against it is SUBMITTED
+ # ----------------------------------------------------------------------------
+ def check_nextdoc_docstatus(self):
+ # Checks Delivery Note
+ submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Detail` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
+ if submit_dn:
+ msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
+ # Checks Receivable Voucher
+ submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name))
+ if submit_rv:
+ msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
+ #check maintenance schedule
+ submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
+ if submit_ms:
+ msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
+ submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
+ if submit_mv:
+ msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
- def check_modified_date(self):
- mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name)
- date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified)))
-
- if date_diff and date_diff[0][0]:
- msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ")
- raise Exception
+ def check_modified_date(self):
+ mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name)
+ date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified)))
+
+ if date_diff and date_diff[0][0]:
+ msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ")
+ raise Exception
- # STOP SALES ORDER
- # ==============================================================================================
- # Stops Sales Order & no more transactions will be created against this Sales Order
- def stop_sales_order(self):
- self.check_modified_date()
- self.update_stock_ledger(update_stock = -1,clear = 1)
- # ::::::::: SET SO STATUS ::::::::::
- set(self.doc, 'status', 'Stopped')
- msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.")
+ # STOP SALES ORDER
+ # ==============================================================================================
+ # Stops Sales Order & no more transactions will be created against this Sales Order
+ def stop_sales_order(self):
+ self.check_modified_date()
+ self.update_stock_ledger(update_stock = -1,clear = 1)
+ # ::::::::: SET SO STATUS ::::::::::
+ set(self.doc, 'status', 'Stopped')
+ msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.")
- # UNSTOP SALES ORDER
- # ==============================================================================================
- # Unstops Sales Order & now transactions can be continued against this Sales Order
- def unstop_sales_order(self):
- self.check_modified_date()
- self.update_stock_ledger(update_stock = 1,clear = 1)
- # ::::::::: SET SO STATUS ::::::::::
- set(self.doc, 'status', 'Submitted')
- msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.")
+ # UNSTOP SALES ORDER
+ # ==============================================================================================
+ # Unstops Sales Order & now transactions can be continued against this Sales Order
+ def unstop_sales_order(self):
+ self.check_modified_date()
+ self.update_stock_ledger(update_stock = 1,clear = 1)
+ # ::::::::: SET SO STATUS ::::::::::
+ set(self.doc, 'status', 'Submitted')
+ msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.")
- # UPDATE STOCK LEDGER
- # ===============================================================================================
- def update_stock_ledger(self, update_stock, clear = 0):
- 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
- if stock_item and stock_item[0]['is_stock_item'] == "Yes":
- if not d[0]:
- msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1])
- 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)
+ # UPDATE STOCK LEDGER
+ # ===============================================================================================
+ def update_stock_ledger(self, update_stock, clear = 0):
+ 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
+ if stock_item and stock_item[0]['is_stock_item'] == "Yes":
+ if not d[0]:
+ msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1])
+ 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)
+
+ # Gets Items from packing list
+ #=================================
+ def get_item_list(self, clear):
+ return get_obj('Sales Common').get_item_list( self, clear)
+
+ # SET MESSAGE FOR SMS
+ #======================
+ def set_sms_msg(self, is_submitted = 0):
+ if is_submitted:
+ if not self.doc.amended_from:
+ msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no)
+ set(self.doc, 'message', msg)
+ else:
+ msg = 'Sales Order has been amended. New SO no:'+self.doc.name
+ set(self.doc, 'message', msg)
+ else:
+ msg = 'Sales Order: '+self.doc.name+' has been cancelled.'
+ set(self.doc, 'message', msg)
+
+ # SEND SMS
+ # =========
+ def send_sms(self):
+ if not self.doc.customer_mobile_no:
+ msgprint("Please enter customer mobile no")
+ elif not self.doc.message:
+ msgprint("Please enter the message you want to send")
+ else:
+ msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message))
- # Gets Items from packing list
- #=================================
- def get_item_list(self, clear):
- return get_obj('Sales Common').get_item_list( self, clear)
-
- # SET MESSAGE FOR SMS
- #======================
- def set_sms_msg(self, is_submitted = 0):
- if is_submitted:
- if not self.doc.amended_from:
- msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no)
- set(self.doc, 'message', msg)
- else:
- msg = 'Sales Order has been amended. New SO no:'+self.doc.name
- set(self.doc, 'message', msg)
- else:
- msg = 'Sales Order: '+self.doc.name+' has been cancelled.'
- set(self.doc, 'message', msg)
-
- # SEND SMS
- # =========
- def send_sms(self):
- if not self.doc.customer_mobile_no:
- msgprint("Please enter customer mobile no")
- elif not self.doc.message:
- msgprint("Please enter the message you want to send")
- else:
- msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message))
+ # on update
+ def on_update(self):
+ pass
- # on update
- def on_update(self):
- pass
-
- # Repair Sales Order
- # ===========================================
- def repair_sales_order(self):
- get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self)
+ # Repair Sales Order
+ # ===========================================
+ def repair_sales_order(self):
+ get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self)
diff --git a/stock/doctype/delivery_note/tests.py b/stock/doctype/delivery_note/tests.py
deleted file mode 100644
index df04c41..0000000
--- a/stock/doctype/delivery_note/tests.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import unittest
-import webnotes
-
-from webnotes.model.code import get_obj
-
-class SubmissionTest(unittest.TestCase):
- def setUp(self):
- self.dn = webnotes.testing.create('Delivery Note')
- self.dn_items = []
-
- # get a line item for testing
- for d in self.dn.doclist:
- if d.doctype=='Delivery Note Detail':
- self.dn_items.append(d)
-
- self.old_bin = get_obj('Warehouse', self.line_item[0].warehouse).get_bin(self.line_item[0].item_code)
- self.dn.on_submit()
-
- def test_bin_is_updated(self):
- "tests if bin quantity is affected when on submission"
- bin = get_obj('Warehouse', self.line_item.warehouse).get_bin(self.line_item[0].item_code)
- self.assertTrue(bin.actual_qty == self.old_bin.actual_qty - self.line_item[0].qty)
-
- def test_sales_order_is_updated(self):
- "tests if"
\ No newline at end of file
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index ae67749..7f0d3c2 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -178,3 +178,7 @@
sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
return sle and 'exists' or 'not exists'
+
+ def on_rename(self,newdn,olddn):
+ sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
+
diff --git a/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
index 1d2408b..50b7154 100644
--- a/stock/doctype/stock_entry_detail/stock_entry_detail.txt
+++ b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
@@ -253,7 +253,8 @@
'no_copy': 1,
'oldfieldname': 'serial_no',
'oldfieldtype': 'Text',
- 'permlevel': 0
+ 'permlevel': 0,
+ 'reqd': 0
},
# DocField
@@ -280,4 +281,4 @@
'oldfieldtype': 'Currency',
'permlevel': 1
}
-]
\ No newline at end of file
+]
diff --git a/utilities/doctype/patch_util/patch_util.py b/utilities/doctype/patch_util/patch_util.py
index f26d110..8413fc0 100644
--- a/utilities/doctype/patch_util/patch_util.py
+++ b/utilities/doctype/patch_util/patch_util.py
@@ -85,7 +85,8 @@
d.parent = doctype
d.parenttype = 'DocType'
d.parentfield = 'permissions'
-
+
+ d.level = level
d.role = role
d.read = read
d.write = write