From f13c4f0145a0a66680398957c6439f6ca2214ba7 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Tue, 9 Dec 2014 12:36:50 +0530 Subject: [PATCH] New feature for issue #2419 --- .../journal_voucher/journal_voucher.py | 21 +- .../journal_voucher_detail.json | 10 +- .../hr/doctype/expense_claim/expense_claim.js | 5 +- .../doctype/expense_claim/expense_claim.json | 428 +++++++++--------- .../expense_claim/expense_claim_list.html | 7 +- .../expense_claim/expense_claim_list.js | 3 +- 6 files changed, 260 insertions(+), 214 deletions(-) diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py index 0c9e800828..e6d7407073 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cstr, flt, fmt_money, formatdate, getdate +from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, cint from frappe import msgprint, _, scrub from erpnext.setup.utils import get_company_currency from erpnext.controllers.accounts_controller import AccountsController @@ -37,11 +37,13 @@ class JournalVoucher(AccountsController): self.validate_against_sales_order() self.validate_against_purchase_order() self.check_credit_days() + self.validate_expense_claim() def on_submit(self): self.check_credit_limit() self.make_gl_entries() self.update_advance_paid() + self.update_expense_claim() def update_advance_paid(self): advance_paid = frappe._dict() @@ -62,6 +64,7 @@ class JournalVoucher(AccountsController): self.make_gl_entries(1) self.update_advance_paid() + self.update_expense_claim() def validate_party(self): for d in self.get("entries"): @@ -420,6 +423,22 @@ class JournalVoucher(AccountsController): return frappe.db.sql("""select name, credit_to as account, supplier as party, outstanding_amount from `tabPurchase Invoice` where docstatus = 1 and company = %s and outstanding_amount > 0 %s""" % ('%s', cond), self.company, as_dict=True) + + def update_expense_claim(self): + for d in self.entries: + if d.against_expense_claim: + amt = frappe.db.sql("""select sum(debit) as amt from `tabJournal Voucher Detail` + where against_expense_claim = %s and docstatus = 1""", d.against_expense_claim ,as_dict=1)[0].amt + frappe.db.sql("update `tabExpense Claim` set total_amount_reimbursed = %s where name = %s",(amt, d.against_expense_claim)) + + def validate_expense_claim(self): + for d in self.entries: + if d.against_expense_claim: + sanctioned_amount = cint(frappe.db.get_value("Expense Claim", d.against_expense_claim, "total_sanctioned_amount")) + reimbursed_amount = cint(frappe.db.get_value("Expense Claim", d.against_expense_claim, "total_amount_reimbursed")) + pending_amount = sanctioned_amount - reimbursed_amount + if d.debit > pending_amount: + frappe.throw("Amount cannot be greater than Expense Claim") @frappe.whitelist() def get_default_bank_cash_account(company, voucher_type): diff --git a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json index 9834c2e1be..f896b6d133 100644 --- a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json +++ b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json @@ -173,6 +173,14 @@ "options": "Purchase Order", "permlevel": 0 }, + { + "fieldname": "against_expense_claim", + "fieldtype": "Link", + "label": "Against Expense Claim", + "options": "Expense Claim", + "permlevel": 0, + "precision": "" + }, { "fieldname": "is_advance", "fieldtype": "Select", @@ -198,7 +206,7 @@ ], "idx": 1, "istable": 1, - "modified": "2014-09-17 13:02:42.012069", + "modified": "2014-12-08 19:32:47.996777", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Voucher Detail", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index e070b3f13d..79d7aac81f 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -89,7 +89,7 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn){ if(doc.docstatus==0 && doc.exp_approver==user && doc.approval_status=="Approved") cur_frm.savesubmit(); - if(doc.docstatus==1 && frappe.model.can_create("Journal Voucher")) + if(doc.docstatus==1 && frappe.model.can_create("Journal Voucher") && doc.total_amount_reimbursed < doc.total_sanctioned_amount) cur_frm.add_custom_button(__("Make Bank Voucher"), cur_frm.cscript.make_bank_voucher, frappe.boot.doctype_icons["Journal Voucher"]); } @@ -109,6 +109,9 @@ cur_frm.cscript.set_help = function(doc) { } else { if(doc.approval_status=="Approved") { cur_frm.set_intro(__("Expense Claim has been approved.")); + if(doc.total_amount_reimbursed== doc.total_sanctioned_amount){ + cur_frm.set_intro(__("Expense Claim has been reimbursed.")); + } } else if(doc.approval_status=="Rejected") { cur_frm.set_intro(__("Expense Claim has been rejected.")); } diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index a38d8a307b..cbbe102976 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -1,257 +1,267 @@ { - "autoname": "naming_series:", - "creation": "2013-01-10 16:34:14", - "docstatus": 0, - "doctype": "DocType", + "autoname": "naming_series:", + "creation": "2013-01-10 16:34:14", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "default": "EXP", - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Series", - "no_copy": 1, - "options": "EXP", - "permlevel": 0, - "precision": "", - "print_hide": 1, + "default": "EXP", + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Series", + "no_copy": 1, + "options": "EXP", + "permlevel": 0, + "precision": "", + "print_hide": 1, "reqd": 1 - }, + }, { - "default": "Draft", - "depends_on": "eval:!doc.__islocal", - "fieldname": "approval_status", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Approval Status", - "no_copy": 1, - "oldfieldname": "approval_status", - "oldfieldtype": "Select", - "options": "Draft\nApproved\nRejected", - "permlevel": 0, + "default": "Draft", + "depends_on": "eval:!doc.__islocal", + "fieldname": "approval_status", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Approval Status", + "no_copy": 1, + "oldfieldname": "approval_status", + "oldfieldtype": "Select", + "options": "Draft\nApproved\nRejected", + "permlevel": 0, "search_index": 1 - }, + }, { - "description": "A user with \"Expense Approver\" role", - "fieldname": "exp_approver", - "fieldtype": "Link", - "label": "Approver", - "oldfieldname": "exp_approver", - "oldfieldtype": "Select", - "options": "User", - "permlevel": 0, + "description": "A user with \"Expense Approver\" role", + "fieldname": "exp_approver", + "fieldtype": "Link", + "label": "Approver", + "oldfieldname": "exp_approver", + "oldfieldtype": "Select", + "options": "User", + "permlevel": 0, "width": "160px" - }, + }, { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break0", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "total_claimed_amount", - "fieldtype": "Currency", - "in_filter": 0, - "in_list_view": 1, - "label": "Total Claimed Amount", - "no_copy": 1, - "oldfieldname": "total_claimed_amount", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "read_only": 1, - "reqd": 0, + "fieldname": "total_claimed_amount", + "fieldtype": "Currency", + "in_filter": 0, + "in_list_view": 1, + "label": "Total Claimed Amount", + "no_copy": 1, + "oldfieldname": "total_claimed_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1, + "reqd": 0, "width": "160px" - }, + }, { - "fieldname": "total_sanctioned_amount", - "fieldtype": "Currency", - "in_filter": 0, - "in_list_view": 1, - "label": "Total Sanctioned Amount", - "no_copy": 1, - "oldfieldname": "total_sanctioned_amount", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "read_only": 1, + "fieldname": "total_sanctioned_amount", + "fieldtype": "Currency", + "in_filter": 0, + "in_list_view": 1, + "label": "Total Sanctioned Amount", + "no_copy": 1, + "oldfieldname": "total_sanctioned_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1, "width": "160px" - }, + }, { - "fieldname": "expense_details", - "fieldtype": "Section Break", - "label": "Expense Details", - "oldfieldtype": "Section Break", + "fieldname": "expense_details", + "fieldtype": "Section Break", + "label": "Expense Details", + "oldfieldtype": "Section Break", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "expense_voucher_details", - "fieldtype": "Table", - "label": "Expense Claim Details", - "oldfieldname": "expense_voucher_details", - "oldfieldtype": "Table", - "options": "Expense Claim Detail", + "allow_on_submit": 0, + "fieldname": "expense_voucher_details", + "fieldtype": "Table", + "label": "Expense Claim Details", + "oldfieldname": "expense_voucher_details", + "oldfieldtype": "Table", + "options": "Expense Claim Detail", "permlevel": 0 - }, + }, { - "fieldname": "sb1", - "fieldtype": "Section Break", - "options": "Simple", + "fieldname": "sb1", + "fieldtype": "Section Break", + "options": "Simple", "permlevel": 0 - }, + }, { - "fieldname": "posting_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Posting Date", - "oldfieldname": "posting_date", - "oldfieldtype": "Date", - "permlevel": 0, + "fieldname": "posting_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Posting Date", + "oldfieldname": "posting_date", + "oldfieldtype": "Date", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "employee", - "fieldtype": "Link", - "in_filter": 1, - "label": "From Employee", - "oldfieldname": "employee", - "oldfieldtype": "Link", - "options": "Employee", - "permlevel": 0, - "reqd": 1, + "fieldname": "employee", + "fieldtype": "Link", + "in_filter": 1, + "label": "From Employee", + "oldfieldname": "employee", + "oldfieldtype": "Link", + "options": "Employee", + "permlevel": 0, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "employee_name", - "fieldtype": "Data", - "in_filter": 1, - "in_list_view": 1, - "label": "Employee Name", - "oldfieldname": "employee_name", - "oldfieldtype": "Data", - "permlevel": 0, - "read_only": 1, - "search_index": 0, + "fieldname": "employee_name", + "fieldtype": "Data", + "in_filter": 1, + "in_list_view": 1, + "label": "Employee Name", + "oldfieldname": "employee_name", + "oldfieldtype": "Data", + "permlevel": 0, + "read_only": 1, + "search_index": 0, "width": "150px" - }, + }, { - "fieldname": "company", - "fieldtype": "Link", - "in_filter": 1, - "label": "Company", - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, + "fieldname": "company", + "fieldtype": "Link", + "in_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "fiscal_year", - "fieldtype": "Link", - "in_filter": 1, - "label": "Fiscal Year", - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "Fiscal Year", - "permlevel": 0, + "fieldname": "fiscal_year", + "fieldtype": "Link", + "in_filter": 1, + "label": "Fiscal Year", + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "Fiscal Year", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "cb1", - "fieldtype": "Column Break", + "fieldname": "cb1", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "remark", - "fieldtype": "Small Text", - "label": "Remark", - "no_copy": 1, - "oldfieldname": "remark", - "oldfieldtype": "Small Text", + "fieldname": "total_amount_reimbursed", + "fieldtype": "Currency", + "label": "Total Amount Reimbursed", + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "read_only": 1 + }, + { + "allow_on_submit": 0, + "fieldname": "remark", + "fieldtype": "Small Text", + "label": "Remark", + "no_copy": 1, + "oldfieldname": "remark", + "oldfieldtype": "Small Text", "permlevel": 0 - }, + }, { - "fieldname": "email_id", - "fieldtype": "Data", - "hidden": 1, - "label": "Employees Email Id", - "oldfieldname": "email_id", - "oldfieldtype": "Data", - "permlevel": 0, + "fieldname": "email_id", + "fieldtype": "Data", + "hidden": 1, + "label": "Employees Email Id", + "oldfieldname": "email_id", + "oldfieldtype": "Data", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "amended_from", - "fieldtype": "Link", - "ignore_user_permissions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Data", - "options": "Expense Claim", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "report_hide": 1, + "fieldname": "amended_from", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Data", + "options": "Expense Claim", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "report_hide": 1, "width": "160px" } - ], - "icon": "icon-money", - "idx": 1, - "is_submittable": 1, - "modified": "2014-11-24 18:25:53.038826", - "modified_by": "Administrator", - "module": "HR", - "name": "Expense Claim", - "owner": "harshada@webnotestech.com", + ], + "icon": "icon-money", + "idx": 1, + "is_submittable": 1, + "modified": "2014-12-09 11:52:32.196383", + "modified_by": "Administrator", + "module": "HR", + "name": "Expense Claim", + "owner": "harshada@webnotestech.com", "permissions": [ { - "apply_user_permissions": 1, - "create": 1, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Employee", + "apply_user_permissions": 1, + "create": 1, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", "write": 1 - }, + }, { - "amend": 1, - "apply_user_permissions": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Expense Approver", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Expense Approver", + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "apply_user_permissions": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "submit": 1, "write": 1 } - ], - "search_fields": "approval_status,employee,employee_name", - "sort_field": "modified", + ], + "search_fields": "approval_status,employee,employee_name", + "sort_field": "modified", "sort_order": "DESC" -} +} \ No newline at end of file diff --git a/erpnext/hr/doctype/expense_claim/expense_claim_list.html b/erpnext/hr/doctype/expense_claim/expense_claim_list.html index dd3c78fc66..944d34c452 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim_list.html +++ b/erpnext/hr/doctype/expense_claim/expense_claim_list.html @@ -13,7 +13,12 @@ data-filter="status,=,{%= doc.approval_status %}"> {%= doc.approval_status %} - + + {% if(doc.total_amount_reimbursed== doc.total_sanctioned_amount && doc.docstatus== 1) { %} + + "Reimbursed" + + {% } %} diff --git a/erpnext/hr/doctype/expense_claim/expense_claim_list.js b/erpnext/hr/doctype/expense_claim/expense_claim_list.js index 34ee5c14fb..818296de8c 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim_list.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim_list.js @@ -1,4 +1,5 @@ frappe.listview_settings['Expense Claim'] = { - add_fields: ["approval_status", "employee", "employee_name", "total_claimed_amount"], + add_fields: ["approval_status", "employee", "employee_name", + "total_claimed_amount", "total_amount_reimbursed", "total_sanctioned_amount", "docstatus"], filters:[["approval_status","!=", "Rejected"]] };