def validate_pl_balances(self): income_bal = webnotes.conn.sql( """ select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1, tabAccount t2 where t1.account = t2.name and t1.posting_date between %s and %s and t2.debit_or_credit = 'Credit' and t2.is_pl_account = 'Yes' and t2.docstatus < 2 and t2.company = %s""", (self.year_start_date, self.doc.posting_date, self.doc.company)) expense_bal = webnotes.conn.sql( """ select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1, tabAccount t2 where t1.account = t2.name and t1.posting_date between %s and %s and t2.debit_or_credit = 'Debit' and t2.is_pl_account = 'Yes' and t2.docstatus < 2 and t2.company=%s""", (self.year_start_date, self.doc.posting_date, self.doc.company)) income_bal = income_bal and income_bal[0][0] or 0 expense_bal = expense_bal and expense_bal[0][0] or 0 if not income_bal and not expense_bal: webnotes.throw( _("Both Income and Expense balances are zero. \ No Need to make Period Closing Entry."))
def check_stock_uom_with_bin(self): if not self.doc.fields.get("__islocal"): matched = True ref_uom = webnotes.conn.get_value("Stock Ledger Entry", {"item_code": self.doc.name}, "stock_uom") if ref_uom: if cstr(ref_uom) != cstr(self.doc.stock_uom): matched = False else: bin_list = webnotes.conn.sql( "select * from tabBin where item_code=%s", self.doc.item_code, as_dict=1) for bin in bin_list: if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \ or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(self.doc.stock_uom): matched = False break if matched and bin_list: webnotes.conn.sql( """update tabBin set stock_uom=%s where item_code=%s""", (self.doc.stock_uom, self.doc.name)) if not matched: webnotes.throw( _("Default Unit of Measure can not be changed directly \ because you have already made some transaction(s) with another UOM.\n \ To change default UOM, use 'UOM Replace Utility' tool under Stock module." ))
def check_duplicate_item(self): if webnotes.conn.sql("""select name from `tabItem Price` where item_code=%s and price_list=%s and name!=%s""", (self.doc.item_code, self.doc.price_list, self.doc.name)): webnotes.throw(_("Duplicate Item: ") + self.doc.item_code + _(" already available in Price List: ") + self.doc.price_list, ItemPriceDuplicateItem)
def save_post(post, content, picture=None, picture_name=None, title=None, assigned_to=None, status=None, event_datetime=None): post = webnotes.bean("Post", post) access = get_access(post.doc.website_group) if not access.get("write"): raise webnotes.PermissionError # TODO improve error message if webnotes.session.user != post.doc.owner: for fieldname in ("title", "content"): if post.doc.fields.get(fieldname) != locals().get(fieldname): webnotes.throw("You cannot change: {}".format(fieldname.title())) if picture and picture_name: webnotes.throw("You cannot change: Picture") post.doc.fields.update({ "title": (title or "").title(), "content": content, "assigned_to": assigned_to, "status": status, "event_datetime": event_datetime }) post.ignore_permissions = True post.save() if picture_name and picture: process_picture(post, picture_name, picture) return post.doc.parent_post or post.doc.name
def pl_must_have_cost_center(self): if webnotes.conn.get_value("Account", self.doc.account, "is_pl_account") == "Yes": if not self.doc.cost_center and self.doc.voucher_type != 'Period Closing Voucher': webnotes.throw(_("Cost Center must be specified for PL Account: ") + self.doc.account) elif self.doc.cost_center: self.doc.cost_center = None
def validate_production_order_against_so(self): # already ordered qty ordered_qty_against_so = webnotes.conn.sql( """select sum(qty) from `tabProduction Order` where production_item = %s and sales_order = %s and docstatus < 2 and name != %s""", (self.doc.production_item, self.doc.sales_order, self.doc.name))[0][0] total_qty = flt(ordered_qty_against_so) + flt(self.doc.qty) # get qty from Sales Order Item table so_item_qty = webnotes.conn.sql( """select sum(qty) from `tabSales Order Item` where parent = %s and item_code = %s""", (self.doc.sales_order, self.doc.production_item))[0][0] # get qty from Packing Item table dnpi_qty = webnotes.conn.sql( """select sum(qty) from `tabPacked Item` where parent = %s and parenttype = 'Sales Order' and item_code = %s""", (self.doc.sales_order, self.doc.production_item))[0][0] # total qty in SO so_qty = flt(so_item_qty) + flt(dnpi_qty) if total_qty > so_qty: webnotes.throw(_("Total production order qty for item") + ": " + cstr(self.doc.production_item) + _(" against sales order") + ": " + cstr(self.doc.sales_order) + _(" will be ") + cstr(total_qty) + ", " + _("which is greater than sales order qty ") + "(" + cstr(so_qty) + ")" + _("Please reduce qty."), exc=OverProductionError)
def validate_master_name(self): """Remind to add master name""" if self.doc.master_type in ("Customer", "Supplier") or self.doc.account_type == "Warehouse": if not self.doc.master_name: msgprint(_("Please enter Master Name once the account is created.")) elif not webnotes.conn.exists(self.doc.master_type or self.doc.account_type, self.doc.master_name): webnotes.throw(_("Invalid Master Name"))
def update_outstanding_amt(account, against_voucher_type, against_voucher, on_cancel=False): # get final outstanding amt bal = flt(webnotes.conn.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` where against_voucher_type=%s and against_voucher=%s and account = %s""", (against_voucher_type, against_voucher, account),debug=1)[0][0] or 0.0) if against_voucher_type == 'Purchase Invoice': bal = -bal elif against_voucher_type == "Journal Voucher": against_voucher_amount = flt(webnotes.conn.sql(""" select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` where voucher_type = 'Journal Voucher' and voucher_no = %s and account = %s and ifnull(against_voucher, '') = ''""", (against_voucher, account),debug=1)[0][0]) bal = against_voucher_amount + bal if against_voucher_amount < 0: bal = -bal # Validation : Outstanding can not be negative if bal < 0 and not on_cancel: webnotes.throw(_("Outstanding for Voucher ") + against_voucher + _(" will become ") + fmt_money(bal) + _(". Outstanding cannot be less than zero. \ Please match exact outstanding.")) # Update outstanding amt on against voucher if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]: webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" % (against_voucher_type, bal, against_voucher))
def validate_warehouse(self, warehouse): if webnotes.conn.get_value("Stock Ledger Entry", {"warehouse": warehouse}): webnotes.throw( _("Stock transactions exist against warehouse ") + warehouse + _(" .You can not assign / modify / remove Master Name") )
def validate_qty_against_so(self): so_items = {} # Format --> {'SO/00001': {'Item/001': 120, 'Item/002': 24}} for d in getlist(self.doclist, 'indent_details'): if d.sales_order_no: if not so_items.has_key(d.sales_order_no): so_items[d.sales_order_no] = {d.item_code: flt(d.qty)} else: if not so_items[d.sales_order_no].has_key(d.item_code): so_items[d.sales_order_no][d.item_code] = flt(d.qty) else: so_items[d.sales_order_no][d.item_code] += flt(d.qty) for so_no in so_items.keys(): for item in so_items[so_no].keys(): already_indented = webnotes.conn.sql("""select sum(qty) from `tabMaterial Request Item` where item_code = %s and sales_order_no = %s and docstatus = 1 and parent != %s""", (item, so_no, self.doc.name)) already_indented = already_indented and flt(already_indented[0][0]) or 0 actual_so_qty = webnotes.conn.sql("""select sum(qty) from `tabSales Order Item` where parent = %s and item_code = %s and docstatus = 1 group by parent""", (so_no, item)) actual_so_qty = actual_so_qty and flt(actual_so_qty[0][0]) or 0 if actual_so_qty and (flt(so_items[so_no][item]) + already_indented > actual_so_qty): webnotes.throw("You can raise indent of maximum qty: %s for item: %s against sales order: %s\ \n Anyway, you can add more qty in new row for the same item." % (actual_so_qty - already_indented, item, so_no))
def update_last_purchase_rate(self, obj, is_submit): """updates last_purchase_rate in item table for each item""" import webnotes.utils this_purchase_date = webnotes.utils.getdate( obj.doc.fields.get('posting_date') or obj.doc.fields.get('transaction_date')) for d in getlist(obj.doclist, obj.fname): # get last purchase details last_purchase_details = get_last_purchase_details( d.item_code, obj.doc.name) # compare last purchase date and this transaction's date last_purchase_rate = None if last_purchase_details and \ (last_purchase_details.purchase_date > this_purchase_date): last_purchase_rate = last_purchase_details['purchase_rate'] elif is_submit == 1: # even if this transaction is the latest one, it should be submitted # for it to be considered for latest purchase rate if flt(d.conversion_factor): last_purchase_rate = flt(d.purchase_rate) / flt( d.conversion_factor) else: webnotes.throw( _("Row ") + cstr(d.idx) + ": " + _("UOM Conversion Factor is mandatory")) # update last purchsae rate if last_purchase_rate: webnotes.conn.sql( """update `tabItem` set last_purchase_rate = %s where name = %s""", (flt(last_purchase_rate), d.item_code))
def validate_warehouse(self): if not self.doc.fields.get("__islocal"): item_code, warehouse = webnotes.conn.get_value("Serial No", self.doc.name, ["item_code", "warehouse"]) if item_code != self.doc.item_code: webnotes.throw(_("Item Code cannot be changed for Serial No."), SerialNoCannotCannotChangeError) if not self.via_stock_ledger and warehouse != self.doc.warehouse: webnotes.throw(_("Warehouse cannot be changed for Serial No."), SerialNoCannotCannotChangeError)
def before_rename(self, old, new, merge=False): # Add company abbr if not provided from setup.doctype.company.company import get_name_with_abbr new_account = get_name_with_abbr(new, self.doc.company) # Validate properties before merging if merge: if not webnotes.conn.exists("Account", new): webnotes.throw(_("Account ") + new + _(" does not exists")) val = list( webnotes.conn.get_value( "Account", new_account, ["group_or_ledger", "debit_or_credit", "is_pl_account"])) if val != [ self.doc.group_or_ledger, self.doc.debit_or_credit, self.doc.is_pl_account ]: webnotes.throw( _("""Merging is only possible if following \ properties are same in both records. Group or Ledger, Debit or Credit, Is PL Account""")) return new_account
def declare_order_negotiated(self): if not self.has_sales_order(): webnotes.conn.set(self.doc, 'status', 'Negotiation Mode') #webnotes.conn.set(self.doc, 'order_lost_reason', arg) self.update_opportunity() else: webnotes.throw(_("Cannot set as Negotiation Mode as Sales Order is made."))
def on_trash(self): webnotes.clear_cache(user=self.doc.name) if self.doc.name in ["Administrator", "Guest"]: throw("{msg}: {name}".format(**{ "msg": _("Hey! You cannot delete user"), "name": self.doc.name })) self.a_system_manager_should_exist() # disable the user and log him/her out self.doc.enabled = 0 if getattr(webnotes.local, "login_manager", None): webnotes.local.login_manager.logout(user=self.doc.name) # delete their password webnotes.conn.sql("""delete from __Auth where user=%s""", (self.doc.name,)) # delete todos webnotes.conn.sql("""delete from `tabToDo` where owner=%s""", (self.doc.name,)) webnotes.conn.sql("""update tabToDo set assigned_by=null where assigned_by=%s""", (self.doc.name,)) # delete events webnotes.conn.sql("""delete from `tabEvent` where owner=%s and event_type='Private'""", (self.doc.name,)) webnotes.conn.sql("""delete from `tabEvent User` where person=%s""", (self.doc.name,)) # delete messages webnotes.conn.sql("""delete from `tabComment` where comment_doctype='Message' and (comment_docname=%s or owner=%s)""", (self.doc.name, self.doc.name))
def check_duplicate_item(self): if self.doc.item_code: if webnotes.conn.sql( """select name from `tabItem Price` where item_code=%s and price_list=%s and name!=%s""", (self.doc.item_code, self.doc.price_list, self.doc.name)): webnotes.throw( "{duplicate_item}: {item_code}, {already}: {price_list}". format( **{ "duplicate_item": _("Duplicate Item"), "item_code": self.doc.item_code, "already": _("already available in Price List"), "price_list": self.doc.price_list }), ItemPriceDuplicateItem) if self.doc.study: if webnotes.conn.sql( """select name from `tabItem Price` where study=%s and price_list=%s and name!=%s""", (self.doc.study, self.doc.price_list, self.doc.name)): webnotes.throw( "{duplicate_item}: {study}, {already}: {price_list}". format( **{ "duplicate_item": _("Duplicate Study"), "item_study": self.doc.study, "already": _("already available in Price List"), "price_list": self.doc.price_list }), ItemPriceDuplicateItem)
def update_stock_ledger(self, update_stock): self.values = [] for d in self.get_item_list(): if webnotes.conn.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 if d['reserved_qty'] < 0 : # Reduce reserved qty from reserved warehouse mentioned in so if not d["reserved_warehouse"]: webnotes.throw(_("Reserved Warehouse is missing in Sales Order")) args = { "item_code": d['item_code'], "voucher_type": self.doc.doctype, "voucher_no": self.doc.name, "reserved_qty": flt(update_stock) * flt(d['reserved_qty']), "posting_date": self.doc.posting_date, "is_amended": self.doc.amended_from and 'Yes' or 'No' } get_obj("Warehouse", d["reserved_warehouse"]).update_bin(args) # Reduce actual qty from warehouse self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock) get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
def validate_inclusive_tax(self, tax): def _on_previous_row_error(row_range): throw((_("Row") + " # %(idx)s [%(doctype)s]: " + _("to be included in Item's rate, it is required that: ") + " [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % { "idx": tax.idx, "doctype": tax.doctype, "inclusive_label": self.meta.get_label("included_in_print_rate", parentfield=self.other_fname), "charge_type_label": self.meta.get_label("charge_type", parentfield=self.other_fname), "charge_type": tax.charge_type, "row_range": row_range }) if cint(tax.included_in_print_rate): if tax.charge_type == "Actual": # inclusive tax cannot be of type Actual throw((_("Row") + " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" " + "cannot be included in Item's rate") % { "idx": tax.idx, "doctype": tax.doctype, "charge_type_label": self.meta.get_label("charge_type", parentfield=self.other_fname), "charge_type": tax.charge_type, }) elif tax.charge_type == "On Previous Row Amount" and \ not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate): # referred row should also be inclusive _on_previous_row_error(tax.row_id) elif tax.charge_type == "On Previous Row Total" and \ not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:tax.row_id - 1]]): # all rows about the reffered tax should be inclusive _on_previous_row_error("1 - %d" % (tax.row_id,))
def set_fieldname(self): if not self.doc.fieldname: if not self.doc.label: webnotes.throw(_("Label is mandatory")) # remove special characters from fieldname self.doc.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_', cstr(self.doc.label).lower().replace(' ','_'))
def validate_filters(filters, account_details): if account_details and account_details.group_or_ledger == "Ledger" \ and filters.get("group_by") == "Group by Account": webnotes.throw(_("Can not filter based on Account, if grouped by Account")) if filters.get("voucher_no") and filters.get("group_by") == "Group by Voucher": webnotes.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
def validate_account_head(self): debit_or_credit, is_pl_account = webnotes.conn.get_value("Account", self.doc.closing_account_head, ["debit_or_credit", "is_pl_account"]) if debit_or_credit != 'Credit' or is_pl_account != 'No': webnotes.throw(_("Account") + ": " + self.doc.closing_account_head + _("must be a Liability account"))
def declare_order_lost(self, arg): if not self.has_sales_order(): webnotes.conn.set(self.doc, 'status', 'Lost') webnotes.conn.set(self.doc, 'order_lost_reason', arg) self.update_opportunity() else: webnotes.throw(_("Cannot set as Lost as Sales Order is made."))
def on_trash(self): # delete bin bins = webnotes.conn.sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1) for d in bins: if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \ d['indented_qty'] or d['projected_qty'] or d['planned_qty']: throw( """Warehouse: %s can not be deleted as qty exists for item: %s""" % (self.doc.name, d['item_code'])) else: webnotes.conn.sql("delete from `tabBin` where name = %s", d['name']) warehouse_account = webnotes.conn.get_value( "Account", { "account_type": "Warehouse", "master_name": self.doc.name }) if warehouse_account: webnotes.delete_doc("Account", warehouse_account) if webnotes.conn.sql( """select name from `tabStock Ledger Entry` where warehouse = %s""", self.doc.name): throw( _("""Warehouse can not be deleted as stock ledger entry exists for this warehouse."""))
def check_stock_uom_with_bin(self): if not self.doc.fields.get("__islocal"): matched=True ref_uom = webnotes.conn.get_value("Stock Ledger Entry", {"item_code": self.doc.name, "is_cancelled": "No"}, "stock_uom") if ref_uom: if cstr(ref_uom) != cstr(self.doc.stock_uom): matched = False else: bin_list = webnotes.conn.sql("select * from tabBin where item_code=%s", self.doc.item_code, as_dict=1) for bin in bin_list: if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \ or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(self.doc.stock_uom): matched = False break if matched and bin_list: webnotes.conn.sql("""update tabBin set stock_uom=%s where item_code=%s""", (self.doc.stock_uom, self.doc.name)) if not matched: webnotes.throw(_("Default Unit of Measure can not be changed directly \ because you have already made some transaction(s) with another UOM.\n \ To change default UOM, use 'UOM Replace Utility' tool under Stock module."))
def update_ordered_qty(self): stock_items = self.get_stock_items() for d in self.doclist.get({"parentfield": "purchase_receipt_details"}): if d.item_code in stock_items and d.warehouse \ and cstr(d.prevdoc_doctype) == 'Purchase Order': already_received_qty = self.get_already_received_qty( d.prevdoc_docname, d.prevdoc_detail_docname) po_qty, ordered_warehouse = self.get_po_qty_and_warehouse( d.prevdoc_detail_docname) if not ordered_warehouse: webnotes.throw(_("Warehouse is missing in Purchase Order")) if already_received_qty + d.qty > po_qty: ordered_qty = -(po_qty - already_received_qty) * flt( d.conversion_factor) else: ordered_qty = -flt(d.qty) * flt(d.conversion_factor) update_bin({ "item_code": d.item_code, "warehouse": ordered_warehouse, "posting_date": self.doc.posting_date, "ordered_qty": flt(ordered_qty) if self.doc.docstatus == 1 else -flt(ordered_qty) })
def declare_enquiry_lost(self, arg): if not self.has_quotation(): webnotes.conn.set(self.doc, 'status', 'Lost') webnotes.conn.set(self.doc, 'order_lost_reason', arg) else: webnotes.throw( _("Cannot declare as lost, because Quotation has been made."))
def validate_one_root(self): if not self.doc.fields[self.nsm_parent_field]: if webnotes.conn.sql( """select count(*) from `tab%s` where ifnull(%s, '')=''""" % (self.doc.doctype, self.nsm_parent_field))[0][0] > 1: webnotes.throw(_("""Multiple root nodes not allowed."""))
def update_prevdoc_status(self, flag): for quotation in self.doclist.get_distinct_values("prevdoc_docname"): #webnotes.errprint(internal) bean = webnotes.bean("Quotation", quotation) #webnotes.errprint(bean) if bean.doc.docstatus==2: webnotes.throw( internal + ": " + webnotes._("Quotation is cancelled."))
def check_duplicate_entry_for_production_order(self): other_ste = [ t[0] for t in webnotes.conn.get_values( "Stock Entry", { "production_order": self.doc.production_order, "purpose": self.doc.purpose, "docstatus": ["!=", 2], "name": ["!=", self.doc.name] }, "name") ] if other_ste: production_item, qty = webnotes.conn.get_value( "Production Order", self.doc.production_order, ["production_item", "qty"]) args = other_ste + [production_item] fg_qty_already_entered = webnotes.conn.sql( """select sum(actual_qty) from `tabStock Entry Detail` where parent in (%s) and item_code = %s and ifnull(s_warehouse,'')='' """ % (", ".join(["%s" * len(other_ste)]), "%s"), args)[0][0] if fg_qty_already_entered >= qty: webnotes.throw( _("Stock Entries already created for Production Order ") + self.doc.production_order + ":" + ", ".join(other_ste), DuplicateEntryForProductionOrderError)
def update_last_purchase_rate(self, obj, is_submit): """updates last_purchase_rate in item table for each item""" import webnotes.utils this_purchase_date = webnotes.utils.getdate(obj.doc.fields.get('posting_date') or obj.doc.fields.get('transaction_date')) for d in getlist(obj.doclist,obj.fname): # get last purchase details last_purchase_details = get_last_purchase_details(d.item_code, obj.doc.name) # compare last purchase date and this transaction's date last_purchase_rate = None if last_purchase_details and \ (last_purchase_details.purchase_date > this_purchase_date): last_purchase_rate = last_purchase_details['purchase_rate'] elif is_submit == 1: # even if this transaction is the latest one, it should be submitted # for it to be considered for latest purchase rate if flt(d.conversion_factor): last_purchase_rate = flt(d.purchase_rate) / flt(d.conversion_factor) else: webnotes.throw(_("Row ") + cstr(d.idx) + ": " + _("UOM Conversion Factor is mandatory")) # update last purchsae rate if last_purchase_rate: webnotes.conn.sql("""update `tabItem` set last_purchase_rate = %s where name = %s""", (flt(last_purchase_rate), d.item_code))
def validate_max_discount(self): for d in self.doclist.get({"parentfield": self.fname}): discount = flt(webnotes.conn.get_value("Item", d.item_code, "max_discount")) if discount and flt(d.adj_rate) > discount: webnotes.throw(_("You cannot give more than ") + cstr(discount) + "% " + _("discount on Item Code") + ": " + cstr(d.item_code))
def _make_customer(source_name, ignore_permissions=False): quotation = webnotes.conn.get_value("Quotation", source_name, ["lead", "order_type"]) if quotation and quotation[0]: lead_name = quotation[0] customer_name = webnotes.conn.get_value("Customer", {"lead_name": lead_name}) if not customer_name: from selling.doctype.lead.lead import _make_customer customer_doclist = _make_customer( lead_name, ignore_permissions=ignore_permissions) customer = webnotes.bean(customer_doclist) customer.ignore_permissions = ignore_permissions if quotation[1] == "Shopping Cart": customer.doc.customer_group = webnotes.conn.get_value( "Shopping Cart Settings", None, "default_customer_group") try: customer.insert() return customer except NameError, e: if webnotes.defaults.get_global_default( 'cust_master_name') == "Customer Name": customer.run_method("autoname") customer.doc.name += "-" + lead_name customer.insert() return customer else: raise except webnotes.MandatoryError: from webnotes.utils import get_url_to_form webnotes.throw(_("Before proceeding, please create Customer from Lead") + \ (" - %s" % get_url_to_form("Lead", lead_name)))
def validate_production_order_against_so(self): # already ordered qty ordered_qty_against_so = webnotes.conn.sql("""select sum(qty) from `tabProduction Order` where production_item = %s and sales_order = %s and docstatus < 2 and name != %s""", (self.doc.production_item, self.doc.sales_order, self.doc.name))[0][0] total_qty = flt(ordered_qty_against_so) + flt(self.doc.qty) # get qty from Sales Order Item table so_item_qty = webnotes.conn.sql("""select sum(qty) from `tabSales Order Item` where parent = %s and item_code = %s""", (self.doc.sales_order, self.doc.production_item))[0][0] # get qty from Packing Item table dnpi_qty = webnotes.conn.sql("""select sum(qty) from `tabPacked Item` where parent = %s and parenttype = 'Sales Order' and item_code = %s""", (self.doc.sales_order, self.doc.production_item))[0][0] # total qty in SO so_qty = flt(so_item_qty) + flt(dnpi_qty) if total_qty > so_qty: webnotes.throw(_("Total production order qty for item") + ": " + cstr(self.doc.production_item) + _(" against sales order") + ": " + cstr(self.doc.sales_order) + _(" will be ") + cstr(total_qty) + ", " + _("which is greater than sales order qty ") + "(" + cstr(so_qty) + ")" + _("Please reduce qty."), exc=OverProductionError)
def validate_purchase_receipts(self, purchase_receipts): for pr in purchase_receipts: if webnotes.conn.get_value("Purchase Receipt", pr, "docstatus") != 1: webnotes.throw( _("Purchase Receipt") + ": " + pr + _(" is not submitted document"))
def validate_exchange_rates_exist(self): """check if exchange rates exist for all Price List currencies (to company's currency)""" company_currency = webnotes.conn.get_value("Company", self.doc.company, "default_currency") if not company_currency: msgprint(_("Please specify currency in Company") + ": " + self.doc.company, raise_exception=ShoppingCartSetupError) price_list_currency_map = webnotes.conn.get_values("Price List", [d.selling_price_list for d in self.doclist.get({"parentfield": "price_lists"})], "currency") # check if all price lists have a currency for price_list, currency in price_list_currency_map.items(): if not currency: webnotes.throw("%s: %s" % (_("Currency is missing for Price List"), price_list)) expected_to_exist = [currency + "-" + company_currency for currency in price_list_currency_map.values() if currency != company_currency] if expected_to_exist: exists = webnotes.conn.sql_list("""select name from `tabCurrency Exchange` where name in (%s)""" % (", ".join(["%s"]*len(expected_to_exist)),), tuple(expected_to_exist)) missing = list(set(expected_to_exist).difference(exists)) if missing: msgprint(_("Missing Currency Exchange Rates for" + ": " + comma_and(missing)), raise_exception=ShoppingCartSetupError)
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 update_outstanding_amt(account, against_voucher_type, against_voucher, on_cancel=False): # get final outstanding amt bal = flt(webnotes.conn.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` where against_voucher_type=%s and against_voucher=%s and account = %s""", (against_voucher_type, against_voucher, account))[0][0] or 0.0) if against_voucher_type == 'Purchase Invoice': bal = -bal elif against_voucher_type == "Journal Voucher": against_voucher_amount = flt(webnotes.conn.sql(""" select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` where voucher_type = 'Journal Voucher' and voucher_no = %s and account = %s and ifnull(against_voucher, '') = ''""", (against_voucher, account))[0][0]) bal = against_voucher_amount + bal if against_voucher_amount < 0: bal = -bal # Validation : Outstanding can not be negative if bal < 0 and not on_cancel: webnotes.throw(_("Outstanding for Voucher ") + against_voucher + _(" will become ") + fmt_money(bal) + _(". Outstanding cannot be less than zero. \ Please match exact outstanding.")) # Update outstanding amt on against voucher if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]: webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" % (against_voucher_type, bal, against_voucher))
def _make_customer(source_name, ignore_permissions=False): quotation = webnotes.conn.get_value("Quotation", source_name, ["lead", "order_type"]) if quotation and quotation[0]: lead_name = quotation[0] customer_name = webnotes.conn.get_value("Customer", {"lead_name": lead_name}) if not customer_name: from selling.doctype.lead.lead import _make_customer customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions) customer = webnotes.bean(customer_doclist) customer.ignore_permissions = ignore_permissions if quotation[1] == "Shopping Cart": customer.doc.customer_group = webnotes.conn.get_value("Shopping Cart Settings", None, "default_customer_group") try: customer.insert() return customer except NameError, e: if webnotes.defaults.get_global_default('cust_master_name') == "Customer Name": customer.run_method("autoname") customer.doc.name += "-" + lead_name customer.insert() return customer else: raise except webnotes.MandatoryError: from webnotes.utils import get_url_to_form webnotes.throw(_("Before proceeding, please create Customer from Lead") + \ (" - %s" % get_url_to_form("Lead", lead_name)))
def update_prevdoc_status(self, flag): for quotation in self.doclist.get_distinct_values("prevdoc_docname"): bean = webnotes.bean("Quotation", quotation) if bean.doc.docstatus==2: webnotes.throw(quotation + ": " + webnotes._("Quotation is cancelled.")) bean.get_controller().set_status(update=True)
def assign_post(post, profile=None): post = webnotes.bean("Post", post) if not get_access(post.doc.unit).get("write"): raise webnotes.PermissionError("You are not allowed edit this post") if profile and not get_access(post.doc.unit, profile).get("write"): raise webnotes.PermissionError("Selected user does not have 'write' access to this post") if profile and post.doc.assigned_to: webnotes.throw("Someone is already assigned to this post. Please refresh.") if not profile and post.doc.status == "Completed": webnotes.throw("You cannot revoke assignment of a completed task.") post.doc.status = "Assigned" if profile else None post.doc.assigned_to = profile post.doc.assigned_to_fullname = get_fullname(profile) if profile else None post.ignore_permissions = True post.save() return { "post_settings_html": get_post_settings(post.doc.unit, post.doc.name), "assigned_to_fullname": post.doc.assigned_to_fullname, "status": post.doc.status }
def validate_frozen_accounts_modifier(self): old_value = webnotes.conn.get_value("Account", self.doc.name, "freeze_account") if old_value and old_value != self.doc.freeze_account: frozen_accounts_modifier = webnotes.conn.get_value( 'Accounts Settings', None, 'frozen_accounts_modifier') if not frozen_accounts_modifier or \ frozen_accounts_modifier not in webnotes.user.get_roles(): webnotes.throw(_("You are not authorized to set Frozen value"))
def check_stop_sales_order(self, ref_fieldname): for d in self.doclist.get({"parentfield": self.fname}): if d.fields.get(ref_fieldname): status = webnotes.conn.get_value("Sales Order", d.fields[ref_fieldname], "status") if status == "Stopped": webnotes.throw(self.doc.doctype + _(" can not be created/modified against stopped Sales Order ") + d.fields[ref_fieldname])
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) \ - flt(self.doc.grand_total) > 1/(10**(self.precision("grand_total") + 1)): webnotes.throw(_("""(Paid amount + Write Off Amount) can not be \ greater than Grand Total"""))
def _validate_production_order(pro_bean): if flt(pro_bean.doc.docstatus) != 1: webnotes.throw(_("Production Order must be submitted") + ": " + self.doc.production_order) if pro_bean.doc.status == 'Stopped': msgprint(_("Transaction not allowed against stopped Production Order") + ": " + self.doc.production_order)
def validate_ledger(self, group_identifier="is_group"): if self.doc.fields.get(group_identifier) == "No": if webnotes.conn.sql( """select name from `tab%s` where %s=%s and docstatus!=2""" % (self.doc.doctype, self.nsm_parent_field, '%s'), (self.doc.name)): webnotes.throw(self.doc.doctype + ": " + self.doc.name + _( " can not be marked as a ledger as it has existing child"))
def validate_rejected_warehouse(self): for d in self.doclist.get({"parentfield": "purchase_receipt_details"}): if flt(d.rejected_qty) and not d.rejected_warehouse: d.rejected_warehouse = self.doc.rejected_warehouse if not d.rejected_warehouse: webnotes.throw( _("Rejected Warehouse is mandatory against regected item" ))
def check_if_page_name_is_unique(self, new_page_name): if webnotes.conn.sql( """select name from `tabWebsite Sitemap` where name=%s and website_sitemap_config!=%s and docname!=%s""", (new_page_name, self._website_config.name, self.doc.name)): webnotes.throw("%s: %s. %s: <b>%s<b>" % (new_page_name, _("Page already exists"), _("Please change the value"), self.doc.title))
def before_rename(self, newdn, olddn, merge=False, group_fname="is_group"): if merge: is_group = webnotes.conn.get_value(self.doc.doctype, newdn, group_fname) if self.doc.fields[group_fname] != is_group: webnotes.throw( _("""Merging is only possible between Group-to-Group or Ledger-to-Ledger"""))