fix: incorrect LWP calculation for half days in employee benefit application

This commit is contained in:
Rucha Mahabal
2022-06-07 10:18:19 +05:30
parent 8b48d45286
commit 10f0c935fe

View File

@@ -5,7 +5,7 @@
import frappe import frappe
from frappe import _ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from frappe.utils import add_days, cint, cstr, date_diff, getdate, rounded from frappe.utils import add_days, cstr, date_diff, flt, getdate, rounded
from erpnext.hr.utils import ( from erpnext.hr.utils import (
get_holiday_dates_for_employee, get_holiday_dates_for_employee,
@@ -27,11 +27,14 @@ class EmployeeBenefitApplication(Document):
validate_active_employee(self.employee) validate_active_employee(self.employee)
self.validate_duplicate_on_payroll_period() self.validate_duplicate_on_payroll_period()
if not self.max_benefits: if not self.max_benefits:
self.max_benefits = get_max_benefits_remaining(self.employee, self.date, self.payroll_period) self.max_benefits = flt(
get_max_benefits_remaining(self.employee, self.date, self.payroll_period),
self.precision("max_benefits"),
)
if self.max_benefits and self.max_benefits > 0: if self.max_benefits and self.max_benefits > 0:
self.validate_max_benefit_for_component() self.validate_max_benefit_for_component()
self.validate_prev_benefit_claim() self.validate_prev_benefit_claim()
if self.remaining_benefit > 0: if self.remaining_benefit and self.remaining_benefit > 0:
self.validate_remaining_benefit_amount() self.validate_remaining_benefit_amount()
else: else:
frappe.throw( frappe.throw(
@@ -110,7 +113,7 @@ class EmployeeBenefitApplication(Document):
max_benefit_amount = 0 max_benefit_amount = 0
for employee_benefit in self.employee_benefits: for employee_benefit in self.employee_benefits:
self.validate_max_benefit(employee_benefit.earning_component) self.validate_max_benefit(employee_benefit.earning_component)
max_benefit_amount += employee_benefit.amount max_benefit_amount += flt(employee_benefit.amount)
if max_benefit_amount > self.max_benefits: if max_benefit_amount > self.max_benefits:
frappe.throw( frappe.throw(
_("Maximum benefit amount of employee {0} exceeds {1}").format( _("Maximum benefit amount of employee {0} exceeds {1}").format(
@@ -125,7 +128,8 @@ class EmployeeBenefitApplication(Document):
benefit_amount = 0 benefit_amount = 0
for employee_benefit in self.employee_benefits: for employee_benefit in self.employee_benefits:
if employee_benefit.earning_component == earning_component_name: if employee_benefit.earning_component == earning_component_name:
benefit_amount += employee_benefit.amount benefit_amount += flt(employee_benefit.amount)
prev_sal_slip_flexi_amount = get_sal_slip_total_benefit_given( prev_sal_slip_flexi_amount = get_sal_slip_total_benefit_given(
self.employee, frappe.get_doc("Payroll Period", self.payroll_period), earning_component_name self.employee, frappe.get_doc("Payroll Period", self.payroll_period), earning_component_name
) )
@@ -209,32 +213,44 @@ def calculate_lwp(employee, start_date, holidays, working_days):
holidays = "','".join(holidays) holidays = "','".join(holidays)
for d in range(working_days): for d in range(working_days):
dt = add_days(cstr(getdate(start_date)), d) date = add_days(cstr(getdate(start_date)), d)
LeaveApplication = frappe.qb.DocType("Leave Application") LeaveApplication = frappe.qb.DocType("Leave Application")
LeaveType = frappe.qb.DocType("Leave Type") LeaveType = frappe.qb.DocType("Leave Type")
is_half_day = (
frappe.qb.terms.Case()
.when(
(
(LeaveApplication.half_day_date == date)
| (LeaveApplication.from_date == LeaveApplication.to_date)
),
LeaveApplication.half_day,
)
.else_(0)
).as_("is_half_day")
query = ( query = (
frappe.qb.from_(LeaveApplication) frappe.qb.from_(LeaveApplication)
.inner_join(LeaveType) .inner_join(LeaveType)
.on((LeaveType.name == LeaveApplication.leave_type)) .on((LeaveType.name == LeaveApplication.leave_type))
.select(LeaveApplication.name, LeaveApplication.half_day) .select(LeaveApplication.name, is_half_day)
.where( .where(
(LeaveType.is_lwp == 1) (LeaveType.is_lwp == 1)
& (LeaveApplication.docstatus == 1) & (LeaveApplication.docstatus == 1)
& (LeaveApplication.status == "Approved") & (LeaveApplication.status == "Approved")
& (LeaveApplication.employee == employee) & (LeaveApplication.employee == employee)
& ((LeaveApplication.from_date <= dt) & (dt <= LeaveApplication.to_date)) & ((LeaveApplication.from_date <= date) & (date <= LeaveApplication.to_date))
) )
) )
# if it's a holiday only include if leave type has "include holiday" enabled # if it's a holiday only include if leave type has "include holiday" enabled
if dt in holidays: if date in holidays:
query = query.where((LeaveType.include_holiday == "1")) query = query.where((LeaveType.include_holiday == "1"))
leaves = query.run() leaves = query.run(as_dict=True)
if leaves: if leaves:
lwp = cint(leaves[0][1]) and (lwp + 0.5) or (lwp + 1) lwp += 0.5 if leaves[0].is_half_day else 1
return lwp return lwp