fix: leave balance reports (#18984)

* fix: process allocation expiry

* fix: leave balance summary filter

* fix: opening and closing balance

* fix: check for department leave approvers

* fix: minor changes

* fix: consider leave approver in employee

* Update employee_leave_balance_summary.py
This commit is contained in:
Mangesh-Khairnar 2019-09-13 11:07:09 +05:30 committed by Nabin Hait
parent 72949e7f73
commit 755020843b
3 changed files with 85 additions and 74 deletions

View File

@ -8,6 +8,8 @@ from frappe.utils import flt
from erpnext.hr.doctype.leave_application.leave_application \
import get_leave_balance_on, get_leaves_for_period
from erpnext.hr.report.employee_leave_balance_summary.employee_leave_balance_summary \
import get_department_leave_approver_map
def execute(filters=None):
leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
@ -19,7 +21,7 @@ def execute(filters=None):
def get_columns(leave_types):
columns = [
_("Employee") + ":Link/Employee:150",
_("Employee") + ":Link.Employee:150",
_("Employee Name") + "::200",
_("Department") +"::150"
]
@ -52,11 +54,13 @@ def get_data(filters, leave_types):
active_employees = frappe.get_all("Employee",
filters=conditions,
fields=["name", "employee_name", "department", "user_id"])
fields=["name", "employee_name", "department", "user_id", "leave_approver"])
department_approver_map = get_department_leave_approver_map(filters.get('department'))
data = []
for employee in active_employees:
leave_approvers = get_approvers(employee.department)
leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver)
if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) or ("HR Manager" in frappe.get_roles(user)):
row = [employee.name, employee.employee_name, employee.department]
@ -66,46 +70,13 @@ def get_data(filters, leave_types):
filters.from_date, filters.to_date) * -1
# opening balance
opening = get_total_allocated_leaves(employee.name, leave_type, filters.from_date, filters.to_date)
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date)
# closing balance
closing = flt(opening) - flt(leaves_taken)
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date)
row += [opening, leaves_taken, closing]
data.append(row)
return data
def get_approvers(department):
if not department:
return []
approvers = []
# get current department and all its child
department_details = frappe.db.get_value("Department", {"name": department}, ["lft", "rgt"], as_dict=True)
department_list = frappe.db.sql("""select name from `tabDepartment`
where lft >= %s and rgt <= %s order by lft desc
""", (department_details.lft, department_details.rgt), as_list = True)
# retrieve approvers list from current department and from its subsequent child departments
for d in department_list:
approvers.extend([l.leave_approver for l in frappe.db.sql("""select approver from `tabDepartment Approver` \
where parent = %s and parentfield = 'leave_approvers'""", (d), as_dict=True)])
return approvers
def get_total_allocated_leaves(employee, leave_type, from_date, to_date):
''' Returns leave allocation between from date and to date '''
leave_allocation_records = frappe.db.get_all('Leave Ledger Entry', filters={
'docstatus': 1,
'is_expired': 0,
'leave_type': leave_type,
'employee': employee,
'transaction_type': 'Leave Allocation'
}, or_filters={
'from_date': ['between', (from_date, to_date)],
'to_date': ['between', (from_date, to_date)]
}, fields=['SUM(leaves) as leaves'])
return flt(leave_allocation_records[0].get('leaves')) if leave_allocation_records else flt(0)
return data

View File

@ -4,6 +4,20 @@
frappe.query_reports['Employee Leave Balance Summary'] = {
filters: [
{
fieldname:'from_date',
label: __('From Date'),
fieldtype: 'Date',
reqd: 1,
default: frappe.defaults.get_default('year_start_date')
},
{
fieldname:'to_date',
label: __('To Date'),
fieldtype: 'Date',
reqd: 1,
default: frappe.defaults.get_default('year_end_date')
},
{
fieldname:'company',
label: __('Company'),
@ -19,18 +33,10 @@ frappe.query_reports['Employee Leave Balance Summary'] = {
options: 'Employee',
},
{
fieldname:'from_date',
label: __('From Date'),
fieldtype: 'Date',
reqd: 1,
default: frappe.defaults.get_default('year_start_date')
},
{
fieldname:'to_date',
label: __('To Date'),
fieldtype: 'Date',
reqd: 1,
default: frappe.defaults.get_default('year_end_date')
fieldname:'department',
label: __('Department'),
fieldtype: 'Link',
options: 'Department',
}
]
};

View File

@ -5,9 +5,7 @@ from __future__ import unicode_literals
import frappe
from frappe.utils import flt
from frappe import _
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period
from erpnext.hr.report.employee_leave_balance.employee_leave_balance import get_total_allocated_leaves
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period, get_leave_balance_on
def execute(filters=None):
if filters.to_date <= filters.from_date:
@ -58,16 +56,14 @@ def get_columns():
def get_data(filters):
leave_types = frappe.db.sql_list("SELECT `name` FROM `tabLeave Type` ORDER BY `name` ASC")
conditions = {
'status': 'Active',
}
conditions = get_conditions(filters)
if filters.get('employee'):
conditions['name'] = filters.get('employee')
user = frappe.session.user
department_approver_map = get_department_leave_approver_map(filters.get('department'))
active_employees = frappe.get_all('Employee',
active_employees = frappe.get_list('Employee',
filters=conditions,
fields=['name', 'employee_name', 'department', 'user_id'])
fields=['name', 'employee_name', 'department', 'user_id', 'leave_approver'])
data = []
@ -76,21 +72,59 @@ def get_data(filters):
'leave_type': leave_type
})
for employee in active_employees:
row = frappe._dict({
'employee': employee.name,
'employee_name': employee.employee_name
})
leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver)
leaves_taken = get_leaves_for_period(employee.name, leave_type,
filters.from_date, filters.to_date) * -1
if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) \
or ("HR Manager" in frappe.get_roles(user)):
row = frappe._dict({
'employee': employee.name,
'employee_name': employee.employee_name
})
opening = get_total_allocated_leaves(employee.name, leave_type, filters.from_date, filters.to_date)
closing = flt(opening) - flt(leaves_taken)
leaves_taken = get_leaves_for_period(employee.name, leave_type,
filters.from_date, filters.to_date) * -1
row.opening_balance = opening
row.leaves_taken = leaves_taken
row.closing_balance = closing
row.indent = 1
data.append(row)
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date)
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date)
row.opening_balance = opening
row.leaves_taken = leaves_taken
row.closing_balance = closing
row.indent = 1
data.append(row)
return data
def get_conditions(filters):
conditions={
'status': 'Active',
}
if filters.get('employee'):
conditions['name'] = filters.get('employee')
if filters.get('employee'):
conditions['name'] = filters.get('employee')
return conditions
def get_department_leave_approver_map(department=None):
conditions=''
if department:
conditions='and department_name = %(department)s or parent_department = %(department)s'%{'department': department}
# get current department and all its child
department_list = frappe.db.sql_list(''' SELECT name FROM `tabDepartment` WHERE disabled=0 {0}'''.format(conditions)) #nosec
# retrieve approvers list from current department and from its subsequent child departments
approver_list = frappe.get_all('Department Approver', filters={
'parentfield': 'leave_approvers',
'parent': ('in', department_list)
}, fields=['parent', 'approver'], as_list=1)
approvers = {}
for k, v in approver_list:
approvers.setdefault(k, []).append(v)
return approvers