def create_sal_slip(self): """ Creates salary slip for selected employees if already not created """ emp_list = self.get_emp_list() ss_list = [] for emp in emp_list: if not sql("""select name from `tabSalary Slip` where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s """, (emp[0], self.doc.month, self.doc.fiscal_year, self.doc.company)): ss = Document('Salary Slip') ss.fiscal_year = self.doc.fiscal_year ss.employee = emp[0] ss.month = self.doc.month ss.email_check = self.doc.send_email ss.company = self.doc.company ss.save(1) ss_obj = get_obj('Salary Slip', ss.name, with_children=1) ss_obj.get_emp_and_leave_details() ss_obj.calculate_net_pay() ss_obj.validate() ss_obj.doc.save() for d in getlist(ss_obj.doclist, 'earning_details'): d.save() for d in getlist(ss_obj.doclist, 'deduction_details'): d.save() ss_list.append(ss.name) return self.create_log(ss_list)
def on_submit(self): if not getlist(self.doclist, 'maintenance_schedule_detail'): msgprint("Please click on 'Generate Schedule' to get schedule") raise Exception self.check_serial_no_added() self.validate_serial_no_warranty() self.validate_schedule() email_map ={} for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: self.update_amc_date(d.serial_no, d.end_date) if d.incharge_name not in email_map: e = sql("select email_id, name from `tabSales Person` where name='%s' " %(d.incharge_name),as_dict=1)[0] email_map[d.incharge_name] = (e['email_id']) scheduled_date =sql("select scheduled_date from `tabMaintenance Schedule Detail` \ where incharge_name='%s' and item_code='%s' and parent='%s' " %(d.incharge_name, \ d.item_code, self.doc.name), as_dict=1) for key in scheduled_date: if email_map[d.incharge_name]: self.add_calender_event(key["scheduled_date"],email_map[d.incharge_name],d.item_code) webnotes.conn.set(self.doc, 'status', 'Submitted')
def cal_charges_and_item_tax_amt(self): """ Re-calculates other charges values and itemwise tax amount for getting valuation rate""" import json for pr in self.selected_pr: obj = get_obj('Purchase Receipt', pr, with_children = 1) total = 0 self.reset_other_charges(obj) for prd in getlist(obj.doclist, 'purchase_receipt_details'): prev_total, item_tax = flt(prd.amount), 0 total += flt(prd.qty) * flt(prd.purchase_rate) try: item_tax_rate = prd.item_tax_rate and json.loads(prd.item_tax_rate) or {} except ValueError: item_tax_rate = prd.item_tax_rate and eval(prd.item_tax_rate) or {} ocd = getlist(obj.doclist, 'purchase_tax_details') # calculate tax for other charges for oc in range(len(ocd)): # Get rate : consider if diff for this item if item_tax_rate.get(ocd[oc].account_head) and ocd[oc].charge_type != 'Actual': rate = item_tax_rate[ocd[oc].account_head] else: rate = flt(ocd[oc].rate) tax_amount = self.cal_tax(ocd, prd, rate, obj.doc.net_total, oc) total, prev_total, item_tax = self.add_deduct_taxes(ocd, oc, tax_amount, total, prev_total, item_tax) prd.item_tax_amount = flt(item_tax) prd.save() obj.doc.save()
def check_final_result(self): count=0 if self.doc.density=='By Weight': for m in getlist(self.doclist, 'density_details'): if m.consider_for_final_result==1: #webnotes.errprint(m.break_no) count=count+1 #webnotes.errprint(count) if count==1: pass else: #webnotes.errprint(count) webnotes.msgprint("At most one record needed for consideration of final result from Density Details Child Table.",raise_exception=1); if self.doc.density=='By Hydrometer': for n in getlist(self.doclist, 'density_reading'): if n.consider_for_final_result==1: #webnotes.errprint(m.break_no) count=count+1 #webnotes.errprint(count) if count==1: pass else: #webnotes.errprint(count) webnotes.msgprint("At most one record needed for consideration of final result from Density Details Child Table.",raise_exception=1);
def get_allocated_sum(self,obj): sum = 0 for d in getlist(obj.doclist,'sales_team'): sum += flt(d.allocated_percentage) if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'): msgprint("Total Allocated % of Sales Persons should be 100%") raise Exception
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 get_item_list(self, obj, is_stopped=0): """get item list""" il = [] for d in getlist(obj.doclist, obj.fname): reserved_warehouse = "" reserved_qty_for_main_item = 0 if obj.doc.doctype == "Sales Order": reserved_warehouse = d.reserved_warehouse if flt(d.qty) > flt(d.delivered_qty): reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty) if obj.doc.doctype == "Delivery Note" and d.prevdoc_doctype == "Sales Order": # if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12. # But in this case reserved qty should only be reduced by 10 and not 12 already_delivered_qty = self.get_already_delivered_qty( obj.doc.name, d.prevdoc_docname, d.prevdoc_detail_docname ) so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname) if already_delivered_qty + d.qty > so_qty: reserved_qty_for_main_item = -(so_qty - already_delivered_qty) else: reserved_qty_for_main_item = -flt(d.qty) if self.has_sales_bom(d.item_code): for p in getlist(obj.doclist, "packing_details"): if p.parent_detail_docname == d.name and p.parent_item == d.item_code: # the packing details table's qty is already multiplied with parent's qty il.append( { "warehouse": p.warehouse, "reserved_warehouse": reserved_warehouse, "item_code": p.item_code, "qty": flt(p.qty), "reserved_qty": (flt(p.qty) / flt(d.qty)) * reserved_qty_for_main_item, "uom": p.uom, "batch_no": cstr(p.batch_no).strip(), "serial_no": cstr(p.serial_no).strip(), "name": d.name, } ) else: il.append( { "warehouse": d.warehouse, "reserved_warehouse": reserved_warehouse, "item_code": d.item_code, "qty": d.qty, "reserved_qty": reserved_qty_for_main_item, "uom": d.stock_uom, "batch_no": cstr(d.batch_no).strip(), "serial_no": cstr(d.serial_no).strip(), "name": d.name, } ) return il
def validate_reference_value(self, obj, to_docname): """ Check consistency of value with reference document""" for t in getlist(self.doclist, 'table_mapper_details'): # Reference key is the fieldname which will relate to the from_table if t.reference_doctype_key: for d in getlist(obj.doclist, t.to_field): if d.fields[t.reference_doctype_key] == self.doc.from_doctype: self.check_consistency(obj.doc, d, to_docname) self.check_ref_docstatus()
def get_item_list(self, obj, is_stopped=0): """get item list""" il = [] for d in getlist(obj.doclist, obj.fname): reserved_warehouse = "" reserved_qty_for_main_item = 0 if obj.doc.doctype == "Sales Order": if (webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or self.has_sales_bom(d.item_code)) and not d.reserved_warehouse: webnotes.throw(_("Please enter Reserved Warehouse for item ") + d.item_code + _(" as it is stock Item or packing item")) reserved_warehouse = d.reserved_warehouse if flt(d.qty) > flt(d.delivered_qty): reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty) if obj.doc.doctype == "Delivery Note" and d.against_sales_order: # if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12. # But in this case reserved qty should only be reduced by 10 and not 12 already_delivered_qty = self.get_already_delivered_qty(obj.doc.name, d.against_sales_order, d.prevdoc_detail_docname) so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname) if already_delivered_qty + d.qty > so_qty: reserved_qty_for_main_item = -(so_qty - already_delivered_qty) else: reserved_qty_for_main_item = -flt(d.qty) if self.has_sales_bom(d.item_code): for p in getlist(obj.doclist, 'packing_details'): if p.parent_detail_docname == d.name and p.parent_item == d.item_code: # the packing details table's qty is already multiplied with parent's qty il.append(webnotes._dict({ 'warehouse': p.warehouse, 'reserved_warehouse': reserved_warehouse, 'item_code': p.item_code, 'qty': flt(p.qty), 'reserved_qty': (flt(p.qty)/flt(d.qty)) * reserved_qty_for_main_item, 'uom': p.uom, 'batch_no': cstr(p.batch_no).strip(), 'serial_no': cstr(p.serial_no).strip(), 'name': d.name })) else: il.append(webnotes._dict({ 'warehouse': d.warehouse, 'reserved_warehouse': reserved_warehouse, 'item_code': d.item_code, 'qty': d.qty, 'reserved_qty': reserved_qty_for_main_item, 'uom': d.stock_uom, 'batch_no': cstr(d.batch_no).strip(), 'serial_no': cstr(d.serial_no).strip(), 'name': d.name })) return il
def validate_warehouse(self, pro_obj): """perform various (sometimes conditional) validations on warehouse""" source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return"] target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return"] validate_for_manufacture_repack = any([d.bom_no for d in self.doclist.get( {"parentfield": "mtn_details"})]) if self.doc.purpose in source_mandatory and self.doc.purpose not in target_mandatory: self.doc.to_warehouse = None for d in getlist(self.doclist, 'mtn_details'): d.t_warehouse = None elif self.doc.purpose in target_mandatory and self.doc.purpose not in source_mandatory: self.doc.from_warehouse = None for d in getlist(self.doclist, 'mtn_details'): d.s_warehouse = None for d in getlist(self.doclist, 'mtn_details'): if not d.s_warehouse and not d.t_warehouse: d.s_warehouse = self.doc.from_warehouse d.t_warehouse = self.doc.to_warehouse if not (d.s_warehouse or d.t_warehouse): msgprint(_("Atleast one warehouse is mandatory"), raise_exception=1) if self.doc.purpose in source_mandatory and not d.s_warehouse: msgprint(_("Row # ") + "%s: " % cint(d.idx) + _("Source Warehouse") + _(" is mandatory"), raise_exception=1) if self.doc.purpose in target_mandatory and not d.t_warehouse: msgprint(_("Row # ") + "%s: " % cint(d.idx) + _("Target Warehouse") + _(" is mandatory"), raise_exception=1) if self.doc.purpose == "Manufacture/Repack": if validate_for_manufacture_repack: if d.bom_no: d.s_warehouse = None if not d.t_warehouse: msgprint(_("Row # ") + "%s: " % cint(d.idx) + _("Target Warehouse") + _(" is mandatory"), raise_exception=1) elif pro_obj and cstr(d.t_warehouse) != pro_obj.doc.fg_warehouse: msgprint(_("Row # ") + "%s: " % cint(d.idx) + _("Target Warehouse") + _(" should be same as that in ") + _("Production Order"), raise_exception=1) else: d.t_warehouse = None if not d.s_warehouse: msgprint(_("Row # ") + "%s: " % cint(d.idx) + _("Source Warehouse") + _(" is mandatory"), raise_exception=1) if cstr(d.s_warehouse) == cstr(d.t_warehouse): msgprint(_("Source and Target Warehouse cannot be same"), raise_exception=1)
def update_current_stock(self): for d in getlist(self.doclist, 'delivery_note_details'): bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 for d in getlist(self.doclist, 'packing_details'): bin = webnotes.conn.sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
def check_serial_no_added(self): serial_present =[] for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: serial_present.append(d.item_code) for m in getlist(self.doclist, 'maintenance_schedule_detail'): if serial_present: if m.item_code in serial_present and not m.serial_no: msgprint("Please click on 'Generate Schedule' to fetch serial no added for item "+m.item_code) raise Exception
def update_sample_status(self): samples, dic = {}, {} for sample in getlist(self.doclist, 'sample_allocation_detail'): #samples[sample.get('sample_no')] = '' self.test_allocation(sample, dic) self.prepare_escape_test(dic) #for updation of status in Sample Doctype for sample in getlist(self.doclist,'sample_allocation_detail'): webnotes.conn.sql("update tabSample set status = 'Assigned' where name ='"+sample.sample_no+"'") webnotes.conn.sql("commit")
def get_finaltest_details(self): self.doclist=self.doc.clear_table(self.doclist,'final_test') for d in getlist(self.doclist, 'test_allocation_detail'): for t in getlist(self.doclist,'test'): #webnotes.errprint(t) cr =addchild(self.doc,'final_test','Final Test Allocation Detail',self.doclist) cr.sample_no=d.sample_no cr.bottle_no=d.bottle_no cr.priority=d.priority cr.specification=d.specification cr.client_name=d.client_name cr.test=t.test_name cr.save(new=1)
def get_items(self): so_list = filter( None, [d.sales_order for d in getlist(self.doclist, 'pp_so_details')]) if not so_list: msgprint("Please enter sales order in the above table") return [] items = webnotes.conn.sql("""select distinct parent, item_code, reserved_warehouse, (qty - ifnull(delivered_qty, 0)) as pending_qty from `tabSales Order Item` so_item where parent in (%s) and docstatus = 1 and ifnull(qty, 0) > ifnull(delivered_qty, 0) and exists (select * from `tabItem` item where item.name=so_item.item_code and (ifnull(item.is_pro_applicable, 'No') = 'Yes' or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \ (", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1) packed_items = webnotes.conn.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as reserved_warhouse, (((so_item.qty - ifnull(so_item.delivered_qty, 0)) * pi.qty) / so_item.qty) as pending_qty from `tabSales Order Item` so_item, `tabPacked Item` pi where so_item.parent = pi.parent and so_item.docstatus = 1 and pi.parent_item = so_item.item_code and so_item.parent in (%s) and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0) and exists (select * from `tabItem` item where item.name=pi.item_code and (ifnull(item.is_pro_applicable, 'No') = 'Yes' or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \ (", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1) return items + packed_items
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ lst = [] for d in getlist(self.doclist, 'advance_adjustment_details'): if flt(d.allocated_amount) > 0: args = { 'voucher_no' : d.journal_voucher, 'voucher_detail_no' : d.jv_detail_no, 'against_voucher_type' : 'Sales Invoice', 'against_voucher' : self.doc.name, 'account' : self.doc.debit_to, 'is_advance' : 'Yes', 'dr_or_cr' : 'credit', 'unadjusted_amt' : flt(d.advance_amount), 'allocated_amt' : flt(d.allocated_amount) } lst.append(args) if lst: from accounts.utils import reconcile_against_document reconcile_against_document(lst)
def update_packing_list_item(self,obj, packing_item_code, qty, warehouse, line): bin = self.get_bin_qty(packing_item_code, warehouse) item = self.get_packing_item_details(packing_item_code) # check if exists exists = 0 for d in getlist(obj.doclist, 'packing_details'): if d.parent_item == line.item_code and d.item_code == packing_item_code and d.parent_detail_docname == line.name: pi, exists = d, 1 break if not exists: pi = addchild(obj.doc, 'packing_details', 'Delivery Note Packing Item', obj.doclist) pi.parent_item = line.item_code pi.item_code = packing_item_code pi.item_name = item['item_name'] pi.parent_detail_docname = line.name pi.description = item['description'] pi.uom = item['stock_uom'] pi.qty = flt(qty) pi.actual_qty = bin and flt(bin['actual_qty']) or 0 pi.projected_qty = bin and flt(bin['projected_qty']) or 0 pi.prevdoc_doctype = line.prevdoc_doctype if not pi.warehouse: pi.warehouse = warehouse if not pi.batch_no: pi.batch_no = cstr(line.batch_no) pi.idx = self.packing_list_idx # saved, since this function is called on_update of delivery note pi.save() self.packing_list_idx += 1
def update_stock(self): sl_entries = [] stock_items = self.get_stock_items() for d in getlist(self.doclist, 'purchase_receipt_details'): if d.item_code in stock_items and d.warehouse: pr_qty = flt(d.qty) * flt(d.conversion_factor) if pr_qty: sl_entries.append(self.get_sl_entries(d, { "actual_qty": flt(pr_qty), "serial_no": cstr(d.serial_no).strip(), "incoming_rate": d.valuation_rate })) if flt(d.rejected_qty) > 0: sl_entries.append(self.get_sl_entries(d, { "warehouse": d.rejected_warehouse, "actual_qty": flt(d.rejected_qty) * flt(d.conversion_factor), "serial_no": cstr(d.rejected_serial_no).strip(), "incoming_rate": d.valuation_rate })) self.bk_flush_supp_wh(sl_entries) self.make_sl_entries(sl_entries)
def validate_data(self): self.validate_company() for d in getlist(self.doclist, 'pp_details'): self.validate_bom_no(d) if not flt(d.planned_qty): webnotes.throw("Please Enter Planned Qty for item: %s at row no: %s" % (d.item_code, d.idx))
def get_other_charges(self,obj, default=0): obj.doclist = obj.doc.clear_table(obj.doclist, 'other_charges') if not getlist(obj.doclist, 'other_charges'): if default: add_cond = 'ifnull(t2.is_default,0) = 1' else: add_cond = 't1.parent = "'+cstr(obj.doc.charge)+'"' idx = 0 other_charge = webnotes.conn.sql("""\ select t1.* from `tabSales Taxes and Charges` t1, `tabSales Taxes and Charges Master` t2 where t1.parent = t2.name and t2.company = '%s' and %s order by t1.idx""" % (obj.doc.company, add_cond), as_dict=1) from webnotes.model import default_fields for other in other_charge: # remove default fields like parent, parenttype etc. # from query results for field in default_fields: if field in other: del other[field] d = addchild(obj.doc, 'other_charges', 'Sales Taxes and Charges', obj.doclist) d.fields.update(other) d.rate = flt(d.rate) d.tax_amount = flt(d.tax_rate) d.included_in_print_rate = cint(d.included_in_print_rate) d.idx = idx idx += 1 return obj.doclist
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ lst = [] for d in getlist(self.doclist, "advance_adjustment_details"): if flt(d.allocated_amount) > 0: args = { "voucher_no": d.journal_voucher, "voucher_detail_no": d.jv_detail_no, "against_voucher_type": "Sales Invoice", "against_voucher": self.doc.name, "account": self.doc.debit_to, "is_advance": "Yes", "dr_or_cr": "credit", "unadjusted_amt": flt(d.advance_amount), "allocated_amt": flt(d.allocated_amount), } lst.append(args) if lst: from accounts.utils import reconcile_against_document reconcile_against_document(lst)
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 get_items(self): so_list = filter(None, [d.sales_order for d in getlist(self.doclist, 'pp_so_details')]) if not so_list: msgprint(_("Please enter sales order in the above table")) return [] items = webnotes.conn.sql("""select distinct parent, item_code, reserved_warehouse, (qty - ifnull(delivered_qty, 0)) as pending_qty from `tabSales Order Item` so_item where parent in (%s) and docstatus = 1 and ifnull(qty, 0) > ifnull(delivered_qty, 0) and exists (select * from `tabItem` item where item.name=so_item.item_code and (ifnull(item.is_pro_applicable, 'No') = 'Yes' or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \ (", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1) packed_items = webnotes.conn.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as reserved_warhouse, (((so_item.qty - ifnull(so_item.delivered_qty, 0)) * pi.qty) / so_item.qty) as pending_qty from `tabSales Order Item` so_item, `tabPacked Item` pi where so_item.parent = pi.parent and so_item.docstatus = 1 and pi.parent_item = so_item.item_code and so_item.parent in (%s) and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0) and exists (select * from `tabItem` item where item.name=pi.item_code and (ifnull(item.is_pro_applicable, 'No') = 'Yes' or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \ (", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1) return items + packed_items
def get_stock_and_rate(self): """get stock and incoming rate on posting date""" for d in getlist(self.doclist, 'mtn_details'): args = webnotes._dict({ "item_code": d.item_code, "warehouse": d.s_warehouse or d.t_warehouse, "posting_date": self.doc.posting_date, "posting_time": self.doc.posting_time, "qty": d.s_warehouse and -1 * d.transfer_qty or d.transfer_qty, "serial_no": d.serial_no, "bom_no": d.bom_no, }) # get actual stock at source warehouse d.actual_qty = get_previous_sle(args).get( "qty_after_transaction") or 0 # get incoming rate if not flt(d.incoming_rate): d.incoming_rate = self.get_incoming_rate(args) d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
def on_update(self): if cint(self.doc.update_stock) == 1: # Set default warehouse from pos setting if cint(self.doc.is_pos) == 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 cint(self.doc.is_pos) == 1: 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: webnotes.conn.set(self.doc,'paid_amount',0)
def update_stock_ledger(self): sl_entries = [] for d in getlist(self.doclist, 'mtn_details'): if cstr(d.s_warehouse) and self.doc.docstatus == 1: sl_entries.append( self.get_sl_entries( d, { "warehouse": cstr(d.s_warehouse), "actual_qty": -flt(d.transfer_qty), "incoming_rate": 0 })) if cstr(d.t_warehouse): sl_entries.append( self.get_sl_entries( d, { "warehouse": cstr(d.t_warehouse), "actual_qty": flt(d.transfer_qty), "incoming_rate": flt(d.incoming_rate) })) # On cancellation, make stock ledger entry for # target warehouse first, to update serial no values properly if cstr(d.s_warehouse) and self.doc.docstatus == 2: sl_entries.append( self.get_sl_entries( d, { "warehouse": cstr(d.s_warehouse), "actual_qty": -flt(d.transfer_qty), "incoming_rate": 0 })) self.make_sl_entries(sl_entries, self.doc.amended_from and 'Yes' or 'No')
def validate_sales_mntc_quotation(self): for d in getlist(self.doclist, 'sales_order_details'): if d.prevdoc_docname: res = sql("select name from `tabQuotation` where name=%s and order_type = %s", (d.prevdoc_docname, self.doc.order_type)) if not res: msgprint("""Order Type (%s) should be same in Quotation: %s \ and current Sales Order""" % (self.doc.order_type, d.prevdoc_docname))
def validate_inspection(self): for d in getlist(self.doclist, 'purchase_receipt_details'): #Enter inspection date for all items that require inspection ins_reqd = webnotes.conn.sql("select inspection_required from `tabItem` where name = %s", (d.item_code,), as_dict = 1) ins_reqd = ins_reqd and ins_reqd[0]['inspection_required'] or 'No' if ins_reqd == 'Yes' and not d.qa_no: msgprint("Item: " + d.item_code + " requires QA Inspection. Please enter QA No or report to authorized person to create Quality Inspection")
def reconcile(self): """ Links booking and payment voucher 1. cancel payment voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit payment voucher """ if not self.doc.voucher_no or not webnotes.conn.sql("""select name from `tab%s` where name = %s""" % (self.doc.voucher_type, '%s'), self.doc.voucher_no): msgprint("Please select valid Voucher No to proceed", raise_exception=1) lst = [] for d in getlist(self.doclist, 'ir_payment_details'): if flt(d.amt_to_be_reconciled) > 0: args = { 'voucher_no' : d.voucher_no, 'voucher_detail_no' : d.voucher_detail_no, 'against_voucher_type' : self.doc.voucher_type, 'against_voucher' : self.doc.voucher_no, 'account' : self.doc.account, 'is_advance' : 'No', 'dr_or_cr' : self.doc.account_type=='debit' and 'credit' or 'debit', 'unadjusted_amt' : flt(d.amt_due), 'allocated_amt' : flt(d.amt_to_be_reconciled) } lst.append(args) if lst: from accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint("Successfully allocated.") else: msgprint("No amount allocated.", raise_exception=1)
def pr_required(self): res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'pr_required'") if res and res[0][0] == 'Yes': for d in getlist(self.doclist,'entries'): if not d.purchase_receipt: msgprint("Purchase Receipt No. required against item %s"%d.item_code) raise Exception
def validate_for_items(self): check_list, flag = [], 0 chk_dupl_itm = [] for d in getlist(self.doclist, 'sales_order_details'): e = [ d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or '' ] f = [d.item_code, d.description] if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes': if not d.reserved_warehouse: msgprint("""Please enter Reserved Warehouse for item %s as it is stock Item""" % d.item_code, raise_exception=1) if e in check_list: msgprint("Item %s has been entered twice." % d.item_code) else: check_list.append(e) else: 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 tot_avail_qty = webnotes.conn.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
def set_against_income_account(self): """Set against account for debit to account""" against_acc = [] for d in getlist(self.doclist, 'entries'): if d.income_account not in against_acc: against_acc.append(d.income_account) self.doc.against_income_account = ','.join(against_acc)
def calculate_ded_total(self): self.doc.total_deduction = 0 qry=webnotes.conn.sql(" select name from `tabEmployee Loan` where employee_id=%s", self.doc.employee ,as_list=1) #webnotes.errprint(qry) r=0 if len(qry)!=0: qr=webnotes.conn.sql("select date_of_installment from `tabLoan Installment Details` where parent=%s",qry[0][0],as_list=1) for i in qr: t=getdate(i[0]).month if t == cint(self.doc.month): q=webnotes.conn.sql("select amount_to_be_paid from `tabLoan Installment Details` where date_of_installment=%s and parent=%s",(getdate(i[0]),qry[0][0]),as_list=1) w=webnotes.conn.sql("Update `tabLoan Installment Details` set status='Paid' where date_of_installment=%s",getdate(i[0])) #webnotes.errprint(q) r=q[0][0] self.doc.loan_amount=r m=0.0 for d in getlist(self.doclist, 'deduction_details'): if cint(d.d_depends_on_lwp) == 1: d.d_modified_amount = _round(flt(d.d_amount) * flt(self.doc.payment_days) / cint(self.doc.total_days_in_month), 2) elif not self.doc.payment_days: d.d_modified_amount = 0 else: d.d_modified_amount = d.d_amount m+=flt(d.d_modified_amount) #m+=flt(d.d_modified_amount) self.doc.total_deduction= m+flt(r)
def validate_for_items(self): check_list, flag = [], 0 chk_dupl_itm = [] for d in getlist(self.doclist, 'sales_order_details'): e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or ''] f = [d.item_code, d.description] if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes': if not d.reserved_warehouse: msgprint("""Please enter Reserved Warehouse for item %s as it is stock Item""" % d.item_code, raise_exception=1) if e in check_list: msgprint("Item %s has been entered twice." % d.item_code) else: check_list.append(e) else: 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 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
def send_notification(new_rv): """Notify concerned persons about recurring invoice generation""" subject = "Invoice : " + new_rv.doc.name com = new_rv.doc.company hd = '''<div><h2>%s</h2></div> <div><h3>Invoice: %s</h3></div> <table cellspacing= "5" cellpadding="5" width = "100%%"> <tr> <td width = "50%%"><b>Customer</b><br>%s<br>%s</td> <td width = "50%%">Invoice Date : %s<br>Invoice Period : %s to %s <br>Due Date : %s</td> </tr> </table> ''' % (com, new_rv.doc.name, new_rv.doc.customer_name, new_rv.doc.address_display, getdate(new_rv.doc.posting_date).strftime("%d-%m-%Y"), \ getdate(new_rv.doc.invoice_period_from_date).strftime("%d-%m-%Y"), getdate(new_rv.doc.invoice_period_to_date).strftime("%d-%m-%Y"),\ getdate(new_rv.doc.due_date).strftime("%d-%m-%Y")) tbl = '''<table border="1px solid #CCC" width="100%%" cellpadding="0px" cellspacing="0px"> <tr> <td width = "15%%" bgcolor="#CCC" align="left"><b>Item</b></td> <td width = "40%%" bgcolor="#CCC" align="left"><b>Description</b></td> <td width = "15%%" bgcolor="#CCC" align="center"><b>Qty</b></td> <td width = "15%%" bgcolor="#CCC" align="center"><b>Rate</b></td> <td width = "15%%" bgcolor="#CCC" align="center"><b>Amount</b></td> </tr> ''' for d in getlist(new_rv.doclist, 'entries'): tbl += '<tr><td>' + cstr(d.item_code) +'</td><td>' + cstr(d.description) + \ '</td><td>' + cstr(d.qty) +'</td><td>' + cstr(d.basic_rate) + \ '</td><td>' + cstr(d.amount) +'</td></tr>' tbl += '</table>' totals = '''<table cellspacing= "5" cellpadding="5" width = "100%%"> <tr> <td width = "50%%"></td> <td width = "50%%"> <table width = "100%%"> <tr> <td width = "50%%">Net Total: </td><td>%s </td> </tr><tr> <td width = "50%%">Total Tax: </td><td>%s </td> </tr><tr> <td width = "50%%">Grand Total: </td><td>%s</td> </tr><tr> <td width = "50%%">In Words: </td><td>%s</td> </tr> </table> </td> </tr> <tr><td>Terms and Conditions:</td></tr> <tr><td>%s</td></tr> </table> ''' % (new_rv.doc.net_total, new_rv.doc.other_charges_total, new_rv.doc.grand_total, new_rv.doc.in_words, new_rv.doc.terms) msg = hd + tbl + totals sendmail(new_rv.doc.notification_email_address, subject=subject, msg=msg)
def validate_data(self): self.validate_company() for d in getlist(self.doclist, 'pp_details'): self.validate_bom_no(d) if not flt(d.planned_qty): webnotes.throw( "Please Enter Planned Qty for item: %s at row no: %s" % (d.item_code, d.idx))
def validate_finished_goods(self): """validation: finished good quantity should be same as manufacturing quantity""" for d in getlist(self.doclist, 'mtn_details'): if d.bom_no and flt(d.transfer_qty) != flt(self.doc.fg_completed_qty): msgprint(_("Row #") + " %s: " % d.idx + _("Quantity should be equal to Manufacturing Quantity. ") + _("To fetch items again, click on 'Get Items' button \ or update the Quantity manually."), raise_exception=1)
def validate_data(self): for d in getlist(self.doclist, 'pp_details'): self.validate_bom_no(d) if not flt(d.planned_qty): msgprint( "Please Enter Planned Qty for item: %s at row no: %s" % (d.item_code, d.idx), raise_exception=1)
def validate_prev_docname(self): """Validates that Sales Order is not pulled twice""" for d in getlist(self.doclist, 'delivery_note_details'): if self.doc.sales_order_no == d.prevdoc_docname: msgprint( cstr(self.doc.sales_order_no) + " sales order details have already been pulled. ") raise Exception, "Validation Error. "
def print_other_charges(self, docname): print_lst = [] for d in getlist(self.doclist, 'other_charges'): lst1 = [] lst1.append(d.description) lst1.append(d.total) print_lst.append(lst1) return print_lst
def on_cancel(self): for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: serial_nos = get_valid_serial_nos(d.serial_no) self.update_amc_date(serial_nos) webnotes.conn.set(self.doc, 'status', 'Cancelled') delete_events(self.doc.doctype, self.doc.name)
def get_current_stock(self): for d in getlist(self.doclist, 'pr_raw_material_details'): if self.doc.supplier_warehouse: bin = webnotes.conn.sql( "select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.rm_item_code, self.doc.supplier_warehouse), as_dict=1) d.current_stock = bin and flt(bin[0]['actual_qty']) or 0
def validate_reference_value(self, obj): ref_doc = [] for d in getlist(obj.doclist, obj.fname): if d.prevdoc_doctype and d.prevdoc_docname and d.prevdoc_doctype not in ref_doc: mapper_name = d.prevdoc_doctype + '-' + obj.doc.doctype get_obj('DocType Mapper', mapper_name, with_children = 1).\ validate_reference_value(obj, obj.doc.name) ref_doc.append(d.prevdoc_doctype)
def reset_other_charges(self, pr_obj): """ Reset all calculated values to zero""" for t in getlist(pr_obj.doclist, 'purchase_tax_details'): t.total_tax_amount = 0 t.total_amount = 0 t.tax_amount = 0 t.total = 0 t.save()
def po_required(self): if webnotes.conn.get_value("Buying Settings", None, "po_required") == 'Yes': for d in getlist(self.doclist, 'purchase_receipt_details'): if not d.prevdoc_docname: msgprint("Purchse Order No. required against item %s" % d.item_code) raise Exception
def validate_serial_no(self): for d in getlist(self.doclist, 'maintenance_visit_details'): if d.serial_no and not webnotes.conn.sql( "select name from `tabSerial No` where name = '%s' and docstatus != 2" % d.serial_no): msgprint("Serial No: " + d.serial_no + " not exists in the system") raise Exception
def pr_required(self): if webnotes.conn.get_value("Buying Settings", None, "pr_required") == 'Yes': for d in getlist(self.doclist, 'entries'): if not d.purchase_receipt: msgprint("Purchase Receipt No. required against item %s" % d.item_code) raise Exception
def validate_schedule_date(self): #:::::::: validate schedule date v/s indent date :::::::::::: for d in getlist(self.doclist, 'indent_details'): if d.schedule_date < self.doc.transaction_date: msgprint( "Expected Schedule Date cannot be before Material Request Date" ) raise Exception
def get_prevdoc_date(self, obj): for d in getlist(obj.doclist, obj.fname): if d.prevdoc_doctype and d.prevdoc_docname: if d.prevdoc_doctype == 'Sales Invoice': dt = webnotes.conn.sql("select posting_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname)) else: dt = webnotes.conn.sql("select transaction_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname)) d.prevdoc_date = (dt and dt[0][0]) and dt[0][0].strftime('%Y-%m-%d') or ''
def on_submit(self): if not getlist(self.doclist, 'maintenance_schedule_detail'): msgprint("Please click on 'Generate Schedule' to get schedule") raise Exception self.check_serial_no_added() self.validate_schedule() email_map = {} for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: serial_nos = get_valid_serial_nos(d.serial_no) self.validate_serial_no(serial_nos, d.start_date) self.update_amc_date(serial_nos, d.end_date) if d.incharge_name not in email_map: email_map[d.incharge_name] = webnotes.bean( "Sales Person", d.incharge_name).run_method("get_email_id") scheduled_date =webnotes.conn.sql("select scheduled_date from `tabMaintenance Schedule Detail` \ where incharge_name='%s' and item_code='%s' and parent='%s' " %(d.incharge_name, \ d.item_code, self.doc.name), as_dict=1) for key in scheduled_date: if email_map[d.incharge_name]: description = "Reference: %s, Item Code: %s and Customer: %s" % \ (self.doc.name, d.item_code, self.doc.customer) webnotes.bean({ "doctype": "Event", "owner": email_map[d.incharge_name] or self.doc.owner, "subject": description, "description": description, "starts_on": key["scheduled_date"] + " 10:00:00", "event_type": "Private", "ref_type": self.doc.doctype, "ref_name": self.doc.name }).insert() webnotes.conn.set(self.doc, 'status', 'Submitted')
def validate_for_items(self): chk_dupl_itm = [] for d in getlist(self.doclist,'quotation_details'): if [cstr(d.item_code),cstr(d.description)] in chk_dupl_itm: msgprint("Item %s has been entered twice. Please change description atleast to continue" % d.item_code) raise Exception else: chk_dupl_itm.append([cstr(d.item_code),cstr(d.description)])
def validate_bom(self): for d in getlist(self.doclist, 'mtn_details'): if d.bom_no and not webnotes.conn.sql("""select name from `tabBOM` where item = %s and name = %s and docstatus = 1 and is_active = 1""", (d.item_code, d.bom_no)): msgprint(_("Item") + " %s: " % cstr(d.item_code) + _("does not belong to BOM: ") + cstr(d.bom_no) + _(" or the BOM is cancelled or inactive"), raise_exception=1)
def scrub_serial_nos(self, obj, table_name = ''): if not table_name: table_name = obj.fname for d in getlist(obj.doclist, table_name): if d.serial_no: serial_nos = cstr(d.serial_no).strip().replace(',', '\n').split('\n') d.serial_no = "\n".join(map(lambda x: x.strip(), serial_nos)) d.save()
def so_required(self): """check in manage account if sales order required or not""" if webnotes.conn.get_value("Selling Settings", None, 'so_required') == 'Yes': for d in getlist(self.doclist, 'delivery_note_details'): if not d.against_sales_order: msgprint("Sales Order No. required against item %s" % d.item_code) raise Exception
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 check_for_stopped_status(self, pc_obj): check_list = [] for d in getlist(self.doclist, 'po_details'): if d.fields.has_key( 'prevdoc_docname' ) and d.prevdoc_docname and d.prevdoc_docname not in check_list: check_list.append(d.prevdoc_docname) pc_obj.check_for_stopped_status(d.prevdoc_doctype, d.prevdoc_docname)
def credit_limit(self): """check credit limit of items in DN Detail which are not fetched from sales order""" amount, total = 0, 0 for d in getlist(self.doclist, 'delivery_note_details'): if not (d.against_sales_order or d.against_sales_invoice): amount += d.amount if amount != 0: total = (amount / self.doc.net_total) * self.doc.grand_total self.check_credit(total)
def get_selected_pr(self): """ Get selected purchase receipt no """ self.selected_pr = [ d.purchase_receipt for d in getlist(self.doclist, 'lc_pr_details') if d.select_pr ] if not self.selected_pr: msgprint("Please select atleast one PR to proceed.", raise_exception=1)
def validate_incoming_rate(self): for d in getlist(self.doclist, 'mtn_details'): if d.t_warehouse: self.validate_value( "incoming_rate", ">", 0, d, raise_exception=IncorrectValuationRateError)