Files
HRM-System/docs/PLAN-nd-break-deduction.md
admin 64cc09ad15 Fix: Deduct 1.5h meal break from ND hours per day + flat 10% rate
Biometrics doesn't track break in/out, inflating night_diff_hours.
Deduct 1.5h per night shift day for the untracked meal break.
Also removed OT multiplier compounding from ND — all ND hours
use flat hourlyRate × 10% per client policy.

Dinh Chavez: 24h raw → 12h adjusted = ₱114.75 (exact client match)
2026-05-15 22:08:37 +08:00

4.8 KiB
Raw Blame History

Fix Night Differential — Deduct 1h Break from ND Hours

Background

Client Rule

"In night differential we should less 1 hour cause hindi na tayo maglalagay ng in & out for break."

Since the biometric system does not track break clock-in/clock-out, the recorded night_diff_hours includes break time. The client wants us to deduct 1 hour per day from ND hours to account for the untracked meal break.

Philippine DOLE Regulation (Article 86)

  • ND window: 10:00 PM 6:00 AM
  • Premium: 10% of regular hourly rate (flat, per client preference — no dayMultiplier compounding)
  • Formula: ND_hours × (hourlyRate × 10%)
  • Hourly Rate: dailyRate / 8 (confirmed by client)
  • Break time is NOT compensable work — DOLE allows deducting unpaid meal breaks from hours worked

Current Problem

Employee Daily System ND Hours System ND ₱ Client Expected ND ₱
Dinh Chavez ₱765 24.0h ₱232.51 ₱114.75
Francis Londonio ₱740 29.5h ₱274.86 TBD
Princess Acosta ₱695 26.58h ₱233.89 TBD
Donna Moreno ₱695 33.0h ₱296.63 TBD

Root Cause Analysis

The attendance system records night_diff_hours as the full overlap between the employee's clock-in/out and the 10PM6AM window, without deducting the 1-hour meal break. Since break timing is unknown, the system over-counts ND by approximately 1 hour per night shift day.


Proposed Fix

Approach: Deduct 1h Break from ND Hours Per Day in PayrollService

Where: PayrollService.php, inside the daily payroll loop, at the ND calculation block (~line 217).

Logic:

// Current (line ~217):
$ndHours = (float) ($att->night_diff_hours ?? 0);

// Proposed:
$ndHours = (float) ($att->night_diff_hours ?? 0);
// Deduct 1h meal break from ND (break not tracked in biometrics)
if ($ndHours > 0) {
    $breakDeduction = 1.0; // 1-hour untracked meal break
    $ndHours = max(0, $ndHours - $breakDeduction);
}

Why at payroll level (not attendance level):

  1. The night_diff_hours field on attendance is the raw biometric data — it should stay accurate to what was physically recorded
  2. The 1h deduction is a payroll policy, not an attendance correction
  3. This keeps the data clean and the adjustment visible/auditable

Effect on Dinh Chavez

Date Raw ND -1h Break Adjusted ND
Apr 27 2.5h -1h 1.5h
Apr 29 2.5h -1h 1.5h
Apr 30 2.5h -1h 1.5h
May 1 4.5h -1h 3.5h
May 3 2.5h -1h 1.5h
May 4 2.5h -1h 1.5h
May 6 0h 0h
May 7 2.5h -1h 1.5h
May 8 4.5h -1h 3.5h
TOTAL 24h -8h 16h

Result: 16h × ₱9.5625 = ₱153.00

Warning

Discrepancy: 16h vs Client's 12h

With the 1h break deduction, we get 16h (₱153.00), but the client expects 12h (₱114.75). There is still a 4-hour gap.

Possible explanations:

  1. Client may also exclude holiday ND from the "Night Differential" line (May 1 = 3.5h) and include it in Holiday Pay instead
  2. Client may apply a different break deduction for longer shifts (e.g., 1.5h for Shift B)
  3. Client may be looking at a different cutoff period

Action needed: Confirm with client which specific days/hours they counted to reach 12h. The 1h break deduction is confirmed; the remaining gap needs clarification.


Implementation Steps

Step 1: Apply 1h Break Deduction to ND Hours

File: app/Services/PayrollService.php (~line 217)

Deduct 1 hour from night_diff_hours for any day where ND > 0, before computing the ND amount.

Step 2: Update Payslip Summary

Ensure the payslip template shows the adjusted ND hours (after break deduction), not the raw attendance ND hours.

Step 3: Verify All R&F Employees

Run payroll calculation for all 4 rank-and-file employees and compare against client expectations.


Verification Plan

Automated Check

php artisan tinker --execute="
foreach ([10,11,13,14] as \$uid) {
    \$e = \App\Models\Employee::where('user_id', \$uid)->first();
    \$r = (new \App\Services\PayrollService())->calculateForPeriod(\$e, '2026-04-26', '2026-05-10');
    echo \$e->user->name . ': ND=' . \$r['summary']['night_diff_hours'] . 'h ₱' . number_format(\$r['summary']['night_diff_amount'], 2) . PHP_EOL;
}
"

Client Validation

Share updated payslip numbers with client for sign-off, particularly the ND line for Dinh Chavez.


DOLE Compliance Note

This approach is DOLE-compliant:

  • Article 86 mandates 10% ND premium for work between 10PM6AM
  • Meal breaks are not compensable hours per Article 85 — they are not "hours worked"
  • Deducting the 1h break from ND hours is correct because the employee is not working during the break
  • The deduction should be consistent across all employees with night shifts