diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js index 3e0d2eec9f..bbdd7d2389 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.js +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.js @@ -8,13 +8,19 @@ frappe.ui.form.on("Payment Tool", "onload", function(frm) { frm.set_value("make_jv_help", ' ' + __("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.on("Payment Tool", "refresh", function(frm) { 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 @@ frappe.ui.form.on("Payment Tool", "received_or_paid", function(frm) { // 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 @@ frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) { "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 @@ frappe.ui.form.on("Payment Tool", "make_journal_voucher", function(frm) { }); 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 b2949a99a9..883043be64 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 d8d6df3da2..93844d3234 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 @@ class PaymentTool(Document): 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) @@ -51,10 +53,6 @@ class PaymentTool(Document): 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 @@ def get_outstanding_vouchers(args): 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 @@ def get_orders_to_be_billed(party_type, party_name): 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 c91a5de2e1..579dad3f82 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 @@ class TestPaymentTool(unittest.TestCase): 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 @@ class TestPaymentTool(unittest.TestCase): "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 @@ class TestPaymentTool(unittest.TestCase): #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 @@ class TestPaymentTool(unittest.TestCase): 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 @@ class TestPaymentTool(unittest.TestCase): 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 @@ class TestPaymentTool(unittest.TestCase): 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 @@ class TestPaymentTool(unittest.TestCase): 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" """)