import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import { inventorySupplyPlanLifecycle } from "../db/inventorySupplyPlan.lifecycle.generated"; import type { InventorySupplyPlanSourceType } from "../generated/enums"; import type { Transaction } from "../generated/kysely-tailordb"; import { InventorySupplyPlanNotFoundError, SupplyPlanNotOpenError } from "../lib/errors.generated"; export interface CloseInventorySupplyPlanByIdInput { target: "SUPPLY_PLAN"; id: string; } export interface CloseInventorySupplyPlansBySourceDocumentInput { target: "SOURCE_DOCUMENT"; sourceType: InventorySupplyPlanSourceType; sourceId: string; } export interface CloseInventorySupplyPlansBySourceLinesInput { target: "SOURCE_LINES"; sourceType: InventorySupplyPlanSourceType; sourceLineIds: string[]; } export type CloseInventorySupplyPlanInput = | CloseInventorySupplyPlanByIdInput | CloseInventorySupplyPlansBySourceDocumentInput | CloseInventorySupplyPlansBySourceLinesInput; export async function run( db: Transaction, input: CloseInventorySupplyPlanInput, _ctx: CommandContext, ) { if (input.target === "SOURCE_DOCUMENT") { let query = db .updateTable("InventorySupplyPlan") .set({ status: "CLOSED" }) .where("sourceType", "=", input.sourceType) .where("sourceId", "=", input.sourceId) .where("status", "=", "OPEN"); const supplyPlans = await query.returningAll().execute(); return ok({ supplyPlans }); } if (input.target === "SOURCE_LINES") { if (input.sourceLineIds.length === 0) { return ok({ supplyPlans: [] }); } const query = db .updateTable("InventorySupplyPlan") .set({ status: "CLOSED" }) .where("sourceType", "=", input.sourceType) .where("sourceLineId", "in", input.sourceLineIds) .where("status", "=", "OPEN"); const supplyPlans = await query.returningAll().execute(); return ok({ supplyPlans }); } const existing = await db .selectFrom("InventorySupplyPlan") .selectAll() .where("id", "=", input.id) .forUpdate() .executeTakeFirst(); if (!existing) { return err(new InventorySupplyPlanNotFoundError(input.id)); } const nextStatus = inventorySupplyPlanLifecycle.tryTransition(existing.status, "close"); if (!nextStatus) { return err(new SupplyPlanNotOpenError(existing.id)); } const supplyPlan = await db .updateTable("InventorySupplyPlan") .set({ status: nextStatus, }) .where("id", "=", existing.id) .returningAll() .executeTakeFirstOrThrow(); return ok({ supplyPlan }); }