def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): account_currency = get_account_currency(item.income_account) gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, "credit_in_account_currency": item.base_net_amount \ if account_currency==self.company_currency else item.net_amount, "cost_center": item.cost_center }, account_currency) ) if item.is_fixed_asset: asset = frappe.get_doc("Asset", item.asset) fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle)) asset.db_set("disposal_date", self.posting_date) asset.set_status("Sold" if self.docstatus==1 else None) # expense account gl entries if cint(self.update_stock) and \ erpnext.is_perpetual_inventory_enabled(self.company): gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_item_gl_entries(self, gl_entries): # income account gl entries adon_added = False for item in self.get("items"): if flt(item.base_net_amount): account_currency = get_account_currency(item.income_account) gl_entries.append( self.get_gl_dict( { "account": item.income_account, "against": self.customer, "credit": item.base_net_amount + (flt(self.adon) or 0.0 if not adon_added else 0.0), "credit_in_account_currency": item.base_net_amount if account_currency == self.company_currency else item.net_amount, "cost_center": item.cost_center, }, account_currency, ) ) # print gl_entries adon_added = True # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) and cint(self.update_stock): gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_pos_gl_entries(self, gl_entries): if cint(self.is_pos) and self.cash_bank_account and self.paid_amount: bank_account_currency = get_account_currency(self.cash_bank_account) # POS, make payment entries gl_entries.append( self.get_gl_dict({ "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": self.cash_bank_account, "credit": self.base_paid_amount, "credit_in_account_currency": self.base_paid_amount \ if self.party_account_currency==self.company_currency else self.paid_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, self.party_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.cash_bank_account, "against": self.customer, "debit": self.base_paid_amount, "debit_in_account_currency": self.base_paid_amount \ if bank_account_currency==self.company_currency else self.paid_amount }, bank_account_currency) )
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): account_currency = get_account_currency(item.income_account) account_report_type = frappe.db.get_value("Account", item.income_account, "report_type") if account_report_type == "Profit and Loss": project_name=self.project support_ticket=self.support_ticket else: project_name='' support_ticket='' gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, "credit_in_account_currency": item.base_net_amount \ if account_currency==self.company_currency else item.net_amount, "cost_center": item.cost_center, "project_name": project_name, "support_ticket": support_ticket }, account_currency) ) # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ and cint(self.update_stock): gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): if item.is_fixed_asset: asset = frappe.get_doc("Asset", item.asset) fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle)) asset.db_set("disposal_date", self.posting_date) asset.set_status("Sold" if self.docstatus==1 else None) else: account_currency = get_account_currency(item.income_account) gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, "credit_in_account_currency": item.base_net_amount \ if account_currency==self.company_currency else item.net_amount, "cost_center": item.cost_center, "project": self.project, "support_ticket": self.support_ticket }, account_currency) ) # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ and cint(self.update_stock): gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_tds_gl_entry(self, gl_entries): if self.tds_account and flt(self.tds_amount): tds_account_currency = get_account_currency(self.tds_account) if(self.tds_amount): self.tds_amount = round(flt(self.tds_amount), 2) if(self.base_tds_amount): self.base_tds_amount = round(flt(self.base_tds_amount), 2) gl_entries.append( self.get_gl_dict({ "account": self.tds_account, "against": self.supplier, #"party_type": "Supplier", #"party": self.supplier, "credit": flt(self.base_tds_amount), "credit_in_account_currency": self.base_tds_amount \ if tds_account_currency==self.company_currency else self.tds_amount, "cost_center": self.tds_cost_center }) ) gl_entries.append( self.get_gl_dict({ "account": self.credit_to, "party_type": "Supplier", "party": self.supplier, "against": self.tds_account, "debit": self.base_tds_amount, "debit_in_account_currency": self.base_tds_amount \ if tds_account_currency==self.company_currency else self.tds_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, tds_account_currency) )
def make_write_off_gl_entry(self, gl_entries): # write off entries, applicable if only pos if self.write_off_account and self.write_off_amount: write_off_account_currency = get_account_currency(self.write_off_account) default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center') gl_entries.append( self.get_gl_dict({ "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": self.write_off_account, "credit": self.base_write_off_amount, "credit_in_account_currency": self.base_write_off_amount \ if self.party_account_currency==self.company_currency else self.write_off_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype }, self.party_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.write_off_account, "against": self.customer, "debit": self.base_write_off_amount, "debit_in_account_currency": self.base_write_off_amount \ if write_off_account_currency==self.company_currency else self.write_off_amount, "cost_center": self.write_off_cost_center or default_cost_center }, write_off_account_currency) )
def make_pos_gl_entries(self, gl_entries): if cint(self.is_pos): for payment_mode in self.payments: # POS, make payment entries gl_entries.append( self.get_gl_dict({ "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": payment_mode.account, "credit": payment_mode.base_amount, "credit_in_account_currency": payment_mode.base_amount \ if self.party_account_currency==self.company_currency \ else payment_mode.amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, self.party_account_currency) ) payment_mode_account_currency = get_account_currency(payment_mode.account) gl_entries.append( self.get_gl_dict({ "account": payment_mode.account, "against": self.customer, "debit": payment_mode.base_amount, "debit_in_account_currency": payment_mode.base_amount \ if payment_mode_account_currency==self.company_currency else payment_mode.amount }, payment_mode_account_currency) )
def get_gl_dict(self, args, account_currency=None): """this method populates the common properties of a gl entry record""" fiscal_years = get_fiscal_years(self.posting_date, company=self.company) if len(fiscal_years) > 1: frappe.throw(_("Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year").format(formatdate(self.posting_date))) else: fiscal_year = fiscal_years[0][0] gl_dict = frappe._dict({ 'company': self.company, 'posting_date': self.posting_date, 'fiscal_year': fiscal_year, 'voucher_type': self.doctype, 'voucher_no': self.name, 'remarks': self.get("remarks"), 'debit': 0, 'credit': 0, 'debit_in_account_currency': 0, 'credit_in_account_currency': 0, 'is_opening': self.get("is_opening") or "No", 'party_type': None, 'party': None, 'project': self.get("project") }) gl_dict.update(args) if not account_currency: account_currency = get_account_currency(gl_dict.account) if self.doctype not in ["Journal Entry", "Period Closing Voucher", "Payment Entry"]: self.validate_account_currency(gl_dict.account, account_currency) set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency) return gl_dict
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 set_account_currency(filters): if not (filters.get("account") or filters.get("party")): return filters else: filters["company_currency"] = frappe.db.get_value("Company", filters.company, "default_currency") account_currency = None if filters.get("account"): account_currency = get_account_currency(filters.account) elif filters.get("party"): gle_currency = frappe.db.get_value( "GL Entry", {"party_type": filters.party_type, "party": filters.party, "company": filters.company}, "account_currency", ) if gle_currency: account_currency = gle_currency else: account_currency = frappe.db.get_value(filters.party_type, filters.party, "default_currency") filters["account_currency"] = account_currency or filters.company_currency if filters.account_currency != filters.company_currency: filters["show_in_account_currency"] = 1 return filters
def make_payment_gl_entries(self, gl_entries): # Make Cash GL Entries if cint(self.is_paid) and self.cash_bank_account and self.paid_amount: bank_account_currency = get_account_currency(self.cash_bank_account) # CASH, make payment entries gl_entries.append( self.get_gl_dict({ "account": self.credit_to, "party_type": "Supplier", "party": self.supplier, "against": self.cash_bank_account, "debit": self.base_paid_amount, "debit_in_account_currency": self.base_paid_amount \ if self.party_account_currency==self.company_currency else self.paid_amount, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher_type": self.doctype, "cost_center": self.cost_center }, self.party_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.cash_bank_account, "against": self.supplier, "credit": self.base_paid_amount, "credit_in_account_currency": self.base_paid_amount \ if bank_account_currency==self.company_currency else self.paid_amount, "cost_center": self.cost_center }, bank_account_currency) )
def make_write_off_gl_entry(self, gl_entries): # writeoff account includes petty difference in the invoice amount # and the amount that is paid if self.write_off_account and flt(self.write_off_amount): write_off_account_currency = get_account_currency(self.write_off_account) gl_entries.append( self.get_gl_dict({ "account": self.credit_to, "party_type": "Supplier", "party": self.supplier, "against": self.write_off_account, "debit": self.base_write_off_amount, "debit_in_account_currency": self.base_write_off_amount \ if self.party_account_currency==self.company_currency else self.write_off_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, self.party_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.write_off_account, "against": self.supplier, "credit": flt(self.base_write_off_amount), "credit_in_account_currency": self.base_write_off_amount \ if write_off_account_currency==self.company_currency else self.write_off_amount, "cost_center": self.write_off_cost_center }) )
def get_gl_dict(self, args, account_currency=None): """this method populates the common properties of a gl entry record""" gl_dict = frappe._dict({ 'company': self.company, 'posting_date': self.posting_date, 'voucher_type': self.doctype, 'voucher_no': self.name, 'remarks': self.get("remarks"), 'fiscal_year': self.fiscal_year, 'debit': 0, 'credit': 0, 'debit_in_account_currency': 0, 'credit_in_account_currency': 0, 'is_opening': self.get("is_opening") or "No", 'party_type': None, 'party': None }) gl_dict.update(args) if not account_currency: account_currency = get_account_currency(gl_dict.account) if self.doctype not in ["Journal Entry", "Period Closing Voucher"]: self.validate_account_currency(gl_dict.account, account_currency) self.set_balance_in_account_currency(gl_dict, account_currency) return gl_dict
def get_outstanding_reference_documents(args): args = json.loads(args) party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") # Get negative outstanding sales /purchase invoices total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), total_field) # Get positive outstanding sales /purchase invoices outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account")) for d in outstanding_invoices: d["exchange_rate"] = 1 if party_account_currency != company_currency \ and d.voucher_type in ("Sales Invoice", "Purchase Invoice"): d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = get_orders_to_be_billed(args.get("party_type"), args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def make_advance_gl_entry(self, gl_entries): for a in self.get("advances"): if flt(a.allocated_amount) and a.advance_account: advance_account_currency = get_account_currency(a.advance_account) allocated_amount = round(flt(a.allocated_amount), 2) gl_entries.append( self.get_gl_dict({ "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": a.advance_account, "credit": allocated_amount, "credit_in_account_currency": allocated_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, advance_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": a.advance_account, "party_type": "Customer", "party": self.customer, "against": self.customer, "debit": allocated_amount, "debit_in_account_currency": allocated_amount, "cost_center": a.advance_cost_center }, advance_account_currency) )
def get_payment_entry_against_order(dt, dn): ref_doc = frappe.get_doc(dt, dn) if flt(ref_doc.per_billed, 2) > 0: frappe.throw(_("Can only make payment against unbilled {0}").format(dt)) if dt == "Sales Order": party_type = "Customer" amount_field_party = "credit_in_account_currency" amount_field_bank = "debit_in_account_currency" else: party_type = "Supplier" amount_field_party = "debit_in_account_currency" amount_field_bank = "credit_in_account_currency" party_account = get_party_account(party_type, ref_doc.get(party_type.lower()), ref_doc.company) party_account_currency = get_account_currency(party_account) if party_account_currency == ref_doc.company_currency: amount = flt(ref_doc.base_grand_total) - flt(ref_doc.advance_paid) else: amount = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) return get_payment_entry(ref_doc, { "party_type": party_type, "party_account": party_account, "party_account_currency": party_account_currency, "amount_field_party": amount_field_party, "amount_field_bank": amount_field_bank, "amount": amount, "remarks": 'Advance Payment received against {0} {1}'.format(dt, dn), "is_advance": "Yes" })
def set_account_currency(filters): if filters.get("account") or (filters.get('party') and len(filters.party) == 1): filters["company_currency"] = frappe.get_cached_value('Company', filters.company, "default_currency") account_currency = None if filters.get("account"): account_currency = get_account_currency(filters.account) elif filters.get("party"): gle_currency = frappe.db.get_value( "GL Entry", { "party_type": filters.party_type, "party": filters.party[0], "company": filters.company }, "account_currency" ) if gle_currency: account_currency = gle_currency else: account_currency = (None if filters.party_type in ["Employee", "Student", "Shareholder", "Member"] else frappe.db.get_value(filters.party_type, filters.party[0], "default_currency")) filters["account_currency"] = account_currency or filters.company_currency if filters.account_currency != filters.company_currency and not filters.presentation_currency: filters.presentation_currency = filters.account_currency return filters
def get_account_details(account, date): frappe.has_permission('Payment Entry', throw=True) return frappe._dict({ "account_currency": get_account_currency(account), "account_balance": get_balance_on(account, date), "account_type": frappe.db.get_value("Account", account, "account_type") })
def get_outstanding_vouchers(args): from erpnext.accounts.utils import get_outstanding_invoices if not frappe.has_permission("Payment Tool"): frappe.throw(_("No permission to use Payment Tool"), frappe.PermissionError) args = json.loads(args) party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") if (args.get("party_type") == "Customer" and args.get("received_or_paid") == "Paid") or ( args.get("party_type") == "Supplier" and args.get("received_or_paid") == "Received" ): frappe.throw(_("Please enter the Against Vouchers manually")) # Get all outstanding sales /purchase invoices outstanding_invoices = get_outstanding_invoices( args.get("party_type"), args.get("party"), args.get("party_account") ) # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = get_orders_to_be_billed( args.get("party_type"), args.get("party"), party_account_currency, company_currency ) return outstanding_invoices + orders_to_be_billed
def validate_orders(self): """Validate totals, stopped 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.db.get_value(reference_type, reference_name, ["docstatus", "per_billed", "status", "advance_paid", "base_grand_total", "grand_total", "currency"], as_dict=1) 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) == "Stopped": frappe.throw(_("{0} {1} is stopped").format(reference_type, reference_name)) account_currency = get_account_currency(account) if account_currency == self.company_currency: voucher_total = order.base_grand_total else: voucher_total = order.grand_total 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, voucher_total))
def get_outstanding_reference_documents(args): if isinstance(args, string_types): args = json.loads(args) if args.get('party_type') == 'Member': return # confirm that Supplier is not blocked if args.get('party_type') == 'Supplier': supplier_status = get_supplier_block_status(args['party']) if supplier_status['on_hold']: if supplier_status['hold_type'] == 'All': return [] elif supplier_status['hold_type'] == 'Payments': if not supplier_status['release_date'] or getdate(nowdate()) <= supplier_status['release_date']: return [] party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.get_cached_value('Company', args.get("company"), "default_currency") # Get negative outstanding sales /purchase invoices negative_outstanding_invoices = [] if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"): negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), party_account_currency, company_currency) # Get positive outstanding sales /purchase invoices/ Fees condition = "" if args.get("voucher_type") and args.get("voucher_no"): condition = " and voucher_type='{0}' and voucher_no='{1}'"\ .format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"])) # Add cost center condition if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account(): condition += " and cost_center='%s'" % args.get("cost_center") outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), condition=condition) for d in outstanding_invoices: d["exchange_rate"] = 1 if party_account_currency != company_currency: if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"): d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") elif d.voucher_type == "Journal Entry": d["exchange_rate"] = get_exchange_rate( party_account_currency, company_currency, d.posting_date ) if d.voucher_type in ("Purchase Invoice"): d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = [] if (args.get("party_type") != "Student"): orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def make_pos_gl_entries(self, gl_entries): if cint(self.is_pos) and self.paid_amount: # POS, make payment entries gl_entries.append( self.get_gl_dict({ "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": self.cash_bank_account, "credit": flt(self.base_paid_amount - self.base_change_amount), "credit_in_account_currency": flt(self.base_paid_amount - self.base_change_amount) \ if self.party_account_currency==self.company_currency else flt(self.paid_amount - self.change_amount), "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, self.party_account_currency) ) cash_account = '' for payment_mode in self.payments: if payment_mode.type == 'Cash': cash_account = payment_mode.account if payment_mode.base_amount > 0: payment_mode_account_currency = get_account_currency(payment_mode.account) gl_entries.append( self.get_gl_dict({ "account": payment_mode.account, "against": self.customer, "debit": payment_mode.base_amount, "debit_in_account_currency": payment_mode.base_amount \ if payment_mode_account_currency==self.company_currency else payment_mode.amount }, payment_mode_account_currency) ) if self.change_amount: cash_account = cash_account or self.payments[0].account cash_account_currency = get_account_currency(cash_account) gl_entries.append( self.get_gl_dict({ "account": cash_account, "against": self.customer, "credit": self.base_change_amount, "credit_in_account_currency": self.base_change_amount \ if payment_mode_account_currency==self.company_currency else self.change_amount }, payment_mode_account_currency) )
def get_payment_entry(ref_doc, args): cost_center = frappe.db.get_value("Company", ref_doc.company, "cost_center") exchange_rate = 1 if args.get("party_account"): exchange_rate = get_exchange_rate(args.get("party_account"), args.get("party_account_currency"), ref_doc.company, ref_doc.doctype, ref_doc.name) je = frappe.new_doc("Journal Entry") je.update({ "voucher_type": "Bank Entry", "company": ref_doc.company, "remark": args.get("remarks") }) party_row = je.append("accounts", { "account": args.get("party_account"), "party_type": args.get("party_type"), "party": ref_doc.get(args.get("party_type").lower()), "cost_center": cost_center, "account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"), "account_currency": args.get("party_account_currency") or \ get_account_currency(args.get("party_account")), "balance": get_balance_on(args.get("party_account")), "party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")), "exchange_rate": exchange_rate, args.get("amount_field_party"): args.get("amount"), "is_advance": args.get("is_advance"), "reference_type": ref_doc.doctype, "reference_name": ref_doc.name }) bank_row = je.append("accounts") #make it bank_details bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account")) if bank_account: bank_row.update(bank_account) bank_row.exchange_rate = get_exchange_rate(bank_account["account"], bank_account["account_currency"], ref_doc.company) bank_row.cost_center = cost_center amount = args.get("debit_in_account_currency") or args.get("amount") if bank_row.account_currency == args.get("party_account_currency"): bank_row.set(args.get("amount_field_bank"), amount) else: bank_row.set(args.get("amount_field_bank"), amount * exchange_rate) # set multi currency check if party_row.account_currency != ref_doc.company_currency \ or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency): je.multi_currency = 1 je.set_amounts_in_company_currency() je.set_total_debit_credit() return je if args.get("journal_entry") else je.as_dict()
def validate_account_head(self): closing_account_type = frappe.db.get_value("Account", self.closing_account_head, "root_type") if closing_account_type not in ["Liability", "Equity"]: frappe.throw(_("Closing Account {0} must be of type Liability / Equity").format(self.closing_account_head)) account_currency = get_account_currency(self.closing_account_head) company_currency = frappe.db.get_value("Company", self.company, "default_currency") if account_currency != company_currency: frappe.throw(_("Currency of the Closing Account must be {0}").format(company_currency))
def make_tax_gl_entries(self, gl_entries): # tax table gl entries valuation_tax = {} for tax in self.get("taxes"): if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): account_currency = get_account_currency(tax.account_head) dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.supplier, dr_or_cr: tax.base_tax_amount_after_discount_amount, dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ if account_currency==self.company_currency \ else tax.tax_amount_after_discount_amount, "cost_center": tax.cost_center }, account_currency) ) # accumulate valuation tax if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): if self.auto_accounting_for_stock and not tax.cost_center: frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) valuation_tax.setdefault(tax.cost_center, 0) valuation_tax[tax.cost_center] += \ (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax: # credit valuation tax amount in "Expenses Included In Valuation" # this will balance out valuation amount included in cost of goods sold total_valuation_amount = sum(valuation_tax.values()) amount_including_divisional_loss = self.negative_expense_to_be_booked i = 1 for cost_center, amount in valuation_tax.items(): if i == len(valuation_tax): applicable_amount = amount_including_divisional_loss else: applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount) amount_including_divisional_loss -= applicable_amount gl_entries.append( self.get_gl_dict({ "account": self.expenses_included_in_valuation, "cost_center": cost_center, "against": self.supplier, "credit": applicable_amount, "remarks": self.remarks or "Accounting Entry for Stock" }) ) i += 1
def create_journal_entry(self): """create entry""" frappe.flags.ignore_account_permission = True ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company) party_account_currency = get_account_currency(party_account) debit_in_account_currency = 0.0 if party_account_currency == ref_doc.company_currency: amount = flt( flt(self.grand_total) * flt(ref_doc.conversion_rate, ref_doc.precision("conversion_rate")), ref_doc.precision("base_grand_total"), ) if self.currency != ref_doc.company_currency: debit_in_account_currency = self.grand_total else: amount = debit_in_account_currency = self.grand_total if self.reference_doctype == "Sales Order": jv = get_payment_entry_against_order( self.reference_doctype, self.reference_name, amount=amount, debit_in_account_currency=debit_in_account_currency, journal_entry=True, bank_account=self.payment_account, ) if self.reference_doctype == "Sales Invoice": jv = get_payment_entry_against_invoice( self.reference_doctype, self.reference_name, amount=amount, debit_in_account_currency=debit_in_account_currency, journal_entry=True, bank_account=self.payment_account, ) jv.update({"voucher_type": "Journal Entry", "posting_date": nowdate()}) jv.insert(ignore_permissions=True) jv.submit() # set status as paid for Payment Request frappe.db.set_value(self.doctype, self.name, "status", "Paid") return jv
def validate_currency(self): company_currency = get_company_currency(self.company) account_currency = get_account_currency(self.account) if not self.account_currency: self.account_currency = company_currency if account_currency != self.account_currency: frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}") .format(self.account, (account_currency or company_currency)), InvalidAccountCurrency) if self.party_type and self.party: validate_party_gle_currency(self.party_type, self.party, self.company, self.account_currency)
def get_payment_entry_from_sales_order(sales_order): """Returns new Journal Entry document as dict for given Sales Order""" from erpnext.accounts.utils import get_balance_on from erpnext.accounts.party import get_party_account so = frappe.get_doc("Sales Order", sales_order) if flt(so.per_billed, 2) != 0.0: frappe.throw(_("Can only make payment against unbilled Sales Order")) jv = get_payment_entry(so) jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name) party_account = get_party_account("Customer", so.customer, so.company) party_account_currency = get_account_currency(party_account) exchange_rate = get_exchange_rate(party_account, party_account_currency, so.company) if party_account_currency == so.company_currency: amount = flt(so.base_grand_total) - flt(so.advance_paid) else: amount = flt(so.grand_total) - flt(so.advance_paid) # credit customer row1 = jv.get("accounts")[0] row1.account = party_account row1.account_currency = party_account_currency row1.party_type = "Customer" row1.party = so.customer row1.balance = get_balance_on(party_account) row1.party_balance = get_balance_on(party=so.customer, party_type="Customer") row1.credit_in_account_currency = amount row1.reference_type = so.doctype row1.reference_name = so.name row1.is_advance = "Yes" row1.exchange_rate = exchange_rate row1.account_type = "Receivable" # debit bank row2 = jv.get("accounts")[1] if row2.account_currency == party_account_currency: row2.debit_in_account_currency = amount else: row2.debit_in_account_currency = amount * exchange_rate # set multi currency check if row1.account_currency != so.company_currency or row2.account_currency != so.company_currency: jv.multi_currency = 1 return jv.as_dict()
def make_tax_gl_entries(self, gl_entries): for tax in self.get("taxes"): if flt(tax.base_tax_amount_after_discount_amount): account_currency = get_account_currency(tax.account_head) gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.customer, "credit": flt(tax.base_tax_amount_after_discount_amount), "credit_in_account_currency": flt(tax.base_tax_amount_after_discount_amount) \ if account_currency==self.company_currency else flt(tax.tax_amount_after_discount_amount), "cost_center": tax.cost_center }, account_currency) )
def validate_currency(self): company_currency = erpnext.get_company_currency(self.company) account_currency = get_account_currency(self.account) if not self.account_currency: self.account_currency = account_currency or company_currency if account_currency != self.account_currency: frappe.throw( _("{0} {1}: Accounting Entry for {2} can only be made in currency: {3}" ).format(self.voucher_type, self.voucher_no, self.account, (account_currency or company_currency)), InvalidAccountCurrency, ) if self.party_type and self.party: validate_party_gle_currency(self.party_type, self.party, self.company, self.account_currency)
def add_deductions_gl_entries(self, gl_entries): for d in self.get("deductions"): if d.amount: account_currency = get_account_currency(d.account) if account_currency != self.company_currency: frappe.throw( _("Currency for {0} must be {1}").format( d.account, self.company_currency)) gl_entries.append( self.get_gl_dict({ "account": d.account, "account_currency": account_currency, "against": self.party or self.paid_from, "debit_in_account_currency": d.amount, "debit": d.amount, "cost_center": d.cost_center }))
def get_gl_dict(self, args, account_currency=None): """this method populates the common properties of a gl entry record""" fiscal_years = get_fiscal_years(self.posting_date, company=self.company) if len(fiscal_years) > 1: frappe.throw( _("Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year" ).format(formatdate(self.posting_date))) else: fiscal_year = fiscal_years[0][0] gl_dict = frappe._dict({ 'company': self.company, 'posting_date': self.posting_date, 'fiscal_year': fiscal_year, 'voucher_type': self.doctype, 'voucher_no': self.name, 'remarks': self.get("remarks"), 'debit': 0, 'credit': 0, 'debit_in_account_currency': 0, 'credit_in_account_currency': 0, 'is_opening': self.get("is_opening") or "No", 'party_type': None, 'party': None, 'code_jour': None, 'project': self.get("project") }) gl_dict.update(args) if not account_currency: account_currency = get_account_currency(gl_dict.account) if gl_dict.account and self.doctype not in [ "Journal Entry", "Period Closing Voucher", "Payment Entry" ]: self.validate_account_currency(gl_dict.account, account_currency) set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency) return gl_dict
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): if item.is_fixed_asset: asset = frappe.get_doc("Asset", item.asset) fixed_asset_gl_entries = get_gl_entries_on_asset_disposal( asset, item.base_net_amount) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle)) asset.db_set("disposal_date", self.posting_date) asset.set_status("Sold" if self.docstatus == 1 else None) else: account_currency = get_account_currency( item.income_account) gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, "credit_in_account_currency": item.base_net_amount \ if account_currency==self.company_currency else item.net_amount, "cost_center": item.cost_center }, account_currency) ) # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ and cint(self.update_stock): # because these come in proper polarities # so to switch back, switch polarity now for gl in super(SalesReturn, self).get_gl_entries(): if gl.debit: gl.debit *= -1 gl.debit_in_account_currency *= -1 elif gl.credit: gl.credit *= -1 gl.credit_in_account_currency *= -1 gl_entries.append(gl)
def make_write_off_gl_entry(self, gl_entries): # writeoff account includes petty difference in the invoice amount # and the amount that is paid if self.write_off_account and flt(self.write_off_amount): write_off_account_currency = get_account_currency(self.write_off_account) gl_entries.append( self.get_gl_dict({ "account": self.credit_to, "party_type": "Supplier", "party": self.supplier, "against": self.write_off_account, "debit": self.base_write_off_amount, "debit_in_account_currency": self.base_write_off_amount \ if self.party_account_currency==self.company_currency else self.write_off_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, self.party_account_currency) ) if self.write_off_account == "Retention Money - SMCL": gl_entries.append( self.get_gl_dict({ "account": self.write_off_account, "against": self.supplier, "party_type": "Supplier", "party": self.supplier, "credit": flt(self.base_write_off_amount), "credit_in_account_currency": self.base_write_off_amount \ if write_off_account_currency==self.company_currency else self.write_off_amount, "cost_center": self.write_off_cost_center, "remarks": "Retention amount deducted from Bill" }) ) else: gl_entries.append( self.get_gl_dict({ "account": self.write_off_account, "against": self.supplier, "credit": flt(self.base_write_off_amount), "credit_in_account_currency": self.base_write_off_amount \ if write_off_account_currency==self.company_currency else self.write_off_amount, "cost_center": self.write_off_cost_center }) )
def make_tax_gl_entries(self, gl_entries): # we dont do these when doing an opeing entry # referred from purchase_invoice.py items expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") # tax table gl entries valuation_tax = {} for tax in self.get("taxes"): if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): account_currency = get_account_currency(tax.account_head) dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.supplier, dr_or_cr: tax.base_tax_amount_after_discount_amount, dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ if account_currency==self.company_currency \ else tax.tax_amount_after_discount_amount, "cost_center": tax.cost_center }, account_currency) ) # accumulate valuation tax if tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): if self.auto_accounting_for_stock and not tax.cost_center: frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) valuation_tax.setdefault(tax.cost_center, 0) valuation_tax[tax.cost_center] += \ (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) if self.auto_accounting_for_stock and valuation_tax: for cost_center, amount in valuation_tax.items(): gl_entries.append( self.get_gl_dict({ "account": expenses_included_in_valuation, "cost_center": cost_center, "against": self.supplier, "credit": amount, "remarks": self.get('remarks') or "Accounting Entry for Stock" }) )
def get_party_details(company, party_type, party, date): if not frappe.db.exists(party_type, party): frappe.throw(_("Invalid {0}: {1}").format(party_type, party)) party_account = get_party_account(party_type, party, company) account_currency = get_account_currency(party_account) account_balance = get_balance_on(party_account, date) _party_name = "title" if party_type == "Student" else party_type.lower() + "_name" party_name = frappe.db.get_value(party_type, party, _party_name) party_balance = get_balance_on(party_type=party_type, party=party) return { "party_account": party_account, "party_name": party_name, "party_account_currency": account_currency, "party_balance": party_balance, "account_balance": account_balance }
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 get_gl_dict(self, args, account_currency=None): """this method populates the common properties of a gl entry record""" gl_dict = frappe._dict({ 'company': self.company, 'posting_date': self.posting_date, 'fiscal_year': get_fiscal_year(self.posting_date, company=self.company)[0], 'voucher_type': self.doctype, 'voucher_no': self.name, 'remarks': self.get("remarks"), 'debit': 0, 'credit': 0, 'debit_in_account_currency': 0, 'credit_in_account_currency': 0, 'is_opening': self.get("is_opening") or "No", 'party_type': None, 'party': None }) gl_dict.update(args) if not account_currency: account_currency = get_account_currency(gl_dict.account) if self.doctype not in ["Journal Entry", "Period Closing Voucher"]: self.validate_account_currency(gl_dict.account, account_currency) set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency) return gl_dict
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount, item.precision("base_net_amount")): if item.is_fixed_asset: asset = frappe.get_doc("Asset", item.asset) fixed_asset_gl_entries = get_gl_entries_on_asset_disposal( asset, item.base_net_amount) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle)) asset.db_set("disposal_date", self.posting_date) asset.set_status("Sold" if self.docstatus == 1 else None) else: account_currency = get_account_currency( item.income_account) gl_entries.append( self.get_gl_dict( { "account": item.income_account, "against": self.customer, "credit": flt(item.base_net_amount, item.precision("base_net_amount")), "credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount")) if account_currency == self.company_currency else flt(item.net_amount, item.precision("net_amount"))), "cost_center": item.cost_center }, account_currency)) # expense account gl entries if cint(self.update_stock) and \ erpnext.is_perpetual_inventory_enabled(self.company): gl_entries += super(SalesInvoice, self).get_gl_entries()
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): account_currency = get_account_currency(item.income_account) gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, "credit_in_account_currency": item.base_net_amount \ if account_currency==self.company_currency else item.net_amount, "cost_center": item.cost_center }, account_currency) ) # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ and cint(self.update_stock): gl_entries += super(SalesInvoice, self).get_gl_entries()
def get_outstanding_reference_documents(args): if isinstance(args, basestring): args = json.loads(args) party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") # Get negative outstanding sales /purchase invoices negative_outstanding_invoices = [] if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"): negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), party_account_currency, company_currency) # Get positive outstanding sales /purchase invoices/ Fees condition = "" if args.get("voucher_type") and args.get("voucher_no"): condition = " and voucher_type='{0}' and voucher_no='{1}'"\ .format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"])) outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), condition=condition) for d in outstanding_invoices: d["exchange_rate"] = 1 if party_account_currency != company_currency: if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"): d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") elif d.voucher_type == "Journal Entry": d["exchange_rate"] = get_exchange_rate( party_account_currency, company_currency, d.posting_date ) if d.voucher_type in ("Purchase Invoice"): d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = [] if (args.get("party_type") != "Student"): orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def validate_orders(self): """Validate totals, stopped 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.db.get_value( reference_type, reference_name, [ "docstatus", "per_billed", "status", "advance_paid", "base_grand_total", "grand_total", "currency" ], as_dict=1) 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) == "Stopped": frappe.throw( _("{0} {1} is stopped").format(reference_type, reference_name)) account_currency = get_account_currency(account) if account_currency == self.company_currency: voucher_total = order.base_grand_total else: voucher_total = order.grand_total 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, voucher_total))
def make_item_gl_entries(self, gl_entries): # income account gl entries for item in self.get("servicos"): if flt(item.total_servico_produto): account_currency = get_account_currency(item.income_account) gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.nome_cliente, "credit": item.total_servico_produto, "credit_in_account_currency": item.total_servico_produto \ if account_currency==self.company_currency else item.total_servico_produto, "cost_center": item.cost_center }, account_currency) ) # expense account gl entries if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ and cint(self.update_stock): print ("algo por saber")
def get_account_details(account, date, cost_center=None): frappe.has_permission('Payment Entry', throw=True) # to check if the passed account is accessible under reference doctype Payment Entry account_list = frappe.get_list('Account', { 'name': account }, reference_doctype='Payment Entry', limit=1) # There might be some user permissions which will allow account under certain doctypes # except for Payment Entry, only in such case we should throw permission error if not account_list: frappe.throw(_('Account: {0} is not permitted under Payment Entry').format(account)) account_balance = get_balance_on(account, date, cost_center=cost_center, ignore_account_permission=True) return frappe._dict({ "account_currency": get_account_currency(account), "account_balance": account_balance, "account_type": frappe.db.get_value("Account", account, "account_type") })
def get_outstanding_reference_documents(args): args = json.loads(args) party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") # Get negative outstanding sales /purchase invoices total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" negative_outstanding_invoices = get_negative_outstanding_invoices( args.get("party_type"), args.get("party"), args.get("party_account"), total_field) # Get positive outstanding sales /purchase invoices outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account")) for d in outstanding_invoices: d["exchange_rate"] = 1 if party_account_currency != company_currency: if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"): d["exchange_rate"] = frappe.db.get_value( d.voucher_type, d.voucher_no, "conversion_rate") elif d.voucher_type == "Journal Entry": d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, d.posting_date) # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"), args.get("party_type"), args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def make_advance_gl_entry(self, gl_entries): for a in self.get("advances"): if flt(a.allocated_amount) and a.advance_account: advance_account_currency = get_account_currency( a.advance_account) allocated_amount = round(flt(a.allocated_amount), 2) gl_entries.append( self.get_gl_dict( { "account": self.debit_to, "party_type": "Customer", "party": self.customer, "against": a.advance_account, "credit": allocated_amount, "credit_in_account_currency": allocated_amount, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }, advance_account_currency)) gl_entries.append( self.get_gl_dict( { "account": a.advance_account, "party_type": "Customer", "party": self.customer, "against": self.customer, "debit": allocated_amount, "debit_in_account_currency": allocated_amount, "cost_center": a.advance_cost_center }, advance_account_currency))
def make_tax_gl_entries(self, gl_entries): for tax in self.get("taxes"): if flt(tax.base_tax_amount_after_discount_amount): account_currency = get_account_currency(tax.account_head) prefix1 = self.return_against if cint( self.is_return) else self.name prefix = prefix1[:2] code_jour = frappe.db.get_value("Series", prefix, "code_jour", order_by="name") gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.customer, "credit": flt(tax.base_tax_amount_after_discount_amount), "credit_in_account_currency": flt(tax.base_tax_amount_after_discount_amount) \ if account_currency==self.company_currency else flt(tax.tax_amount_after_discount_amount), "code_jour": code_jour, "cost_center": tax.cost_center }, account_currency) )
def make_regional_gl_entries(gl_entries, doc): country = frappe.get_cached_value('Company', doc.company, 'country') if country != 'India': return gl_entries gst_tax, base_gst_tax = get_gst_tax_amount(doc) if not base_gst_tax: return gl_entries if doc.reverse_charge == 'Y': gst_accounts = get_gst_accounts(doc.company) gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \ + gst_accounts.get('igst_account') for tax in doc.get('taxes'): if tax.category not in ("Total", "Valuation and Total"): continue dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit" if flt(tax.base_tax_amount_after_discount_amount ) and tax.account_head in gst_account_list: account_currency = get_account_currency(tax.account_head) gl_entries.append(doc.get_gl_dict( { "account": tax.account_head, "cost_center": tax.cost_center, "posting_date": doc.posting_date, "against": doc.supplier, dr_or_cr: tax.base_tax_amount_after_discount_amount, dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ if account_currency==doc.company_currency \ else tax.tax_amount_after_discount_amount }, account_currency, item=tax) ) return gl_entries
def _book_deferred_revenue_or_expense(item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on): start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date) if not (start_date and end_date): return account_currency = get_account_currency(item.expense_account) if doc.doctype == "Sales Invoice": against, project = doc.customer, doc.project credit_account, debit_account = item.income_account, item.deferred_revenue_account else: against, project = doc.supplier, item.project credit_account, debit_account = item.deferred_expense_account, item.expense_account total_days = date_diff(item.service_end_date, item.service_start_date) + 1 total_booking_days = date_diff(end_date, start_date) + 1 if book_deferred_entries_based_on == 'Months': amount, base_amount = calculate_monthly_amount(doc, item, last_gl_entry, start_date, end_date, total_days, total_booking_days, account_currency) else: amount, base_amount = calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, account_currency) if not amount: return if via_journal_entry: book_revenue_via_journal_entry(doc, credit_account, debit_account, against, amount, base_amount, end_date, project, account_currency, item.cost_center, item, deferred_process, submit_journal_entry) else: make_gl_entries(doc, credit_account, debit_account, against, amount, base_amount, end_date, project, account_currency, item.cost_center, item, deferred_process) # Returned in case of any errors because it tries to submit the same record again and again in case of errors if frappe.flags.deferred_accounting_error: return if getdate(end_date) < getdate(posting_date) and not last_gl_entry: _book_deferred_revenue_or_expense(item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on)
def get_payment_entry_against_order(dt, dn): ref_doc = frappe.get_doc(dt, dn) if flt(ref_doc.per_billed, 2) > 0: frappe.throw( _("Can only make payment against unbilled {0}").format(dt)) if dt == "Sales Order": party_type = "Customer" amount_field_party = "credit_in_account_currency" amount_field_bank = "debit_in_account_currency" else: party_type = "Supplier" amount_field_party = "debit_in_account_currency" amount_field_bank = "credit_in_account_currency" party_account = get_party_account(party_type, ref_doc.get(party_type.lower()), ref_doc.company) party_account_currency = get_account_currency(party_account) if party_account_currency == ref_doc.company_currency: amount = flt(ref_doc.base_grand_total) - flt(ref_doc.advance_paid) else: amount = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) return get_payment_entry( ref_doc, { "party_type": party_type, "party_account": party_account, "party_account_currency": party_account_currency, "amount_field_party": amount_field_party, "amount_field_bank": amount_field_bank, "amount": amount, "remarks": 'Advance Payment received against {0} {1}'.format( dt, dn), "is_advance": "Yes" })
def get_party_details(company, party_type, party, date, cost_center=None): bank_account = '' if not frappe.db.exists(party_type, party): frappe.throw(_("Invalid {0}: {1}").format(party_type, party)) party_account = get_party_account(party_type, party, company) account_currency = get_account_currency(party_account) account_balance = get_balance_on(party_account, date, cost_center=cost_center) _party_name = "title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name" party_name = frappe.db.get_value(party_type, party, _party_name) party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center) if party_type in ["Customer", "Supplier"]: bank_account = get_party_bank_account(party_type, party) return { "party_account": party_account, "party_name": party_name, "party_account_currency": account_currency, "party_balance": party_balance, "account_balance": account_balance, "bank_account": bank_account }
def set_account_currency(filters): if not (filters.get("account") or filters.get("party")): return filters else: filters["company_currency"] = frappe.db.get_value("Company", filters.company, "default_currency") account_currency = None if filters.get("account"): account_currency = get_account_currency(filters.account) elif filters.get("party"): gle_currency = frappe.db.get_value("GL Entry", {"party_type": filters.party_type, "party": filters.party, "company": filters.company}, "account_currency") if gle_currency: account_currency = gle_currency else: account_currency = frappe.db.get_value(filters.party_type, filters.party, "default_currency") filters["account_currency"] = account_currency or filters.company_currency if filters.account_currency != filters.company_currency: filters["show_in_account_currency"] = 1 return filters
def get_against_voucher_amount(against_voucher_type, against_voucher_no, party_account, company): party_account_currency = get_account_currency(party_account) company_currency = frappe.db.get_value("Company", company, "default_currency") ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" if against_voucher_type in ["Sales Order", "Purchase Order"]: select_cond = "{0} as total_amount, {0} - advance_paid as outstanding_amount"\ .format(ref_field) elif against_voucher_type in ["Sales Invoice", "Purchase Invoice"]: select_cond = "{0} as total_amount, outstanding_amount".format( ref_field) elif against_voucher_type == "Journal Entry": ref_field = "total_debit" if party_account_currency == company_currency else "total_debit/exchange_rate" select_cond = "{0} as total_amount".format(ref_field) details = frappe.db.sql( """select {0} from `tab{1}` where name = %s""".format( select_cond, frappe.db.escape(against_voucher_type)), against_voucher_no, as_dict=1) return details[0] if details else {}
def get_gl_dict(company, posting_date, fiscal_year, args, account_currency=None): """this method populates the common properties of a gl entry record""" fiscal_years = get_fiscal_years(posting_date, company=company) if len(fiscal_years) > 1: frappe.throw( _("Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year" ).format(formatdate(self.posting_date))) else: fiscal_year = fiscal_years[0][0] gl_dict = frappe._dict({ 'company': company, 'posting_date': posting_date, 'fiscal_year': fiscal_year, 'voucher_type': "Period Closing Voucher", 'voucher_no': "Vc", 'remarks': "period closing", 'debit': 0, 'credit': 0, 'debit_in_account_currency': 0, 'credit_in_account_currency': 0, 'is_opening': "No", 'party_type': None, 'party': None }) gl_dict.update(args) if not account_currency: account_currency = get_account_currency(gl_dict.account) return gl_dict
def get_gl_entries(self, warehouse_account=None): from erpnext.accounts.general_ledger import process_gl_map stock_rbnb = self.get_company_default("stock_received_but_not_billed") expenses_included_in_valuation = self.get_company_default( "expenses_included_in_valuation") gl_entries = [] warehouse_with_no_account = [] negative_expense_to_be_booked = 0.0 stock_items = self.get_stock_items() for d in self.get("items"): if d.item_code in stock_items and flt(d.valuation_rate) and flt( d.qty): if warehouse_account.get(d.warehouse): stock_value_diff = frappe.db.get_value( "Stock Ledger Entry", { "voucher_type": "Purchase Receipt", "voucher_no": self.name, "voucher_detail_no": d.name, "warehouse": d.warehouse }, "stock_value_difference") if not stock_value_diff: continue gl_entries.append( self.get_gl_dict( { "account": warehouse_account[d.warehouse]["account"], "against": stock_rbnb, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": stock_value_diff }, warehouse_account[d.warehouse] ["account_currency"])) # stock received but not billed stock_rbnb_currency = get_account_currency(stock_rbnb) gl_entries.append(self.get_gl_dict({ "account": stock_rbnb, "against": warehouse_account[d.warehouse]["account"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(d.base_net_amount, d.precision("base_net_amount")), "credit_in_account_currency": flt(d.base_net_amount, d.precision("base_net_amount")) \ if stock_rbnb_currency==self.company_currency else flt(d.net_amount, d.precision("net_amount")) }, stock_rbnb_currency)) negative_expense_to_be_booked += flt(d.item_tax_amount) # Amount added through landed-cost-voucher if flt(d.landed_cost_voucher_amount): gl_entries.append( self.get_gl_dict({ "account": expenses_included_in_valuation, "against": warehouse_account[d.warehouse]["account"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(d.landed_cost_voucher_amount), "project": d.project })) # sub-contracting warehouse if flt(d.rm_supp_cost) and warehouse_account.get( self.supplier_warehouse): gl_entries.append( self.get_gl_dict( { "account": warehouse_account[ self.supplier_warehouse]["account"], "against": warehouse_account[d.warehouse]["account"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(d.rm_supp_cost) }, warehouse_account[self.supplier_warehouse] ["account_currency"])) # divisional loss adjustment valuation_amount_as_per_doc = flt(d.base_net_amount, d.precision("base_net_amount")) + \ flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount) divisional_loss = flt( valuation_amount_as_per_doc - stock_value_diff, d.precision("base_net_amount")) if divisional_loss: if self.is_return or flt(d.item_tax_amount): loss_account = expenses_included_in_valuation else: loss_account = stock_rbnb gl_entries.append( self.get_gl_dict( { "account": loss_account, "against": warehouse_account[d.warehouse]["account"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": divisional_loss, "project": d.project }, stock_rbnb_currency)) elif d.warehouse not in warehouse_with_no_account or \ d.rejected_warehouse not in warehouse_with_no_account: warehouse_with_no_account.append(d.warehouse) if not is_cwip_accounting_disabled(): self.get_asset_gl_entry(gl_entries) # Cost center-wise amount breakup for other charges included for valuation valuation_tax = {} for tax in self.get("taxes"): if tax.category in ("Valuation", "Valuation and Total") and flt( tax.base_tax_amount_after_discount_amount): if not tax.cost_center: frappe.throw( _("Cost Center is required in row {0} in Taxes table for type {1}" ).format(tax.idx, _(tax.category))) valuation_tax.setdefault(tax.cost_center, 0) valuation_tax[tax.cost_center] += \ (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) if negative_expense_to_be_booked and valuation_tax: # Backward compatibility: # If expenses_included_in_valuation account has been credited in against PI # and charges added via Landed Cost Voucher, # post valuation related charges on "Stock Received But Not Billed" negative_expense_booked_in_pi = frappe.db.sql( """select name from `tabPurchase Invoice Item` pi where docstatus = 1 and purchase_receipt=%s and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=pi.parent and account=%s)""", (self.name, expenses_included_in_valuation)) if negative_expense_booked_in_pi: expenses_included_in_valuation = stock_rbnb against_account = ", ".join( [d.account for d in gl_entries if flt(d.debit) > 0]) total_valuation_amount = sum(valuation_tax.values()) amount_including_divisional_loss = negative_expense_to_be_booked i = 1 for cost_center, amount in iteritems(valuation_tax): if i == len(valuation_tax): applicable_amount = amount_including_divisional_loss else: applicable_amount = negative_expense_to_be_booked * ( amount / total_valuation_amount) amount_including_divisional_loss -= applicable_amount gl_entries.append( self.get_gl_dict({ "account": expenses_included_in_valuation, "cost_center": cost_center, "credit": applicable_amount, "remarks": self.remarks or _("Accounting Entry for Stock"), "against": against_account })) i += 1 if warehouse_with_no_account: frappe.msgprint( _("No accounting entries for the following warehouses") + ": \n" + "\n".join(warehouse_with_no_account)) return process_gl_map(gl_entries)
def get_payment_entry(ref_doc, args): cost_center = frappe.db.get_value("Company", ref_doc.company, "cost_center") exchange_rate = 1 if args.get("party_account"): exchange_rate = get_exchange_rate(args.get("party_account"), args.get("party_account_currency"), ref_doc.company, ref_doc.doctype, ref_doc.name) je = frappe.new_doc("Journal Entry") je.update({ "voucher_type": "Bank Entry", "company": ref_doc.company, "remark": args.get("remarks") }) party_row = je.append("accounts", { "account": args.get("party_account"), "party_type": args.get("party_type"), "party": ref_doc.get(args.get("party_type").lower()), "cost_center": cost_center, "account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"), "account_currency": args.get("party_account_currency") or \ get_account_currency(args.get("party_account")), "balance": get_balance_on(args.get("party_account")), "party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")), "exchange_rate": exchange_rate, args.get("amount_field_party"): args.get("amount"), "is_advance": args.get("is_advance"), "reference_type": ref_doc.doctype, "reference_name": ref_doc.name }) bank_row = je.append("accounts") #make it bank_details bank_account = get_default_bank_cash_account( ref_doc.company, "Bank Entry", account=args.get("bank_account")) if bank_account: bank_row.update(bank_account) bank_row.exchange_rate = get_exchange_rate( bank_account["account"], bank_account["account_currency"], ref_doc.company) bank_row.cost_center = cost_center amount = args.get("debit_in_account_currency") or args.get("amount") if bank_row.account_currency == args.get("party_account_currency"): bank_row.set(args.get("amount_field_bank"), amount) else: bank_row.set(args.get("amount_field_bank"), amount * exchange_rate) # set multi currency check if party_row.account_currency != ref_doc.company_currency \ or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency): je.multi_currency = 1 je.set_amounts_in_company_currency() je.set_total_debit_credit() return je if args.get("journal_entry") else je.as_dict()
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None): doc = frappe.get_doc(dt, dn) if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0: frappe.throw( _("Can only make payment against unbilled {0}").format(dt)) if dt in ("Sales Invoice", "Sales Order"): party_type = "Customer" elif dt in ("Purchase Invoice", "Purchase Order"): party_type = "Supplier" elif dt in ("Expense Claim", "Employee Advance"): party_type = "Employee" elif dt in ("Fees"): party_type = "Student" # party account if dt == "Sales Invoice": party_account = doc.debit_to elif dt == "Purchase Invoice": party_account = doc.credit_to elif dt == "Fees": party_account = doc.receivable_account elif dt == "Employee Advance": party_account = doc.advance_account elif dt == "Expense Claim": party_account = doc.payable_account else: party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company) party_account_currency = doc.get( "party_account_currency") or get_account_currency(party_account) # payment type if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \ or (dt=="Purchase Invoice" and doc.outstanding_amount < 0): payment_type = "Receive" else: payment_type = "Pay" # amounts grand_total = outstanding_amount = 0 if party_amount: grand_total = outstanding_amount = party_amount elif dt in ("Sales Invoice", "Purchase Invoice"): if party_account_currency == doc.company_currency: grand_total = doc.base_rounded_total or doc.base_grand_total else: grand_total = doc.rounded_total or doc.grand_total outstanding_amount = doc.outstanding_amount elif dt in ("Expense Claim"): grand_total = doc.total_sanctioned_amount outstanding_amount = doc.total_sanctioned_amount \ - doc.total_amount_reimbursed - flt(doc.total_advance_amount) elif dt == "Employee Advance": grand_total = doc.advance_amount outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount) elif dt == "Fees": grand_total = doc.grand_total outstanding_amount = doc.outstanding_amount else: if party_account_currency == doc.company_currency: grand_total = flt( doc.get("base_rounded_total") or doc.base_grand_total) else: grand_total = flt(doc.get("rounded_total") or doc.grand_total) outstanding_amount = grand_total - flt(doc.advance_paid) # bank or cash bank = get_default_bank_cash_account( doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), account=bank_account) paid_amount = received_amount = 0 if party_account_currency == bank.account_currency: paid_amount = received_amount = abs(outstanding_amount) elif payment_type == "Receive": paid_amount = abs(outstanding_amount) if bank_amount: received_amount = bank_amount else: received_amount = abs(outstanding_amount) if bank_amount: paid_amount = bank_amount pe = frappe.new_doc("Payment Entry") pe.payment_type = payment_type pe.company = doc.company pe.posting_date = nowdate() pe.mode_of_payment = doc.get("mode_of_payment") pe.party_type = party_type pe.party = doc.get(scrub(party_type)) pe.ensure_supplier_is_not_blocked() pe.paid_from = party_account if payment_type == "Receive" else bank.account pe.paid_to = party_account if payment_type == "Pay" else bank.account pe.paid_from_account_currency = party_account_currency \ if payment_type=="Receive" else bank.account_currency pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency pe.paid_amount = paid_amount pe.received_amount = received_amount pe.allocate_payment_amount = 1 pe.letter_head = doc.get("letter_head") # only Purchase Invoice can be blocked individually if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked(): frappe.msgprint( _('{0} is on hold till {1}'.format(doc.name, doc.release_date))) else: pe.append( "references", { 'reference_doctype': dt, 'reference_name': dn, "bill_no": doc.get("bill_no"), "due_date": doc.get("due_date"), 'total_amount': grand_total, 'outstanding_amount': outstanding_amount, 'allocated_amount': outstanding_amount }) pe.setup_party_account_field() pe.set_missing_values() if party_account and bank: pe.set_exchange_rate() pe.set_amounts() return pe
def get_outstanding_reference_documents(args): if isinstance(args, string_types): args = json.loads(args) # confirm that Supplier is not blocked if args.get('party_type') == 'Supplier': supplier_status = get_supplier_block_status(args['party']) if supplier_status['on_hold']: if supplier_status['hold_type'] == 'All': return [] elif supplier_status['hold_type'] == 'Payments': if not supplier_status['release_date'] or getdate( nowdate()) <= supplier_status['release_date']: return [] party_account_currency = get_account_currency(args.get("party_account")) company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") # Get negative outstanding sales /purchase invoices negative_outstanding_invoices = [] if args.get("party_type") not in ["Student", "Employee" ] and not args.get("voucher_no"): negative_outstanding_invoices = get_negative_outstanding_invoices( args.get("party_type"), args.get("party"), args.get("party_account"), party_account_currency, company_currency) # Get positive outstanding sales /purchase invoices/ Fees condition = "" if args.get("voucher_type") and args.get("voucher_no"): condition = " and voucher_type='{0}' and voucher_no='{1}'"\ .format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"])) outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"), condition=condition) for d in outstanding_invoices: d["exchange_rate"] = 1 if party_account_currency != company_currency: if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"): d["exchange_rate"] = frappe.db.get_value( d.voucher_type, d.voucher_no, "conversion_rate") elif d.voucher_type == "Journal Entry": d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, d.posting_date) if d.voucher_type in ("Purchase Invoice"): d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") # Get all SO / PO which are not fully billed or aginst which full advance not paid orders_to_be_billed = [] if (args.get("party_type") != "Student"): orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"), args.get("party_type"), args.get("party"), party_account_currency, company_currency) return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def make_tax_gl_entries(self, gl_entries): # tax table gl entries valuation_tax = {} for tax in self.get("taxes"): if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): account_currency = get_account_currency(tax.account_head) dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.supplier, dr_or_cr: tax.base_tax_amount_after_discount_amount, dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ if account_currency==self.company_currency \ else tax.tax_amount_after_discount_amount, "cost_center": tax.cost_center }, account_currency) ) # accumulate valuation tax if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): if self.auto_accounting_for_stock and not tax.cost_center: frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) valuation_tax.setdefault(tax.cost_center, 0) valuation_tax[tax.cost_center] += \ (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax: # credit valuation tax amount in "Expenses Included In Valuation" # this will balance out valuation amount included in cost of goods sold total_valuation_amount = sum(valuation_tax.values()) amount_including_divisional_loss = self.negative_expense_to_be_booked i = 1 for cost_center, amount in iteritems(valuation_tax): if i == len(valuation_tax): applicable_amount = amount_including_divisional_loss else: applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount) amount_including_divisional_loss -= applicable_amount gl_entries.append( self.get_gl_dict({ "account": self.expenses_included_in_valuation, "cost_center": cost_center, "against": self.supplier, "credit": applicable_amount, "remarks": self.remarks or "Accounting Entry for Stock" }) ) i += 1 if self.auto_accounting_for_stock and self.update_stock and valuation_tax: for cost_center, amount in iteritems(valuation_tax): gl_entries.append( self.get_gl_dict({ "account": self.expenses_included_in_valuation, "cost_center": cost_center, "against": self.supplier, "credit": amount, "remarks": self.remarks or "Accounting Entry for Stock" }) )