From 46bcbaf97b11f4a4030747e1c87171e18d9c58f5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 19 Aug 2015 13:49:10 +0530 Subject: [PATCH] GL Entry in account currency --- .../doctype/journal_entry/journal_entry.py | 1 - .../purchase_invoice/purchase_invoice.py | 20 ++++--- .../doctype/sales_invoice/sales_invoice.py | 59 ++++++++++++------- erpnext/controllers/accounts_controller.py | 24 +++++++- erpnext/controllers/stock_controller.py | 21 ++++--- .../purchase_receipt/purchase_receipt.py | 31 ++++++---- 6 files changed, 102 insertions(+), 54 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 315685da8fe..ebdd7293358 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -13,7 +13,6 @@ from erpnext.accounts.utils import get_balance_on class JournalEntry(AccountsController): def __init__(self, arg1, arg2=None): super(JournalEntry, self).__init__(arg1, arg2) - self.company_currency = get_company_currency(self.company) def get_feed(self): return self.voucher_type diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 132cb1027d6..fca96c218fb 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -254,7 +254,6 @@ class PurchaseInvoice(BuyingController): "party": self.supplier, "against": self.against_expense_account, "credit": self.total_amount_to_pay, - "remarks": self.remarks, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, }) @@ -264,15 +263,20 @@ class PurchaseInvoice(BuyingController): 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 = frappe.db.get_value("Account", tax.account_head, "currency") + + 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, - "debit": tax.add_deduct_tax == "Add" and tax.base_tax_amount_after_discount_amount or 0, - "credit": tax.add_deduct_tax == "Deduct" and tax.base_tax_amount_after_discount_amount or 0, - "remarks": self.remarks, + 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 @@ -288,14 +292,15 @@ class PurchaseInvoice(BuyingController): stock_items = self.get_stock_items() for item in self.get("items"): if flt(item.base_net_amount): + account_currency = frappe.db.get_value("Account", item.expense_account, "currency") gl_entries.append( self.get_gl_dict({ "account": item.expense_account, "against": self.supplier, "debit": item.base_net_amount, - "remarks": self.remarks, + "debit_in_account_currency": item.net_amount, "cost_center": item.cost_center - }) + }, account_currency) ) if auto_accounting_for_stock and self.is_opening == "No" and \ @@ -353,7 +358,6 @@ class PurchaseInvoice(BuyingController): "account": self.write_off_account, "against": self.supplier, "credit": flt(self.write_off_amount), - "remarks": self.remarks, "cost_center": self.write_off_cost_center }) ) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index f82590a6094..7298b43d2b4 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -468,8 +468,10 @@ class SalesInvoice(SellingController): from erpnext.accounts.general_ledger import merge_similar_entries gl_entries = [] + + customer_account_currency = frappe.db.get_value("Account", self.debit_to, "currency") - self.make_customer_gl_entry(gl_entries) + self.make_customer_gl_entry(gl_entries, customer_account_currency) self.make_tax_gl_entries(gl_entries) @@ -478,14 +480,14 @@ class SalesInvoice(SellingController): # merge gl entries before adding pos entries gl_entries = merge_similar_entries(gl_entries) - self.make_pos_gl_entries(gl_entries) + self.make_pos_gl_entries(gl_entries, customer_account_currency) - self.make_write_off_gl_entry(gl_entries) + self.make_write_off_gl_entry(gl_entries, customer_account_currency) return gl_entries - def make_customer_gl_entry(self, gl_entries): - if self.base_grand_total: + def make_customer_gl_entry(self, gl_entries, customer_account_currency): + if self.grand_total: gl_entries.append( self.get_gl_dict({ "account": self.debit_to, @@ -493,37 +495,42 @@ class SalesInvoice(SellingController): "party": self.customer, "against": self.against_income_account, "debit": self.base_grand_total, - "remarks": self.remarks, + "debit_in_account_currency": self.base_grand_total \ + if customer_account_currency==self.company_currency else self.grand_total, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype - }) + }, customer_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 = frappe.db.get_value("Account", tax.account_head, "currency") gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.customer, "credit": flt(tax.base_tax_amount_after_discount_amount), - "remarks": self.remarks, + "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 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 = frappe.db.get_value("Account", item.income_account, "currency") gl_entries.append( self.get_gl_dict({ "account": item.income_account, "against": self.customer, "credit": item.base_net_amount, - "remarks": self.remarks, + "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 @@ -531,8 +538,11 @@ class SalesInvoice(SellingController): and cint(self.update_stock): gl_entries += super(SalesInvoice, self).get_gl_entries() - def make_pos_gl_entries(self, gl_entries): + def make_pos_gl_entries(self, gl_entries, customer_account_currency): if cint(self.is_pos) and self.cash_bank_account and self.paid_amount: + bank_account_currency = frappe.db.get_value("Account", self.cash_bank_account, "currency") + paid_amount_in_account_currency = self.paid_amount if bank_account_currency==self.company_currency \ + else flt(self.paid_amount/self.conversion_rate, self.precision("paid_amount")) # POS, make payment entries gl_entries.append( self.get_gl_dict({ @@ -541,23 +551,28 @@ class SalesInvoice(SellingController): "party": self.customer, "against": self.cash_bank_account, "credit": self.paid_amount, - "remarks": self.remarks, + "credit_in_account_currency": paid_amount_in_account_currency, "against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher_type": self.doctype, - }) + }, customer_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.cash_bank_account, "against": self.customer, "debit": self.paid_amount, - "remarks": self.remarks, - }) + "debit_in_account_currency": paid_amount_in_account_currency + }, bank_account_currency) ) - def make_write_off_gl_entry(self, gl_entries): + def make_write_off_gl_entry(self, gl_entries, customer_account_currency): # write off entries, applicable if only pos if self.write_off_account and self.write_off_amount: + write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "currency") + write_off_amount_in_account_currency = self.write_off_amount \ + if write_off_account_currency==self.company_currency \ + else flt(self.write_off_amount/self.conversion_rate, self.precision("write_off_amount")) + gl_entries.append( self.get_gl_dict({ "account": self.debit_to, @@ -565,19 +580,19 @@ class SalesInvoice(SellingController): "party": self.customer, "against": self.write_off_account, "credit": self.write_off_amount, - "remarks": self.remarks, + "credit_in_account_currency": write_off_amount_in_account_currency, "against_voucher": self.return_against if cint(self.is_return) else self.name, - "against_voucher_type": self.doctype, - }) + "against_voucher_type": self.doctype + }, customer_account_currency) ) gl_entries.append( self.get_gl_dict({ "account": self.write_off_account, "against": self.customer, "debit": self.write_off_amount, - "remarks": self.remarks, + "debit_in_account_currency": write_off_amount_in_account_currency, "cost_center": self.write_off_cost_center - }) + }, write_off_account_currency) ) def get_list_context(context=None): diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index c7600dfaeac..7aacf735ebe 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -16,6 +16,11 @@ force_item_fields = ("item_group", "barcode", "brand", "stock_uom") class CustomerFrozen(frappe.ValidationError): pass class AccountsController(TransactionBase): + def __init__(self, arg1, arg2=None): + super(AccountsController, self).__init__(arg1, arg2) + + self.company_currency = get_company_currency(self.company) + def validate(self): if self.get("_action") and self._action != "update_after_submit": self.set_missing_values(for_validate=True) @@ -187,7 +192,7 @@ class AccountsController(TransactionBase): if frappe.db.get_value(taxes_and_charges_doctype, self.taxes_and_charges, "disabled"): frappe.throw(_("{0} '{1}' is disabled").format(taxes_and_charges_doctype, self.taxes_and_charges)) - def get_gl_dict(self, args): + 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, @@ -198,11 +203,28 @@ class AccountsController(TransactionBase): '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 = frappe.db.get_value("Account", gl_dict.account, "currency") + + gl_dict["currency"] = self.company_currency if account_currency==self.company_currency else self.currency + + # set debit/credit in account currency if not provided + if flt(gl_dict.debit) and not flt(gl_dict.debit_in_account_currency): + gl_dict.debit_in_account_currency = gl_dict.debit if account_currency==self.company_currency \ + else flt(gl_dict.debit / (self.get("conversion_rate") or 1), 2) + + if flt(gl_dict.credit) and not flt(gl_dict.credit_in_account_currency): + gl_dict.credit_in_account_currency = gl_dict.credit if account_currency==self.company_currency \ + else flt(gl_dict.credit / (self.get("conversion_rate") or 1), 2) + return gl_dict def clear_unallocated_advances(self, childtype, parentfield): diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index cfde04b5720..425aadd27b7 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -48,22 +48,22 @@ class StockController(AccountsController): # from warehouse account self.check_expense_account(detail) - + gl_list.append(self.get_gl_dict({ - "account": warehouse_account[sle.warehouse], + "account": warehouse_account[sle.warehouse]["name"], "against": detail.expense_account, "cost_center": detail.cost_center, "remarks": self.get("remarks") or "Accounting Entry for Stock", - "debit": flt(sle.stock_value_difference, 2) - })) + "debit": flt(sle.stock_value_difference, 2), + }, warehouse_account[sle.warehouse]["currency"])) - # to target warehouse / expense account + # to target warehouse / expense account gl_list.append(self.get_gl_dict({ "account": detail.expense_account, - "against": warehouse_account[sle.warehouse], + "against": warehouse_account[sle.warehouse]["name"], "cost_center": detail.cost_center, "remarks": self.get("remarks") or "Accounting Entry for Stock", - "credit": flt(sle.stock_value_difference, 2) + "credit": flt(sle.stock_value_difference, 2), })) elif sle.warehouse not in warehouse_with_no_account: warehouse_with_no_account.append(sle.warehouse) @@ -316,6 +316,9 @@ def get_voucherwise_gl_entries(future_stock_vouchers, posting_date): return gl_entries def get_warehouse_account(): - warehouse_account = dict(frappe.db.sql("""select warehouse, name from tabAccount - where account_type = 'Warehouse' and ifnull(warehouse, '') != ''""")) + warehouse_account = frappe._dict() + + for d in frappe.db.sql("""select warehouse, name, currency from tabAccount + where account_type = 'Warehouse' and ifnull(warehouse, '') != ''""", as_dict=1): + warehouse_account.setdefault(d.warehouse, d) return warehouse_account diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 53233ce777e..759b7a767a7 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -293,23 +293,28 @@ class PurchaseReceipt(BuyingController): val_rate_db_precision = 6 if cint(d.precision("valuation_rate")) <= 6 else 9 # warehouse account + stock_value_diff = flt(flt(d.valuation_rate, val_rate_db_precision) * flt(d.qty) + * flt(d.conversion_factor), d.precision("base_net_amount")) + gl_entries.append(self.get_gl_dict({ - "account": warehouse_account[d.warehouse], + "account": warehouse_account[d.warehouse]["name"], "against": stock_rbnb, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), - "debit": flt(flt(d.valuation_rate, val_rate_db_precision) * flt(d.qty) * flt(d.conversion_factor), - self.precision("base_net_amount", d)) - })) + "debit": stock_value_diff + }, warehouse_account[d.warehouse]["currency"])) # stock received but not billed + stock_rbnb_currency = frappe.db.get_value("Account", stock_rbnb, "currency") gl_entries.append(self.get_gl_dict({ "account": stock_rbnb, - "against": warehouse_account[d.warehouse], + "against": warehouse_account[d.warehouse]["name"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), - "credit": flt(d.base_net_amount, self.precision("base_net_amount", d)) - })) + "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.currency else flt(d.net_amount, d.precision("net_amount")) + }, stock_rbnb_currency)) negative_expense_to_be_booked += flt(d.item_tax_amount) @@ -317,7 +322,7 @@ class PurchaseReceipt(BuyingController): if flt(d.landed_cost_voucher_amount): gl_entries.append(self.get_gl_dict({ "account": expenses_included_in_valuation, - "against": warehouse_account[d.warehouse], + "against": warehouse_account[d.warehouse]["name"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(d.landed_cost_voucher_amount) @@ -326,12 +331,12 @@ class PurchaseReceipt(BuyingController): # 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], - "against": warehouse_account[d.warehouse], + "account": warehouse_account[self.supplier_warehouse]["name"], + "against": warehouse_account[d.warehouse]["name"], "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]["currency"])) # divisional loss adjustment if not self.get("taxes"): @@ -345,11 +350,11 @@ class PurchaseReceipt(BuyingController): if divisional_loss: gl_entries.append(self.get_gl_dict({ "account": stock_rbnb, - "against": warehouse_account[d.warehouse], + "against": warehouse_account[d.warehouse]["name"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": divisional_loss - })) + }, stock_rbnb_currency)) elif d.warehouse not in warehouse_with_no_account or \ d.rejected_warehouse not in warehouse_with_no_account: