[fix] added validation to match account currency with existing gle and test case
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 5551ab7..3927b8e 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -6,12 +6,10 @@
 from frappe import _
 from frappe.utils import flt, fmt_money, getdate, formatdate
 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
-
-class CustomerFrozen(frappe.ValidationError): pass
-class InvalidCurrency(frappe.ValidationError): pass
-class InvalidAccountCurrency(frappe.ValidationError): pass
+from erpnext.setup.doctype.company.company import get_company_currency
+from erpnext.exceptions import InvalidAccountCurrency, CustomerFrozen
 
 class GLEntry(Document):
 	def validate(self):
@@ -103,16 +101,16 @@
 					frappe.throw("{0} {1} is frozen".format(self.party_type, self.party), CustomerFrozen)
 
 	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)
 
 		if not self.account_currency:
 			self.account_currency = company_currency
+
 		if account_currency != self.account_currency:
 			frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
 				.format(self.account, (account_currency or company_currency)), InvalidAccountCurrency)
 
-
 		if self.party_type and self.party:
 			party_account_currency = get_party_account_currency(self.party_type, self.party, self.company)
 
@@ -120,6 +118,8 @@
 				frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")
 					.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):
 	if not adv_adj and account:
 		balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 753e012..a4d6406 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -5,6 +5,7 @@
 import unittest, frappe
 from frappe.utils import flt
 from erpnext.accounts.utils import get_actual_expense, BudgetError, get_fiscal_year
+from erpnext.exceptions import InvalidAccountCurrency
 
 
 class TestJournalEntry(unittest.TestCase):
@@ -166,15 +167,15 @@
 		existing_expense = self.get_actual_expense(posting_date)
 		make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_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, 
+
+		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)
@@ -197,12 +198,10 @@
 				"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()
@@ -212,6 +211,40 @@
 
 		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):
 	jv = frappe.new_doc("Journal Entry")
 	jv.posting_date = "2013-02-14"
@@ -231,7 +264,7 @@
 			"cost_center": cost_center,
 			"credit_in_account_currency": 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:
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index b39f30b..67286db 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -10,7 +10,7 @@
 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
+from erpnext.exceptions import InvalidCurrency
 
 test_dependencies = ["Item", "Cost Center"]
 test_ignore = ["Serial No"]
@@ -219,7 +219,7 @@
 		pi.load_from_db()
 
 		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))
 
 		self.assertEqual(pi.outstanding_amount, 1212.30)
@@ -237,17 +237,17 @@
 		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""")
 		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")
-		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)
 
 		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)
 
 		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)
 
 		pi.cancel()
@@ -278,14 +278,14 @@
 			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", 
+
+		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, 
+		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)
@@ -308,16 +308,16 @@
 				"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
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 449f98d..0eae7cb 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -7,8 +7,7 @@
 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
+from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
 
 class TestSalesInvoice(unittest.TestCase):
 	def make(self):
@@ -842,13 +841,13 @@
 		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", 
+		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, 
+		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)
@@ -871,7 +870,7 @@
 				"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])
@@ -883,38 +882,38 @@
 			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", 
+		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", 
+		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", 
+		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", 
+		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", 
+		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):
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 8181feb..1eaf8a7 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -10,6 +10,7 @@
 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.contact.contact import get_contact_details
+from erpnext.exceptions import InvalidAccountCurrency
 
 class DuplicatePartyAccountError(frappe.ValidationError): pass
 
@@ -191,6 +192,25 @@
 
 	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):
 	companies = []
 
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 4f3e6c8..a92d070 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -10,13 +10,11 @@
 from erpnext.utilities.transaction_base import TransactionBase
 from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
 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")
 
-class CustomerFrozen(frappe.ValidationError): pass
-class InvalidCurrency(frappe.ValidationError): pass
-
 class AccountsController(TransactionBase):
 	def __init__(self, arg1, arg2=None):
 		super(AccountsController, self).__init__(arg1, arg2)
diff --git a/erpnext/exceptions.py b/erpnext/exceptions.py
new file mode 100644
index 0000000..c339edf
--- /dev/null
+++ b/erpnext/exceptions.py
@@ -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
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index 4bd02d5..f18194f 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -7,7 +7,7 @@
 import unittest
 
 from frappe.test_runner import make_test_records
-from erpnext.controllers.accounts_controller import CustomerFrozen
+from erpnext.exceptions import CustomerFrozen
 
 test_ignore = ["Price List"]
 
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index ccb792f..ba5f025 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -7,6 +7,8 @@
 import unittest
 from erpnext.selling.doctype.sales_order.sales_order \
 	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
 
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 785e7aa..d337805 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -46,13 +46,13 @@
 					if for_company != self.name:
 						frappe.throw(_("Account {0} does not belong to company: {1}")
 							.format(self.get(field), self.name))
-							
+
 	def validate_currency(self):
 		self.previous_default_currency = frappe.db.get_value("Company", self.name, "default_currency")
 		if self.default_currency and self.previous_default_currency and \
 			self.default_currency != self.previous_default_currency and \
 			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):
 		if not frappe.db.sql("""select name from tabAccount
@@ -208,7 +208,7 @@
 
 		# clear default accounts, warehouses from item
 		if warehouses:
-			
+
 			for f in ["default_warehouse", "website_warehouse"]:
 				frappe.db.sql("""update tabItem set %s=NULL where %s in (%s)"""
 					% (f, f, ', '.join(['%s']*len(warehouses))), tuple(warehouses))
@@ -257,3 +257,7 @@
 		parts.append(company_abbr)
 
 	return " - ".join(parts)
+
+def get_company_currency(company):
+	return frappe.local_cache("company_currency", company,
+		lambda: frappe.db.get_value("Company", company, "default_currency"))