import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import { workCenterLifecycle } from "../db/workCenter.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { WorkCenterNotFoundError, WorkCenterNotActivatableError, MissingCalendarContextError, InvalidCapacityError, InvalidRateError, OverheadCurrencyRequiredError, } from "../lib/errors.generated"; export interface ActivateWorkCenterInput { id: string; } /** * Function: activateWorkCenter * * Validates that a draft or inactive work center has the execution data * required by planning and costing, then marks it available for routing * and work-order use. */ export async function run(db: Transaction, input: ActivateWorkCenterInput, _ctx: CommandContext) { const { id } = input; // 1. Fetch work center with lock const workCenter = await db .selectFrom("WorkCenter") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!workCenter) { return err(new WorkCenterNotFoundError(id)); } // 2. Validate status is activatable const nextStatus = workCenterLifecycle.tryTransition(workCenter.status, "activate"); if (!nextStatus) { return err(new WorkCenterNotActivatableError(workCenter.code)); } // 3. Validate calendar context if (!workCenter.calendarReference) { return err(new MissingCalendarContextError(workCenter.code)); } // 4. Validate capacity > 0 if (workCenter.capacityAssumptions <= 0) { return err(new InvalidCapacityError(workCenter.code)); } // 5. Validate rates >= 0 if (workCenter.laborRate != null && workCenter.laborRate < 0) { return err(new InvalidRateError(workCenter.code)); } if (workCenter.machineRate != null && workCenter.machineRate < 0) { return err(new InvalidRateError(workCenter.code)); } // 6. Validate overhead currency for FIXED_AMOUNT_PER_GOOD_UNIT if ( workCenter.overheadAbsorptionMethod === "FIXED_AMOUNT_PER_GOOD_UNIT" && !workCenter.overheadAbsorptionCurrency ) { return err(new OverheadCurrencyRequiredError(workCenter.code)); } // 7. Set status to ACTIVE const updatedWorkCenter = await db .updateTable("WorkCenter") .set({ status: nextStatus, }) .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow(); return ok({ workCenter: updatedWorkCenter }); }