Skip to main content

Function: computeCatchupCentavos()

computeCatchupCentavos(svc, companyId, contractorId, assignmentId, period, newByDate): Promise<number>

Defined in: src/server/services/catchupPay.ts:40

The marginal pay that applying newByDate (the new per-date hours) would earn in their own (already-paid) bi-monthly period: pay(baseline overlaid with newByDate) − pay(baseline), using the same engine + inputs as a real run with the proration cap respected (so hours in a week already at 100% add nothing). Must be called BEFORE the new entries are persisted, so the existing payable set is the baseline. Returns 0 when the period can't be priced (no rate / no contracted hours).

The pay engine is consulted with the assignment's bi-monthly rate, the contractor type (outsourced default; in_house_admin also folds in approved holiday leave), the holidays config, and the set of approved overage weeks for this assignment (translated from the stored Sunday billing week to the engine's Monday ISO week). Existing entries are read from the period's settling-week range and counted only when their status is in PAYABLE_ENTRY_STATUSES.

Parameters

svc

SupabaseClient

Service-role Supabase client (bypasses RLS); all queries are still scoped by companyId.

companyId

string

Tenant scope applied to every query.

contractorId

string

Contractor whose leave and overage approvals are loaded.

assignmentId

string

Contractor↔facility assignment supplying the rate, contracted hours, and effective/end dates.

period

BiMonthlyPeriod

Bi-monthly pay period to price (billing weeks are Sunday-anchored; the pay engine keys on Monday ISO weeks).

newByDate

Map<string, number>

New per-date hours, keyed by entry_date (ISO YYYY-MM-DD); each key OVERWRITES (does not add to) the baseline hours for that date.

Returns

Promise<number>

Non-negative marginal pay in integer centavos (clamped at 0); 0 if the assignment/rate is missing or the engine cannot price the period.

Throws

DateError on a malformed stored date (assignment effective/end date); throws from the Centavos guard if a stored bimonthly_rate_centavos is non-integer.