import { err, ok } from "@tailor-platform/erp-kit/core"; import { CompanyNotFoundError, NameRequiredError, InvalidDateRangeError, DatesImmutableError, HasAssociatedPeriodsError, } from "../lib/errors.generated"; export interface FiscalYear { readonly id: string; readonly companyId: string; readonly name: string; readonly startDate: Date; readonly endDate: Date; readonly yearEndCloseExecuted: boolean; } export interface CreateFiscalYearInput { companyId: string; name: string; startDate: Date; endDate: Date; } export interface UpdateFiscalYearInput { id: string; yearName?: string; startDate?: Date; endDate?: Date; } export function create>( input: CreateFiscalYearInput & CF, refs: { companyExists: boolean }, ) { if (!refs.companyExists) return err(new CompanyNotFoundError(input.companyId)); if (!input.name || input.name.trim() === "") return err(new NameRequiredError(input.companyId)); if (input.startDate >= input.endDate) return err(new InvalidDateRangeError(input.companyId)); const { companyId, name, startDate, endDate, ...customFields } = input; return ok({ ...customFields, companyId, name, startDate, endDate, yearEndCloseExecuted: false }); } export function update>( existing: FiscalYear, input: UpdateFiscalYearInput & Partial, refs: { periodsExist: boolean }, ) { const { id, yearName, startDate, endDate, ...customFields } = input; const validName = validateNameChange(id, yearName); if (!validName.ok) return validName; if (startDate !== undefined || endDate !== undefined) { if (refs.periodsExist) return err(new DatesImmutableError(id)); if ((startDate ?? existing.startDate) >= (endDate ?? existing.endDate)) return err(new InvalidDateRangeError(id)); } return ok({ ...customFields, ...(yearName !== undefined ? { name: yearName } : {}), ...(startDate !== undefined ? { startDate } : {}), ...(endDate !== undefined ? { endDate } : {}), }); } export function checkDeletable(id: string, hasPeriods: boolean) { return hasPeriods ? err(new HasAssociatedPeriodsError(id)) : ok({}); } export function validateNameChange(id: string, name: string | undefined) { return name !== undefined && name.trim() === "" ? err(new NameRequiredError(id)) : ok({}); }