Merge pull request #5620 from nabinhait/payment_entry

Payment Entry
diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py
index 4580d02..5744721 100644
--- a/erpnext/accounts/doctype/account/test_account.py
+++ b/erpnext/accounts/doctype/account/test_account.py
@@ -12,6 +12,7 @@
 		["_Test Bank", "Bank Accounts", 0, "Bank", None],
 		["_Test Bank USD", "Bank Accounts", 0, "Bank", "USD"],
 		["_Test Bank EUR", "Bank Accounts", 0, "Bank", "EUR"],
+		["_Test Cash", "Cash In Hand", 0, "Cash", None],
 
 		["_Test Account Stock Expenses", "Direct Expenses", 1, None, None],
 		["_Test Account Shipping Charges", "_Test Account Stock Expenses", 0, "Chargeable", None],
@@ -32,6 +33,7 @@
 		["_Test Account CST", "Direct Expenses", 0, "Tax", None],
 		["_Test Account Discount", "Direct Expenses", 0, None, None],
 		["_Test Write Off", "Indirect Expenses", 0, None, None],
+		["_Test Exchange Gain/Loss", "Indirect Expenses", 0, None, None],
 
 		# related to Account Inventory Integration
 		["_Test Account Stock In Hand", "Current Assets", 0, None, None],
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index d46c2d5..aca83da 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -91,6 +91,55 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "column_break_4", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "allow_payment_entry_via_journal_entry", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Allow Payment Entry via Journal Entry", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "description": "Role that is allowed to submit transactions that exceed credit limits set.", 
    "fieldname": "credit_controller", 
    "fieldtype": "Link", 
@@ -150,7 +199,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-06-27 15:18:27.566087", 
+ "modified": "2016-06-27 15:18:28.566087", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Accounts Settings", 
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
index 3de8241..4b33fd3 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
@@ -3,11 +3,22 @@
 
 frappe.ui.form.on("Bank Reconciliation", {
 	setup: function(frm) {
-		frm.get_docfield("journal_entries").allow_bulk_edit = 1;
+		frm.get_docfield("payment_entries").allow_bulk_edit = 1;
 		frm.add_fetch("bank_account", "account_currency", "account_currency");
+		
+		frm.get_field('payment_entries').grid.editable_fields = [
+			{fieldname: 'against_account', columns: 3},
+			{fieldname: 'amount', columns: 2},
+			{fieldname: 'cheque_number', columns: 3},
+			{fieldname: 'clearance_date', columns: 3}
+		];
 	},
 
 	onload: function(frm) {
+		var default_bank_account =  locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"];
+		
+		frm.set_value("bank_account", default_bank_account);
+		
 		frm.set_query("bank_account", function() {
 			return {
 				"filters": {
@@ -27,16 +38,21 @@
 
 	update_clearance_date: function(frm) {
 		return frappe.call({
-			method: "update_details",
-			doc: frm.doc
-		});
-	},
-	get_relevant_entries: function(frm) {
-		return frappe.call({
-			method: "get_details",
+			method: "update_clearance_date",
 			doc: frm.doc,
 			callback: function(r, rt) {
-				frm.refresh()
+				frm.refresh_field("payment_entries");
+				frm.refresh_fields();
+			}
+		});
+	},
+	get_payment_entries: function(frm) {
+		return frappe.call({
+			method: "get_payment_entries",
+			doc: frm.doc,
+			callback: function(r, rt) {
+				frm.refresh_field("payment_entries");
+				frm.refresh_fields();
 			}
 		});
 	}
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json
index 59a3cfc..1a7b763 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json
@@ -2,6 +2,7 @@
  "allow_copy": 1, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2013-01-10 16:34:05", 
  "custom": 0, 
  "docstatus": 0, 
@@ -16,6 +17,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Bank Account", 
@@ -40,6 +42,7 @@
    "fieldtype": "Link", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Account Currency", 
@@ -64,6 +67,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "From Date", 
@@ -87,6 +91,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "To Date", 
@@ -110,6 +115,7 @@
    "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Include Reconciled Entries", 
@@ -129,13 +135,14 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "get_relevant_entries", 
+   "fieldname": "get_payment_entries", 
    "fieldtype": "Button", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Get Relevant Entries", 
+   "label": "Get Payment Entries", 
    "length": 0, 
    "no_copy": 0, 
    "options": "", 
@@ -153,13 +160,14 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "journal_entries", 
+   "fieldname": "payment_entries", 
    "fieldtype": "Table", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Journal Entries", 
+   "label": "Payment Entries", 
    "length": 0, 
    "no_copy": 0, 
    "options": "Bank Reconciliation Detail", 
@@ -181,6 +189,7 @@
    "fieldtype": "Button", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Update Clearance Date", 
@@ -205,6 +214,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Total Amount", 
@@ -226,6 +236,7 @@
  "hide_toolbar": 1, 
  "icon": "icon-check", 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
@@ -233,7 +244,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2015-11-30 12:44:45.105451", 
+ "modified": "2016-06-28 13:11:09.396353", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Bank Reconciliation", 
@@ -260,7 +271,10 @@
    "write": 1
   }
  ], 
+ "quick_entry": 1, 
  "read_only": 1, 
  "read_only_onload": 0, 
+ "sort_order": "ASC", 
+ "track_seen": 0, 
  "version": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index fb95731..b07c82d 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -12,7 +12,7 @@
 }
 
 class BankReconciliation(Document):
-	def get_details(self):
+	def get_payment_entries(self):
 		if not (self.bank_account and self.from_date and self.to_date):
 			msgprint("Bank Account, From Date and To Date are Mandatory")
 			return
@@ -22,48 +22,68 @@
 			condition = "and (clearance_date is null or clearance_date='0000-00-00')"
 
 
-		dl = frappe.db.sql("""select t1.name, t1.cheque_no, t1.cheque_date, t2.debit_in_account_currency,
-				t2.credit_in_account_currency, t1.posting_date, t2.against_account, t1.clearance_date
+		journal_entries = frappe.db.sql("""
+			select 
+				"Journal Entry" as payment_document, t1.name as payment_entry, 
+				t1.cheque_no as cheque_number, t1.cheque_date, 
+				abs(t2.debit_in_account_currency - t2.credit_in_account_currency) as amount, 
+				t1.posting_date, t2.against_account, t1.clearance_date
 			from
 				`tabJournal Entry` t1, `tabJournal Entry Account` t2
 			where
-				t2.parent = t1.name and t2.account = %s
-				and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1
-				and ifnull(t1.is_opening, 'No') = 'No' %s
-				order by t1.posting_date DESC, t1.name DESC""" %
-				('%s', '%s', '%s', condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
-
-		self.set('journal_entries', [])
+				t2.parent = t1.name and t2.account = %s and t1.docstatus=1
+				and t1.posting_date >= %s and t1.posting_date <= %s 
+				and ifnull(t1.is_opening, 'No') = 'No' {0}
+			order by t1.posting_date DESC, t1.name DESC
+		""".format(condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
+				
+		payment_entries = frappe.db.sql("""
+			select 
+				"Payment Entry" as payment_document, name as payment_entry, 
+				reference_no as cheque_number, reference_date as cheque_date, 
+				if(paid_from=%s, paid_amount, received_amount) as amount, 
+				posting_date, party as against_account, clearance_date
+			from `tabPayment Entry`
+			where
+				(paid_from=%s or paid_to=%s) and docstatus=1
+				and posting_date >= %s and posting_date <= %s {0}
+			order by 
+				posting_date DESC, name DESC
+		""".format(condition), 
+		(self.bank_account, self.bank_account, self.bank_account, self.from_date, self.to_date), as_dict=1)
+		
+		entries = sorted(list(payment_entries)+list(journal_entries), 
+			key=lambda k: k['posting_date'] or getdate(nowdate()))
+				
+		self.set('payment_entries', [])
 		self.total_amount = 0.0
 
-		for d in dl:
-			nl = self.append('journal_entries', {})
-			nl.posting_date = d.posting_date
-			nl.voucher_id = d.name
-			nl.cheque_number = d.cheque_no
-			nl.cheque_date = d.cheque_date
-			nl.debit = d.debit_in_account_currency
-			nl.credit = d.credit_in_account_currency
-			nl.against_account = d.against_account
-			nl.clearance_date = d.clearance_date
-			self.total_amount += flt(d.debit_in_account_currency) - flt(d.credit_in_account_currency)
+		for d in entries:
+			row = self.append('payment_entries', {})
+			row.update(d)
+			self.total_amount += flt(d.amount)
 
-	def update_details(self):
-		vouchers = []
-		for d in self.get('journal_entries'):
+	def update_clearance_date(self):
+		clearance_date_updated = False
+		for d in self.get('payment_entries'):
 			if d.clearance_date:
 				if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
-					frappe.throw(_("Clearance date cannot be before check date in row {0}").format(d.idx))
+					frappe.throw(_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}")
+						.format(d.idx, d.clearance_date, d.cheque_date))
 
 			if d.clearance_date or self.include_reconciled_entries:
 				if not d.clearance_date:
 					d.clearance_date = None
-				frappe.db.set_value("Journal Entry", d.voucher_id, "clearance_date", d.clearance_date)
-				frappe.db.sql("""update `tabJournal Entry` set clearance_date = %s, modified = %s
-					where name=%s""", (d.clearance_date, nowdate(), d.voucher_id))
-				vouchers.append(d.voucher_id)
 
-		if vouchers:
-			msgprint("Clearance Date updated in: {0}".format(", ".join(vouchers)))
+				frappe.db.set_value(d.payment_document, d.payment_entry, "clearance_date", d.clearance_date)
+				frappe.db.sql("""update `tab{0}` set clearance_date = %s, modified = %s 
+					where name=%s""".format(d.payment_document), 
+				(d.clearance_date, nowdate(), d.payment_entry))
+				
+				clearance_date_updated = True
+
+		if clearance_date_updated:
+			self.get_payment_entries()
+			msgprint(_("Clearance Date updated"))
 		else:
 			msgprint(_("Clearance Date not mentioned"))
diff --git a/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json b/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
index fc3c3b6..b56ad8b 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
+++ b/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
@@ -2,6 +2,7 @@
  "allow_copy": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2013-02-22 01:27:37", 
  "custom": 0, 
  "docstatus": 0, 
@@ -11,18 +12,45 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "voucher_id", 
+   "fieldname": "payment_document", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Payment Document", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "DocType", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "payment_entry", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
-   "label": "Voucher ID", 
+   "label": "Payment Entry", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldname": "voucher_id", 
    "oldfieldtype": "Link", 
-   "options": "Journal Entry", 
+   "options": "payment_document", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -42,6 +70,7 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Against Account", 
@@ -64,13 +93,14 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "debit", 
+   "fieldname": "amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Debit", 
+   "in_list_view": 1, 
+   "label": "Amount", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldname": "debit", 
@@ -90,36 +120,11 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "credit", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Credit", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "credit", 
-   "oldfieldtype": "Currency", 
-   "options": "account_currency", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "column_break_5", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
@@ -144,8 +149,9 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "label": "Posting Date", 
    "length": 0, 
    "no_copy": 0, 
@@ -169,6 +175,7 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Cheque Number", 
@@ -194,6 +201,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Cheque Date", 
@@ -219,6 +227,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Clearance Date", 
@@ -240,6 +249,7 @@
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
@@ -247,12 +257,15 @@
  "istable": 1, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-02-17 06:50:40.074578", 
+ "modified": "2016-06-28 13:23:15.412477", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Bank Reconciliation Detail", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 1, 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "sort_order": "ASC", 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 1f95fb8..b90cd23 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -38,7 +38,7 @@
 					self.against_voucher)
 
 	def check_mandatory(self):
-		mandatory = ['account','remarks','voucher_type','voucher_no','company']
+		mandatory = ['account','voucher_type','voucher_no','company']
 		for k in mandatory:
 			if not self.get(k):
 				frappe.throw(_("{0} is required").format(_(self.meta.get_label(k))))
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index f670c90..cb6c36c 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -283,7 +283,8 @@
 				type: "GET",
 				method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
 				args: {
-					"voucher_type": doc.voucher_type,
+					"account_type": (doc.voucher_type=="Bank Entry" ? 
+						"Bank" : (doc.voucher_type=="Cash" ? "Cash" : null)),
 					"company": doc.company
 				},
 				callback: function(r) {
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 40386e0..96b95f9 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -525,22 +525,19 @@
 			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, account_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":
+		if account_type=="Bank":
 			account = frappe.db.get_value("Company", company, "default_bank_account")
 			if not account:
 				account = frappe.db.get_value("Account",
 					{"company": company, "account_type": "Bank", "is_group": 0})
 
-		elif voucher_type=="Cash Entry":
+		elif account_type=="Cash":
 			account = frappe.db.get_value("Company", company, "default_cash_account")
 			if not account:
 				account = frappe.db.get_value("Account",
@@ -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):
@@ -662,7 +660,7 @@
 	bank_row = je.append("accounts")
 
 	#make it bank_details
-	bank_account = get_default_bank_cash_account(ref_doc.company, "Bank Entry", account=args.get("bank_account"))
+	bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
 	if bank_account:
 		bank_row.update(bank_account)
 		bank_row.exchange_rate = get_exchange_rate(bank_account["account"],
@@ -814,7 +812,7 @@
 	company_currency = get_company_currency(company)
 
 	if account_currency != company_currency:
-		if reference_type and reference_name and frappe.get_meta(reference_type).get_field("conversion_rate"):
+		if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name:
 			exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate")
 
 		elif account_details and account_details.account_type == "Bank" and \
@@ -831,6 +829,7 @@
 	# don't return None or 0 as it is multipled with a value and that value could be lost
 	return exchange_rate or 1
 
+@frappe.whitelist()
 def get_average_exchange_rate(account):
 	exchange_rate = 0
 	bank_balance_in_account_currency = get_balance_on(account)
diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js
index 10807ff..9115c20 100644
--- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js
+++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js
@@ -2,11 +2,12 @@
 // License: GNU General Public License v3. See license.txt
 
 cur_frm.set_query("default_account", "accounts", function(doc, cdt, cdn) {
+	var d = locals[cdt][cdn];
 	return{
 		filters: [
 			['Account', 'account_type', 'in', 'Bank, Cash'],
 			['Account', 'is_group', '=', 0],
-			['Account', 'company', '=', doc.company]
+			['Account', 'company', '=', d.company]
 		]
 	}
 });
diff --git a/erpnext/accounts/doctype/payment_entry/__init__.py b/erpnext/accounts/doctype/payment_entry/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/__init__.py
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
new file mode 100644
index 0000000..230d728
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -0,0 +1,724 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Payment Entry', {
+	onload: function(frm) {
+		if(frm.doc.__islocal) {
+			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);
+		}
+	},
+	
+	setup: function(frm) {
+		frm.get_field('references').grid.editable_fields = [
+			{fieldname: 'reference_doctype', columns: 2},
+			{fieldname: 'reference_name', columns: 3},
+			{fieldname: 'outstanding_amount', columns: 3},
+			{fieldname: 'allocated_amount', columns: 3}
+		];
+		
+		var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
+				
+		frm.set_query("paid_from", function() {
+			var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ? 
+				["Bank", "Cash"] : party_account_type;
+
+			return {
+				filters: {
+					"account_type": ["in", account_types],
+					"is_group": 0,
+					"company": frm.doc.company
+				}
+			}
+		});
+		
+		frm.set_query("paid_to", function() {
+			var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ? 
+	 			["Bank", "Cash"] : party_account_type;
+			
+			return {
+				filters: {
+					"account_type": ["in", account_types],
+					"is_group": 0,
+					"company": frm.doc.company
+				}
+			}
+		});
+		
+		frm.set_query("account", "deductions", function() {
+			return {
+				filters: {
+					"is_group": 0,
+					"company": frm.doc.company
+				}
+			}
+		});
+		
+		frm.set_query("cost_center", "deductions", function() {
+			return {
+				filters: {
+					"is_group": 0,
+					"company": frm.doc.company
+				}
+			}
+		});
+		
+		frm.set_query("reference_doctype", "references", function() {
+			if (frm.doc.party_type=="Customer") {
+				var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry"];
+			} else if (frm.doc.party_type=="Supplier") {
+				var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
+			} else {
+				var doctypes = ["Journal Entry"];
+			}
+			
+			return {
+				filters: { "name": ["in", doctypes] }
+			};
+		});
+	},
+	
+	refresh: function(frm) {
+		frm.events.hide_unhide_fields(frm);
+		frm.events.set_dynamic_labels(frm);
+		frm.events.show_general_ledger(frm);
+	},
+	
+	hide_unhide_fields: function(frm) {
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+		
+		frm.toggle_display("source_exchange_rate", 
+			(frm.doc.paid_amount && frm.doc.paid_from_account_currency != company_currency));
+			
+		frm.toggle_display("target_exchange_rate", (frm.doc.received_amount && 
+			frm.doc.paid_to_account_currency != company_currency &&
+			frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
+			
+			frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
+			
+		frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency && 
+			frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
+				
+		frm.toggle_display("received_amount", 
+			frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency)
+				
+		frm.toggle_display(["base_total_allocated_amount"], 
+			(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.base_total_allocated_amount &&
+			((frm.doc.payment_type=="Receive" && frm.doc.paid_from_account_currency != company_currency) || 
+			(frm.doc.payment_type=="Pay" && frm.doc.paid_to_account_currency != company_currency))));
+			
+		var party_amount = frm.doc.payment_type=="Receive" ? 
+			frm.doc.paid_amount : frm.doc.received_amount;
+					
+		frm.toggle_display("write_off_difference_amount", (frm.doc.difference_amount && frm.doc.party &&
+			(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) && 
+			(frm.doc.total_allocated_amount > party_amount)));
+		
+		frm.toggle_display("set_exchange_gain_loss", 
+			(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount && 
+				(frm.doc.paid_from_account_currency != company_currency || 
+					frm.doc.paid_to_account_currency != company_currency)));
+			
+		frm.refresh_fields();
+	},
+	
+	set_dynamic_labels: function(frm) {
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+		
+		var field_label_map = {};
+		var grid_field_label_map = {};
+
+		var setup_field_label_map = function(fields_list, currency, parentfield) {
+			var doctype = parentfield ? frm.fields_dict[parentfield].grid.doctype : frm.doc.doctype;
+			$.each(fields_list, function(i, fname) {
+				var docfield = frappe.meta.docfield_map[doctype][fname];
+				if(docfield) {
+					var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
+					if(parentfield) {
+						grid_field_label_map[doctype + "-" + fname] = 
+							label.trim() + " (" + __(currency) + ")";
+					} else {
+						field_label_map[fname] = label.trim() + " (" + currency + ")";
+					}
+				}
+			});
+		}
+		
+		setup_field_label_map(["base_paid_amount", "base_received_amount", "base_total_allocated_amount", 
+			"difference_amount"], company_currency);
+		
+		setup_field_label_map(["paid_amount"], frm.doc.paid_from_account_currency);
+		setup_field_label_map(["received_amount"], frm.doc.paid_to_account_currency);
+		
+		var party_account_currency = frm.doc.payment_type=="Receive" ? 
+			frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency;
+
+		setup_field_label_map(["total_allocated_amount", "unallocated_amount"], party_account_currency);
+		
+		$.each(field_label_map, function(fname, label) {
+			me.frm.fields_dict[fname].set_label(label);
+		});
+		
+		setup_field_label_map(["total_amount", "outstanding_amount", "allocated_amount"], 
+			party_account_currency, "references");
+			
+		setup_field_label_map(["amount"], company_currency, "deductions");
+		
+		$.each(grid_field_label_map, function(fname, label) {
+			fname = fname.split("-");
+			var df = frappe.meta.get_docfield(fname[0], fname[1], me.frm.doc.name);
+			if(df) df.label = label;
+		});
+		
+		cur_frm.set_df_property("source_exchange_rate", "description", 
+			("1 " + frm.doc.paid_from_account_currency + " = [?] " + company_currency));
+		
+		cur_frm.set_df_property("target_exchange_rate", "description", 
+			("1 " + frm.doc.paid_to_account_currency + " = [?] " + company_currency));
+			
+		frm.refresh_fields();
+	},
+	
+	show_general_ledger: function(frm) {
+		if(frm.doc.docstatus==1) {
+			frm.add_custom_button(__('Ledger'), function() {
+				frappe.route_options = {
+					"voucher_no": frm.doc.name,
+					"from_date": frm.doc.posting_date,
+					"to_date": frm.doc.posting_date,
+					"company": frm.doc.company,
+					group_by_voucher: 0
+				};
+				frappe.set_route("query-report", "General Ledger");
+			}, "icon-table");
+		}
+	},
+	
+	payment_type: function(frm) {
+		if(frm.doc.payment_type == "Internal Transfer") {
+			$.each(["party", "party_balance", "paid_from", "paid_to", 
+				"references", "total_allocated_amount"], function(i, field) {
+					frm.set_value(field, null);
+			})
+		} else {
+			if(!frm.doc.party)
+				frm.set_value("party_type", frm.doc.payment_type=="Receive" ? "Customer" : "Supplier");
+			else 
+				frm.events.party(frm);
+			
+			if(frm.doc.mode_of_payment)
+				frm.events.mode_of_payment(frm);
+		}
+	},
+	
+	party_type: function(frm) {
+		if(frm.doc.party) {
+			$.each(["party", "party_balance", "paid_from", "paid_to", 
+				"paid_from_account_currency", "paid_from_account_balance",
+				"paid_to_account_currency", "paid_to_account_balance",
+				"references", "total_allocated_amount"], function(i, field) {
+					frm.set_value(field, null);
+			})
+		}
+	},
+		
+	party: function(frm) {
+		if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) {
+			frm.set_party_account_based_on_party = true;
+			
+			return frappe.call({
+				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_details",
+				args: {
+					company: frm.doc.company,
+					party_type: frm.doc.party_type,
+					party: frm.doc.party, 
+					date: frm.doc.posting_date
+				},
+				callback: function(r, rt) {
+					if(r.message) {
+						if(frm.doc.payment_type == "Receive") {
+							frm.set_value("paid_from", r.message.party_account);
+							frm.set_value("paid_from_account_currency", r.message.party_account_currency);
+							frm.set_value("paid_from_account_balance", r.message.account_balance);
+						} else if (frm.doc.payment_type == "Pay"){
+							frm.set_value("paid_to", r.message.party_account);
+							frm.set_value("paid_to_account_currency", r.message.party_account_currency);
+							frm.set_value("paid_to_account_balance", r.message.account_balance);
+						}
+						frm.set_value("party_balance", r.message.party_balance);
+						frm.events.get_outstanding_documents(frm);
+						frm.events.hide_unhide_fields(frm);
+						frm.events.set_dynamic_labels(frm);
+						frm.set_party_account_based_on_party = false;
+					}
+				}
+			});
+		}
+	},
+		
+	mode_of_payment: function(frm) {
+		return  frappe.call({
+			method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
+			args: {
+				"mode_of_payment": frm.doc.mode_of_payment,
+				"company": frm.doc.company
+			},
+			callback: function(r, rt) {
+				if(r.message) {
+					var payment_account_field = frm.doc.payment_type == "Receive" ? "paid_to" : "paid_from";
+					frm.set_value(payment_account_field, r.message['account']);
+				}
+			}
+		});
+	},
+	
+	paid_from: function(frm) {
+		if(frm.set_party_account_based_on_party) return;
+		
+		frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from, 
+			"paid_from_account_currency", "paid_from_account_balance", function(frm) {
+				if(frm.doc.payment_type == "Receive") frm.events.get_outstanding_documents(frm);
+			}
+		);
+	},	
+	
+	paid_to: function(frm) {
+		if(frm.set_party_account_based_on_party) return;
+		
+		frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to, 
+			"paid_to_account_currency", "paid_to_account_balance", function(frm) {
+				if(frm.doc.payment_type == "Pay") frm.events.get_outstanding_documents(frm);
+			}
+		);
+	},
+	
+	set_account_currency_and_balance: function(frm, account, currency_field, 
+			balance_field, callback_function) {
+		frappe.call({
+			method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details",
+			args: {
+				"account": account,
+				"date": frm.doc.posting_date
+			},
+			callback: function(r, rt) {
+				if(r.message) {
+					frm.set_value(currency_field, r.message['account_currency']);
+					frm.set_value(balance_field, r.message['account_balance']);
+					
+					if(frm.doc.payment_type=="Receive" && currency_field=="paid_to_account_currency") {
+						frm.toggle_reqd(["reference_no", "reference_date"], 
+							(r.message['account_type'] == "Bank" ? 1 : 0));
+						if(!frm.doc.received_amount && frm.doc.paid_amount)
+							frm.events.paid_amount(frm);
+					} else if(frm.doc.payment_type=="Pay" && currency_field=="paid_from_account_currency") { 
+						frm.toggle_reqd(["reference_no", "reference_date"], 
+							(r.message['account_type'] == "Bank" ? 1 : 0));
+							
+						if(!frm.doc.paid_amount && frm.doc.received_amount)
+							frm.events.received_amount(frm);
+					}
+					
+					if(callback_function) callback_function(frm);
+						
+					frm.events.hide_unhide_fields(frm);
+					frm.events.set_dynamic_labels(frm);
+				}
+			}
+		});
+	},
+	
+	paid_from_account_currency: function(frm) {
+		if(!frm.doc.paid_from_account_currency) return;
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+		
+		if (frm.doc.paid_from_account_currency == company_currency) {
+			frm.set_value("source_exchange_rate", 1);
+		} else if (frm.doc.paid_from){
+			if (in_list(["Internal Transfer", "Pay"], frm.doc.payment_type)) {
+				frappe.call({
+					method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_average_exchange_rate",
+					args: {
+						account: frm.doc.paid_from
+					},
+					callback: function(r, rt) {
+						frm.set_value("source_exchange_rate", r.message);
+					}
+				})
+			} else {
+				frm.events.set_current_exchange_rate(frm, "source_exchange_rate", 
+					frm.doc.paid_from_account_currency, company_currency);
+			}
+		}
+	},
+	
+	paid_to_account_currency: function(frm) {
+		if(!frm.doc.paid_to_account_currency) return;
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+		
+		frm.events.set_current_exchange_rate(frm, "target_exchange_rate", 
+			frm.doc.paid_to_account_currency, company_currency);
+	},
+	
+	set_current_exchange_rate: function(frm, exchange_rate_field, from_currency, to_currency) {
+		frappe.call({
+			method: "erpnext.setup.utils.get_exchange_rate",
+			args: {
+				from_currency: from_currency,
+				to_currency: to_currency
+			},
+			callback: function(r, rt) {
+				frm.set_value(exchange_rate_field, r.message);
+			}
+		})
+	},
+	
+	source_exchange_rate: function(frm) {
+		if (frm.doc.paid_amount) {
+			frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
+		}
+	},
+	
+	target_exchange_rate: function(frm) {
+		if (frm.doc.received_amount) {
+			frm.set_value("base_received_amount", 
+				flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate));
+		}
+	},
+	
+	paid_amount: function(frm) {
+		frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
+		
+		if(!frm.set_paid_amount_based_on_received_amount && 
+				(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
+			frm.set_value("received_amount", frm.doc.paid_amount);
+			frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
+			frm.set_value("base_received_amount", frm.doc.base_paid_amount);
+		}
+		if(frm.doc.payment_type == "Receive")
+			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
+		else
+			frm.events.set_difference_amount(frm);
+		
+		frm.set_paid_amount_based_on_received_amount = false;
+	},
+	
+	received_amount: function(frm) {
+		frm.set_paid_amount_based_on_received_amount = true;
+		
+		if(!frm.doc.paid_amount && frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
+			frm.set_value("paid_amount", frm.doc.received_amount);
+			frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate);
+			frm.set_value("base_paid_amount", frm.doc.base_received_amount);
+		}
+		
+		frm.set_value("base_received_amount", 
+			flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate));
+			
+		if(frm.doc.payment_type == "Pay")
+			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
+		else
+			frm.events.set_difference_amount(frm);
+	},
+	
+	get_outstanding_documents: function(frm) {
+		frm.clear_table("references");
+		
+		if(!frm.doc.party) return;
+		
+		frm.events.check_mandatory_to_fetch(frm);
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+
+		return  frappe.call({
+			method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
+			args: {
+				args: {
+					"company": frm.doc.company,
+					"party_type": frm.doc.party_type,
+					"payment_type": frm.doc.payment_type,
+					"party": frm.doc.party,
+					"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to
+				}
+			},
+			callback: function(r, rt) {
+				if(r.message) {
+					var total_positive_outstanding = 0;
+					var total_negative_outstanding = 0;
+					
+					$.each(r.message, function(i, d) {
+						var c = frm.add_child("references");
+						c.reference_doctype = d.voucher_type;
+						c.reference_name = d.voucher_no;
+						c.total_amount = d.invoice_amount;
+						c.outstanding_amount = d.outstanding_amount;
+						if(!in_list(["Sales Order", "Purchase Order"], d.voucher_type)) {
+							if(flt(d.outstanding_amount) > 0)
+								total_positive_outstanding += flt(d.outstanding_amount);
+							else
+								total_negative_outstanding += Math.abs(flt(d.outstanding_amount));
+						}
+							
+						var party_account_currency = frm.doc.payment_type=="Receive" ? 
+							frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency;
+
+						if(party_account_currency != company_currency) {
+							c.exchange_rate = d.exchange_rate;
+						} else {
+							c.exchange_rate = 1;
+						}
+						if (in_list(['Sales Invoice', 'Purchase Invoice'], d.reference_doctype)){
+							c.due_date = d.due_date;
+						}
+					});
+					
+					if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") || 
+						(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")) {
+							if(total_positive_outstanding > total_negative_outstanding)
+								frm.set_value("paid_amount", 
+									total_positive_outstanding - total_negative_outstanding);
+					} else if (total_negative_outstanding && 
+							(total_positive_outstanding < total_negative_outstanding)) {
+						frm.set_value("received_amount", 
+							total_negative_outstanding - total_positive_outstanding);
+					}
+				}
+				
+				frm.events.allocate_party_amount_against_ref_docs(frm,
+					(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
+			}
+		});
+	},
+	
+	allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
+		var total_positive_outstanding_including_order = 0;
+		var total_negative_outstanding = 0;
+		
+		$.each(frm.doc.references || [], function(i, row) {
+			if(flt(row.outstanding_amount) > 0)
+				total_positive_outstanding_including_order += flt(row.outstanding_amount);
+			else
+				total_negative_outstanding += Math.abs(flt(row.outstanding_amount));
+		})
+		
+		var allocated_negative_outstanding = 0;
+		if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") || 
+				(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")) {
+			if(total_positive_outstanding_including_order > paid_amount) {
+				var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
+				allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ? 
+					total_negative_outstanding : remaining_outstanding;
+			}
+		
+			var allocated_positive_outstanding =  paid_amount + allocated_negative_outstanding;
+		} else {
+			if(paid_amount > total_negative_outstanding) {
+				if(total_negative_outstanding == 0) {
+					frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice", 
+						[frm.doc.payment_type, 
+							(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type]));
+					return false
+				} else {
+					frappe.msgprint(__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding]));
+					return false;
+				}
+			} else {
+				allocated_positive_outstanding = total_negative_outstanding - paid_amount;
+				allocated_negative_outstanding = paid_amount + 
+					(total_positive_outstanding_including_order < allocated_positive_outstanding ? 
+						total_positive_outstanding_including_order : allocated_positive_outstanding)
+			}
+		}
+		
+		$.each(frm.doc.references || [], function(i, row) {
+			row.allocated_amount = 0
+			
+			if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
+				if(row.outstanding_amount >= allocated_positive_outstanding) 
+						row.allocated_amount = allocated_positive_outstanding;
+				else row.allocated_amount = row.outstanding_amount;
+				
+				allocated_positive_outstanding -= flt(row.allocated_amount);
+			} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
+				if(Math.abs(row.outstanding_amount) >= allocated_negative_outstanding)
+					row.allocated_amount = -1*allocated_negative_outstanding;
+				else row.allocated_amount = row.outstanding_amount;
+				
+				allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
+			}
+		})
+		frm.refresh_fields()
+		frm.events.set_total_allocated_amount(frm);
+	},
+	
+	set_total_allocated_amount: function(frm) {
+		var total_allocated_amount = base_total_allocated_amount = 0.0;
+		$.each(frm.doc.references || [], function(i, row) {
+			if (row.allocated_amount) {
+				total_allocated_amount += flt(row.allocated_amount);
+				base_total_allocated_amount += flt(flt(row.allocated_amount)*flt(row.exchange_rate), 
+					precision("base_paid_amount"));
+			}
+		});
+		frm.set_value("total_allocated_amount", Math.abs(total_allocated_amount));
+		frm.set_value("base_total_allocated_amount", Math.abs(base_total_allocated_amount));
+					
+		frm.events.set_difference_amount(frm);
+	},
+	
+	set_difference_amount: function(frm) {
+		var unallocated_amount = 0;
+		if(frm.doc.party) {
+			var party_amount = frm.doc.payment_type=="Receive" ? 
+				frm.doc.paid_amount : frm.doc.received_amount;
+		
+			if(frm.doc.total_allocated_amount < party_amount)
+				unallocated_amount = party_amount - frm.doc.total_allocated_amount;
+		}	
+		
+		frm.set_value("unallocated_amount", unallocated_amount);
+		
+		var difference_amount = 0;
+		var base_unallocated_amount = flt(frm.doc.unallocated_amount) *	
+			(frm.doc.payment_type=="Receive" ? frm.doc.source_exchange_rate : frm.doc.target_exchange_rate);
+			
+		var base_party_amount = flt(frm.doc.base_total_allocated_amount) + base_unallocated_amount;
+		
+		if(frm.doc.payment_type == "Receive") {
+			difference_amount = base_party_amount - flt(frm.doc.base_received_amount);
+		} else if (frm.doc.payment_type == "Pay") {
+			difference_amount = flt(frm.doc.base_paid_amount) - base_party_amount;
+		} else {
+			difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount);
+		}
+		
+		$.each(frm.doc.deductions || [], function(i, d) {
+			if(d.amount) difference_amount -= flt(d.amount);
+		})
+		
+		frm.set_value("difference_amount", difference_amount);
+		
+		frm.events.hide_unhide_fields(frm);
+	},
+	
+	check_mandatory_to_fetch: function(frm) {
+		$.each(["Company", "Party Type", "Party", "payment_type"], function(i, field) {
+			if(!frm.doc[frappe.model.scrub(field)]) {
+				frappe.msgprint(__("Please select {0} first", [field]));
+				return false;
+			}
+				
+		});
+	},
+		
+	validate_reference_document: function(frm, row) {
+		var _validate = function(i, row) {
+			if (!row.reference_doctype) {
+				return;
+			}
+
+			if(frm.doc.party_type=="Customer"
+				&& !in_list(["Sales Order", "Sales Invoice", "Journal Entry"], row.reference_doctype)) {
+					frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
+					frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice or Journal Entry", [row.idx]));
+					return false;
+				}
+
+			if(frm.doc.party_type=="Supplier" && !in_list(["Purchase Order", 
+				"Purchase Invoice", "Journal Entry"], row.reference_doctype)) {
+					frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
+					frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
+					return false;
+				}
+		}
+
+		if (row) {
+			_validate(0, row);
+		} else {
+			$.each(frm.doc.vouchers || [], _validate);
+		}
+	},
+	
+	write_off_difference_amount: function(frm) {
+		frm.events.set_deductions_entry(frm, "write_off_account");	
+	},
+
+	set_exchange_gain_loss: function(frm) {
+		frm.events.set_deductions_entry(frm, "exchange_gain_loss_account");
+	},
+	
+	set_deductions_entry: function(frm, account) {
+		if(frm.doc.difference_amount) {
+			frappe.call({
+				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_company_defaults",
+				args: {
+					company: frm.doc.company
+				},
+				callback: function(r, rt) {
+					if(r.message) {
+						var write_off_row = $.map(frm.doc["deductions"] || [], function(t) { 
+							return t.account==r.message[account] ? t : null; });
+						
+						if (!write_off_row.length) {
+							var row = frm.add_child("deductions");
+							row.account = r.message[account];
+							row.cost_center = r.message["cost_center"];
+						} else {
+							var row = write_off_row[0];
+						}
+						
+						row.amount = flt(row.amount) + flt(frm.doc.difference_amount);
+						refresh_field("deductions");
+						
+						frm.events.set_difference_amount(frm);
+					}
+				}
+			})
+		}
+	}
+});
+
+
+frappe.ui.form.on('Payment Entry Reference', {
+	reference_doctype: function(frm, cdt, cdn) {
+		var row = locals[cdt][cdn];
+		frm.events.validate_reference_document(frm, row);
+	},
+	
+	reference_name: function(frm, cdt, cdn) {
+		var row = locals[cdt][cdn];
+		return frappe.call({
+			method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
+			args: {
+				reference_doctype: row.reference_doctype,
+				reference_name: row.reference_name,
+				party_account_currency: frm.doc.payment_type=="Receive" ? 
+					frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
+			}, 
+			callback: function(r, rt) {
+				if(r.message) {
+					$.each(r.message, function(field, value) {
+						frappe.model.set_value(cdt, cdn, field, value);
+					})
+					frm.refresh_fields();
+				}
+			}
+		})
+	},
+	
+	allocated_amount: function(frm) {
+		frm.events.set_total_allocated_amount(frm);
+	},
+	
+	references_remove: function(frm) {
+		frm.events.set_total_allocated_amount(frm);
+	}
+})
+
+frappe.ui.form.on('Payment Entry Deduction', {
+	amount: function(frm) {
+		frm.events.set_difference_amount(frm);
+	},
+	
+	deductions_remove: function(frm) {
+		frm.events.set_difference_amount(frm);
+	}
+})
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
new file mode 100644
index 0000000..d40ba9d
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -0,0 +1,1430 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 1, 
+ "allow_rename": 0, 
+ "autoname": "naming_series:", 
+ "beta": 0, 
+ "creation": "2016-06-01 14:38:51.012597", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "fieldname": "naming_series", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Series", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "PE-", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "fieldname": "payment_type", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Payment Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Receive\nPay\nInternal Transfer", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_5", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "default": "Today", 
+   "fieldname": "posting_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Posting Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "company", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Company", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Mode of Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", 
+   "fieldname": "party_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", 
+   "fieldname": "party_type", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Party Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Customer\nSupplier", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_10", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type", 
+   "fieldname": "party", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Party", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "party_type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "party", 
+   "fieldname": "party_balance", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Party Balance", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "payment_accounts_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:(in_list([\"Internal Transfer\", \"Pay\"], doc.payment_type) || doc.party)", 
+   "fieldname": "paid_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Paid From", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "paid_from", 
+   "fieldname": "paid_from_account_currency", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Currency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "paid_from", 
+   "fieldname": "paid_from_account_balance", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Balance", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "paid_from_account_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_18", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)", 
+   "fieldname": "paid_to", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Paid To", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "paid_to", 
+   "fieldname": "paid_to_account_currency", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Currency", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "paid_to", 
+   "fieldname": "paid_to_account_balance", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Account Balance", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "paid_to_account_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "collapsible_depends_on": "", 
+   "depends_on": "eval:(doc.paid_to && doc.paid_from)", 
+   "fieldname": "payment_amounts_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Paid Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "paid_from_account_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "source_exchange_rate", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Exchange Rate", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "base_paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Paid Amount (Company Currency)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_21", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "received_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Received Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "paid_to_account_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "target_exchange_rate", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Exchange Rate", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "base_received_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Received Amount (Company Currency)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "collapsible_depends_on": "references", 
+   "depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", 
+   "fieldname": "section_break_14", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Reference Documents", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "references", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Payment References", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Payment Entry Reference", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "section_break_34", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)", 
+   "fieldname": "total_allocated_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Total Allocated Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "base_total_allocated_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Total Allocated Amount (Company Currency)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "difference_amount", 
+   "fieldname": "write_off_difference_amount", 
+   "fieldtype": "Button", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Write Off Difference Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "set_exchange_gain_loss", 
+   "fieldtype": "Button", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Set Exchange Gain / Loss", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_36", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)", 
+   "fieldname": "unallocated_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Unallocated Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:(doc.paid_amount && doc.received_amount)", 
+   "fieldname": "difference_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Difference Amount (Company Currency)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "collapsible_depends_on": "deductions", 
+   "depends_on": "eval:(doc.paid_amount && doc.received_amount)", 
+   "fieldname": "deductions_or_loss_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Deductions or Loss", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "deductions", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Payment Deductions or Loss", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Payment Entry Deduction", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "transaction_references", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Transaction References", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:(doc.paid_from && doc.paid_to)", 
+   "fieldname": "reference_no", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Cheque/Reference No", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_23", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "depends_on": "eval:(doc.paid_from && doc.paid_to)", 
+   "fieldname": "reference_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Cheque/Reference Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "eval:doc.docstatus==1", 
+   "fieldname": "clearance_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Clearance Date", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "collapsible_depends_on": "", 
+   "depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", 
+   "fieldname": "section_break_12", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "More Information", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "", 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "remarks", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Remarks", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_16", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "letter_head", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Letter Head", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Letter Head", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "print_heading", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Print Heading", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Print Heading", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Amended From", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Payment Entry", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "title", 
+   "fieldtype": "Data", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Title", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 1, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2016-07-01 17:14:17.562924", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Payment Entry", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 1, 
+   "apply_user_permissions": 0, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 1, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Accounts User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "apply_user_permissions": 0, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 1, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Accounts Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 0, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "title_field": "title", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
new file mode 100644
index 0000000..d4d93a7
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -0,0 +1,666 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe, json
+from frappe import _, scrub, ValidationError
+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, get_default_bank_cash_account
+from erpnext.setup.utils import get_exchange_rate
+from erpnext.accounts.general_ledger import make_gl_entries
+
+from erpnext.controllers.accounts_controller import AccountsController
+
+class InvalidPaymentEntry(ValidationError): pass
+
+class PaymentEntry(AccountsController):
+	def setup_party_account_field(self):		
+		self.party_account_field = None
+		self.party_account = None
+		self.party_account_currency = None
+		
+		if self.payment_type == "Receive":
+			self.party_account_field = "paid_from"
+			self.party_account = self.paid_from
+			self.party_account_currency = self.paid_from_account_currency
+			
+		elif self.payment_type == "Pay":
+			self.party_account_field = "paid_to"
+			self.party_account = self.paid_to
+			self.party_account_currency = self.paid_to_account_currency
+							
+	def validate(self):
+		self.setup_party_account_field()
+		self.set_missing_values()
+		self.validate_party_details()
+		self.validate_bank_accounts()
+		self.set_exchange_rate()
+		self.validate_mandatory()
+		self.validate_reference_documents()
+		self.set_amounts()
+		self.clear_unallocated_reference_document_rows()
+		self.validate_payment_against_negative_invoice()
+		self.validate_transaction_reference()
+		self.set_title()
+		self.set_remarks()
+		
+	def on_submit(self):
+		if self.difference_amount:
+			frappe.throw(_("Difference Amount must be zero"))
+		self.make_gl_entries()
+		self.update_advance_paid()
+		
+	def on_cancel(self):
+		self.setup_party_account_field()
+		self.make_gl_entries(cancel=1)
+		self.update_advance_paid()
+							
+	def set_missing_values(self):
+		if self.payment_type == "Internal Transfer":
+			for field in ("party", "party_balance", "total_allocated_amount", 
+				"base_total_allocated_amount", "unallocated_amount"):
+					self.set(field, None)
+			self.references = []
+		else:
+			if not self.party_type:
+				frappe.throw(_("Party Type is mandatory"))
+				
+			if not self.party:
+				frappe.throw(_("Party is mandatory"))
+		
+		if self.party:
+			if not self.party_balance:
+				self.party_balance = get_balance_on(party_type=self.party_type,
+					party=self.party, date=self.posting_date)
+			
+			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 = party_account
+				
+		if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
+			acc = get_account_details(self.paid_from, self.posting_date)
+			self.paid_from_account_currency = acc.account_currency
+			self.paid_from_account_balance = acc.account_balance
+				
+		if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
+			acc = get_account_details(self.paid_to, self.posting_date)
+			self.paid_to_account_currency = acc.account_currency
+			self.paid_to_account_balance = acc.account_balance
+			
+		self.party_account_currency = self.paid_from_account_currency \
+			if self.payment_type=="Receive" else self.paid_to_account_currency
+			
+		self.set_missing_ref_details()
+			
+	
+	def set_missing_ref_details(self):
+		for d in self.get("references"):
+			if d.allocated_amount:
+				ref_details = get_reference_details(d.reference_doctype, 
+					d.reference_name, self.party_account_currency)
+					
+				for field, value in ref_details.items():
+					if not d.get(field):
+						d.set(field, value)
+	
+	def validate_party_details(self):
+		if self.party:
+			if not frappe.db.exists(self.party_type, self.party):
+				frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
+			
+			if self.party_account:
+				party_account_type = "Receivable" if self.party_type=="Customer" else "Payable"
+				self.validate_account_type(self.party_account, [party_account_type])
+					
+	def validate_bank_accounts(self):
+		if self.payment_type in ("Pay", "Internal Transfer"):
+			self.validate_account_type(self.paid_from, ["Bank", "Cash"])
+			
+		if self.payment_type in ("Receive", "Internal Transfer"):
+			self.validate_account_type(self.paid_to, ["Bank", "Cash"])
+			
+	def validate_account_type(self, account, account_types):
+		account_type = frappe.db.get_value("Account", account, "account_type")
+		if account_type not in account_types:
+			frappe.throw(_("Account Type for {0} must be {1}").format(comma_or(account_types)))
+				
+	def set_exchange_rate(self):
+		if self.paid_from and not self.source_exchange_rate:
+			if self.paid_from_account_currency == self.company_currency:
+				self.source_exchange_rate = 1
+			elif self.payment_type in ("Pay", "Internal Transfer"):
+				self.source_exchange_rate = get_average_exchange_rate(self.paid_from)
+			else:
+				self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency, 
+					self.company_currency)
+		
+		if self.paid_to and not self.target_exchange_rate:
+			self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency, 
+				self.company_currency)
+				
+	def validate_mandatory(self):
+		for field in ("paid_amount", "received_amount", "source_exchange_rate", "target_exchange_rate"):
+			if not self.get(field):
+				frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
+				
+	def validate_reference_documents(self):
+		if self.party_type == "Customer":
+			valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
+		else:
+			valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
+			
+		for d in self.get("references"):
+			if not d.allocated_amount:
+				continue
+			if d.reference_doctype not in valid_reference_doctypes:
+				frappe.throw(_("Reference Doctype must be one of {0}")
+					.format(comma_or(valid_reference_doctypes)))
+				
+			elif d.reference_name:
+				if not frappe.db.exists(d.reference_doctype, d.reference_name):
+					frappe.throw(_("{0} {1} does not exist").format(d.reference_doctype, d.reference_name))
+				else:
+					ref_doc = frappe.get_doc(d.reference_doctype, d.reference_name)
+
+					if d.reference_doctype != "Journal Entry":
+						if self.party != ref_doc.get(scrub(self.party_type)):
+							frappe.throw(_("{0} {1} does not associated with {2} {3}")
+								.format(d.reference_doctype, d.reference_name, self.party_type, self.party))
+					else:
+						self.validate_journal_entry()
+								
+					if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
+						ref_party_account = ref_doc.debit_to \
+							if self.party_type=="Customer" else ref_doc.credit_to
+						if ref_party_account != self.party_account:
+							frappe.throw(_("{0} {1} does not associated with Party Account {2}")
+								.format(d.reference_doctype, d.reference_name, self.party_account))
+						
+					if ref_doc.docstatus != 1:
+						frappe.throw(_("{0} {1} must be submitted")
+							.format(d.reference_doctype, d.reference_name))
+							
+	def validate_journal_entry(self):
+		for d in self.get("references"):
+			if d.allocated_amount and d.reference_doctype == "Journal Entry":				
+				je_accounts = frappe.db.sql("""select debit, credit from `tabJournal Entry Account`
+					where account = %s and party=%s and docstatus = 1 and parent = %s
+					and (reference_type is null or reference_type in ("", "Sales Order", "Purchase Order"))
+					""", (self.party_account, self.party, d.reference_name), as_dict=True)
+
+				if not je_accounts:
+					frappe.throw(_("Row #{0}: Journal Entry {0} does not have account {1} or already matched against another voucher")
+						.format(d.idx, d.reference_name, self.party_account))
+				else:
+					dr_or_cr = "debit" if self.payment_type == "Receive" else "credit"
+					valid = False
+					for jvd in je_accounts:
+						if flt(jvd[dr_or_cr]) > 0:
+							valid = True
+					if not valid:
+						frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
+							.format(d.reference_name, dr_or_cr))
+							
+	def set_amounts(self):
+		self.set_amounts_in_company_currency()
+		self.set_total_allocated_amount()
+		self.set_unallocated_amount()
+		self.set_difference_amount()
+
+	def set_amounts_in_company_currency(self):
+		self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
+		if self.paid_amount:
+			self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate), 
+				self.precision("base_paid_amount"))
+				
+		if self.received_amount:
+			self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate), 
+				self.precision("base_received_amount"))
+				
+	def set_total_allocated_amount(self):
+		if self.payment_type == "Internal Transfer":
+			return
+			
+		total_allocated_amount, base_total_allocated_amount = 0, 0
+		for d in self.get("references"):
+			if d.allocated_amount:				
+				total_allocated_amount += flt(d.allocated_amount)
+				base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate), 
+					self.precision("base_paid_amount"))
+					
+		self.total_allocated_amount = abs(total_allocated_amount)
+		self.base_total_allocated_amount = abs(base_total_allocated_amount)
+	
+	def set_unallocated_amount(self):
+		self.unallocated_amount = 0;
+		if self.party:
+			party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
+			
+			if self.total_allocated_amount < party_amount:
+				self.unallocated_amount = party_amount - self.total_allocated_amount
+				
+	def set_difference_amount(self):
+		base_unallocated_amount = self.unallocated_amount * \
+			(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
+			
+		base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
+		
+		if self.payment_type == "Receive":
+			self.difference_amount = base_party_amount - self.base_received_amount
+		elif self.payment_type == "Pay":
+			self.difference_amount = self.base_paid_amount - base_party_amount
+		else:
+			self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
+			
+		for d in self.get("deductions"):
+			if d.amount:
+				self.difference_amount -= flt(d.amount)
+				
+	def clear_unallocated_reference_document_rows(self):
+		self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]}))
+
+		frappe.db.sql("""delete from `tabPayment Entry Reference` 
+			where parent = %s and allocated_amount = 0""", self.name)
+			
+	def validate_payment_against_negative_invoice(self):
+		if ((self.payment_type=="Pay" and self.party_type=="Customer") 
+				or (self.payment_type=="Receive" and self.party_type=="Supplier")):
+			total_negative_outstanding = sum([abs(flt(d.outstanding_amount)) 
+				for d in self.get("references") if flt(d.outstanding_amount) < 0])
+			
+			party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
+
+			if not total_negative_outstanding:
+				frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
+					.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"), 
+						self.party_type), InvalidPaymentEntry)
+					
+			elif party_amount > total_negative_outstanding:
+				frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
+					.format(total_negative_outstanding), InvalidPaymentEntry)
+			
+	def set_title(self):
+		if self.payment_type in ("Receive", "Pay"):
+			self.title = self.party
+		else:
+			self.title = self.paid_from + " - " + self.paid_to
+			
+	def validate_transaction_reference(self):
+		bank_account = self.paid_to if self.payment_type == "Receive" else self.paid_from
+		bank_account_type = frappe.db.get_value("Account", bank_account, "account_type")
+		
+		if bank_account_type == "Bank":
+			if not self.reference_no or not self.reference_date:
+				frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
+				
+	def set_remarks(self):
+		if self.remarks: return
+		
+		if self.payment_type=="Internal Transfer":
+			remarks = [_("Amount {0} {1} transferred from {2} to {3}")
+				.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
+		else:
+			
+			remarks = [_("Amount {0} {1} {2} {3}").format(
+				self.party_account_currency,
+				self.paid_amount if self.payment_type=="Receive" else self.received_amount,
+				_("received from") if self.payment_type=="Receive" else _("to"), self.party
+			)]
+			
+		if self.reference_no:
+			remarks.append(_("Transaction reference no {0} dated {1}")
+				.format(self.reference_no, self.reference_date))
+
+		if self.payment_type in ["Receive", "Pay"]:
+			for d in self.get("references"):
+				if d.allocated_amount:
+					remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency, 
+						d.allocated_amount, d.reference_doctype, d.reference_name))
+		
+		for d in self.get("deductions"):
+			if d.amount:
+				remarks.append(_("Amount {0} {1} deducted against {2}")
+					.format(self.company_currency, d.amount, d.account))
+
+		self.set("remarks", "\n".join(remarks))
+			
+	def make_gl_entries(self, cancel=0, adv_adj=0):
+		gl_entries = []
+		self.add_party_gl_entries(gl_entries)
+		self.add_bank_gl_entries(gl_entries)
+		self.add_deductions_gl_entries(gl_entries)
+
+		make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj)
+		
+	def add_party_gl_entries(self, gl_entries):
+		if self.party_account:
+			if self.payment_type=="Receive":
+				against_account = self.paid_to
+			else:
+				 against_account = self.paid_from
+			
+				
+			party_gl_dict = self.get_gl_dict({
+				"account": self.party_account,
+				"party_type": self.party_type,
+				"party": self.party,
+				"against": against_account,
+				"account_currency": self.party_account_currency
+			})
+			
+			dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
+			
+			for d in self.get("references"):
+				gle = party_gl_dict.copy()
+				gle.update({
+					"against_voucher_type": d.reference_doctype,
+					"against_voucher": d.reference_name
+				})
+				
+				allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate), 
+					self.precision("paid_amount"))	
+				
+				gle.update({
+					dr_or_cr + "_in_account_currency": d.allocated_amount,
+					dr_or_cr: allocated_amount_in_company_currency
+				})
+				
+				gl_entries.append(gle)
+				
+			if self.unallocated_amount:
+				base_unallocated_amount = base_unallocated_amount = self.unallocated_amount * \
+					(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
+					
+				gle = party_gl_dict.copy()
+				
+				gle.update({
+					dr_or_cr + "_in_account_currency": d.unallocated_amount,
+					dr_or_cr: base_unallocated_amount
+				})
+
+				gl_entries.append(gle)
+				
+	def add_bank_gl_entries(self, gl_entries):
+		if self.payment_type in ("Pay", "Internal Transfer"):
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.paid_from,
+					"account_currency": self.paid_from_account_currency,
+					"against": self.party if self.payment_type=="Pay" else self.paid_to,
+					"credit_in_account_currency": self.paid_amount,
+					"credit": self.base_paid_amount
+				})
+			)
+		if self.payment_type in ("Receive", "Internal Transfer"):
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.paid_to,
+					"account_currency": self.paid_to_account_currency,
+					"against": self.party if self.payment_type=="Receive" else self.paid_from,
+					"debit_in_account_currency": self.received_amount,
+					"debit": self.base_received_amount
+				})
+			)
+			
+	def add_deductions_gl_entries(self, gl_entries):
+		for d in self.get("deductions"):
+			if d.amount:
+				account_currency = get_account_currency(d.account)
+				if account_currency != self.company_currency:
+					frappe.throw(_("Currency for {0} must be {1}").format(d.account, self.company_currency))
+					
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": d.account,
+						"account_currency": account_currency,
+						"against": self.party or self.paid_from,
+						"debit_in_account_currency": d.amount,
+						"debit": d.amount,
+						"cost_center": d.cost_center
+					})
+				)
+				
+	def update_advance_paid(self):
+		if self.payment_type in ("Receive", "Pay") and self.party:
+			for d in self.get("references"):
+				if d.allocated_amount and d.reference_doctype in ("Sales Order", "Purchase Order"):
+					frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
+
+@frappe.whitelist()
+def get_outstanding_reference_documents(args):
+	args = json.loads(args)
+
+	party_account_currency = get_account_currency(args.get("party_account"))
+	company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
+	
+	# Get negative outstanding sales /purchase invoices
+	total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
+		
+	negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), 
+		args.get("party"), args.get("party_account"), total_field)
+
+	# Get positive outstanding sales /purchase invoices
+	outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), 
+		args.get("party_account"))
+	
+	for d in outstanding_invoices:
+		d["exchange_rate"] = 1
+		if party_account_currency != company_currency \
+			and d.voucher_type in ("Sales Invoice", "Purchase Invoice"):
+				d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate")
+
+	# Get all SO / PO which are not fully billed or aginst which full advance not paid
+	orders_to_be_billed =  get_orders_to_be_billed(args.get("party_type"), args.get("party"), 
+		party_account_currency, company_currency)
+	
+	return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
+	
+def get_orders_to_be_billed(party_type, party, party_account_currency, company_currency):
+	voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
+
+	ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
+
+	orders = frappe.db.sql("""
+		select
+			name as voucher_no,
+			{ref_field} as invoice_amount,
+			({ref_field} - advance_paid) as outstanding_amount,
+			transaction_date as posting_date
+		from
+			`tab{voucher_type}`
+		where
+			{party_type} = %s
+			and docstatus = 1
+			and ifnull(status, "") != "Closed"
+			and {ref_field} > advance_paid
+			and abs(100 - per_billed) > 0.01
+		order by
+			transaction_date, name
+		""".format(**{
+			"ref_field": ref_field,
+			"voucher_type": voucher_type,
+			"party_type": scrub(party_type)
+		}), party, as_dict = True)
+
+	order_list = []
+	for d in orders:
+		d["voucher_type"] = voucher_type
+		d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency)
+		order_list.append(d)
+
+	return order_list
+	
+def get_negative_outstanding_invoices(party_type, party, party_account, total_field):
+	voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
+	return frappe.db.sql("""
+		select
+			"{voucher_type}" as voucher_type, name as voucher_no, 
+			{total_field} as invoice_amount, outstanding_amount, posting_date, 
+			due_date, conversion_rate as exchange_rate
+		from
+			`tab{voucher_type}`
+		where
+			{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
+		order by
+			posting_date, name
+		""".format(**{
+			"total_field": total_field,
+			"voucher_type": voucher_type,
+			"party_type": scrub(party_type),
+			"party_account": "debit_to" if party_type=="Customer" else "credit_to"
+		}), (party, party_account), as_dict = True)
+	
+@frappe.whitelist()
+def get_party_details(company, party_type, party, date):
+	if not frappe.db.exists(party_type, party):
+		frappe.throw(_("Invalid {0}: {1}").format(party_type, party))
+		
+	party_account = get_party_account(party_type, party, company)
+	
+	account_currency = get_account_currency(party_account)
+	account_balance = get_balance_on(party_account, date)
+	party_balance = get_balance_on(party_type=party_type, party=party)
+	
+	return {
+		"party_account": party_account,
+		"party_account_currency": account_currency,
+		"party_balance": party_balance,
+		"account_balance": account_balance
+	}
+
+@frappe.whitelist()	
+def get_account_details(account, date):
+	return frappe._dict({
+		"account_currency": get_account_currency(account),
+		"account_balance": get_balance_on(account, date),
+		"account_type": frappe.db.get_value("Account", account, "account_type")
+	})
+	
+@frappe.whitelist()
+def get_company_defaults(company):
+	fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
+	ret = frappe.db.get_value("Company", company, fields, as_dict=1)
+	
+	for fieldname in fields:
+		if not ret[fieldname]:
+			frappe.throw(_("Please set default {0} in Company {1}")
+				.format(frappe.get_meta("Company").get_label(fieldname), company))
+	
+	return ret
+
+@frappe.whitelist()
+def get_reference_details(reference_doctype, reference_name, party_account_currency):
+	total_amount = outstanding_amount = exchange_rate = None
+	
+	if reference_doctype != "Journal Entry":
+		ref_doc = frappe.get_doc(reference_doctype, reference_name)
+
+		if party_account_currency == ref_doc.company_currency:
+			total_amount = ref_doc.base_grand_total
+			exchange_rate = 1
+		else:
+			total_amount = ref_doc.grand_total
+			exchange_rate = ref_doc.get("conversion_rate") or \
+				get_exchange_rate(party_account_currency, ref_doc.company_currency)
+		
+		outstanding_amount = ref_doc.get("outstanding_amount") \
+			if reference_doctype in ("Sales Invoice", "Purchase Invoice") \
+			else flt(total_amount) - flt(ref_doc.advance_paid)			
+	else:
+		exchange_rate = get_exchange_rate(party_account_currency, ref_doc.company_currency)
+		
+	return frappe._dict({
+		"due_date": ref_doc.get("due_date"),
+		"total_amount": total_amount,
+		"outstanding_amount": outstanding_amount,
+		"exchange_rate": exchange_rate
+	})
+	
+@frappe.whitelist()
+def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
+	doc = frappe.get_doc(dt, dn)
+	
+	if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
+		frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
+	
+	party_type = "Customer" if dt in ("Sales Invoice", "Sales Order") else "Supplier"
+
+	# party account
+	if dt == "Sales Invoice":
+		party_account = doc.debit_to
+	elif dt == "Purchase Invoice":
+		party_account = doc.credit_to
+	else:
+		party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
+		
+	party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
+	
+	# payment type
+	if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
+		or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
+			payment_type = "Receive"
+	else:
+		payment_type = "Pay"
+	
+	# amounts
+	grand_total = outstanding_amount = 0
+	if party_amount:
+		grand_total = outstanding_amount = party_amount
+	elif dt in ("Sales Invoice", "Purchase Invoice"):
+		grand_total = doc.grand_total
+		outstanding_amount = doc.outstanding_amount
+	else:
+		total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
+		grand_total = flt(doc.get(total_field))
+		outstanding_amount = grand_total - flt(doc.advance_paid)
+
+	# bank or cash
+	bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), 
+		account=bank_account)
+	
+	paid_amount = received_amount = 0
+	if party_account_currency == bank.account_currency:
+		paid_amount = received_amount = abs(outstanding_amount)
+	elif payment_type == "Receive":
+		paid_amount = abs(outstanding_amount)
+		if bank_amount:
+			received_amount = bank_amount
+	else:
+		received_amount = abs(outstanding_amount)
+		if bank_amount:
+			paid_amount = bank_amount
+	
+	pe = frappe.new_doc("Payment Entry")
+	pe.payment_type = payment_type
+	pe.company = doc.company
+	pe.posting_date = nowdate()
+	pe.mode_of_payment = doc.get("mode_of_payment")
+	pe.party_type = party_type
+	pe.party = doc.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_from_account_currency = party_account_currency \
+		if payment_type=="Receive" else bank.account_currency
+	pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
+	pe.paid_amount = paid_amount
+	pe.received_amount = received_amount
+	
+	pe.append("references", {
+		"reference_doctype": dt,
+		"reference_name": dn,
+		"due_date": doc.get("due_date"),
+		"total_amount": grand_total,
+		"outstanding_amount": outstanding_amount,
+		"allocated_amount": 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/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
new file mode 100644
index 0000000..8be5f6d
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import flt, nowdate
+from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
+from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry
+from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
+
+test_dependencies = ["Item"]
+
+class TestPaymentEntry(unittest.TestCase):
+	def test_payment_entry_against_order(self):
+		so = make_sales_order()
+		pe = get_payment_entry("Sales Order", so.name, bank_account="_Test Cash - _TC")
+		pe.paid_from = "Debtors - _TC"
+		pe.insert()
+		pe.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["Debtors - _TC", 0, 1000, so.name],
+			["_Test Cash - _TC", 1000.0, 0, None]
+		])
+		
+		self.validate_gl_entries(pe.name, expected_gle)
+		
+		so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
+		self.assertEqual(so_advance_paid, 1000)
+		
+		pe.cancel()
+		
+		self.assertFalse(self.get_gle(pe.name))
+		
+		so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
+		self.assertEqual(so_advance_paid, 0)
+		
+	def test_payment_entry_against_si_usd_to_usd(self):
+		si =  create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
+			currency="USD", conversion_rate=50)
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
+		pe.reference_no = "1"
+		pe.reference_date = "2016-01-01"
+		pe.target_exchange_rate = 50		
+		pe.insert()
+		pe.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["_Test Receivable USD - _TC", 0, 5000, si.name],
+			["_Test Bank USD - _TC", 5000.0, 0, None]
+		])
+		
+		self.validate_gl_entries(pe.name, expected_gle)
+		
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, 0)
+		
+		pe.cancel()
+		self.assertFalse(self.get_gle(pe.name))
+		
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, 100)
+		
+	def test_payment_entry_against_pi(self):
+		pi =  make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
+			currency="USD", conversion_rate=50)
+		pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
+		pe.reference_no = "1"
+		pe.reference_date = "2016-01-01"
+		pe.source_exchange_rate = 50		
+		pe.insert()
+		pe.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["_Test Payable USD - _TC", 12500, 0, pi.name],
+			["_Test Bank USD - _TC", 0, 12500, None]
+		])
+		
+		self.validate_gl_entries(pe.name, expected_gle)
+		
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, 0)
+		
+	def test_payment_entry_against_si_usd_to_inr(self):
+		si =  create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
+			currency="USD", conversion_rate=50)
+		pe = get_payment_entry("Sales Invoice", si.name, party_amount=20, 
+			bank_account="_Test Bank - _TC", bank_amount=900)
+		pe.reference_no = "1"
+		pe.reference_date = "2016-01-01"
+		
+		self.assertEqual(pe.difference_amount, 100)
+		
+		pe.append("deductions", {
+			"account": "_Test Exchange Gain/Loss - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"amount": 100
+		})
+		pe.insert()
+		pe.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["_Test Receivable USD - _TC", 0, 1000, si.name],
+			["_Test Bank - _TC", 900, 0, None],
+			["_Test Exchange Gain/Loss - _TC", 100.0, 0, None],
+		])
+		
+		self.validate_gl_entries(pe.name, expected_gle)
+		
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, 80)
+		
+	def test_internal_transfer_usd_to_inr(self):
+		pe = frappe.new_doc("Payment Entry")
+		pe.payment_type = "Internal Transfer"
+		pe.company = "_Test Company"
+		pe.paid_from = "_Test Bank USD - _TC"
+		pe.paid_to = "_Test Bank - _TC"
+		pe.paid_amount = 100
+		pe.source_exchange_rate = 50
+		pe.received_amount = 4500
+		pe.reference_no = "2"
+		pe.reference_date = nowdate()
+		
+		pe.setup_party_account_field()
+		pe.set_missing_values()
+		pe.set_exchange_rate()
+		pe.set_amounts()
+				
+		self.assertEquals(pe.difference_amount, 500)
+		
+		pe.append("deductions", {
+			"account": "_Test Exchange Gain/Loss - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"amount": 500
+		})
+		
+		pe.insert()
+		pe.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["_Test Bank USD - _TC", 0, 5000, None],
+			["_Test Bank - _TC", 4500, 0, None],
+			["_Test Exchange Gain/Loss - _TC", 500.0, 0, None],
+		])
+		
+		self.validate_gl_entries(pe.name, expected_gle)
+		
+	def test_payment_against_negative_sales_invoice(self):
+		pe1 = frappe.new_doc("Payment Entry")
+		pe1.payment_type = "Pay"
+		pe1.company = "_Test Company"
+		pe1.party_type = "Customer"
+		pe1.party = "_Test Customer"
+		pe1.paid_from = "_Test Cash - _TC"
+		pe1.paid_amount = 100
+		pe1.received_amount = 100
+		
+		self.assertRaises(InvalidPaymentEntry, pe1.validate)
+		
+		si1 =  create_sales_invoice()
+		
+		# create full payment entry against si1
+		pe2 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
+		pe2.insert()
+		pe2.submit()
+		
+		# create return entry against si1
+		create_sales_invoice(is_return=1, return_against=si1.name, qty=-1)
+		si1_outstanding = frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount")
+		self.assertEqual(si1_outstanding, -100)
+		
+		# pay more than outstanding against si1
+		pe3 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
+		pe3.paid_amount = pe3.received_amount = 300
+		self.assertRaises(InvalidPaymentEntry, pe3.validate)
+		
+		# pay negative outstanding against si1
+		pe3.paid_to = "Debtors - _TC"
+		pe3.paid_amount = pe3.received_amount = 100
+		
+		pe3.insert()
+		pe3.submit()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["Debtors - _TC", 100, 0, si1.name],
+			["_Test Cash - _TC", 0, 100, None]
+		])
+
+		self.validate_gl_entries(pe3.name, expected_gle)
+
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, 0)
+
+		pe3.cancel()
+		self.assertFalse(self.get_gle(pe3.name))
+
+		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"))
+		self.assertEqual(outstanding_amount, -100)
+		
+	def validate_gl_entries(self, voucher_no, expected_gle):
+		gl_entries = self.get_gle(voucher_no)
+			
+		self.assertTrue(gl_entries)
+
+		for i, gle in enumerate(gl_entries):
+			self.assertEquals(expected_gle[gle.account][0], gle.account)
+			self.assertEquals(expected_gle[gle.account][1], gle.debit)
+			self.assertEquals(expected_gle[gle.account][2], gle.credit)
+			self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
+		
+	def get_gle(self, voucher_no):
+		return frappe.db.sql("""select account, debit, credit, against_voucher
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", voucher_no, as_dict=1)
diff --git a/erpnext/accounts/doctype/payment_entry_deduction/__init__.py b/erpnext/accounts/doctype/payment_entry_deduction/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_deduction/__init__.py
diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
new file mode 100644
index 0000000..e71d973
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
@@ -0,0 +1,113 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2016-06-15 15:56:30.815503", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "cost_center", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Cost Center", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cost Center", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2016-06-27 11:18:35.021945", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Payment Entry Deduction", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py
new file mode 100644
index 0000000..d6686bb
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PaymentEntryDeduction(Document):
+	pass
diff --git a/erpnext/accounts/doctype/payment_entry_reference/__init__.py b/erpnext/accounts/doctype/payment_entry_reference/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_reference/__init__.py
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
new file mode 100644
index 0000000..5d61996
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
@@ -0,0 +1,237 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2016-06-01 16:55:32.196722", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "reference_doctype", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "DocType", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "reference_name", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "reference_doctype", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "due_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Due Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "column_break_4", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "total_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Total Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "outstanding_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Outstanding Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "allocated_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Allocated Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "exchange_rate", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Exchange Rate", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2016-06-27 11:18:20.442383", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Payment Entry Reference", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
new file mode 100644
index 0000000..51f8c06
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PaymentEntryReference(Document):
+	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index 5075f15..a50ff19 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -4,7 +4,15 @@
 frappe.provide("erpnext.accounts");
 
 erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.extend({
-
+	setup: function() {
+		this.frm.get_field('payments').grid.editable_fields = [
+			{fieldname: 'reference_name', columns: 3},
+			{fieldname: 'amount', columns: 2},
+			{fieldname: 'invoice_number', columns: 3},
+			{fieldname: 'allocated_amount', columns: 3}
+		];
+	}, 
+	
 	onload: function() {
 		var me = this
 		this.frm.set_query('party_type', function() {
@@ -105,14 +113,16 @@
 			if (row.invoice_number && !inList(invoices, row.invoice_number))
 				invoices.push(row.invoice_type + " | " + row.invoice_number);
 		});
+		
+		if (invoices) {
+			frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number",
+				me.frm.doc.name).options = "\n" + invoices.join("\n");
 
-		frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number",
-			me.frm.doc.name).options = invoices.join("\n");
-
-		$.each(me.frm.doc.payments || [], function(i, p) {
-			if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null;
-		});
-
+			$.each(me.frm.doc.payments || [], function(i, p) {
+				if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null;
+			});
+		}
+		
 		refresh_field("payments");
 	},
 
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 832a346..5910a24 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -7,31 +7,49 @@
 from frappe import msgprint, _
 from frappe.model.document import Document
 from erpnext.accounts.utils import get_outstanding_invoices
+from erpnext.controllers.accounts_controller import get_advance_payment_entries
 
 class PaymentReconciliation(Document):
 	def get_unreconciled_entries(self):
-		self.get_jv_entries()
+		self.get_nonreconciled_payment_entries()
 		self.get_invoice_entries()
+		
+	def get_nonreconciled_payment_entries(self):
+		self.check_mandatory_to_fetch()
+		
+		payment_entries = self.get_payment_entries()
+		journal_entries = self.get_jv_entries()
+				
+		self.add_payment_entries(payment_entries + journal_entries)
+		
+	def get_payment_entries(self):
+		order_doctype = "Sales Order" if self.party_type=="Customer" else "Purchase Order"
+		payment_entries = get_advance_payment_entries(self.party_type, self.party, 
+			self.receivable_payable_account, order_doctype, against_all_orders=True)
+			
+		return payment_entries
 
 	def get_jv_entries(self):
-		self.check_mandatory_to_fetch()
 		dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \
 			else "debit_in_account_currency"
 
 		bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
 				if self.bank_cash_account else "1=1"
 
-		jv_entries = frappe.db.sql("""
+		journal_entries = frappe.db.sql("""
 			select
-				t1.name as voucher_no, t1.posting_date, t1.remark,
-				t2.name as voucher_detail_no, {dr_or_cr} as payment_amount, t2.is_advance
+				"Journal Entry" as reference_type, t1.name as reference_name, 
+				t1.posting_date, t1.remark as remarks, t2.name as reference_row, 
+				{dr_or_cr} as amount, t2.is_advance
 			from
 				`tabJournal Entry` t1, `tabJournal Entry Account` t2
 			where
 				t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
 				and t2.party_type = %(party_type)s and t2.party = %(party)s
 				and t2.account = %(account)s and {dr_or_cr} > 0
-				and (t2.reference_type is null or t2.reference_type in ('', 'Sales Order', 'Purchase Order'))
+				and (t2.reference_type is null or t2.reference_type = '' or 
+					(t2.reference_type in ('Sales Order', 'Purchase Order') 
+						and t2.reference_name is not null and t2.reference_name != ''))
 				and (CASE
 					WHEN t1.voucher_type in ('Debit Note', 'Credit Note')
 					THEN 1=1
@@ -47,18 +65,13 @@
 				"bank_cash_account": "%%%s%%" % self.bank_cash_account
 			}, as_dict=1)
 
-		self.add_payment_entries(jv_entries)
+		return list(journal_entries)
 
-	def add_payment_entries(self, jv_entries):
+	def add_payment_entries(self, entries):
 		self.set('payments', [])
-		for e in jv_entries:
-			ent = self.append('payments', {})
-			ent.journal_entry = e.get('voucher_no')
-			ent.posting_date = e.get('posting_date')
-			ent.amount = flt(e.get('payment_amount'))
-			ent.remark = e.get('remark')
-			ent.voucher_detail_number = e.get('voucher_detail_no')
-			ent.is_advance = e.get('is_advance')
+		for e in entries:
+			row = self.append('payments', {})
+			row.update(e)
 
 	def get_invoice_entries(self):
 		#Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
@@ -90,14 +103,16 @@
 
 		self.get_invoice_entries()
 		self.validate_invoice()
-		dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \
-			else "debit_in_account_currency"
+		dr_or_cr = "credit_in_account_currency" \
+			if self.party_type == "Customer" else "debit_in_account_currency"
+			
 		lst = []
 		for e in self.get('payments'):
 			if e.invoice_number and e.allocated_amount:
-				lst.append({
-					'voucher_no' : e.journal_entry,
-					'voucher_detail_no' : e.voucher_detail_number,
+				lst.append(frappe._dict({
+					'voucher_type': e.reference_type,
+					'voucher_no' : e.reference_name,
+					'voucher_detail_no' : e.reference_row,
 					'against_voucher_type' : e.invoice_type,
 					'against_voucher'  : e.invoice_number,
 					'account' : self.receivable_payable_account,
@@ -105,13 +120,14 @@
 					'party': self.party,
 					'is_advance' : e.is_advance,
 					'dr_or_cr' : dr_or_cr,
-					'unadjusted_amt' : flt(e.amount),
-					'allocated_amt' : flt(e.allocated_amount)
-				})
-
+					'unadjusted_amount' : flt(e.amount),
+					'allocated_amount' : flt(e.allocated_amount)
+				}))
+				
 		if lst:
 			from erpnext.accounts.utils import reconcile_against_document
 			reconcile_against_document(lst)
+			
 			msgprint(_("Successfully Reconciled"))
 			self.get_unreconciled_entries()
 
@@ -142,7 +158,7 @@
 						.format(p.invoice_type, p.invoice_number))
 
 				if flt(p.allocated_amount) > flt(p.amount):
-					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to JV amount {2}")
+					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to Payment Entry amount {2}")
 						.format(p.idx, p.allocated_amount, p.amount))
 
 				invoice_outstanding = unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number)
diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
index f9b6039..401d234 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
@@ -2,6 +2,7 @@
  "allow_copy": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2014-07-09 16:13:35.452759", 
  "custom": 0, 
  "docstatus": 0, 
@@ -12,18 +13,46 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "journal_entry", 
+   "fieldname": "reference_type", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Journal Entry", 
+   "in_list_view": 0, 
+   "label": "Reference Type", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Journal Entry", 
+   "options": "DocType", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "reference_name", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Reference_name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "reference_type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -39,6 +68,7 @@
    "fieldtype": "Date", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Posting Date", 
@@ -46,6 +76,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -61,6 +92,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Amount", 
@@ -68,6 +100,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -83,6 +116,7 @@
    "fieldtype": "Data", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Is Advance", 
@@ -90,6 +124,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -101,17 +136,19 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "voucher_detail_number", 
+   "fieldname": "reference_row", 
    "fieldtype": "Data", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Voucher Detail Number", 
+   "label": "Reference Row", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -127,6 +164,7 @@
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "", 
@@ -134,6 +172,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -149,6 +188,7 @@
    "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Invoice Number", 
@@ -157,6 +197,7 @@
    "options": "", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -172,6 +213,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Allocated amount", 
@@ -180,6 +222,7 @@
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -195,6 +238,7 @@
    "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "", 
@@ -202,6 +246,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -217,6 +262,7 @@
    "fieldtype": "Small Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Remark", 
@@ -224,6 +270,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -234,21 +281,27 @@
  ], 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:51.563989", 
+ "menu_index": 0, 
+ "modified": "2016-06-27 18:27:15.663498", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Reconciliation Payment", 
  "name_case": "", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_field": "modified", 
- "sort_order": "DESC"
+ "sort_order": "DESC", 
+ "track_seen": 0, 
+ "version": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index fc40d42..f7d9586 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -6,11 +6,11 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import flt, nowdate, get_url, cstr
+from frappe.utils import flt, get_url, nowdate
 from erpnext.accounts.party import get_party_account
 from erpnext.accounts.utils import get_account_currency
-from erpnext.accounts.doctype.journal_entry.journal_entry import (get_payment_entry_against_invoice, 
-get_payment_entry_against_order)
+from erpnext.setup.utils import get_exchange_rate
+from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
 
 class PaymentRequest(Document):		
 	def validate(self):
@@ -41,7 +41,6 @@
 	def on_submit(self):
 		send_mail = True
 		self.make_communication_entry()
-		
 		ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
 		
 		if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
@@ -77,55 +76,56 @@
 		if frappe.session.user == "Guest":
 			frappe.set_user("Administrator")
 			
-		jv = self.create_journal_entry()
+		payment_entry = self.create_payment_entry()
 		self.make_invoice()
 		
-		return jv
+		return payment_entry
 		
-	def create_journal_entry(self):
+	def create_payment_entry(self):
 		"""create entry"""
 		frappe.flags.ignore_account_permission = True
 		
 		ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
-		
-		party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company)
-		party_account_currency = get_account_currency(party_account)
-				
-		debit_in_account_currency = 0.0
-				
-		if party_account_currency == ref_doc.company_currency:
-			amount = flt(flt(self.grand_total) * \
-				flt(ref_doc.conversion_rate, ref_doc.precision("conversion_rate")), \
-				ref_doc.precision("base_grand_total"))
-			
-			if self.currency != ref_doc.company_currency:
-				debit_in_account_currency = self.grand_total
-			
-		else:
-			amount = debit_in_account_currency = self.grand_total
-				
-		if self.reference_doctype == "Sales Order":
-			jv = get_payment_entry_against_order(self.reference_doctype, self.reference_name,
-			amount=amount, debit_in_account_currency=debit_in_account_currency , journal_entry=True,
-			bank_account=self.payment_account)
-			
+
 		if self.reference_doctype == "Sales Invoice":
-			jv = get_payment_entry_against_invoice(self.reference_doctype, self.reference_name,
-			amount=amount, debit_in_account_currency=debit_in_account_currency, journal_entry=True,
-			bank_account=self.payment_account)
+			party_account = ref_doc.debit_to
+		elif self.reference_doctype == "Purchase Invoice":
+			party_account = ref_doc.credit_to
+		else:
+			party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company)
 			
-		jv.update({
-			"voucher_type": "Journal Entry",
-			"posting_date": nowdate()
-		})
+		party_account_currency = ref_doc.get("party_account_currency") or get_account_currency(party_account)
 		
-		jv.insert(ignore_permissions=True)
-		jv.submit()
+		bank_amount = self.grand_total
+		if party_account_currency == ref_doc.company_currency and party_account_currency != self.currency:
+			party_amount = self.base_grand_total
+		else:
+			party_amount = self.grand_total
+					
+		payment_entry = get_payment_entry(self.reference_doctype, self.reference_name, 
+			party_amount=party_amount, bank_account=self.payment_account, bank_amount=bank_amount)
+		
+		payment_entry.update({
+			"reference_no": self.name,
+			"reference_date": nowdate(),
+			"remarks": "Payment Entry against {0} {1} via Payment Request {2}".format(self.reference_doctype, 
+				self.reference_name, self.name)
+		})
+
+		company_details = get_company_defaults(ref_doc.company)
+		if payment_entry.difference_amount:
+			payment_entry.append("deductions", {
+				"account": company_details.exchange_gain_loss_account,
+				"cost_center": company_details.cost_center,
+				"amount": payment_entry.difference_amount
+			})
+		payment_entry.insert(ignore_permissions=True)
+		payment_entry.submit()
 
 		#set status as paid for Payment Request
 		frappe.db.set_value(self.doctype, self.name, "status", "Paid")
 		
-		return jv
+		return payment_entry
 		
 	def send_email(self):
 		"""send email with payment link"""
@@ -177,7 +177,7 @@
 	grand_total = get_amount(ref_doc, args.dt)
 	
 	existing_payment_request = frappe.db.get_value("Payment Request", 
-		{"reference_doctype": args.dt, "reference_name": args.dn})
+		{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ["!=", 2]})
 	
 	if existing_payment_request:
 		pr = frappe.get_doc("Payment Request", existing_payment_request)
@@ -199,7 +199,6 @@
 	
 		if args.return_doc:
 			return pr
-		
 		if args.submit_doc:
 			pr.insert(ignore_permissions=True)
 			pr.submit()
diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py
index eb8e558..73c412f 100644
--- a/erpnext/accounts/doctype/payment_request/test_payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py
@@ -6,7 +6,7 @@
 import frappe
 import unittest
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
-from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request, get_gateway_details
+from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.setup.utils import get_exchange_rate
 # test_records = frappe.get_test_records('Payment Request')
@@ -62,27 +62,44 @@
 		self.assertEquals(pr.currency, "USD")
 
 	def test_payment_entry(self):
+		frappe.db.set_value("Company", "_Test Company", 
+			"exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC")
+		frappe.db.set_value("Company", "_Test Company", 
+			"write_off_account", "_Test Write Off - _TC")
+		frappe.db.set_value("Company", "_Test Company", 
+			"cost_center", "_Test Cost Center - _TC")
+		
 		so_inr = make_sales_order(currency="INR")
 		pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com",
 			mute_email=1, submit_doc=1)
-		jv = pr.set_as_paid()
+		pe = pr.set_as_paid()
 
 		so_inr = frappe.get_doc("Sales Order", so_inr.name)
 
-		self.assertEquals(so_inr.advance_paid, jv.total_debit)
-
-		conversion_rate = get_exchange_rate("USD", "INR")
+		self.assertEquals(so_inr.advance_paid, 1000)
 
 		si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
-			currency="USD", conversion_rate=conversion_rate)
+			currency="USD", conversion_rate=50)
 
 		pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
-			mute_email=1, return_doc=1, payment_gateway="_Test Gateway - USD")
+			mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1)
+		
+		pe = pr.set_as_paid()
+		
+		expected_gle = dict((d[0], d) for d in [
+			["_Test Receivable USD - _TC", 0, 5000, si_usd.name],
+			[pr.payment_account, 6000.0, 0, None],
+			["_Test Exchange Gain/Loss - _TC", 0, 1000, None]
+		])
+		
+		gl_entries = frappe.db.sql("""select account, debit, credit, against_voucher
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", pe.name, as_dict=1)
 
-		jv = pr.set_as_paid()
+		self.assertTrue(gl_entries)
 
-		payment_gateway_details = get_gateway_details({"payment_gateway": "_Test Gateway - USD"})
-				
-		self.assertEquals(jv.accounts[0].account, "_Test Receivable USD - _TC")
-		self.assertEquals(jv.accounts[1].account, payment_gateway_details.payment_account)
-		
\ No newline at end of file
+		for i, gle in enumerate(gl_entries):
+			self.assertEquals(expected_gle[gle.account][0], gle.account)
+			self.assertEquals(expected_gle[gle.account][1], gle.debit)
+			self.assertEquals(expected_gle[gle.account][2], gle.credit)
+			self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 7a83c7b..8aae29e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -34,8 +34,8 @@
 		}
 
 		if(!doc.is_return && doc.docstatus==1) {
-			if(doc.outstanding_amount > 0) {
-				this.frm.add_custom_button(__('Payment'), this.make_bank_entry, __("Make"));
+			if(doc.outstanding_amount != 0) {
+				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/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index c6d04c1..b247e3e 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -2055,7 +2055,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "get_advances_paid", 
+   "fieldname": "get_advances", 
    "fieldtype": "Button", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -2066,7 +2066,7 @@
    "length": 0, 
    "no_copy": 0, 
    "oldfieldtype": "Button", 
-   "options": "get_advances", 
+   "options": "", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -3031,7 +3031,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-06-30 13:40:39.440646", 
+ "modified": "2016-06-30 13:40:39.440648", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index de65485..3bb402d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -65,7 +65,7 @@
 			self.po_required()
 			self.pr_required()
 			self.validate_supplier_invoice()
-			self.validate_advance_jv("Purchase Order")
+			
 
 		# validate cash purchase
 		if (self.is_paid == 1):
@@ -109,11 +109,6 @@
 
 		super(PurchaseInvoice, self).set_missing_values(for_validate)
 
-	def get_advances(self):
-		if not self.is_return:
-			super(PurchaseInvoice, self).get_advances(self.credit_to, "Supplier", self.supplier,
-				"Purchase Invoice Advance", "advances", "debit_in_account_currency", "purchase_order")
-
 	def check_conversion_rate(self):
 		default_currency = get_company_currency(self.company)
 		if not default_currency:
@@ -234,37 +229,6 @@
 				if not submitted:
 					frappe.throw(_("Purchase Receipt {0} is not submitted").format(d.purchase_receipt))
 
-
-	def update_against_document_in_jv(self):
-		"""
-			Links invoice and advance voucher:
-				1. cancel advance voucher
-				2. split into multiple rows if partially adjusted, assign against voucher
-				3. submit advance voucher
-		"""
-
-		lst = []
-		for d in self.get('advances'):
-			if flt(d.allocated_amount) > 0:
-				args = {
-					'voucher_no' : d.journal_entry,
-					'voucher_detail_no' : d.jv_detail_no,
-					'against_voucher_type' : 'Purchase Invoice',
-					'against_voucher'  : self.name,
-					'account' : self.credit_to,
-					'party_type': 'Supplier',
-					'party': self.supplier,
-					'is_advance' : 'Yes',
-					'dr_or_cr' : 'debit_in_account_currency',
-					'unadjusted_amt' : flt(d.advance_amount),
-					'allocated_amt' : flt(d.allocated_amount)
-				}
-				lst.append(args)
-
-		if lst:
-			from erpnext.accounts.utils import reconcile_against_document
-			reconcile_against_document(lst)
-
 	def update_status_updater_args(self):
 		if cint(self.update_stock):
 			self.status_updater.extend([{
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 5dacb9b..bb489e7 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -196,8 +196,9 @@
 
 		pi = frappe.copy_doc(test_records[0])
 		pi.append("advances", {
-			"journal_entry": jv.name,
-			"jv_detail_no": jv.get("accounts")[0].name,
+			"reference_type": "Journal Entry",
+			"reference_name": jv.name,
+			"reference_row": jv.get("accounts")[0].name,
 			"advance_amount": 400,
 			"allocated_amount": 300,
 			"remarks": jv.remark
diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
index 34156f5..462773d 100644
--- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
+++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
@@ -2,29 +2,33 @@
  "allow_copy": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2013-03-08 15:36:46", 
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Document", 
  "fields": [
   {
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "journal_entry", 
+   "fieldname": "reference_type", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Journal Entry", 
+   "in_list_view": 0, 
+   "label": "Reference Type", 
    "length": 0, 
    "no_copy": 1, 
    "oldfieldname": "journal_voucher", 
    "oldfieldtype": "Link", 
-   "options": "Journal Entry", 
+   "options": "DocType", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "180px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -38,19 +42,75 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "jv_detail_no", 
+   "fieldname": "reference_name", 
+   "fieldtype": "Dynamic Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Reference Name", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "reference_type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "remarks", 
+   "fieldtype": "Read Only", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Remarks", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "remarks", 
+   "oldfieldtype": "Small Text", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "print_width": "150px", 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0, 
+   "width": "150px"
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "reference_row", 
    "fieldtype": "Data", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Journal Entry Detail No", 
+   "label": "Reference Row", 
    "length": 0, 
    "no_copy": 1, 
    "oldfieldname": "jv_detail_no", 
    "oldfieldtype": "Date", 
    "permlevel": 0, 
    "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
    "print_width": "80px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -64,42 +124,18 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "remarks", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Remarks", 
-   "length": 0, 
-   "no_copy": 1, 
-   "oldfieldname": "remarks", 
-   "oldfieldtype": "Small Text", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_width": "150px", 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0, 
-   "width": "150px"
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "col_break1", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -115,6 +151,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Advance Amount", 
@@ -125,6 +162,7 @@
    "options": "party_account_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -142,6 +180,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Allocated Amount", 
@@ -152,6 +191,7 @@
    "options": "party_account_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "100px", 
    "read_only": 0, 
    "report_hide": 0, 
@@ -165,18 +205,23 @@
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:53.288895", 
+ "menu_index": 0, 
+ "modified": "2016-06-27 12:37:42.845967", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice Advance", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 1, 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "track_seen": 0, 
+ "version": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index d64a024..4bc634a 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -65,10 +65,14 @@
 				}
 			}
 
+			if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
+				cur_frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
+			}
+			
 			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"));
 			}
+			
 
 		}
 
@@ -244,7 +248,7 @@
 // Hide Fields
 // ------------
 cur_frm.cscript.hide_fields = function(doc) {
-	parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances_received',
+	parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances',
 		'advances', 'sales_partner', 'commission_rate', 'total_commission', 'advances', 'from_date', 'to_date'];
 
 	if(cint(doc.is_pos) == 1) {
@@ -280,20 +284,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.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 308db38..746209f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -2019,7 +2019,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "get_advances_received", 
+   "fieldname": "get_advances", 
    "fieldtype": "Button", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -2030,7 +2030,7 @@
    "length": 0, 
    "no_copy": 0, 
    "oldfieldtype": "Button", 
-   "options": "get_advances", 
+   "options": "", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -3676,7 +3676,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-07-02 20:10:14.146763", 
+ "modified": "2016-07-02 20:10:14.146963", 
  "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 470ea91..82cb365 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -77,7 +77,6 @@
 		self.check_close_sales_order("sales_order")
 		self.validate_debit_to_acc()
 		self.clear_unallocated_advances("Sales Invoice Advance", "advances")
-		self.validate_advance_jv("Sales Order")
 		self.add_remarks()
 		self.validate_write_off_account()
 		self.validate_fixed_asset()
@@ -294,44 +293,9 @@
 
 		return pos
 
-	def get_advances(self):
-		if not self.is_return:
-			super(SalesInvoice, self).get_advances(self.debit_to, "Customer", self.customer,
-				"Sales Invoice Advance", "advances", "credit_in_account_currency", "sales_order")
-
 	def get_company_abbr(self):
 		return frappe.db.sql("select abbr from tabCompany where name=%s", self.company)[0][0]
 
-	def update_against_document_in_jv(self):
-		"""
-			Links invoice and advance voucher:
-				1. cancel advance voucher
-				2. split into multiple rows if partially adjusted, assign against voucher
-				3. submit advance voucher
-		"""
-
-		lst = []
-		for d in self.get('advances'):
-			if flt(d.allocated_amount) > 0:
-				args = {
-					'voucher_no' : d.journal_entry,
-					'voucher_detail_no' : d.jv_detail_no,
-					'against_voucher_type' : 'Sales Invoice',
-					'against_voucher'  : self.name,
-					'account' : self.debit_to,
-					'party_type': 'Customer',
-					'party': self.customer,
-					'is_advance' : 'Yes',
-					'dr_or_cr' : 'credit_in_account_currency',
-					'unadjusted_amt' : flt(d.advance_amount),
-					'allocated_amt' : flt(d.allocated_amount)
-				}
-				lst.append(args)
-
-		if lst:
-			from erpnext.accounts.utils import reconcile_against_document
-			reconcile_against_document(lst)
-
 	def validate_debit_to_acc(self):
 		account = frappe.db.get_value("Account", self.debit_to,
 			["account_type", "report_type", "account_currency"], as_dict=True)
@@ -740,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/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index cc3d952..ec63b1f 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -676,8 +676,9 @@
 		si = frappe.copy_doc(test_records[0])
 		si.append("advances", {
 			"doctype": "Sales Invoice Advance",
-			"journal_entry": jv.name,
-			"jv_detail_no": jv.get("accounts")[0].name,
+			"reference_type": "Journal Entry",
+			"reference_name": jv.name,
+			"reference_row": jv.get("accounts")[0].name,
 			"advance_amount": 400,
 			"allocated_amount": 300,
 			"remarks": jv.remark
diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
index b1fae8e..06c6735 100644
--- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
+++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
@@ -2,29 +2,33 @@
  "allow_copy": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2013-02-22 01:27:41", 
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Document", 
  "fields": [
   {
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "journal_entry", 
+   "fieldname": "reference_type", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Journal Entry", 
+   "in_list_view": 0, 
+   "label": "Reference Type", 
    "length": 0, 
    "no_copy": 1, 
    "oldfieldname": "journal_voucher", 
    "oldfieldtype": "Link", 
-   "options": "Journal Entry", 
+   "options": "DocType", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "250px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -38,10 +42,37 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "remarks", 
-   "fieldtype": "Small Text", 
+   "fieldname": "reference_name", 
+   "fieldtype": "Dynamic Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 1, 
+   "label": "Reference Name", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "reference_type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "remarks", 
+   "fieldtype": "Read Only", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Remarks", 
@@ -51,8 +82,9 @@
    "oldfieldtype": "Small Text", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "150px", 
-   "read_only": 1, 
+   "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -64,19 +96,21 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "jv_detail_no", 
+   "fieldname": "reference_row", 
    "fieldtype": "Data", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Journal Entry Detail No", 
+   "label": "Reference Row", 
    "length": 0, 
    "no_copy": 1, 
    "oldfieldname": "jv_detail_no", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
    "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
    "print_width": "120px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -94,12 +128,14 @@
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -115,6 +151,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Advance amount", 
@@ -125,6 +162,7 @@
    "options": "party_account_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "120px", 
    "read_only": 1, 
    "report_hide": 0, 
@@ -142,6 +180,7 @@
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Allocated amount", 
@@ -152,6 +191,7 @@
    "options": "party_account_currency", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "print_width": "120px", 
    "read_only": 0, 
    "report_hide": 0, 
@@ -165,18 +205,24 @@
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:56.263776", 
+ "menu_index": 0, 
+ "modified": "2016-06-27 12:38:58.845134", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice Advance", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 1, 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "sort_order": "DESC", 
+ "track_seen": 0, 
+ "version": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index b7fb053..4af197e 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -160,7 +160,6 @@
 
 	gl_map.append(round_off_gle)
 
-
 def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
 		adv_adj=False, update_outstanding="Yes"):
 
@@ -168,8 +167,12 @@
 		check_freezing_date, update_outstanding_amt, validate_frozen_account
 
 	if not gl_entries:
-		gl_entries = frappe.db.sql("""select * from `tabGL Entry`
+		gl_entries = frappe.db.sql("""
+			select account, posting_date, party_type, party, cost_center, fiscal_year,
+			voucher_type, voucher_no, against_voucher_type, against_voucher, cost_center
+			from `tabGL Entry`
 			where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no), as_dict=True)
+
 	if gl_entries:
 		check_freezing_date(gl_entries[0]["posting_date"], adv_adj)
 
@@ -180,7 +183,7 @@
 		validate_frozen_account(entry["account"], adv_adj)
 		validate_balance_type(entry["account"], adv_adj)
 		validate_expense_against_budget(entry)
-
+		
 		if entry.get("against_voucher") and update_outstanding == 'Yes':
 			update_outstanding_amt(entry["account"], entry.get("party_type"), entry.get("party"), entry.get("against_voucher_type"),
 				entry.get("against_voucher"), on_cancel=True)
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 8d11374..c65a845 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -181,8 +181,16 @@
 				{"parenttype": party_group_doctype, "parent": group, "company": company}, "account")
 
 		if not account:
-			default_account_name = "default_receivable_account" if party_type=="Customer" else "default_payable_account"
+			default_account_name = "default_receivable_account" \
+				if party_type=="Customer" else "default_payable_account"
 			account = frappe.db.get_value("Company", company, default_account_name)
+			
+		existing_gle_currency = get_party_gle_currency(party_type, party, company)
+		if existing_gle_currency:
+			if account:
+				account_currency = frappe.db.get_value("Account", account, "account_currency")
+			if (account and account_currency != existing_gle_currency) or not account:
+					account = get_party_gle_account(party_type, party, company)
 
 		return account
 
@@ -203,6 +211,17 @@
 
 	return frappe.local_cache("party_gle_currency", (party_type, party, company), generator,
 		regenerate_if_none=True)
+		
+def get_party_gle_account(party_type, party, company):
+	def generator():
+		existing_gle_account = frappe.db.sql("""select account 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_account[0][0] if existing_gle_account else None
+
+	return frappe.local_cache("party_gle_account", (party_type, party, company), generator,
+		regenerate_if_none=True)
 
 def validate_party_gle_currency(party_type, party, company, party_account_currency=None):
 	"""Validate party account currency with existing GL Entry's currency"""
@@ -235,7 +254,7 @@
 
 		if doc.default_currency and party_account_currency and company_default_currency:
 			if doc.default_currency != party_account_currency and doc.default_currency != company_default_currency:
-				frappe.throw(_("Billing currency must be equal to either default comapany's currency or party's payble account currency"))
+				frappe.throw(_("Billing currency must be equal to either default comapany's currency or party account currency"))
 
 @frappe.whitelist()
 def get_due_date(posting_date, party_type, party, company):
diff --git a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.js b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.js
index 37d8130..ac3366c 100644
--- a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.js
+++ b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.js
@@ -22,6 +22,7 @@
 			"fieldtype": "Link",
 			"options": "Account",
 			"reqd": 1,
+			"default": locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"],
 			"get_query": function() {
 				return {
 					"query": "erpnext.controllers.queries.get_account_list",
diff --git a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py
index cfb677f..07ab969 100644
--- a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py
+++ b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py
@@ -3,7 +3,8 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _, msgprint
+from frappe import _
+from frappe.utils import nowdate, getdate
 
 def execute(filters=None):
 	if not filters: filters = {}
@@ -14,28 +15,36 @@
 	return columns, data
 	
 def get_columns():
-	return [_("Journal Entry") + ":Link/Journal Entry:140", _("Account") + ":Link/Account:140", 
-		_("Posting Date") + ":Date:100", _("Clearance Date") + ":Date:110", _("Against Account") + ":Link/Account:200", 
-		_("Debit") + ":Currency:120", _("Credit") + ":Currency:120"
+	return [
+		_("Payment Document") + ":Link/DocType:130", 
+		_("Payment Entry") + ":Dynamic Link/"+_("Payment Document")+":110", 
+		_("Posting Date") + ":Date:100", 
+		_("Cheque/Reference No") + "::120",
+		_("Clearance Date") + ":Date:100", 
+		_("Against Account") + ":Link/Account:170", 
+		_("Amount") + ":Currency:120"
 	]
 
 def get_conditions(filters):
 	conditions = ""
-	if not filters.get("account"):
-		msgprint(_("Please select Bank Account"), raise_exception=1)
-	else:
-		conditions += " and jvd.account = %(account)s"
 		
-	if filters.get("from_date"): conditions += " and jv.posting_date>=%(from_date)s"
-	if filters.get("to_date"): conditions += " and jv.posting_date<=%(to_date)s"
+	if filters.get("from_date"): conditions += " and posting_date>=%(from_date)s"
+	if filters.get("to_date"): conditions += " and posting_date<=%(to_date)s"
 	
 	return conditions
 	
 def get_entries(filters):
 	conditions = get_conditions(filters)
-	entries =  frappe.db.sql("""select jv.name, jvd.account, jv.posting_date, 
-		jv.clearance_date, jvd.against_account, jvd.debit, jvd.credit
+	journal_entries =  frappe.db.sql("""select "Journal Entry", jv.name, jv.posting_date, 
+		jv.cheque_no, jv.clearance_date, jvd.against_account, (jvd.debit - jvd.credit)
 		from `tabJournal Entry Account` jvd, `tabJournal Entry` jv 
-		where jvd.parent = jv.name and jv.docstatus=1 %s
-		order by jv.name DESC""" % conditions, filters, as_list=1)
-	return entries
\ No newline at end of file
+		where jvd.parent = jv.name and jv.docstatus=1 and jvd.account = %(account)s {0}
+		order by posting_date DESC, jv.name DESC""".format(conditions), filters, as_list=1)
+		
+	payment_entries =  frappe.db.sql("""select "Payment Entry", name, posting_date, 
+		reference_no, clearance_date, party, if(paid_from=%(account)s, paid_amount, received_amount)
+		from `tabPayment Entry`
+		where docstatus=1 and (paid_from = %(account)s or paid_to = %(account)s) {0}
+		order by posting_date DESC, name DESC""".format(conditions), filters, as_list=1, debug=1)
+		
+	return sorted(journal_entries + payment_entries, key=lambda k: k[2] or getdate(nowdate()))
\ No newline at end of file
diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
index 581a7c8..76e0de2 100644
--- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
+++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import flt
+from frappe.utils import flt, getdate, nowdate
 from frappe import _
 
 def execute(filters=None):
@@ -24,16 +24,8 @@
 	for d in data:
 		total_debit += flt(d.debit)
 		total_credit += flt(d.credit)
-
-	amounts_not_reflected_in_system = frappe.db.sql("""
-		select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
-		from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
-		where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%s
-		and jv.posting_date > %s and jv.clearance_date <= %s and ifnull(jv.is_opening, 'No') = 'No'
-		""", (filters["account"], filters["report_date"], filters["report_date"]))
-
-	amounts_not_reflected_in_system = flt(amounts_not_reflected_in_system[0][0]) \
-		if amounts_not_reflected_in_system else 0.0
+		
+	amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
 
 	bank_bal = flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) \
 		+ amounts_not_reflected_in_system
@@ -42,7 +34,7 @@
 		get_balance_row(_("Bank Statement balance as per General Ledger"), balance_as_per_system, account_currency),
 		{},
 		{
-			"journal_entry": _("Outstanding Cheques and Deposits to clear"),
+			"payment_entry": _("Outstanding Cheques and Deposits to clear"),
 			"debit": total_debit,
 			"credit": total_credit,
 			"account_currency": account_currency
@@ -61,13 +53,21 @@
 			"fieldname": "posting_date",
 			"label": _("Posting Date"),
 			"fieldtype": "Date",
-			"width": 100
+			"width": 90
 		},
 		{
-			"fieldname": "journal_entry",
-			"label": _("Journal Entry"),
+			"fieldname": "payment_document",
+			"label": _("Payment Document"),
 			"fieldtype": "Link",
-			"options": "Journal Entry",
+			"options": "DocType",
+			"width": 120,
+			"hidden": 1
+		},
+		{
+			"fieldname": "payment_entry",
+			"label": _("Payment Entry"),
+			"fieldtype": "Dynamic Link",
+			"options": "payment_document",
 			"width": 220
 		},
 		{
@@ -92,7 +92,7 @@
 			"width": 200
 		},
 		{
-			"fieldname": "reference",
+			"fieldname": "reference_no",
 			"label": _("Reference"),
 			"fieldtype": "Data",
 			"width": 100
@@ -119,31 +119,67 @@
 	]
 
 def get_entries(filters):
-	entries = frappe.db.sql("""select
-			jv.posting_date, jv.name as journal_entry, jvd.debit_in_account_currency as debit, 
+	journal_entries = frappe.db.sql("""
+		select "Journal Entry" as payment_document, jv.posting_date, 
+			jv.name as payment_entry, jvd.debit_in_account_currency as debit, 
 			jvd.credit_in_account_currency as credit, jvd.against_account, 
-			jv.cheque_no as reference, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency
+			jv.cheque_no as reference_no, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency
 		from
 			`tabJournal Entry Account` jvd, `tabJournal Entry` jv
 		where jvd.parent = jv.name and jv.docstatus=1
 			and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
 			and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
-			and ifnull(jv.is_opening, 'No') = 'No'
-		order by jv.posting_date DESC,jv.name DESC""", filters, as_dict=1)
+			and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
+			
+	payment_entries = frappe.db.sql("""
+		select 
+			"Payment Entry" as payment_document, name as payment_entry, 
+			reference_no, reference_date as ref_date, 
+			if(paid_to=%(account)s, received_amount, 0) as debit, 
+			if(paid_from=%(account)s, paid_amount, 0) as credit, 
+			posting_date, party as against_account, clearance_date,
+			if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
+		from `tabPayment Entry`
+		where
+			(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
+			and posting_date <= %(report_date)s
+			and ifnull(clearance_date, '4000-01-01') > %(report_date)s
+	""", filters, as_dict=1)
 
-	return entries
+	return sorted(list(payment_entries)+list(journal_entries), 
+			key=lambda k: k['posting_date'] or getdate(nowdate()))
+			
+def get_amounts_not_reflected_in_system(filters):
+	je_amount = frappe.db.sql("""
+		select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
+		from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
+		where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%(account)s
+		and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s 
+		and ifnull(jv.is_opening, 'No') = 'No' """, filters)
+
+	je_amount = flt(je_amount[0][0]) if je_amount else 0.0
+	
+	pe_amount = frappe.db.sql("""
+		select sum(if(paid_from=%(account)s, paid_amount, received_amount))
+		from `tabPayment Entry`
+		where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1 
+		and posting_date > %(report_date)s and clearance_date <= %(report_date)s""", filters)
+
+	pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0
+	
+	return je_amount + pe_amount
 
 def get_balance_row(label, amount, account_currency):
 	if amount > 0:
 		return {
-			"journal_entry": label,
+			"payment_entry": label,
 			"debit": amount,
 			"credit": 0,
 			"account_currency": account_currency
 		}
 	else:
 		return {
-			"journal_entry": label,
+			"payment_entry": label,
 			"debit": 0,
 			"credit": abs(amount),
 			"account_currency": account_currency
diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
index 20bdae8..85c7daa 100644
--- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
+++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
@@ -5,7 +5,7 @@
 import frappe
 from frappe import _
 from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data
-from frappe.utils import flt, getdate
+from frappe.utils import getdate, flt
 
 def execute(filters=None):
 	if not filters: filters = {}
@@ -14,21 +14,21 @@
 	columns = get_columns(filters)
 	entries = get_entries(filters)
 	invoice_details = get_invoice_posting_date_map(filters)
-	against_date = ""
 
 	data = []
 	for d in entries:
-		invoice = invoice_details.get(d.reference_name) or frappe._dict()
+		invoice = invoice_details.get(d.against_voucher) or frappe._dict()
+		
 		if d.reference_type=="Purchase Invoice":
 			payment_amount = flt(d.debit) or -1 * flt(d.credit)
 		else:
 			payment_amount = flt(d.credit) or -1 * flt(d.debit)
 
-		row = [d.name, d.party_type, d.party, d.posting_date, d.reference_name, invoice.posting_date, 
-			invoice.due_date, d.debit, d.credit, d.cheque_no, d.cheque_date, d.remark]
+		row = [d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher, 
+			invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks]
 
-		if d.reference_name:
-			row += get_ageing_data(30, 60, 90, d.posting_date, against_date, payment_amount)
+		if d.against_voucher:
+			row += get_ageing_data(30, 60, 90, d.posting_date, invoice.posting_date, payment_amount)
 		else:
 			row += ["", "", "", "", ""]
 		if invoice.due_date:
@@ -46,7 +46,8 @@
 
 def get_columns(filters):
 	return [
-		_("Journal Entry") + ":Link/Journal Entry:140",
+		_("Payment Document") + ":Link/DocType: 100",
+		_("Payment Entry") + ":Dynamic Link/"+_("Payment Document")+":140",
 		_("Party Type") + "::100", 
 		_("Party") + ":Dynamic Link/Party Type:140",
 		_("Posting Date") + ":Date:100",
@@ -55,8 +56,6 @@
 		_("Payment Due Date") + ":Date:130", 
 		_("Debit") + ":Currency:120", 
 		_("Credit") + ":Currency:120",
-		_("Reference No") + "::100", 
-		_("Reference Date") + ":Date:100", 
 		_("Remarks") + "::150", 
 		_("Age") +":Int:40",
 		"0-30:Currency:100", 
@@ -69,45 +68,36 @@
 def get_conditions(filters):
 	conditions = []
 
-	if not filters.get("party_type"):
-		if filters.get("payment_type") == "Outgoing":
-			filters["party_type"] = "Supplier"
+	if not filters.party_type:
+		if filters.payment_type == "Outgoing":
+			filters.party_type = "Supplier"
 		else:
-			filters["party_type"] = "Customer"
+			filters.party_type = "Customer"
 
-	if filters.get("party_type"):
-		conditions.append("jvd.party_type=%(party_type)s")
+	if filters.party_type:
+		conditions.append("party_type=%(party_type)s")
 
-	if filters.get("party"):
-		conditions.append("jvd.party=%(party)s")
+	if filters.party:
+		conditions.append("party=%(party)s")
 		
-	if filters.get("party_type"):
-		conditions.append("jvd.reference_type=%(reference_type)s")
-		if filters.get("party_type") == "Customer":
-			filters["reference_type"] = "Sales Invoice"
-		else:
-			filters["reference_type"] = "Purchase Invoice"
-		
-	if filters.get("company"):
-		conditions.append("jv.company=%(company)s")
+	if filters.party_type:
+		conditions.append("against_voucher_type=%(reference_type)s")
+		filters["reference_type"] = "Sales Invoice" if filters.party_type=="Customer" else "Purchase Invoice"
 
 	if filters.get("from_date"):
-		conditions.append("jv.posting_date >= %(from_date)s")
+		conditions.append("posting_date >= %(from_date)s")
+		
 	if filters.get("to_date"):
-		conditions.append("jv.posting_date <= %(to_date)s")
+		conditions.append("posting_date <= %(to_date)s")
 
-	return "and {}".format(" and ".join(conditions)) if conditions else ""
+	return "and " + " and ".join(conditions) if conditions else ""
 
 def get_entries(filters):
-	conditions = get_conditions(filters)
-	entries =  frappe.db.sql("""select jv.name, jvd.party_type, jvd.party, jv.posting_date,
-		jvd.reference_type, jvd.reference_name, jvd.debit, jvd.credit,
-		jv.cheque_no, jv.cheque_date, jv.remark
-		from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
-		where jvd.parent = jv.name and jv.docstatus=1 %s order by jv.name DESC""" %
-		conditions, filters, as_dict=1)
-
-	return entries
+	return frappe.db.sql("""select 
+		voucher_type, voucher_no, party_type, party, posting_date, debit, credit, remarks, against_voucher
+		from `tabGL Entry`
+		where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') {0}
+	""".format(get_conditions(filters)), filters, as_dict=1)
 
 def get_invoice_posting_date_map(filters):
 	invoice_details = {}
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 27389aa..6bd5eb1 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -172,53 +172,77 @@
 		Cancel JV, Update aginst document, split if required and resubmit jv
 	"""
 	for d in args:
-		check_if_jv_modified(d)
+		
+		check_if_advance_entry_modified(d)			
 		validate_allocated_amount(d)
+		
+		# cancel advance entry
+		doc = frappe.get_doc(d.voucher_type, d.voucher_no)
 
-		# cancel JV
-		jv_obj = frappe.get_doc('Journal Entry', d['voucher_no'])
+		doc.make_gl_entries(cancel=1, adv_adj=1)
 
-		jv_obj.make_gl_entries(cancel=1, adv_adj=1)
+		# update ref in advance entry
+		if d.voucher_type == "Journal Entry":
+			update_reference_in_journal_entry(d, doc)
+		else:
+			update_reference_in_payment_entry(d, doc)
 
-		# update ref in JV Detail
-		update_against_doc(d, jv_obj)
+		# re-submit advance entry
+		doc = frappe.get_doc(d.voucher_type, d.voucher_no)
+		doc.make_gl_entries(cancel = 0, adv_adj =1)
 
-		# re-submit JV
-		jv_obj = frappe.get_doc('Journal Entry', d['voucher_no'])
-		jv_obj.make_gl_entries(cancel = 0, adv_adj =1)
-
-
-def check_if_jv_modified(args):
+def check_if_advance_entry_modified(args):
 	"""
 		check if there is already a voucher reference
 		check if amount is same
 		check if jv is submitted
 	"""
-	ret = frappe.db.sql("""
-		select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2
-		where t1.name = t2.parent and t2.account = %(account)s
-		and t2.party_type = %(party_type)s and t2.party = %(party)s
-		and (t2.reference_type is null or t2.reference_type in ("", "Sales Order", "Purchase Order"))
-		and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
-		and t1.docstatus=1 """.format(dr_or_cr = args.get("dr_or_cr")), args)
+	ret = None
+	if args.voucher_type == "Journal Entry":
+		ret = frappe.db.sql("""
+			select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2
+			where t1.name = t2.parent and t2.account = %(account)s
+			and t2.party_type = %(party_type)s and t2.party = %(party)s
+			and (t2.reference_type is null or t2.reference_type in ("", "Sales Order", "Purchase Order"))
+			and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
+			and t1.docstatus=1 """.format(dr_or_cr = args.get("dr_or_cr")), args)
+	else:
+		party_account_field = "paid_from" if args.party_type == "Customer" else "paid_to"
+		if args.voucher_detail_no:
+			ret = frappe.db.sql("""select t1.name 			
+				from `tabPayment Entry` t1, `tabPayment Entry Reference` t2 
+				where
+					t1.name = t2.parent and t1.docstatus = 1 
+					and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
+					and t1.party_type = %(party_type)s and t1.party = %(party)s and t1.{0} = %(account)s
+					and t2.reference_doctype in ("", "Sales Order", "Purchase Order") 
+					and t2.allocated_amount = %(unadjusted_amount)s
+			""".format(party_account_field), args)
+		else:
+			ret = frappe.db.sql("""select name from `tabPayment Entry`
+				where
+					name = %(voucher_no)s and docstatus = 1
+					and party_type = %(party_type)s and party = %(party)s and {0} = %(account)s
+					and unallocated_amount = %(unadjusted_amount)s
+			""".format(party_account_field), args)
 
 	if not ret:
 		throw(_("""Payment Entry has been modified after you pulled it. Please pull it again."""))
 
 def validate_allocated_amount(args):
-	if args.get("allocated_amt") < 0:
+	if args.get("allocated_amount") < 0:
 		throw(_("Allocated amount can not be negative"))
-	elif args.get("allocated_amt") > args.get("unadjusted_amt"):
-		throw(_("Allocated amount can not greater than unadusted amount"))
+	elif args.get("allocated_amount") > args.get("unadjusted_amount"):
+		throw(_("Allocated amount can not greater than unadjusted amount"))
 
-def update_against_doc(d, jv_obj):
+def update_reference_in_journal_entry(d, jv_obj):
 	"""
 		Updates against document, if partial amount splits into rows
 	"""
 	jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
-	jv_detail.set(d["dr_or_cr"], d["allocated_amt"])
+	jv_detail.set(d["dr_or_cr"], d["allocated_amount"])
 	jv_detail.set('debit' if d['dr_or_cr']=='debit_in_account_currency' else 'credit',
-		d["allocated_amt"]*flt(jv_detail.exchange_rate))
+		d["allocated_amount"]*flt(jv_detail.exchange_rate))
 
 	original_reference_type = jv_detail.reference_type
 	original_reference_name = jv_detail.reference_name
@@ -226,14 +250,14 @@
 	jv_detail.set("reference_type", d["against_voucher_type"])
 	jv_detail.set("reference_name", d["against_voucher"])
 
-	if d['allocated_amt'] < d['unadjusted_amt']:
+	if d['allocated_amount'] < d['unadjusted_amount']:
 		jvd = frappe.db.sql("""
 			select cost_center, balance, against_account, is_advance,
 				account_type, exchange_rate, account_currency
 			from `tabJournal Entry Account` where name = %s
 		""", d['voucher_detail_no'], as_dict=True)
 
-		amount_in_account_currency = flt(d['unadjusted_amt']) - flt(d['allocated_amt'])
+		amount_in_account_currency = flt(d['unadjusted_amount']) - flt(d['allocated_amount'])
 		amount_in_company_currency = amount_in_account_currency * flt(jvd[0]['exchange_rate'])
 
 		# new entry with balance amount
@@ -263,6 +287,39 @@
 	# will work as update after submit
 	jv_obj.flags.ignore_validate_update_after_submit = True
 	jv_obj.save(ignore_permissions=True)
+	
+def update_reference_in_payment_entry(d, payment_entry):
+	reference_details = {
+		"reference_doctype": d.against_voucher_type,
+		"reference_name": d.against_voucher,
+		"total_amount": d.grand_total,
+		"outstanding_amount": d.outstanding_amount,
+		"allocated_amount": d.allocated_amount,
+		"exchange_rate": d.exchange_rate
+	}
+		
+	if d.voucher_detail_no:
+		existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0]
+		original_row = existing_row.as_dict().copy()
+		existing_row.update(reference_details)
+		
+		if d.allocated_amount < original_row.allocated_amount:
+			new_row = payment_entry.append("references")
+			new_row.docstatus = 1
+			for field in reference_details.keys():
+				new_row.set(field, original_row[field])
+			
+			new_row.allocated_amount = original_row.allocated_amount - d.allocated_amount
+	else:
+		new_row = payment_entry.append("references")
+		new_row.docstatus = 1
+		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)
 
 def remove_against_link_from_jv(ref_type, ref_no):
 	linked_jv = frappe.db.sql_list("""select parent from `tabJournal Entry Account`
@@ -290,7 +347,7 @@
 	value = frappe.db.get_value("Company", company, fieldname)
 
 	if not value:
-		throw(_("Please set default value {0} in Company {1}").format(frappe.get_meta("Company").get_label(fieldname), company))
+		throw(_("Please set default {0} in Company {1}").format(frappe.get_meta("Company").get_label(fieldname), company))
 
 	return value
 
@@ -378,7 +435,7 @@
 		payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
 
 	invoice_list = frappe.db.sql("""select
-			voucher_no,	voucher_type, posting_date,
+			voucher_no,	voucher_type, posting_date, 
 			ifnull(sum({dr_or_cr}), 0) as invoice_amount,
 			(
 				select
@@ -401,11 +458,11 @@
 			and {dr_or_cr} > 0
 			{condition}
 			and ((voucher_type = 'Journal Entry'
-					and (against_voucher = ''
-						or against_voucher is null))
-				or (voucher_type != 'Journal Entry'))
+					and (against_voucher = '' or against_voucher is null))
+				or (voucher_type not in ('Journal Entry', 'Payment Entry')))
 		group by voucher_type, voucher_no
-		having (invoice_amount - payment_amount) > 0.005""".format(
+		having (invoice_amount - payment_amount) > 0.005
+		order by posting_date, name""".format(
 			dr_or_cr = dr_or_cr,
 			payment_dr_or_cr = payment_dr_or_cr,
 			condition = condition or ""
@@ -416,16 +473,18 @@
 		}, as_dict=True)
 
 	for d in invoice_list:
-		outstanding_invoices.append({
+		outstanding_invoices.append(frappe._dict({
 			'voucher_no': d.voucher_no,
 			'voucher_type': d.voucher_type,
 			'posting_date': d.posting_date,
 			'invoice_amount': flt(d.invoice_amount),
 			'payment_amount': flt(d.payment_amount),
 			'outstanding_amount': flt(d.invoice_amount - d.payment_amount, precision),
-			'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date")
-		})
-
+			'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date"),
+		}))
+		
+	outstanding_invoices = sorted(outstanding_invoices, key=lambda k: k['due_date'] or getdate(nowdate()))
+	
 	return outstanding_invoices
 
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 9e44855..f5d4e2e 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -76,7 +76,7 @@
 					this.make_purchase_invoice, __("Make"));
 
 			if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
-				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry, __("Make"));
+				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __("Make"));
 			}
 			cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
 
@@ -184,20 +184,6 @@
 		this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
 	},
 
-	make_bank_entry: function() {
-		return frappe.call({
-			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order",
-			args: {
-				"dt": "Purchase Order",
-				"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);
-			}
-		});
-	},
-
 	unclose_purchase_order: function(){
 		cur_frm.cscript.update_status('Re-open', 'Submitted')
 	},
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index d4b2221..ec1bf46 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -308,7 +308,7 @@
 	def postprocess(source, target):
 		set_missing_values(source, target)
 		#Get the advance paid Journal Entries in Purchase Invoice Advance
-		target.get_advances()
+		target.set_advances()
 
 	def update_item(obj, target, source_parent):
 		target.amount = flt(obj.amount) - flt(obj.billed_amt)
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index b6b1480..9dd50f8 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -46,6 +46,11 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Payment Entry",
+					"description": _("Payment entries against party or for internal transfer")
+				},
+				{
+					"type": "doctype",
 					"name": "Journal Entry",
 					"description": _("Accounting journal entries.")
 				},
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index e3a66a4..2b67ceb 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -42,6 +42,7 @@
 
 		if self.doctype in ("Sales Invoice", "Purchase Invoice") and not self.is_return:
 			self.validate_due_date()
+			self.validate_advance_entries()
 
 		if self.meta.get_field("taxes_and_charges"):
 			self.validate_enabled_taxes_and_charges()
@@ -255,7 +256,7 @@
 		if not account_currency:
 			account_currency = get_account_currency(gl_dict.account)
 
-		if self.doctype not in ["Journal Entry", "Period Closing Voucher"]:
+		if self.doctype not in ["Journal Entry", "Period Closing Voucher", "Payment Entry"]:
 			self.validate_account_currency(gl_dict.account, account_currency)
 			set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency)
 
@@ -276,71 +277,114 @@
 		frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s
 			and allocated_amount = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
 
-	def get_advances(self, account_head, party_type, party, child_doctype, parentfield, dr_or_cr, against_order_field):
+	def set_advances(self):
 		"""Returns list of advances against Account, Party, Reference"""
-		order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
+				
+		res = self.get_advance_entries()
 
-		# conver sales_order to "Sales Order"
-		reference_type = against_order_field.replace("_", " ").title()
-
-		condition = ""
-		if order_list:
-			in_placeholder = ', '.join(['%s'] * len(order_list))
-			condition = "or (t2.reference_type = '{0}' and ifnull(t2.reference_name, '') in ({1}))"\
-				.format(reference_type, in_placeholder)
-
-		res = frappe.db.sql("""
-			select
-				t1.name as jv_no, t1.remark, t2.{0} as amount, t2.name as jv_detail_no,
-				t2.reference_name as against_order
-			from
-				`tabJournal Entry` t1, `tabJournal Entry Account` t2
-			where
-				t1.name = t2.parent and t2.account = %s
-				and t2.party_type = %s and t2.party = %s
-				and t2.is_advance = 'Yes' and t1.docstatus = 1
-				and (ifnull(t2.reference_type, '')='' {1})
-			order by t1.posting_date""".format(dr_or_cr, condition),
-			[account_head, party_type, party] + order_list, as_dict=1)
-
-		self.set(parentfield, [])
+		self.set("advances", [])
 		for d in res:
-			self.append(parentfield, {
-				"doctype": child_doctype,
-				"journal_entry": d.jv_no,
-				"jv_detail_no": d.jv_detail_no,
-				"remarks": d.remark,
+			self.append("advances", {
+				"doctype": self.doctype + " Advance",
+				"reference_type": d.reference_type,
+				"reference_name": d.reference_name,
+				"reference_row": d.reference_row,
+				"remarks": d.remarks,
 				"advance_amount": flt(d.amount),
 				"allocated_amount": flt(d.amount) if d.against_order else 0
 			})
+			
+	def get_advance_entries(self, include_unallocated=True):
+		if self.doctype == "Sales Invoice":
+			party_account = self.debit_to
+			party_type = "Customer"
+			party = self.customer
+			amount_field = "credit_in_account_currency"
+			order_field = "sales_order"
+			order_doctype = "Sales Order"
+		else:
+			party_account = self.credit_to
+			party_type = "Supplier"
+			party = self.supplier
+			amount_field = "debit_in_account_currency"
+			order_field = "purchase_order"
+			order_doctype = "Purchase Order"
+			
+		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)
+			
+		payment_entries = get_advance_payment_entries(party_type, party, party_account, 
+			order_doctype, order_list, include_unallocated)
+		
+		res = journal_entries + payment_entries
+		
+		return res
 
-	def validate_advance_jv(self, reference_type):
-		against_order_field = frappe.scrub(reference_type)
-		order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
-		if order_list:
-			account = self.get("debit_to" if self.doctype=="Sales Invoice" else "credit_to")
+	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:
+			advance_entries_against_si = [d.reference_name for d in self.get("advances")]
+			for d in advance_entries:
+				if not advance_entries_against_si or d.reference_name not in advance_entries_against_si:
+					frappe.msgprint(_("Payment Entry {0} is linked against Order {1}, check if it should be pulled as advance in this invoice.")
+						.format(d.reference_name, d.against_order))
+						
+	def update_against_document_in_jv(self):
+		"""
+			Links invoice and advance voucher:
+				1. cancel advance voucher
+				2. split into multiple rows if partially adjusted, assign against voucher
+				3. submit advance voucher
+		"""
+		
+		if self.doctype == "Sales Invoice":
+			party_type = "Customer"
+			party = self.customer
+			party_account = self.debit_to
+			dr_or_cr = "credit_in_account_currency"
+		else:
+			party_type = "Supplier"
+			party = self.supplier
+			party_account = self.credit_to
+			dr_or_cr = "debit_in_account_currency"
 
-			jv_against_order = frappe.db.sql("""select parent, reference_name as against_order
-				from `tabJournal Entry Account`
-				where docstatus=1 and account=%s and ifnull(is_advance, 'No') = 'Yes'
-				and reference_type=%s
-				and ifnull(reference_name, '') in ({0})
-				group by parent, reference_name""".format(', '.join(['%s']*len(order_list))),
-					tuple([account, reference_type] + order_list), as_dict=1)
-
-			if jv_against_order:
-				order_jv_map = {}
-				for d in jv_against_order:
-					order_jv_map.setdefault(d.against_order, []).append(d.parent)
-
-				advance_jv_against_si = [d.journal_entry for d in self.get("advances")]
-
-				for order, jv_list in order_jv_map.items():
-					for jv in jv_list:
-						if not advance_jv_against_si or jv not in advance_jv_against_si:
-							frappe.msgprint(_("Journal Entry {0} is linked against Order {1}, check if it should be pulled as advance in this invoice.")
-								.format(jv, order))
-
+		lst = []
+		for d in self.get('advances'):
+			if flt(d.allocated_amount) > 0:
+				args = frappe._dict({
+					'voucher_type': d.reference_type,
+					'voucher_no' : d.reference_name,
+					'voucher_detail_no' : d.reference_row,
+					'against_voucher_type' : self.doctype,
+					'against_voucher'  : self.name,
+					'account' : party_account,
+					'party_type': party_type,
+					'party': party,
+					'is_advance' : 'Yes',
+					'dr_or_cr' : dr_or_cr,
+					'unadjusted_amount' : flt(d.advance_amount),
+					'allocated_amount' : flt(d.allocated_amount),
+					'exchange_rate': (self.conversion_rate 
+						if self.party_account_currency != self.company_currency else 1),
+					'grand_total': (self.base_grand_total 
+						if self.party_account_currency==self.company_currency else self.grand_total),
+					'outstanding_amount': self.outstanding_amount
+				})
+				lst.append(args)
+				
+		if lst:
+			from erpnext.accounts.utils import reconcile_against_document
+			reconcile_against_document(lst)
 
 	def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
 		from erpnext.controllers.status_updater import get_tolerance_for
@@ -396,10 +440,10 @@
 			select
 				account_currency, sum({dr_or_cr}) as amount
 			from
-				`tabJournal Entry Account`
+				`tabGL Entry`
 			where
-				reference_type = %s and reference_name = %s and party=%s
-				and docstatus = 1 and is_advance = "Yes"
+				against_voucher_type = %s and against_voucher = %s and party=%s
+				and docstatus = 1
 		""".format(dr_or_cr=dr_or_cr), (self.doctype, self.name, party), as_dict=1)
 
 		if advance:
@@ -420,11 +464,11 @@
 				formatted_order_total = fmt_money(order_total, precision=self.precision("base_grand_total"),
 					currency=advance.account_currency)
 
-			if order_total >= advance_paid:
-				frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid)
-			else:
+			if self.currency == self.company_currency and advance_paid > order_total:
 				frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})")
 					.format(formatted_advance_paid, self.name, formatted_order_total))
+					
+			frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid)
 
 	@property
 	def company_abbr(self):
@@ -600,3 +644,77 @@
 	if flt(gl_dict.credit) and not flt(gl_dict.credit_in_account_currency):
 		gl_dict.credit_in_account_currency = gl_dict.credit if account_currency==company_currency \
 			else flt(gl_dict.credit / conversion_rate, 2)
+
+
+def get_advance_journal_entries(party_type, party, party_account, amount_field, 
+		order_doctype, order_list, include_unallocated=True):
+		
+	dr_or_cr = "credit_in_account_currency" if party_type=="Customer" else "debit_in_account_currency"
+	
+	conditions = []
+	if include_unallocated:
+		conditions.append("ifnull(t2.reference_name, '')=''")
+
+	if order_list:
+		order_condition = ', '.join(['%s'] * len(order_list))
+		conditions.append(" (t2.reference_type = '{0}' and ifnull(t2.reference_name, '') in ({1}))"\
+			.format(order_doctype, order_condition))
+		
+	reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
+	
+	journal_entries = frappe.db.sql("""
+		select
+			"Journal Entry" as reference_type, t1.name as reference_name, 
+			t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
+			t2.reference_name as against_order
+		from
+			`tabJournal Entry` t1, `tabJournal Entry Account` t2
+		where
+			t1.name = t2.parent and t2.account = %s
+			and t2.party_type = %s and t2.party = %s
+			and t2.is_advance = 'Yes' and t1.docstatus = 1
+			and {1} > 0
+			and (ifnull(t2.reference_name, '')='' {2})
+		order by t1.posting_date""".format(amount_field, dr_or_cr, reference_condition),
+		[party_account, party_type, party] + order_list, as_dict=1)
+		
+	return list(journal_entries)
+	
+def get_advance_payment_entries(party_type, party, party_account, 
+		order_doctype, order_list=None, include_unallocated=True, against_all_orders=False):
+	party_account_field = "paid_from" if party_type == "Customer" else "paid_to"
+	payment_type = "Receive" if party_type == "Customer" else "Pay"
+	payment_entries_against_order, unallocated_payment_entries = [], []
+
+	if order_list or against_all_orders:
+		if order_list:
+			reference_condition = " and t2.reference_name in ({0})"\
+				.format(', '.join(['%s'] * len(order_list)))
+		else:
+			reference_condition = ""
+			order_list = []
+		
+		payment_entries_against_order = frappe.db.sql("""
+			select
+				"Payment Entry" as reference_type, t1.name as reference_name,
+				t1.remarks, t2.allocated_amount as amount, t2.name as reference_row,
+				t2.reference_name as against_order, t1.posting_date
+			from `tabPayment Entry` t1, `tabPayment Entry Reference` t2 
+			where
+				t1.name = t2.parent and t1.{0} = %s and t1.payment_type = %s
+				and t1.party_type = %s and t1.party = %s and t1.docstatus = 1
+				and t2.reference_doctype = %s {1}
+		""".format(party_account_field, reference_condition), 
+		[party_account, payment_type, party_type, party, order_doctype] + order_list, as_dict=1)
+		
+	if include_unallocated:
+		unallocated_payment_entries = frappe.db.sql("""
+				select "Payment Entry" as reference_type, name as reference_name, 
+				remarks, unallocated_amount as amount
+				from `tabPayment Entry`
+				where
+					{0} = %s and party_type = %s and party = %s and payment_type = %s
+					and docstatus = 1 and unallocated_amount > 0
+			""".format(party_account_field), (party_account, party_type, party, payment_type), as_dict=1)
+		
+	return list(payment_entries_against_order) + list(unallocated_payment_entries)
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index d6bb12e..bafa008 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -10,7 +10,7 @@
 			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
 			args: {
 				"company": cur_frm.doc.company,
-				"voucher_type": "Bank Entry"
+				"account_type": "Bank"
 			},
 			callback: function(r) {
 				var jv = frappe.model.make_new_doc_and_get_name('Journal Entry');
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 911e42c..d4de2e9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -285,3 +285,4 @@
 erpnext.patches.v7_0.set_is_group_for_warehouse
 erpnext.patches.v7_0.update_maintenance_module_in_doctype
 erpnext.patches.v7_0.update_prevdoc_values_for_supplier_quotation_item
+erpnext.patches.v7_0.rename_advance_table_fields
\ No newline at end of file
diff --git a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
index 37b6c63..b1464d5 100644
--- a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
+++ b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
@@ -5,6 +5,9 @@
 import frappe
 
 def execute():
+	frappe.reload_doctype("Sales Invoice Advance")
+	frappe.reload_doctype("Purchase Invoice Advance")
+	
 	je_rows = frappe.db.sql("""
 		select name, parent, reference_type, reference_name, debit, credit
 		from `tabJournal Entry Account`
@@ -23,7 +26,7 @@
 		is_advance_entry=None
 		if d.reference_type in ("Sales Invoice", "Purchase Invoice") and d.reference_name:
 			is_advance_entry = frappe.db.sql("""select name from `tab{0}` 
-				where journal_entry=%s and jv_detail_no=%s 
+				where reference_name=%s and reference_row=%s 
 					and ifnull(allocated_amount, 0) > 0 and docstatus=1"""
 				.format(d.reference_type + " Advance"), (d.parent, d.name))
 				
diff --git a/erpnext/patches/v7_0/rename_advance_table_fields.py b/erpnext/patches/v7_0/rename_advance_table_fields.py
new file mode 100644
index 0000000..ba8b2da
--- /dev/null
+++ b/erpnext/patches/v7_0/rename_advance_table_fields.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+	for dt in ("Sales Invoice Advance", "Purchase Invoice Advance"):
+		frappe.reload_doctype(dt)
+		
+		frappe.db.sql("update `tab{0}` set reference_type = 'Journal Entry'".format(dt))
+		
+		rename_field(dt, "journal_entry", "reference_name")
+		rename_field(dt, "jv_detail_no", "reference_row")
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ce11c8a..1379048 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -4,6 +4,16 @@
 erpnext.TransactionController = erpnext.taxes_and_totals.extend({
 	setup: function() {
 		this._super();
+		
+		if(in_list(["Sales Invoice", "Purchase Invoice"], this.frm.doc.doctype)) {
+			this.frm.get_field('advances').grid.editable_fields = [
+				{fieldname: 'reference_name', columns: 2},
+				{fieldname: 'remarks', columns: 3},
+				{fieldname: 'advance_amount', columns: 3},
+				{fieldname: 'allocated_amount', columns: 3}
+			];
+		}
+		
 		frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
 			var item = frappe.get_doc(cdt, cdn);
 			frappe.model.round_floats_in(item, ["rate", "price_list_rate"]);
@@ -159,7 +169,6 @@
 		this.show_item_wise_taxes();
 		this.set_dynamic_labels();
 		this.setup_sms();
-		this.make_show_payments_btn();
 	},
 
 	apply_default_taxes: function() {
@@ -195,22 +204,6 @@
 		var sms_man = new SMSManager(this.frm.doc);
 	},
 
-	make_show_payments_btn: function() {
-		var me = this;
-		if (in_list(["Purchase Invoice", "Sales Invoice"], this.frm.doctype)) {
-			if(this.frm.doc.outstanding_amount !== this.frm.doc.base_grand_total) {
-				this.frm.add_custom_button(__("Payments"), function() {
-					frappe.route_options = {
-						"Journal Entry Account.reference_type": me.frm.doc.doctype,
-						"Journal Entry Account.reference_name": me.frm.doc.name
-					};
-
-					frappe.set_route("List", "Journal Entry");
-				}, __("View"));
-			}
-		}
-	},
-
 	barcode: function(doc, cdt, cdn) {
 		var d = locals[cdt][cdn];
 		if(d.barcode=="" || d.barcode==null) {
@@ -978,5 +971,32 @@
 		if(!this.item_selector) {
 			this.item_selector = new erpnext.ItemSelector({frm: this.frm});
 		}
+	},
+	
+	get_advances: function() {
+		if(!this.frm.is_return) {
+			return this.frm.call({
+				method: "set_advances",
+				doc: this.frm.doc,
+				callback: function(r, rt) {
+					refresh_field("advances");
+				}
+			})
+		}
+	},
+	
+	make_payment_entry: function() {
+		return frappe.call({
+			method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
+			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);
+				// cur_frm.refresh_fields()
+			}
+		});
 	}
 });
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index ce9c958..5f1a5c7 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -76,11 +76,12 @@
 
 				if(flt(doc.per_billed)==0) {
 					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'), cur_frm.cscript.make_payment_entry, __("Make"));
 				}
 
 				// maintenance
-				if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
+				if(flt(doc.per_delivered, 2) < 100 && 
+						["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
 					cur_frm.add_custom_button(__('Maintenance Visit'), this.make_maintenance_visit, __("Make"));
 					cur_frm.add_custom_button(__('Maintenance Schedule'), this.make_maintenance_schedule, __("Make"));
 				}
@@ -157,19 +158,6 @@
 		})
 	},
 
-	make_bank_entry: function() {
-		return frappe.call({
-			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order",
-			args: {
-				"dt": "Sales Order",
-				"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);
-			}
-		});
-	},
 	make_purchase_order: function(){
 		var dialog = new frappe.ui.Dialog({
 			title: __("For Supplier"),
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 8103756..8fcd89d 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -441,7 +441,7 @@
 	def postprocess(source, target):
 		set_missing_values(source, target)
 		#Get the advance paid Journal Entries in Sales Invoice Advance
-		target.get_advances()
+		target.set_advances()
 
 	def set_missing_values(source, target):
 		target.is_pos = 0
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 2a18286..ff12f68 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -136,6 +136,8 @@
 		["default_expense_account", {"root_type": "Expense"}],
 		["default_income_account", {"root_type": "Income"}],
 		["round_off_account", {"root_type": "Expense"}],
+		["write_off_account", {"root_type": "Expense"}],
+		["exchange_gain_loss_account", {"root_type": "Expense"}],
 		["accumulated_depreciation_account", {"root_type": "Asset"}],
 		["depreciation_expense_account", {"root_type": "Expense"}],
 		["disposal_account", {"report_type": "Profit and Loss"}],
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 9140534..25e0cfb 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -499,6 +499,58 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "write_off_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Write Off Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "exchange_gain_loss_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Exchange Gain / Loss Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "column_break0", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -1325,6 +1377,7 @@
  "hide_toolbar": 0, 
  "icon": "icon-building", 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
  "in_dialog": 0, 
  "is_submittable": 0, 
@@ -1332,7 +1385,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-05-16 15:24:47.178826", 
+ "modified": "2016-06-26 09:08:50.476200", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Company",