import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { InvalidLegalNameError, CurrencyNotFoundError } from "../lib/errors.generated"; import type { PrimitivesQueries } from "../module"; export interface CreateCompanyInput { legalName: string; baseCurrencyId?: string; taxId?: string; registrationNumber?: string; street?: string; city?: string; state?: string; postalCode?: string; country?: string; } /** * Function: createCompany * * Establishes a new legal entity in the system in DRAFT status. Accepts the * company's legal name, and optionally tax identification, registration number, * base currency, and registered address fields. */ export async function run>( db: Transaction, input: CreateCompanyInput & CF, ctx: CommandContext, primitivesQueries?: Pick, ) { const { legalName, baseCurrencyId, taxId, registrationNumber, street, city, state, postalCode, country, ...customFields } = input; // 1. Validate legalName non-empty if (!legalName || legalName.trim() === "") { return err(new InvalidLegalNameError(String(legalName))); } // 2. If baseCurrencyId provided, validate currency exists and is active if (baseCurrencyId && primitivesQueries) { const { currency } = (await primitivesQueries.getCurrency(db, { id: baseCurrencyId }, ctx)) .value; if (currency?.status !== "ACTIVE") { return err(new CurrencyNotFoundError(baseCurrencyId)); } } // 3. Insert with status DRAFT const company = await db .insertInto("Company") .values({ ...(customFields as Record), legalName, baseCurrencyId: baseCurrencyId ?? null, taxId: taxId ?? null, registrationNumber: registrationNumber ?? null, street: street ?? null, city: city ?? null, state: state ?? null, postalCode: postalCode ?? null, country: country ?? null, status: "DRAFT", }) .returningAll() .executeTakeFirstOrThrow(); return ok({ company }); }