feat: Bank remittance report for tracking payroll-entry transactions (#17013)

* feat: Bank remittance report for tracking payroll-entry transactions

* feat: show Company bank account and bank name

* feat: Added Permissions to view report

* feat: Validated report only if debit account is present

* fix: query optimisation

* feat: Added From date and To date filters

* fix: code optimisation

* fix: requested changes

* fix: requested changes and refactor

* style: indentation

* style: Formatting

* fix: added parameter filters
This commit is contained in:
Anurag Mishra 2019-05-13 19:03:21 +05:30 committed by GitHub
parent 3866e132f7
commit 73706f85aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 246 additions and 5 deletions

View File

@ -21,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@ -53,6 +54,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@ -86,6 +88,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
"fetch_if_empty": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
@ -120,6 +123,7 @@
"columns": 0,
"default": "",
"depends_on": "eval:doc.salary_slip_based_on_timesheet == 0",
"fetch_if_empty": 0,
"fieldname": "payroll_frequency",
"fieldtype": "Select",
"hidden": 0,
@ -153,6 +157,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@ -186,6 +191,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@ -220,6 +226,7 @@
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@ -252,6 +259,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "branch",
"fieldtype": "Link",
"hidden": 0,
@ -285,6 +293,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@ -318,6 +327,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"hidden": 0,
@ -349,6 +359,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "designation",
"fieldtype": "Link",
"hidden": 0,
@ -382,6 +393,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "number_of_employees",
"fieldtype": "Int",
"hidden": 0,
@ -414,6 +426,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sec_break20",
"fieldtype": "Section Break",
"hidden": 0,
@ -445,6 +458,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "employees",
"fieldtype": "Table",
"hidden": 0,
@ -478,6 +492,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_13",
"fieldtype": "Section Break",
"hidden": 0,
@ -509,6 +524,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "validate_attendance",
"fieldtype": "Check",
"hidden": 0,
@ -541,6 +557,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "attendance_detail_html",
"fieldtype": "HTML",
"hidden": 0,
@ -572,6 +589,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_12",
"fieldtype": "Section Break",
"hidden": 0,
@ -604,6 +622,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
"fetch_if_empty": 0,
"fieldname": "salary_slip_based_on_timesheet",
"fieldtype": "Check",
"hidden": 0,
@ -637,6 +656,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "select_payroll_period",
"fieldtype": "Section Break",
"hidden": 0,
@ -670,6 +690,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
@ -703,6 +724,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "end_date",
"fieldtype": "Date",
"hidden": 0,
@ -735,6 +757,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@ -766,6 +789,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "deduct_tax_for_unclaimed_employee_benefits",
"fieldtype": "Check",
"hidden": 0,
@ -798,6 +822,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "deduct_tax_for_unsubmitted_tax_exemption_proof",
"fieldtype": "Check",
"hidden": 0,
@ -830,6 +855,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
@ -864,6 +890,7 @@
"columns": 0,
"default": ":Company",
"fetch_from": "",
"fetch_if_empty": 0,
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
@ -897,6 +924,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_18",
"fieldtype": "Column Break",
"hidden": 0,
@ -928,6 +956,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@ -961,6 +990,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@ -993,6 +1023,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "account",
"fieldtype": "Section Break",
"hidden": 0,
@ -1026,6 +1057,7 @@
"collapsible": 0,
"columns": 0,
"description": "Select Payment Account to make Bank Entry",
"fetch_if_empty": 0,
"fieldname": "payment_account",
"fieldtype": "Link",
"hidden": 0,
@ -1059,6 +1091,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break2",
"fieldtype": "Section Break",
"hidden": 0,
@ -1090,6 +1123,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@ -1122,6 +1156,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "salary_slips_created",
"fieldtype": "Check",
"hidden": 1,
@ -1154,6 +1189,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "salary_slips_submitted",
"fieldtype": "Check",
"hidden": 1,
@ -1181,17 +1217,16 @@
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-cog",
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-02-05 10:41:08.865842",
"menu_index": 0,
"modified": "2019-03-26 16:55:04.158800",
"modified_by": "Administrator",
"module": "HR",
"name": "Payroll Entry",
@ -1210,7 +1245,7 @@
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"report": 1,
"role": "HR Manager",
"set_user_permissions": 0,
"share": 1,
@ -1220,7 +1255,6 @@
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",

View File

@ -0,0 +1,28 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Bank Remittance"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company"),
"reqd": 1
},
{
fieldname:"from_date",
label: __("From Date"),
fieldtype: "Date",
},
{
fieldname:"to_date",
label: __("To Date"),
fieldtype: "Date",
},
]
}

View File

@ -0,0 +1,25 @@
{
"add_total_row": 0,
"creation": "2019-03-26 16:57:52.558895",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-26 16:57:52.558895",
"modified_by": "Administrator",
"module": "HR",
"name": "Bank Remittance",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Payroll Entry",
"report_name": "Bank Remittance",
"report_type": "Script Report",
"roles": [
{
"role": "HR Manager"
}
]
}

View File

@ -0,0 +1,154 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import formatdate
import itertools
from frappe import _, get_all
def execute(filters=None):
columns = [
{
"label": _("Payroll Number"),
"fieldtype": "Link",
"fieldname": "payroll_no",
"options": "Payroll Entry",
"width": 150
},
{
"label": _("Debit A/C Number"),
"fieldtype": "Int",
"fieldname": "debit_account",
"hidden": 1,
"width": 200
},
{
"label": _("Payment Date"),
"fieldtype": "Data",
"fieldname": "payment_date",
"width": 100
},
{
"label": _("Employee Name"),
"fieldtype": "Link",
"fieldname": "employee_name",
"options": "Employee",
"width": 200
},
{
"label": _("Bank Name"),
"fieldtype": "Data",
"fieldname": "bank_name",
"width": 50
},
{
"label": _("Employee A/C Number"),
"fieldtype": "Int",
"fieldname": "employee_account_no",
"width": 50
},
{
"label": _("IFSC Code"),
"fieldtype": "Data",
"fieldname": "bank_code",
"width": 100
},
{
"label": _("Currency"),
"fieldtype": "Data",
"fieldname": "currency",
"width": 50
},
{
"label": _("Net Salary Amount"),
"fieldtype": "Currency",
"options": "currency",
"fieldname": "amount",
"width": 100
}
]
data = []
accounts = get_bank_accounts()
payroll_entries = get_payroll_entries(accounts, filters)
salary_slips = get_salary_slips(payroll_entries)
get_emp_bank_ifsc_code(salary_slips)
for salary in salary_slips:
if salary.bank_name and salary.bank_account_no and salary.debit_acc_no and salary.status in ["Submitted", "Paid"]:
row = {
"payroll_no": salary.payroll_entry,
"debit_account": salary.debit_acc_no,
"payment_date": frappe.utils.formatdate(salary.modified.strftime('%Y-%m-%d')),
"bank_name": salary.bank_name,
"employee_account_no": salary.bank_account_no,
"bank_code": salary.ifsc_code,
"employee_name": salary.employee+": " + salary.employee_name,
"currency": frappe.get_cached_value('Company', filters.company, 'default_currency'),
"amount": salary.net_pay,
}
data.append(row)
return columns, data
def get_bank_accounts():
accounts = [d.name for d in get_all("Account", filters={"account_type": "Bank"})]
return accounts
def get_payroll_entries(accounts, filters):
payroll_filter = [
('payment_account', 'IN', accounts),
('number_of_employees', '>', 0),
('Company', '=', filters.company)
]
if filters.to_date:
payroll_filter.append(('posting_date', '<', filters.to_date))
if filters.from_date:
payroll_filter.append(('posting_date', '>', filters.from_date))
entries = get_all("Payroll Entry", payroll_filter, ["name", "payment_account"])
payment_accounts = [d.payment_account for d in entries]
set_company_account(payment_accounts, entries)
return entries
def get_salary_slips(payroll_entries):
payroll = [d.name for d in payroll_entries]
salary_slips = get_all("Salary Slip", filters = [("payroll_entry", "IN", payroll)],
fields = ["modified", "net_pay", "bank_name", "bank_account_no", "payroll_entry", "employee", "employee_name", "status"]
)
payroll_entry_map = {}
for entry in payroll_entries:
payroll_entry_map[entry.name] = entry
# appending company debit accounts
for slip in salary_slips:
slip["debit_acc_no"] = payroll_entry_map[slip.payroll_entry]['company_account']
return salary_slips
def get_emp_bank_ifsc_code(salary_slips):
emp_names = [d.employee for d in salary_slips]
ifsc_codes = get_all("Employee", [("name", "IN", emp_names)], ["ifsc_code", "name"])
ifsc_codes_map = {}
for code in ifsc_codes:
ifsc_codes_map[code.name] = code
for slip in salary_slips:
slip["ifsc_code"] = ifsc_codes_map[code.name]['ifsc_code']
return salary_slips
def set_company_account(payment_accounts, payroll_entries):
company_accounts = get_all("Bank Account", [("account", "in", payment_accounts)], ["account", "bank_account_no"])
company_accounts_map = {}
for acc in company_accounts:
company_accounts_map[acc.account] = acc
for entry in payroll_entries:
entry["company_account"] = company_accounts_map[entry.payment_account]['bank_account_no']
return payroll_entries