Payment Entry from invoice
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 9ff64eb..81fe436 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -525,13 +525,10 @@
 			d.party_balance = party_balance[(d.party_type, d.party)]
 
 @frappe.whitelist()
-def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None, account=None):
+def get_default_bank_cash_account(company, voucher_type=None, mode_of_payment=None, account=None):
 	from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
 	if mode_of_payment:
-		account = get_bank_cash_account(mode_of_payment, company)
-		if account.get("account"):
-			account.update({"balance": get_balance_on(account.get("account"))})
-			return account
+		account = get_bank_cash_account(mode_of_payment, company).get("account")
 
 	if not account:
 		if voucher_type=="Bank Entry":
@@ -549,12 +546,13 @@
 	if account:
 		account_details = frappe.db.get_value("Account", account,
 			["account_currency", "account_type"], as_dict=1)
-		return {
+			
+		return frappe._dict({
 			"account": account,
 			"balance": get_balance_on(account),
 			"account_currency": account_details.account_currency,
 			"account_type": account_details.account_type
-		}
+		})
 
 @frappe.whitelist()
 def get_payment_entry_against_order(dt, dn, amount=None, debit_in_account_currency=None, journal_entry=False, bank_account=None):
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index da4f10d..52834d4 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -4,8 +4,8 @@
 frappe.ui.form.on('Payment Entry', {
 	onload: function(frm) {
 		if(frm.doc.__islocal) {
-			frm.set_value("paid_from_account_currency", null);
-			frm.set_value("paid_to_account_currency", null);
+			if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
+			if (!frm.doc.paid_to) frm.set_value("paid_to_account_currency", null);
 		}
 	},
 	
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 0e5d8e7..dae7bda 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -5,10 +5,11 @@
 from __future__ import unicode_literals
 import frappe, json
 from frappe import _, scrub
-from frappe.utils import flt, comma_or
+from frappe.utils import flt, comma_or, nowdate
 from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
 from erpnext.accounts.party import get_party_account
-from erpnext.accounts.doctype.journal_entry.journal_entry import get_average_exchange_rate
+from erpnext.accounts.doctype.journal_entry.journal_entry \
+	import get_average_exchange_rate, get_default_bank_cash_account
 from erpnext.setup.utils import get_exchange_rate
 from erpnext.accounts.general_ledger import make_gl_entries
 
@@ -16,9 +17,7 @@
 
 
 class PaymentEntry(AccountsController):
-	def __init__(self, arg1, arg2=None):
-		super(PaymentEntry, self).__init__(arg1, arg2)
-		
+	def setup_party_account_field(self):		
 		self.party_account_field = None
 		self.party_account = None
 		self.party_account_currency = None
@@ -32,8 +31,11 @@
 			self.party_account_field = "paid_to"
 			self.party_account = self.paid_to
 			self.party_account_currency = self.paid_to_account_currency
+			
+		print self.payment_type, self.party_account_field
 				
 	def validate(self):
+		self.setup_party_account_field()
 		self.set_missing_values()
 		self.validate_party_details()
 		self.validate_bank_accounts()
@@ -69,11 +71,10 @@
 				self.party_balance = get_balance_on(party_type=self.party_type,
 					party=self.party, date=self.posting_date)
 			
-			if not self.get(self.party_account_field):
+			if not self.party_account:
 				party_account = get_party_account(self.party_type, self.party, self.company)
 				self.set(self.party_account_field, party_account)
-				
-			self.party_account = self.get(self.party_account_field)
+				self.party_account = party_account
 				
 		if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
 			acc = get_account_currency_and_balance(self.paid_from, self.posting_date)
@@ -187,7 +188,6 @@
 		self.total_allocated_amount, self.base_total_allocated_amount = 0, 0
 		for d in self.get("references"):
 			if d.allocated_amount:
-				print d.reference_name, d.outstanding_amount, d.allocated_amount
 				if d.allocated_amount > d.outstanding_amount:
 					frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount")
 						.format(d.idx))
@@ -439,4 +439,59 @@
 			frappe.throw(_("Please set default {0} in Company {1}")
 				.format(frappe.get_meta("Company").get_label(fieldname), company))
 	
-	return ret
\ No newline at end of file
+	return ret
+	
+@frappe.whitelist()
+def get_payment_entry_against_invoice(dt, dn):
+	invoice = frappe.get_doc(dt, dn)
+	
+	if dt == "Sales Invoice":
+		party_type = "Customer"
+		party_account = invoice.debit_to
+	else:
+		party_type = "Supplier"
+		party_account = invoice.credit_to
+
+
+	if (dt=="Sales Invoice" and invoice.outstanding_amount > 0) \
+		or (dt=="Purchase Invoice" and invoice.outstanding_amount < 0):
+			payment_type = "Receive"
+	else:
+		payment_type = "Pay"
+	
+	bank = frappe._dict()
+	if invoice.mode_of_payment:
+		bank = get_default_bank_cash_account(invoice.company, mode_of_payment=invoice.mode_of_payment)
+	
+	paid_amount = received_amount = 0
+	if invoice.party_account_currency == bank.account_currency:
+		paid_amount = received_amount = invoice.outstanding_amount
+	elif payment_type == "Receive":
+		paid_amount = invoice.outstanding_amount
+	else:
+		received_amount = invoice.outstanding_amount
+			
+	pe = frappe.new_doc("Payment Entry")
+	pe.payment_type = payment_type
+	pe.company = invoice.company
+	pe.posting_date = nowdate()
+	pe.mode_of_payment = invoice.mode_of_payment
+	pe.party_type = party_type
+	pe.party = invoice.get(scrub(party_type))
+	pe.paid_from = party_account if payment_type=="Receive" else bank.account
+	pe.paid_to = party_account if payment_type=="Pay" else bank.account
+	pe.paid_amount = paid_amount
+	pe.received_amount = received_amount
+	
+	pe.append("references", {
+		"reference_doctype": dt,
+		"reference_name": dn,
+		"allocated_amount": invoice.outstanding_amount
+	})
+	
+	pe.setup_party_account_field()
+	pe.set_missing_values()
+	pe.set_exchange_rate()
+	pe.set_amounts()
+	
+	return pe
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 7a83c7b..e919c4b 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -35,7 +35,7 @@
 
 		if(!doc.is_return && doc.docstatus==1) {
 			if(doc.outstanding_amount > 0) {
-				this.frm.add_custom_button(__('Payment'), this.make_bank_entry, __("Make"));
+				this.frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
 				cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
 			}
 
@@ -218,21 +218,6 @@
 	}
 }
 
-cur_frm.cscript.make_bank_entry = function() {
-	return frappe.call({
-		method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice",
-		args: {
-			"dt": "Purchase Invoice",
-			"dn": cur_frm.doc.name
-		},
-		callback: function(r) {
-			var doclist = frappe.model.sync(r.message);
-			frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
-		}
-	});
-}
-
-
 cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
 	return{
 		filters:{'supplier':  doc.supplier}
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 09ff5b2..95ad98a 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -67,7 +67,7 @@
 
 			if(doc.outstanding_amount>0 && !cint(doc.is_return)) {
 				cur_frm.add_custom_button(__('Payment Request'), this.make_payment_request, __("Make"));
-				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry, __("Make"));
+				cur_frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
 			}
 
 		}
@@ -280,20 +280,6 @@
 	})
 }
 
-cur_frm.cscript.make_bank_entry = function() {
-	return frappe.call({
-		method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice",
-		args: {
-			"dt": "Sales Invoice",
-			"dn": cur_frm.doc.name
-		},
-		callback: function(r) {
-			var doclist = frappe.model.sync(r.message);
-			frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
-		}
-	});
-}
-
 cur_frm.fields_dict.cash_bank_account.get_query = function(doc) {
 	return {
 		filters: [
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index a6fbff7..82cb365 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -704,7 +704,8 @@
 	account = frappe.db.get_value("Mode of Payment Account",
 		{"parent": mode_of_payment, "company": company}, "default_account")
 	if not account:
-		frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}").format(mode_of_payment))
+		frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
+			.format(mode_of_payment))
 	return {
 		"account": account
 	}
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 048a534..b1f55df 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -316,6 +316,7 @@
 		new_row.update(reference_details)
 		
 	payment_entry.flags.ignore_validate_update_after_submit = True
+	payment_entry.setup_party_account_field()
 	payment_entry.set_missing_values()
 	payment_entry.set_amounts()
 	payment_entry.save(ignore_permissions=True)
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 5185614..1c7d032 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -312,7 +312,7 @@
 			
 		order_list = list(set([d.get(order_field) 
 			for d in self.get("items") if d.get(order_field)]))
-
+		
 		journal_entries = get_advance_journal_entries(party_type, party, party_account, 
 			amount_field, order_doctype, order_list, include_unallocated)
 			
@@ -324,6 +324,12 @@
 		return res
 
 	def validate_advance_entries(self):
+		order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
+		order_list = list(set([d.get(order_field) 
+			for d in self.get("items") if d.get(order_field)]))
+		
+		if not order_list: return
+		
 		advance_entries = self.get_advance_entries(include_unallocated=False)
 		
 		if advance_entries:
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ad6901c..a7f7e2a 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1000,5 +1000,19 @@
 				}
 			})
 		}
+	},
+	
+	make_payment_entry: function() {
+		return frappe.call({
+			method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry_against_invoice",
+			args: {
+				"dt": cur_frm.doc.doctype,
+				"dn": cur_frm.doc.name
+			},
+			callback: function(r) {
+				var doclist = frappe.model.sync(r.message);
+				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+			}
+		});
 	}
 });
\ No newline at end of file