From 6e439a5e5383662b9715b853ec84ec38875122ee Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 28 Aug 2015 19:24:22 +0530 Subject: [PATCH] Multi currency: test case and fixes --- erpnext/accounts/doctype/account/account.json | 41 +++++++- erpnext/accounts/doctype/account/account.py | 6 +- .../accounts/doctype/account/test_account.py | 52 +++++----- .../accounts/doctype/gl_entry/gl_entry.json | 46 ++++++++- erpnext/accounts/doctype/gl_entry/gl_entry.py | 28 +++--- .../doctype/gl_entry/test_gl_entry.py | 2 +- .../doctype/journal_entry/journal_entry.js | 8 +- .../doctype/journal_entry/journal_entry.py | 63 +++++++----- .../journal_entry/test_journal_entry.py | 75 +++++++++++--- .../doctype/journal_entry/test_records.json | 28 +++--- .../journal_entry_account.json | 6 +- .../doctype/payment_tool/payment_tool.py | 6 +- .../doctype/payment_tool/test_payment_tool.py | 24 ++--- .../test_period_closing_voucher.py | 4 +- .../purchase_invoice/purchase_invoice.py | 6 +- .../purchase_invoice/test_purchase_invoice.py | 50 ++++++++++ .../doctype/sales_invoice/sales_invoice.json | 4 +- .../doctype/sales_invoice/sales_invoice.py | 24 ++--- .../sales_invoice/test_sales_invoice.py | 97 ++++++++++++++++--- .../page/accounts_browser/accounts_browser.js | 2 +- .../buying/doctype/supplier/test_records.json | 14 ++- erpnext/controllers/accounts_controller.py | 72 +++++++------- erpnext/controllers/stock_controller.py | 4 +- erpnext/patches/v6_0/multi_currency.py | 2 +- .../selling/doctype/customer/customer.json | 4 +- .../doctype/customer/test_records.json | 16 ++- .../setup/doctype/company/test_records.json | 2 +- .../purchase_receipt/purchase_receipt.py | 8 +- 28 files changed, 495 insertions(+), 199 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json index 82c9c6622c..737b07ee20 100644 --- a/erpnext/accounts/doctype/account/account.json +++ b/erpnext/accounts/doctype/account/account.json @@ -11,6 +11,8 @@ "fields": [ { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "properties", "fieldtype": "Section Break", "hidden": 0, @@ -31,6 +33,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "column_break0", "fieldtype": "Column Break", "hidden": 0, @@ -50,6 +54,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "account_name", "fieldtype": "Data", "hidden": 0, @@ -71,6 +77,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "default": "0", "fieldname": "is_group", "fieldtype": "Check", @@ -92,6 +100,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, @@ -114,6 +124,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "root_type", "fieldtype": "Select", "hidden": 0, @@ -134,6 +146,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "report_type", "fieldtype": "Select", "hidden": 0, @@ -154,7 +168,10 @@ }, { "allow_on_submit": 0, - "fieldname": "currency", + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.is_group==0", + "fieldname": "account_currency", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -175,6 +192,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "column_break1", "fieldtype": "Column Break", "hidden": 0, @@ -194,6 +213,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "parent_account", "fieldtype": "Link", "hidden": 0, @@ -216,6 +237,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "description": "", "fieldname": "account_type", "fieldtype": "Select", @@ -239,6 +262,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "description": "Rate at which this tax is applied", "fieldname": "tax_rate", "fieldtype": "Float", @@ -261,6 +286,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "description": "If the account is frozen, entries are allowed to restricted users.", "fieldname": "freeze_account", "fieldtype": "Select", @@ -284,6 +311,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "warehouse", "fieldtype": "Link", "hidden": 0, @@ -304,6 +333,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "balance_must_be", "fieldtype": "Select", "hidden": 0, @@ -324,6 +355,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "lft", "fieldtype": "Int", "hidden": 1, @@ -343,6 +376,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "rgt", "fieldtype": "Int", "hidden": 1, @@ -362,6 +397,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "old_parent", "fieldtype": "Data", "hidden": 1, @@ -389,7 +426,7 @@ "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-08-13 16:43:10.645538", + "modified": "2015-08-28 17:17:20.899845", "modified_by": "Administrator", "module": "Accounts", "name": "Account", diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index a57cc25920..7f632b11bd 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -89,10 +89,10 @@ class Account(Document): frappe.throw(_("Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'")) def validate_account_currency(self): - if not self.currency: - self.currency = frappe.db.get_value("Company", self.company, "default_currency") + if not self.account_currency: + self.account_currency = frappe.db.get_value("Company", self.company, "default_currency") - elif self.currency != frappe.db.get_value("Account", self.name, "currency"): + elif self.account_currency != frappe.db.get_value("Account", self.name, "account_currency"): if frappe.db.get_value("GL Entry", {"account": self.name}): frappe.throw(_("Currency can not be changed after making entries using some other currency")) diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py index 2a3feda79b..83516dacb9 100644 --- a/erpnext/accounts/doctype/account/test_account.py +++ b/erpnext/accounts/doctype/account/test_account.py @@ -9,36 +9,39 @@ def _make_test_records(verbose): accounts = [ # [account_name, parent_account, is_group] - ["_Test Account Bank Account", "Bank Accounts", 0, "Bank"], + ["_Test Bank", "Bank Accounts", 0, "Bank", None], + ["_Test Bank USD", "Bank Accounts", 0, "Bank", "USD"], + ["_Test Bank EUR", "Bank Accounts", 0, "Bank", "EUR"], - ["_Test Account Stock Expenses", "Direct Expenses", 1, None], - ["_Test Account Shipping Charges", "_Test Account Stock Expenses", 0, "Chargeable"], - ["_Test Account Customs Duty", "_Test Account Stock Expenses", 0, "Tax"], - ["_Test Account Insurance Charges", "_Test Account Stock Expenses", 0, "Chargeable"], - ["_Test Account Stock Adjustment", "_Test Account Stock Expenses", 0, "Stock Adjustment"], + ["_Test Account Stock Expenses", "Direct Expenses", 1, None, None], + ["_Test Account Shipping Charges", "_Test Account Stock Expenses", 0, "Chargeable", None], + ["_Test Account Customs Duty", "_Test Account Stock Expenses", 0, "Tax", None], + ["_Test Account Insurance Charges", "_Test Account Stock Expenses", 0, "Chargeable", None], + ["_Test Account Stock Adjustment", "_Test Account Stock Expenses", 0, "Stock Adjustment", None], + ["_Test Account Tax Assets", "Current Assets", 1, None, None], + ["_Test Account VAT", "_Test Account Tax Assets", 0, "Tax", None], + ["_Test Account Service Tax", "_Test Account Tax Assets", 0, "Tax", None], - ["_Test Account Tax Assets", "Current Assets", 1, None], - ["_Test Account VAT", "_Test Account Tax Assets", 0, "Tax"], - ["_Test Account Service Tax", "_Test Account Tax Assets", 0, "Tax"], + ["_Test Account Reserves and Surplus", "Current Liabilities", 0, None, None], - ["_Test Account Reserves and Surplus", "Current Liabilities", 0, None], - - ["_Test Account Cost for Goods Sold", "Expenses", 0, None], - ["_Test Account Excise Duty", "_Test Account Tax Assets", 0, "Tax"], - ["_Test Account Education Cess", "_Test Account Tax Assets", 0, "Tax"], - ["_Test Account S&H Education Cess", "_Test Account Tax Assets", 0, "Tax"], - ["_Test Account CST", "Direct Expenses", 0, "Tax"], - ["_Test Account Discount", "Direct Expenses", 0, None], - ["_Test Write Off", "Indirect Expenses", 0, None], + ["_Test Account Cost for Goods Sold", "Expenses", 0, None, None], + ["_Test Account Excise Duty", "_Test Account Tax Assets", 0, "Tax", None], + ["_Test Account Education Cess", "_Test Account Tax Assets", 0, "Tax", None], + ["_Test Account S&H Education Cess", "_Test Account Tax Assets", 0, "Tax", None], + ["_Test Account CST", "Direct Expenses", 0, "Tax", None], + ["_Test Account Discount", "Direct Expenses", 0, None, None], + ["_Test Write Off", "Indirect Expenses", 0, None, None], # related to Account Inventory Integration - ["_Test Account Stock In Hand", "Current Assets", 0, None], - ["_Test Account Fixed Assets", "Current Assets", 0, None], + ["_Test Account Stock In Hand", "Current Assets", 0, None, None], + ["_Test Account Fixed Assets", "Current Assets", 0, None, None], # Receivable / Payable Account - ["_Test Receivable", "Current Assets", 0, "Receivable"], - ["_Test Payable", "Current Liabilities", 0, "Payable"], + ["_Test Receivable", "Current Assets", 0, "Receivable", None], + ["_Test Payable", "Current Liabilities", 0, "Payable", None], + ["_Test Receivable USD", "Current Assets", 0, "Receivable", "USD"], + ["_Test Payable USD", "Current Liabilities", 0, "Payable", "USD"] ] for company, abbr in [["_Test Company", "_TC"], ["_Test Company 1", "_TC1"]]: @@ -48,7 +51,8 @@ def _make_test_records(verbose): "parent_account": parent_account + " - " + abbr, "company": company, "is_group": is_group, - "account_type": account_type - } for account_name, parent_account, is_group, account_type in accounts]) + "account_type": account_type, + "account_currency": currency + } for account_name, parent_account, is_group, account_type, currency in accounts]) return test_objects diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index dfe9fc3e5c..23a44aaafd 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -10,6 +10,8 @@ "fields": [ { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -31,6 +33,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "transaction_date", "fieldtype": "Date", "hidden": 0, @@ -52,6 +56,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "account", "fieldtype": "Link", "hidden": 0, @@ -74,6 +80,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "party_type", "fieldtype": "Link", "hidden": 0, @@ -94,6 +102,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "party", "fieldtype": "Dynamic Link", "hidden": 0, @@ -114,6 +124,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "cost_center", "fieldtype": "Link", "hidden": 0, @@ -136,6 +148,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "debit", "fieldtype": "Currency", "hidden": 0, @@ -158,6 +172,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "credit", "fieldtype": "Currency", "hidden": 0, @@ -180,7 +196,9 @@ }, { "allow_on_submit": 0, - "fieldname": "currency", + "bold": 0, + "collapsible": 0, + "fieldname": "account_currency", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -201,6 +219,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "debit_in_account_currency", "fieldtype": "Currency", "hidden": 0, @@ -222,6 +242,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "credit_in_account_currency", "fieldtype": "Currency", "hidden": 0, @@ -243,6 +265,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "against", "fieldtype": "Text", "hidden": 0, @@ -264,6 +288,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "against_voucher_type", "fieldtype": "Link", "hidden": 0, @@ -286,6 +312,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "against_voucher", "fieldtype": "Dynamic Link", "hidden": 0, @@ -308,6 +336,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "voucher_type", "fieldtype": "Link", "hidden": 0, @@ -330,6 +360,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "voucher_no", "fieldtype": "Dynamic Link", "hidden": 0, @@ -352,6 +384,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "remarks", "fieldtype": "Text", "hidden": 0, @@ -373,6 +407,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "is_opening", "fieldtype": "Select", "hidden": 0, @@ -395,6 +431,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "is_advance", "fieldtype": "Select", "hidden": 0, @@ -417,6 +455,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "fiscal_year", "fieldtype": "Link", "hidden": 0, @@ -439,6 +479,8 @@ }, { "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, @@ -469,7 +511,7 @@ "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-08-18 14:25:44.430671", + "modified": "2015-08-28 17:14:52.661217", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index b37b404905..83edf1df55 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -10,6 +10,8 @@ from frappe import _ from frappe.model.document import Document class CustomerFrozen(frappe.ValidationError): pass +class InvalidCurrency(frappe.ValidationError): pass +class InvalidAccountCurrency(frappe.ValidationError): pass class GLEntry(Document): def validate(self): @@ -102,27 +104,31 @@ class GLEntry(Document): def validate_currency(self): company_currency = frappe.db.get_value("Company", self.company, "default_currency") - account_currency = frappe.db.get_value("Account", self.account, "currency") or company_currency + account_currency = frappe.db.get_value("Account", self.account, "account_currency") or company_currency - if not self.currency: - self.currency = company_currency - if account_currency != self.currency: + 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))) + .format(self.account, (account_currency or company_currency)), InvalidAccountCurrency) + if self.party_type and self.party: existing_gle = frappe.db.get_value("GL Entry", {"party_type": self.party_type, - "party": self.party, "company": self.company}, ["name", "currency"], as_dict=1) + "party": self.party, "company": self.company}, ["name", "account_currency"], as_dict=1) if not existing_gle: - party_currency = frappe.db.get_value(self.party_type, self.party, "default_currency") or company_currency + party_currency = frappe.db.get_value(self.party_type, self.party, "default_currency")\ + or company_currency if party_currency != account_currency: frappe.throw(_("Invalid Account {0}. Account Currency must be {1}, same as {2}: {3}") - .format(self.account, party_currency, self.party_type, self.party)) + .format(self.account, party_currency, self.party_type, self.party), + InvalidAccountCurrency) else: - currency_in_existing_entries = existing_gle.currency or company_currency - if currency_in_existing_entries != self.currency: + currency_in_existing_entries = existing_gle.account_currency or company_currency + if currency_in_existing_entries != self.account_currency: frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}") - .format(self.party_type, self.party, currency_in_existing_entries)) + .format(self.party_type, self.party, currency_in_existing_entries), + InvalidAccountCurrency) def validate_balance_type(account, adv_adj=False): if not adv_adj and account: diff --git a/erpnext/accounts/doctype/gl_entry/test_gl_entry.py b/erpnext/accounts/doctype/gl_entry/test_gl_entry.py index 383409cd3b..146d084a11 100644 --- a/erpnext/accounts/doctype/gl_entry/test_gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/test_gl_entry.py @@ -11,7 +11,7 @@ class TestGLEntry(unittest.TestCase): frappe.db.set_value("Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC") jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 100, "_Test Cost Center - _TC", submit=False) + "_Test Bank - _TC", 100, "_Test Cost Center - _TC", submit=False) jv.get("accounts")[0].debit = 100.01 jv.flags.ignore_validate = True diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index e0d580c595..adf4c20c29 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -35,7 +35,7 @@ erpnext.journal_entry.toggle_fields_based_on_currency = function(frm) { var company_currency = erpnext.get_currency(frm.doc.company); var grid = frm.get_field("accounts").grid; - grid.set_column_disp(fields, grid.currency!=company_currency); + grid.set_column_disp(fields, grid.account_currency!=company_currency); } erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ @@ -324,7 +324,7 @@ frappe.ui.form.on("Journal Entry Account", { $.extend(d, r.message[0]); refresh_field('balance', d.name, 'accounts'); refresh_field('party_type', d.name, 'accounts'); - refresh_field('currency', d.name, 'accounts'); + refresh_field('account_currency', d.name, 'accounts'); if(r.message[1] && (!frm.doc.exchange_rate || frm.doc.exchange_rate == 1.0)) { frm.set_value("exchange_rate", r.message[1]) @@ -339,7 +339,7 @@ frappe.ui.form.on("Journal Entry Account", { var company_currency = erpnext.get_currency(frm.doc.company); var row = locals[dt][dn]; - var exchange_rate = (row.currency==company_currency) ? 1 : frm.doc.exchange_rate; + var exchange_rate = (row.account_currency==company_currency) ? 1 : frm.doc.exchange_rate; frappe.model.set_value(dt, dn, "debit", flt(flt(row.debit_in_account_currency)*exchange_rate), precision("debit", row)); @@ -349,7 +349,7 @@ frappe.ui.form.on("Journal Entry Account", { var company_currency = erpnext.get_currency(frm.doc.company); var row = locals[dt][dn]; - var exchange_rate = (row.currency==company_currency) ? 1 : frm.doc.exchange_rate; + var exchange_rate = (row.account_currency==company_currency) ? 1 : frm.doc.exchange_rate; frappe.model.set_value(dt, dn, "credit", flt(flt(row.credit_in_account_currency)*exchange_rate), precision("credit", row)); diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index d61e63a394..57d9f0d37b 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, date_diff +from frappe.utils import cstr, flt, fmt_money, formatdate from frappe import msgprint, _, scrub from erpnext.setup.utils import get_company_currency, get_exchange_rate from erpnext.controllers.accounts_controller import AccountsController @@ -248,13 +248,18 @@ class JournalEntry(AccountsController): self.difference = flt(self.total_debit, self.precision("total_debit")) - \ flt(self.total_credit, self.precision("total_credit")) - print self.difference + if self.difference: frappe.throw(_("Total Debit must be equal to Total Credit. The difference is {0}") .format(self.difference)) def validate_multi_currency(self): - alternate_currency = [d.currency for d in self.get("accounts") if d.currency!=self.company_currency] + alternate_currency = [] + for d in self.get("accounts"): + d.account_currency = frappe.db.get_value("Account", d.account, "account_currency") or self.company_currency + + if d.account_currency!=self.company_currency: + alternate_currency.append(d.account_currency) if alternate_currency: if not self.exchange_rate: @@ -266,10 +271,7 @@ class JournalEntry(AccountsController): self.exchange_rate = 1.0 for d in self.get("accounts"): - if not d.currency: - d.currency = frappe.db.get_value("Account", d.account, "currency") or self.company_currency - - exchange_rate = self.exchange_rate if d.currency != self.company_currency else 1 + exchange_rate = self.exchange_rate if d.account_currency != self.company_currency else 1 d.debit = flt(flt(d.debit_in_account_currency)*exchange_rate, d.precision("debit")) d.credit = flt(flt(d.credit_in_account_currency)*exchange_rate, d.precision("credit")) @@ -340,7 +342,7 @@ class JournalEntry(AccountsController): "against": d.against_account, "debit": flt(d.debit, d.precision("debit")), "credit": flt(d.credit, d.precision("credit")), - "currency": d.currency, + "account_currency": d.account_currency, "debit_in_account_currency": flt(d.debit_in_account_currency, d.precision("debit_in_account_currency")), "credit_in_account_currency": flt(d.credit_in_account_currency, d.precision("credit_in_account_currency")), "against_voucher_type": d.reference_type, @@ -488,12 +490,12 @@ def get_payment_entry_from_sales_invoice(sales_invoice): jv.get("accounts")[0].party = si.customer jv.get("accounts")[0].balance = get_balance_on(si.debit_to) jv.get("accounts")[0].party_balance = get_balance_on(party=si.customer, party_type="Customer") - jv.get("accounts")[0].credit = si.outstanding_amount + jv.get("accounts")[0].credit_in_account_currency = si.outstanding_amount jv.get("accounts")[0].reference_type = si.doctype jv.get("accounts")[0].reference_name = si.name # debit bank - jv.get("accounts")[1].debit = si.outstanding_amount + jv.get("accounts")[1].debit_in_account_currency = si.outstanding_amount return jv.as_dict() @@ -510,12 +512,12 @@ def get_payment_entry_from_purchase_invoice(purchase_invoice): jv.get("accounts")[0].party = pi.supplier jv.get("accounts")[0].balance = get_balance_on(pi.credit_to) jv.get("accounts")[0].party_balance = get_balance_on(party=pi.supplier, party_type="Supplier") - jv.get("accounts")[0].debit = pi.outstanding_amount + jv.get("accounts")[0].debit_in_account_currency = pi.outstanding_amount jv.get("accounts")[0].reference_type = pi.doctype jv.get("accounts")[0].reference_name = pi.name # credit bank - jv.get("accounts")[1].credit = pi.outstanding_amount + jv.get("accounts")[1].credit_in_account_currency = pi.outstanding_amount return jv.as_dict() @@ -524,6 +526,7 @@ 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: @@ -531,9 +534,15 @@ def get_payment_entry_from_sales_order(sales_order): jv = get_payment_entry(so) jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name) + party_account = get_party_account(so.company, so.customer, "Customer") - - amount = flt(so.base_grand_total) - flt(so.advance_paid) + party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") + company_currency = get_company_currency(so.company) + + if party_account_currency == company_currency: + amount = flt(so.base_grand_total) - flt(so.advance_paid) + else: + amount = flt(so.grand_total) - flt(so.advance_paid) # credit customer jv.get("accounts")[0].account = party_account @@ -541,13 +550,13 @@ def get_payment_entry_from_sales_order(sales_order): jv.get("accounts")[0].party = so.customer jv.get("accounts")[0].balance = get_balance_on(party_account) jv.get("accounts")[0].party_balance = get_balance_on(party=so.customer, party_type="Customer") - jv.get("accounts")[0].credit = amount + jv.get("accounts")[0].credit_in_account_currency = amount jv.get("accounts")[0].reference_type = so.doctype jv.get("accounts")[0].reference_name = so.name jv.get("accounts")[0].is_advance = "Yes" # debit bank - jv.get("accounts")[1].debit = amount + jv.get("accounts")[1].debit_in_account_currency = amount return jv.as_dict() @@ -563,9 +572,15 @@ def get_payment_entry_from_purchase_order(purchase_order): jv = get_payment_entry(po) jv.remark = 'Advance payment made against Purchase Order {0}.'.format(po.name) + party_account = get_party_account(po.company, po.supplier, "Supplier") - - amount = flt(po.base_grand_total) - flt(po.advance_paid) + party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") + company_currency = get_company_currency(po.company) + + if party_account_currency == company_currency: + amount = flt(po.base_grand_total) - flt(po.advance_paid) + else: + amount = flt(po.grand_total) - flt(po.advance_paid) # credit customer jv.get("accounts")[0].account = party_account @@ -573,13 +588,13 @@ def get_payment_entry_from_purchase_order(purchase_order): jv.get("accounts")[0].party = po.supplier jv.get("accounts")[0].balance = get_balance_on(party_account) jv.get("accounts")[0].party_balance = get_balance_on(party=po.supplier, party_type="Supplier") - jv.get("accounts")[0].debit = amount + jv.get("accounts")[0].debit_in_account_currency = amount jv.get("accounts")[0].reference_type = po.doctype jv.get("accounts")[0].reference_name = po.name jv.get("accounts")[0].is_advance = "Yes" # debit bank - jv.get("accounts")[1].credit = amount + jv.get("accounts")[1].credit_in_account_currency = amount return jv.as_dict() @@ -669,7 +684,7 @@ def get_account_balance_and_party_type(account, date, company): frappe.msgprint(_("No Permission"), raise_exception=1) company_currency = get_company_currency(company) - account_details = frappe.db.get_value("Account", account, ["account_type", "currency"], as_dict=1) + account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1) if account_details.account_type == "Receivable": party_type = "Customer" @@ -679,12 +694,12 @@ def get_account_balance_and_party_type(account, date, company): party_type = "" exchange_rate = None - if account_details.currency != company_currency: - exchange_rate = get_exchange_rate(account_details.currency, company_currency) + if account_details.account_currency != company_currency: + exchange_rate = get_exchange_rate(account_details.account_currency, company_currency) grid_values = { "balance": get_balance_on(account, date), "party_type": party_type, - "currency": account_details.currency or company_currency, + "account_currency": account_details.account_currency or company_currency, } return grid_values, exchange_rate \ No newline at end of file diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 8995e34220..0d9cd249ab 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -101,7 +101,7 @@ class TestJournalEntry(unittest.TestCase): self.set_total_expense_zero("2013-02-28") jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC", submit=True) + "_Test Bank - _TC", 40000, "_Test Cost Center - _TC", submit=True) self.assertTrue(frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv.name})) @@ -112,7 +112,7 @@ class TestJournalEntry(unittest.TestCase): self.set_total_expense_zero("2013-02-28") jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC") + "_Test Bank - _TC", 40000, "_Test Cost Center - _TC") self.assertRaises(BudgetError, jv.submit) @@ -126,7 +126,7 @@ class TestJournalEntry(unittest.TestCase): self.set_total_expense_zero("2013-02-28") jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 150000, "_Test Cost Center - _TC") + "_Test Bank - _TC", 150000, "_Test Cost Center - _TC") self.assertRaises(BudgetError, jv.submit) @@ -136,13 +136,13 @@ class TestJournalEntry(unittest.TestCase): self.set_total_expense_zero("2013-02-28") jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True) + "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", submit=True) self.assertTrue(frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv1.name})) jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True) + "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", submit=True) self.assertTrue(frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv2.name})) @@ -165,32 +165,79 @@ class TestJournalEntry(unittest.TestCase): def set_total_expense_zero(self, posting_date): existing_expense = self.get_actual_expense(posting_date) make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True) + "_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True) + + def test_multi_currency(self): + jv = make_journal_entry("_Test Bank USD - _TC", + "_Test Bank - _TC", 100, exchange_rate=50, save=False) + + jv.get("accounts")[1].credit_in_account_currency = 5000 + jv.submit() + + gl_entries = frappe.db.sql("""select account, account_currency, debit, credit, + debit_in_account_currency, credit_in_account_currency + from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s + order by account asc""", jv.name, as_dict=1) -def make_journal_entry(account1, account2, amount, cost_center=None, submit=False): + self.assertTrue(gl_entries) + + expected_values = { + "_Test Bank USD - _TC": { + "account_currency": "USD", + "debit": 5000, + "debit_in_account_currency": 100, + "credit": 0, + "credit_in_account_currency": 0 + }, + "_Test Bank - _TC": { + "account_currency": "INR", + "debit": 0, + "debit_in_account_currency": 0, + "credit": 5000, + "credit_in_account_currency": 5000 + } + } + + for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"): + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[gle.account][field], gle[field]) + + + + # cancel + jv.cancel() + + gle = frappe.db.sql("""select name from `tabGL Entry` + where voucher_type='Sales Invoice' and voucher_no=%s""", jv.name) + + self.assertFalse(gle) + +def make_journal_entry(account1, account2, amount, cost_center=None, exchange_rate=1, save=True, submit=False): jv = frappe.new_doc("Journal Entry") jv.posting_date = "2013-02-14" jv.company = "_Test Company" jv.fiscal_year = "_Test Fiscal Year 2013" jv.user_remark = "test" + jv.exchange_rate = exchange_rate jv.set("accounts", [ { "account": account1, "cost_center": cost_center, - "debit": amount if amount > 0 else 0, - "credit": abs(amount) if amount < 0 else 0, + "debit_in_account_currency": amount if amount > 0 else 0, + "credit_in_account_currency": abs(amount) if amount < 0 else 0, }, { "account": account2, "cost_center": cost_center, - "credit": amount if amount > 0 else 0, - "debit": abs(amount) if amount < 0 else 0, + "credit_in_account_currency": amount if amount > 0 else 0, + "debit_in_account_currency": abs(amount) if amount < 0 else 0, } ]) - jv.insert() + if save or submit: + jv.insert() - if submit: - jv.submit() + if submit: + jv.submit() return jv diff --git a/erpnext/accounts/doctype/journal_entry/test_records.json b/erpnext/accounts/doctype/journal_entry/test_records.json index f6608638e0..5e25c3cb4a 100644 --- a/erpnext/accounts/doctype/journal_entry/test_records.json +++ b/erpnext/accounts/doctype/journal_entry/test_records.json @@ -9,15 +9,15 @@ "account": "_Test Receivable - _TC", "party_type": "Customer", "party": "_Test Customer", - "credit": 400.0, - "debit": 0.0, + "credit_in_account_currency": 400.0, + "debit_in_account_currency": 0.0, "doctype": "Journal Entry Account", "parentfield": "accounts" }, { - "account": "_Test Account Bank Account - _TC", - "credit": 0.0, - "debit": 400.0, + "account": "_Test Bank - _TC", + "credit_in_account_currency": 0.0, + "debit_in_account_currency": 400.0, "doctype": "Journal Entry Account", "parentfield": "accounts" } @@ -40,15 +40,15 @@ "account": "_Test Payable - _TC", "party_type": "Supplier", "party": "_Test Supplier", - "credit": 0.0, - "debit": 400.0, + "credit_in_account_currency": 0.0, + "debit_in_account_currency": 400.0, "doctype": "Journal Entry Account", "parentfield": "accounts" }, { - "account": "_Test Account Bank Account - _TC", - "credit": 400.0, - "debit": 0.0, + "account": "_Test Bank - _TC", + "credit_in_account_currency": 400.0, + "debit_in_account_currency": 0.0, "doctype": "Journal Entry Account", "parentfield": "accounts" } @@ -71,16 +71,16 @@ "account": "_Test Receivable - _TC", "party_type": "Customer", "party": "_Test Customer", - "credit": 0.0, - "debit": 400.0, + "credit_in_account_currency": 0.0, + "debit_in_account_currency": 400.0, "doctype": "Journal Entry Account", "parentfield": "accounts" }, { "account": "Sales - _TC", "cost_center": "_Test Cost Center - _TC", - "credit": 400.0, - "debit": 0.0, + "credit_in_account_currency": 400.0, + "debit_in_account_currency": 0.0, "doctype": "Journal Entry Account", "parentfield": "accounts" } diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json index fa7fcf9748..11c92e2ea0 100644 --- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json +++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json @@ -38,13 +38,13 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "currency", + "fieldname": "account_currency", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, - "label": "Currency", + "label": "Account Currency", "no_copy": 1, "options": "Currency", "permlevel": 0, @@ -520,7 +520,7 @@ "is_submittable": 0, "issingle": 0, "istable": 1, - "modified": "2015-08-27 16:09:43.872157", + "modified": "2015-08-28 17:15:25.180681", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Entry Account", diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py index 4edbebd09f..4c001c5b3c 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.py +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.py @@ -33,7 +33,8 @@ class PaymentTool(Document): d1.party_type = self.party_type d1.party = self.party d1.balance = get_balance_on(self.party_account) - d1.set("debit" if self.received_or_paid=="Paid" else "credit", flt(v.payment_amount)) + d1.set("debit_in_account_currency" if self.received_or_paid=="Paid" \ + else "credit_in_account_currency", flt(v.payment_amount)) d1.set("reference_type", v.against_voucher_type) d1.set("reference_name", v.against_voucher_no) d1.set('is_advance', 'Yes' if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No') @@ -41,7 +42,8 @@ class PaymentTool(Document): d2 = jv.append("accounts") d2.account = self.payment_account - d2.set('debit' if total_payment_amount < 0 else 'credit', abs(total_payment_amount)) + d2.set('debit_in_account_currency' if total_payment_amount < 0 \ + else 'credit_in_account_currency', abs(total_payment_amount)) if self.payment_account: d2.balance = get_balance_on(self.payment_account) diff --git a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py index 321986cd46..4f1c9e98a4 100644 --- a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py +++ b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py @@ -39,7 +39,7 @@ class TestPaymentTool(unittest.TestCase): "party": "_Test Customer 3", "reference_type": "Sales Order", "reference_name": so2.name, - "credit": 1000, + "credit_in_account_currency": 1000, "is_advance": "Yes" }) @@ -67,7 +67,7 @@ class TestPaymentTool(unittest.TestCase): "party": "_Test Customer 3", "reference_type": si2.doctype, "reference_name": si2.name, - "credit": 561.80 + "credit_in_account_currency": 561.80 }) pi = self.create_voucher(pi_test_records[0], { @@ -91,7 +91,7 @@ class TestPaymentTool(unittest.TestCase): "party": "_Test Customer 3", "party_account": "_Test Receivable - _TC", "payment_mode": "Cheque", - "payment_account": "_Test Account Bank Account - _TC", + "payment_account": "_Test Bank - _TC", "reference_no": "123456", "reference_date": "2013-02-14" } @@ -117,10 +117,10 @@ class TestPaymentTool(unittest.TestCase): def create_against_jv(self, test_record, args): jv = frappe.copy_doc(test_record) jv.get("accounts")[0].update(args) - if args.get("debit"): - jv.get("accounts")[1].credit = args["debit"] - elif args.get("credit"): - jv.get("accounts")[1].debit = args["credit"] + if args.get("debit_in_account_currency"): + jv.get("accounts")[1].credit_in_account_currency = args["debit_in_account_currency"] + elif args.get("credit_in_account_currency"): + jv.get("accounts")[1].debit_in_account_currency = args["credit_in_account_currency"] jv.insert() jv.submit() @@ -141,7 +141,8 @@ class TestPaymentTool(unittest.TestCase): outstanding_entries = get_outstanding_vouchers(json.dumps(args)) for d in outstanding_entries: - self.assertEquals(flt(d.get("outstanding_amount"), 2), expected_outstanding.get(d.get("voucher_type"))[1]) + self.assertEquals(flt(d.get("outstanding_amount"), 2), + expected_outstanding.get(d.get("voucher_type"))[1]) self.check_jv_entries(doc, outstanding_entries, expected_outstanding) @@ -156,11 +157,10 @@ class TestPaymentTool(unittest.TestCase): paytool.total_payment_amount = 300 new_jv = paytool.make_journal_entry() - for jv_entry in new_jv.get("accounts"): if paytool.party_account == jv_entry.get("account") and paytool.party == jv_entry.get("party"): - self.assertEquals(100.00, - jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit")) + self.assertEquals(100.00, jv_entry.get("debit_in_account_currency" + if paytool.party_type=="Supplier" else "credit_in_account_currency")) self.assertEquals(jv_entry.reference_name, expected_outstanding[jv_entry.reference_type][0]) @@ -170,4 +170,6 @@ class TestPaymentTool(unittest.TestCase): def clear_table_entries(self): frappe.db.sql("""delete from `tabGL Entry` where party in ("_Test Customer 3", "_Test Supplier 1")""") frappe.db.sql("""delete from `tabSales Order` where customer = "_Test Customer 3" """) + frappe.db.sql("""delete from `tabSales Invoice` where customer = "_Test Customer 3" """) frappe.db.sql("""delete from `tabPurchase Order` where supplier = "_Test Supplier 1" """) + frappe.db.sql("""delete from `tabPurchase Invoice` where supplier = "_Test Supplier 1" """) diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index afff47fd40..0b597462a9 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -10,11 +10,11 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ class TestPeriodClosingVoucher(unittest.TestCase): def test_closing_entry(self): - make_journal_entry("_Test Account Bank Account - _TC", "Sales - _TC", 400, + make_journal_entry("_Test Bank - _TC", "Sales - _TC", 400, "_Test Cost Center - _TC", submit=True) make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Account Bank Account - _TC", 600, "_Test Cost Center - _TC", submit=True) + "_Test Bank - _TC", 600, "_Test Cost Center - _TC", submit=True) profit_or_loss = frappe.db.sql("""select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) as balance from `tabGL Entry` t1, `tabAccount` t2 diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 1a591356e5..b640ddae8c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -269,7 +269,7 @@ 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") + account_currency = frappe.db.get_value("Account", tax.account_head, "account_currency") dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" @@ -298,7 +298,7 @@ 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") + account_currency = frappe.db.get_value("Account", item.expense_account, "account_currency") gl_entries.append( self.get_gl_dict({ "account": item.expense_account, @@ -360,7 +360,7 @@ class PurchaseInvoice(BuyingController): # 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 = frappe.db.get_value("Account", self.write_off_account, "currency") + write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "account_currency") gl_entries.append( self.get_gl_dict({ diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 0b74948d0e..2754ee6def 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -10,6 +10,7 @@ from frappe.utils import cint import frappe.defaults from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \ test_records as pr_test_records +from erpnext.controllers.accounts_controller import InvalidCurrency test_dependencies = ["Item", "Cost Center"] test_ignore = ["Serial No"] @@ -276,6 +277,55 @@ class TestPurchaseInvoice(unittest.TestCase): self.assertEquals(expected_values[gle.account][1], gle.credit) set_perpetual_inventory(0) + + def test_multi_currency_gle(self): + set_perpetual_inventory(0) + + pi = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC", + currency="USD", conversion_rate=50) + + gl_entries = frappe.db.sql("""select account, account_currency, debit, credit, + debit_in_account_currency, credit_in_account_currency + from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s + order by account asc""", pi.name, as_dict=1) + + self.assertTrue(gl_entries) + + expected_values = { + "_Test Payable USD - _TC": { + "account_currency": "USD", + "debit": 0, + "debit_in_account_currency": 0, + "credit": 12500, + "credit_in_account_currency": 250 + }, + "_Test Account Cost for Goods Sold - _TC": { + "account_currency": "INR", + "debit": 12500, + "debit_in_account_currency": 12500, + "credit": 0, + "credit_in_account_currency": 0 + } + } + + for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"): + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[gle.account][field], gle[field]) + + + # Check for valid currency + pi1 = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC", + do_not_save=True) + + self.assertRaises(InvalidCurrency, pi1.save) + + # cancel + pi.cancel() + + gle = frappe.db.sql("""select name from `tabGL Entry` + where voucher_type='Sales Invoice' and voucher_no=%s""", pi.name) + + self.assertFalse(gle) def make_purchase_invoice(**args): pi = frappe.new_doc("Purchase Invoice") diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 955a19b3d6..0d1b42cc76 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -1145,7 +1145,7 @@ "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, - "label": "Discount", + "label": "Additional Discount", "no_copy": 0, "permlevel": 0, "precision": "", @@ -2951,7 +2951,7 @@ "is_submittable": 1, "issingle": 0, "istable": 0, - "modified": "2015-08-27 16:12:12.077662", + "modified": "2015-08-27 16:46:11.526089", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 9639038b43..0871a66c75 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -423,22 +423,18 @@ class SalesInvoice(SellingController): if cint(self.is_pos) == 1: if flt(self.paid_amount) == 0: if self.cash_bank_account: - paid_amount = flt(flt(self.grand_total) - flt(self.write_off_amount), - self.precision("paid_amount")) - base_paid_amount = flt(paid_amount*self.conversion_rate, self.precision("base_paid_amount")) - - frappe.db.set(self, 'paid_amount', paid_amount) - frappe.db.set(self, 'base_paid_amount', base_paid_amount) - + frappe.db.set(self, 'paid_amount', + flt(flt(self.grand_total) - flt(self.write_off_amount), self.precision("paid_amount"))) else: # show message that the amount is not paid frappe.db.set(self,'paid_amount',0) - frappe.db.set(self,'base_paid_amount',0) frappe.msgprint(_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified")) else: frappe.db.set(self,'paid_amount',0) - frappe.db.set(self,'base_paid_amount',0) - + + frappe.db.set(self, 'base_paid_amount', + flt(self.paid_amount*self.conversion_rate, self.precision("base_paid_amount"))) + def check_prev_docstatus(self): for d in self.get('items'): if d.sales_order and frappe.db.get_value("Sales Order", d.sales_order, "docstatus") != 1: @@ -512,7 +508,7 @@ class SalesInvoice(SellingController): 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") + account_currency = frappe.db.get_value("Account", tax.account_head, "account_currency") gl_entries.append( self.get_gl_dict({ "account": tax.account_head, @@ -528,7 +524,7 @@ class SalesInvoice(SellingController): # 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") + account_currency = frappe.db.get_value("Account", item.income_account, "account_currency") gl_entries.append( self.get_gl_dict({ "account": item.income_account, @@ -547,7 +543,7 @@ class SalesInvoice(SellingController): 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 = frappe.db.get_value("Account", self.cash_bank_account, "currency") + bank_account_currency = frappe.db.get_value("Account", self.cash_bank_account, "account_currency") # POS, make payment entries gl_entries.append( self.get_gl_dict({ @@ -575,7 +571,7 @@ class SalesInvoice(SellingController): 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 = frappe.db.get_value("Account", self.write_off_account, "currency") + write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "account_currency") gl_entries.append( self.get_gl_dict({ diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index c7a992c489..e519bd3969 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -7,6 +7,8 @@ import unittest, copy from frappe.utils import nowdate, add_days, flt from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory +from erpnext.controllers.accounts_controller import InvalidCurrency +from erpnext.accounts.doctype.gl_entry.gl_entry import InvalidAccountCurrency class TestSalesInvoice(unittest.TestCase): def make(self): @@ -401,7 +403,7 @@ class TestSalesInvoice(unittest.TestCase): jv.cancel() self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8) - def test_sales_invoice_gl_entry_without_aii(self): + def test_sales_invoice_gl_entry_without_perpetual_inventory(self): set_perpetual_inventory(0) si = frappe.copy_doc(test_records[1]) si.insert() @@ -433,7 +435,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertFalse(gle) - def test_pos_gl_entry_with_aii(self): + def test_pos_gl_entry_with_perpetual_inventory(self): set_perpetual_inventory() self.make_pos_profile() @@ -442,8 +444,7 @@ class TestSalesInvoice(unittest.TestCase): pos = copy.deepcopy(test_records[1]) pos["is_pos"] = 1 pos["update_stock"] = 1 - # pos["posting_time"] = "12:05" - pos["cash_bank_account"] = "_Test Account Bank Account - _TC" + pos["cash_bank_account"] = "_Test Bank - _TC" pos["paid_amount"] = 600.0 si = frappe.copy_doc(pos) @@ -474,7 +475,7 @@ class TestSalesInvoice(unittest.TestCase): [stock_in_hand, 0.0, abs(sle.stock_value_difference)], [pos["items"][0]["expense_account"], abs(sle.stock_value_difference), 0.0], [si.debit_to, 0.0, 600.0], - ["_Test Account Bank Account - _TC", 600.0, 0.0] + ["_Test Bank - _TC", 600.0, 0.0] ]) for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)): @@ -494,7 +495,7 @@ class TestSalesInvoice(unittest.TestCase): def make_pos_profile(self): pos_profile = frappe.get_doc({ - "cash_bank_account": "_Test Account Bank Account - _TC", + "cash_bank_account": "_Test Bank - _TC", "company": "_Test Company", "cost_center": "_Test Cost Center - _TC", "currency": "INR", @@ -513,7 +514,7 @@ class TestSalesInvoice(unittest.TestCase): if not frappe.db.exists("POS Profile", "_Test POS Profile"): pos_profile.insert() - def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self): + def test_si_gl_entry_with_perpetual_inventory_and_update_stock_with_warehouse_but_no_account(self): set_perpetual_inventory() frappe.delete_doc("Account", "_Test Warehouse No Account - _TC") @@ -567,7 +568,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertFalse(gle) set_perpetual_inventory(0) - def test_sales_invoice_gl_entry_with_aii_no_item_code(self): + def test_sales_invoice_gl_entry_with_perpetual_inventory_no_item_code(self): set_perpetual_inventory() si = frappe.get_doc(test_records[1]) @@ -593,7 +594,7 @@ class TestSalesInvoice(unittest.TestCase): set_perpetual_inventory(0) - def test_sales_invoice_gl_entry_with_aii_non_stock_item(self): + def test_sales_invoice_gl_entry_with_perpetual_inventory_non_stock_item(self): set_perpetual_inventory() si = frappe.get_doc(test_records[1]) si.get("items")[0].item_code = "_Test Non Stock Item" @@ -841,7 +842,80 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(si.total_taxes_and_charges, 234.44) self.assertEquals(si.base_grand_total, 859.44) self.assertEquals(si.grand_total, 859.44) + + def test_multi_currency_gle(self): + set_perpetual_inventory(0) + si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=50) + gl_entries = frappe.db.sql("""select account, account_currency, debit, credit, + debit_in_account_currency, credit_in_account_currency + from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s + order by account asc""", si.name, as_dict=1) + + self.assertTrue(gl_entries) + + expected_values = { + "_Test Receivable USD - _TC": { + "account_currency": "USD", + "debit": 5000, + "debit_in_account_currency": 100, + "credit": 0, + "credit_in_account_currency": 0 + }, + "Sales - _TC": { + "account_currency": "INR", + "debit": 0, + "debit_in_account_currency": 0, + "credit": 5000, + "credit_in_account_currency": 5000 + } + } + + for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"): + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[gle.account][field], gle[field]) + + # cancel + si.cancel() + + gle = frappe.db.sql("""select name from `tabGL Entry` + where voucher_type='Sales Invoice' and voucher_no=%s""", si.name) + + self.assertFalse(gle) + + def test_invalid_currency(self): + # Customer currency = USD + + # Transaction currency cannot be INR + si1 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + do_not_save=True) + + self.assertRaises(InvalidCurrency, si1.save) + + # Transaction currency cannot be EUR + si2 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="EUR", conversion_rate=80, do_not_save=True) + + self.assertRaises(InvalidCurrency, si2.save) + + # Transaction currency only allowed in USD + si3 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=50) + + # Party Account currency must be in USD, as there is existing GLE with USD + si4 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable - _TC", + currency="USD", conversion_rate=50, do_not_submit=True) + + self.assertRaises(InvalidAccountCurrency, si4.submit) + + # Party Account currency must be in USD, force customer currency as there is no GLE + + si3.cancel() + si5 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable - _TC", + currency="USD", conversion_rate=50, do_not_submit=True) + + self.assertRaises(InvalidAccountCurrency, si5.submit) def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") @@ -856,14 +930,15 @@ def create_sales_invoice(**args): si.is_pos = args.is_pos si.is_return = args.is_return si.return_against = args.return_against - si.currency="INR" - si.conversion_rate = 1 + si.currency=args.currency or "INR" + si.conversion_rate = args.conversion_rate or 1 si.append("items", { "item_code": args.item or args.item_code or "_Test Item", "warehouse": args.warehouse or "_Test Warehouse - _TC", "qty": args.qty or 1, "rate": args.rate or 100, + "income_account": "Sales - _TC", "expense_account": "Cost of Goods Sold - _TC", "cost_center": "_Test Cost Center - _TC", "serial_no": args.serial_no diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js index 5627781495..7fbe92bc07 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.js +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js @@ -212,7 +212,7 @@ erpnext.AccountsChart = Class.extend({ description: __("Optional. This setting will be used to filter in various transactions.") }, {fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate')}, {fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse"}, - {fieldtype:'Link', fieldname:'currency', label:__('Currency'), options:"Currency"} + {fieldtype:'Link', fieldname:'account_currency', label:__('Currency'), options:"Currency"} ] }) diff --git a/erpnext/buying/doctype/supplier/test_records.json b/erpnext/buying/doctype/supplier/test_records.json index dfa5d46f24..82e0a447bb 100644 --- a/erpnext/buying/doctype/supplier/test_records.json +++ b/erpnext/buying/doctype/supplier/test_records.json @@ -1,14 +1,22 @@ [ { - "company": "_Test Company", "doctype": "Supplier", "supplier_name": "_Test Supplier", "supplier_type": "_Test Supplier Type" }, { - "company": "_Test Company", "doctype": "Supplier", "supplier_name": "_Test Supplier 1", "supplier_type": "_Test Supplier Type" + }, + { + "doctype": "Supplier", + "supplier_name": "_Test Supplier USD", + "supplier_type": "_Test Supplier Type", + "default_currency": "USD", + "accounts": [{ + "company": "_Test Company", + "account": "_Test Payable USD - _TC" + }] } -] +] \ No newline at end of file diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 6ba954f7a3..7af7369188 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -14,6 +14,7 @@ from erpnext.controllers.sales_and_purchase_return import validate_return force_item_fields = ("item_group", "barcode", "brand", "stock_uom") class CustomerFrozen(frappe.ValidationError): pass +class InvalidCurrency(frappe.ValidationError): pass class AccountsController(TransactionBase): def __init__(self, arg1, arg2=None): @@ -106,8 +107,6 @@ class AccountsController(TransactionBase): def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("currency"): - company_currency = get_company_currency(self.company) - # price list part fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \ else "buying_price_list" @@ -115,22 +114,22 @@ class AccountsController(TransactionBase): self.price_list_currency = frappe.db.get_value("Price List", self.get(fieldname), "currency") - if self.price_list_currency == company_currency: + if self.price_list_currency == self.company_currency: self.plc_conversion_rate = 1.0 elif not self.plc_conversion_rate: self.plc_conversion_rate = get_exchange_rate( - self.price_list_currency, company_currency) + self.price_list_currency, self.company_currency) # currency if not self.currency: self.currency = self.price_list_currency self.conversion_rate = self.plc_conversion_rate - elif self.currency == company_currency: + elif self.currency == self.company_currency: self.conversion_rate = 1.0 elif not self.conversion_rate: self.conversion_rate = get_exchange_rate(self.currency, - company_currency) + self.company_currency) def set_missing_item_details(self): """set missing item values""" @@ -218,7 +217,7 @@ class AccountsController(TransactionBase): gl_dict.update(args) if not account_currency: - account_currency = frappe.db.get_value("Account", gl_dict.account, "currency") + account_currency = frappe.db.get_value("Account", gl_dict.account, "account_currency") self.validate_account_currency(gl_dict.account, account_currency) gl_dict = self.set_balance_in_account_currency(gl_dict, account_currency) @@ -226,17 +225,23 @@ class AccountsController(TransactionBase): return gl_dict def validate_account_currency(self, account, account_currency=None): - valid_currency = list(set([self.currency, self.company_currency])) + if self.doctype == "Journal Entry": + return + valid_currency = [self.company_currency] + if self.get("currency") and self.currency != self.company_currency: + valid_currency.append(self.currency) + if account_currency not in valid_currency: frappe.throw(_("Account {0} is invalid. Account Currency must be {1}") .format(account, " or ".join(valid_currency))) def set_balance_in_account_currency(self, gl_dict, account_currency=None): - if not self.get("conversion_rate") and account_currency!=self.company_currency: - frappe.throw(_("Account: {0} with currency: {1} can not be selected") - .format(gl_dict.account, account_currency)) + if not (self.get("conversion_rate") or self.get("exchange_rate")) \ + and account_currency!=self.company_currency: + frappe.throw(_("Account: {0} with currency: {1} can not be selected") + .format(gl_dict.account, account_currency)) - gl_dict["currency"] = self.company_currency if account_currency==self.company_currency \ + gl_dict["account_currency"] = self.company_currency if account_currency==self.company_currency \ else account_currency # set debit/credit in account currency if not provided @@ -366,9 +371,9 @@ class AccountsController(TransactionBase): def set_total_advance_paid(self): if self.doctype == "Sales Order": - dr_or_cr = "credit" + dr_or_cr = "credit_in_account_currency" else: - dr_or_cr = "debit" + dr_or_cr = "debit_in_account_currency" advance_paid = frappe.db.sql(""" select @@ -376,10 +381,9 @@ class AccountsController(TransactionBase): from `tabJournal Entry Account` where - reference_type = %s and - reference_name = %s and - docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr), - (self.doctype, self.name)) + reference_type = %s and reference_name = %s + and docstatus = 1 and is_advance = "Yes" + """.format(dr_or_cr=dr_or_cr), (self.doctype, self.name)) if advance_paid: advance_paid = flt(advance_paid[0][0], self.precision("advance_paid")) @@ -421,23 +425,23 @@ class AccountsController(TransactionBase): return party_type, party def validate_currency(self): - if self.get("currency") and self.currency != self.company_currency: + if self.get("currency"): party_type, party = self.get_party() - - existing_gle = frappe.db.get_value("GL Entry", {"party_type": party_type, - "party": party, "company": self.company}, ["name", "currency"], as_dict=1) - currency_in_existing_entries = existing_gle.currency or self.company_currency - - if existing_gle: - if currency_in_existing_entries != self.company_currency \ - and currency_in_existing_entries != self.currency: - frappe.throw(_("Currency must be {0} for {1} {2}") - .format(currency_in_existing_entries, party_type, party)) - else: - party_currency = frappe.db.get_value(party_type, party, "default_currency") - if party_currency != self.company_currency and self.currency != party_currency: - frappe.throw(_("Currency must be same as {0} currency {1}") - .format(party_type, party_currency)) + if party_type and party: + existing_gle = frappe.db.get_value("GL Entry", {"party_type": party_type, + "party": party, "company": self.company}, ["name", "account_currency"], as_dict=1) + if existing_gle: + currency_in_existing_entries = existing_gle.account_currency or self.company_currency + if currency_in_existing_entries != self.company_currency \ + and currency_in_existing_entries != self.currency: + frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}") + .format(party_type, party, currency_in_existing_entries), InvalidCurrency) + else: + party_currency = frappe.db.get_value(party_type, party, "default_currency") \ + or self.company_currency + if party_currency != self.company_currency and self.currency != party_currency: + frappe.throw(_("Currency must be same as {0} currency {1}") + .format(party_type, party_currency), InvalidCurrency) @frappe.whitelist() def get_tax_rate(account_head): diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index ccbad0d122..eccceb0ad3 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -53,7 +53,7 @@ class StockController(AccountsController): "cost_center": detail.cost_center, "remarks": self.get("remarks") or "Accounting Entry for Stock", "debit": flt(sle.stock_value_difference, 2), - }, warehouse_account[sle.warehouse]["currency"])) + }, warehouse_account[sle.warehouse]["account_currency"])) # to target warehouse / expense account gl_list.append(self.get_gl_dict({ @@ -338,7 +338,7 @@ def get_voucherwise_gl_entries(future_stock_vouchers, posting_date): def get_warehouse_account(): warehouse_account = frappe._dict() - for d in frappe.db.sql("""select warehouse, name, currency from tabAccount + for d in frappe.db.sql("""select warehouse, name, account_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/patches/v6_0/multi_currency.py b/erpnext/patches/v6_0/multi_currency.py index 21c851b448..d506ab76d4 100644 --- a/erpnext/patches/v6_0/multi_currency.py +++ b/erpnext/patches/v6_0/multi_currency.py @@ -77,7 +77,7 @@ def execute(): party_account = party_gle.account or company.default_receivable_account - party.append("party_accounts", { + party.append("accounts", { "company": company.name, "account": party_account }) diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index 105f814eb9..952be8ba72 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -567,7 +567,7 @@ "no_copy": 0, "oldfieldname": "credit_limit", "oldfieldtype": "Currency", - "options": "Company:company:default_currency", + "options": "", "permlevel": 1, "print_hide": 0, "read_only": 0, @@ -796,7 +796,7 @@ "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-08-27 16:21:57.520411", + "modified": "2015-08-27 17:00:50.604869", "modified_by": "Administrator", "module": "Selling", "name": "Customer", diff --git a/erpnext/selling/doctype/customer/test_records.json b/erpnext/selling/doctype/customer/test_records.json index e076f7a893..5c0bbd9246 100644 --- a/erpnext/selling/doctype/customer/test_records.json +++ b/erpnext/selling/doctype/customer/test_records.json @@ -1,6 +1,5 @@ [ { - "company": "_Test Company", "customer_group": "_Test Customer Group", "customer_name": "_Test Customer", "customer_type": "Individual", @@ -8,7 +7,6 @@ "territory": "_Test Territory" }, { - "company": "_Test Company", "customer_group": "_Test Customer Group", "customer_name": "_Test Customer 1", "customer_type": "Individual", @@ -16,7 +14,6 @@ "territory": "_Test Territory" }, { - "company": "_Test Company", "customer_group": "_Test Customer Group", "customer_name": "_Test Customer 2", "customer_type": "Individual", @@ -24,11 +21,22 @@ "territory": "_Test Territory" }, { - "company": "_Test Company", "customer_group": "_Test Customer Group", "customer_name": "_Test Customer 3", "customer_type": "Individual", "doctype": "Customer", "territory": "_Test Territory" + }, + { + "customer_group": "_Test Customer Group", + "customer_name": "_Test Customer USD", + "customer_type": "Individual", + "doctype": "Customer", + "territory": "_Test Territory", + "default_currency": "USD", + "accounts": [{ + "company": "_Test Company", + "account": "_Test Receivable USD - _TC" + }] } ] diff --git a/erpnext/setup/doctype/company/test_records.json b/erpnext/setup/doctype/company/test_records.json index 13cb03e081..b6918b3afa 100644 --- a/erpnext/setup/doctype/company/test_records.json +++ b/erpnext/setup/doctype/company/test_records.json @@ -19,7 +19,7 @@ }, { "abbr": "_TC2", - "company_name": "_Test Company 3", + "company_name": "_Test Company 2", "default_currency": "EUR", "country": "Germany", "doctype": "Company", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index f6649c119c..85610a49d2 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -316,10 +316,10 @@ class PurchaseReceipt(BuyingController): "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": stock_value_diff - }, warehouse_account[d.warehouse]["currency"])) + }, warehouse_account[d.warehouse]["account_currency"])) # stock received but not billed - stock_rbnb_currency = frappe.db.get_value("Account", stock_rbnb, "currency") + stock_rbnb_currency = frappe.db.get_value("Account", stock_rbnb, "account_currency") gl_entries.append(self.get_gl_dict({ "account": stock_rbnb, "against": warehouse_account[d.warehouse]["name"], @@ -350,14 +350,14 @@ class PurchaseReceipt(BuyingController): "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"])) + }, warehouse_account[self.supplier_warehouse]["account_currency"])) # divisional loss adjustment sle_valuation_amount = flt(flt(d.valuation_rate, val_rate_db_precision) * flt(d.qty) * flt(d.conversion_factor), self.precision("base_net_amount", d)) distributed_amount = flt(flt(d.base_net_amount, self.precision("base_net_amount", d))) + \ - flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount) divisional_loss = flt(distributed_amount - sle_valuation_amount, self.precision("base_net_amount", d)) if divisional_loss: