refactor(api): extract vacation chargeability helpers
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { countCalendarDaysInPeriod } from "../lib/vacation-day-count.js";
|
||||
import {
|
||||
VACATION_BALANCE_TYPES,
|
||||
buildVacationDeductionSnapshotWriteData,
|
||||
calculateVacationDeductionSnapshot,
|
||||
type VacationChargeableInput,
|
||||
} from "../lib/vacation-deduction-snapshot.js";
|
||||
import type { TRPCContext } from "../trpc.js";
|
||||
|
||||
type VacationDb = TRPCContext["db"];
|
||||
type VacationDeductionWriteData = ReturnType<typeof buildVacationDeductionSnapshotWriteData>;
|
||||
|
||||
export async function calculateVacationEffectiveDays(
|
||||
db: VacationDb,
|
||||
vacation: VacationChargeableInput,
|
||||
): Promise<number> {
|
||||
if (!VACATION_BALANCE_TYPES.has(vacation.type)) {
|
||||
return countCalendarDaysInPeriod(vacation);
|
||||
}
|
||||
|
||||
const snapshot = await calculateVacationDeductionSnapshot(db, vacation);
|
||||
return snapshot.deductedDays;
|
||||
}
|
||||
|
||||
export async function assertVacationStillChargeable(
|
||||
db: VacationDb,
|
||||
vacation: VacationChargeableInput,
|
||||
): Promise<void> {
|
||||
if (!VACATION_BALANCE_TYPES.has(vacation.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const effectiveDays = await calculateVacationEffectiveDays(db, vacation);
|
||||
if (effectiveDays <= 0) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Vacation no longer deducts any vacation days for the current holiday calendar and cannot be approved",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function resolveVacationCreationChargeability(
|
||||
db: VacationDb,
|
||||
vacation: VacationChargeableInput,
|
||||
): Promise<{
|
||||
effectiveDays: number | null;
|
||||
deductionSnapshotWriteData: VacationDeductionWriteData | null;
|
||||
}> {
|
||||
if (!VACATION_BALANCE_TYPES.has(vacation.type)) {
|
||||
return {
|
||||
effectiveDays: null,
|
||||
deductionSnapshotWriteData: null,
|
||||
};
|
||||
}
|
||||
|
||||
const deductionSnapshot = await calculateVacationDeductionSnapshot(db, vacation);
|
||||
const effectiveDays = deductionSnapshot.deductedDays;
|
||||
|
||||
if (effectiveDays <= 0) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Selected vacation period only contains public holidays and does not deduct any vacation days",
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
effectiveDays,
|
||||
deductionSnapshotWriteData: buildVacationDeductionSnapshotWriteData(deductionSnapshot),
|
||||
};
|
||||
}
|
||||
|
||||
export async function buildVacationApprovalWriteData(
|
||||
db: VacationDb,
|
||||
vacation: VacationChargeableInput,
|
||||
): Promise<VacationDeductionWriteData | { deductedDays: 0 }> {
|
||||
if (!VACATION_BALANCE_TYPES.has(vacation.type)) {
|
||||
return { deductedDays: 0 };
|
||||
}
|
||||
|
||||
return buildVacationDeductionSnapshotWriteData(
|
||||
await calculateVacationDeductionSnapshot(db, vacation),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user