[fix] added validation to match account currency with existing gle and test case
This commit is contained in:
parent
248c867a2c
commit
4945b94950
@ -6,12 +6,10 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, fmt_money, getdate, formatdate
|
from frappe.utils import flt, fmt_money, getdate, formatdate
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.party import get_party_account_currency
|
from erpnext.accounts.party import validate_party_gle_currency, get_party_account_currency
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
from erpnext.setup.doctype.company.company import get_company_currency
|
||||||
class CustomerFrozen(frappe.ValidationError): pass
|
from erpnext.exceptions import InvalidAccountCurrency, CustomerFrozen
|
||||||
class InvalidCurrency(frappe.ValidationError): pass
|
|
||||||
class InvalidAccountCurrency(frappe.ValidationError): pass
|
|
||||||
|
|
||||||
class GLEntry(Document):
|
class GLEntry(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -103,16 +101,16 @@ class GLEntry(Document):
|
|||||||
frappe.throw("{0} {1} is frozen".format(self.party_type, self.party), CustomerFrozen)
|
frappe.throw("{0} {1} is frozen".format(self.party_type, self.party), CustomerFrozen)
|
||||||
|
|
||||||
def validate_currency(self):
|
def validate_currency(self):
|
||||||
company_currency = frappe.db.get_value("Company", self.company, "default_currency")
|
company_currency = get_company_currency(self.company)
|
||||||
account_currency = get_account_currency(self.account)
|
account_currency = get_account_currency(self.account)
|
||||||
|
|
||||||
if not self.account_currency:
|
if not self.account_currency:
|
||||||
self.account_currency = company_currency
|
self.account_currency = company_currency
|
||||||
|
|
||||||
if account_currency != self.account_currency:
|
if account_currency != self.account_currency:
|
||||||
frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
|
frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
|
||||||
.format(self.account, (account_currency or company_currency)), InvalidAccountCurrency)
|
.format(self.account, (account_currency or company_currency)), InvalidAccountCurrency)
|
||||||
|
|
||||||
|
|
||||||
if self.party_type and self.party:
|
if self.party_type and self.party:
|
||||||
party_account_currency = get_party_account_currency(self.party_type, self.party, self.company)
|
party_account_currency = get_party_account_currency(self.party_type, self.party, self.company)
|
||||||
|
|
||||||
@ -120,6 +118,8 @@ class GLEntry(Document):
|
|||||||
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")
|
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")
|
||||||
.format(self.party_type, self.party, party_account_currency), InvalidAccountCurrency)
|
.format(self.party_type, self.party, party_account_currency), InvalidAccountCurrency)
|
||||||
|
|
||||||
|
validate_party_gle_currency(self.party_type, self.party, self.company)
|
||||||
|
|
||||||
def validate_balance_type(account, adv_adj=False):
|
def validate_balance_type(account, adv_adj=False):
|
||||||
if not adv_adj and account:
|
if not adv_adj and account:
|
||||||
balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
|
balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest, frappe
|
import unittest, frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.accounts.utils import get_actual_expense, BudgetError, get_fiscal_year
|
from erpnext.accounts.utils import get_actual_expense, BudgetError, get_fiscal_year
|
||||||
|
from erpnext.exceptions import InvalidAccountCurrency
|
||||||
|
|
||||||
|
|
||||||
class TestJournalEntry(unittest.TestCase):
|
class TestJournalEntry(unittest.TestCase):
|
||||||
@ -166,15 +167,15 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
existing_expense = self.get_actual_expense(posting_date)
|
existing_expense = self.get_actual_expense(posting_date)
|
||||||
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Bank - _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):
|
def test_multi_currency(self):
|
||||||
jv = make_journal_entry("_Test Bank USD - _TC",
|
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||||
"_Test Bank - _TC", 100, exchange_rate=50, save=False)
|
"_Test Bank - _TC", 100, exchange_rate=50, save=False)
|
||||||
|
|
||||||
jv.get("accounts")[1].credit_in_account_currency = 5000
|
jv.get("accounts")[1].credit_in_account_currency = 5000
|
||||||
jv.submit()
|
jv.submit()
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||||
debit_in_account_currency, credit_in_account_currency
|
debit_in_account_currency, credit_in_account_currency
|
||||||
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
|
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
|
||||||
order by account asc""", jv.name, as_dict=1)
|
order by account asc""", jv.name, as_dict=1)
|
||||||
@ -197,12 +198,10 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
"credit_in_account_currency": 5000
|
"credit_in_account_currency": 5000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEquals(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
@ -212,6 +211,40 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
|
def test_disallow_change_in_account_currency_for_a_party(self):
|
||||||
|
# create jv in USD
|
||||||
|
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||||
|
"_Test Receivable USD - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
jv.submit()
|
||||||
|
|
||||||
|
# create jv in USD, but account currency in INR
|
||||||
|
jv = make_journal_entry("_Test Bank - _TC",
|
||||||
|
"_Test Receivable - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertRaises(InvalidAccountCurrency, jv.submit)
|
||||||
|
|
||||||
|
# back in USD
|
||||||
|
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||||
|
"_Test Receivable USD - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
jv.submit()
|
||||||
|
|
||||||
def make_journal_entry(account1, account2, amount, cost_center=None, exchange_rate=1, save=True, submit=False):
|
def make_journal_entry(account1, account2, amount, cost_center=None, exchange_rate=1, save=True, submit=False):
|
||||||
jv = frappe.new_doc("Journal Entry")
|
jv = frappe.new_doc("Journal Entry")
|
||||||
jv.posting_date = "2013-02-14"
|
jv.posting_date = "2013-02-14"
|
||||||
@ -231,7 +264,7 @@ def make_journal_entry(account1, account2, amount, cost_center=None, exchange_ra
|
|||||||
"cost_center": cost_center,
|
"cost_center": cost_center,
|
||||||
"credit_in_account_currency": 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,
|
"debit_in_account_currency": abs(amount) if amount < 0 else 0,
|
||||||
exchange_rate: exchange_rate
|
"exchange_rate": exchange_rate
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
if save or submit:
|
if save or submit:
|
||||||
|
@ -10,7 +10,7 @@ from frappe.utils import cint
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||||
test_records as pr_test_records
|
test_records as pr_test_records
|
||||||
from erpnext.controllers.accounts_controller import InvalidCurrency
|
from erpnext.exceptions import InvalidCurrency
|
||||||
|
|
||||||
test_dependencies = ["Item", "Cost Center"]
|
test_dependencies = ["Item", "Cost Center"]
|
||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
@ -219,7 +219,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
pi.load_from_db()
|
pi.load_from_db()
|
||||||
|
|
||||||
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
|
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
|
||||||
where reference_type='Purchase Invoice'
|
where reference_type='Purchase Invoice'
|
||||||
and reference_name=%s and debit_in_account_currency=300""", pi.name))
|
and reference_name=%s and debit_in_account_currency=300""", pi.name))
|
||||||
|
|
||||||
self.assertEqual(pi.outstanding_amount, 1212.30)
|
self.assertEqual(pi.outstanding_amount, 1212.30)
|
||||||
@ -237,17 +237,17 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
existing_purchase_cost = frappe.db.sql("""select sum(ifnull(base_net_amount, 0))
|
existing_purchase_cost = frappe.db.sql("""select sum(ifnull(base_net_amount, 0))
|
||||||
from `tabPurchase Invoice Item` where project_name = '_Test Project' and docstatus=1""")
|
from `tabPurchase Invoice Item` where project_name = '_Test Project' and docstatus=1""")
|
||||||
existing_purchase_cost = existing_purchase_cost and existing_purchase_cost[0][0] or 0
|
existing_purchase_cost = existing_purchase_cost and existing_purchase_cost[0][0] or 0
|
||||||
|
|
||||||
pi = make_purchase_invoice(currency="USD", conversion_rate=60, project_name="_Test Project")
|
pi = make_purchase_invoice(currency="USD", conversion_rate=60, project_name="_Test Project")
|
||||||
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
||||||
existing_purchase_cost + 15000)
|
existing_purchase_cost + 15000)
|
||||||
|
|
||||||
pi1 = make_purchase_invoice(qty=10, project_name="_Test Project")
|
pi1 = make_purchase_invoice(qty=10, project_name="_Test Project")
|
||||||
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
||||||
existing_purchase_cost + 15500)
|
existing_purchase_cost + 15500)
|
||||||
|
|
||||||
pi1.cancel()
|
pi1.cancel()
|
||||||
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
|
||||||
existing_purchase_cost + 15000)
|
existing_purchase_cost + 15000)
|
||||||
|
|
||||||
pi.cancel()
|
pi.cancel()
|
||||||
@ -278,14 +278,14 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(expected_values[gle.account][1], gle.credit)
|
self.assertEquals(expected_values[gle.account][1], gle.credit)
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def test_multi_currency_gle(self):
|
def test_multi_currency_gle(self):
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC",
|
pi = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||||
debit_in_account_currency, credit_in_account_currency
|
debit_in_account_currency, credit_in_account_currency
|
||||||
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
|
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
|
||||||
order by account asc""", pi.name, as_dict=1)
|
order by account asc""", pi.name, as_dict=1)
|
||||||
@ -308,16 +308,16 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
"credit_in_account_currency": 0
|
"credit_in_account_currency": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEquals(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
|
|
||||||
# Check for valid currency
|
# Check for valid currency
|
||||||
pi1 = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC",
|
pi1 = make_purchase_invoice(supplier="_Test Supplier USD", credit_to="_Test Payable USD - _TC",
|
||||||
do_not_save=True)
|
do_not_save=True)
|
||||||
|
|
||||||
self.assertRaises(InvalidCurrency, pi1.save)
|
self.assertRaises(InvalidCurrency, pi1.save)
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
|
@ -7,8 +7,7 @@ import unittest, copy
|
|||||||
from frappe.utils import nowdate, add_days, flt
|
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.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.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
from erpnext.controllers.accounts_controller import InvalidCurrency
|
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import InvalidAccountCurrency
|
|
||||||
|
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
@ -842,13 +841,13 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(si.total_taxes_and_charges, 234.44)
|
self.assertEquals(si.total_taxes_and_charges, 234.44)
|
||||||
self.assertEquals(si.base_grand_total, 859.44)
|
self.assertEquals(si.base_grand_total, 859.44)
|
||||||
self.assertEquals(si.grand_total, 859.44)
|
self.assertEquals(si.grand_total, 859.44)
|
||||||
|
|
||||||
def test_multi_currency_gle(self):
|
def test_multi_currency_gle(self):
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||||
debit_in_account_currency, credit_in_account_currency
|
debit_in_account_currency, credit_in_account_currency
|
||||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||||
order by account asc""", si.name, as_dict=1)
|
order by account asc""", si.name, as_dict=1)
|
||||||
@ -871,7 +870,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
"credit_in_account_currency": 5000
|
"credit_in_account_currency": 5000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEquals(expected_values[gle.account][field], gle[field])
|
||||||
@ -883,38 +882,38 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
|
where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
|
||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
def test_invalid_currency(self):
|
def test_invalid_currency(self):
|
||||||
# Customer currency = USD
|
# Customer currency = USD
|
||||||
|
|
||||||
# Transaction currency cannot be INR
|
# Transaction currency cannot be INR
|
||||||
si1 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
si1 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
do_not_save=True)
|
do_not_save=True)
|
||||||
|
|
||||||
self.assertRaises(InvalidCurrency, si1.save)
|
self.assertRaises(InvalidCurrency, si1.save)
|
||||||
|
|
||||||
# Transaction currency cannot be EUR
|
# Transaction currency cannot be EUR
|
||||||
si2 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
si2 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
currency="EUR", conversion_rate=80, do_not_save=True)
|
currency="EUR", conversion_rate=80, do_not_save=True)
|
||||||
|
|
||||||
self.assertRaises(InvalidCurrency, si2.save)
|
self.assertRaises(InvalidCurrency, si2.save)
|
||||||
|
|
||||||
# Transaction currency only allowed in USD
|
# Transaction currency only allowed in USD
|
||||||
si3 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
si3 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
# Party Account currency must be in USD, as there is existing GLE with USD
|
# 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",
|
si4 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable - _TC",
|
||||||
currency="USD", conversion_rate=50, do_not_submit=True)
|
currency="USD", conversion_rate=50, do_not_submit=True)
|
||||||
|
|
||||||
self.assertRaises(InvalidAccountCurrency, si4.submit)
|
self.assertRaises(InvalidAccountCurrency, si4.submit)
|
||||||
|
|
||||||
# Party Account currency must be in USD, force customer currency as there is no GLE
|
# Party Account currency must be in USD, force customer currency as there is no GLE
|
||||||
|
|
||||||
si3.cancel()
|
si3.cancel()
|
||||||
si5 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable - _TC",
|
si5 = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable - _TC",
|
||||||
currency="USD", conversion_rate=50, do_not_submit=True)
|
currency="USD", conversion_rate=50, do_not_submit=True)
|
||||||
|
|
||||||
self.assertRaises(InvalidAccountCurrency, si5.submit)
|
self.assertRaises(InvalidAccountCurrency, si5.submit)
|
||||||
|
|
||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
|
@ -10,6 +10,7 @@ from frappe.defaults import get_user_permissions
|
|||||||
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff
|
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff
|
||||||
from erpnext.utilities.doctype.address.address import get_address_display
|
from erpnext.utilities.doctype.address.address import get_address_display
|
||||||
from erpnext.utilities.doctype.contact.contact import get_contact_details
|
from erpnext.utilities.doctype.contact.contact import get_contact_details
|
||||||
|
from erpnext.exceptions import InvalidAccountCurrency
|
||||||
|
|
||||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||||
|
|
||||||
@ -191,6 +192,25 @@ def get_party_account_currency(party_type, party, company):
|
|||||||
|
|
||||||
return frappe.local_cache("party_account_currency", (party_type, party, company), generator)
|
return frappe.local_cache("party_account_currency", (party_type, party, company), generator)
|
||||||
|
|
||||||
|
def get_party_gle_currency(party_type, party, company):
|
||||||
|
def generator():
|
||||||
|
existing_gle_currency = frappe.db.sql("""select account_currency from `tabGL Entry`
|
||||||
|
where docstatus=1 and company=%(company)s and party_type=%(party_type)s and party=%(party)s
|
||||||
|
limit 1""", { "company": company, "party_type": party_type, "party": party })
|
||||||
|
|
||||||
|
return existing_gle_currency[0][0] if existing_gle_currency else None
|
||||||
|
|
||||||
|
return frappe.local_cache("party_gle_currency", (party_type, party, company), generator)
|
||||||
|
|
||||||
|
def validate_party_gle_currency(party_type, party, company):
|
||||||
|
"""Validate party account currency with existing GL Entry's currency"""
|
||||||
|
party_account_currency = get_party_account_currency(party_type, party, company)
|
||||||
|
existing_gle_currency = get_party_gle_currency(party_type, party, company)
|
||||||
|
|
||||||
|
if existing_gle_currency and party_account_currency != existing_gle_currency:
|
||||||
|
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")
|
||||||
|
.format(party_type, party, existing_gle_currency), InvalidAccountCurrency)
|
||||||
|
|
||||||
def validate_party_accounts(doc):
|
def validate_party_accounts(doc):
|
||||||
companies = []
|
companies = []
|
||||||
|
|
||||||
|
@ -10,13 +10,11 @@ from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year, get_ac
|
|||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
|
from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
|
||||||
from erpnext.controllers.sales_and_purchase_return import validate_return
|
from erpnext.controllers.sales_and_purchase_return import validate_return
|
||||||
from erpnext.accounts.party import get_party_account_currency
|
from erpnext.accounts.party import get_party_account_currency, validate_party_gle_currency
|
||||||
|
from erpnext.exceptions import CustomerFrozen, InvalidCurrency
|
||||||
|
|
||||||
force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
|
force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
|
||||||
|
|
||||||
class CustomerFrozen(frappe.ValidationError): pass
|
|
||||||
class InvalidCurrency(frappe.ValidationError): pass
|
|
||||||
|
|
||||||
class AccountsController(TransactionBase):
|
class AccountsController(TransactionBase):
|
||||||
def __init__(self, arg1, arg2=None):
|
def __init__(self, arg1, arg2=None):
|
||||||
super(AccountsController, self).__init__(arg1, arg2)
|
super(AccountsController, self).__init__(arg1, arg2)
|
||||||
|
7
erpnext/exceptions.py
Normal file
7
erpnext/exceptions.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
class CustomerFrozen(frappe.ValidationError): pass
|
||||||
|
class InvalidAccountCurrency(frappe.ValidationError): pass
|
||||||
|
class InvalidCurrency(frappe.ValidationError): pass
|
@ -7,7 +7,7 @@ import frappe
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from frappe.test_runner import make_test_records
|
from frappe.test_runner import make_test_records
|
||||||
from erpnext.controllers.accounts_controller import CustomerFrozen
|
from erpnext.exceptions import CustomerFrozen
|
||||||
|
|
||||||
test_ignore = ["Price List"]
|
test_ignore = ["Price List"]
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import frappe.permissions
|
|||||||
import unittest
|
import unittest
|
||||||
from erpnext.selling.doctype.sales_order.sales_order \
|
from erpnext.selling.doctype.sales_order.sales_order \
|
||||||
import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired
|
import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired
|
||||||
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry \
|
||||||
|
import make_journal_entry
|
||||||
|
|
||||||
from frappe.tests.test_permissions import set_user_permission_doctypes
|
from frappe.tests.test_permissions import set_user_permission_doctypes
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ class Company(Document):
|
|||||||
if for_company != self.name:
|
if for_company != self.name:
|
||||||
frappe.throw(_("Account {0} does not belong to company: {1}")
|
frappe.throw(_("Account {0} does not belong to company: {1}")
|
||||||
.format(self.get(field), self.name))
|
.format(self.get(field), self.name))
|
||||||
|
|
||||||
def validate_currency(self):
|
def validate_currency(self):
|
||||||
self.previous_default_currency = frappe.db.get_value("Company", self.name, "default_currency")
|
self.previous_default_currency = frappe.db.get_value("Company", self.name, "default_currency")
|
||||||
if self.default_currency and self.previous_default_currency and \
|
if self.default_currency and self.previous_default_currency and \
|
||||||
self.default_currency != self.previous_default_currency and \
|
self.default_currency != self.previous_default_currency and \
|
||||||
self.check_if_transactions_exist():
|
self.check_if_transactions_exist():
|
||||||
frappe.throw(_("Cannot change company's default currency, because there are existing transactions. Transactions must be cancelled to change the default currency."))
|
frappe.throw(_("Cannot change company's default currency, because there are existing transactions. Transactions must be cancelled to change the default currency."))
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
if not frappe.db.sql("""select name from tabAccount
|
if not frappe.db.sql("""select name from tabAccount
|
||||||
@ -208,7 +208,7 @@ class Company(Document):
|
|||||||
|
|
||||||
# clear default accounts, warehouses from item
|
# clear default accounts, warehouses from item
|
||||||
if warehouses:
|
if warehouses:
|
||||||
|
|
||||||
for f in ["default_warehouse", "website_warehouse"]:
|
for f in ["default_warehouse", "website_warehouse"]:
|
||||||
frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
|
frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
|
||||||
% (f, f, ', '.join(['%s']*len(warehouses))), tuple(warehouses))
|
% (f, f, ', '.join(['%s']*len(warehouses))), tuple(warehouses))
|
||||||
@ -257,3 +257,7 @@ def get_name_with_abbr(name, company):
|
|||||||
parts.append(company_abbr)
|
parts.append(company_abbr)
|
||||||
|
|
||||||
return " - ".join(parts)
|
return " - ".join(parts)
|
||||||
|
|
||||||
|
def get_company_currency(company):
|
||||||
|
return frappe.local_cache("company_currency", company,
|
||||||
|
lambda: frappe.db.get_value("Company", company, "default_currency"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user