def validate_party_frozen_disabled(party_type, party_name): if party_type and party_name: if party_type in ("Customer", "Supplier"): party = dataent.get_cached_value(party_type, party_name, ["is_frozen", "disabled"], as_dict=True) if party.disabled: dataent.throw( _("{0} {1} is disabled").format(party_type, party_name), PartyDisabled) elif party.get("is_frozen"): frozen_accounts_modifier = dataent.db.get_single_value( 'Accounts Settings', 'frozen_accounts_modifier') if not frozen_accounts_modifier in dataent.get_roles(): dataent.throw( _("{0} {1} is frozen").format(party_type, party_name), PartyFrozen) elif party_type == "Employee": if dataent.db.get_value("Employee", party_name, "status") == "Left": dataent.msgprint(_("{0} {1} is not active").format( party_type, party_name), alert=True)
def upload(): # get record details dt = dataent.form_dict.doctype dn = dataent.form_dict.docname file_url = dataent.form_dict.file_url filename = dataent.form_dict.filename dataent.form_dict.is_private = cint(dataent.form_dict.is_private) if not filename and not file_url: dataent.msgprint(_("Please select a file or url"), raise_exception=True) file_doc = get_file_doc() comment = {} if dt and dn: comment = dataent.get_doc(dt, dn).add_comment("Attachment", _("added {0}").format("<a href='{file_url}' target='_blank'>{file_name}</a>{icon}".format(**{ "icon": ' <i class="fa fa-lock text-warning"></i>' \ if file_doc.is_private else "", "file_url": file_doc.file_url.replace("#", "%23") \ if file_doc.file_name else file_doc.file_url, "file_name": file_doc.file_name or file_doc.file_url }))) return { "name": file_doc.name, "file_name": file_doc.file_name, "file_url": file_doc.file_url, "is_private": file_doc.is_private, "comment": comment.as_dict() if comment else {} }
def allocate_leave(self): self.validate_values() leave_allocated_for = [] employees = self.get_employees() if not employees: dataent.throw(_("No employee found")) for d in self.get_employees(): try: la = dataent.new_doc('Leave Allocation') la.set("__islocal", 1) la.employee = cstr(d[0]) la.employee_name = dataent.db.get_value( 'Employee', cstr(d[0]), 'employee_name') la.leave_type = self.leave_type la.from_date = self.from_date la.to_date = self.to_date la.carry_forward = cint(self.carry_forward) la.new_leaves_allocated = flt(self.no_of_days) la.docstatus = 1 la.save() leave_allocated_for.append(d[0]) except: pass if leave_allocated_for: msgprint( _("Leaves Allocated Successfully for {0}").format( comma_and(leave_allocated_for)))
def after_insert(self): if self.procedure_prescription: dataent.db.set_value("Procedure Prescription", self.procedure_prescription, "appointment_booked", True) if self.procedure_template: comments = dataent.db.get_value("Procedure Prescription", self.procedure_prescription, "comments") if comments: dataent.db.set_value("Patient Appointment", self.name, "notes", comments) # Check fee validity exists appointment = self validity_exist = validity_exists(appointment.practitioner, appointment.patient) if validity_exist: fee_validity = dataent.get_doc("Fee Validity", validity_exist[0][0]) # Check if the validity is valid appointment_date = getdate(appointment.appointment_date) if (fee_validity.valid_till >= appointment_date) and (fee_validity.visited < fee_validity.max_visit): visited = fee_validity.visited + 1 dataent.db.set_value("Fee Validity", fee_validity.name, "visited", visited) if fee_validity.ref_invoice: dataent.db.set_value("Patient Appointment", appointment.name, "invoiced", True) dataent.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till)) confirm_sms(self) if dataent.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1' and \ dataent.db.get_value("Patient Appointment", self.name, "invoiced") != 1: invoice_appointment(self)
def insert_item_price(args): """Insert Item Price if Price List and Price List Rate are specified and currency is the same""" if dataent.db.get_value("Price List", args.price_list, "currency", cache=True) == args.currency \ and cint(dataent.db.get_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing")): if dataent.has_permission("Item Price", "write"): price_list_rate = (args.rate / args.get('conversion_factor') if args.get("conversion_factor") else args.rate) item_price = dataent.db.get_value('Item Price', {'item_code': args.item_code, 'price_list': args.price_list, 'currency': args.currency}, ['name', 'price_list_rate'], as_dict=1) if item_price and item_price.name: if item_price.price_list_rate != price_list_rate: dataent.db.set_value('Item Price', item_price.name, "price_list_rate", price_list_rate) dataent.msgprint(_("Item Price updated for {0} in Price List {1}").format(args.item_code, args.price_list), alert=True) else: item_price = dataent.get_doc({ "doctype": "Item Price", "price_list": args.price_list, "item_code": args.item_code, "currency": args.currency, "price_list_rate": price_list_rate }) item_price.insert() dataent.msgprint(_("Item Price added for {0} in Price List {1}").format(args.item_code, args.price_list), alert=True)
def scrap_asset(asset_name): asset = dataent.get_doc("Asset", asset_name) if asset.docstatus != 1: dataent.throw(_("Asset {0} must be submitted").format(asset.name)) elif asset.status in ("Cancelled", "Sold", "Scrapped"): dataent.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status)) depreciation_series = dataent.get_cached_value('Company', asset.company, "series_for_depreciation_entry") je = dataent.new_doc("Journal Entry") je.voucher_type = "Journal Entry" je.naming_series = depreciation_series je.posting_date = today() je.company = asset.company je.remark = "Scrap Entry for asset {0}".format(asset_name) for entry in get_gl_entries_on_asset_disposal(asset): entry.update({ "reference_type": "Asset", "reference_name": asset_name }) je.append("accounts", entry) je.flags.ignore_permissions = True je.submit() dataent.db.set_value("Asset", asset_name, "disposal_date", today()) dataent.db.set_value("Asset", asset_name, "journal_entry_for_scrap", je.name) asset.set_status("Scrapped") dataent.msgprint(_("Asset scrapped via Journal Entry {0}").format(je.name))
def show_update_popup(): cache = dataent.cache() user = dataent.session.user update_info = cache.get_value("update-info") if not update_info: return updates = json.loads(update_info) # Check if user is int the set of users to send update message to update_message = "" if cache.sismember("update-user-set", user): for update_type in updates: release_links = "" for app in updates[update_type]: app = dataent._dict(app) release_links += "<a href='https://github.com/{org_name}/{app_name}/releases/tag/v{available_version}'><b>{title}</b>: v{available_version}</a><br>".format( available_version=app.available_version, org_name=app.org_name, app_name=app.app_name, title=app.title) if release_links: update_message += _( "New {} releases for the following apps are available". format(update_type)) + ":<br><br>{}<hr>".format( release_links) if update_message: dataent.msgprint(update_message, title=_("New updates are available"), indicator='green') cache.srem("update-user-set", user)
def execute(filters=None): if not filters: filters = {} communication_list = get_communication_details(filters) columns = get_columns() if not communication_list: msgprint(_("No record found")) return columns, communication_list data = [] for communication in communication_list: row = [communication.get('customer'), communication.get('interactions'),\ communication.get('duration'), communication.get('support_tickets')] data.append(row) # add the average row total_interactions = 0 total_duration = 0 total_tickets = 0 for row in data: total_interactions += row[1] total_duration += row[2] total_tickets += row[3] data.append(['Average', total_interactions/len(data), total_duration/len(data), total_tickets/len(data)]) return columns, data
def save_customization(self): if not self.doc_type: return self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False self.set_property_setters() self.update_custom_fields() self.set_name_translation() validate_fields_for_doctype(self.doc_type) if self.flags.update_db: from dataent.model.db_schema import updatedb updatedb(self.doc_type) if not hasattr(self, 'hide_success') or not self.hide_success: dataent.msgprint(_("{0} updated").format(_(self.doc_type))) dataent.clear_cache(doctype=self.doc_type) self.fetch_to_customize() if self.flags.rebuild_doctype_for_global_search: dataent.enqueue('dataent.utils.global_search.rebuild_for_doctype', now=True, doctype=self.doc_type)
def get_columns(filters): for fieldname in ["fiscal_year", "period", "target_on"]: if not filters.get(fieldname): label = (" ".join(fieldname.split("_"))).title() msgprint(_("Please specify") + ": " + label, raise_exception=True) columns = [ _("Territory") + ":Link/Territory:120", _("Item Group") + ":Link/Item Group:120" ] group_months = False if filters["period"] == "Monthly" else True for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]): for label in [ _("Target") + " (%s)", _("Achieved") + " (%s)", _("Variance") + " (%s)" ]: if group_months: label = label % (_(from_date.strftime("%b")) + " - " + _(to_date.strftime("%b"))) else: label = label % _(from_date.strftime("%b")) columns.append(label + ":Float:120") return columns + [ _("Total Target") + ":Float:120", _("Total Achieved") + ":Float:120", _("Total Variance") + ":Float:120" ]
def update_clearance_date(self): clearance_date_updated = False for d in self.get('payment_entries'): if d.clearance_date: if not d.payment_document: dataent.throw( _("Row #{0}: Payment document is required to complete the trasaction" )) if d.cheque_date and getdate(d.clearance_date) < getdate( d.cheque_date): dataent.throw( _("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}" ).format(d.idx, d.clearance_date, d.cheque_date)) if d.clearance_date or self.include_reconciled_entries: if not d.clearance_date: d.clearance_date = None dataent.db.set_value(d.payment_document, d.payment_entry, "clearance_date", d.clearance_date) dataent.db.sql( """update `tab{0}` set clearance_date = %s, modified = %s where name=%s""".format(d.payment_document), (d.clearance_date, nowdate(), d.payment_entry)) clearance_date_updated = True if clearance_date_updated: self.get_payment_entries() msgprint(_("Clearance Date updated")) else: msgprint(_("Clearance Date not mentioned"))
def create_supplier_quotation(doc): if isinstance(doc, string_types): doc = json.loads(doc) try: sq_doc = dataent.get_doc({ "doctype": "Supplier Quotation", "supplier": doc.get('supplier'), "terms": doc.get("terms"), "company": doc.get("company"), "currency": doc.get('currency') or get_party_account_currency( 'Supplier', doc.get('supplier'), doc.get('company')), "buying_price_list": doc.get('buying_price_list') or dataent.db.get_value( 'Buying Settings', None, 'buying_price_list') }) add_items(sq_doc, doc.get('supplier'), doc.get('items')) sq_doc.flags.ignore_permissions = True sq_doc.run_method("set_missing_values") sq_doc.save() dataent.msgprint( _("Supplier Quotation {0} created").format(sq_doc.name)) return sq_doc.name except Exception: return None
def notify_employee(self): employee = dataent.get_doc("Employee", self.employee) if not employee.user_id: return parent_doc = dataent.get_doc('Leave Application', self.name) args = parent_doc.as_dict() template = dataent.db.get_single_value( 'HR Settings', 'leave_status_notification_template') if not template: dataent.msgprint( _("Please set default template for Leave Status Notification in HR Settings." )) return email_template = dataent.get_doc("Email Template", template) message = dataent.render_template(email_template.response, args) self.notify({ # for post in messages "message": message, "message_to": employee.user_id, # for email "subject": email_template.subject, "notify": "employee" })
def validate_balance_leaves(self): if self.from_date and self.to_date: self.total_leave_days = get_number_of_leave_days( self.employee, self.leave_type, self.from_date, self.to_date, self.half_day, self.half_day_date) if self.total_leave_days <= 0: dataent.throw( _("The day(s) on which you are applying for leave are holidays. You need not apply for leave." )) if not is_lwp(self.leave_type): self.leave_balance = get_leave_balance_on( self.employee, self.leave_type, self.from_date, docname=self.name, consider_all_leaves_in_the_allocation_period=True) if self.status != "Rejected" and self.leave_balance < self.total_leave_days: if dataent.db.get_value("Leave Type", self.leave_type, "allow_negative"): dataent.msgprint( _("Note: There is not enough leave balance for Leave Type {0}" ).format(self.leave_type)) else: dataent.throw( _("There is not enough leave balance for Leave Type {0}" ).format(self.leave_type))
def validate(self): for key in [ "item_naming_by", "item_group", "stock_uom", "allow_negative_stock", "default_warehouse", "set_qty_in_transactions_based_on_serial_no_input" ]: dataent.db.set_default(key, self.get(key, "")) from epaas.setup.doctype.naming_series.naming_series import set_by_naming_series set_by_naming_series("Item", "item_code", self.get("item_naming_by") == "Naming Series", hide_name_field=True) stock_frozen_limit = 356 submitted_stock_frozen = self.stock_frozen_upto_days or 0 if submitted_stock_frozen > stock_frozen_limit: self.stock_frozen_upto_days = stock_frozen_limit dataent.msgprint( _("`Freeze Stocks Older Than` should be smaller than %d days.") % stock_frozen_limit) # show/hide barcode field for name in ["barcode", "barcodes", "scan_barcode"]: dataent.make_property_setter({ 'fieldname': name, 'property': 'hidden', 'value': 0 if self.show_barcode_field else 1 }) self.cant_change_valuation_method() self.validate_clean_description_html()
def fetch_to_customize(self): self.clear_existing_doc() if not self.doc_type: return meta = dataent.get_meta(self.doc_type) if self.doc_type in core_doctypes_list: return dataent.msgprint(_("Core DocTypes cannot be customized.")) if meta.issingle: return dataent.msgprint(_("Single DocTypes cannot be customized.")) if meta.custom: return dataent.msgprint( _("Only standard DocTypes are allowed to be customized from Customize Form." )) # doctype properties for property in doctype_properties: self.set(property, meta.get(property)) for d in meta.get("fields"): new_d = { "fieldname": d.fieldname, "is_custom_field": d.get("is_custom_field"), "name": d.name } for property in docfield_properties: new_d[property] = d.get(property) self.append("fields", new_d) # load custom translation translation = self.get_name_translation() self.label = translation.target_name if translation else ''
def create_custom_field_for_workflow_state(self): dataent.clear_cache(doctype=self.document_type) meta = dataent.get_meta(self.document_type) if not meta.get_field(self.workflow_state_field): # create custom field dataent.get_doc({ "doctype": "Custom Field", "dt": self.document_type, "__islocal": 1, "fieldname": self.workflow_state_field, "label": self.workflow_state_field.replace("_", " ").title(), "hidden": 1, "allow_on_submit": 1, "no_copy": 1, "fieldtype": "Link", "options": "Workflow State", "owner": "Administrator" }).save() dataent.msgprint( _("Created Custom Field {0} in {1}").format( self.workflow_state_field, self.document_type))
def make_material_request(self): '''Create Material Requests grouped by Sales Order and Material Request Type''' material_request_list = [] material_request_map = {} for item in self.mr_items: item_doc = dataent.get_cached_doc('Item', item.item_code) # key for Sales Order:Material Request Type key = '{}:{}'.format(item.sales_order, item_doc.default_material_request_type) schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days)) if not key in material_request_map: # make a new MR for the combination material_request_map[key] = dataent.new_doc("Material Request") material_request = material_request_map[key] material_request.update({ "transaction_date": nowdate(), "status": "Draft", "company": self.company, "requested_by": dataent.session.user, 'material_request_type': item_doc.default_material_request_type }) material_request_list.append(material_request) else: material_request = material_request_map[key] # add item material_request.append("items", { "item_code": item.item_code, "qty": item.quantity, "schedule_date": schedule_date, "warehouse": item.warehouse, "sales_order": item.sales_order, 'production_plan': self.name, 'material_request_plan_item': item.name, "project": dataent.db.get_value("Sales Order", item.sales_order, "project") \ if item.sales_order else None }) for material_request in material_request_list: # submit material_request.flags.ignore_permissions = 1 material_request.run_method("set_missing_values") material_request.submit() dataent.flags.mute_messages = False if material_request_list: material_request_list = ["""<a href="#Form/Material Request/{0}">{1}</a>""".format(m.name, m.name) \ for m in material_request_list] msgprint(_("{0} created").format(comma_and(material_request_list))) else: msgprint(_("No material request created"))
def create_new_connection(module, connection_name): if not dataent.conf.get('developer_mode'): dataent.msgprint(_('Please enable developer mode to create new connection')) return # create folder module_path = dataent.get_module_path(module) connectors_folder = os.path.join(module_path, 'connectors') dataent.create_folder(connectors_folder) # create init py create_init_py(module_path, 'connectors', '') connection_class = connection_name.replace(' ', '') file_name = dataent.scrub(connection_name) + '.py' file_path = os.path.join(module_path, 'connectors', file_name) # create boilerplate file with open(file_path, 'w') as f: f.write(connection_boilerplate.format(connection_class=connection_class)) # get python module string from file_path app_name = dataent.db.get_value('Module Def', module, 'app_name') python_module = os.path.relpath( file_path, '../apps/{0}'.format(app_name)).replace(os.path.sep, '.')[:-3] return python_module
def check_sal_struct(self, joining_date, relieving_date): cond = """and sa.employee=%(employee)s and (sa.from_date <= %(start_date)s or sa.from_date <= %(end_date)s or sa.from_date <= %(joining_date)s)""" if self.payroll_frequency: cond += """and ss.payroll_frequency = '%(payroll_frequency)s'""" % { "payroll_frequency": self.payroll_frequency } st_name = dataent.db.sql( """ select sa.salary_structure from `tabSalary Structure Assignment` sa join `tabSalary Structure` ss where sa.salary_structure=ss.name and sa.docstatus = 1 and ss.docstatus = 1 and ss.is_active ='Yes' %s order by sa.from_date desc limit 1 """ % cond, { 'employee': self.employee, 'start_date': self.start_date, 'end_date': self.end_date, 'joining_date': joining_date }) if st_name: self.salary_structure = st_name[0][0] return self.salary_structure else: self.salary_structure = None dataent.msgprint(_( "No active or default Salary Structure found for employee {0} for the given dates" ).format(self.employee), title=_('Salary Structure Missing'))
def appointment_cancel(appointment_id): appointment = dataent.get_doc("Patient Appointment", appointment_id) # If invoiced --> fee_validity update with -1 visit if appointment.invoiced: sales_invoice = exists_sales_invoice(appointment) if sales_invoice and cancel_sales_invoice(sales_invoice): dataent.msgprint( _("Appointment {0} and Sales Invoice {1} cancelled".format(appointment.name, sales_invoice.name)) ) else: validity = validity_exists(appointment.practitioner, appointment.patient) if validity: fee_validity = dataent.get_doc("Fee Validity", validity[0][0]) if appointment_valid_in_fee_validity(appointment, fee_validity.valid_till, True, fee_validity.ref_invoice): visited = fee_validity.visited - 1 dataent.db.set_value("Fee Validity", fee_validity.name, "visited", visited) dataent.msgprint( _("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice)) ) else: dataent.msgprint(_("Appointment cancelled")) else: dataent.msgprint(_("Appointment cancelled")) else: dataent.msgprint(_("Appointment cancelled"))
def validate(self): self.status = self.get_status() self.validate_dates() self.check_existing() if not self.salary_slip_based_on_timesheet: self.get_date_details() if not (len(self.get("earnings")) or len(self.get("deductions"))): # get details from salary structure self.get_emp_and_leave_details() else: self.get_leave_details(lwp=self.leave_without_pay) self.calculate_net_pay() company_currency = epaas.get_company_currency(self.company) self.total_in_words = money_in_words(self.rounded_total, company_currency) if dataent.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"): max_working_hours = dataent.db.get_single_value( "HR Settings", "max_working_hours_against_timesheet") if self.salary_slip_based_on_timesheet and ( self.total_working_hours > int(max_working_hours)): dataent.msgprint(_( "Total working hours should not be greater than max working hours {0}" ).format(max_working_hours), alert=True)
def invoice_appointment(appointment_doc): if not appointment_doc.name: return False sales_invoice = dataent.new_doc("Sales Invoice") sales_invoice.customer = dataent.get_value("Patient", appointment_doc.patient, "customer") sales_invoice.appointment = appointment_doc.name sales_invoice.due_date = getdate() sales_invoice.is_pos = True sales_invoice.company = appointment_doc.company sales_invoice.debit_to = get_receivable_account(appointment_doc.company) item_line = sales_invoice.append("items") service_item, practitioner_charge = service_item_and_practitioner_charge(appointment_doc) item_line.item_code = service_item item_line.description = "Consulting Charges: " + appointment_doc.practitioner item_line.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company) item_line.rate = practitioner_charge item_line.amount = practitioner_charge item_line.qty = 1 item_line.reference_dt = "Patient Appointment" item_line.reference_dn = appointment_doc.name payments_line = sales_invoice.append("payments") payments_line.mode_of_payment = appointment_doc.mode_of_payment payments_line.amount = appointment_doc.paid_amount sales_invoice.set_missing_values(for_validate = True) sales_invoice.save(ignore_permissions=True) sales_invoice.submit() dataent.msgprint(_("Sales Invoice {0} created as paid".format(sales_invoice.name)), alert=True)
def email_salary_slip(self): receiver = dataent.db.get_value("Employee", self.employee, "prefered_email") if receiver: email_args = { "recipients": [receiver], "message": _("Please see attachment"), "subject": 'Salary Slip - from {0} to {1}'.format(self.start_date, self.end_date), "attachments": [ dataent.attach_print(self.doctype, self.name, file_name=self.name) ], "reference_doctype": self.doctype, "reference_name": self.name } if not dataent.flags.in_test: enqueue(method=dataent.sendmail, queue='short', timeout=300, is_async=True, **email_args) else: dataent.sendmail(**email_args) else: msgprint( _("{0}: Employee email not found, hence email not sent"). format(self.employee_name))
def enqueue_update_cost(): dataent.enqueue( "epaas.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost" ) dataent.msgprint( _("Queued for updating latest price in all Bill of Materials. It may take a few minutes." ))
def create_tasks_for_diseases(self): for disease in self.detected_disease: if not disease.tasks_created: self.import_disease_tasks(disease.disease, disease.start_date) disease.tasks_created = True dataent.msgprint(_("Tasks have been created for managing the {0} disease (on row {1})".format(disease.disease, disease.idx)))
def make_fee_records(self): from epaas.education.api import get_fee_components fee_list = [] for d in self.fees: fee_components = get_fee_components(d.fee_structure) if fee_components: fees = dataent.new_doc("Fees") fees.update({ "student": self.student, "academic_year": self.academic_year, "academic_term": d.academic_term, "fee_structure": d.fee_structure, "program": self.program, "due_date": d.due_date, "student_name": self.student_name, "program_enrollment": self.name, "components": fee_components }) fees.save() fees.submit() fee_list.append(fees.name) if fee_list: fee_list = ["""<a href="#Form/Fees/%s" target="_blank">%s</a>""" % \ (fee, fee) for fee in fee_list] msgprint(_("Fee Records Created - {0}").format(comma_and(fee_list)))
def validate_case_nos(self): """ Validate if case nos overlap. If they do, recommend next case no. """ if not cint(self.from_case_no): dataent.msgprint(_("Please specify a valid 'From Case No.'"), raise_exception=1) elif not self.to_case_no: self.to_case_no = self.from_case_no elif self.from_case_no > self.to_case_no: dataent.msgprint( _("'To Case No.' cannot be less than 'From Case No.'"), raise_exception=1) res = dataent.db.sql( """SELECT name FROM `tabPacking Slip` WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND ((from_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s) OR (to_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s) OR (%(from_case_no)s BETWEEN from_case_no AND to_case_no)) """, { "delivery_note": self.delivery_note, "from_case_no": self.from_case_no, "to_case_no": self.to_case_no }) if res: dataent.throw( _("""Case No(s) already in use. Try from Case No {0}"""). format(self.get_recommended_case_no()))
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0): actual_expense = amount or get_actual_expense(args) if actual_expense > budget_amount: diff = actual_expense - budget_amount currency = dataent.get_cached_value('Company', args.company, 'default_currency') msg = _( "{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}" ).format(_(action_for), dataent.bold(args.account), args.budget_against_field, dataent.bold(budget_against), dataent.bold(fmt_money(budget_amount, currency=currency)), dataent.bold(fmt_money(diff, currency=currency))) if (dataent.flags.exception_approver_role and dataent.flags.exception_approver_role in dataent.get_roles( dataent.session.user)): action = "Warn" if action == "Stop": dataent.throw(msg, BudgetError) else: dataent.msgprint(msg, indicator='orange')
def validate_due_date(posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None): if getdate(due_date) < getdate(posting_date): dataent.throw( _("Due Date cannot be before Posting / Supplier Invoice Date")) else: if not template_name: return default_due_date = get_due_date_from_template( template_name, posting_date, bill_date).strftime("%Y-%m-%d") if not default_due_date: return if default_due_date != posting_date and getdate(due_date) > getdate( default_due_date): is_credit_controller = dataent.db.get_single_value( "Accounts Settings", "credit_controller") in dataent.get_roles() if is_credit_controller: msgprint( _("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)" ).format(date_diff(due_date, default_due_date))) else: dataent.throw( _("Due / Reference Date cannot be after {0}").format( formatdate(default_due_date)))