121 lines
4.0 KiB
TypeScript
121 lines
4.0 KiB
TypeScript
import { Prisma, VacationType } from "@capakraken/db";
|
|
import type { TRPCContext } from "../trpc.js";
|
|
import { loadResourceHolidayContext } from "./resource-holiday-context.js";
|
|
import { countVacationChargeableDays } from "./vacation-day-count.js";
|
|
|
|
export const VACATION_BALANCE_TYPES = new Set<VacationType>([
|
|
VacationType.ANNUAL,
|
|
VacationType.OTHER,
|
|
]);
|
|
|
|
export type VacationChargeableInput = {
|
|
resourceId: string;
|
|
type: VacationType;
|
|
startDate: Date;
|
|
endDate: Date;
|
|
isHalfDay: boolean;
|
|
};
|
|
|
|
export type VacationDeductionSnapshot = {
|
|
deductedDays: number;
|
|
holidayCountryCode: string | null;
|
|
holidayCountryName: string | null;
|
|
holidayFederalState: string | null;
|
|
holidayMetroCityName: string | null;
|
|
holidayCalendarDates: string[];
|
|
holidayLegacyPublicHolidayDates: string[];
|
|
};
|
|
|
|
type VacationSnapshotCarrier = {
|
|
deductedDays?: number | null;
|
|
holidayCountryCode?: string | null;
|
|
holidayFederalState?: string | null;
|
|
holidayMetroCityName?: string | null;
|
|
holidayCalendarDates?: Prisma.JsonValue | null;
|
|
holidayLegacyPublicHolidayDates?: Prisma.JsonValue | null;
|
|
startDate: Date;
|
|
endDate: Date;
|
|
isHalfDay: boolean;
|
|
};
|
|
|
|
function isStringArray(value: unknown): value is string[] {
|
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
}
|
|
|
|
export function parseVacationSnapshotDateList(value: Prisma.JsonValue | null | undefined): string[] {
|
|
return isStringArray(value) ? [...value].sort() : [];
|
|
}
|
|
|
|
export async function calculateVacationDeductionSnapshot(
|
|
db: TRPCContext["db"],
|
|
vacation: VacationChargeableInput,
|
|
): Promise<VacationDeductionSnapshot> {
|
|
const holidayContext = await loadResourceHolidayContext(
|
|
db,
|
|
vacation.resourceId,
|
|
vacation.startDate,
|
|
vacation.endDate,
|
|
);
|
|
|
|
return {
|
|
deductedDays: countVacationChargeableDays({
|
|
vacation,
|
|
countryCode: holidayContext.countryCode,
|
|
federalState: holidayContext.federalState,
|
|
metroCityName: holidayContext.metroCityName,
|
|
calendarHolidayStrings: holidayContext.calendarHolidayStrings,
|
|
publicHolidayStrings: holidayContext.publicHolidayStrings,
|
|
}),
|
|
holidayCountryCode: holidayContext.countryCode ?? null,
|
|
holidayCountryName: holidayContext.countryName ?? null,
|
|
holidayFederalState: holidayContext.federalState ?? null,
|
|
holidayMetroCityName: holidayContext.metroCityName ?? null,
|
|
holidayCalendarDates: [...holidayContext.calendarHolidayStrings].sort(),
|
|
holidayLegacyPublicHolidayDates: [...holidayContext.publicHolidayStrings].sort(),
|
|
};
|
|
}
|
|
|
|
export function buildVacationDeductionSnapshotWriteData(
|
|
snapshot: VacationDeductionSnapshot,
|
|
): {
|
|
deductedDays: number;
|
|
holidayCountryCode: string | null;
|
|
holidayCountryName: string | null;
|
|
holidayFederalState: string | null;
|
|
holidayMetroCityName: string | null;
|
|
holidayCalendarDates: Prisma.InputJsonValue;
|
|
holidayLegacyPublicHolidayDates: Prisma.InputJsonValue;
|
|
} {
|
|
return {
|
|
deductedDays: snapshot.deductedDays,
|
|
holidayCountryCode: snapshot.holidayCountryCode,
|
|
holidayCountryName: snapshot.holidayCountryName,
|
|
holidayFederalState: snapshot.holidayFederalState,
|
|
holidayMetroCityName: snapshot.holidayMetroCityName,
|
|
holidayCalendarDates: snapshot.holidayCalendarDates as unknown as Prisma.InputJsonValue,
|
|
holidayLegacyPublicHolidayDates:
|
|
snapshot.holidayLegacyPublicHolidayDates as unknown as Prisma.InputJsonValue,
|
|
};
|
|
}
|
|
|
|
export function countVacationChargeableDaysFromSnapshot(
|
|
vacation: VacationSnapshotCarrier,
|
|
periodStart?: Date,
|
|
periodEnd?: Date,
|
|
): number | null {
|
|
if (vacation.deductedDays == null) {
|
|
return null;
|
|
}
|
|
|
|
return countVacationChargeableDays({
|
|
vacation,
|
|
periodStart,
|
|
periodEnd,
|
|
countryCode: vacation.holidayCountryCode,
|
|
federalState: vacation.holidayFederalState,
|
|
metroCityName: vacation.holidayMetroCityName,
|
|
calendarHolidayStrings: parseVacationSnapshotDateList(vacation.holidayCalendarDates),
|
|
publicHolidayStrings: parseVacationSnapshotDateList(vacation.holidayLegacyPublicHolidayDates),
|
|
});
|
|
}
|