def validate_expense_against_budget(args): args = frappe._dict(args) if frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}): budget = frappe.db.sql(""" select bd.budget_allocated, cc.distribution_id from `tabCost Center` cc, `tabBudget Detail` bd where cc.name=bd.parent and cc.name=%s and account=%s and bd.fiscal_year=%s """, (args.cost_center, args.account, args.fiscal_year), as_dict=True) if budget and budget[0].budget_allocated: yearly_action, monthly_action = frappe.db.get_value("Company", args.company, ["yearly_bgt_flag", "monthly_bgt_flag"]) action_for = action = "" if monthly_action in ["Stop", "Warn"]: budget_amount = get_allocated_budget(budget[0].distribution_id, args.posting_date, args.fiscal_year, budget[0].budget_allocated) args["month_end_date"] = frappe.db.sql("select LAST_DAY(%s)", args.posting_date)[0][0] action_for, action = _("Monthly"), monthly_action elif yearly_action in ["Stop", "Warn"]: budget_amount = budget[0].budget_allocated action_for, action = _("Annual"), yearly_action if action_for: actual_expense = get_actual_expense(args) if actual_expense > budget_amount: frappe.msgprint(_("{0} budget for Account {1} against Cost Center {2} will exceed by {3}").format( _(action_for), args.account, args.cost_center, cstr(actual_expense - budget_amount))) if action=="Stop": raise BudgetError
def validate_mandatory_fields(self): if self.group_based_on == "Course" and not self.course: frappe.throw(_("Please select Course")) if self.group_based_on == "Course" and (not self.program and self.batch): frappe.throw(_("Please select Program")) if self.group_based_on == "Batch" and not self.program: frappe.throw(_("Please select Program"))
def _get_message(url=False): if url: name = get_url_to_form(self.doctype, self.name) else: name = self.name return (_("Leave Application") + ": %s - %s") % (name, _(status))
def validate_filters(filters): if not filters.fiscal_year: frappe.throw(_("Fiscal Year {0} is required").format(filters.fiscal_year)) fiscal_year = frappe.db.get_value("Fiscal Year", filters.fiscal_year, ["year_start_date", "year_end_date"], as_dict=True) if not fiscal_year: frappe.throw(_("Fiscal Year {0} does not exist").format(filters.fiscal_year)) else: filters.year_start_date = getdate(fiscal_year.year_start_date) filters.year_end_date = getdate(fiscal_year.year_end_date) if not filters.from_date: filters.from_date = filters.year_start_date if not filters.to_date: filters.to_date = filters.year_end_date filters.from_date = getdate(filters.from_date) filters.to_date = getdate(filters.to_date) if filters.from_date > filters.to_date: frappe.throw(_("From Date cannot be greater than To Date")) if (filters.from_date < filters.year_start_date) or (filters.from_date > filters.year_end_date): frappe.msgprint(_("From Date should be within the Fiscal Year. Assuming From Date = {0}")\ .format(formatdate(filters.year_start_date))) filters.from_date = filters.year_start_date if (filters.to_date < filters.year_start_date) or (filters.to_date > filters.year_end_date): frappe.msgprint(_("To Date should be within the Fiscal Year. Assuming To Date = {0}")\ .format(formatdate(filters.year_end_date))) filters.to_date = filters.year_end_date
def validate_website_image(self): """Validate if the website image is a public file""" auto_set_website_image = False if not self.website_image and self.image: auto_set_website_image = True self.website_image = self.image if not self.website_image: return # find if website image url exists as public file_doc = frappe.get_all("File", filters={ "file_url": self.website_image }, fields=["name", "is_private"], order_by="is_private asc", limit_page_length=1) if file_doc: file_doc = file_doc[0] if not file_doc: if not auto_set_website_image: frappe.msgprint(_("Website Image {0} attached to Item {1} cannot be found") .format(self.website_image, self.name)) self.website_image = None elif file_doc.is_private: if not auto_set_website_image: frappe.msgprint(_("Website Image should be a public file or website URL")) self.website_image = None
def connect(self): """Connect to **Email Account**.""" try: if cint(self.settings.use_ssl): self.pop = Timed_POP3_SSL(self.settings.host, timeout=frappe.conf.get("pop_timeout")) else: self.pop = Timed_POP3(self.settings.host, timeout=frappe.conf.get("pop_timeout")) self.pop.user(self.settings.username) self.pop.pass_(self.settings.password) # connection established! return True except _socket.error: # Invalid mail server -- due to refusing connection frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.')) raise except poplib.error_proto, e: if self.is_temporary_system_problem(e): return False else: frappe.msgprint(_('Invalid User Name or Support Password. Please rectify and try again.')) raise
def validate_fiscal_year(date, fiscal_year, label=_("Date"), doc=None): years = [f[0] for f in get_fiscal_years(date, label=label)] if fiscal_year not in years: if doc: doc.fiscal_year = years[0] else: throw(_("{0} '{1}' not in Fiscal Year {2}").format(label, formatdate(date), fiscal_year))
def validate_item(self): stock_items = self.get_stock_items() serialized_items = self.get_serialized_items() for item in self.get("items"): if item.item_code not in stock_items: frappe.throw(_("{0} is not a stock Item").format(item.item_code)) item_details = self.get_item_details(frappe._dict({"item_code": item.item_code, "company": self.company, "project_name": self.project_name})) for f in ("uom", "stock_uom", "description", "item_name", "expense_account", "cost_center", "conversion_factor"): if f not in ["expense_account", "cost_center"] or not item.get(f): item.set(f, item_details.get(f)) if self.difference_account: item.expense_account = self.difference_account if not item.transfer_qty: item.transfer_qty = item.qty * item.conversion_factor if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return", "Material Transfer for Manufacture") and not item.serial_no and item.item_code in serialized_items): frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code), frappe.MandatoryError)
def bulk_rename(doctype, rows=None, via_console = False): """Bulk rename documents :param doctype: DocType to be renamed :param rows: list of documents as `((oldname, newname), ..)`""" if not rows: frappe.throw(_("Please select a valid csv file with data")) if not via_console: max_rows = 500 if len(rows) > max_rows: frappe.throw(_("Maximum {0} rows allowed").format(max_rows)) rename_log = [] for row in rows: # if row has some content if len(row) > 1 and row[0] and row[1]: try: if rename_doc(doctype, row[0], row[1]): msg = _("Successful: {0} to {1}").format(row[0], row[1]) frappe.db.commit() else: msg = _("Ignored: {0} to {1}").format(row[0], row[1]) except Exception, e: msg = _("** Failed: {0} to {1}: {2}").format(row[0], row[1], repr(e)) frappe.db.rollback() if via_console: print msg else: rename_log.append(msg)
def validate_fieldtype_change(self, df, old_value, new_value): for allowed_changes in self.allowed_fieldtype_change: if ((old_value in allowed_changes and new_value in allowed_changes) or (old_value not in allowed_changes and new_value not in allowed_changes)): continue else: frappe.throw(_("Fieldtype must be one of {0} in row {1}").format(", ".join([_(fieldtype) for fieldtype in allowed_changes]), df.idx))
def get_data(): return { 'fieldname': 'purchase_invoice', 'non_standard_fieldnames': { 'Journal Entry': 'reference_name', 'Payment Entry': 'reference_name', 'Payment Request': 'reference_name', 'Landed Cost Voucher': 'receipt_document', 'Purchase Invoice': 'return_against', 'Subscription': 'reference_document' }, 'internal_links': { 'Purchase Order': ['items', 'purchase_order'], 'Purchase Receipt': ['items', 'purchase_receipt'], }, 'transactions': [ { 'label': _('Payment'), 'items': ['Payment Entry', 'Payment Request', 'Journal Entry'] }, { 'label': _('Reference'), 'items': ['Purchase Order', 'Purchase Receipt', 'Asset', 'Landed Cost Voucher'] }, { 'label': _('Returns'), 'items': ['Purchase Invoice'] }, { 'label': _('Subscription'), 'items': ['Subscription'] }, ] }
def validate(self): """Validate email id and check POP3 and SMTP connections is enabled.""" if self.email_id: validate_email_add(self.email_id, True) if self.login_id_is_different: if not self.login_id: frappe.throw(_("Login Id is required")) else: self.login_id = None if frappe.local.flags.in_patch or frappe.local.flags.in_test: return if self.enable_incoming and not self.append_to: frappe.throw(_("Append To is mandatory for incoming mails")) if not frappe.local.flags.in_install and not frappe.local.flags.in_patch: if self.enable_incoming: self.get_pop3() if self.enable_outgoing: self.check_smtp() if self.notify_if_unreplied: if not self.send_notification_to: frappe.throw(_("{0} is mandatory").format(self.meta.get_label("send_notification_to"))) for e in self.get_unreplied_notification_emails(): validate_email_add(e, True) if self.enable_incoming and self.append_to: valid_doctypes = [d[0] for d in get_append_to()] if self.append_to not in valid_doctypes: frappe.throw(_("Append To can be one of {0}").format(comma_or(valid_doctypes)))
def get_data(filters): conditions, filters = get_conditions(filters) data = frappe.db.sql(""" select t1.employee, t3.employee_name, t1.designation, t3.passport_number, sum(case when t2.salary_component = 'Basic Pay' then ifnull(t2.amount,0) else 0 end) as basicpay, t3.nppf_number, sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0) else 0 end) as employeepf, sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0) else 0 end) as employerpf, sum(case when t2.salary_component = 'PF' then ifnull(t2.amount,0)*2 else 0 end) as total, t1.company, t1.branch, t1.department, t1.division, t1.section, t1.fiscal_year, t1.month from `tabSalary Slip` t1, `tabSalary Detail` t2, `tabEmployee` t3 where t1.docstatus = 1 %s and t3.employee = t1.employee and t2.parent = t1.name and t2.salary_component in ('Basic Pay','PF') group by t1.employee, t3.employee_name, t1.designation, t3.passport_number, t3.nppf_number, t1.company, t1.branch, t1.department, t1.division, t1.section, t1.fiscal_year, t1.month """ % conditions, filters) if not data: msgprint(_("No Data Found for month: ") + cstr(filters.get("month")) + _(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1) return data
def get_conditions(filters): conditions = "" if not filters.get("from_date"): frappe.throw(_("'From Date' is required")) if filters.get("to_date"): conditions += " and sle.posting_date <= '%s'" % frappe.db.escape(filters.get("to_date")) else: frappe.throw(_("'To Date' is required")) if filters.get("item_group"): ig_details = frappe.db.get_value("Item Group", filters.get("item_group"), ["lft", "rgt"], as_dict=1) if ig_details: conditions += """ and exists (select name from `tabItem Group` ig where ig.lft >= %s and ig.rgt <= %s and item.item_group = ig.name) """ % (ig_details.lft, ig_details.rgt) if filters.get("item_code"): conditions += " and sle.item_code = '%s'" % frappe.db.escape(filters.get("item_code"), percent=False) if filters.get("warehouse"): warehouse_details = frappe.db.get_value("Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1) if warehouse_details: conditions += " and exists (select name from `tabWarehouse` wh \ where wh.lft >= %s and wh.rgt <= %s and sle.warehouse = wh.name)"%(warehouse_details.lft, warehouse_details.rgt) return conditions
def validate_credit_debit_note(self): if self.stock_entry: if frappe.db.get_value("Stock Entry", self.stock_entry, "docstatus") != 1: frappe.throw(_("Stock Entry {0} is not submitted").format(self.stock_entry)) if frappe.db.exists({"doctype": "Journal Entry", "stock_entry": self.stock_entry, "docstatus":1}): frappe.msgprint(_("Warning: Another {0} # {1} exists against stock entry {2}".format(self.voucher_type, self.name, self.stock_entry)))
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item): allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value') if allow_rename_attribute_value: pass elif attribute_value not in attributes_list: frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format( attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
def validate_against_jv(self): for d in self.get('accounts'): if d.reference_type=="Journal Entry": account_root_type = frappe.db.get_value("Account", d.account, "root_type") if account_root_type == "Asset" and flt(d.debit) > 0: frappe.throw(_("For {0}, only credit accounts can be linked against another debit entry") .format(d.account)) elif account_root_type == "Liability" and flt(d.credit) > 0: frappe.throw(_("For {0}, only debit accounts can be linked against another credit entry") .format(d.account)) if d.reference_name == self.name: frappe.throw(_("You can not enter current voucher in 'Against Journal Entry' column")) against_entries = frappe.db.sql("""select * from `tabJournal Entry Account` where account = %s and docstatus = 1 and parent = %s and (reference_type is null or reference_type in ("", "Sales Order", "Purchase Order")) """, (d.account, d.reference_name), as_dict=True) if not against_entries: frappe.throw(_("Journal Entry {0} does not have account {1} or already matched against other voucher") .format(d.reference_name, d.account)) else: dr_or_cr = "debit" if d.credit > 0 else "credit" valid = False for jvd in against_entries: if flt(jvd[dr_or_cr]) > 0: valid = True if not valid: frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry") .format(d.reference_name, dr_or_cr))
def validate_orders(self): """Validate totals, closed and docstatus for orders""" for reference_name, total in self.reference_totals.iteritems(): reference_type = self.reference_types[reference_name] account = self.reference_accounts[reference_name] if reference_type in ("Sales Order", "Purchase Order"): order = frappe.get_doc(reference_type, reference_name) if order.docstatus != 1: frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name)) if flt(order.per_billed) >= 100: frappe.throw(_("{0} {1} is fully billed").format(reference_type, reference_name)) if cstr(order.status) == "Closed": frappe.throw(_("{0} {1} is closed").format(reference_type, reference_name)) account_currency = get_account_currency(account) if account_currency == self.company_currency: voucher_total = order.base_grand_total formatted_voucher_total = fmt_money(voucher_total, order.precision("base_grand_total"), currency=account_currency) else: voucher_total = order.grand_total formatted_voucher_total = fmt_money(voucher_total, order.precision("grand_total"), currency=account_currency) if flt(voucher_total) < (flt(order.advance_paid) + total): frappe.throw(_("Advance paid against {0} {1} cannot be greater \ than Grand Total {2}").format(reference_type, reference_name, formatted_voucher_total))
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): from erpnext.controllers.status_updater import get_tolerance_for item_tolerance = {} global_tolerance = None for item in self.get("items"): if item.get(item_ref_dn): ref_amt = flt(frappe.db.get_value(ref_dt + " Item", item.get(item_ref_dn), based_on), self.precision(based_on, item)) if not ref_amt: frappe.msgprint(_("Warning: System will not check overbilling since amount for Item {0} in {1} is zero").format(item.item_code, ref_dt)) else: already_billed = frappe.db.sql("""select sum(%s) from `tab%s` where %s=%s and docstatus=1 and parent != %s""" % (based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'), (item.get(item_ref_dn), self.name))[0][0] total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)), self.precision(based_on, item)) tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, item_tolerance, global_tolerance) max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100) if total_billed_amt - max_allowed_amt > 0.01: frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow overbilling, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt))
def get_data(): return [ { "label": _("Documents"), "icon": "icon-star", "items": [ { "type":"doctype", "name": "Locate Address On Map", "description": _("Locate Address On Map") }, ] }, { "label": _("Setup"), "icon": "icon-star", "items": [ { "type":"doctype", "name": "Map Settings", "description": _("Map Settings") }, ] }, ]
def validate_value(self, fieldname, condition, val2, doc=None, raise_exception=None): """Check that value of fieldname should be 'condition' val2 else throw Exception.""" error_condition_map = { "in": _("one of"), "not in": _("none of"), "^": _("beginning with"), } if not doc: doc = self val1 = doc.get_value(fieldname) df = doc.meta.get_field(fieldname) val2 = doc.cast(val2, df) if not frappe.compare(val1, condition, val2): label = doc.meta.get_label(fieldname) condition_str = error_condition_map.get(condition, condition) if doc.parentfield: msg = _("Incorrect value in row {0}: {1} must be {2} {3}".format(doc.idx, label, condition_str, val2)) else: msg = _("Incorrect value: {0} must be {1} {2}".format(label, condition_str, val2)) # raise passed exception or True msgprint(msg, raise_exception=raise_exception or True)
def add_custom_doctypes(data, doctype_info): """Adds Custom DocTypes to modules setup via `config/desktop.py`.""" add_section(data, _("Documents"), "icon-star", [d for d in doctype_info if (d.custom and d.document_type in ("Document", "Transaction"))]) add_section(data, _("Setup"), "icon-cog", [d for d in doctype_info if (d.custom and d.document_type in ("Setup", "Master", ""))])
def set_transfer_qty(self): for item in self.get("items"): if not flt(item.qty): frappe.throw(_("Row {0}: Qty is mandatory").format(item.idx)) if not flt(item.conversion_factor): frappe.throw(_("Row {0}: UOM Conversion Factor is mandatory").format(item.idx)) item.transfer_qty = flt(item.qty * item.conversion_factor, self.precision("transfer_qty", item))
def get_gl_entries(self, warehouse_account): expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account) for d in self.get("items"): additional_cost = flt(d.additional_cost, d.precision("additional_cost")) if additional_cost: gl_entries.append( self.get_gl_dict( { "account": expenses_included_in_valuation, "against": d.expense_account, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": additional_cost, } ) ) gl_entries.append( self.get_gl_dict( { "account": d.expense_account, "against": expenses_included_in_valuation, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": -1 * additional_cost, # put it as negative credit instead of debit purposefully } ) ) return gl_entries
def validate_price_list(args): if args.get("price_list"): if not frappe.db.get_value("Price List", {"name": args.price_list, args.transaction_type: 1, "enabled": 1}): throw(_("Price List {0} is disabled").format(args.price_list)) else: throw(_("Price List not selected"))
def _validate_selects(self): if frappe.flags.in_import: return for df in self.meta.get_select_fields(): if df.fieldname=="naming_series" or not (self.get(df.fieldname) and df.options): continue options = (df.options or "").split("\n") # if only empty options if not filter(None, options): continue # strip and set self.set(df.fieldname, cstr(self.get(df.fieldname)).strip()) value = self.get(df.fieldname) if value not in options and not (frappe.flags.in_test and value.startswith("_T-")): # show an elaborate message prefix = _("Row #{0}:").format(self.idx) if self.get("parentfield") else "" label = _(self.meta.get_label(df.fieldname)) comma_options = '", "'.join(_(each) for each in options) frappe.throw(_('{0} {1} cannot be "{2}". It should be one of "{3}"').format(prefix, label, value, comma_options))
def validate_purchase_order(self): """Throw exception if more raw material is transferred against Purchase Order than in the raw materials supplied table""" if self.purpose == "Subcontract" and self.purchase_order: purchase_order = frappe.get_doc("Purchase Order", self.purchase_order) for se_item in self.items: total_allowed = sum( [flt(d.required_qty) for d in purchase_order.supplied_items if d.rm_item_code == se_item.item_code] ) if not total_allowed: frappe.throw( _("Item {0} not found in 'Raw Materials Supplied' table in Purchase Order {1}").format( se_item.item_code, self.purchase_order ) ) total_supplied = frappe.db.sql( """select sum(qty) from `tabStock Entry Detail`, `tabStock Entry` where `tabStock Entry`.purchase_order = %s and `tabStock Entry`.docstatus = 1 and `tabStock Entry Detail`.item_code = %s and `tabStock Entry Detail`.parent = `tabStock Entry`.name""", (self.purchase_order, se_item.item_code), )[0][0] if total_supplied > total_allowed: frappe.throw( _("Not allowed to tranfer more {0} than {1} against Purchase Order {2}").format( se_item.item_code, total_allowed, self.purchase_order ) )
def get_pending_raw_materials(self): """ issue (item quantity) that is pending to issue or desire to transfer, whichever is less """ item_dict = self.get_bom_raw_materials(1) issued_item_qty = self.get_issued_qty() max_qty = flt(self.pro_doc.qty) only_pending_fetched = [] for item in item_dict: pending_to_issue = (max_qty * item_dict[item]["qty"]) - issued_item_qty.get(item, 0) desire_to_transfer = flt(self.fg_completed_qty) * item_dict[item]["qty"] if desire_to_transfer <= pending_to_issue: item_dict[item]["qty"] = desire_to_transfer else: item_dict[item]["qty"] = pending_to_issue if pending_to_issue: only_pending_fetched.append(item) # delete items with 0 qty for item in item_dict.keys(): if not item_dict[item]["qty"]: del item_dict[item] # show some message if not len(item_dict): frappe.msgprint(_("""All items have already been transferred for this Production Order.""")) elif only_pending_fetched: frappe.msgprint(_("Pending Items {0} updated").format(only_pending_fetched)) return item_dict
def get_columns(): return [_("Agent") + ":Link/Agent:200", _("First Name") + ":Data:100", _("Last Name") + ":Data:120", _("Contact No") + ":Data:160", _("Location") + ":Data:250" ]
def check_prev_docstatus(self): for d in self.get('items'): if d.sales_order and frappe.db.get_value("Sales Order", d.sales_order, "docstatus") != 1: frappe.throw(_("Sales Order {0} is not submitted").format(d.sales_order)) if d.delivery_note and frappe.db.get_value("Delivery Note", d.delivery_note, "docstatus") != 1: throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
def get_columns(filters): columns = [ { "label": _("Applicant Type"), "fieldname": "applicant_type", "options": "DocType", "width": 100, }, { "label": _("Applicant Name"), "fieldname": "applicant_name", "fieldtype": "Dynamic Link", "options": "applicant_type", "width": 150, }, { "label": _("Loan Security"), "fieldname": "loan_security", "fieldtype": "Link", "options": "Loan Security", "width": 160, }, { "label": _("Loan Security Code"), "fieldname": "loan_security_code", "fieldtype": "Data", "width": 100, }, { "label": _("Loan Security Name"), "fieldname": "loan_security_name", "fieldtype": "Data", "width": 150, }, { "label": _("Haircut"), "fieldname": "haircut", "fieldtype": "Percent", "width": 100 }, { "label": _("Loan Security Type"), "fieldname": "loan_security_type", "fieldtype": "Link", "options": "Loan Security Type", "width": 120, }, { "label": _("Disabled"), "fieldname": "disabled", "fieldtype": "Check", "width": 80 }, { "label": _("Total Qty"), "fieldname": "total_qty", "fieldtype": "Float", "width": 100 }, { "label": _("Latest Price"), "fieldname": "latest_price", "fieldtype": "Currency", "options": "currency", "width": 100, }, { "label": _("Price Valid Upto"), "fieldname": "price_valid_upto", "fieldtype": "Datetime", "width": 100, }, { "label": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "currency", "width": 100, }, { "label": _("% Of Applicant Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100, }, { "label": _("Currency"), "fieldname": "currency", "fieldtype": "Currency", "options": "Currency", "hidden": 1, "width": 100, }, ] return columns
def validate_rm_item(self, item): if (item[0]['name'] in [it.item_code for it in self.items]) and item[0]['name'] == self.item: frappe.throw(_("Raw material cannot be same as main Item"))
def get_columns(filters): """return columns""" columns = [ # {"label": _("Country"), "fieldname": "country", "fieldtype": "Link", "options": "Country", "width": 80}, # {"label": _("Company"), "fieldname": "company", "fieldtype": "Link", "options": "Company", "width": 200}, {"label": _("Item"), "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 300}, {"label": _("Category"), "fieldname": "item_group", "fieldtype": "Link", "options": "Item Group", "width": 150}, {"label": _("Department"), "fieldname": "department", "fieldtype": "Link", "options": "Department", "width": 200}, # {"label": _("Category"), "fieldname": "item_group", "fieldtype": "Link", "options": "Item Group", "width": 150}, {"label": _("Supplier"), "fieldname": "supplier", "fieldtype": "Data","width": 150}, {"label": _("Part No."), "fieldname": "supplier_part_no", "fieldtype": "Data", "width": 150}, # {"label": _("Item"), "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 300}, {"label": _("Warehouse"), "fieldname": "warehouse", "fieldtype": "Link", "options": "Warehouse", "width": 300}, {"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, {"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": 150} ] if filters.get('show_stock_ageing_data'): columns += [{'label': _('Average Age'), 'fieldname': 'average_age', 'width': 100}, {'label': _('Earliest Age'), 'fieldname': 'earliest_age', 'width': 100}, {'label': _('Latest Age'), 'fieldname': 'latest_age', 'width': 100}] if filters.get('show_variant_attributes'): columns += [{'label': att_name, 'fieldname': att_name, 'width': 100} for att_name in get_variants_attributes()] return columns
def execute(filters=None): if not filters: filters = {} validate_filters(filters) stock_value_in_sc = 0 from_date = filters.get('from_date') to_date = filters.get('to_date') include_uom = filters.get("include_uom") columns = get_columns(filters) items = get_items(filters) sle = get_stock_ledger_entries(filters, items) if filters.get('show_stock_ageing_data'): filters['show_warehouse_wise_stock'] = True item_wise_fifo_queue = get_fifo_queue(filters, sle) if not sle: return columns, [] if filters.get("currency"): columns.extend([ {"label": _("Currency"), "fieldname": "sc_currency", "fieldtype": "Data", "width": 80}, {"label": _("Balance Value"), "fieldname": "sc_value", "fieldtype": "Float", "width": 100} ]) if filters.get('warehouse'): filters.warehouse = frappe.parse_json(filters.get('warehouse')) iwb_map = get_item_warehouse_map(filters, sle) item_map = get_item_details(items, sle, filters) item_reorder_detail_map = get_item_reorder_details(item_map.keys()) data = [] test = [] conversion_factors = {} _func = lambda x: x[1] item_head = [] for (company, item, warehouse) in sorted(iwb_map): if not item in item_head: item_info = get_parent_details(item, filters) data.append({ 'item_code': item, 'bal_qty': item_info.bal_qty, 'indent': 0 }) item_head.append(item) if item_map.get(item): qty_dict = iwb_map[(company, item, warehouse)] item_reorder_level = 0 item_reorder_qty = 0 if item + warehouse in item_reorder_detail_map: item_reorder_level = item_reorder_detail_map[item + warehouse]["warehouse_reorder_level"] item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"] supplier = supplier_part_no = '' supplier_info = frappe.get_value('Item Supplier',{'parent':item},['supplier','supplier_part_no']) if supplier_info: supplier = supplier_info[0] supplier_part_no = supplier_info[1] report_data = { 'item_code': item, 'warehouse': warehouse, 'company': company, 'supplier': supplier, 'indent': 1, 'supplier_part_no': supplier_part_no, 'bal_val_cur':frappe.db.get_value('Company',company, "default_currency"), 'country': frappe.get_value('Warehouse',warehouse,'country'), 'reorder_level': item_reorder_level, 'reorder_qty': item_reorder_qty, 'indent': 1 } report_data.update(item_map[item]) report_data.update(qty_dict) if include_uom: conversion_factors.setdefault(item, item_map[item].conversion_factor) if filters.get('show_stock_ageing_data'): fifo_queue = item_wise_fifo_queue[(item, warehouse)].get('fifo_queue') stock_ageing_data = { 'average_age': 0, 'earliest_age': 0, 'latest_age': 0 } if fifo_queue: fifo_queue = sorted(filter(_func, fifo_queue), key=_func) if not fifo_queue: continue stock_ageing_data['average_age'] = get_average_age(fifo_queue, to_date) stock_ageing_data['earliest_age'] = date_diff(to_date, fifo_queue[0][1]) stock_ageing_data['latest_age'] = date_diff(to_date, fifo_queue[-1][1]) report_data.update(stock_ageing_data) data.append(report_data) add_additional_uom_columns(columns, data, include_uom, conversion_factors) sc_val_cur = '' sc_val = 0 for d in data: status = 'Ideal Quantity' if d['indent'] != 0: if int(d['bal_qty']) <= int(d['reorder_level']): status = 'Low Quantity' frozen = frappe.get_value('Item',d['item_code'],'disabled') if frozen: status = 'Frozen Item' if filters.get("currency"): default_currency = d['bal_val_cur'] selected_currency = filters.currency exchange_rate = frappe.get_value('Currency Exchange',{'from_currency':default_currency,'to_currency':selected_currency},['exchange_rate']) if filters.get('currency') == default_currency: exchange_rate = 1 sc_val_cur = frappe.db.get_value('Currency',selected_currency,['name']) sc_val = d['bal_val'] * flt(exchange_rate) # if no stock ledger entry found return converted_value = { 'sc_currency': sc_val_cur, 'sc_value' : sc_val, 'status': status } d.update(converted_value) data = sorted(data, key=lambda x: x['item_code']) from collections import defaultdict tmp = defaultdict(list) for item in data: if item['indent'] != 0: tmp[item['item_code']].append([item['warehouse'],item['bal_qty']]) parsed_data = [{'item_code':k, 'warehouse':v[0][0], 'indent':1} for k,v in tmp.items()] # frappe.errprint(parsed_data) return columns,data
def get_state(state): for s in self.states: if s.state==state: return s frappe.throw(frappe._("{0} not a valid State").format(state))
def get_data(): return [ { "label": _("Documents"), "icon": "icon-star", "items": [ { "type": "doctype", "name": "Supplier", "description": _("Supplier database."), }, { "type": "doctype", "name": "Material Request", "description": _("Request for purchase."), }, { "type": "doctype", "name": "Request For Quote", "description": _("Request For Quote."), }, { "type": "doctype", "name": "Supplier Quotation", "description": _("Quotations received from Suppliers."), }, { "type": "doctype", "name": "Purchase Order", "description": _("Purchase Orders given to Suppliers."), }, { "type": "doctype", "name": "Contact", "description": _("All Contacts."), }, { "type": "doctype", "name": "Address", "description": _("All Addresses."), }, { "type": "doctype", "name": "Item", "description": _("All Products or Services."), }, ] }, { "label": _("Setup"), "icon": "icon-cog", "items": [ { "type": "doctype", "name": "Buying Settings", "description": _("Default settings for buying transactions.") }, { "type": "doctype", "name": "Supplier Type", "description": _("Supplier Type master.") }, { "type": "page", "name": "Sales Browser", "icon": "icon-sitemap", "label": _("Item Group Tree"), "link": "Sales Browser/Item Group", "description": _("Tree of Item Groups."), "doctype": "Item Group", }, { "type": "doctype", "name": "Terms and Conditions", "label": _("Terms and Conditions Template"), "description": _("Template of terms or contract.") }, { "type": "doctype", "name": "Purchase Taxes and Charges Template", "description": _("Tax template for buying transactions.") }, { "type": "doctype", "name": "Price List", "description": _("Price List master.") }, { "type": "doctype", "name": "Item Price", "description": _("Multiple Item prices."), "route": "Report/Item Price" }, { "type": "doctype", "name": "Pricing Rule", "description": _("Rules for applying pricing and discount.") }, ] }, { "label": _("Main Reports"), "icon": "icon-table", "items": [ { "type": "page", "name": "purchase-analytics", "label": _("Purchase Analytics"), "icon": "icon-bar-chart", }, ] }, { "label": _("Standard Reports"), "icon": "icon-list", "items": [{ "type": "report", "is_query_report": True, "name": "Items To Be Requested", "doctype": "Item" }, { "type": "report", "is_query_report": True, "name": "Requested Items To Be Ordered", "doctype": "Material Request" }, { "type": "report", "is_query_report": True, "name": "Material Requests for which Supplier Quotations are not created", "doctype": "Material Request" }, { "type": "report", "is_query_report": True, "name": "Item-wise Purchase History", "doctype": "Item" }, { "type": "report", "is_query_report": True, "name": "Purchase Order Trends", "doctype": "Purchase Order" }, { "type": "report", "is_query_report": True, "name": "Supplier Addresses and Contacts", "doctype": "Supplier" }, { "type": "report", "is_query_report": True, "name": "Supplier-Wise Sales Analytics", "doctype": "Stock Ledger Entry" }] }, { "label": _("Help"), "items": [ { "type": "help", "label": _("Customer and Supplier"), "youtube_id": "anoGi_RpQ20" }, { "type": "help", "label": _("Material Request to Purchase Order"), "youtube_id": "4TN9kPyfIqM" }, { "type": "help", "label": _("Purchase Order to Payment"), "youtube_id": "EK65tLdVUDk" }, { "type": "help", "label": _("Managing Subcontracting"), "youtube_id": "ThiMCC2DtKo" }, ] }, ]
def get_columns(): return [ _("Item") + ":Link/Item:120", _("Item Name") + ":Data:120", _("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100", _("Description") + "::160", _("Safety Stock") + ":Float:160", _("Lead Time Days") + ":Float:120", _("Consumed") + ":Float:120", _("Delivered") + ":Float:120", _("Total Outgoing") + ":Float:120", _("Avg Daily Outgoing") + ":Float:160", _("Reorder Level") + ":Float:120" ]
def get_columns(): """return columns""" columns = [ _("SREQ No") + ":Link/Stock Requisition:100", _("Project") + ":Link/Project:100", _("SREQ Item") + ":Link/Item:100", _("SREQ Quantity") + "::100", _("SREQ UOM") + "::140", _("Stock UOM") + "::100", _("SREQ Quantity in Stock UOM") + "::150", _("Quantity Available in Source Warehouse (Stock UOM)") + "::150", _("Excess to be Ordered") + "::90", _("PO UOM") + "::100", _("Conversion Factor") + "::", _("Qty in PO UOM") + "::100", _("Default Supplier") + "::140", _("Last Purchase Price (Stock UOM)") + "::100", _("Number of Purchase Transactions") + "::150", _("Highest Price of Last 10 Purchase Transactions (Stock UOM)") + "::90", _("Lowest Price of Last 10 Purchase Transactions (Stock UOM)") + "::100", _("Average of Last 10 Purchase Transactions") + "::150" ] return columns
def get_list_context(context): context.title = _("Bill of Materials")
def get_context(self, context): context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
def validate_bom_currecny(self, item): if item.get('bom_no') and frappe.db.get_value('BOM', item.get('bom_no'), 'currency') != self.currency: frappe.throw(_("Row {0}: Currency of the BOM #{1} should be equal to the selected currency {2}").format(item.idx, item.bom_no, self.currency))
def validate_currency(self): if self.rm_cost_as_per == 'Price List' and \ frappe.db.get_value('Price List', self.buying_price_list, 'currency') != self.currency: frappe.throw(_("Currency of the price list {0} is not similar with the selected currency {1}").format(self.buying_price_list, self.currency))
def get_data(): return [ { "label": _("Employee"), "items": [ { "type": "doctype", "name": "Employee", "onboard": 1, }, { "type": "doctype", "name": "Employment Type", }, { "type": "doctype", "name": "Branch", }, { "type": "doctype", "name": "Department", }, { "type": "doctype", "name": "Designation", }, { "type": "doctype", "name": "Employee Grade", }, { "type": "doctype", "name": "Employee Group", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Health Insurance" }, ] }, { "label": _("Attendance"), "items": [ { "type": "doctype", "name": "Employee Attendance Tool", "hide_count": True, "onboard": 1, "dependencies": ["Employee"] }, { "type": "doctype", "name": "Attendance", "onboard": 1, "dependencies": ["Employee"] }, { "type": "doctype", "name": "Attendance Request", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Upload Attendance", "hide_count": True, "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Checkin", "hide_count": True, "dependencies": ["Employee"] }, { "type": "report", "is_query_report": True, "name": "Monthly Attendance Sheet", "doctype": "Attendance" }, ] }, { "label": _("Leaves"), "items": [ { "type": "doctype", "name": "Leave Application", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Leave Allocation", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Leave Policy", "dependencies": ["Leave Type"] }, { "type": "doctype", "name": "Leave Period", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Leave Type", }, { "type": "doctype", "name": "Holiday List", }, { "type": "doctype", "name": "Compensatory Leave Request", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Leave Encashment", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Leave Block List", }, { "type": "report", "is_query_report": True, "name": "Employee Leave Balance", "doctype": "Leave Application" }, { "type": "report", "is_query_report": True, "name": "Leave Ledger Entry", "doctype": "Leave Ledger Entry" }, ] }, { "label": _("Payroll"), "items": [ { "type": "doctype", "name": "Salary Structure", "onboard": 1, }, { "type": "doctype", "name": "Salary Structure Assignment", "onboard": 1, "dependencies": ["Salary Structure", "Employee"], }, { "type": "doctype", "name": "Payroll Entry", "onboard": 1, }, { "type": "doctype", "name": "Salary Slip", "onboard": 1, }, { "type": "doctype", "name": "Payroll Period", }, { "type": "doctype", "name": "Salary Component", }, { "type": "doctype", "name": "Additional Salary", }, { "type": "doctype", "name": "Retention Bonus", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Incentive", "dependencies": ["Employee"] }, { "type": "report", "is_query_report": True, "name": "Salary Register", "doctype": "Salary Slip" }, ] }, { "label": _("Employee Tax and Benefits"), "items": [ { "type": "doctype", "name": "Employee Tax Exemption Declaration", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Tax Exemption Proof Submission", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Benefit Application", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Benefit Claim", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Tax Exemption Category", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Tax Exemption Sub Category", "dependencies": ["Employee"] }, ] }, { "label": _("Employee Lifecycle"), "items": [ { "type": "doctype", "name": "Employee Onboarding", "dependencies": ["Job Applicant"], }, { "type": "doctype", "name": "Employee Skill Map", "dependencies": ["Employee"], }, { "type": "doctype", "name": "Employee Promotion", "dependencies": ["Employee"], }, { "type": "doctype", "name": "Employee Transfer", "dependencies": ["Employee"], }, { "type": "doctype", "name": "Employee Separation", "dependencies": ["Employee"], }, { "type": "doctype", "name": "Employee Onboarding Template", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Separation Template", "dependencies": ["Employee"] }, ] }, { "label": _("Recruitment"), "items": [ { "type": "doctype", "name": "Job Opening", "onboard": 1, }, { "type": "doctype", "name": "Job Applicant", "onboard": 1, }, { "type": "doctype", "name": "Job Offer", "onboard": 1, }, { "type": "doctype", "name": "Staffing Plan", }, ] }, { "label": _("Training"), "items": [ { "type": "doctype", "name": "Training Program" }, { "type": "doctype", "name": "Training Event" }, { "type": "doctype", "name": "Training Result" }, { "type": "doctype", "name": "Training Feedback" }, ] }, { "label": _("Performance"), "items": [ { "type": "doctype", "name": "Appraisal", }, { "type": "doctype", "name": "Appraisal Template", }, { "type": "doctype", "name": "Energy Point Rule", }, { "type": "doctype", "name": "Energy Point Log", }, { "type": "link", "doctype": "Energy Point Log", "label": _("Energy Point Leaderboard"), "route": "#social/users" }, ] }, { "label": _("Expense Claims"), "items": [ { "type": "doctype", "name": "Expense Claim", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Employee Advance", "dependencies": ["Employee"] }, ] }, { "label": _("Loans"), "items": [ { "type": "doctype", "name": "Loan Application", "dependencies": ["Employee"] }, { "type": "doctype", "name": "Loan" }, { "type": "doctype", "name": "Loan Type", }, ] }, { "label": _("Shift Management"), "items": [ { "type": "doctype", "name": "Shift Type", }, { "type": "doctype", "name": "Shift Request", }, { "type": "doctype", "name": "Shift Assignment", }, ] }, { "label": _("Fleet Management"), "items": [ { "type": "doctype", "name": "Vehicle" }, { "type": "doctype", "name": "Vehicle Log" }, { "type": "report", "is_query_report": True, "name": "Vehicle Expenses", "doctype": "Vehicle" }, ] }, { "label": _("Settings"), "icon": "fa fa-cog", "items": [ { "type": "doctype", "name": "HR Settings", }, { "type": "doctype", "name": "Daily Work Summary Group" }, { "type": "page", "name": "team-updates", "label": _("Team Updates") }, ] }, { "label": _("Reports"), "icon": "fa fa-list", "items": [ { "type": "report", "is_query_report": True, "name": "Employee Birthday", "doctype": "Employee" }, { "type": "report", "is_query_report": True, "name": "Employees working on a holiday", "doctype": "Employee" }, { "type": "report", "is_query_report": True, "name": "Department Analytics", "doctype": "Employee" }, ] }, ]
def get_single_value(doctype, field): if not frappe.has_permission(doctype): frappe.throw(_("No permission for {doctype}".format(doctype=doctype)), frappe.PermissionError) value = frappe.db.get_single_value(doctype, field) return value
def validate_cancellation(self): if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"): frappe.throw( _("Asset cannot be cancelled, as it is already {0}").format( self.status))
def validate_in_use_date(self): if not self.available_for_use_date: frappe.throw(_("Available for use date is required"))
def make_payment_request(**args): """Make payment request""" args = frappe._dict(args) ref_doc = frappe.get_doc(args.dt, args.dn) grand_total = get_amount(ref_doc) if args.loyalty_points and args.dt == "Sales Order": from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points loyalty_amount = validate_loyalty_points(ref_doc, int(args.loyalty_points)) frappe.db.set_value("Sales Order", args.dn, "loyalty_points", int(args.loyalty_points), update_modified=False) frappe.db.set_value("Sales Order", args.dn, "loyalty_amount", loyalty_amount, update_modified=False) grand_total = grand_total - loyalty_amount gateway_account = get_gateway_details(args) or frappe._dict() bank_account = (get_party_bank_account(args.get('party_type'), args.get('party')) if args.get('party_type') else '') existing_payment_request = None if args.order_type == "Shopping Cart": existing_payment_request = frappe.db.get_value("Payment Request", {"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ("!=", 2)}) if existing_payment_request: frappe.db.set_value("Payment Request", existing_payment_request, "grand_total", grand_total, update_modified=False) pr = frappe.get_doc("Payment Request", existing_payment_request) else: if args.order_type != "Shopping Cart": existing_payment_request_amount = \ get_existing_payment_request_amount(args.dt, args.dn) if existing_payment_request_amount: grand_total -= existing_payment_request_amount pr = frappe.new_doc("Payment Request") pr.update({ "payment_gateway_account": gateway_account.get("name"), "payment_gateway": gateway_account.get("payment_gateway"), "payment_account": gateway_account.get("payment_account"), "payment_request_type": args.get("payment_request_type"), "currency": ref_doc.currency, "grand_total": grand_total, "email_to": args.recipient_id or "", "subject": _("Payment Request for {0}").format(args.dn), "message": gateway_account.get("message") or get_dummy_message(ref_doc), "reference_doctype": args.dt, "reference_name": args.dn, "party_type": args.get("party_type"), "party": args.get("party"), "bank_account": bank_account }) if args.order_type == "Shopping Cart" or args.mute_email: pr.flags.mute_email = True if args.submit_doc: pr.insert(ignore_permissions=True) pr.submit() if args.order_type == "Shopping Cart": frappe.db.commit() frappe.local.response["type"] = "redirect" frappe.local.response["location"] = pr.get_payment_url() if args.return_doc: return pr return pr.as_dict()
def validate_currency(self): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if self.payment_account and ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"): frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
def validate_filters(filters): if not (filters.get("item_code") or filters.get("warehouse")): sle_count = flt(frappe.db.sql("""select count(name) from `tabStock Ledger Entry`""")[0][0]) if sle_count > 500000: frappe.throw(_("Please set filter based on Item or Warehouse due to a large amount of entries."))
def validate_reference_document(self): if not self.reference_doctype or not self.reference_name: frappe.throw(_("To create a Payment Request reference document is required"))
def validate_employee_role(doc, method): # called via User hook if "Employee" in [d.role for d in doc.get("roles")]: if not frappe.db.get_value("Employee", {"user_id": doc.name}): frappe.msgprint(_("Please set User ID field in an Employee record to set Employee Role")) doc.get("roles").remove(doc.get("roles", {"role": "Employee"})[0])
def set_title(self): self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
def validate_returned_items(doc): from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos valid_items = frappe._dict() select_fields = "item_code, qty, stock_qty, rate, parenttype, conversion_factor" if doc.doctype != 'Purchase Invoice': select_fields += ",serial_no, batch_no" if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']: select_fields += ",rejected_qty, received_qty" for d in frappe.db.sql("""select {0} from `tab{1} Item` where parent = %s""" .format(select_fields, doc.doctype), doc.return_against, as_dict=1): valid_items = get_ref_item_dict(valid_items, d) if doc.doctype in ("Delivery Note", "Sales Invoice"): for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item` where parent = %s""".format(doc.doctype), doc.return_against, as_dict=1): valid_items = get_ref_item_dict(valid_items, d) already_returned_items = get_already_returned_items(doc) # ( not mandatory when it is Purchase Invoice or a Sales Invoice without Update Stock ) warehouse_mandatory = not ((doc.doctype=="Purchase Invoice" or doc.doctype=="Sales Invoice") and not doc.update_stock) items_returned = False for d in doc.get("items"): if flt(d.qty) < 0 or d.get('received_qty') < 0: if d.item_code not in valid_items: frappe.throw(_("Row # {0}: Returned Item {1} does not exists in {2} {3}") .format(d.idx, d.item_code, doc.doctype, doc.return_against)) else: ref = valid_items.get(d.item_code, frappe._dict()) validate_quantity(doc, d, ref, valid_items, already_returned_items) if ref.rate and doc.doctype in ("Delivery Note", "Sales Invoice") and flt(d.rate) > ref.rate: frappe.throw(_("Row # {0}: Rate cannot be greater than the rate used in {1} {2}") .format(d.idx, doc.doctype, doc.return_against)) elif ref.batch_no and d.batch_no not in ref.batch_no: frappe.throw(_("Row # {0}: Batch No must be same as {1} {2}") .format(d.idx, doc.doctype, doc.return_against)) elif ref.serial_no: if not d.serial_no: frappe.throw(_("Row # {0}: Serial No is mandatory").format(d.idx)) else: serial_nos = get_serial_nos(d.serial_no) for s in serial_nos: if s not in ref.serial_no: frappe.throw(_("Row # {0}: Serial No {1} does not match with {2} {3}") .format(d.idx, s, doc.doctype, doc.return_against)) if warehouse_mandatory and frappe.db.get_value("Item", d.item_code, "is_stock_item") \ and not d.get("warehouse"): frappe.throw(_("Warehouse is mandatory")) items_returned = True if not items_returned: frappe.throw(_("Atleast one item should be entered with negative quantity in return document"))
def get_data(): return [ { "label": _("Web Site"), "items": [ { "type": "doctype", "name": "Web Page", "description": _("Content web page."), "onboard": 1, }, { "type": "doctype", "name": "Web Form", "description": _("User editable form on Website."), "onboard": 1, }, { "type": "doctype", "name": "Website Sidebar", }, { "type": "doctype", "name": "Website Slideshow", "description": _("Embed image slideshows in website pages."), }, { "type": "doctype", "name": "Website Route Meta", "description": _("Add meta tags to your web pages"), }, ] }, { "label": _("Blog"), "items": [ { "type": "doctype", "name": "Blog Post", "description": _("Single Post (article)."), "onboard": 1, }, { "type": "doctype", "name": "Blog Settings", "description": _("Write titles and introductions to your blog."), }, { "type": "doctype", "name": "Blog Category", "description": _("Categorize blog posts."), }, ] }, { "label": _("Setup"), "items": [ { "type": "doctype", "name": "Website Settings", "description": _("Setup of top navigation bar, footer and logo."), "onboard": 1, }, { "type": "doctype", "name": "Website Theme", "description": _("List of themes for Website."), "onboard": 1, }, { "type": "doctype", "name": "Website Script", "description": _("Javascript to append to the head section of the page."), "onboard": 1, }, { "type": "doctype", "name": "About Us Settings", "description": _("Settings for About Us Page."), }, { "type": "doctype", "name": "Contact Us Settings", "description": _("Settings for Contact Us Page."), }, ] }, { "label": _("Portal"), "items": [{ "type": "doctype", "name": "Portal Settings", "label": _("Portal Settings"), "onboard": 1, }] }, { "label": _("Knowledge Base"), "items": [ { "type": "doctype", "name": "Help Category", }, { "type": "doctype", "name": "Help Article", }, ] }, ]
def check_duplicate_fiscal_year(doc): year_start_end_dates = frappe.db.sql("""select name, year_start_date, year_end_date from `tabFiscal Year` where name!=%s""", (doc.name)) for fiscal_year, ysd, yed in year_start_end_dates: if (getdate(doc.year_start_date) == ysd and getdate(doc.year_end_date) == yed) and (not frappe.flags.in_test): frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}").format(fiscal_year))
def validate_valid_till(self): if self.valid_till and getdate(self.valid_till) < getdate(self.transaction_date): frappe.throw(_("Valid till date cannot be before transaction date"))
def validate_preferred_email(self): if self.prefered_contact_email and not self.get(scrub(self.prefered_contact_email)): frappe.msgprint(_("Please enter " + self.prefered_contact_email))
return { "redirect_to": frappe.redirect_to_message( _('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account." )), "status": 401 } except InvalidRequest, e: make_log_entry(e.message, options) return { "redirect_to": frappe.redirect_to_message( _('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account." )), "status": 400 } except GatewayError, e: make_log_entry(e.message, options) return { "redirect_to": frappe.redirect_to_message( _('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account." )), "status":
def validate_reports_to(self): if self.reports_to == self.name: throw(_("Employee cannot report to himself."))
def on_trash(self): global_defaults = frappe.get_doc("Global Defaults") if global_defaults.current_fiscal_year == self.name: frappe.throw(_("You cannot delete Fiscal Year {0}. Fiscal Year {0} is set as default in Global Settings").format(self.name)) frappe.cache().delete_value("fiscal_years")