Timesheet Validator - Validation Rules

Version 3.0.1 | Last Updated: March, 2026 | ASK IT Limited
Total Rules
17
Completed
15
Pending
2
Completion
88%
Priority Rule Name Scope Condition (Logic) Output / Remark Pattern Status
1 Leave without reason (all empty) Weekday Weekday AND
• Start Time (C) = Empty
• End Time (D) = Empty
• Remarks (H) = Empty
Business Logic:
On weekdays, employees are expected to work. If no time is entered and no remarks explain the absence, this indicates unapproved leave.

Example:
Date: Jan 15 (Mon) | C/D/H: All empty → Error
dispDate & " Leave without reason (weekday, no time in C/D, no remarks in H)" Done
2 Leave without reason (missing time, no AL/SL/PH) Weekday Weekday AND
• (C = Empty OR D = Empty)
• Remarks (H) NOT contain:
  AL/SL/CL/ML/PL/NPL/NPSL/Public Holiday
Business Logic:
Partial attendance must be explained with a valid leave type or have both start/end times filled.

Example:
Date: Jan 20 (Mon) | C: Empty, D: 18:00, Remarks: "Doctor appointment" → Error
dispDate & " Leave without reason (weekday, no time in C/D, no AL/SL/Public Holiday in remarks)" Done
2.1 Special paid leave (CL/ML/PL) Weekday Saturday PH (Weekday OR Sat OR PH) AND
• C = Empty AND D = Empty
• actualHours = 0
• Remarks contain: CL or ML or PL
Business Logic:
CL, ML, and PL are special paid leave types that don't require work hours. These are exempt from "leave without reason" rules.

Example:
Date: Jan 25 (Mon) | C/D: Empty, Remarks: "CL - Family emergency" → OK ✅
(No remark - valid paid leave CL/ML/PL) Done
2.5 Half-day leave without work hours Weekday Weekday AND
• Remarks contain "(AM)" or "(PM)"
• C = Empty AND D = Empty
Business Logic:
If marking half-day leave (AM or PM), the employee should still work the other half and enter those hours in columns C/D.

Example:
Date: Feb 5 (Wed) | C/D: Empty, Remarks: "AL (AM)" → Error
dispDate & " - Half-day leave but no work hours (expected work time in C/D for other half)" Done
3 Working hours not numeric (E is N/A) Weekday Weekday AND
• C filled AND D filled
• actualHours > 0 (from C-D)
• E NOT numeric (N/A, text, error)
Business Logic:
If time is entered (C & D), the working hours formula (E) should calculate a numeric value. "N/A" or errors indicate formula/data issues.

Example:
Date: Jan 12 (Mon) | C: 09:00, D: 18:00, E: "N/A", actual: 9.0h → Error
dispDate & " Working hours missing C-D=" & Format(actualHours,"0.0") & "h E is not numeric (N/A)" Done
4 C/D vs E mismatch Weekday Weekday AND
• C filled AND D filled
• E is numeric
• E ≠ (D-C) × 24
Business Logic:
The working hours in column E must match the calculated difference between end time and start time [(D-C) × 24].

Example:
Date: Jan 18 (Mon) | C: 09:00, D: 18:00, E: 8.5h, actual: 9.0h → Error
dispDate & " Working hours mismatch C-D=" & Format(actualHours,"0.0") & "h E=" & Format(workHours,"0.0") & "h" Done
5 Actual < expected hours Weekday Weekday AND
• actualHours + tolerance(0.5) < expectedHours
Business Logic:
Employees should work their expected hours unless on approved leave. Small discrepancies within tolerance (0.5h) are allowed for rounding.

Example:
Date: Feb 8 (Mon) | actual: 7.5h, expected: 9.0h → 7.5+0.5=8.0<9.0 → Error
dispDate & " Hours mismatch actual " & Format(actualHours,"0.0") & "h expected " & Format(expectedHours,"0.0") & "h" Done
6 OT not allowed (no OT eligibility) Weekday Weekday AND
• actualHours ≤ expectedHours + tolerance
• OT (G) > 0
Business Logic:
Overtime is only permitted when actual hours exceed expected hours + tolerance. Working exactly expected hours = no OT allowed.

Example:
Date: Jan 22 (Mon) | actual: 9.0h, expected: 9.0h, OT: 1.0h → Error
dispDate & " OT not allowed actual " & Format(actualHours,"0.0") & "h expected " & Format(expectedHours,"0.0") & "h OT(col G)=" & Format(otFromCol,"0.0") & "h" Done
7 OT miscalculation (1-hour buffer) Weekday Weekday AND
• actualHours > expectedHours
• calcOT = MAX(0, actual - expected - 1)
• calcOT ≠ OT in col G
Business Logic - 1-hour buffer rule:
Employees must work >1 hour beyond expected hours before OT is counted.
• actual - expected ≤ 1h → No OT allowed
• actual - expected > 1h → OT = excess hours - 1

Example:
Date: Feb 3 (Wed) | actual: 11.0h, expected: 9.0h, OT(G): 2.0h, calcOT: 11-9-1=1.0h → Error
dispDate & " OT miscalculation actual " & Format(actualHours,"0.0") & "h expected " & Format(expectedHours,"0.0") & "h OT(col G)=" & Format(otFromCol,"0.0") & "h OT(calc)=" & Format(calcOT,"0.0") & "h (OT = hours - 1)" Done
8 Late coming (time-based) Weekday Weekday AND
• C filled AND D filled
• startTime > scheduledStartTime + 15min
Business Logic:
Employees arriving later than scheduled start time + 15min tolerance are marked as late. Requires employee schedule data.

Example:
Date: Jan 10 (Mon) | Scheduled: 09:00, Actual: 09:25 → 09:25>09:15 → Error

⚠️ Status: Not started - requires employee schedule data
dispDate & " Late coming start " & Format(startTime,"hh:nn") Pending
9 Early leave (time-based) Weekday Weekday AND
• C filled AND D filled
• endTime < scheduledEndTime - 15min
Business Logic:
Employees leaving earlier than scheduled end time - 15min tolerance are marked as early departure. Requires employee schedule data.

Example:
Date: Jan 15 (Mon) | Scheduled: 18:00, Actual: 17:30 → 17:30<17:45 → Error

⚠️ Status: Not started - requires employee schedule data
dispDate & " Early leave end " & Format(endTime,"hh:nn") Pending
10 Short hours (possible early leave/late coming) Weekday Weekday AND
• C filled AND D filled
• actualHours + tolerance < expectedHours
Business Logic:
When hours worked are significantly less than expected (beyond 0.5h tolerance), it suggests late arrival or early departure. This flags for manager review.

Example:
Date: Feb 12 (Fri) | actual: 7.0h, expected: 9.0h → Error (warning)
dispDate & " Working hours less than standard (possible early leave/late coming) actual " & Format(actualHours,"0.0") & "h expected " & Format(expectedHours,"0.0") & "h" Done
11 Saturday leave without reason (5.5-day staff) Saturday Saturday AND 5.5-day employee AND
• 0 < actualHours ≤ 4
• actualHours < expectedHours
• Remarks NOT contain leave types
Business Logic:
5.5-day employees are expected to work Saturdays (typically 4 hours). Partial hours without valid leave explanation require justification.

Example:
Date: Jan 11 (Sat) | Type: 5.5-day, expected: 4.0h, actual: 2.5h, Remarks: "Personal matters" → Error
dispDate & " - Sat leave without reason (5.5-day staff) actual " & Format(actualHours,"0.0") & "h expected " & Format(expectedHours,"0.0") & "h" Done
12 Saturday OT after 5.5 days (4h+ only) Saturday Part A: Sat AND 5.5-day AND
• C/D filled, weeklyDays>5.5, hrs≥4

Part B: Sat AND 5.5-day AND
• actualHours > 4
• calcOT = actualHours - 4
• calcOT ≠ OT in col G
Business Logic - Saturday OT Rule:
• First 4 hours = regular working hours
• Hours beyond 4 = overtime
• OT only counted if worked >5.5 days that week
• Formula: Saturday OT = actualHours - 4

Example:
Date: Jan 18 (Sat) | Type: 5.5-day, actual: 6.0h, OT(G): 2.5h, calcOT: 6.0-4.0=2.0h → Error
Part A:
dispDate & " Saturday OT hours=" & Format(actualHours,"0.0") & "h (after 5.5 days rule)"

Part B:
dispDate & " - Sat OT miscalculation (5.5-day staff) actual " & Format(actualHours,"0.0") & "h OT(col G)=" & Format(otFromCol,"0.0") & "h OT(calc)=" & Format(satOT,"0.0") & "h (OT = hours - 4)"
Done
13 Sunday/PH hours mismatch Sunday/PH (Sunday OR Public Holiday) AND
• C filled AND D filled
• E is numeric AND E ≠ (D-C)×24
OR
• At least one of E or G filled
• NOT (C-D = E = G)
Business Logic - Sunday/PH work rule:
• All hours worked = OT (no "regular hours")
• C-D = E = G (all three must match)
• If employee works 5 hours on PH, all 5 hours should be in both E and G

Example:
Date: Jan 1 (Sun-PH) | C: 10:00, D: 15:00, actual: 5.0h, E: 5.0h, G: 4.5h → Error
Version 1:
dispDate & " Public Holiday hours mismatch C-D=" & Format(actualHours,"0.0") & "h E=" & Format(vE,"0.0") & "h G=" & Format(vG,"0.0") & "h"

Version 2:
dispDate & " - Public Holiday hours mismatch C-D=" & Format(actualHours,"0.0") & "h E=" & Format(CDbl(colE),"0.0") & "h"
Done
14 Sunday/PH no work, no issue Sunday/PH (Sunday OR Public Holiday) AND
• C = Empty
• D = Empty
Business Logic:
Sundays and public holidays are rest days. No work = no error.

Example:
Date: Jan 1 (Sun-New Year) | C/D: Empty → OK ✅ (no error)
(No remark) Done
15 Leave marked on rest day (warning) Sunday/PH (Sunday OR Public Holiday) AND
• Remarks contain any leave type:
  AL/SL/CL/ML/PL/NPL/NPSL
Business Logic:
Leave types shouldn't be marked on Sundays/Public Holidays since these are already non-working days. This is a WARNING to prevent accidental leave deduction.

Example:
Date: Jan 1 (Sun-New Year) | Remarks: "AL" → Warning: "Jan 1 - AL marked on rest day (Sun/PH)"

6 different messages: One for each leave type (AL, SL, CL, ML, PL, NPL)
dispDate & " - AL marked on rest day (Sun/PH)"
dispDate & " - SL marked on rest day (Sun/PH)"
dispDate & " - CL marked on rest day (Sun/PH)"
dispDate & " - ML marked on rest day (Sun/PH)"
dispDate & " - PL marked on rest day (Sun/PH)"
dispDate & " - NPL marked on rest day (Sun/PH)"
(6 different messages based on leave type)
Done