def _calculate_taxes_and_totals(self): # validate conversion rate company_currency = get_company_currency(self.company) if not self.currency or self.currency == company_currency: self.currency = company_currency self.conversion_rate = 1.0 else: from erpnext.setup.doctype.currency.currency import validate_conversion_rate validate_conversion_rate(self.currency, self.conversion_rate, self.meta.get_label("conversion_rate"), self.company) self.conversion_rate = flt(self.conversion_rate) self.item_doclist = self.get(self.fname) self.tax_doclist = self.get(self.other_fname) self.calculate_item_values() self.initialize_taxes() if hasattr(self, "determine_exclusive_rate"): self.determine_exclusive_rate() self.calculate_net_total() self.calculate_taxes() self.calculate_totals() self._cleanup()
def get_exchange_rate(account, account_currency=None, company=None, reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None): from erpnext.setup.utils import get_exchange_rate account_details = frappe.db.get_value("Account", account, ["account_type", "root_type", "account_currency", "company"], as_dict=1) if not account_details: frappe.throw(_("Please select correct account")) if not company: company = account_details.company if not account_currency: account_currency = account_details.account_currency company_currency = get_company_currency(company) if account_currency != company_currency: if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name: exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate") elif account_details and account_details.account_type == "Bank" and \ ((account_details.root_type == "Asset" and flt(credit) > 0) or (account_details.root_type == "Liability" and debit)): exchange_rate = get_average_exchange_rate(account) if not exchange_rate and account_currency: exchange_rate = get_exchange_rate(account_currency, company_currency) else: exchange_rate = 1 # don't return None or 0 as it is multipled with a value and that value could be lost return exchange_rate or 1
def get_exchange_rate( account, account_currency, company, reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None, ): from erpnext.setup.utils import get_exchange_rate company_currency = get_company_currency(company) account_details = frappe.db.get_value("Account", account, ["account_type", "root_type"], as_dict=1) if account_currency != company_currency: if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name: exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate") elif account_details.account_type == "Bank" and ( (account_details.root_type == "Asset" and flt(credit) > 0) or (account_details.root_type == "Liability" and debit) ): exchange_rate = get_average_exchange_rate(account) if not exchange_rate: exchange_rate = get_exchange_rate(account_currency, company_currency) else: exchange_rate = 1 return exchange_rate
def validate(self): self.status = self.get_status() self.validate_dates() self.check_existing() self.set_month_dates() 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) if self.salary_slip_based_on_timesheet or not self.net_pay: self.calculate_net_pay() company_currency = get_company_currency(self.company) self.total_in_words = money_in_words(self.rounded_total, company_currency) if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"): max_working_hours = frappe.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)): frappe.msgprint(_( "Total working hours should not be greater than max working hours {0}" ).format(max_working_hours), alert=True)
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None): """Returns dict of account balance and party type to be set in Journal Entry on selection of account.""" if not frappe.has_permission("Account"): frappe.msgprint(_("No Permission"), raise_exception=1) company_currency = get_company_currency(company) account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1) if not account_details: return if account_details.account_type == "Receivable": party_type = "Customer" elif account_details.account_type == "Payable": party_type = "Supplier" else: party_type = "" grid_values = { "balance": get_balance_on(account, date), "party_type": party_type, "account_type": account_details.account_type, "account_currency": account_details.account_currency or company_currency, # The date used to retreive the exchange rate here is the date passed in # as an argument to this function. It is assumed to be the date on which the balance is sought "exchange_rate": get_exchange_rate(date, account, account_details.account_currency, company, debit=debit, credit=credit, exchange_rate=exchange_rate) } # un-set party if not party type if not party_type: grid_values["party"] = "" return grid_values
def validate(self): #frappe.errprint("in validate") from datetime import datetime from frappe.utils import money_in_words d1 = datetime.strptime(self.from_date, "%Y-%m-%d") d2 = datetime.strptime(self.to_date, "%Y-%m-%d") diff = abs((d2 - d1).days) #frappe.errprint(diff) self.check_existing() self.validate_attendance() if not (len(self.get("earning_details")) or len(self.get("deduction_details"))): self.get_emp_and_leave_details(diff) else: self.get_leave_details(diff, self.leave_without_pay) if not self.net_pay: self.calculate_net_pay() company_currency = get_company_currency(self.company) #frappe.errprint(company_currency) self.total_in_words = money_in_words(self.rounded_total, company_currency) #frappe.errprint(self.total_in_words) set_employee_name(self)
def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("currency"): company_currency = get_company_currency(self.company) # price list part fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \ else "buying_price_list" if self.meta.get_field(fieldname) and self.get(fieldname): self.price_list_currency = frappe.db.get_value("Price List", self.get(fieldname), "currency") if self.price_list_currency == company_currency: self.plc_conversion_rate = 1.0 elif not self.plc_conversion_rate: self.plc_conversion_rate = get_exchange_rate( self.price_list_currency, company_currency) # currency if not self.currency: self.currency = self.price_list_currency self.conversion_rate = self.plc_conversion_rate elif self.currency == company_currency: self.conversion_rate = 1.0 elif not self.conversion_rate: self.conversion_rate = get_exchange_rate(self.currency, company_currency)
def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("currency"): company_currency = get_company_currency(self.company) # price list part fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \ else "buying_price_list" if self.meta.get_field(fieldname) and self.get(fieldname): self.price_list_currency = frappe.db.get_value( "Price List", self.get(fieldname), "currency") if self.price_list_currency == company_currency: self.plc_conversion_rate = 1.0 elif not self.plc_conversion_rate: self.plc_conversion_rate = get_exchange_rate( self.price_list_currency, company_currency) # currency if not self.currency: self.currency = self.price_list_currency self.conversion_rate = self.plc_conversion_rate elif self.currency == company_currency: self.conversion_rate = 1.0 elif not self.conversion_rate: self.conversion_rate = get_exchange_rate( self.currency, company_currency)
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None): """Returns dict of account balance and party type to be set in Journal Entry on selection of account.""" if not frappe.has_permission("Account"): frappe.msgprint(_("No Permission"), raise_exception=1) company_currency = get_company_currency(company) account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1) if account_details.account_type == "Receivable": party_type = "Customer" elif account_details.account_type == "Payable": party_type = "Supplier" else: party_type = "" grid_values = { "balance": get_balance_on(account, date), "party_type": party_type, "account_type": account_details.account_type, "account_currency": account_details.account_currency or company_currency, "exchange_rate": get_exchange_rate(account, account_details.account_currency, company, debit=debit, credit=credit, exchange_rate=exchange_rate) } # un-set party if not party type if not party_type: grid_values["party"] = "" return grid_values
def set_total_in_words(self): from frappe.utils import money_in_words company_currency = get_company_currency(self.company) if self.meta.get_field("base_in_words"): self.base_in_words = money_in_words(self.base_grand_total, company_currency) if self.meta.get_field("in_words"): self.in_words = money_in_words(self.grand_total, self.currency)
def check_conversion_rate(self): default_currency = get_company_currency(self.company) if not default_currency: throw(_('Please enter default currency in Company Master')) if (self.currency == default_currency and flt(self.conversion_rate) != 1.00) or not self.conversion_rate or ( self.currency != default_currency and flt(self.conversion_rate) == 1.00): throw(_("Conversion rate cannot be 0 or 1"))
def validate_conversion_rate(self): # validate conversion rate company_currency = get_company_currency(self.doc.company) if not self.doc.currency or self.doc.currency == company_currency: self.doc.currency = company_currency self.doc.conversion_rate = 1.0 else: validate_conversion_rate(self.doc.currency, self.doc.conversion_rate, self.doc.meta.get_label("conversion_rate"), self.doc.company) self.doc.conversion_rate = flt(self.doc.conversion_rate)
def set_total_in_words(self): from frappe.utils import money_in_words company_currency = get_company_currency(self.company) disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total")) if self.meta.get_field("base_in_words"): self.base_in_words = money_in_words(disable_rounded_total and abs(self.base_grand_total) or abs(self.base_rounded_total), company_currency) if self.meta.get_field("in_words"): self.in_words = money_in_words(disable_rounded_total and abs(self.grand_total) or abs(self.rounded_total), self.currency)
def create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append(_("Reference #{0} dated {1}").format(self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) company_currency = get_company_currency(self.company) for d in self.get("accounts"): if d.against_invoice and d.credit: r.append( _("{0} against Sales Invoice {1}").format( fmt_money(flt(d.credit), currency=company_currency), d.against_invoice ) ) if d.against_sales_order and d.credit: r.append( _("{0} against Sales Order {1}").format( fmt_money(flt(d.credit), currency=company_currency), d.against_sales_order ) ) if d.against_voucher and d.debit: bill_no = frappe.db.sql( """select bill_no, bill_date from `tabPurchase Invoice` where name=%s""", d.against_voucher, ) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() not in ["na", "not applicable", "none"]: r.append( _("{0} against Bill {1} dated {2}").format( fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime("%Y-%m-%d")), ) ) if d.against_purchase_order and d.debit: r.append( _("{0} against Purchase Order {1}").format( fmt_money(flt(d.credit), currency=company_currency), d.against_purchase_order ) ) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) # User Remarks is not mandatory
def check_conversion_rate(self): default_currency = get_company_currency(self.doc.company) if not default_currency: msgprint( 'Message: Please enter default currency in Company Master') raise Exception if (self.doc.currency == default_currency and flt(self.doc.conversion_rate) != 1.00 ) or not self.doc.conversion_rate or ( self.doc.currency != default_currency and flt(self.doc.conversion_rate) == 1.00): msgprint("Message: Please Enter Appropriate Conversion Rate.") raise Exception
def set_total_in_words(self): from frappe.utils import money_in_words company_currency = get_company_currency(self.doc.company) disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total")) if self.meta.get_field("in_words"): self.doc.in_words = money_in_words(disable_rounded_total and self.doc.grand_total or self.doc.rounded_total, company_currency) if self.meta.get_field("in_words_export"): self.doc.in_words_export = money_in_words(disable_rounded_total and self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
def calculate_totals(self): self.doc.grand_total = flt( self.doc.get("taxes")[-1].total if self.doc.get("taxes") else self. doc.net_total) self.doc.total_taxes_and_charges = flt( self.doc.grand_total - self.doc.net_total, self.doc.precision("total_taxes_and_charges")) self._set_in_company_currency(self.doc, ["total_taxes_and_charges"]) if self.doc.doctype in [ "Quotation", "Sales Order", "Delivery Note", "Sales Invoice" ]: self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \ if self.doc.total_taxes_and_charges else self.doc.base_net_total else: self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0 for tax in self.doc.get("taxes"): if tax.category in ["Valuation and Total", "Total"]: if tax.add_deduct_tax == "Add": self.doc.taxes_and_charges_added += flt( tax.tax_amount_after_discount_amount) else: self.doc.taxes_and_charges_deducted += flt( tax.tax_amount_after_discount_amount) self.doc.round_floats_in( self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]) self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \ if (self.doc.taxes_and_charges_added or self.doc.taxes_and_charges_deducted) \ else self.doc.base_net_total self._set_in_company_currency( self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]) self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"]) if self.doc.meta.get_field("rounded_total"): self.doc.rounded_total = round_based_on_smallest_currency_fraction( self.doc.grand_total, self.doc.currency, self.doc.precision("rounded_total")) if self.doc.meta.get_field("base_rounded_total"): company_currency = get_company_currency(self.doc.company) self.doc.base_rounded_total = \ round_based_on_smallest_currency_fraction(self.doc.base_grand_total, company_currency, self.doc.precision("base_rounded_total"))
def get_outstanding(args): if not frappe.has_permission("Account"): frappe.msgprint(_("No Permission"), raise_exception=1) if isinstance(args, basestring): args = json.loads(args) company_currency = get_company_currency(args.get("company")) if args.get("doctype") == "Journal Entry": condition = " and party=%(party)s" if args.get("party") else "" against_jv_amount = frappe.db.sql( """ select sum(debit_in_account_currency) - sum(credit_in_account_currency) from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0} and (reference_type is null or reference_type = '')""".format(condition), args) against_jv_amount = flt( against_jv_amount[0][0]) if against_jv_amount else 0 amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency" return {amount_field: abs(against_jv_amount)} elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"): party_type = "Customer" if args.get( "doctype") == "Sales Invoice" else "Supplier" invoice = frappe.db.get_value( args["doctype"], args["docname"], ["outstanding_amount", "conversion_rate", scrub(party_type)], as_dict=1) exchange_rate = invoice.conversion_rate if ( args.get("account_currency") != company_currency) else 1 if args["doctype"] == "Sales Invoice": amount_field = "credit_in_account_currency" \ if flt(invoice.outstanding_amount) > 0 else "debit_in_account_currency" else: amount_field = "debit_in_account_currency" \ if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency" return { amount_field: abs(flt(invoice.outstanding_amount)), "exchange_rate": exchange_rate, "party_type": party_type, "party": invoice.get(scrub(party_type)) }
def validate(self): from frappe.utils import money_in_words self.check_existing() if not (len(self.get("earning_details")) or len(self.get("deduction_details"))): self.get_emp_and_leave_details() else: self.get_leave_details(self.leave_without_pay) if not self.net_pay: self.calculate_net_pay() company_currency = get_company_currency(self.company) self.total_in_words = money_in_words(self.rounded_total, company_currency)
def validate(self): self.check_existing() if not (len(self.get("earnings")) or len(self.get("deductions"))): self.get_emp_and_leave_details() else: self.get_leave_details(lwp = self.leave_without_pay) if not self.net_pay: self.calculate_net_pay() company_currency = get_company_currency(self.company) self.total_in_words = money_in_words(self.rounded_total, company_currency) set_employee_name(self)
def get_outstanding(args): if not frappe.has_permission("Account"): frappe.msgprint(_("No Permission"), raise_exception=1) if isinstance(args, basestring): args = json.loads(args) company_currency = get_company_currency(args.get("company")) if args.get("doctype") == "Journal Entry": condition = " and party=%(party)s" if args.get("party") else "" against_jv_amount = frappe.db.sql( """ select sum(debit_in_account_currency) - sum(credit_in_account_currency) from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0} and (reference_type is null or reference_type = '')""".format( condition ), args, ) against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency" return {amount_field: abs(against_jv_amount)} elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"): party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier" invoice = frappe.db.get_value( args["doctype"], args["docname"], ["outstanding_amount", "conversion_rate", scrub(party_type)], as_dict=1 ) exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1 if args["doctype"] == "Sales Invoice": amount_field = ( "credit_in_account_currency" if flt(invoice.outstanding_amount) > 0 else "debit_in_account_currency" ) else: amount_field = ( "debit_in_account_currency" if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency" ) return { amount_field: abs(flt(invoice.outstanding_amount)), "exchange_rate": exchange_rate, "party_type": party_type, "party": invoice.get(scrub(party_type)), }
def get_appr_user_role(self, det, doctype_name, total, based_on, condition, item, company): amt_list, appr_users, appr_roles = [], [], [] users, roles = '', '' if det: for x in det: amt_list.append(flt(x[0])) max_amount = max(amt_list) app_dtl = frappe.db.sql( "select approving_user, approving_role from `tabAuthorization Rule` where transaction = %s and (value = %s or value > %s) and docstatus != 2 and based_on = %s and company = %s %s" % ('%s', '%s', '%s', '%s', '%s', condition), (doctype_name, flt(max_amount), total, based_on, company)) if not app_dtl: app_dtl = frappe.db.sql( "select approving_user, approving_role from `tabAuthorization Rule` where transaction = %s and (value = %s or value > %s) and docstatus != 2 and based_on = %s and ifnull(company,'') = '' %s" % ('%s', '%s', '%s', '%s', condition), (doctype_name, flt(max_amount), total, based_on)) for d in app_dtl: if (d[0]): appr_users.append(d[0]) if (d[1]): appr_roles.append(d[1]) if not has_common(appr_roles, frappe.user.get_roles()) and not has_common( appr_users, [session['user']]): msg, add_msg = '', '' if max_amount: dcc = get_company_currency(self.doc.company) if based_on == 'Grand Total': msg = "since Grand Total exceeds %s. %s" % ( dcc, flt(max_amount)) elif based_on == 'Itemwise Discount': msg = "since Discount exceeds %s for Item Code : %s" % ( cstr(max_amount) + '%', item) elif based_on == 'Average Discount' or based_on == 'Customerwise Discount': msg = "since Discount exceeds %s" % (cstr(max_amount) + '%') if appr_users: add_msg = "Users : " + cstr(appr_users) if appr_roles: add_msg = "Roles : " + cstr(appr_roles) if appr_users and appr_roles: add_msg = "Users : " + cstr( appr_users) + " or " + "Roles : " + cstr(appr_roles) msgprint( "You are not authorize to submit this %s %s. Please send for approval to %s" % (doctype_name, msg, add_msg)) raise Exception
def set_print_format_fields(self): for d in self.get('entries'): account_type, master_type = frappe.db.get_value("Account", d.account, ["account_type", "master_type"]) if master_type in ['Supplier', 'Customer']: if not self.pay_to_recd_from: self.pay_to_recd_from = frappe.db.get_value(master_type, ' - '.join(d.account.split(' - ')[:-1]), master_type == 'Customer' and 'customer_name' or 'supplier_name') if account_type in ['Bank', 'Cash']: company_currency = get_company_currency(self.company) amt = flt(d.debit) and d.debit or d.credit self.total_amount = company_currency + ' ' + cstr(amt) from frappe.utils import money_in_words self.total_amount_in_words = money_in_words(amt, company_currency)
def set_total_in_words(doc, method): from frappe.utils import money_in_words company_currency = get_company_currency(doc.company) disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total")) if doc.meta.get_field("base_in_words"): doc.base_in_words = money_in_words(disable_rounded_total and abs(doc.base_grand_total) or abs(doc.base_rounded_total), company_currency) if doc.meta.get_field("in_words"): doc.in_words = money_in_words(disable_rounded_total and abs(doc.grand_total) or abs(doc.rounded_total), doc.currency) if doc.meta.get_field("amount_of_duty_in_words"): doc.amount_of_duty_in_words = money_in_words(disable_rounded_total and abs(doc.excise_amount) or abs(doc.excise_amount), doc.currency) if doc.meta.get_field("vat_in_words"): doc.vat_in_words = money_in_words(disable_rounded_total and abs(doc.vat_amount) or abs(doc.vat_amount), doc.currency)
def set_print_format_fields(self): for d in self.get('entries'): account_type, master_type = frappe.db.get_value( "Account", d.account, ["account_type", "master_type"]) if master_type in ['Supplier', 'Customer']: if not self.pay_to_recd_from: self.pay_to_recd_from = frappe.db.get_value( master_type, ' - '.join(d.account.split(' - ')[:-1]), master_type == 'Customer' and 'customer_name' or 'supplier_name') if account_type in ['Bank', 'Cash']: company_currency = get_company_currency(self.company) amt = flt(d.debit) and d.debit or d.credit self.total_amount = company_currency + ' ' + cstr(amt) from frappe.utils import money_in_words self.total_amount_in_words = money_in_words( amt, company_currency)
def create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append( _('Reference #{0} dated {1}').format( self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) company_currency = get_company_currency(self.company) for d in self.get('accounts'): if d.against_invoice and d.credit: r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.against_invoice)) if d.against_sales_order and d.credit: r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.against_sales_order)) if d.against_voucher and d.debit: bill_no = frappe.db.sql( """select bill_no, bill_date from `tabPurchase Invoice` where name=%s""", d.against_voucher) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \ not in ['na', 'not applicable', 'none']: r.append( _('{0} against Bill {1} dated {2}').format( fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0], bill_no[0][1] and formatdate( bill_no[0][1].strftime('%Y-%m-%d')))) if d.against_purchase_order and d.debit: r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.against_purchase_order)) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) #User Remarks is not mandatory
def calculate_totals(self): self.doc.grand_total = flt(self.doc.get("taxes")[-1].total if self.doc.get("taxes") else self.doc.net_total) self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total, self.doc.precision("total_taxes_and_charges")) self._set_in_company_currency(self.doc, ["total_taxes_and_charges"]) if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \ if self.doc.total_taxes_and_charges else self.doc.base_net_total else: self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0 for tax in self.doc.get("taxes"): if tax.category in ["Valuation and Total", "Total"]: if tax.add_deduct_tax == "Add": self.doc.taxes_and_charges_added += flt(tax.tax_amount_after_discount_amount) else: self.doc.taxes_and_charges_deducted += flt(tax.tax_amount_after_discount_amount) self.doc.round_floats_in(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]) self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \ if (self.doc.taxes_and_charges_added or self.doc.taxes_and_charges_deducted) \ else self.doc.base_net_total self._set_in_company_currency(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]) self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"]) if self.doc.meta.get_field("rounded_total"): self.doc.rounded_total = round_based_on_smallest_currency_fraction(self.doc.grand_total, self.doc.currency, self.doc.precision("rounded_total")) if self.doc.meta.get_field("base_rounded_total"): company_currency = get_company_currency(self.doc.company) self.doc.base_rounded_total = \ round_based_on_smallest_currency_fraction(self.doc.base_grand_total, company_currency, self.doc.precision("base_rounded_total"))
def validate(self): self.status = self.get_status() self.validate_dates() self.check_existing() 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) # if self.salary_slip_based_on_timesheet or not self.net_pay: self.calculate_net_pay() company_currency = get_company_currency(self.company) self.total_in_words = money_in_words(self.rounded_total, company_currency) if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"): max_working_hours = frappe.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)): frappe.msgprint(_("Total working hours should not be greater than max working hours {0}"). format(max_working_hours), alert=True)
def _calculate_taxes_and_totals(self): # validate conversion rate company_currency = get_company_currency(self.company) if not self.currency or self.currency == company_currency: self.currency = company_currency self.conversion_rate = 1.0 else: validate_conversion_rate(self.currency, self.conversion_rate, self.meta.get_label("conversion_rate"), self.company) self.conversion_rate = flt(self.conversion_rate) self.calculate_item_values() self.initialize_taxes() if hasattr(self, "determine_exclusive_rate"): self.determine_exclusive_rate() self.calculate_net_total() self.calculate_taxes() self.calculate_totals() self._cleanup()
def create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) company_currency = get_company_currency(self.company) for d in self.get('accounts'): if d.reference_type=="Sales Invoice" and d.credit: r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.reference_name)) if d.reference_type=="Sales Order" and d.credit: r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.reference_name)) if d.reference_type == "Purchase Invoice" and d.debit: bill_no = frappe.db.sql("""select bill_no, bill_date from `tabPurchase Invoice` where name=%s""", d.reference_name) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \ not in ['na', 'not applicable', 'none']: r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')))) if d.reference_type == "Purchase Order" and d.debit: r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \ d.reference_name)) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) #User Remarks is not mandatory
def get_outstanding(args): if not frappe.has_permission("Account"): frappe.msgprint(_("No Permission"), raise_exception=1) args = eval(args) company_currency = get_company_currency(args.get("company")) if args.get("doctype") == "Journal Entry": condition = " and party=%(party)s" if args.get("party") else "" against_jv_amount = frappe.db.sql(""" select sum(ifnull(debit_in_account_currency, 0)) - sum(ifnull(credit_in_account_currency, 0)) from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0} and ifnull(reference_type, '')=''""".format(condition), args) against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency" return { amount_field: abs(against_jv_amount) } elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"): invoice = frappe.db.get_value(args["doctype"], args["docname"], ["outstanding_amount", "conversion_rate"], as_dict=1) exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1 if args["doctype"] == "Sales Invoice": amount_field = "credit_in_account_currency" \ if flt(invoice.outstanding_amount) > 0 else "debit_in_account_currency" else: amount_field = "debit_in_account_currency" \ if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency" return { amount_field: abs(flt(invoice.outstanding_amount)), "exchange_rate": exchange_rate }
def set_print_format_fields(self): for d in self.get("entries"): result = frappe.db.get_value("Account", d.account, ["account_type", "master_type"]) if not result: continue account_type, master_type = result if master_type in ["Supplier", "Customer"]: if not self.pay_to_recd_from: self.pay_to_recd_from = frappe.db.get_value( master_type, " - ".join(d.account.split(" - ")[:-1]), master_type == "Customer" and "customer_name" or "supplier_name", ) if account_type in ["Bank", "Cash"]: company_currency = get_company_currency(self.company) amt = flt(d.debit) and d.debit or d.credit self.total_amount = fmt_money(amt, currency=company_currency) from frappe.utils import money_in_words self.total_amount_in_words = money_in_words(amt, company_currency)
def calculate_net_salary(doc, msd, med): gross_pay = 0 net_pay = 0 tot_ded = 0 tot_cont = 0 tot_books = 0 emp = frappe.get_doc("Employee", doc.employee) tdim, twd = get_total_days(doc, emp, msd, med) holidays = get_holidays(doc, msd, med, emp) lwp, plw = get_leaves(doc, msd, med, emp) doc.leave_without_pay = lwp doc.posting_date = med wd = twd - holidays #total working days doc.total_days_in_month = tdim att = frappe.db.sql("""SELECT sum(overtime), count(name) FROM `tabAttendance` WHERE employee = '%s' AND att_date >= '%s' AND att_date <= '%s' AND status = 'Present' AND docstatus=1""" \ %(doc.employee, msd, med),as_list=1) half_day = frappe.db.sql("""SELECT count(name) FROM `tabAttendance` WHERE employee = '%s' AND att_date >= '%s' AND att_date <= '%s' AND status = 'Half Day' AND docstatus=1""" \ %(doc.employee, msd, med),as_list=1) t_hd = flt(half_day[0][0]) t_ot = flt(att[0][0]) doc.total_overtime = t_ot tpres = flt(att[0][1]) ual = twd - tpres - lwp - holidays - plw - (t_hd / 2) if ual < 0: frappe.throw(("Unauthorized Leave cannot be Negative for Employee {0}").\ format(doc.employee_name)) paydays = tpres + (t_hd / 2) + plw + math.ceil( (tpres + (t_hd / 2)) / wd * holidays) pd_ded = flt(doc.payment_days_for_deductions) doc.payment_days = paydays if doc.change_deductions == 0: doc.payment_days_for_deductions = doc.payment_days if doc.payment_days_for_deductions == doc.payment_days: doc.change_deductions = 0 doc.unauthorized_leaves = ual ot_ded = round(8 * ual, 1) if ot_ded > t_ot: ot_ded = (int(t_ot / 8)) * 8 doc.overtime_deducted = ot_ded d_ual = int(ot_ded / 8) #Calculate Earnings chk_ot = 0 #Check if there is an Overtime Rate for d in doc.earnings: if d.salary_component == "Overtime Rate": chk_ot = 1 for d in doc.earnings: earn = frappe.get_doc("Salary Component", d.salary_component) if earn.depends_on_lwp == 1: d.depends_on_lwp = 1 else: d.depends_on_lwp = 0 if earn.based_on_earning: for d2 in doc.earnings: #Calculate Overtime Value if earn.earning == d2.salary_component: d.default_amount = flt(d2.amount) * t_ot d.amount = flt(d2.amount) * (t_ot - ot_ded) else: if d.depends_on_lwp == 1 and earn.books == 0: if chk_ot == 1: d.amount = round( flt(d.default_amount) * (paydays + d_ual) / tdim, 0) else: d.amount = round( flt(d.default_amount) * (paydays) / tdim, 0) elif d.depends_on_lwp == 1 and earn.books == 1: d.amount = round( flt(d.default_amount) * flt(doc.payment_days_for_deductions) / tdim, 0) elif earn.manual == 1: d.default_amount = d.amount else: d.amount = d.default_amount if earn.books == 1: tot_books += flt(d.amount) if earn.only_for_deductions <> 1: gross_pay += flt(d.amount) if gross_pay < 0: frappe.throw( ("Gross Pay Cannot be Less than Zero for Employee: {0}").format( emp.employee_name)) #Calculate Deductions for d in doc.deductions: if d.salary_component <> 'Loan Deduction': sal_comp_doc = frappe.get_doc("Salary Component", d.salary_component) if sal_comp_doc.depends_on_lwp == 1: if sal_comp_doc.round_up == 1: d.amount = int( flt(d.default_amount) * flt(doc.payment_days_for_deductions) / tdim) + 1 else: d.amount = round( flt(d.default_amount) * flt(doc.payment_days_for_deductions) / tdim, 0) tot_ded += d.amount #Calculate Contributions for c in doc.contributions: c.amount = round((flt(c.default_amount) * flt(doc.payment_days_for_deductions) / tdim), 0) tot_cont += c.amount doc.gross_pay = gross_pay doc.total_deduction = tot_ded doc.net_pay = doc.gross_pay - doc.total_deduction doc.rounded_total = myround(doc.net_pay, 10) doc.net_pay_books = tot_books - doc.total_deduction company_currency = get_company_currency(doc.company) doc.total_in_words = money_in_words(doc.rounded_total, company_currency) doc.total_ctc = doc.gross_pay + tot_cont
def company_currency(self): if not hasattr(self, "__company_currency"): self.__company_currency = get_company_currency(self.company) return self.__company_currency
class ShippingRule(Document): def validate(self): self.validate_value("calculate_based_on", "in", ["Net Total", "Net Weight"]) self.conditions = self.get("conditions") self.validate_from_to_values() self.sort_shipping_rule_conditions() self.validate_overlapping_shipping_rule_conditions() if self.worldwide_shipping: self.countries = [] elif not len([d.country for d in self.countries if d.country]): frappe.throw( _("Please specify a country for this Shipping Rule or check Worldwide Shipping" )) def autoname(self): self.name = self.label + '-' + self.company def validate_from_to_values(self): zero_to_values = [] for d in self.get("conditions"): self.round_floats_in(d) # values cannot be negative self.validate_value("from_value", ">=", 0.0, d) self.validate_value("to_value", ">=", 0.0, d) if not d.to_value: zero_to_values.append(d) elif d.from_value >= d.to_value: throw( _("From value must be less than to value in row {0}"). format(d.idx), FromGreaterThanToError) # check if more than two or more rows has To Value = 0 if len(zero_to_values) >= 2: throw( _('There can only be one Shipping Rule Condition with 0 or blank value for "To Value"' ), ManyBlankToValuesError) def sort_shipping_rule_conditions(self): """Sort Shipping Rule Conditions based on increasing From Value""" self.shipping_rules_conditions = sorted( self.conditions, key=lambda d: flt(d.from_value)) for i, d in enumerate(self.conditions): d.idx = i + 1 def validate_overlapping_shipping_rule_conditions(self): def overlap_exists_between((x1, x2), (y1, y2)): """ (x1, x2) and (y1, y2) are two ranges if condition x = 100 to 300 then condition y can only be like 50 to 99 or 301 to 400 hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2) """ separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2) return (not separate) overlaps = [] for i in xrange(0, len(self.conditions)): for j in xrange(i + 1, len(self.conditions)): d1, d2 = self.conditions[i], self.conditions[j] if d1.as_dict() != d2.as_dict(): # in our case, to_value can be zero, hence pass the from_value if so range_a = (d1.from_value, d1.to_value or d1.from_value) range_b = (d2.from_value, d2.to_value or d2.from_value) if overlap_exists_between(range_a, range_b): overlaps.append([d1, d2]) if overlaps: company_currency = get_company_currency(self.company) msgprint(_("Overlapping conditions found between:")) messages = [] for d1, d2 in overlaps: messages.append( "%s-%s = %s " % (d1.from_value, d1.to_value, fmt_money(d1.shipping_amount, currency=company_currency)) + _("and") + " %s-%s = %s" % (d2.from_value, d2.to_value, fmt_money(d2.shipping_amount, currency=company_currency))) msgprint("\n".join(messages), raise_exception=OverlappingConditionError)
def set_total_amount(self, amt): company_currency = get_company_currency(self.company) self.total_amount = amt from frappe.utils import money_in_words self.total_amount_in_words = money_in_words(amt, company_currency)
def check_conversion_rate(self): default_currency = get_company_currency(self.company) if not default_currency: throw(_('Please enter default currency in Company Master')) if (self.currency == default_currency and flt(self.conversion_rate) != 1.00) or not self.conversion_rate or (self.currency != default_currency and flt(self.conversion_rate) == 1.00): throw(_("Conversion rate cannot be 0 or 1"))
class DocType(DocListController): def __init__(self, d, dl): self.doc, self.doclist = d, dl def validate(self): self.validate_value("calculate_based_on", "in", ["Net Total", "Net Weight"]) self.shipping_rule_conditions = self.doclist.get( {"parentfield": "shipping_rule_conditions"}) self.validate_from_to_values() self.sort_shipping_rule_conditions() self.validate_overlapping_shipping_rule_conditions() def validate_from_to_values(self): zero_to_values = [] for d in self.shipping_rule_conditions: self.round_floats_in(d) # values cannot be negative self.validate_value("from_value", ">=", 0.0, d) self.validate_value("to_value", ">=", 0.0, d) if d.to_value == 0: zero_to_values.append(d) elif d.from_value >= d.to_value: msgprint(_("Error") + ": " + _("Row") + " # %d: " % d.idx + _("From Value should be less than To Value"), raise_exception=FromGreaterThanToError) # check if more than two or more rows has To Value = 0 if len(zero_to_values) >= 2: msgprint(_( '''There can only be one Shipping Rule Condition with 0 or blank value for "To Value"''' ), raise_exception=ManyBlankToValuesError) def sort_shipping_rule_conditions(self): """Sort Shipping Rule Conditions based on increasing From Value""" self.shipping_rules_conditions = sorted( self.shipping_rule_conditions, key=lambda d: flt(d.from_value)) for i, d in enumerate(self.shipping_rule_conditions): d.idx = i + 1 def validate_overlapping_shipping_rule_conditions(self): def overlap_exists_between((x1, x2), (y1, y2)): """ (x1, x2) and (y1, y2) are two ranges if condition x = 100 to 300 then condition y can only be like 50 to 99 or 301 to 400 hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2) """ separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2) return (not separate) overlaps = [] for i in xrange(0, len(self.shipping_rule_conditions)): for j in xrange(i + 1, len(self.shipping_rule_conditions)): d1, d2 = self.shipping_rule_conditions[ i], self.shipping_rule_conditions[j] if d1.fields != d2.fields: # in our case, to_value can be zero, hence pass the from_value if so range_a = (d1.from_value, d1.to_value or d1.from_value) range_b = (d2.from_value, d2.to_value or d2.from_value) if overlap_exists_between(range_a, range_b): overlaps.append([d1, d2]) if overlaps: company_currency = get_company_currency(self.doc.company) msgprint( _("Error") + ": " + _("Overlapping Conditions found between") + ":") messages = [] for d1, d2 in overlaps: messages.append( "%s-%s = %s " % (d1.from_value, d1.to_value, fmt_money(d1.shipping_amount, currency=company_currency)) + _("and") + " %s-%s = %s" % (d2.from_value, d2.to_value, fmt_money(d2.shipping_amount, currency=company_currency))) msgprint("\n".join(messages), raise_exception=OverlappingConditionError)