import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { DuplicateHolidayDateError, HolidayNotFoundError, InvalidHolidayKindError, } from "../lib/errors.generated"; const HOLIDAY_KINDS = ["STATUTORY", "PRESCRIBED"] as const; export type UpdateCompanyHolidayInput = { id: string; } & { holidayDate?: Date; holidayKind?: string; name?: string; }; /** * Function: updateCompanyHoliday * Description: Corrects a previously registered holiday's name or * holidayKind (or holidayDate) in place. Because CompanyHoliday is a plain * dated fact rather than an effective-dated series, the correction edits * the existing record directly instead of closing a generation. */ export async function run(db: Transaction, input: UpdateCompanyHolidayInput, _ctx: CommandContext) { const companyHoliday = await db .selectFrom("CompanyHoliday") .selectAll() .where("id", "=", input.id) .forUpdate() .executeTakeFirst(); if (!companyHoliday) { return err(new HolidayNotFoundError(input.id)); } if ( input.holidayKind !== undefined && !(HOLIDAY_KINDS as readonly string[]).includes(input.holidayKind) ) { return err(new InvalidHolidayKindError(input.holidayKind)); } if ( input.holidayDate !== undefined && input.holidayDate.getTime() !== companyHoliday.holidayDate.getTime() ) { const duplicate = await db .selectFrom("CompanyHoliday") .selectAll() .where("calendarId", "=", companyHoliday.calendarId) .where("holidayDate", "=", input.holidayDate) .where("id", "!=", input.id) .forUpdate() .executeTakeFirst(); if (duplicate) { return err( new DuplicateHolidayDateError( `${companyHoliday.calendarId}:${input.holidayDate.toISOString()}`, ), ); } } const updates: { holidayDate?: Date; holidayKind?: (typeof HOLIDAY_KINDS)[number]; name?: string; } = {}; if (input.holidayDate !== undefined) updates.holidayDate = input.holidayDate; if (input.holidayKind !== undefined) updates.holidayKind = input.holidayKind as (typeof HOLIDAY_KINDS)[number]; if (input.name !== undefined) updates.name = input.name; const updated = await db .updateTable("CompanyHoliday") .set(updates) .where("id", "=", input.id) .returningAll() .executeTakeFirstOrThrow(); return ok({ companyHoliday: updated }); }