Payment tool as per party model
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js
index 3e0d2ee..bbdd7d2 100644
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.js
+++ b/erpnext/accounts/doctype/payment_tool/payment_tool.js
@@ -8,13 +8,19 @@
 	frm.set_value("make_jv_help", '<i class="icon-hand-right"></i> '
 		+ __("Note: If payment is not made against any reference, make Journal Voucher manually."));
 
+	frm.set_query("party_type", function() {
+		return {
+			filters: {"name": ["in", ["Customer", "Supplier"]]}
+		};
+	});
+
 	frm.set_query("payment_account", function() {
 		return {
-			filters: [
-				['Account', 'account_type', 'in', 'Bank, Cash'],
-				['Account', 'group_or_ledger', '=', 'Ledger'],
-				['Account', 'company', '=', frm.doc.company]
-			]
+			filters: {
+				"account_type": ["in", ["Receivable", "Payable"]],
+				"group_or_ledger": "Ledger",
+				"company": frm.doc.company
+			}
 		}
 	});
 
@@ -29,10 +35,24 @@
 	frappe.ui.form.trigger("Payment Tool", "party_type");
 });
 
-frappe.ui.form.on("Payment Tool", "party_type", function(frm) {
-	frm.toggle_reqd("customer", frm.doc.party_type == "Customer");
-	frm.toggle_reqd("supplier", frm.doc.party_type == "Supplier");
-});
+frappe.ui.form.on("Payment Tool", "party", function(frm) {
+	if(!frm.doc.party_account && frm.doc.party_type && frm.doc.party) {
+		return frappe.call({
+			method: "erpnext.accounts.party.get_party_account",
+			args: {
+				company: frm.doc.company,
+				party_type: frm.doc.party_type,
+				party: frm.doc.party
+			},
+			callback: function(r) {
+				if(!r.exc && r.message) {
+					frappe.model.set_value("party_account", r.message);
+					erpnext.payment_tool.check_mandatory_to_set_button(frm);
+				}
+			}
+		});
+	}
+})
 
 frappe.ui.form.on("Payment Tool", "company", function(frm) {
 	erpnext.payment_tool.check_mandatory_to_set_button(frm);
@@ -45,44 +65,12 @@
 // Fetch bank/cash account based on payment mode
 cur_frm.add_fetch("payment_mode", "default_account", "payment_account");
 
-// Set party account name
-frappe.ui.form.on("Payment Tool", "customer", function(frm) {
-	erpnext.payment_tool.set_party_account(frm);
-	erpnext.payment_tool.check_mandatory_to_set_button(frm);
-});
-
-frappe.ui.form.on("Payment Tool", "supplier", function(frm) {
-	erpnext.payment_tool.set_party_account(frm);
-	erpnext.payment_tool.check_mandatory_to_set_button(frm);
-});
-
 erpnext.payment_tool.check_mandatory_to_set_button = function(frm) {
-	if (frm.doc.company && frm.doc.party_type && frm.doc.received_or_paid && (frm.doc.customer || frm.doc.supplier)) {
+	if (frm.doc.company && frm.doc.party_type && frm.doc.party && frm.doc.received_or_paid) {
 		frm.fields_dict.get_outstanding_vouchers.$input.addClass("btn-primary");
 	}
 }
 
-//Set Button color
-erpnext.payment_tool.set_party_account = function(frm) {
-	if(frm.doc.party_type == "Customer") {
-		var party_name = frm.doc.customer;
-	} else {
-		var party_name = frm.doc.supplier;
-	}
-	return  frappe.call({
-		method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_party_account',
-		args: {
-			party_type: frm.doc.party_type,
-			party_name: party_name
-		},
-		callback: function(r, rt) {
-			if(!r.exc) {
-				frm.set_value("party_account", r.message);
-			}
-		}
-	});
-}
-
 // Get outstanding vouchers
 frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) {
 	erpnext.payment_tool.check_mandatory_to_fetch(frm.doc);
@@ -96,7 +84,7 @@
 				"company": frm.doc.company,
 				"party_type": frm.doc.party_type,
 				"received_or_paid": frm.doc.received_or_paid,
-				"party_name": frm.doc.party_type == "Customer" ? frm.doc.customer : frm.doc.supplier,
+				"party": frm.doc.party,
 				"party_account": frm.doc.party_account
 			}
 		},
@@ -204,14 +192,7 @@
 });
 
 erpnext.payment_tool.check_mandatory_to_fetch = function(doc) {
-	var check_fields = [
-		['Company', doc.company],
-		['Party Type', doc.party_type],
-		['Received Or Paid', doc.received_or_paid],
-		['Customer / Supplier', doc.party_type == "Customer" ? doc.customer : doc.supplier]
-	];
-
-	$.each(check_fields, function(i, v) {
-		if(!v[1]) frappe.throw(__("Please select {0} first", [v[0]]));
+	$.each(["Company", "Party Type", "Party", "Received or Paid"], function(i, field) {
+		if(!doc[frappe.model.scrub(field)]]) frappe.throw(__("Please select {0} first", [field]));
 	});
 }
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.json b/erpnext/accounts/doctype/payment_tool/payment_tool.json
index b2949a9..883043b 100644
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.json
+++ b/erpnext/accounts/doctype/payment_tool/payment_tool.json
@@ -26,14 +26,14 @@
    "allow_on_submit": 0, 
    "default": "Customer", 
    "fieldname": "party_type", 
-   "fieldtype": "Select", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Party Type", 
    "no_copy": 0, 
-   "options": "Customer\nSupplier", 
+   "options": "DocType", 
    "permlevel": 0, 
    "print_hide": 0, 
    "read_only": 0, 
@@ -44,53 +44,33 @@
   }, 
   {
    "allow_on_submit": 0, 
-   "depends_on": "eval:(doc.party_type == 'Customer')", 
-   "fieldname": "customer", 
-   "fieldtype": "Link", 
+   "depends_on": "", 
+   "fieldname": "party", 
+   "fieldtype": "Dynamic Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
-   "label": "Customer", 
+   "label": "Party", 
    "no_copy": 0, 
-   "options": "Customer", 
+   "options": "party_type", 
    "permlevel": 0, 
    "print_hide": 0, 
    "read_only": 0, 
    "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "depends_on": "eval:(doc.party_type == 'Supplier')", 
-   "fieldname": "supplier", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Supplier", 
-   "no_copy": 0, 
-   "options": "Supplier", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0
   }, 
   {
    "fieldname": "party_account", 
    "fieldtype": "Link", 
-   "hidden": 1, 
+   "hidden": 0, 
    "label": "Party Account", 
    "no_copy": 1, 
    "options": "Account", 
    "permlevel": 0, 
-   "read_only": 1
+   "read_only": 0
   }, 
   {
    "allow_on_submit": 0, 
@@ -330,7 +310,7 @@
  "is_submittable": 0, 
  "issingle": 1, 
  "istable": 0, 
- "modified": "2014-09-12 04:43:05.963218", 
+ "modified": "2014-09-15 16:01:04.820559", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Tool", 
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py
index d8d6df3..93844d3 100644
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.py
+++ b/erpnext/accounts/doctype/payment_tool/payment_tool.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _, scrub
+from frappe import _
 from frappe.utils import flt
 from frappe.model.document import Document
 import json
@@ -37,6 +37,8 @@
 			if v.payment_amount:
 				d1 = jv.append("entries")
 				d1.account = self.party_account
+				d1.party_type = self.party_type
+				d1.party = self.party
 				d1.balance = get_balance_on(self.party_account)
 				d1.set("debit" if self.received_or_paid=="Paid" else "credit", flt(v.payment_amount))
 				d1.set(invoice_voucher_type.get(v.against_voucher_type), v.against_voucher_no)
@@ -52,10 +54,6 @@
 		return jv.as_dict()
 
 @frappe.whitelist()
-def get_party_account(party_type, party_name):
-	return frappe.db.get_value("Account", {"master_type": party_type, "master_name": party_name})
-
-@frappe.whitelist()
 def get_outstanding_vouchers(args):
 	from erpnext.accounts.utils import get_outstanding_invoices
 
@@ -72,13 +70,14 @@
 		frappe.throw(_("Please enter the Against Vouchers manually"))
 
 	# Get all outstanding sales /purchase invoices
-	outstanding_invoices = get_outstanding_invoices(amount_query, args.get("party_account"))
+	outstanding_invoices = get_outstanding_invoices(amount_query, args.get("party_account"),
+		args.get("party_type"), args.get("party"))
 
 	# 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_name"))
+	orders_to_be_billed = get_orders_to_be_billed(args.get("party_type"), args.get("party"))
 	return outstanding_invoices + orders_to_be_billed
 
-def get_orders_to_be_billed(party_type, party_name):
+def get_orders_to_be_billed(party_type, party):
 	voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
 	orders = frappe.db.sql("""
 		select
@@ -93,8 +92,7 @@
 			and docstatus = 1
 			and ifnull(grand_total, 0) > ifnull(advance_paid, 0)
 			and ifnull(per_billed, 0) < 100.0
-		""" % (voucher_type, 'customer' if party_type == "Customer" else 'supplier', '%s'),
-		party_name, as_dict = True)
+		""" % (voucher_type, 'customer' if party_type == "Customer" else 'supplier', '%s'), party, as_dict = True)
 
 	order_list = []
 	for d in orders:
diff --git a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
index c91a5de..579dad3 100644
--- a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
+++ b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
@@ -22,18 +22,19 @@
 
 		self.clear_table_entries()
 
-		base_customer_jv = self.create_against_jv(jv_test_records[2], { "account": "_Test Customer 3 - _TC"})
-		base_supplier_jv = self.create_against_jv(jv_test_records[1], { "account": "_Test Supplier 1 - _TC"})
+		base_customer_jv = self.create_against_jv(jv_test_records[2], { "party": "_Test Customer 3"})
+		base_supplier_jv = self.create_against_jv(jv_test_records[1], { "party": "_Test Supplier 1"})
 
 
-		#Create SO with partial outstanding
+		# Create SO with partial outstanding
 		so1 = self.create_voucher(so_test_records[0], {
 			"customer": "_Test Customer 3"
 		})
 
-		jv_against_so1 = self.create_against_jv(jv_test_records[0], { 
-			"account": "_Test Customer 3 - _TC",
-			"against_sales_order": so1.name
+		self.create_against_jv(jv_test_records[0], {
+			"party": "_Test Customer 3",
+			"against_sales_order": so1.name,
+			"is_advance": "Yes"
 		})
 
 
@@ -42,11 +43,14 @@
 			"customer": "_Test Customer 3"
 		})
 
-		jv_against_so2 = self.create_against_jv(jv_test_records[0], { 
-			"account": "_Test Customer 3 - _TC",
+		self.create_against_jv(jv_test_records[0], {
+			"party": "_Test Customer 3",
 			"against_sales_order": so2.name,
-			"credit": 1000
+			"credit": 1000,
+			"is_advance": "Yes"
 		})
+
+		# Purchase order
 		po = self.create_voucher(po_test_records[1], {
 			"supplier": "_Test Supplier 1"
 		})
@@ -54,45 +58,45 @@
 		#Create SI with partial outstanding
 		si1 = self.create_voucher(si_test_records[0], {
 			"customer": "_Test Customer 3",
-			"debit_to": "_Test Customer 3 - _TC" 
+			"debit_to": "_Test Receivable - _TC"
 		})
-		
-		jv_against_si1 = self.create_against_jv(jv_test_records[0], { 
-			"account": "_Test Customer 3 - _TC",
+
+		self.create_against_jv(jv_test_records[0], {
+			"party": "_Test Customer 3",
 			"against_invoice": si1.name
 		})
 		#Create SI with no outstanding
 		si2 = self.create_voucher(si_test_records[0], {
 			"customer": "_Test Customer 3",
-			"debit_to": "_Test Customer 3 - _TC" 
+			"debit_to": "_Test Receivable - _TC"
 		})
-		
-		jv_against_si2 = self.create_against_jv(jv_test_records[0], { 
-			"account": "_Test Customer 3 - _TC",
+
+		self.create_against_jv(jv_test_records[0], {
+			"party": "_Test Customer 3",
 			"against_invoice": si2.name,
 			"credit": 561.80
 		})
 
 		pi = self.create_voucher(pi_test_records[0], {
 			"supplier": "_Test Supplier 1",
-			"credit_to": "_Test Supplier 1 - _TC" 
+			"credit_to": "_Test Payable - _TC"
 		})
 
 		#Create a dict containing properties and expected values
 		expected_outstanding = {
 			"Journal Voucher"	: [base_customer_jv.name, 400.00],
-			"Sales Invoice"				: [si1.name, 161.80],
-			"Purchase Invoice"			: [pi.name, 1512.30],
-			"Sales Order"				: [so1.name, 600.00],
-			"Purchase Order"			: [po.name, 5000.00]
+			"Sales Invoice"		: [si1.name, 161.80],
+			"Purchase Invoice"	: [pi.name, 1512.30],
+			"Sales Order"		: [so1.name, 600.00],
+			"Purchase Order"	: [po.name, 5000.00]
 		}
 
 		args = {
 			"company": "_Test Company",
 			"party_type": "Customer",
 			"received_or_paid": "Received",
-			"customer": "_Test Customer",
-			"party_account": "_Test Customer 3 - _TC",
+			"party": "_Test Customer 3",
+			"party_account": "_Test Receivable - _TC",
 			"payment_mode": "Cheque",
 			"payment_account": "_Test Account Bank Account - _TC",
 			"reference_no": "123456",
@@ -104,8 +108,8 @@
 		args.update({
 			"party_type": "Supplier",
 			"received_or_paid": "Paid",
-			"supplier": "_Test Supplier 1",
-			"party_account": "_Test Supplier 1 - _TC"
+			"party": "_Test Supplier 1",
+			"party_account": "_Test Payable - _TC"
 		})
 		expected_outstanding["Journal Voucher"] = [base_supplier_jv.name, 400.00]
 		self.make_voucher_for_party(args, expected_outstanding)
@@ -137,11 +141,10 @@
 			payment_tool_doc.set(k, v)
 
 		self.check_outstanding_vouchers(payment_tool_doc, args, expected_outstanding)
-		
+
 
 	def check_outstanding_vouchers(self, doc, args, expected_outstanding):
 		from erpnext.accounts.doctype.payment_tool.payment_tool import get_outstanding_vouchers
-
 		outstanding_entries = get_outstanding_vouchers(json.dumps(args))
 
 		for d in outstanding_entries:
@@ -161,20 +164,21 @@
 
 		new_jv = paytool.make_journal_voucher()
 
-		#Create a list of expected values as [party account, payment against, against_jv, against_invoice, 
+		#Create a list of expected values as [party account, payment against, against_jv, against_invoice,
 		#against_voucher, against_sales_order, against_purchase_order]
 		expected_values = [
-			[paytool.party_account, 100.00, expected_outstanding.get("Journal Voucher")[0], None, None, None, None],
-			[paytool.party_account, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None],
-			[paytool.party_account, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None],
-			[paytool.party_account, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None],
-			[paytool.party_account, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
+			[paytool.party_account, paytool.party, 100.00, expected_outstanding.get("Journal Voucher")[0], None, None, None, None],
+			[paytool.party_account, paytool.party, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None],
+			[paytool.party_account, paytool.party, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None],
+			[paytool.party_account, paytool.party, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None],
+			[paytool.party_account, paytool.party, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
 		]
 
-		for jv_entry in new_jv.get("entries"): 
-			if paytool.party_account == jv_entry.get("account"):
+		for jv_entry in new_jv.get("entries"):
+			if paytool.party_account == jv_entry.get("account") and paytool.party == jv_entry.get("party"):
 				row = [
 					jv_entry.get("account"),
+					jv_entry.get("party"),
 					jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"),
 					jv_entry.get("against_jv"),
 					jv_entry.get("against_invoice"),
@@ -183,11 +187,11 @@
 					jv_entry.get("against_purchase_order"),
 				]
 				self.assertTrue(row in expected_values)
-			
+
 		self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
 		self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)
 
 	def clear_table_entries(self):
-		frappe.db.sql("""delete from `tabGL Entry` where (account = "_Test Customer 3 - _TC" or account = "_Test Supplier 1 - _TC")""")
-		frappe.db.sql("""delete from `tabSales Order` where customer_name = "_Test Customer 3" """)
-		frappe.db.sql("""delete from `tabPurchase Order` where supplier_name = "_Test Supplier 1" """)	
+		frappe.db.sql("""delete from `tabGL Entry` where party in ("_Test Customer 3", "_Test Supplier 1")""")
+		frappe.db.sql("""delete from `tabSales Order` where customer = "_Test Customer 3" """)
+		frappe.db.sql("""delete from `tabPurchase Order` where supplier = "_Test Supplier 1" """)