From 30f37b2eb1026ea1a79c9dc6c4529d160f756531 Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Wed, 13 Jun 2018 15:29:38 +0530 Subject: [PATCH] Payroll Entry - Separate JE for flexi salary component (#14502) * Payroll Entry - Accrual entry - exclude only tax impact - and separate JE for Flexi in Bank Entry * Journal Entry - validate cheque info on submit * Payroll Entry - Make Bamk Entry - Separate JE for benefit component --- .../doctype/journal_entry/journal_entry.py | 4 +- .../hr/doctype/payroll_entry/payroll_entry.js | 11 +-- .../hr/doctype/payroll_entry/payroll_entry.py | 87 +++++++++++-------- 3 files changed, 55 insertions(+), 47 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 01ac14c9af5..2e787d1fe0b 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -26,7 +26,6 @@ class JournalEntry(AccountsController): self.clearance_date = None self.validate_party() - self.validate_cheque_info() self.validate_entries_for_advance() self.validate_multi_currency() self.set_amounts_in_company_currency() @@ -45,6 +44,7 @@ class JournalEntry(AccountsController): self.title = self.get_title() def on_submit(self): + self.validate_cheque_info() self.check_credit_limit() self.make_gl_entries() self.update_advance_paid() @@ -949,4 +949,4 @@ def make_inter_company_journal_entry(name, voucher_type, company): journal_entry.company = company journal_entry.posting_date = nowdate() journal_entry.inter_company_journal_entry_reference = name - return journal_entry.as_dict() \ No newline at end of file + return journal_entry.as_dict() diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.js b/erpnext/hr/doctype/payroll_entry/payroll_entry.js index d02e1f1dc3f..297c3d084ac 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.js @@ -221,17 +221,14 @@ cur_frm.cscript.get_employee_details = function (doc) { let make_bank_entry = function (frm) { var doc = frm.doc; - if (doc.company && doc.start_date && doc.end_date) { + if (doc.company && doc.start_date && doc.end_date && doc.payment_account) { return frappe.call({ doc: cur_frm.doc, method: "make_payment_entry", - callback: function (r) { - if (r.message) - var doc = frappe.model.sync(r.message)[0]; - frappe.set_route("Form", doc.doctype, doc.name); - } + freeze: true, + freeze_message: __("Creating Bank Entries......") }); } else { - frappe.msgprint(__("Company, From Date and To Date is mandatory")); + frappe.msgprint(__("Company, Payment Account, From Date and To Date is mandatory")); } }; diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py index e70a5bdd3f2..7e0ef200a09 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py @@ -192,16 +192,6 @@ class PayrollEntry(Document): t1.docstatus = 1 and t1.name = eld.parent and start_date >= %s and end_date <= %s %s """ % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True) or [] - def get_total_salary_amount(self): - """ - Get total salary amount from submitted salary slip based on selected criteria - """ - cond = self.get_filter_condition() - totals = frappe.db.sql(""" select sum(rounded_total) as rounded_total from `tabSalary Slip` t1 - where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s - """ % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True) - return totals and totals[0] or None - def get_salary_component_account(self, salary_component): account = frappe.db.get_value("Salary Component Account", {"parent": salary_component, "company": self.company}, "default_account") @@ -225,7 +215,13 @@ class PayrollEntry(Document): if salary_components: component_dict = {} for item in salary_components: - component_dict[item['salary_component']] = component_dict.get(item['salary_component'], 0) + item['amount'] + add_component_to_accrual_jv_entry = True + if component_type == "earnings": + is_flexible_benefit, only_tax_impact = frappe.db.get_value("Salary Component", item['salary_component'], ['is_flexible_benefit', 'only_tax_impact']) + if is_flexible_benefit == 1 and only_tax_impact ==1: + add_component_to_accrual_jv_entry = False + if add_component_to_accrual_jv_entry: + component_dict[item['salary_component']] = component_dict.get(item['salary_component'], 0) + item['amount'] account_details = self.get_account(component_dict = component_dict) return account_details @@ -325,38 +321,53 @@ class PayrollEntry(Document): def make_payment_entry(self): self.check_permission('write') - total_salary_amount = self.get_total_salary_amount() + + cond = self.get_filter_condition() + salary_slip_name_list = frappe.db.sql(""" select t1.name from `tabSalary Slip` t1 + where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s + """ % ('%s', '%s', cond), (self.start_date, self.end_date), as_list = True) + + if salary_slip_name_list and len(salary_slip_name_list) > 0: + for salary_slip_name in salary_slip_name_list: + salary_slip_total = 0 + salary_slip = frappe.get_doc("Salary Slip", salary_slip_name[0]) + for sal_detail in salary_slip.earnings: + is_flexible_benefit, only_tax_impact, creat_separate_je = frappe.db.get_value("Salary Component", \ + sal_detail.salary_component, ['is_flexible_benefit', 'only_tax_impact', 'create_separate_payment_entry_against_benefit_claim']) + if only_tax_impact != 1: + if is_flexible_benefit == 1 and creat_separate_je == 1: + self.create_journal_entry(sal_detail.amount, sal_detail.salary_component) + else: + salary_slip_total += sal_detail.amount + if salary_slip_total > 0: + self.create_journal_entry(salary_slip_total, "salary") + + def create_journal_entry(self, je_payment_amount, user_remark): default_payroll_payable_account = self.get_default_payroll_payable_account() precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency") - if total_salary_amount and total_salary_amount.rounded_total: - journal_entry = frappe.new_doc('Journal Entry') - journal_entry.voucher_type = 'Bank Entry' - journal_entry.user_remark = _('Payment of salary from {0} to {1}')\ - .format(self.start_date, self.end_date) - journal_entry.company = self.company - journal_entry.posting_date = self.posting_date + journal_entry = frappe.new_doc('Journal Entry') + journal_entry.voucher_type = 'Bank Entry' + journal_entry.user_remark = _('Payment of {0} from {1} to {2}')\ + .format(user_remark, self.start_date, self.end_date) + journal_entry.company = self.company + journal_entry.posting_date = self.posting_date - payment_amount = flt(total_salary_amount.rounded_total, precision) + payment_amount = flt(je_payment_amount, precision) - journal_entry.set("accounts", [ - { - "account": self.payment_account, - "credit_in_account_currency": payment_amount - }, - { - "account": default_payroll_payable_account, - "debit_in_account_currency": payment_amount, - "reference_type": self.doctype, - "reference_name": self.name - } - ]) - return journal_entry.as_dict() - else: - frappe.msgprint( - _("There are no submitted Salary Slips to process."), - title="Error", indicator="red" - ) + journal_entry.set("accounts", [ + { + "account": self.payment_account, + "credit_in_account_currency": payment_amount + }, + { + "account": default_payroll_payable_account, + "debit_in_account_currency": payment_amount, + "reference_type": self.doctype, + "reference_name": self.name + } + ]) + journal_entry.save(ignore_permissions = True) def update_salary_slip_status(self, jv_name = None): ss_list = self.get_sal_slip_list(ss_status=1)