Outstanding, paid and write-off amount in Invoice
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 7693e08..f372cd8 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -157,20 +157,9 @@
 	},
 	add_deduct_tax: function(doc, cdt, cdn) {
 		this.calculate_taxes_and_totals();
-	},
-
-	calculate_outstanding_amount: function() {
-		if(this.frm.doc.doctype == "Purchase Invoice" && this.frm.doc.docstatus < 2) {
-			frappe.model.round_floats_in(this.frm.doc, ["base_grand_total", "total_advance", "write_off_amount"]);
-			this.frm.doc.total_amount_to_pay = flt(this.frm.doc.base_grand_total - this.frm.doc.write_off_amount,
-				precision("total_amount_to_pay"));
-			if (!this.frm.doc.is_return) {
-				this.frm.doc.outstanding_amount = flt(this.frm.doc.total_amount_to_pay - this.frm.doc.total_advance,
-					precision("outstanding_amount"));
-			}
-		}
 	}
 });
+
 cur_frm.add_fetch('project_name', 'cost_center', 'cost_center');
 
 erpnext.buying.get_default_bom = function(frm) {
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 7775cb3..6ba954f 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -18,8 +18,13 @@
 class AccountsController(TransactionBase):
 	def __init__(self, arg1, arg2=None):
 		super(AccountsController, self).__init__(arg1, arg2)
-		if self.get("company"):
-			self.company_currency = get_company_currency(self.company)
+		
+	@property
+	def company_currency(self):
+		if not hasattr(self, "__company_currency"):
+			self.__company_currency = get_company_currency(self.company)
+			
+		return self.__company_currency
 		
 	def validate(self):
 		if self.get("_action") and self._action != "update_after_submit":
@@ -221,10 +226,10 @@
 		return gl_dict
 		
 	def validate_account_currency(self, account, account_currency=None):
-		valid_currency = list(set(self.currency, self.company_currency))
+		valid_currency = list(set([self.currency, self.company_currency]))
 		if account_currency not in valid_currency:
-			frappe.throw(_("Invalid Account {0}. Account Currency must be {1}")
-				.format(account, "or".join(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:
@@ -397,22 +402,28 @@
 		if frozen_accounts_modifier in frappe.get_roles():
 			return
 
+		party_type, party = self.get_party()
+
+		if party_type:
+			if frappe.db.get_value(party_type, party, "is_frozen"): 
+				frappe.throw("{0} {1} is frozen".format(party_type, party), CustomerFrozen)
+				
+	def get_party(self):
 		party_type = None
 		if self.meta.get_field("customer"):
 			party_type = 'Customer'
 
 		elif self.meta.get_field("supplier"):
 			party_type = 'Supplier'
-
-		if party_type:
-			party = self.get(party_type.lower())
-			if frappe.db.get_value(party_type, party, "is_frozen"): 
-				frappe.throw("{0} {1} is frozen".format(party_type, party), CustomerFrozen)
-				
-		self.validate_currency(party_type, party)
-				
-	def validate_currency(self, party_type, party):
+			
+		party = self.get(party_type.lower()) if party_type else None
+		
+		return party_type, party
+								
+	def validate_currency(self):
 		if self.get("currency") and self.currency != self.company_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
@@ -420,7 +431,8 @@
 			if existing_gle:
 				if currency_in_existing_entries != self.company_currency \
 					and currency_in_existing_entries != self.currency:
-						frappe.throw(_("Currency must be {0}").format(currency_in_existing_entries))
+						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:
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index d526f66..0fbe22d 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -394,17 +394,21 @@
 		# NOTE:
 		# write_off_amount is only for POS Invoice
 		# total_advance is only for non POS Invoice
-
+		if self.doc.is_return:
+			return
+		
+		self.doc.round_floats_in(self.doc, ["grand_total", "total_advance", "write_off_amount"])
+		total_amount_to_pay = flt(self.doc.grand_total  - self.doc.total_advance - self.doc.write_off_amount,
+			self.doc.precision("grand_total"))
+			
 		if self.doc.doctype == "Sales Invoice":
-			if not self.doc.is_return:
-				self.doc.round_floats_in(self.doc, ["base_grand_total", "total_advance", "write_off_amount", "paid_amount"])
-				total_amount_to_pay = self.doc.base_grand_total - self.doc.write_off_amount
-				self.doc.outstanding_amount = flt(total_amount_to_pay - self.doc.total_advance - self.doc.paid_amount,
-					self.doc.precision("outstanding_amount"))
+			self.doc.round_floats_in(self.doc, ["paid_amount"])
+			outstanding_amount = flt(total_amount_to_pay - self.doc.paid_amount, self.doc.precision("outstanding_amount"))
+		elif self.doc.doctype == "Purchase Invoice":
+			outstanding_amount = flt(total_amount_to_pay, self.doc.precision("outstanding_amount"))
+		
+		if self.doc.party_account_currency == self.doc.currency:
+			self.doc.outstanding_amount = outstanding_amount
 		else:
-			self.doc.round_floats_in(self.doc, ["total_advance", "write_off_amount"])
-			self.doc.total_amount_to_pay = flt(self.doc.base_grand_total - self.doc.write_off_amount,
-				self.doc.precision("total_amount_to_pay"))
-			if not self.doc.is_return:
-				self.doc.outstanding_amount = flt(self.doc.total_amount_to_pay - self.doc.total_advance,
-					self.doc.precision("outstanding_amount"))
+			self.doc.outstanding_amount = flt(outstanding_amount * self.doc.conversion_rate, 
+				self.doc.precision("outstanding_amount"))
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 0b3ca7f..ad794d6 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -491,5 +491,45 @@
 		this.frm.doc.total_advance = flt(total_allocated_amount, precision("total_advance"));
 
 		this.calculate_outstanding_amount(update_paid_amount);
+	},
+	
+	calculate_outstanding_amount: function(update_paid_amount) {
+		// NOTE:
+		// paid_amount and write_off_amount is only for POS Invoice
+		// total_advance is only for non POS Invoice
+		if(this.frm.doc.is_return || this.frm.doc.docstatus > 0) return;
+		
+		frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]);
+		
+		var total_amount_to_pay = flt((this.frm.doc.grand_total - this.frm.doc.total_advance 
+			- this.frm.doc.write_off_amount), precision("grand_total"));
+		
+		if(this.frm.doc.doctype == "Sales Invoice") {
+			frappe.model.round_floats_in(this.frm.doc, ["paid_amount"]);
+			
+			if(this.frm.doc.is_pos) {
+				if(!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount) {
+					this.frm.doc.paid_amount = flt(total_amount_to_pay);
+				}
+			} else {
+				this.frm.doc.paid_amount = 0
+			}
+			this.set_in_company_currency(this.frm.doc, ["paid_amount"]);
+			this.frm.refresh_field("paid_amount");
+			this.frm.refresh_field("base_paid_amount");
+			
+			var outstanding_amount =  flt(total_amount_to_pay - this.frm.doc.paid_amount, 
+				precision("outstanding_amount"));
+				
+		} else if(this.frm.doc.doctype == "Purchase Invoice") {
+			var outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
+		}
+		
+		if(this.frm.doc.party_account_currency == this.frm.doc.currency) {			
+			this.frm.set_value("outstanding_amount", outstanding_amount);
+		} else {
+			this.frm.set_value("outstanding_amount", 
+				flt(outstanding_amount * this.frm.doc.conversion_rate, precision("outstanding_amount")));
+		}
 	}
 })
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ba10702..5cc75b6 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -415,11 +415,14 @@
 		setup_field_label_map(["base_total", "base_net_total", "base_total_taxes_and_charges",
 			"base_discount_amount", "base_grand_total", "base_rounded_total", "base_in_words",
 			"base_taxes_and_charges_added", "base_taxes_and_charges_deducted", "total_amount_to_pay",
-			"outstanding_amount", "total_advance", "paid_amount", "write_off_amount"], company_currency);
+			"base_paid_amount", "base_write_off_amount"
+		], company_currency);
 
 		setup_field_label_map(["total", "net_total", "total_taxes_and_charges", "discount_amount",
 			"grand_total", "taxes_and_charges_added", "taxes_and_charges_deducted",
-			"rounded_total", "in_words"], this.frm.doc.currency);
+			"rounded_total", "in_words", "paid_amount", "write_off_amount"], this.frm.doc.currency);
+			
+		setup_field_label_map(["outstanding_amount", "total_advance"], this.frm.doc.party_account_currency);
 
 		cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
 			+ " = [?] " + company_currency)
@@ -432,7 +435,8 @@
 		// toggle fields
 		this.frm.toggle_display(["conversion_rate", "base_total", "base_net_total", "base_total_taxes_and_charges",
 			"base_taxes_and_charges_added", "base_taxes_and_charges_deducted",
-			"base_grand_total", "base_rounded_total", "base_in_words", "base_discount_amount"],
+			"base_grand_total", "base_rounded_total", "base_in_words", "base_discount_amount",
+			"base_paid_amount", "base_write_off_amount"],
 			this.frm.doc.currency != company_currency);
 
 		this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
diff --git a/erpnext/public/js/pos/pos.js b/erpnext/public/js/pos/pos.js
index 5f82796..02eeab0 100644
--- a/erpnext/public/js/pos/pos.js
+++ b/erpnext/public/js/pos/pos.js
@@ -473,13 +473,11 @@
 			}
 			me.frm.set_value("mode_of_payment", values.mode_of_payment);
 
-			//me.frm.cscript.calculate_taxes_and_totals();
-
-			var paid_amount = flt((flt(values.paid_amount) - flt(values.change)) / me.frm.doc.conversion_rate, precision("paid_amount"));
+			var paid_amount = flt((flt(values.paid_amount) - flt(values.change)), precision("paid_amount"));
 			me.frm.set_value("paid_amount", paid_amount);
-
+			
 			// specifying writeoff amount here itself, so as to avoid recursion issue
-			me.frm.set_value("write_off_amount", me.frm.doc.base_grand_total - paid_amount);
+			me.frm.set_value("write_off_amount", me.frm.doc.grand_total - paid_amount);
 			me.frm.set_value("outstanding_amount", 0);
 
 			me.frm.savesubmit(this);
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 5404947..6a8744a 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -206,30 +206,6 @@
 		}
 	},
 
-	calculate_outstanding_amount: function(update_paid_amount) {
-		// NOTE:
-		// paid_amount and write_off_amount is only for POS Invoice
-		// total_advance is only for non POS Invoice
-		if(this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.docstatus==0 && !this.frm.doc.is_return) {
-			frappe.model.round_floats_in(this.frm.doc, ["base_grand_total", "total_advance", "write_off_amount",
-				"paid_amount"]);
-			var total_amount_to_pay = this.frm.doc.base_grand_total - this.frm.doc.write_off_amount
-				- this.frm.doc.total_advance;
-			if(this.frm.doc.is_pos) {
-				if(!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount) {
-					this.frm.doc.paid_amount = flt(total_amount_to_pay);
-					this.frm.refresh_field("paid_amount");
-				}
-			} else {
-				this.frm.doc.paid_amount = 0
-				this.frm.refresh_field("paid_amount");
-			}
-
-			this.frm.set_value("outstanding_amount", flt(total_amount_to_pay
-				- this.frm.doc.paid_amount, precision("outstanding_amount")));
-		}
-	},
-
 	calculate_commission: function() {
 		if(this.frm.fields_dict.commission_rate) {
 			if(this.frm.doc.commission_rate > 100) {