import { createContext, DomainError } from "@tailor-platform/erp-kit/app"; import { createResolver, t } from "@tailor-platform/sdk"; import { getDB } from "@/generated/kysely-tailordb"; import { finModulesExport } from "@/modules"; /** * createFiscalYear — define a fiscal year (会計年度) for a company. * * Thin wrapper over the native `createFiscalYear`. The end date must be strictly * after the start date and the range must not overlap an existing fiscal year * for the same company. */ export default createResolver({ name: "createFiscalYear", operation: "mutation", input: { companyId: t.string().description("Company the fiscal year belongs to"), name: t.string().description("Fiscal year name (e.g. FY2026)"), startDate: t.string().description("Start date (YYYY-MM-DD)"), endDate: t.string().description("End date (YYYY-MM-DD); must be after the start date"), }, body: async (context) => { const ctx = createContext(context); const db = getDB("main-db"); return db .transaction() .execute(async (trx) => { const result = await finModulesExport.commands.createFiscalYear( trx, { companyId: context.input.companyId, name: context.input.name, startDate: new Date(context.input.startDate), endDate: new Date(context.input.endDate), }, ctx, ); if (!result.ok) { switch (result.error.code) { case "FINANCIAL_ACCOUNTING_COMPANY_NOT_FOUND": throw new DomainError(`Company not found: ${context.input.companyId}`); case "FINANCIAL_ACCOUNTING_NAME_REQUIRED": throw new DomainError("Fiscal year name must not be empty."); case "FINANCIAL_ACCOUNTING_INVALID_DATE_RANGE": throw new DomainError("The end date must be after the start date."); case "FINANCIAL_ACCOUNTING_OVERLAPPING_FISCAL_YEAR": throw new DomainError( "The date range overlaps an existing fiscal year for this company.", ); case "UNAUTHENTICATED": throw new DomainError("Authentication is required"); case "INSUFFICIENT_PERMISSION": throw new DomainError("You do not have permission to perform this action"); default: throw result.error satisfies never; } } return { id: result.value.fiscalYear.id, name: result.value.fiscalYear.name, }; }) .catch((err: unknown) => { if (err instanceof DomainError) throw err; throw new Error("Failed to create the fiscal year", { cause: err }); }); }, output: t .object({ id: t.string().description("Fiscal year ID"), name: t.string().description("Fiscal year name"), }) .description("CreateFiscalYear response"), });