import { percentOfPay } from '../pay'; import { AdminTask, type CompanyLeaveProgramDefinitionConfig, type ParentalRelationship } from '../types'; import { weeks } from '../duration'; export interface ParentalTopUpPolicyOptions { code: string; displayName: string; description?: string; jurisdiction: { country: string; subdivisions?: string[]; }; appliesTo?: { employeeCountry?: string; }; qualifyingLeaveReasons: string[]; paidWeeksByParentalRelationship: Partial>; pay: { type: 'MAKE_WHOLE_TOPUP'; targetPercentOfPay: number; offsetByPrograms: string[]; earningType?: string; }; requirements?: Array; leaveType?: string; } export function parentalTopUpPolicy( options: ParentalTopUpPolicyOptions, ): CompanyLeaveProgramDefinitionConfig { const requirements = options.requirements ?? [ AdminTask.ManagerAcknowledgement, AdminTask.PaymentRecordReconciliation, AdminTask.SeparateFromJobProtection, ]; const earningType = options.pay.earningType ?? 'EMPLOYER_TOPUP_MAKE_WHOLE'; const leaveType = options.leaveType ?? 'EMPLOYER_PARENTAL_TOPUP'; const paidWeeksByRelationship = options.paidWeeksByParentalRelationship; const employeeCountry = options.appliesTo?.employeeCountry; return { code: options.code, displayName: options.displayName, ...(options.description === undefined ? {} : { description: options.description }), jurisdiction: options.jurisdiction, dependsOn: options.pay.offsetByPrograms, ...(employeeCountry === undefined ? {} : { appliesTo: (context) => context.employee.country.is(employeeCountry) }), evaluate(context) { const paidLeaveCases = Object.fromEntries( Object.entries(paidWeeksByRelationship).map(([relationship, paidWeeks]) => [ relationship, weeks(paidWeeks ?? 0), ]), ); const builder = context .policy() .eligibleWhen(context.leave.reason.isOneOf(options.qualifyingLeaveReasons)) .requireKnown(context.pay.contractualWeeklyPay, { evidenceKey: 'weekly_wage', message: 'Contractual weekly pay is required to calculate company top-up.', }) .requireKnown(context.programs.wageReplacement(options.pay.offsetByPrograms), { evidenceKey: 'upstream_pay_rates', message: 'Statutory or insurance wage-replacement amounts are required to calculate company top-up.', }) .grantPaidLeave(context.leave.parentalRelationship.match(paidLeaveCases), { leaveType }) .topUpTo(percentOfPay(options.pay.targetPercentOfPay), { base: context.pay.contractualWeeklyPay, offsetBy: context.programs.wageReplacement(options.pay.offsetByPrograms), earningType, }) .doesNotProvideJobProtection(); for (const requirement of requirements) { builder.requireAdminTask(requirement); } return builder.build(); }, }; }