Attendance Calculation Examples
Step-by-step worked examples showing how overtime and penalties are calculated in real scenarios.
Attendance Calculation Examples
Step-by-step worked examples showing how overtime and penalties are calculated in real scenarios.
Example 1: Standard Overtime Calculation
Tenant: i90042721 (Pilot) Employee: Azman Bin Hussin Date: January 9, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Template | "7.30AM" |
| Shift Time | 07:30 - 16:00 |
| Working Hours | 7.5 hours |
| OvertimeClockOutBuffer | 30 minutes |
| OvertimeBlockMode | Floor |
| OvertimeMinuteBlock | 60 minutes |
| OvertimeStrategy | DailyPayFactor |
| OvertimeFactor | 1.5× |
| Daily Wage | RM 98.10 |
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 07:18 |
| Clock Out | 18:05 |
| Break | 60 minutes |
Step-by-Step Calculation
Step 1: Calculate Raw Overtime After Shift
Shift End Time = 16:00
Actual Clock Out = 18:05
Raw OT After = 18:05 - 16:00 = 2 hours 5 minutes (125 minutes)
Step 2: Calculate Raw Overtime Before Shift
Shift Start Time = 07:30
Actual Clock In = 07:18
Raw OT Before = 07:30 - 07:18 = 12 minutes
Step 3: Apply OT Buffer
OvertimeClockOutBuffer = 30 minutes
After Shift: 125 min ≥ 30 min buffer ✓ (counts)
OvertimeClockInBuffer = null (not set)
Before Shift: 12 min → counts as OT (no buffer)
Step 4: Block/Round Overtime (Floor Mode)
Total Raw OT = 125 + 12 = 137 minutes
Block Size = 60 minutes
Blocks = Floor(137 / 60) = 2 blocks
Chunked OT = 2 × 60 = 120 minutes = 2:00:00
Step 5: Calculate Hourly Rate
Daily Wage = RM 98.10
Working Hours = 7.5 hours
Hourly Rate = RM 98.10 / 7.5 = RM 13.08
Step 6: Calculate OT Earnings
OT Hours = 2.0
Hourly Rate = RM 13.08
OT Factor = 1.5 (not applied to OvertimeEarned directly)
OT Earned = RM 13.08 × 2.0 hours = RM 26.16
Result
| Item | Value |
|---|---|
| Raw Overtime | 2:17:00 |
| Chunked Overtime | 2:00:00 |
| OT Earnings | RM 26.16 |
Example 2: Simple Late Arrival Penalty (DailyRate)
Tenant: i90042721 (Pilot) Employee: Muhamad Firdaus Date: January 25, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Template | "7.30AM" |
| Shift Time | 07:30 - 16:00 |
| PenaltyClockInBuffer | 5 minutes |
| ClockInDeductionMode | DailyRate |
| NormalHourlyRate | RM 8.75 |
| PenaltyBlockMode | Floor |
| PenaltyMinuteBlock | null |
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 07:35:07 |
| Clock Out | 16:00 |
Step-by-Step Calculation
Step 1: Calculate Lateness
Shift Start = 07:30:00
Actual Clock In = 07:35:07
Late By = 5 minutes 7 seconds (5.12 minutes)
Step 2: Apply Buffer
PenaltyClockInBuffer = 5 minutes
Effective Late = 5.12 - 5 = 0.12 minutes (7 seconds)
Step 3: Calculate Rate (DailyRate Mode)
DailyRate mode uses: NormalHourlyRate / 60 per minute
Rate = RM 8.75 / 60 = RM 0.146 per minute
Step 4: Calculate Penalty
Late Minutes (after buffer) = 0.12 minutes
Penalty = 0.12 × RM 0.146 = RM 0.02
Rounded to 2 decimal places = RM 0.02
Result
| Item | Value |
|---|---|
| Late By | 5:07 |
| Effective Late (after buffer) | 0:07 |
| Clock In Penalty | RM 0.02 |
Note: In practice, such small penalties may be negligible.
Example 3: Tiered Late Penalty
Tenant: Kaewta (AppStafyCoTh) Employee: Somchai Date: January 15, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Template | "Morning" |
| Shift Time | 08:45 - 19:45 |
| ClockInDeductionMode | OneTime |
| Tiered Penalties | Configured |
Tiered Penalty Configuration: | Tier | Range | Penalty | |------|-------|---------| | Tier 1 | 1 - 15 minutes | RM 10.00 | | Tier 2 | 16 - 45 minutes | RM 30.00 | | Tier 3 | 46+ minutes | RM 50.00 |
Scenario A: 10 Minutes Late
Actual Clock In: 08:55 (10 minutes late)
Calculation:
Late By = 10 minutes
Matching Tier = Tier 1 (1-15 min range)
Penalty = RM 10.00
Result: RM 10.00 penalty
Scenario B: 30 Minutes Late
Actual Clock In: 09:15 (30 minutes late)
Calculation:
Late By = 30 minutes
Matching Tier = Tier 2 (16-45 min range)
Penalty = RM 30.00
Result: RM 30.00 penalty
Scenario C: 75 Minutes Late
Actual Clock In: 10:00 (75 minutes late)
Calculation:
Late By = 75 minutes
Matching Tier = Tier 3 (46+ min range)
Penalty = RM 50.00
Result: RM 50.00 penalty
Example 4: Break Penalty (FixedPerBlock)
Tenant: MrPa (AppStafyCoTh) Employee: Nattapong Date: January 20, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Template | "Shop 3 - A" |
| MaxBreakLengthInMinutes | 60 |
| BreakDeductionMode | FixedPerBlock |
| BreakDeductionRate | RM 1.00 |
| PenaltyMinuteBlock | 1 |
| PenaltyBreakBuffer | null |
Actual Attendance
| Event | Time |
|---|---|
| Clock In | 09:00 |
| Break Start | 12:00 |
| Break End | 13:12 |
| Clock Out | 18:00 |
Step-by-Step Calculation
Step 1: Calculate Break Duration
Break Start = 12:00
Break End = 13:12
Break Duration = 1 hour 12 minutes = 72 minutes
Step 2: Calculate Break Excess
Allowed Break = 60 minutes
Actual Break = 72 minutes
Break Excess = 72 - 60 = 12 minutes
Step 3: Apply Buffer
PenaltyBreakBuffer = null (not set)
Effective Excess = 12 minutes
Step 4: Calculate Blocks
PenaltyMinuteBlock = 1 minute
Blocks = Floor(12 / 1) = 12 blocks
Step 5: Calculate Penalty
Rate = RM 1.00 per block
Penalty = 12 blocks × RM 1.00 = RM 12.00
Result
| Item | Value |
|---|---|
| Break Duration | 1:12:00 |
| Allowed Break | 1:00:00 |
| Break Excess | 0:12:00 |
| Break Penalty | RM 12.00 |
Example 5: Early Departure Penalty (DailyRate)
Employee: Lee Date: January 22, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Time | 09:00 - 18:00 |
| ClockOutDeductionMode | DailyRate |
| NormalHourlyRate | RM 12.50 |
| PenaltyClockOutBuffer | 5 minutes |
| PenaltyBlockMode | Floor |
| PenaltyMinuteBlock | 5 |
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 09:00 |
| Clock Out | 17:42 |
Step-by-Step Calculation
Step 1: Calculate Early Departure
Shift End = 18:00
Actual Clock Out = 17:42
Early By = 18 minutes
Step 2: Apply Buffer
PenaltyClockOutBuffer = 5 minutes
Effective Early = 18 - 5 = 13 minutes (buffer doesn't work this way)
Actually: 18 min ≥ 5 min buffer, so penalty applies
Step 3: Block the Time
PenaltyMinuteBlock = 5 minutes
Blocks = Floor(18 / 5) = 3 blocks (15 minutes)
Step 4: Calculate Rate
DailyRate: Rate = NormalHourlyRate / 60
Rate = RM 12.50 / 60 = RM 0.208 per minute
Step 5: Calculate Penalty
Penalized Minutes = 3 blocks × 5 min = 15 minutes
Penalty = 15 × RM 0.208 = RM 3.12
Result
| Item | Value |
|---|---|
| Early By | 0:18:00 |
| Blocked Time | 0:15:00 |
| Clock Out Penalty | RM 3.12 |
Example 6: Combined Scenario (Late + OT + Break Excess)
Employee: Ahmad Date: January 18, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Time | 08:00 - 17:00 |
| Working Hours | 8 hours |
| AllowedBreakMinutes | 60 |
| NormalHourlyRate | RM 10.00 |
| OvertimeHourlyRate | RM 15.00 |
| ClockInDeductionMode | FixedPerBlock |
| ClockInDeductionRate | RM 2.00 |
| BreakDeductionMode | FixedPerBlock |
| BreakDeductionRate | RM 1.00 |
| PenaltyMinuteBlock | 5 |
| OvertimeMinuteBlock | 30 |
| OvertimeBlockMode | Floor |
| OvertimeClockOutBuffer | 15 |
| PenaltyClockInBuffer | 5 |
Actual Attendance
| Event | Time |
|---|---|
| Clock In | 08:12 |
| Break Start | 12:00 |
| Break End | 13:08 |
| Clock Out | 18:25 |
Step-by-Step Calculations
Part A: Late Arrival Penalty
Shift Start = 08:00
Actual Clock In = 08:12
Late By = 12 minutes
Buffer Check: 12 min > 5 min buffer ✓
Blocks = Floor(12 / 5) = 2 blocks
Penalty = 2 blocks × RM 2.00 = RM 4.00
Clock In Penalty: RM 4.00
Part B: Break Penalty
Allowed Break = 60 minutes
Actual Break = 68 minutes (1:08)
Excess = 8 minutes
Blocks = Floor(8 / 5) = 1 block
Penalty = 1 block × RM 1.00 = RM 1.00
Break Penalty: RM 1.00
Part C: Overtime Calculation
Shift End = 17:00
Actual Clock Out = 18:25
Raw OT = 1 hour 25 minutes = 85 minutes
Buffer Check: 85 min > 15 min buffer ✓
Blocks = Floor(85 / 30) = 2 blocks
Chunked OT = 2 × 30 = 60 minutes = 1 hour
OT Earned = 1.0 hour × RM 15.00 = RM 15.00
Overtime Earned: RM 15.00
Summary
| Item | Value |
|---|---|
| Clock In Penalty | RM 4.00 |
| Break Penalty | RM 1.00 |
| Clock Out Penalty | RM 0.00 |
| Total Penalty | RM 5.00 |
| Overtime Earned | RM 15.00 |
| Net Effect | +RM 10.00 |
Example 7: MaxPenalty Cap Applied
Employee: Wong Date: January 24, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Time | 09:00 - 18:00 |
| ClockInDeductionMode | FixedPerBlock |
| ClockInDeductionRate | RM 5.00 |
| PenaltyMinuteBlock | 5 |
| MaxPenalty | RM 50.00 |
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 10:30 |
| Clock Out | 15:00 |
Calculation
Late Penalty:
Late By = 90 minutes
Blocks = Floor(90 / 5) = 18 blocks
Raw Penalty = 18 × RM 5.00 = RM 90.00
Early Departure Penalty:
Early By = 180 minutes (3 hours)
Blocks = Floor(180 / 5) = 36 blocks
Raw Penalty = 36 × RM 5.00 = RM 180.00
Total Raw Penalty:
Total = RM 90.00 + RM 180.00 = RM 270.00
Apply MaxPenalty Cap:
MaxPenalty = RM 50.00
Applied Penalty = min(RM 270.00, RM 50.00) = RM 50.00
Result
| Item | Value |
|---|---|
| Raw Clock In Penalty | RM 90.00 |
| Raw Clock Out Penalty | RM 180.00 |
| Total Raw | RM 270.00 |
| MaxPenalty Cap | RM 50.00 |
| Final Penalty | RM 50.00 |
Example 8: Half-Day Leave Adjustment (AM)
Employee: Sarah Date: January 16, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Time | 09:00 - 18:00 |
| Working Hours | 8 hours |
| IsOnHalfDayLeave | true |
| HalfDayLeavePart | "AM" |
| PenaltyClockInBuffer | 5 |
Half-Day Adjustment
When on AM half-day leave, the shift start time is moved forward by half the working hours.
Original Shift Start = 09:00
Working Hours = 8 hours
Adjusted Shift Start = 09:00 + (8 / 2) = 13:00
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 13:10 |
| Clock Out | 18:00 |
Calculation
Adjusted Shift Start = 13:00
Actual Clock In = 13:10
Late By = 10 minutes
Buffer Check: 10 min > 5 min buffer ✓
Penalty applies on 10 minutes late
Result
Without half-day adjustment, Sarah would appear to be 4+ hours late (clocking in at 13:10 for a 09:00 shift). With the adjustment, she's correctly assessed as only 10 minutes late.
Example 9: Time-Off Slot Adjustment
Employee: John Date: January 21, 2026
Configuration
| Setting | Value |
|---|---|
| Shift Time | 09:00 - 18:00 |
| PenaltyClockInBuffer | 5 |
Approved Time-Off Slot
| Property | Value |
|---|---|
| Type | Start |
| Status | Approved |
| Starts | 09:00 |
| Ends | 10:00 |
Actual Attendance
| Time | Value |
|---|---|
| Clock In | 10:15 |
| Clock Out | 18:00 |
Without Time-Off Adjustment
Expected Clock In = 09:00
Actual Clock In = 10:15
Late By = 1 hour 15 minutes ❌
With Time-Off Adjustment
Original Shift Start = 09:00
Time-Off Slot (Type: Start) ends at = 10:00
Adjusted Shift Start = 10:00
Actual Clock In = 10:15
Late By = 15 minutes ✓
Result
The time-off slot adjustment correctly recognizes that John was only 15 minutes late (from 10:00, not from 09:00).
Example 10: Ceiling Block Mode Comparison
Employee: Test Case Configuration:
| Setting | Value |
|---|---|
| OvertimeMinuteBlock | 30 |
| OvertimeHourlyRate | RM 15.00 |
Raw Overtime: 47 minutes
With Floor Mode:
Blocks = Floor(47 / 30) = 1 block
Chunked OT = 30 minutes = 0.5 hours
OT Earned = 0.5 × RM 15.00 = RM 7.50
With Ceiling Mode:
Blocks = Ceiling(47 / 30) = 2 blocks
Chunked OT = 60 minutes = 1.0 hours
OT Earned = 1.0 × RM 15.00 = RM 15.00
Comparison
| Mode | Blocks | Chunked OT | Earnings |
|---|---|---|---|
| Floor | 1 | 0:30 | RM 7.50 |
| Ceiling | 2 | 1:00 | RM 15.00 |
Difference: RM 7.50 - Ceiling mode pays more for partial blocks.
Summary of Key Formulas
Overtime
Raw OT = (ActualClockOut - ShiftClockOut) + (ShiftClockIn - ActualClockIn)
Buffered OT = Apply buffer checks (set to 0 if under buffer)
Chunked OT = Block(Buffered OT, BlockMode, MinuteBlock)
OT Earned = ChunkedOT hours × OvertimeHourlyRate
Penalty (FixedPerBlock)
Late Time = ActualClockIn - ShiftClockIn
If Late Time > Buffer:
Blocks = BlockMode(Late Time / MinuteBlock)
Penalty = Blocks × DeductionRate
Else:
Penalty = 0
Penalty (DailyRate)
Rate = NormalHourlyRate / 60 (per minute)
Penalty = Late Minutes × Rate
Penalty (Tiered)
For each tier where StartMinutes <= LateMinutes <= EndMinutes:
If Mode == OneTime: Return tier.Rate
If Mode == Tiered: Accumulate tier.Rate per block
Total Penalty
Total = ClockInPenalty + ClockOutPenalty + BreakPenalty
Final = min(Total, MaxPenalty)