# 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