def create_auto_indent(self, i , doc_type, doc_name, cur_qty): """ Create indent on reaching reorder level """ indent = Document('Purchase Request') indent.transaction_date = nowdate() indent.naming_series = 'IDT' indent.company = get_defaults()['company'] indent.fiscal_year = get_defaults()['fiscal_year'] indent.remark = "This is an auto generated Purchase Request. It was raised because the (actual + ordered + indented - reserved) quantity reaches re-order level when %s %s was created"%(doc_type,doc_name) indent.save(1) indent_obj = get_obj('Purchase Request',indent.name,with_children=1) indent_details_child = addchild(indent_obj.doc,'indent_details','Purchase Request Item',0) indent_details_child.item_code = self.doc.item_code indent_details_child.uom = self.doc.stock_uom indent_details_child.warehouse = self.doc.warehouse indent_details_child.schedule_date= add_days(nowdate(),cint(i['lead_time_days'])) indent_details_child.item_name = i['item_name'] indent_details_child.description = i['description'] indent_details_child.item_group = i['item_group'] indent_details_child.qty = i['re_order_qty'] or (flt(i['re_order_level']) - flt(cur_qty)) indent_details_child.brand = i['brand'] indent_details_child.save() indent_obj = get_obj('Purchase Request',indent.name,with_children=1) indent_obj.validate() set(indent_obj.doc,'docstatus',1) indent_obj.on_submit() msgprint("Item: " + self.doc.item_code + " is to be re-ordered. Purchase Request %s raised. It was generated from %s %s"%(indent.name,doc_type, doc_name )) if(i['email_notify']): send_email_notification(doc_type,doc_name)
def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0, ignore_no_table = 1, debug=0, ignore_ddl=0): """ * Execute a `query`, with given `values` * returns as a dictionary if as_dict = 1 * returns as a list of lists (with cleaned up dates and decimals) if as_list = 1 """ # in transaction validations self.check_transaction_status(query) if getattr(defs,'multi_tenant',None): query = self.add_multi_tenant_condition(query) # execute try: if values!=(): self._cursor.execute(query, values) if debug: webnotes.msgprint(query % values) else: self._cursor.execute(query) if debug: webnotes.msgprint(query) except Exception, e: # ignore data definition errors if ignore_ddl and e.args[0] in (1146,1054,1091): pass else: raise e
def create_remarks(self): r = [] if self.doc.cheque_no : if self.doc.cheque_date: r.append('Via Reference #%s dated %s' % (self.doc.cheque_no, formatdate(self.doc.cheque_date))) else : msgprint("Please enter Reference date", raise_exception=1) for d in getlist(self.doclist, 'entries'): if d.against_invoice and d.credit: currency = webnotes.conn.get_value("Sales Invoice", d.against_invoice, "currency") r.append('%s %s against Invoice: %s' % (cstr(currency), fmt_money(flt(d.credit)), d.against_invoice)) if d.against_voucher and d.debit: bill_no = webnotes.conn.sql("""select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s""", d.against_voucher) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \ not in ['na', 'not applicable', 'none']: r.append('%s %s against Bill %s dated %s' % (cstr(bill_no[0][2]), fmt_money(flt(d.debit)), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')) or '')) if self.doc.user_remark: r.append("User Remark : %s"%self.doc.user_remark) if r: self.doc.remark = ("\n").join(r) else: webnotes.msgprint("User Remarks is mandatory", raise_exception=1)
def make_gl_entries(self, doc, doclist, cancel=0, adv_adj = 0, use_mapper='', merge_entries = 1, update_outstanding='Yes'): self.entries = [] # get entries le_map_list = webnotes.conn.sql("select * from `tabGL Mapper Detail` where parent = %s", use_mapper or doc.doctype, as_dict=1) self.td, self.tc = 0.0, 0.0 for le_map in le_map_list: if le_map['table_field']: for d in getlist(doclist,le_map['table_field']): # purchase_tax_details is the table of other charges in purchase cycle if le_map['table_field'] != 'purchase_tax_details' or (le_map['table_field'] == 'purchase_tax_details' and d.fields.get('category') != 'For Valuation'): self.make_single_entry(doc,d,le_map,cancel, merge_entries) else: self.make_single_entry(None,doc,le_map,cancel, merge_entries) # save entries self.save_entries(cancel, adv_adj, update_outstanding) # check total debit / credit # Due to old wrong entries (total debit != total credit) some voucher could be cancelled if abs(self.td - self.tc) > 0.001 and not cancel: msgprint("Debit and Credit not equal for this voucher: Diff (Debit) is %s" % (self.td-self.tc)) raise Exception # set as cancelled if cancel: vt, vn = self.get_val(le_map['voucher_type'], doc, doc), self.get_val(le_map['voucher_no'], doc, doc) webnotes.conn.sql("update `tabGL Entry` set is_cancelled='Yes' where voucher_type=%s and voucher_no=%s", (vt, vn))
def get_balance(self): if not getlist(self.doclist,'entries'): msgprint("Please enter atleast 1 entry in 'GL Entries' table") else: flag, self.doc.total_debit, self.doc.total_credit = 0, 0, 0 diff = flt(self.doc.difference, 2) # If any row without amount, set the diff on that row for d in getlist(self.doclist,'entries'): if not d.credit and not d.debit and diff != 0: if diff>0: d.credit = diff elif diff<0: d.debit = diff flag = 1 # Set the diff in a new row if flag == 0 and diff != 0: jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', self.doclist) if diff>0: jd.credit = abs(diff) elif diff<0: jd.debit = abs(diff) # Set the total debit, total credit and difference for d in getlist(self.doclist,'entries'): self.doc.total_debit += flt(d.debit, 2) self.doc.total_credit += flt(d.credit, 2) self.doc.difference = flt(self.doc.total_debit, 2) - flt(self.doc.total_credit, 2)
def convert_ledger_to_group(self): if self.check_gle_exists(): msgprint("Cost Center with existing transaction can not be converted to group.", raise_exception=1) else: self.doc.group_or_ledger = 'Group' self.doc.save() return 1
def check_if_expired(): """check if account is expired. If expired, do not allow login""" import conf # check if expires_on is specified if not hasattr(conf, 'expires_on'): return # check if expired from datetime import datetime, date expires_on = datetime.strptime(conf.expires_on, '%Y-%m-%d').date() if date.today() <= expires_on: return # if expired, stop user from logging in from webnotes.utils import formatdate msg = """Oops! Your subscription expired on <b>%s</b>.<br>""" % formatdate(conf.expires_on) if 'System Manager' in webnotes.user.get_roles(): msg += """Just drop in a mail at <b>[email protected]</b> and we will guide you to get your account re-activated.""" else: msg += """Just ask your System Manager to drop in a mail at <b>[email protected]</b> and we will guide him to get your account re-activated.""" webnotes.msgprint(msg) webnotes.response['message'] = 'Account Expired' raise webnotes.AuthenticationError
def validate_first_entry(self, obj): if obj.doc.doctype == "Purchase Invoice": supp_acc = obj.doc.credit_to elif obj.doc.doctype == "Journal Voucher": supp_acc = obj.doc.supplier_account if obj.doc.ded_amount: # first pv first_pv = sql( "select posting_date from `tabPurchase Invoice` where credit_to = '%s' and docstatus = 1 and tds_category = '%s' and fiscal_year = '%s' and tds_applicable = 'Yes' and (ded_amount != 0 or ded_amount is not null) order by posting_date asc limit 1" % (supp_acc, obj.doc.tds_category, obj.doc.fiscal_year) ) first_pv_date = first_pv and first_pv[0][0] or "" # first jv first_jv = sql( "select posting_date from `tabJournal Voucher` where supplier_account = '%s'and docstatus = 1 and tds_category = '%s' and fiscal_year = '%s' and tds_applicable = 'Yes' and (ded_amount != 0 or ded_amount is not null) order by posting_date asc limit 1" % (supp_acc, obj.doc.tds_category, obj.doc.fiscal_year) ) first_jv_date = first_jv and first_jv[0][0] or "" # first tds voucher date first_tds_date = "" if first_pv_date and first_jv_date: first_tds_date = first_pv_date < first_jv_date and first_pv_date or first_jv_date elif first_pv_date: first_tds_date = first_pv_date elif first_jv_date: first_tds_date = first_jv_date if first_tds_date and getdate(obj.doc.posting_date) < first_tds_date: msgprint( "First tds voucher for this category has been made already. Hence payable voucher cannot be made before posting date of first tds voucher " ) raise Exception
def execute_cmd(cmd): """execute a request as python module""" validate_cmd(cmd) method = get_method(cmd) # check if whitelisted if webnotes.session['user'] == 'Guest': if (method not in webnotes.guest_methods): webnotes.response['403'] = 1 raise Exception, 'Not Allowed, %s' % str(method) else: if not method in webnotes.whitelisted: webnotes.response['403'] = 1 webnotes.msgprint('Not Allowed, %s' % str(method)) raise Exception, 'Not Allowed, %s' % str(method) if not webnotes.conn.in_transaction: webnotes.conn.begin() if 'arg' in webnotes.form_dict: # direct method call ret = method(webnotes.form_dict.get('arg')) else: ret = method() # returns with a message if ret: webnotes.response['message'] = ret # update session webnotes.session_obj.update() if webnotes.conn.in_transaction: webnotes.conn.commit()
def validate_pos(self): if not self.doc.cash_bank_account and flt(self.doc.paid_amount): msgprint("Cash/Bank Account is mandatory for POS, for making payment entry") raise Exception if (flt(self.doc.paid_amount) + flt(self.doc.write_off_amount) - round(flt(self.doc.grand_total), 2))>0.001: msgprint("(Paid amount + Write Off Amount) can not be greater than Grand Total") raise Exception
def on_update(self): # Set default warehouse from pos setting if cint(self.doc.is_pos) == 1: if cint(self.doc.update_stock) == 1: w = self.get_warehouse() if w: for d in getlist(self.doclist, 'entries'): if not d.warehouse: d.warehouse = cstr(w) self.make_packing_list() else: self.doclist = self.doc.clear_table(self.doclist, 'packing_details') if flt(self.doc.paid_amount) == 0: if self.doc.cash_bank_account: webnotes.conn.set(self.doc, 'paid_amount', (flt(self.doc.grand_total) - flt(self.doc.write_off_amount))) else: # show message that the amount is not paid webnotes.conn.set(self.doc,'paid_amount',0) webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.") else: self.doclist = self.doc.clear_table(self.doclist, 'packing_details') webnotes.conn.set(self.doc,'paid_amount',0) webnotes.conn.set(self.doc, 'outstanding_amount', flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
def validate_item_fetch(args, item): from stock.utils import validate_end_of_life validate_end_of_life(item.name, item.end_of_life) # validate company if not args.company: msgprint(_("Please specify Company"), raise_exception=True)
def validate_proj_cust(self): """check for does customer belong to same project as entered..""" if self.doc.project_name and self.doc.customer: res = webnotes.conn.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 that project."%(self.doc.customer,self.doc.project_name)) raise Exception
def validate_order_type(self): valid_types = ["Sales", "Maintenance", "Shopping Cart"] if not self.doc.order_type: self.doc.order_type = "Sales" elif self.doc.order_type not in valid_types: msgprint(_(self.meta.get_label("order_type")) + " " + _("must be one of") + ": " + comma_or(valid_types), raise_exception=True)
def check_mandatory(self): """ Check mandatory fields """ if not self.doc.from_pr_date or not self.doc.to_pr_date: msgprint("Please enter From and To PR Date", raise_exception=1) if not self.doc.currency: msgprint("Please enter Currency.", raise_exception=1)
def save(self, new=0, check_links=1, ignore_fields=0, make_autoname=1, keep_timestamps=False): res = webnotes.model.meta.get_dt_values(self.doctype, 'autoname, issingle, istable, name_case', as_dict=1) res = res and res[0] or {} if new: self.fields["__islocal"] = 1 # add missing parentinfo (if reqd) if self.parent and not (self.parenttype and self.parentfield): self.update_parentinfo() if self.parent and not self.idx: self.set_idx() # if required, make new if self.fields.get('__islocal') and (not res.get('issingle')): r = self._insert(res.get('autoname'), res.get('istable'), res.get('name_case'), make_autoname, keep_timestamps = keep_timestamps) if r: return r else: if not res.get('issingle') and not webnotes.conn.exists(self.doctype, self.name): webnotes.msgprint("""This document was updated before your change. Please refresh before saving.""", raise_exception=1) # save the values self._update_values(res.get('issingle'), check_links and self.make_link_list() or {}, ignore_fields=ignore_fields, keep_timestamps=keep_timestamps) self._clear_temp_fields()
def send(self): """ * Execute get method * Send email to recipients """ if not self.doc.recipient_list: return self.sending = True result, email_body = self.get() recipient_list = self.doc.recipient_list.split("\n") # before sending, check if user is disabled or not # do not send if disabled profile_list = webnotes.conn.sql("SELECT name, enabled FROM tabProfile", as_dict=1) for profile in profile_list: if profile['name'] in recipient_list and profile['enabled'] == 0: del recipient_list[recipient_list.index(profile['name'])] from webnotes.utils.email_lib import sendmail try: #webnotes.msgprint('in send') sendmail( recipients=recipient_list, sender='*****@*****.**', reply_to='*****@*****.**', subject=self.doc.frequency + ' Digest', msg=email_body, from_defs=1 ) except Exception, e: webnotes.msgprint('There was a problem in sending your email. Please contact [email protected]') webnotes.errprint(webnotes.getTraceback())
def get_payables_group(self): g = sql("select payables_group from tabCompany where name=%s", self.doc.company) g = g and g[0][0] or '' if not g: msgprint("Update Company master, assign a default group for Payables") raise Exception return g
def on_submit(self): if self.doc.doi_start >= time.strftime("%Y-%m-%d"): self.doc.loan_sanction_date = time.strftime("%Y-%m-%d") else : webnotes.msgprint("DOI Start date is greater than todays date") raise Exception self.doc.save()
def on_cancel(self): chk = sql("select t1.name from `tabQuotation` t1, `tabQuotation Detail` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name) if chk: msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Enquiry. Thus can not be cancelled.") raise Exception else: set(self.doc, 'status', 'Cancelled')
def validate(self): if self.doc.standard=="Yes" and webnotes.session.user != "Administrator": webnotes.msgprint("Standard Print Format cannot be updated.", raise_exception=1) # old_doc_type is required for clearing item cache self.old_doc_type = webnotes.conn.get_value('Print Format', self.doc.name, 'doc_type')
def set_last_contact_date(self): if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date: if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date): self.doc.last_contact_date=self.doc.contact_date_ref else: msgprint("Contact Date Cannot be before Last Contact Date") raise Exception
def validate_time_logs_are_submitted(self): for d in self.doclist.get({"doctype":"Sales Invoice Item"}): if d.time_log_batch: status = webnotes.conn.get_value("Time Log Batch", d.time_log_batch, "status") if status!="Submitted": webnotes.msgprint(_("Time Log Batch status must be 'Submitted'") + ":" + d.time_log_batch, raise_exception=True)
def update_add_node(doctype, name, parent, parent_field): """ insert a new node """ from webnotes.utils import now n = now() # get the last sibling of the parent if parent: right = webnotes.conn.sql("select rgt from `tab%s` where name='%s'" % (doctype, parent))[0][0] else: # root right = webnotes.conn.sql("select ifnull(max(rgt),0)+1 from `tab%s` where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0] right = right or 1 # update all on the right webnotes.conn.sql("update `tab%s` set rgt = rgt+2, modified='%s' where rgt >= %s" %(doctype,n,right)) webnotes.conn.sql("update `tab%s` set lft = lft+2, modified='%s' where lft >= %s" %(doctype,n,right)) # update index of new node if webnotes.conn.sql("select * from `tab%s` where lft=%s or rgt=%s"% (doctype, right, right+1)): webnotes.msgprint("Nested set error. Please send mail to support") raise Exception webnotes.conn.sql("update `tab%s` set lft=%s, rgt=%s, modified='%s' where name='%s'" % (doctype,right,right+1,n,name)) return right
def on_trash(self): parent = self.doc.fields[self.nsm_parent_field] if not parent: msgprint(_("Root ") + self.doc.doctype + _(" cannot be deleted."), raise_exception=1) parent = "" update_nsm(self)
def on_submit(self): if self.doc.status != "Approved": webnotes.msgprint("""Only Leave Applications with status 'Approved' can be Submitted.""", raise_exception=True) # notify leave applier about approval self.notify_employee(self.doc.status)
def do_stock_reco(self, is_submit = 1): """ Make stock entry of qty diff, calculate incoming rate to maintain valuation rate. If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation """ for row in self.data: # Get qty as per system sys_stock = self.get_system_stock(row[0],row[1]) # Diff between file and system qty_diff = row[2] != '~' and flt(row[2]) - flt(sys_stock['actual_qty']) or 0 rate_diff = row[3] != '~' and flt(row[3]) - flt(sys_stock['val_rate']) or 0 # Make sl entry if qty_diff: self.make_sl_entry(is_submit, row, qty_diff, sys_stock) elif rate_diff: self.make_sl_entry(is_submit, row, 1, sys_stock) sys_stock['val_rate'] = row[3] sys_stock['actual_qty'] += 1 self.make_sl_entry(is_submit, row, -1, sys_stock) if is_submit == 1: self.add_data_in_CSV(qty_diff, rate_diff) msgprint("Stock Reconciliation Completed Successfully...")
def get_bank_cash_account(mode_of_payment): val = webnotes.conn.get_value("Mode of Payment", mode_of_payment, "default_account") if not val: webnotes.msgprint("Default Bank / Cash Account not set in Mode of Payment: %s. Please add a Default Account in Mode of Payment master." % mode_of_payment) return { "cash_bank_account": val }
def update_against_document_in_jv(self, obj, table_field_name, against_document_no, against_document_doctype, account_head, dr_or_cr,doctype): for d in getlist(obj.doclist, table_field_name): self.validate_jv_entry(d, account_head, dr_or_cr) if flt(d.advance_amount) == flt(d.allocated_amount): # cancel JV jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1) get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1) # update ref in JV Detail webnotes.conn.sql("update `tabJournal Voucher Detail` set %s = '%s' where name = '%s'" % (doctype=='Purchase Invoice' and 'against_voucher' or 'against_invoice', cstr(against_document_no), d.jv_detail_no)) # re-submit JV jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1) get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1) elif flt(d.advance_amount) > flt(d.allocated_amount): # cancel JV jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1) get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1) # add extra entries self.add_extra_entry(jv_obj, d.journal_voucher, d.jv_detail_no, flt(d.allocated_amount), account_head, doctype, dr_or_cr, against_document_no) # re-submit JV jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1) get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj = 1) else: msgprint("Allocation amount cannot be greater than advance amount") raise Exception
def validate_fiscal_year(self): fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year) ysd=fy and fy[0][0] or "" yed=add_days(str(ysd),365) if str(self.doc.transaction_date) < str(ysd) or str(self.doc.transaction_date) > str(yed): msgprint("Enquiry Date is not within the Fiscal Year selected") raise Exception
def validate_query(self, q): cmd = q.strip().lower().split()[0] if cmd in ['alter', 'drop', 'truncate' ] and webnotes.user.name != 'Administrator': webnotes.msgprint('Not allowed to execute query') raise Execption
def setup_account(self, args): import webnotes, json args = json.loads(args) webnotes.conn.begin() curr_fiscal_year, fy_start_date, fy_abbr = self.get_fy_details( args.get('fy_start')) #webnotes.msgprint(self.get_fy_details(args.get('fy_start'))) args['name'] = webnotes.session.get('user') # Update Profile if not args.get('last_name') or args.get('last_name') == 'None': args['last_name'] = None webnotes.conn.sql( """\ UPDATE `tabProfile` SET first_name=%(first_name)s, last_name=%(last_name)s WHERE name=%(name)s AND docstatus<2""", args) # Fiscal Year master_dict = { 'Fiscal Year': { 'year': curr_fiscal_year, 'year_start_date': fy_start_date, 'company': args.get('company_name') } } self.create_records(master_dict) # Company master_dict = { 'Company': { 'company_name': args.get('company_name'), 'abbr': args.get('company_abbr'), 'default_currency': args.get('currency') } } self.create_records(master_dict) def_args = {'current_fiscal_year':curr_fiscal_year, 'default_currency': args.get('currency'), 'default_company':args.get('company_name'), 'default_valuation_method':'FIFO', 'default_stock_uom':'Nos', 'date_format':'dd-mm-yyyy', 'default_currency_format':'Lacs', 'so_required':'No', 'dn_required':'No', 'po_required':'No', 'pr_required':'No', 'emp_created_by':'Naming Series', 'cust_master_name':'Customer Name', 'supp_master_name':'Supplier Name', 'default_currency_format': \ (args.get('currency')=='INR') and 'Lacs' or 'Millions' } # Set self.set_defaults(def_args) cp_args = {} for k in ['industry', 'country', 'timezone', 'company_name']: cp_args[k] = args[k] self.set_cp_defaults(**cp_args) self.create_feed_and_todo() self.create_email_digest() webnotes.clear_cache() msgprint("Company setup is complete") import webnotes.utils user_fullname = (args.get('first_name') or '') + (args.get('last_name') and (" " + args.get('last_name')) or '') webnotes.conn.commit() return { 'sys_defaults': webnotes.utils.get_defaults(), 'user_fullname': user_fullname }
def a_system_manager_should_exist(self): if not self.get_other_system_managers(): webnotes.msgprint( _("""Hey! There should remain at least one System Manager"""), raise_exception=True)
def set_message(self, arg=''): fn = self.doc.select_transaction.lower().replace(' ', '_') + '_message' webnotes.conn.set(self.doc, fn, self.doc.custom_message) msgprint("Custom Message for %s updated!" % self.doc.select_transaction)
def check_warehouse_is_set_for_stock_item(self): if self.doc.is_stock_item == "Yes" and not self.doc.default_warehouse: webnotes.msgprint( _("Default Warehouse is mandatory for Stock Item."), raise_exception=WarehouseNotSet)
def validate_name_with_item_group(self): if webnotes.conn.exists("Item Group", self.doc.name): webnotes.msgprint("An item group exists with same name (%s), \ please change the item name or rename the item group" % self.doc.name, raise_exception=1)
def _msgprint(msg, verbose): if verbose: msgprint(msg, raise_exception=True) else: raise webnotes.ValidationError, msg
def add_bom(self, d): #----- fetching default bom from Bill of Materials instead of Item Master -- bom_det = sql( """select t1.item, t2.item_code, t2.qty_consumed_per_unit, t2.moving_avg_rate, t2.value_as_per_mar, t2.stock_uom, t2.name, t2.description from `tabBOM` t1, `tabBOM Item` t2 where t2.parent = t1.name and t1.item = %s and t1.is_default = 1 and t1.docstatus = 1 and t2.docstatus =1 and t1.is_active = 1""", d.item_code) if not bom_det: msgprint("No default BOM exists for item: %s" % d.item_code) raise Exception else: #-------------- add child function-------------------- chgd_rqd_qty = [] for i in bom_det: if i and not sql( "select name from `tabPurchase Receipt Item Supplied` where reference_name = '%s' and bom_detail_no = '%s' and parent = '%s' " % (d.name, i[6], self.doc.name)): rm_child = addchild(self.doc, 'pr_raw_material_details', 'Purchase Receipt Item Supplied', self.doclist) rm_child.reference_name = d.name rm_child.bom_detail_no = i and i[6] or '' rm_child.main_item_code = i and i[0] or '' rm_child.rm_item_code = i and i[1] or '' rm_child.description = i and i[7] or '' rm_child.stock_uom = i and i[5] or '' rm_child.rate = i and flt(i[3]) or flt(i[4]) rm_child.conversion_factor = d.conversion_factor rm_child.required_qty = flt(i and flt(i[2]) or 0) * flt( d.qty) * flt(d.conversion_factor) rm_child.consumed_qty = flt(i and flt(i[2]) or 0) * flt( d.qty) * flt(d.conversion_factor) rm_child.amount = flt( flt(rm_child.consumed_qty) * flt(rm_child.rate)) rm_child.save() chgd_rqd_qty.append(cstr(i[1])) else: act_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt( d.conversion_factor) for pr_rmd in getlist(self.doclist, 'pr_raw_material_details'): if i and i[6] == pr_rmd.bom_detail_no and ( flt(act_qty) != flt(pr_rmd.required_qty) or i[1] != pr_rmd.rm_item_code or i[7] != pr_rmd.description): chgd_rqd_qty.append(cstr(i[1])) pr_rmd.main_item_code = i[0] pr_rmd.rm_item_code = i[1] pr_rmd.description = i[7] pr_rmd.stock_uom = i[5] pr_rmd.required_qty = flt(act_qty) pr_rmd.consumed_qty = flt(act_qty) pr_rmd.rate = i and flt(i[3]) or flt(i[4]) pr_rmd.amount = flt( flt(pr_rmd.consumed_qty) * flt(pr_rmd.rate)) pr_rmd.save() if chgd_rqd_qty: msgprint( "Please check consumed quantity for Raw Material Item Code: '%s'in Raw materials Detail Table" % ((len(chgd_rqd_qty) > 1 and ','.join(chgd_rqd_qty[:-1]) + ' and ' + cstr(chgd_rqd_qty[-1:][0])) or cstr(chgd_rqd_qty[0])))
def validate(self): if self.doc.email_id and not validate_email_add(self.doc.email_id): msgprint("Please enter valid Email Id", raise_exception=1) self.update_parent_account()
def validate_debit_credit(self): for d in getlist(self.doclist, 'entries'): if d.debit and d.credit: msgprint( "You cannot credit and debit same account at the same time.", raise_exception=1)
def validate_rule(self): if self.doc.transaction != 'Appraisal': if not self.doc.approving_role and not self.doc.approving_user: msgprint("Please enter Approving Role or Approving User", raise_exception=1) elif self.doc.system_user and self.doc.system_user == self.doc.approving_user: msgprint( "Approving User cannot be same as user the rule is Applicable To (User)", raise_exception=1) elif self.doc.system_role and self.doc.system_role == self.doc.approving_role: msgprint("Approving Role cannot be same as user the rule is \ Applicable To (Role).", raise_exception=1) elif self.doc.system_user and self.doc.approving_role and \ has_common([self.doc.approving_role], [x[0] for x in \ sql("select role from `tabUserRole` where parent = '%s'" % \ (self.doc.system_user))]): msgprint( "System User : %s is assigned role : %s. So rule does not make sense" % (self.doc.system_user, self.doc.approving_role), raise_exception=1) elif self.doc.transaction in ['Purchase Order', 'Purchase Receipt', \ 'Purchase Invoice', 'Stock Entry'] and self.doc.based_on \ in ['Average Discount', 'Customerwise Discount', 'Itemwise Discount']: msgprint( "You cannot set authorization on basis of Discount for %s" % self.doc.transaction, raise_exception=1) elif self.doc.based_on == 'Average Discount' and flt( self.doc.value) > 100.00: msgprint("Discount cannot given for more than 100%", raise_exception=1) elif self.doc.based_on == 'Customerwise Discount' and not self.doc.master_name: msgprint( "Please enter Customer Name for 'Customerwise Discount'", raise_exception=1) else: if self.doc.transaction == 'Appraisal' and self.doc.based_on != 'Not Applicable': msgprint( "Based on should be 'Not Applicable' while setting authorization rule\ for 'Appraisal'", raise_exception=1)
def validate_mandatory(self): if not self.doc.account: msgprint("Please select Account first", raise_exception=1)
def validate_mandatory(self): if self.doc.amended_from and not self.doc.amendment_date: msgprint("Please Enter Amendment Date") raise Exception, "Validation Error. "
def validate(self): #validation for Naming Series mandatory field... if webnotes.defaults.get_global_default( 'supp_master_name') == 'Naming Series': if not self.doc.naming_series: msgprint("Series is Mandatory.", raise_exception=1)
def check_guest_access(doc): if webnotes.session['user']=='Guest' and not webnotes.conn.sql("select name from tabDocPerm where role='Guest' and parent=%s and ifnull(`read`,0)=1", doc.doctype): webnotes.msgprint("Guest not allowed to call this object") raise Exception
def validate_expense_account(self): if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \ and not self.doc.expense_account: msgprint(_("Expense Account is mandatory"), raise_exception=1)
def check_sal_struct(self): struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee) if not struct: msgprint("Please create Salary Structure for employee '%s'"%self.doc.employee) self.doc.employee = '' return struct and struct[0][0] or ''
def get_gl_entries_for_stock(self, warehouse_account=None): if not self.doc.cost_center: msgprint(_("Please enter Cost Center"), raise_exception=1) return super(DocType, self).get_gl_entries_for_stock(warehouse_account, self.doc.expense_account, self.doc.cost_center)
def validate_budget(self, acct, cost_center, actual, budget, action): # action if actual exceeds budget if flt(actual) > flt(budget): msgprint("Your monthly expense "+ cstr((action == 'stop') and "will exceed" or "has exceeded") +" budget for <b>Account - "+cstr(acct)+" </b> under <b>Cost Center - "+ cstr(cost_center) + "</b>"+cstr((action == 'Stop') and ", you can not have this transaction." or ".")) if action == 'Stop': raise Exception
if ignore_encoding: newrow.append(cstr(val.strip())) else: try: newrow.append(unicode(val.strip(), 'utf-8')) except UnicodeDecodeError, e: raise Exception, """Some character(s) in row #%s, column #%s are not readable by utf-8. Ignoring them. If you are importing a non english language, please make sure your file is saved in the 'utf-8' encoding.""" % (csvrows.index(row)+1, row.index(val)+1) rows.append(newrow) return rows except Exception, e: webnotes.msgprint("Not a valid Comma Separated Value (CSV File)") raise e @webnotes.whitelist() def send_csv_to_client(args): if isinstance(args, basestring): args = json.loads(args) args = webnotes._dict(args) webnotes.response["result"] = cstr(to_csv(args.data)) webnotes.response["doctype"] = args.filename webnotes.response["type"] = "csv" def to_csv(data): writer = UnicodeWriter()
def check_if_submittable(d): if d.submit and not issubmittable: webnotes.msgprint( doctype + " is not Submittable, cannot assign submit rights.", raise_exception=True)
def send_mail_funct(self): from webnotes.utils.email_lib import sendmail receiver = webnotes.conn.get_value("Employee", self.doc.employee, "company_email") if receiver: subj = 'Salary Slip - ' + cstr(self.doc.month) +'/'+cstr(self.doc.fiscal_year) earn_ret=sql("""select e_type, e_modified_amount from `tabSalary Slip Earning` where parent = %s""", self.doc.name) ded_ret=sql("""select d_type, d_modified_amount from `tabSalary Slip Deduction` where parent = %s""", self.doc.name) earn_table = '' ded_table = '' if earn_ret: earn_table += "<table cellspacing=5px cellpadding=5px width='100%%'>" for e in earn_ret: if not e[1]: earn_table += '<tr><td>%s</td><td align="right">0.00</td></tr>' % cstr(e[0]) else: earn_table += '<tr><td>%s</td><td align="right">%s</td></tr>' \ % (cstr(e[0]), cstr(e[1])) earn_table += '</table>' if ded_ret: ded_table += "<table cellspacing=5px cellpadding=5px width='100%%'>" for d in ded_ret: if not d[1]: ded_table +='<tr><td">%s</td><td align="right">0.00</td></tr>' % cstr(d[0]) else: ded_table +='<tr><td>%s</td><td align="right">%s</td></tr>' \ % (cstr(d[0]), cstr(d[1])) ded_table += '</table>' letter_head = webnotes.conn.get_value("Letter Head", {"is_default": 1, "disabled": 0}, "content") msg = '''<div> %s <br> <table cellspacing= "5" cellpadding="5" width = "100%%"> <tr> <td width = "100%%" colspan = "2"><h4>Salary Slip</h4></td> </tr> <tr> <td width = "50%%"><b>Employee Code : %s</b></td> <td width = "50%%"><b>Employee Name : %s</b></td> </tr> <tr> <td width = "50%%">Month : %s</td> <td width = "50%%">Fiscal Year : %s</td> </tr> <tr> <td width = "50%%">Department : %s</td> <td width = "50%%">Branch : %s</td> </tr> <tr> <td width = "50%%">Designation : %s</td> <td width = "50%%">Grade : %s</td> </tr> <tr> <td width = "50%%">Bank Account No. : %s</td> <td width = "50%%">Bank Name : %s</td> </tr> <tr> <td width = "50%%">Arrear Amount : <b>%s</b></td> <td width = "50%%">Payment days : %s</td> </tr> </table> <table border="1px solid #CCC" width="100%%" cellpadding="0px" cellspacing="0px"> <tr> <td colspan = 2 width = "50%%" bgcolor="#CCC" align="center"> <b>Earnings</b></td> <td colspan = 2 width = "50%%" bgcolor="#CCC" align="center"> <b>Deductions</b></td> </tr> <tr> <td colspan = 2 width = "50%%" valign= "top">%s</td> <td colspan = 2 width = "50%%" valign= "top">%s</td> </tr> </table> <table cellspacing= "5" cellpadding="5" width = '100%%'> <tr> <td width = '25%%'><b>Gross Pay :</b> </td> <td width = '25%%' align='right'>%s</td> <td width = '25%%'><b>Total Deduction :</b></td> <td width = '25%%' align='right'> %s</td> </tr> <tr> <tdwidth='25%%'><b>Net Pay : </b></td> <td width = '25%%' align='right'><b>%s</b></td> <td colspan = '2' width = '50%%'></td> </tr> <tr> <td width='25%%'><b>Net Pay(in words) : </td> <td colspan = '3' width = '50%%'>%s</b></td> </tr> </table></div>''' % (cstr(letter_head), cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words)) sendmail([receiver], subject=subj, msg = msg) else: msgprint("Company Email ID not found, hence mail not sent")
def check_atleast_one_set(d): if not d.read and not d.write and not d.submit and not d.cancel and not d.create: webnotes.msgprint( get_txt(d) + " Atleast one of Read, Write, Create, Submit, Cancel must be set.", raise_exception=True)
def validate(self): for d in getlist(self.doclist, 'target_details'): if not flt(d.target_qty) and not flt(d.target_amount): webnotes.msgprint( "Either target qty or target amount is mandatory.") raise Exception
def check_hidden_and_mandatory(d): if d.hidden and d.reqd: webnotes.msgprint( """#%(idx)s %(label)s: Cannot be hidden and mandatory (reqd)""" % d.fields, raise_exception=True)
def remove_report_if_single(d): if d.report and issingle: webnotes.msgprint( doctype + " is a single DocType, permission of type Report is meaningless." )
def validate_fields(fields): def check_illegal_characters(fieldname): for c in [ '.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$', '(', ')', '[', ']', '/' ]: if c in fieldname: webnotes.msgprint("'%s' not allowed in fieldname (%s)" % (c, fieldname)) def check_unique_fieldname(fieldname): duplicates = filter( None, map(lambda df: df.fieldname == fieldname and str(df.idx) or None, fields)) if len(duplicates) > 1: webnotes.msgprint('Fieldname <b>%s</b> appears more than once in rows (%s). Please rectify' \ % (fieldname, ', '.join(duplicates)), raise_exception=1) def check_illegal_mandatory(d): if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd: webnotes.msgprint('%(label)s [%(fieldtype)s] cannot be mandatory' % d.fields, raise_exception=1) def check_link_table_options(d): if d.fieldtype in ("Link", "Table"): if not d.options: webnotes.msgprint( """#%(idx)s %(label)s: Options must be specified for Link and Table type fields""" % d.fields, raise_exception=1) if d.options == "[Select]": return if not webnotes.conn.exists("DocType", d.options): webnotes.msgprint( """#%(idx)s %(label)s: Options %(options)s must be a valid "DocType" for Link and Table type fields""" % d.fields, raise_exception=1) def check_hidden_and_mandatory(d): if d.hidden and d.reqd: webnotes.msgprint( """#%(idx)s %(label)s: Cannot be hidden and mandatory (reqd)""" % d.fields, raise_exception=True) def check_max_items_in_list(fields): count = 0 for d in fields: if d.in_list_view: count += 1 if count > 5: webnotes.msgprint( """Max 5 Fields can be set as 'In List View', please unselect a field before selecting a new one.""" ) def check_width(d): if d.fieldtype == "Currency" and cint(d.width) < 100: webnotes.msgprint( "Minimum width for FieldType 'Currency' is 100px", raise_exception=1) for d in fields: if not d.permlevel: d.permlevel = 0 if not d.fieldname: webnotes.msgprint("Fieldname is mandatory in row %s" % d.idx, raise_exception=1) check_illegal_characters(d.fieldname) check_unique_fieldname(d.fieldname) check_illegal_mandatory(d) check_link_table_options(d) check_hidden_and_mandatory(d)
def check_width(d): if d.fieldtype == "Currency" and cint(d.width) < 100: webnotes.msgprint( "Minimum width for FieldType 'Currency' is 100px", raise_exception=1)
def is_serial_no_match(self, cur_s_no, prevdoc_s_no, prevdoc_docname): for sr in cur_s_no: if sr not in prevdoc_s_no: msgprint("Serial No. " + sr + " is not matching with the Delivery Note " + prevdoc_docname, raise_exception = 1)
def check_illegal_mandatory(d): if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd: webnotes.msgprint('%(label)s [%(fieldtype)s] cannot be mandatory' % d.fields, raise_exception=1)