feat(platform): checkpoint current implementation state
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"use client";
|
||||
|
||||
export const HOLIDAY_SOURCE_LABELS = {
|
||||
CALENDAR: "Holiday Calendar",
|
||||
LEGACY_PUBLIC_HOLIDAY: "Legacy import",
|
||||
CALENDAR_AND_LEGACY: "Holiday Calendar + legacy",
|
||||
} as const;
|
||||
|
||||
export type VacationExplainabilityEntry = {
|
||||
startDate: Date | string;
|
||||
endDate: Date | string;
|
||||
isHalfDay?: boolean | null;
|
||||
deductedDays?: number | null;
|
||||
holidayCountryCode?: string | null;
|
||||
holidayCountryName?: string | null;
|
||||
holidayFederalState?: string | null;
|
||||
holidayMetroCityName?: string | null;
|
||||
holidayCalendarDates?: unknown;
|
||||
holidayLegacyPublicHolidayDates?: unknown;
|
||||
};
|
||||
|
||||
function toSortedDateList(value: unknown): string[] {
|
||||
return Array.isArray(value) && value.every((entry) => typeof entry === "string")
|
||||
? [...value].sort()
|
||||
: [];
|
||||
}
|
||||
|
||||
export function getRequestedDays(vacation: Pick<VacationExplainabilityEntry, "startDate" | "endDate" | "isHalfDay">): number {
|
||||
if (vacation.isHalfDay) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
const start = new Date(vacation.startDate);
|
||||
const end = new Date(vacation.endDate);
|
||||
return Math.round((end.getTime() - start.getTime()) / 86_400_000) + 1;
|
||||
}
|
||||
|
||||
export function getHolidayBasis(vacation: VacationExplainabilityEntry): string[] {
|
||||
return [
|
||||
vacation.holidayCountryName ?? vacation.holidayCountryCode ?? null,
|
||||
vacation.holidayFederalState ?? null,
|
||||
vacation.holidayMetroCityName ?? null,
|
||||
].filter((value): value is string => Boolean(value));
|
||||
}
|
||||
|
||||
export function getHolidayBreakdown(vacation: VacationExplainabilityEntry): Array<{ date: string; source: string }> {
|
||||
const calendarDates = toSortedDateList(vacation.holidayCalendarDates);
|
||||
const legacyDates = toSortedDateList(vacation.holidayLegacyPublicHolidayDates);
|
||||
const uniqueDates = [...new Set([...calendarDates, ...legacyDates])].sort();
|
||||
|
||||
return uniqueDates.map((date) => ({
|
||||
date,
|
||||
source:
|
||||
calendarDates.includes(date) && legacyDates.includes(date)
|
||||
? HOLIDAY_SOURCE_LABELS.CALENDAR_AND_LEGACY
|
||||
: calendarDates.includes(date)
|
||||
? HOLIDAY_SOURCE_LABELS.CALENDAR
|
||||
: HOLIDAY_SOURCE_LABELS.LEGACY_PUBLIC_HOLIDAY,
|
||||
}));
|
||||
}
|
||||
|
||||
export function buildVacationExplainabilityTooltip(
|
||||
vacation: VacationExplainabilityEntry & { type?: string | null },
|
||||
): string | null {
|
||||
const requestedDays = getRequestedDays(vacation);
|
||||
const deductedDays = typeof vacation.deductedDays === "number" ? vacation.deductedDays : null;
|
||||
const holidayBasis = getHolidayBasis(vacation);
|
||||
const holidayBreakdown = getHolidayBreakdown(vacation);
|
||||
const lines = [`Requested: ${requestedDays}d`];
|
||||
|
||||
if (deductedDays !== null) {
|
||||
lines.push(`Deducted: ${deductedDays}d`);
|
||||
}
|
||||
|
||||
if (holidayBasis.length > 0) {
|
||||
lines.push(`Holiday basis: ${holidayBasis.join(" / ")}`);
|
||||
}
|
||||
|
||||
if (holidayBreakdown.length > 0) {
|
||||
lines.push(`Excluded holidays: ${holidayBreakdown.map((holiday) => `${holiday.date} (${holiday.source})`).join(", ")}`);
|
||||
}
|
||||
|
||||
if ((vacation.type === "SICK" || vacation.type === "PUBLIC_HOLIDAY") && deductedDays === 0) {
|
||||
lines.push("Does not reduce annual vacation entitlement.");
|
||||
}
|
||||
|
||||
return lines.length > 0 ? lines.join("\n") : null;
|
||||
}
|
||||
Reference in New Issue
Block a user