feat: employee leave balance reports (#20754)
* feat: Employee leave balance summary report new design * feat: Employee leave balance report new design * fix: leave based on multiple holiday list Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
ba70e7e8bc
commit
ded418e31d
@ -374,7 +374,8 @@ class LeaveApplication(Document):
|
|||||||
leaves=self.total_leave_days * -1,
|
leaves=self.total_leave_days * -1,
|
||||||
from_date=self.from_date,
|
from_date=self.from_date,
|
||||||
to_date=self.to_date,
|
to_date=self.to_date,
|
||||||
is_lwp=lwp
|
is_lwp=lwp,
|
||||||
|
holiday_list=get_holiday_list_for_employee(self.employee)
|
||||||
)
|
)
|
||||||
create_leave_ledger_entry(self, args, submit)
|
create_leave_ledger_entry(self, args, submit)
|
||||||
|
|
||||||
@ -384,7 +385,9 @@ class LeaveApplication(Document):
|
|||||||
from_date=self.from_date,
|
from_date=self.from_date,
|
||||||
to_date=expiry_date,
|
to_date=expiry_date,
|
||||||
leaves=(date_diff(expiry_date, self.from_date) + 1) * -1,
|
leaves=(date_diff(expiry_date, self.from_date) + 1) * -1,
|
||||||
is_lwp=lwp
|
is_lwp=lwp,
|
||||||
|
holiday_list=get_holiday_list_for_employee(self.employee),
|
||||||
|
|
||||||
)
|
)
|
||||||
create_leave_ledger_entry(self, args, submit)
|
create_leave_ledger_entry(self, args, submit)
|
||||||
|
|
||||||
@ -410,7 +413,7 @@ def get_allocation_expiry(employee, leave_type, to_date, from_date):
|
|||||||
return expiry[0]['to_date'] if expiry else None
|
return expiry[0]['to_date'] if expiry else None
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None):
|
def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None, holiday_list = None):
|
||||||
number_of_days = 0
|
number_of_days = 0
|
||||||
if cint(half_day) == 1:
|
if cint(half_day) == 1:
|
||||||
if from_date == to_date:
|
if from_date == to_date:
|
||||||
@ -424,7 +427,7 @@ def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day
|
|||||||
number_of_days = date_diff(to_date, from_date) + 1
|
number_of_days = date_diff(to_date, from_date) + 1
|
||||||
|
|
||||||
if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
|
if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
|
||||||
number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date))
|
number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date, holiday_list=holiday_list))
|
||||||
return number_of_days
|
return number_of_days
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -575,7 +578,7 @@ def get_leaves_for_period(employee, leave_type, from_date, to_date):
|
|||||||
{'name': leave_entry.transaction_name}, ['half_day_date'])
|
{'name': leave_entry.transaction_name}, ['half_day_date'])
|
||||||
|
|
||||||
leave_days += get_number_of_leave_days(employee, leave_type,
|
leave_days += get_number_of_leave_days(employee, leave_type,
|
||||||
leave_entry.from_date, leave_entry.to_date, half_day, half_day_date) * -1
|
leave_entry.from_date, leave_entry.to_date, half_day, half_day_date, holiday_list=leave_entry.holiday_list) * -1
|
||||||
|
|
||||||
return leave_days
|
return leave_days
|
||||||
|
|
||||||
@ -589,7 +592,7 @@ def get_leave_entries(employee, leave_type, from_date, to_date):
|
|||||||
''' Returns leave entries between from_date and to_date. '''
|
''' Returns leave entries between from_date and to_date. '''
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
employee, leave_type, from_date, to_date, leaves, transaction_name, transaction_type,
|
employee, leave_type, from_date, to_date, leaves, transaction_name, transaction_type, holiday_list,
|
||||||
is_carry_forward, is_expired
|
is_carry_forward, is_expired
|
||||||
FROM `tabLeave Ledger Entry`
|
FROM `tabLeave Ledger Entry`
|
||||||
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
|
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
|
||||||
@ -607,8 +610,9 @@ def get_leave_entries(employee, leave_type, from_date, to_date):
|
|||||||
}, as_dict=1)
|
}, as_dict=1)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_holidays(employee, from_date, to_date):
|
def get_holidays(employee, from_date, to_date, holiday_list = None):
|
||||||
'''get holidays between two dates for the given employee'''
|
'''get holidays between two dates for the given employee'''
|
||||||
|
if not holiday_list:
|
||||||
holiday_list = get_holiday_list_for_employee(employee)
|
holiday_list = get_holiday_list_for_employee(employee)
|
||||||
|
|
||||||
holidays = frappe.db.sql("""select count(distinct holiday_date) from `tabHoliday` h1, `tabHoliday List` h2
|
holidays = frappe.db.sql("""select count(distinct holiday_date) from `tabHoliday` h1, `tabHoliday List` h2
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2019-05-09 15:47:39.760406",
|
"creation": "2019-05-09 15:47:39.760406",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
@ -12,6 +13,7 @@
|
|||||||
"column_break_7",
|
"column_break_7",
|
||||||
"from_date",
|
"from_date",
|
||||||
"to_date",
|
"to_date",
|
||||||
|
"holiday_list",
|
||||||
"is_carry_forward",
|
"is_carry_forward",
|
||||||
"is_expired",
|
"is_expired",
|
||||||
"is_lwp",
|
"is_lwp",
|
||||||
@ -98,11 +100,18 @@
|
|||||||
"fieldname": "is_lwp",
|
"fieldname": "is_lwp",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Leave Without Pay"
|
"label": "Is Leave Without Pay"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "holiday_list",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Holiday List",
|
||||||
|
"options": "Holiday List"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-08-20 14:40:04.130799",
|
"links": [],
|
||||||
|
"modified": "2020-02-27 14:40:10.502605",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Leave Ledger Entry",
|
"name": "Leave Ledger Entry",
|
||||||
|
|||||||
@ -1,85 +1,186 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# License: GNU General Public License v3. See license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.hr.doctype.leave_application.leave_application \
|
from frappe import _
|
||||||
import get_leave_balance_on, get_leaves_for_period
|
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period, get_leave_balance_on, get_leave_allocation_records
|
||||||
|
|
||||||
from erpnext.hr.report.employee_leave_balance_summary.employee_leave_balance_summary \
|
|
||||||
import get_department_leave_approver_map
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
|
if filters.to_date <= filters.from_date:
|
||||||
|
frappe.throw(_('From date can not be greater than than To date'))
|
||||||
|
|
||||||
columns = get_columns(leave_types)
|
columns = get_columns()
|
||||||
data = get_data(filters, leave_types)
|
data = get_data(filters)
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def get_columns(leave_types):
|
def get_columns():
|
||||||
columns = [
|
columns = [{
|
||||||
_("Employee") + ":Link.Employee:150",
|
'label': _('Leave Type'),
|
||||||
_("Employee Name") + "::200",
|
'fieldtype': 'Link',
|
||||||
_("Department") +"::150"
|
'fieldname': 'leave_type',
|
||||||
]
|
'width': 200,
|
||||||
|
'options': 'Leave Type'
|
||||||
for leave_type in leave_types:
|
}, {
|
||||||
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
|
'label': _('Employee'),
|
||||||
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
|
'fieldtype': 'Link',
|
||||||
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
|
'fieldname': 'employee',
|
||||||
|
'width': 100,
|
||||||
|
'options': 'Employee'
|
||||||
|
}, {
|
||||||
|
'label': _('Employee Name'),
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fieldname': 'employee_name',
|
||||||
|
'width': 100,
|
||||||
|
}, {
|
||||||
|
'label': _('Opening Balance'),
|
||||||
|
'fieldtype': 'float',
|
||||||
|
'fieldname': 'opening_balance',
|
||||||
|
'width': 130,
|
||||||
|
}, {
|
||||||
|
'label': _('Leaves Allocated'),
|
||||||
|
'fieldtype': 'float',
|
||||||
|
'fieldname': 'leaves_allocated',
|
||||||
|
'width': 130,
|
||||||
|
}, {
|
||||||
|
'label': _('Leaves Taken'),
|
||||||
|
'fieldtype': 'float',
|
||||||
|
'fieldname': 'leaves_taken',
|
||||||
|
'width': 130,
|
||||||
|
}, {
|
||||||
|
'label': _('Leaves Expired'),
|
||||||
|
'fieldtype': 'float',
|
||||||
|
'fieldname': 'leaves_expired',
|
||||||
|
'width': 130,
|
||||||
|
}, {
|
||||||
|
'label': _('Closing Balance'),
|
||||||
|
'fieldtype': 'float',
|
||||||
|
'fieldname': 'closing_balance',
|
||||||
|
'width': 130,
|
||||||
|
}]
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_data(filters):
|
||||||
conditions = {
|
leave_types = frappe.db.sql_list("SELECT `name` FROM `tabLeave Type` ORDER BY `name` ASC")
|
||||||
"status": "Active",
|
|
||||||
"company": filters.company,
|
|
||||||
}
|
|
||||||
if filters.get("department"):
|
|
||||||
conditions.update({"department": filters.get("department")})
|
|
||||||
if filters.get("employee"):
|
|
||||||
conditions.update({"employee": filters.get("employee")})
|
|
||||||
|
|
||||||
return conditions
|
|
||||||
|
|
||||||
def get_data(filters, leave_types):
|
|
||||||
user = frappe.session.user
|
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
|
|
||||||
if filters.to_date <= filters.from_date:
|
user = frappe.session.user
|
||||||
frappe.throw(_("From date can not be greater than than To date"))
|
|
||||||
|
|
||||||
active_employees = frappe.get_all("Employee",
|
|
||||||
filters=conditions,
|
|
||||||
fields=["name", "employee_name", "department", "user_id", "leave_approver"])
|
|
||||||
|
|
||||||
department_approver_map = get_department_leave_approver_map(filters.get('department'))
|
department_approver_map = get_department_leave_approver_map(filters.get('department'))
|
||||||
|
|
||||||
data = []
|
active_employees = frappe.get_list('Employee',
|
||||||
for employee in active_employees:
|
filters=conditions,
|
||||||
leave_approvers = department_approver_map.get(employee.department_name, [])
|
fields=['name', 'employee_name', 'department', 'user_id', 'leave_approver'])
|
||||||
if employee.leave_approver:
|
|
||||||
leave_approvers.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)):
|
data = []
|
||||||
row = [employee.name, employee.employee_name, employee.department]
|
|
||||||
|
|
||||||
for leave_type in leave_types:
|
for leave_type in leave_types:
|
||||||
# leaves taken
|
if len(active_employees) > 1:
|
||||||
|
data.append({
|
||||||
|
'leave_type': leave_type
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
row = frappe._dict({
|
||||||
|
'leave_type': leave_type
|
||||||
|
})
|
||||||
|
|
||||||
|
for employee in active_employees:
|
||||||
|
|
||||||
|
leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver)
|
||||||
|
|
||||||
|
if (leave_approvers and len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) \
|
||||||
|
or ("HR Manager" in frappe.get_roles(user)):
|
||||||
|
if len(active_employees) > 1:
|
||||||
|
row = frappe._dict()
|
||||||
|
row.employee = employee.name,
|
||||||
|
row.employee_name = employee.employee_name
|
||||||
|
|
||||||
leaves_taken = get_leaves_for_period(employee.name, leave_type,
|
leaves_taken = get_leaves_for_period(employee.name, leave_type,
|
||||||
filters.from_date, filters.to_date) * -1
|
filters.from_date, filters.to_date) * -1
|
||||||
|
|
||||||
# opening balance
|
new_allocation, expired_leaves = get_allocated_and_expired_leaves(filters.from_date, filters.to_date, employee.name, leave_type)
|
||||||
|
|
||||||
|
|
||||||
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date)
|
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date)
|
||||||
|
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date)
|
||||||
|
|
||||||
# closing balance
|
row.leaves_allocated = new_allocation
|
||||||
closing = max(opening - leaves_taken, 0)
|
row.leaves_expired = expired_leaves - leaves_taken if expired_leaves - leaves_taken > 0 else 0
|
||||||
|
row.opening_balance = opening
|
||||||
row += [opening, leaves_taken, closing]
|
row.leaves_taken = leaves_taken
|
||||||
|
row.closing_balance = closing
|
||||||
|
row.indent = 1
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
new_leaves_allocated = 0
|
||||||
|
|
||||||
|
|
||||||
return data
|
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
|
||||||
|
|
||||||
|
def get_allocated_and_expired_leaves(from_date, to_date, employee, leave_type):
|
||||||
|
|
||||||
|
from frappe.utils import getdate
|
||||||
|
|
||||||
|
new_allocation = 0
|
||||||
|
expired_leaves = 0
|
||||||
|
|
||||||
|
records= frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
employee, leave_type, from_date, to_date, leaves, transaction_name,
|
||||||
|
is_carry_forward, is_expired
|
||||||
|
FROM `tabLeave Ledger Entry`
|
||||||
|
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
|
||||||
|
AND docstatus=1 AND leaves>0
|
||||||
|
AND (from_date between %(from_date)s AND %(to_date)s
|
||||||
|
OR to_date between %(from_date)s AND %(to_date)s
|
||||||
|
OR (from_date < %(from_date)s AND to_date > %(to_date)s))
|
||||||
|
""", {
|
||||||
|
"from_date": from_date,
|
||||||
|
"to_date": to_date,
|
||||||
|
"employee": employee,
|
||||||
|
"leave_type": leave_type
|
||||||
|
}, as_dict=1)
|
||||||
|
|
||||||
|
for record in records:
|
||||||
|
if record.to_date <= getdate(to_date):
|
||||||
|
expired_leaves += record.leaves
|
||||||
|
|
||||||
|
if record.from_date >= getdate(from_date):
|
||||||
|
new_allocation += record.leaves
|
||||||
|
|
||||||
|
return new_allocation, expired_leaves
|
||||||
|
|||||||
@ -5,18 +5,11 @@
|
|||||||
frappe.query_reports['Employee Leave Balance Summary'] = {
|
frappe.query_reports['Employee Leave Balance Summary'] = {
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
fieldname:'from_date',
|
fieldname:'date',
|
||||||
label: __('From Date'),
|
label: __('Date'),
|
||||||
fieldtype: 'Date',
|
fieldtype: 'Date',
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
default: frappe.defaults.get_default('year_start_date')
|
default: frappe.datetime.now_date()
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname:'to_date',
|
|
||||||
label: __('To Date'),
|
|
||||||
fieldtype: 'Date',
|
|
||||||
reqd: 1,
|
|
||||||
default: frappe.defaults.get_default('year_end_date')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:'company',
|
fieldname:'company',
|
||||||
|
|||||||
@ -1,130 +1,75 @@
|
|||||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# For license information, please see license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period, get_leave_balance_on
|
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.employee_leave_balance \
|
||||||
|
import get_department_leave_approver_map
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if filters.to_date <= filters.from_date:
|
leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
|
||||||
frappe.throw(_('From date can not be greater than than To date'))
|
|
||||||
|
|
||||||
columns = get_columns()
|
columns = get_columns(leave_types)
|
||||||
data = get_data(filters)
|
data = get_data(filters, leave_types)
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def get_columns():
|
def get_columns(leave_types):
|
||||||
columns = [{
|
columns = [
|
||||||
'label': _('Leave Type'),
|
_("Employee") + ":Link.Employee:150",
|
||||||
'fieldtype': 'Link',
|
_("Employee Name") + "::200",
|
||||||
'fieldname': 'leave_type',
|
_("Department") +"::150"
|
||||||
'width': 300,
|
]
|
||||||
'options': 'Leave Type'
|
|
||||||
}, {
|
for leave_type in leave_types:
|
||||||
'label': _('Employee'),
|
columns.append(_(leave_type) + ":Float:160")
|
||||||
'fieldtype': 'Link',
|
|
||||||
'fieldname': 'employee',
|
|
||||||
'width': 100,
|
|
||||||
'options': 'Employee'
|
|
||||||
}, {
|
|
||||||
'label': _('Employee Name'),
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'fieldname': 'employee_name',
|
|
||||||
'width': 100,
|
|
||||||
}, {
|
|
||||||
'label': _('Opening Balance'),
|
|
||||||
'fieldtype': 'float',
|
|
||||||
'fieldname': 'opening_balance',
|
|
||||||
'width': 160,
|
|
||||||
}, {
|
|
||||||
'label': _('Leaves Taken'),
|
|
||||||
'fieldtype': 'float',
|
|
||||||
'fieldname': 'leaves_taken',
|
|
||||||
'width': 160,
|
|
||||||
}, {
|
|
||||||
'label': _('Closing Balance'),
|
|
||||||
'fieldtype': 'float',
|
|
||||||
'fieldname': 'closing_balance',
|
|
||||||
'width': 160,
|
|
||||||
}]
|
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
def get_data(filters):
|
|
||||||
leave_types = frappe.db.sql_list("SELECT `name` FROM `tabLeave Type` ORDER BY `name` ASC")
|
|
||||||
|
|
||||||
conditions = get_conditions(filters)
|
|
||||||
|
|
||||||
user = frappe.session.user
|
|
||||||
department_approver_map = get_department_leave_approver_map(filters.get('department'))
|
|
||||||
|
|
||||||
active_employees = frappe.get_list('Employee',
|
|
||||||
filters=conditions,
|
|
||||||
fields=['name', 'employee_name', 'department', 'user_id', 'leave_approver'])
|
|
||||||
|
|
||||||
data = []
|
|
||||||
|
|
||||||
for leave_type in leave_types:
|
|
||||||
data.append({
|
|
||||||
'leave_type': leave_type
|
|
||||||
})
|
|
||||||
for employee in active_employees:
|
|
||||||
|
|
||||||
leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver)
|
|
||||||
|
|
||||||
if (leave_approvers and 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
|
|
||||||
})
|
|
||||||
|
|
||||||
leaves_taken = get_leaves_for_period(employee.name, leave_type,
|
|
||||||
filters.from_date, filters.to_date) * -1
|
|
||||||
|
|
||||||
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):
|
def get_conditions(filters):
|
||||||
conditions={
|
conditions = {
|
||||||
'status': 'Active',
|
"status": "Active",
|
||||||
|
"company": filters.company,
|
||||||
}
|
}
|
||||||
if filters.get('employee'):
|
if filters.get("department"):
|
||||||
conditions['name'] = filters.get('employee')
|
conditions.update({"department": filters.get("department")})
|
||||||
|
if filters.get("employee"):
|
||||||
if filters.get('employee'):
|
conditions.update({"employee": filters.get("employee")})
|
||||||
conditions['name'] = filters.get('employee')
|
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_department_leave_approver_map(department=None):
|
def get_data(filters, leave_types):
|
||||||
conditions=''
|
user = frappe.session.user
|
||||||
if department:
|
conditions = get_conditions(filters)
|
||||||
conditions="and (department_name = '%(department)s' or parent_department = '%(department)s')"%{'department': department}
|
|
||||||
|
|
||||||
# get current department and all its child
|
active_employees = frappe.get_all("Employee",
|
||||||
department_list = frappe.db.sql_list(""" SELECT name FROM `tabDepartment` WHERE disabled=0 {0}""".format(conditions)) #nosec
|
filters=conditions,
|
||||||
|
fields=["name", "employee_name", "department", "user_id", "leave_approver"])
|
||||||
|
|
||||||
# retrieve approvers list from current department and from its subsequent child departments
|
department_approver_map = get_department_leave_approver_map(filters.get('department'))
|
||||||
approver_list = frappe.get_all('Department Approver', filters={
|
|
||||||
'parentfield': 'leave_approvers',
|
|
||||||
'parent': ('in', department_list)
|
|
||||||
}, fields=['parent', 'approver'], as_list=1)
|
|
||||||
|
|
||||||
approvers = {}
|
data = []
|
||||||
|
for employee in active_employees:
|
||||||
|
leave_approvers = department_approver_map.get(employee.department_name, [])
|
||||||
|
if employee.leave_approver:
|
||||||
|
leave_approvers.append(employee.leave_approver)
|
||||||
|
|
||||||
for k, v in approver_list:
|
if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) or ("HR Manager" in frappe.get_roles(user)):
|
||||||
approvers.setdefault(k, []).append(v)
|
row = [employee.name, employee.employee_name, employee.department]
|
||||||
|
|
||||||
return approvers
|
for leave_type in leave_types:
|
||||||
|
|
||||||
|
# opening balance
|
||||||
|
opening = get_leave_balance_on(employee.name, leave_type, filters.date)
|
||||||
|
|
||||||
|
|
||||||
|
row += [opening]
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
Loading…
x
Reference in New Issue
Block a user