Skip to content

Commit

Permalink
fix: show validation message before changing shift start time
Browse files Browse the repository at this point in the history
chore: added tests
  • Loading branch information
asmitahase committed Jan 31, 2025
1 parent 0ae2335 commit a68aa49
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
19 changes: 19 additions & 0 deletions hrms/hr/doctype/shift_type/shift_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from itertools import groupby

import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, create_batch, get_datetime, get_time, getdate

Expand All @@ -25,6 +26,24 @@


class ShiftType(Document):
def validate(self):
if self.is_field_modified("start_time") and self.unlinked_checkins_exist():
frappe.throw(
title=_("Unlinked Logs Found"),
msg=_(
"Mark attendance for the exsiting check in/out logs before changing important shift settings"
),
)

def is_field_modified(self, fieldname):
return not self.is_new() and self.has_value_changed(fieldname)

def unlinked_checkins_exist(self):
return frappe.db.exists(
"Employee Checkin",
{"shift": self.name, "attendance": ["is", "not set"], "skip_auto_attendance": 0},
)

@frappe.whitelist()
def process_auto_attendance(self):
if (
Expand Down
36 changes: 36 additions & 0 deletions hrms/hr/doctype/shift_type/test_shift_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,42 @@ def test_mark_attendance_for_default_shift_when_shift_assignment_is_not_overlapp
"Absent",
)

def test_validation_for_unlinked_logs_before_changing_important_shift_configuration(self):
# the important shift configuration is start time, it is used to sort logs chronologically
shift = setup_shift_type(shift_type="Test Shift", start_time="10:00:00", end_time="18:00:00")
employee = make_employee(
"[email protected]", company="_Test Company", default_shift=shift.name
)

from hrms.hr.doctype.employee_checkin.test_employee_checkin import make_checkin

in_time = datetime.combine(getdate(), get_time("10:00:00"))
check_in = make_checkin(employee, in_time)
check_in.fetch_shift()
# Case 1: raise valdiation error if shift time is being changed and checkin logs exists
shift.start_time = get_time("10:15:00")
self.assertRaises(frappe.ValidationError, shift.save)

# don't raise validation error if something else is being changed
# even if checkin logs exists, it's probably fine
shift.reload()
shift.begin_check_in_before_shift_start_time = 120
shift.save()
self.assertEqual(
frappe.get_value("Shift Type", shift.name, "begin_check_in_before_shift_start_time"), 120
)
out_time = datetime.combine(getdate(), get_time("18:00:00"))
check_out = make_checkin(employee, out_time)
check_out.fetch_shift()
shift.process_auto_attendance()

# Case 2: allow shift time to change if no unlinked logs exist
shift.start_time = get_time("10:15:00")
shift.save()
self.assertEqual(
get_time(frappe.get_value("Shift Type", shift.name, "start_time")), get_time("10:15:00")
)


def setup_shift_type(**args):
args = frappe._dict(args)
Expand Down

0 comments on commit a68aa49

Please sign in to comment.