Skip to content

Commit

Permalink
Merge pull request #946 from frappe/version-14-hotfix
Browse files Browse the repository at this point in the history
  • Loading branch information
ruchamahabal authored Oct 6, 2023
2 parents d638dc6 + 3c2aa6b commit 753b29d
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 105 deletions.
143 changes: 142 additions & 1 deletion hrms/hr/doctype/employee_checkin/test_employee_checkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def test_fetch_night_shift_on_assignment_boundary(self):
self.assertEqual(log.shift_start, start_timestamp)
self.assertEqual(log.shift_end, end_timestamp)

def test_night_shift_not_fetched_outside_assignment_boundary(self):
def test_night_shift_not_fetched_outside_assignment_boundary_for_diff_start_date(self):
employee = make_employee("[email protected]", company="_Test Company")
shift_type = setup_shift_type(
shift_type="Midnight Shift", start_time="23:00:00", end_time="07:00:00"
Expand All @@ -302,6 +302,147 @@ def test_night_shift_not_fetched_outside_assignment_boundary(self):
log = make_checkin(employee, datetime.combine(prev_day, get_time("23:00:00")))
self.assertIsNone(log.shift)

def test_night_shift_not_fetched_outside_assignment_boundary_for_diff_end_date(self):
employee = make_employee("[email protected]", company="_Test Company")
shift_type = setup_shift_type(
shift_type="Midnight Shift", start_time="19:00:00", end_time="00:30:00"
)
date = getdate()
next_day = add_days(date, 1)
prev_day = add_days(date, -1)

# shift assigned for a single day
make_shift_assignment(shift_type.name, employee, date, date)

# shift not applicable on next day's start time
log = make_checkin(employee, datetime.combine(next_day, get_time("19:00:00")))
self.assertIsNone(log.shift)

# shift not applicable on current day's end time
log = make_checkin(employee, datetime.combine(date, get_time("00:30:00")))
self.assertIsNone(log.shift)

# shift not applicable on prev day's start time
log = make_checkin(employee, datetime.combine(prev_day, get_time("19:00:00")))
self.assertIsNone(log.shift)

def test_night_shift_not_fetched_outside_before_shift_margin(self):
employee = make_employee("[email protected]", company="_Test Company")
shift_type = setup_shift_type(
shift_type="Midnight Shift", start_time="00:30:00", end_time="10:00:00"
)
date = getdate()
next_day = add_days(date, 1)
prev_day = add_days(date, -1)

# shift assigned for a single day
make_shift_assignment(shift_type.name, employee, date, date)

# shift not fetched in today's shift margin
log = make_checkin(employee, datetime.combine(date, get_time("23:30:00")))
self.assertIsNone(log.shift)

# shift not applicable on next day's start time
log = make_checkin(employee, datetime.combine(next_day, get_time("00:30:00")))
self.assertIsNone(log.shift)

# shift not applicable on prev day's start time
log = make_checkin(employee, datetime.combine(prev_day, get_time("00:30:00")))
self.assertIsNone(log.shift)

def test_night_shift_not_fetched_outside_after_shift_margin(self):
employee = make_employee("[email protected]", company="_Test Company")
shift_type = setup_shift_type(
shift_type="Midnight Shift", start_time="15:00:00", end_time="23:30:00"
)
date = getdate()
next_day = add_days(date, 1)
prev_day = add_days(date, -1)

# shift assigned for a single day
make_shift_assignment(shift_type.name, employee, date, date)

# shift not fetched in today's shift margin
log = make_checkin(employee, datetime.combine(date, get_time("00:30:00")))
self.assertIsNone(log.shift)

# shift not applicable on next day's start time
log = make_checkin(employee, datetime.combine(next_day, get_time("15:00:00")))
self.assertIsNone(log.shift)

# shift not applicable on prev day's start time
log = make_checkin(employee, datetime.combine(prev_day, get_time("15:00:00")))
self.assertIsNone(log.shift)

# shift not applicable on prev day's end time
log = make_checkin(employee, datetime.combine(prev_day, get_time("00:30:00")))
self.assertIsNone(log.shift)

def test_fetch_night_shift_in_margin_period_after_shift(self):
"""
Tests if shift is correctly fetched in logs if the actual end time exceeds a day
i.e: shift is from 15:00 to 23:00 (starts & ends on the same day)
but shift margin = 2 hours, so the actual shift goes to 1:00 of the next day
"""
employee = make_employee("[email protected]", company="_Test Company")
# shift margin goes to next day (1:00 am)
shift_type = setup_shift_type(
shift_type="Midnight Shift",
start_time="15:00:00",
end_time="23:00:00",
allow_check_out_after_shift_end_time=120,
)
date = getdate()
next_day = add_days(date, 1)

# shift assigned for a single day
make_shift_assignment(shift_type.name, employee, date, date)

# IN log falls on the first day
start_timestamp = datetime.combine(date, get_time("14:00:00"))
log_in = make_checkin(employee, start_timestamp)

# OUT log falls on the second day in the shift margin period
end_timestamp = datetime.combine(next_day, get_time("01:00:00"))
log_out = make_checkin(employee, end_timestamp)

for log in [log_in, log_out]:
self.assertEqual(log.shift, shift_type.name)
self.assertEqual(log.shift_actual_start, start_timestamp)
self.assertEqual(log.shift_actual_end, end_timestamp)

def test_fetch_night_shift_in_margin_period_before_shift(self):
"""
Tests if shift is correctly fetched in logs if the actual end time exceeds a day
i.e: shift is from 00:30 to 10:00 (starts & ends on the same day)
but shift margin = 1 hour, so the actual shift start goes to 23:30:00 of the prev day
"""
employee = make_employee("[email protected]", company="_Test Company")
# shift margin goes to next day (1:00 am)
shift_type = setup_shift_type(
shift_type="Midnight Shift",
start_time="00:30:00",
end_time="10:00:00",
)
date = getdate()
prev_day = add_days(date, -1)

# shift assigned for a single day
make_shift_assignment(shift_type.name, employee, date, date)

# IN log falls on the first day in the shift margin period
start_timestamp = datetime.combine(prev_day, get_time("23:30:00"))
log_in = make_checkin(employee, start_timestamp)

# OUT log falls on the second day
end_timestamp = datetime.combine(date, get_time("11:00:00"))
log_out = make_checkin(employee, end_timestamp)

for log in [log_in, log_out]:
self.assertEqual(log.shift, shift_type.name)
self.assertEqual(log.shift_actual_start, start_timestamp)
self.assertEqual(log.shift_actual_end, end_timestamp)

def test_consecutive_shift_assignments_overlapping_within_grace_period(self):
# test adjustment for start and end times if they are overlapping
# within "begin_check_in_before_shift_start_time" and "allow_check_out_after_shift_end_time" periods
Expand Down
41 changes: 29 additions & 12 deletions hrms/hr/doctype/goal/goal.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,35 @@ frappe.ui.form.on("Goal", {
},

add_custom_buttons(frm) {
if (!frm.doc.__islocal) {
if (frm.doc.status !== "Archived") {
frm.add_custom_button(__("Archive"), () => {
frm.set_value("status", "Archived");
frm.save();
});
} else {
frm.add_custom_button(__("Unarchive"), () => {
frm.set_value("status", "");
frm.save();
});
}
if (frm.doc.__islocal || frm.doc.status === "Completed") return;
const doc_status = frm.doc.status;

if (doc_status === "Archived") {
frm.add_custom_button(__("Unarchive"), () => {
frm.set_value("status", "");
frm.save();
}, __("Status"));
}

if (doc_status === "Closed") {
frm.add_custom_button(__("Reopen"), () => {
frm.set_value("status", "");
frm.save();
}, __("Status"));
}

if (doc_status !== "Archived") {
frm.add_custom_button(__("Archive"), () => {
frm.set_value("status", "Archived");
frm.save();
}, __("Status"));
}

if (doc_status !== "Closed") {
frm.add_custom_button(__("Close"), () => {
frm.set_value("status", "Closed");
frm.save();
}, __("Status"));
}
},

Expand Down
6 changes: 3 additions & 3 deletions hrms/hr/doctype/goal/goal.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"fieldtype": "Percent",
"in_list_view": 1,
"label": "Progress",
"read_only_depends_on": "eval:doc.is_group"
"read_only_depends_on": "eval:doc.is_group || doc.status=='Closed'"
},
{
"default": "Pending",
Expand All @@ -71,7 +71,7 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Status",
"options": "\nPending\nIn Progress\nCompleted\nArchived",
"options": "\nPending\nIn Progress\nCompleted\nArchived\nClosed",
"read_only": 1
},
{
Expand Down Expand Up @@ -213,7 +213,7 @@
"index_web_pages_for_search": 1,
"is_tree": 1,
"links": [],
"modified": "2023-03-31 09:56:03.450215",
"modified": "2023-09-29 12:38:53.405179",
"modified_by": "Administrator",
"module": "HR",
"name": "Goal",
Expand Down
15 changes: 8 additions & 7 deletions hrms/hr/doctype/goal/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@ def validate_progress(self):
frappe.throw(_("Goal progress percentage cannot be more than 100."))

def set_status(self, status=None):
if self.status != "Archived":
if flt(self.progress) == 0:
self.status = "Pending"
elif flt(self.progress) == 100:
self.status = "Completed"
elif flt(self.progress) < 100:
self.status = "In Progress"
if self.status in ["Archived", "Closed"]:
return
if flt(self.progress) == 0:
self.status = "Pending"
elif flt(self.progress) == 100:
self.status = "Completed"
elif flt(self.progress) < 100:
self.status = "In Progress"

def update_kra_in_child_goals(self, doc_before_save):
"""Aligns children's KRA to parent goal's KRA if parent goal's KRA is changed"""
Expand Down
1 change: 1 addition & 0 deletions hrms/hr/doctype/goal/goal_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ frappe.listview_settings["Goal"] = {
"In Progress": "orange",
"Completed": "green",
"Archived": "gray",
"Closed": "red",
};
return [__(doc.status), status_color[doc.status], "status,=," + doc.status];
},
Expand Down
Loading

0 comments on commit 753b29d

Please sign in to comment.