import { ok, err, type ReadonlyDB } from "@tailor-platform/erp-kit/core"; import type { DB } from "../generated/kysely-tailordb"; import { ProductionOrderNotFoundError } from "../lib/errors.generated"; export interface GetProductionOrderInput { id: string; } /** * Function: getProductionOrder * * Returns one production order with release snapshots, material and work-order * details, and execution rollups for end-to-end planner review. */ export async function run(db: ReadonlyDB, input: GetProductionOrderInput) { const productionOrder = await db .selectFrom("ProductionOrder") .selectAll() .where("id", "=", input.id) .executeTakeFirst(); if (!productionOrder) { return err(new ProductionOrderNotFoundError(input.id)); } const bomSnapshot = await db .selectFrom("ProductionOrderBomSnapshot") .selectAll() .where("productionOrderId", "=", productionOrder.id) .executeTakeFirst(); const routingSnapshot = await db .selectFrom("ProductionOrderRoutingSnapshot") .selectAll() .where("productionOrderId", "=", productionOrder.id) .executeTakeFirst(); const costBaseline = await db .selectFrom("ProductionOrderCostBaseline") .selectAll() .where("productionOrderId", "=", productionOrder.id) .executeTakeFirst(); const materialRequirements = await db .selectFrom("ProductionOrderMaterialRequirement") .selectAll() .where("productionOrderId", "=", productionOrder.id) .execute(); const workOrders = await db .selectFrom("WorkOrder") .selectAll() .where("productionOrderId", "=", productionOrder.id) .orderBy("routingOperationSequenceNumber", "asc") .execute(); const costSummary = await db .selectFrom("ManufacturingCostSummary") .selectAll() .where("productionOrderId", "=", productionOrder.id) .executeTakeFirst(); const quantityRollup = { plannedQuantity: productionOrder.plannedQuantity, completedQuantity: workOrders.reduce((sum, workOrder) => sum + workOrder.completedQuantity, 0), scrapQuantity: workOrders.reduce((sum, workOrder) => sum + workOrder.scrapQuantity, 0), actualSetupTime: workOrders.reduce((sum, workOrder) => sum + workOrder.actualSetupTime, 0), actualRunTime: workOrders.reduce((sum, workOrder) => sum + workOrder.actualRunTime, 0), openWorkOrderCount: workOrders.filter( (workOrder) => workOrder.status !== "COMPLETE" && workOrder.status !== "CANCELLED", ).length, }; return ok({ productionOrder, bomSnapshot: bomSnapshot ?? null, routingSnapshot: routingSnapshot ?? null, costBaseline: costBaseline ?? null, materialRequirements, workOrders, quantityRollup, costSummary: costSummary ?? null, }); }