Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import frappe
from frappe.utils import add_days, getdate

from erpnext.setup.doctype.employee.employee import is_holiday
from erpnext.setup.doctype.employee.test_employee import make_employee

from hrms.hr.doctype.attendance.attendance import mark_attendance
Expand Down Expand Up @@ -78,30 +79,31 @@ def test_get_employees_for_half_day_attendance(self):
# only half day attendance created from leave type should be fetched to update in the tool
employee = frappe.get_doc("Employee", self.employee1)
leave_type = create_leave_type(leave_type="_Test Employee Attendance Tool", include_holidays=0)
date = getdate()
while is_holiday(employee=employee.name, date=date):
date = add_days(date, -1)
frappe.get_doc(
{
"doctype": "Leave Allocation",
"employee": employee.name,
"employee_name": employee.employee_name,
"leave_type": leave_type.name,
"from_date": add_days(getdate(), -2),
"from_date": add_days(date, -2),
"new_leaves_allocated": 15,
"carry_forward": 0,
"to_date": add_days(getdate(), 30),
}
).submit()
make_leave_application(
employee=employee.name,
from_date=getdate(),
to_date=getdate(),
from_date=date,
to_date=date,
leave_type=leave_type.name,
half_day=1,
half_day_date=getdate(),
)
mark_attendance(
self.employee2, attendance_date=getdate(), status="Half Day", half_day_status="Absent"
half_day_date=date,
)
total_employees = get_employees(getdate(), company="_Test Company")
mark_attendance(self.employee2, attendance_date=date, status="Half Day", half_day_status="Absent")
total_employees = get_employees(date, company="_Test Company")
half_marked_employees = total_employees.get("half_day_marked")
self.assertEqual(len(half_marked_employees), 1)
self.assertEqual(half_marked_employees[0].get("employee_name"), employee.employee_name)
Expand All @@ -114,8 +116,12 @@ def test_update_half_day_attendance(self):
employee2 = frappe.get_doc("Employee", self.employee2)
leave_type = create_leave_type(leave_type="_Test Employee Attendance Tool", include_holidays=0)
date = add_days(getdate(), -1)
create_leave_allocation(employee2, leave_type)
create_leave_allocation(employee4, leave_type)
while is_holiday(employee=employee2.name, date=date) or is_holiday(
employee=employee4.name, date=date
):
date = add_days(date, -1)
create_leave_allocation(employee2, leave_type, date)
create_leave_allocation(employee4, leave_type, date)
make_leave_application(
employee=employee2.name,
from_date=date,
Expand Down Expand Up @@ -229,14 +235,15 @@ def test_get_unmarked_attendance_with_shift(self):
self.assertNotIn(self.employee3.name, filtered)


def create_leave_allocation(employee, leave_type):
def create_leave_allocation(employee, leave_type, date=None):
from_date = add_days(date or getdate(), -2)
frappe.get_doc(
{
"doctype": "Leave Allocation",
"employee": employee.name,
"employee_name": employee.employee_name,
"leave_type": leave_type.name,
"from_date": add_days(getdate(), -2),
"from_date": from_date,
"new_leaves_allocated": 15,
"carry_forward": 0,
"to_date": add_days(getdate(), 30),
Expand Down
14 changes: 14 additions & 0 deletions hrms/hr/doctype/leave_application/leave_application.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ frappe.ui.form.on("Leave Application", {
},

half_day_date(frm) {
frm.trigger("validate_half_day_date");
frm.trigger("calculate_total_days");
},

Expand Down Expand Up @@ -229,7 +230,20 @@ frappe.ui.form.on("Leave Application", {
});
}
},
validate_half_day_date: function (frm) {
if (!frm.doc.half_day_date) {
return;
}

return frm
.call("validate_half_day_date")
.then(() => {
frm.trigger("calculate_total_days");
})
.catch(() => {
frm.set_value("half_day_date", "");
});
},
calculate_total_days: function (frm) {
if (frm.doc.from_date && frm.doc.to_date && frm.doc.employee && frm.doc.leave_type) {
// server call is done to include holidays in leave days calculations
Expand Down
41 changes: 22 additions & 19 deletions hrms/hr/doctype/leave_application/leave_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
)

from erpnext.buying.doctype.supplier_scorecard.supplier_scorecard import daterange
from erpnext.setup.doctype.employee.employee import get_holiday_list_for_employee
from erpnext.setup.doctype.employee.employee import get_holiday_list_for_employee, is_holiday

import hrms
from hrms.api import get_current_employee_info
Expand Down Expand Up @@ -229,15 +229,7 @@ def validate_dates(self):
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
frappe.throw(_("To date cannot be before from date"))

if (
self.half_day
and self.half_day_date
and (
getdate(self.half_day_date) < getdate(self.from_date)
or getdate(self.half_day_date) > getdate(self.to_date)
)
):
frappe.throw(_("Half Day Date should be between From Date and To Date"))
self.validate_half_day_date()

if not is_lwp(self.leave_type):
self.validate_dates_across_allocation()
Expand Down Expand Up @@ -915,6 +907,17 @@ def onload(self):
frappe.db.get_single_value("HR Settings", "prevent_self_leave_approval"),
)

@frappe.whitelist()
def validate_half_day_date(self) -> bool:
if not self.half_day:
return

if is_holiday(employee=self.employee, date=self.half_day_date):
frappe.throw(_("Half Day Date cannot be a holiday"))

if not (getdate(self.from_date) <= getdate(self.half_day_date) <= getdate(self.to_date)):
frappe.throw(_("Half Day Date should be between From Date and To Date"))


def get_allocation_expiry_for_cf_leaves(
employee: str, leave_type: str, to_date: datetime.date, from_date: datetime.date
Expand Down Expand Up @@ -972,16 +975,16 @@ def get_number_of_leave_days(
) -> float:
"""Returns number of leave days between 2 dates after considering half day and holidays
(Based on the include_holiday setting in Leave Type)"""
number_of_days = 0
number_of_days = date_diff(to_date, from_date) + 1

if cint(half_day) == 1:
if getdate(from_date) == getdate(to_date):
number_of_days = 0.5
elif half_day_date and getdate(from_date) <= getdate(half_day_date) <= getdate(to_date):
number_of_days = date_diff(to_date, from_date) + 0.5
else:
number_of_days = date_diff(to_date, from_date) + 1
else:
number_of_days = date_diff(to_date, from_date) + 1
is_valid_half_day = (
half_day_date
and getdate(from_date) <= getdate(half_day_date) <= getdate(to_date)
and not is_holiday(employee=employee, date=half_day_date)
)
if is_valid_half_day:
number_of_days -= 0.5

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))
Expand Down
Loading
Loading