32. Pay perks: opt-in eligibility + 13th-month disbursement
Date: 2026-06-14
Status
Accepted
Context
13th-month pay (PD 851) and a health allowance are perks that apply to some contractors, by
employer decision — not automatically to everyone. The payroll engine (computePayRun) is sensitive
and well-tested; we wanted to add 13th-month without modifying its core path. The owner specified the
13th-month disbursement schedule: two tranches, in the 16–30 November run and the 1–15
December run. New hires must default to not eligible.
Decision
- Opt-in eligibility flags (default off). Migration
0029addscontractors.thirteenth_month_eligibleandhealth_allowance_eligible(not null default false). A contractor is ineligible until an admin (owner) checks the box on the contractor detail page ("Pay eligibility") or in the hire flow. Existing contractors become ineligible — correct, since eligibility is granted explicitly. - 13th-month as an owner-triggered adjustment, not an engine change. On a prepared run whose
period is a tranche (16–30 Nov or 1–15 Dec), the owner clicks "Generate 13th-month". The action
computes each eligible contractor's entitlement = year-to-date basic ÷ 12 (
thirteenthMonthCentavosover theirpayments.base_amount_centavosfor the year), and writes the top-up to that entitlement as apayment_adjustment(kindallowance, label13th-month (tranche N)). November pays what's earned through November; December tops up to the full-year entitlement. Reusing the adjustment plumbing means the existing net-pay recompute, payment-lock, and payslip rendering all apply unchanged. It is idempotent per run and owner-reviewed before funding. - Health allowance: ₱20,000, added manually with a 6-month reminder. Unlike 13th-month, the
health allowance is not auto-computed — the admin adds it as a pay adjustment (kind
allowance, label "Health allowance",HEALTH_ALLOWANCE_CENTAVOS= ₱20,000). An eligible contractor becomes due 6 months after their hire date (healthAllowanceDueDate); the dashboard reminds the owner once that date passes and no health-allowance adjustment exists yet for them (the reminder clears once it's added). One-time per contractor.
Consequences
- The sensitive
computePayRun/closePeriodcore is untouched; 13th-month rides the audited adjustment path. - 13th-month is explicit + owner-controlled (a button per tranche run), not silent — the owner sees the amounts before funding. Re-running a tranche is a no-op for contractors already topped up.
- A contractor with no prior 13th who becomes eligible mid-year still gets the full YTD-based entitlement in the next tranche run.
src/db/types.tsgains the two flags; regenerate after further schema changes.