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:
parent
72949e7f73
commit
755020843b
@ -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
|
@ -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',
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user