From 9641d5b1f499bd8bab43b998259ef15d2f58dac0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 1 Aug 2017 17:33:08 +0530 Subject: [PATCH] Make payment entry button in expense claim and some minor cleanup --- .../doctype/payment_entry/payment_entry.js | 10 +- erpnext/demo/user/hr.py | 2 +- .../hr/doctype/expense_claim/expense_claim.js | 165 +++++++++--------- .../hr/doctype/expense_claim/expense_claim.py | 10 +- .../expense_claim/test_expense_claim.py | 2 +- 5 files changed, 100 insertions(+), 89 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index fbbfd28d9a..05986a0808 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -71,7 +71,7 @@ frappe.ui.form.on('Payment Entry', { } else if (frm.doc.party_type=="Supplier") { var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; } else if (frm.doc.party_type=="Employee") { - var doctypes = ["Expense Claim"]; + var doctypes = ["Expense Claim", "Journal Entry"]; } else { var doctypes = ["Journal Entry"]; } @@ -84,12 +84,18 @@ frappe.ui.form.on('Payment Entry', { frm.set_query("reference_name", "references", function(doc, cdt, cdn) { child = locals[cdt][cdn]; filters = {"docstatus": 1, "company": doc.company}; - party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice', 'Purchase Order', 'Expense Claim']; + party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice', + 'Purchase Order', 'Expense Claim']; if (in_list(party_type_doctypes, child.reference_doctype)) { filters[doc.party_type.toLowerCase()] = doc.party; } + if(child.reference_doctype == "Expense Claim") { + filters["status"] = "Approved"; + filters["is_paid"] = 0; + } + return { filters: filters }; diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index 0b644c42d3..1570df5963 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -67,7 +67,7 @@ def work(): if random.randint(0, 1): #make journal entry against expense claim - je = frappe.get_doc(make_bank_entry(expense_claim.name)) + je = frappe.get_doc(make_bank_entry("Expense Claim", expense_claim.name)) je.posting_date = frappe.flags.current_date je.cheque_no = random_string(10) je.cheque_date = frappe.flags.current_date diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index b1c43d771b..0bd89112a6 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -4,26 +4,12 @@ frappe.provide("erpnext.hr"); erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ - make_bank_entry: function() { - var me = this; - return frappe.call({ - method: "erpnext.hr.doctype.expense_claim.expense_claim.make_bank_entry", - args: { - "docname": cur_frm.doc.name, - }, - callback: function(r) { - var doc = frappe.model.sync(r.message); - frappe.set_route('Form', 'Journal Entry', r.message.name); - } - }); - }, - expense_type: function(doc, cdt, cdn) { var d = locals[cdt][cdn]; if(!doc.company) { d.expense_type = ""; frappe.msgprint(__("Please set the Company")); - this.frm.refresh_fields() + this.frm.refresh_fields(); return; } @@ -44,16 +30,16 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ } }); } -}) +}); $.extend(cur_frm.cscript, new erpnext.hr.ExpenseClaimController({frm: cur_frm})); cur_frm.add_fetch('employee', 'company', 'company'); cur_frm.add_fetch('employee','employee_name','employee_name'); -cur_frm.cscript.onload = function(doc,cdt,cdn) { +cur_frm.cscript.onload = function(doc) { if(!doc.approval_status) - cur_frm.set_value("approval_status", "Draft") + cur_frm.set_value("approval_status", "Draft"); if (doc.__islocal) { cur_frm.set_value("posting_date", frappe.datetime.get_today()); @@ -62,10 +48,10 @@ cur_frm.cscript.onload = function(doc,cdt,cdn) { cur_frm.cscript.clear_sanctioned(doc); } - cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) { - return{ + cur_frm.fields_dict.employee.get_query = function() { + return { query: "erpnext.controllers.queries.employee_query" - } + }; }; cur_frm.set_query("exp_approver", function() { @@ -73,7 +59,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn) { query: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_approver" }; }); -} +}; cur_frm.cscript.clear_sanctioned = function(doc) { var val = doc.expenses || []; @@ -83,9 +69,9 @@ cur_frm.cscript.clear_sanctioned = function(doc) { doc.total_sanctioned_amount = ''; refresh_many(['sanctioned_amount', 'total_sanctioned_amount']); -} +}; -cur_frm.cscript.refresh = function(doc,cdt,cdn) { +cur_frm.cscript.refresh = function(doc) { cur_frm.cscript.set_help(doc); if(!doc.__islocal) { @@ -96,11 +82,6 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn) { cur_frm.savesubmit(); if (doc.docstatus===1 && doc.approval_status=="Approved") { - if (cint(doc.total_amount_reimbursed) < cint(doc.total_sanctioned_amount) && frappe.model.can_create("Journal Entry")) { - cur_frm.add_custom_button(__("Bank Entry"), cur_frm.cscript.make_bank_entry, __("Make")); - cur_frm.page.set_inner_btn_group_as_primary(__("Make")); - } - /* eslint-disable */ // no idea how `me` works here if (cint(doc.total_amount_reimbursed) > 0 && frappe.model.can_read("Journal Entry")) { @@ -116,12 +97,12 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn) { /* eslint-enable */ } } -} +}; cur_frm.cscript.set_help = function(doc) { cur_frm.set_intro(""); if(doc.__islocal && !in_list(frappe.user_roles, "HR User")) { - cur_frm.set_intro(__("Fill the form and save it")) + cur_frm.set_intro(__("Fill the form and save it")); } else { if(doc.docstatus==0 && doc.approval_status=="Draft") { if(frappe.session.user==doc.exp_approver) { @@ -131,13 +112,13 @@ cur_frm.cscript.set_help = function(doc) { } } } -} +}; cur_frm.cscript.validate = function(doc) { cur_frm.cscript.calculate_total(doc); -} +}; -cur_frm.cscript.calculate_total = function(doc,cdt,cdn){ +cur_frm.cscript.calculate_total = function(doc){ doc.total_claimed_amount = 0; doc.total_sanctioned_amount = 0; $.each((doc.expenses || []), function(i, d) { @@ -147,18 +128,17 @@ cur_frm.cscript.calculate_total = function(doc,cdt,cdn){ refresh_field("total_claimed_amount"); refresh_field('total_sanctioned_amount'); - -} +}; cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){ cur_frm.cscript.calculate_total(doc,cdt,cdn); -} +}; -cur_frm.cscript.on_submit = function(doc, cdt, cdn) { +cur_frm.cscript.on_submit = function() { if(cint(frappe.boot.notification_settings && frappe.boot.notification_settings.expense_claim)) { cur_frm.email_doc(frappe.boot.notification_settings.expense_claim_message); } -} +}; erpnext.expense_claim = { set_title :function(frm) { @@ -169,11 +149,20 @@ erpnext.expense_claim = { frm.set_value("title", frm.doc.employee_name + " for "+ frm.doc.task); } } -} +}; frappe.ui.form.on("Expense Claim", { + setup: function(frm) { + frm.trigger("set_query_for_cost_center"); + frm.trigger("set_query_for_payable_account"); + frm.add_fetch("company", "cost_center", "cost_center"); + frm.add_fetch("company", "default_payable_account", "payable_account"); + }, + refresh: function(frm) { - if(frm.doc.docstatus == 1) { + frm.trigger("toggle_fields"); + + if(frm.doc.docstatus == 1 && frm.doc.approval_status == 'Approved') { frm.add_custom_button(__('Accounting Ledger'), function() { frappe.route_options = { voucher_no: frm.doc.name, @@ -183,47 +172,41 @@ frappe.ui.form.on("Expense Claim", { frappe.set_route("query-report", "General Ledger"); }, __("View")); } - } -}) -frappe.ui.form.on("Expense Claim Detail", { - claim_amount: function(frm, cdt, cdn) { - var child = locals[cdt][cdn]; - var doc = frm.doc; - - if(!child.sanctioned_amount){ - frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount) + if (frm.doc.docstatus===1 && frm.doc.approval_status=="Approved" + && (cint(frm.doc.total_amount_reimbursed) < cint(frm.doc.total_sanctioned_amount)) + && frappe.model.can_create("Payment Entry")) { + frm.add_custom_button(__('Payment'), + function() { frm.events.make_payment_entry(frm); }, __("Make")); } - - cur_frm.cscript.calculate_total(doc,cdt,cdn); }, - sanctioned_amount: function(frm, cdt, cdn) { - var doc = frm.doc; - cur_frm.cscript.calculate_total(doc,cdt,cdn); - } -}) - -frappe.ui.form.on("Expense Claim",{ - setup: function(frm) { - frm.trigger("set_query_for_cost_center") - frm.trigger("set_query_for_payable_account") - frm.add_fetch("company", "cost_center", "cost_center"); - frm.add_fetch("company", "default_payable_account", "payable_account"); + make_payment_entry: function(frm) { + var method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry"; + if(frm.doc.__onload && frm.doc.__onload.make_payment_via_journal_entry) { + method = "erpnext.hr.doctype.expense_claim.expense_claim.make_bank_entry" + } + return frappe.call({ + method: method, + args: { + "dt": frm.doc.doctype, + "dn": frm.doc.name + }, + callback: function(r) { + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }); }, - - refresh: function(frm) { - frm.trigger("toggle_fields") - }, - + set_query_for_cost_center: function(frm) { frm.fields_dict["cost_center"].get_query = function() { return { filters: { "company": frm.doc.company } - } - } + }; + }; }, set_query_for_payable_account: function(frm) { @@ -233,25 +216,43 @@ frappe.ui.form.on("Expense Claim",{ "report_type": "Balance Sheet", "account_type": "Payable" } - } - } + }; + }; }, is_paid: function(frm) { - frm.trigger("toggle_fields") + frm.trigger("toggle_fields"); }, toggle_fields: function(frm) { - frm.toggle_reqd("mode_of_payment", frm.doc.is_paid) + frm.toggle_reqd("mode_of_payment", frm.doc.is_paid); + }, + + employee_name: function(frm) { + erpnext.expense_claim.set_title(frm); + }, + + task: function(frm) { + erpnext.expense_claim.set_title(frm); } }); -frappe.ui.form.on("Expense Claim", "employee_name", function(frm) { - erpnext.expense_claim.set_title(frm); -}); +frappe.ui.form.on("Expense Claim Detail", { + claim_amount: function(frm, cdt, cdn) { + var child = locals[cdt][cdn]; + var doc = frm.doc; -frappe.ui.form.on("Expense Claim", "task", function(frm) { - erpnext.expense_claim.set_title(frm); + if(!child.sanctioned_amount){ + frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount); + } + + cur_frm.cscript.calculate_total(doc,cdt,cdn); + }, + + sanctioned_amount: function(frm, cdt, cdn) { + var doc = frm.doc; + cur_frm.cscript.calculate_total(doc,cdt,cdn); + } }); cur_frm.fields_dict['task'].get_query = function(doc) { @@ -259,5 +260,5 @@ cur_frm.fields_dict['task'].get_query = function(doc) { filters:{ 'project': doc.project } - } -} + }; +}; diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index 2781f28213..507d6a9752 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -16,6 +16,10 @@ from frappe.utils.csvutils import getlink class InvalidExpenseApproverError(frappe.ValidationError): pass class ExpenseClaim(AccountsController): + def onload(self): + self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings', + 'make_payment_via_journal_entry') + def get_feed(self): return _("{0}: From {0} for {1}").format(self.approval_status, self.employee_name, self.total_claimed_amount) @@ -207,10 +211,10 @@ def get_expense_approver(doctype, txt, searchfield, start, page_len, filters): """, ("%" + txt + "%")) @frappe.whitelist() -def make_bank_entry(docname): +def make_bank_entry(dt, dn): from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account - expense_claim = frappe.get_doc("Expense Claim", docname) + expense_claim = frappe.get_doc(dt, dn) default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Bank") if not default_bank_cash_account: default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Cash") @@ -218,7 +222,7 @@ def make_bank_entry(docname): je = frappe.new_doc("Journal Entry") je.voucher_type = 'Bank Entry' je.company = expense_claim.company - je.remark = 'Payment against Expense Claim: ' + docname; + je.remark = 'Payment against Expense Claim: ' + dn; je.append("accounts", { "account": expense_claim.payable_account, diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index bcde2c010c..b813537441 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -45,7 +45,7 @@ class TestExpenseClaim(unittest.TestCase): payable_account = get_payable_account("Wind Power LLC") expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP") - je_dict = make_bank_entry(expense_claim.name) + je_dict = make_bank_entry("Expense Claim", expense_claim.name) je = frappe.get_doc(je_dict) je.posting_date = nowdate() je.cheque_no = random_string(5)