85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
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),
|
|
);
|
|
}
|