def on_submit(self): if cint(self.doc.update_stock) == 1: self.update_stock_ledger() else: # Check for Approving Authority if not self.doc.recurring_id: get_obj('Authorization Control').validate_approving_authority( self.doc.doctype, self.doc.company, self.doc.grand_total, self) self.check_prev_docstatus() self.update_status_updater_args() self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Sales Order") # this sequence because outstanding may get -ve self.make_gl_entries() self.check_credit_limit(self.doc.debit_to) if not cint(self.doc.is_pos) == 1: self.update_against_document_in_jv() self.update_c_form() self.update_time_log_batch(self.doc.name) self.convert_to_recurring()
def on_submit(self): self.update_stock_ledger(update_stock = 1) self.check_credit(self.doc.grand_total) get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self) self.update_prevdoc_status('submit') frappe.db.set(self.doc, 'status', 'Submitted')
def check_credit_limit(self, account): total_outstanding = frappe.db.sql( """ select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` where account = %s""", account) total_outstanding = total_outstanding[0][0] if total_outstanding else 0 if total_outstanding: get_obj('Account', account).check_credit_limit(total_outstanding)
def on_submit(self): self.check_item_table() # Check for Approving Authority get_obj('Authorization Control').validate_approving_authority( self.doc.doctype, self.doc.company, self.doc.grand_total, self) #update enquiry status self.update_opportunity()
def on_submit(self): self.check_prev_docstatus() get_obj('Authorization Control').validate_approving_authority( self.doc.doctype, self.doc.company, self.doc.grand_total) # this sequence because outstanding may get -negative self.make_gl_entries() self.update_against_document_in_jv() self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
def on_submit(self): purchase_controller = frappe.get_obj("Purchase Common") self.update_prevdoc_status() self.update_bin(is_submit=1, is_stopped=0) get_obj('Authorization Control').validate_approving_authority( self.doc.doctype, self.doc.company, self.doc.grand_total) purchase_controller.update_last_purchase_rate(self, is_submit=1) frappe.db.set(self.doc, 'status', 'Submitted')
def get_leave_details(self, lwp=None): if not self.doc.fiscal_year: self.doc.fiscal_year = frappe.get_default("fiscal_year") if not self.doc.month: self.doc.month = "%02d" % getdate(nowdate()).month m = get_obj('Salary Manager').get_month_details( self.doc.fiscal_year, self.doc.month) holidays = self.get_holidays_for_employee(m) if not cint( frappe.db.get_value("HR Settings", "HR Settings", "include_holidays_in_total_working_days")): m["month_days"] -= len(holidays) if m["month_days"] < 0: msgprint(_( "Bummer! There are more holidays than working days this month." ), raise_exception=True) if not lwp: lwp = self.calculate_lwp(holidays, m) self.doc.total_days_in_month = m['month_days'] self.doc.leave_without_pay = lwp payment_days = flt(self.get_payment_days(m)) - flt(lwp) self.doc.payment_days = payment_days > 0 and payment_days or 0
def update_cost_and_exploded_items(self, bom_list=[]): bom_list = self.traverse_tree(bom_list) for bom in bom_list: bom_obj = get_obj("BOM", bom, with_children=1) bom_obj.on_update() return bom_list
def on_cancel(self): pc_obj = get_obj('Purchase Common') self.check_for_stopped_status(pc_obj) # Check if Purchase Invoice has been submitted against current Purchase Order # pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Invoice', docname = self.doc.name, detail_doctype = 'Purchase Invoice Item') submitted = frappe.db.sql( "select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % self.doc.name) if submitted: msgprint("Purchase Invoice : " + cstr(submitted[0][0]) + " has already been submitted !") raise Exception frappe.db.set(self.doc, 'status', 'Cancelled') self.update_ordered_qty() self.update_stock() self.update_prevdoc_status() pc_obj.update_last_purchase_rate(self, 0) self.make_cancel_gl_entries()
def reset_global_defaults(): flds = { 'default_company': None, 'default_currency': None, 'current_fiscal_year': None, 'date_format': 'dd-mm-yyyy', 'sms_sender_name': None, 'default_item_group': 'Default', 'default_stock_uom': 'Nos', 'default_valuation_method': 'FIFO', 'tolerance': None, 'acc_frozen_upto': None, 'bde_auth_role': None, 'credit_controller': None, 'default_customer_group': 'Default Customer Group', 'default_territory': 'Default', 'default_price_list': 'Standard', 'default_supplier_type': 'Default Supplier Type', 'hide_currency_symbol': None, 'default_price_list_currency': None, } from frappe.model.code import get_obj gd = get_obj('Global Defaults', 'Global Defaults') for d in flds: gd.doc.fields[d] = flds[d] gd.doc.save() frappe.clear_cache()
def validate(self): super(DocType, self).validate() self.po_required() if not self.doc.status: self.doc.status = "Draft" from erpnext.utilities import validate_status validate_status(self.doc.status, ["Draft", "Submitted", "Cancelled"]) self.validate_with_previous_doc() self.validate_rejected_warehouse() self.validate_accepted_rejected_qty() self.validate_inspection() self.validate_uom_is_integer("uom", ["qty", "received_qty"]) self.validate_uom_is_integer("stock_uom", "stock_qty") self.validate_challan_no() pc_obj = get_obj(dt='Purchase Common') pc_obj.validate_for_items(self) self.check_for_stopped_status(pc_obj) # sub-contracting self.validate_for_subcontracting() self.update_raw_materials_supplied("pr_raw_material_details") self.update_valuation_rate("purchase_receipt_details")
def send_sms(self): if not self.doc.message: msgprint(_("Please enter message before sending")) else: receiver_list = self.get_receiver_nos() if receiver_list: msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message)))
def on_submit(self): self.validate_packed_qty() # Check for Approving Authority get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self) # update delivered qty in sales order self.update_prevdoc_status() # create stock ledger entry self.update_stock_ledger() self.credit_limit() self.make_gl_entries() # set DN status frappe.db.set(self.doc, 'status', 'Submitted')
def replace_bom(self): self.validate_bom() self.update_new_bom() bom_list = self.get_parent_boms() updated_bom = [] for bom in bom_list: bom_obj = get_obj("BOM", bom, with_children=1) updated_bom = bom_obj.update_cost_and_exploded_items(updated_bom) frappe.msgprint(_("BOM replaced"))
def send_via_gateway(self, arg): ss = get_obj('SMS Settings', 'SMS Settings', with_children=1) args = {ss.doc.message_parameter: arg.get('message')} for d in getlist(ss.doclist, 'static_parameter_details'): args[d.parameter] = d.value resp = [] for d in arg.get('receiver_list'): args[ss.doc.receiver_parameter] = d resp.append(self.send_request(ss.doc.sms_gateway_url, args)) return resp
def validate_production_order(self, pro_obj=None): if not pro_obj: if self.doc.production_order: pro_obj = get_obj('Production Order', self.doc.production_order) else: return if self.doc.purpose == "Manufacture/Repack": # check for double entry self.check_duplicate_entry_for_production_order() elif self.doc.purpose != "Material Transfer": self.doc.production_order = None
def on_submit(self): purchase_controller = frappe.get_obj("Purchase Common") # Check for Approving Authority get_obj('Authorization Control').validate_approving_authority( self.doc.doctype, self.doc.company, self.doc.grand_total) # Set status as Submitted frappe.db.set(self.doc, 'status', 'Submitted') self.update_prevdoc_status() self.update_ordered_qty() self.update_stock() from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit update_serial_nos_after_submit(self, "purchase_receipt_details") purchase_controller.update_last_purchase_rate(self, 1) self.make_gl_entries()
def update_stock(self, values, is_amended = 'No'): for v in values: sle_id = '' # reverse quantities for cancel if v.get('is_cancelled') == 'Yes': v['actual_qty'] = -flt(v['actual_qty']) # cancel matching entry frappe.db.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes', modified=%s, modified_by=%s where voucher_no=%s and voucher_type=%s""", (now(), frappe.session.user, v['voucher_no'], v['voucher_type'])) if v.get("actual_qty"): sle_id = self.make_entry(v) args = v.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) get_obj('Warehouse', v["warehouse"]).update_bin(args)
def send(): from frappe.model.code import get_obj from frappe.utils import getdate now_date = now_datetime().date() from frappe import conf if "expires_on" in conf and now_date > getdate(conf.expires_on): # do not send email digests to expired accounts return for ed in frappe.db.sql("""select name from `tabEmail Digest` where enabled=1 and docstatus<2""", as_list=1): ed_obj = get_obj('Email Digest', ed[0]) if (now_date == ed_obj.get_next_sending()): ed_obj.send()
def update_bin(self, is_submit, is_stopped=0): from erpnext.stock.utils import update_bin pc_obj = get_obj('Purchase Common') for d in getlist(self.doclist, 'po_details'): #1. Check if is_stock_item == 'Yes' if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes": # this happens when item is changed from non-stock to stock item if not d.warehouse: continue ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor) if is_stopped: po_qty = flt(d.qty) > flt(d.received_qty) and \ flt( flt(flt(d.qty) - flt(d.received_qty))*flt(d.conversion_factor)) or 0 # No updates in Material Request on Stop / Unstop if cstr(d.prevdoc_doctype ) == 'Material Request' and not is_stopped: # get qty and pending_qty of prevdoc curr_ref_qty = pc_obj.get_qty( d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Material Request Item', 'Material Request - Purchase Order', self.doc.name) max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), \ flt(curr_ref_qty.split('~~~')[0]), 0 if flt(qty) + flt(po_qty) > flt(max_qty): curr_qty = flt(max_qty) - flt(qty) # special case as there is no restriction # for Material Request - Purchase Order curr_qty = curr_qty > 0 and curr_qty or 0 else: curr_qty = flt(po_qty) ind_qty = -flt(curr_qty) # Update ordered_qty and indented_qty in bin args = { "item_code": d.item_code, "warehouse": d.warehouse, "ordered_qty": (is_submit and 1 or -1) * flt(po_qty), "indented_qty": (is_submit and 1 or -1) * flt(ind_qty), "posting_date": self.doc.transaction_date } update_bin(args)
def delete_items(): """delete selected items""" import json from frappe.model.code import get_obj il = json.loads(frappe.form_dict.get('items')) doctype = frappe.form_dict.get('doctype') for d in il: try: dt_obj = get_obj(doctype, d) if hasattr(dt_obj, 'on_trash'): dt_obj.on_trash() frappe.delete_doc(doctype, d) except Exception, e: frappe.errprint(frappe.get_traceback()) pass
def validate(self): super(DocType, self).validate() self.validate_schedule_date() self.validate_uom_is_integer("uom", "qty") if not self.doc.status: self.doc.status = "Draft" from erpnext.utilities import validate_status validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", "Cancelled"]) self.validate_value("material_request_type", "in", ["Purchase", "Transfer"]) pc_obj = get_obj(dt='Purchase Common') pc_obj.validate_for_items(self)
def allocate_leave(self): self.validate_values() for d in self.get_employees(): la = Document('Leave Allocation') la.employee = cstr(d[0]) la.employee_name = frappe.db.get_value('Employee', cstr(d[0]), 'employee_name') la.leave_type = self.doc.leave_type la.fiscal_year = self.doc.fiscal_year la.posting_date = nowdate() la.carry_forward = cint(self.doc.carry_forward) la.new_leaves_allocated = flt(self.doc.no_of_days) la_obj = get_obj(doc=la) la_obj.doc.docstatus = 1 la_obj.validate() la_obj.on_update() la_obj.doc.save(1) msgprint("Leaves Allocated Successfully")
def get_bin(item_code, warehouse): bin = frappe.db.get_value("Bin", { "item_code": item_code, "warehouse": warehouse }) if not bin: bin_wrapper = frappe.bean([{ "doctype": "Bin", "item_code": item_code, "warehouse": warehouse, }]) bin_wrapper.ignore_permissions = 1 bin_wrapper.insert() bin_obj = bin_wrapper.make_controller() else: from frappe.model.code import get_obj bin_obj = get_obj('Bin', bin) return bin_obj
def on_cancel(self): # Step 1:=> Get Purchase Common Obj pc_obj = get_obj(dt='Purchase Common') # Step 2:=> Check for stopped status pc_obj.check_for_stopped_status(self.doc.doctype, self.doc.name) # Step 3:=> Check if Purchase Order has been submitted against current Material Request pc_obj.check_docstatus(check='Next', doctype='Purchase Order', docname=self.doc.name, detail_doctype='Purchase Order Item') # Step 4:=> Update Bin self.update_bin(is_submit=0, is_stopped=(cstr(self.doc.status) == 'Stopped') and 1 or 0) # Step 5:=> Set Status frappe.db.set(self.doc, 'status', 'Cancelled')
def submit_salary_slip(self): """ Submit all salary slips based on selected criteria """ ss_list = self.get_sal_slip_list() not_submitted_ss = [] for ss in ss_list: ss_obj = get_obj("Salary Slip", ss[0], with_children=1) try: frappe.db.set(ss_obj.doc, 'email_check', cint(self.doc.send_mail)) if cint(self.doc.send_email) == 1: ss_obj.send_mail_funct() frappe.db.set(ss_obj.doc, 'docstatus', 1) except Exception, e: not_submitted_ss.append(ss[0]) msgprint(e) continue
def validate(self): self.validate_posting_time() self.validate_purpose() pro_obj = self.doc.production_order and \ get_obj('Production Order', self.doc.production_order) or None self.validate_item() self.validate_uom_is_integer("uom", "qty") self.validate_uom_is_integer("stock_uom", "transfer_qty") self.validate_warehouse(pro_obj) self.validate_production_order(pro_obj) self.get_stock_and_rate() self.validate_incoming_rate() self.validate_bom() self.validate_finished_goods() self.validate_return_reference_doc() self.validate_with_material_request() self.validate_fiscal_year() self.set_total_amount()
def validate(self): super(DocType, self).validate() if not self.doc.status: self.doc.status = "Draft" from erpnext.utilities import validate_status validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", "Cancelled"]) pc_obj = get_obj(dt='Purchase Common') pc_obj.validate_for_items(self) self.check_for_stopped_status(pc_obj) self.validate_uom_is_integer("uom", "qty") self.validate_uom_is_integer("stock_uom", ["qty", "required_qty"]) self.validate_with_previous_doc() self.validate_for_subcontracting() self.update_raw_materials_supplied("po_raw_material_details")
def get_obj(dt = None, dn = None, doc=None, doclist=None, with_children = True): from frappe.model.code import get_obj return get_obj(dt, dn, doc, doclist, with_children)
def get_last_purchase_rate(self): get_obj('Purchase Common').get_last_purchase_rate(self)