diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.js b/erpnext/hr/doctype/payroll_entry/payroll_entry.js index a26283d9a6..3f00166249 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.js @@ -10,24 +10,73 @@ frappe.ui.form.on('Payroll Entry', { }, refresh: function(frm) { - if (frm.doc.docstatus==1) { - if(frm.doc.payment_account) { - frm.add_custom_button("Make Bank Entry", function() { - make_bank_entry(frm); - }); - } - - frm.add_custom_button("Submit Salary Slip", function() { - submit_salary_slip(frm); - }); - - frm.add_custom_button("View Salary Slip", function() { - frappe.set_route('List', 'Salary Slip', - {posting_date: frm.doc.posting_date}); - }); + if (frm.doc.docstatus == 1) { + if (frm.custom_buttons) frm.clear_custom_buttons(); + frm.events.add_context_buttons(frm); } }, + add_context_buttons: function(frm) { + frappe.call({ + method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.payroll_entry_has_created_slips', + args: { + 'name': frm.doc.name + }, + callback: function(r) { + if(r.message) { + frm.events.add_salary_slip_buttons(frm, r.message); + if(r.message.submitted){ + frm.events.add_bank_entry_button(frm); + } + } + } + }); + }, + + add_salary_slip_buttons: function(frm, slip_status) { + if (!slip_status.draft && !slip_status.submitted) { + return; + } else { + frm.add_custom_button("View Salary Slips", + function() { + frappe.set_route( + 'List', 'Salary Slip', {posting_date: frm.doc.posting_date} + ); + } + ); + } + + if (slip_status.draft) { + frm.add_custom_button("Submit Salary Slip", + function() { + submit_salary_slip(frm); + }, + __('Make') + ); + frm.page.set_inner_btn_group_as_primary(__('Make')); + } + }, + + add_bank_entry_button: function(frm) { + frappe.call({ + method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.payroll_entry_has_bank_entries', + args: { + 'name': frm.doc.name + }, + callback: function(r) { + if (r.message && !r.message.submitted) { + frm.add_custom_button("Bank Entry", + function() { + make_bank_entry(frm); + }, + __('Make') + ); + frm.page.set_inner_btn_group_as_primary(__('Make')); + } + } + }); + }, + setup: function (frm) { frm.set_query("payment_account", function () { var account_types = ["Bank", "Cash"]; @@ -132,9 +181,25 @@ frappe.ui.form.on('Payroll Entry', { // Submit salary slips -let submit_salary_slip = function (frm) { - var doc = frm.doc; - return $c('runserverobj', { 'method': 'submit_salary_slips', 'docs': doc }); +const submit_salary_slip = function (frm) { + frappe.confirm(__('This will create a Journal Entry. Do you want to proceed?'), + function() { + frappe.call({ + method: 'submit_salary_slips', + args: {}, + callback: function() {frm.events.refresh(frm);}, + doc: frm.doc, + freeze: true, + freeze_message: 'Creating Journal Entries...' + }); + }, + function() { + if(frappe.dom.freeze_count) { + frappe.dom.unfreeze(); + frm.events.refresh(frm); + } + } + ); }; cur_frm.cscript.get_employee_details = function (doc) { diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py index 2f5fae4a9b..0b4e3bf0c7 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py @@ -461,4 +461,54 @@ def create_submit_log(submitted_ss, not_submitted_ss, jv_name): frappe.msgprint("Could not submit any Salary Slip
\ Possible reasons:
\ 1. Net pay is less than 0.
\ - 2. Company Email Address specified in employee master is not valid.
") \ No newline at end of file + 2. Company Email Address specified in employee master is not valid.
") + + +def get_salary_slip_list(name, docstatus, as_dict=0): + payroll_entry = frappe.get_doc('Payroll Entry', name) + + salary_slip_list = frappe.db.sql( + "select t1.name, t1.salary_structure from `tabSalary Slip` t1 " + "where t1.docstatus = %s " + "and t1.start_date >= %s " + "and t1.end_date <= %s", + (docstatus, payroll_entry.start_date, payroll_entry.end_date), + as_dict=as_dict + ) + + return salary_slip_list + + +@frappe.whitelist() +def payroll_entry_has_created_slips(name): + response = {} + + draft_salary_slips = get_salary_slip_list(name, docstatus=0) + submitted_salary_slips = get_salary_slip_list(name, docstatus=1) + + response['draft'] = 1 if draft_salary_slips else 0 + response['submitted'] = 1 if submitted_salary_slips else 0 + + return response + + +def get_payroll_entry_bank_entries(payroll_entry_name): + journal_entries = frappe.db.sql( + 'select name from `tabJournal Entry Account` ' + 'where reference_type="Payroll Entry" ' + 'and reference_name=%s and docstatus=1', + payroll_entry_name, + as_dict=1 + ) + + return journal_entries + + +@frappe.whitelist() +def payroll_entry_has_bank_entries(name): + response = {} + + bank_entries = get_payroll_entry_bank_entries(name) + response['submitted'] = 1 if bank_entries else 0 + + return response diff --git a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.js b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.js index c109aab377..05cd66f7df 100644 --- a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.js +++ b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.js @@ -38,8 +38,9 @@ QUnit.test("test: Payroll Entry", function (assert) { () => frappe.set_route('Form', 'Payroll Entry', docname), () => frappe.timeout(2), - () => frappe.click_button('Submit Salary Slip'), - () => frappe.timeout(3), + () => frappe.click_button('Make'), + () => frappe.click_dropdown_item('Submit Salary Slip'), + () => frappe.timeout(5), () => frappe.click_button('Close'), () => frappe.timeout(1),