|
- import { z } from "zod";
-
- const nullableStr = z.string().nullable().optional();
- const nullableNum = z.number().nullable().optional();
-
- const ItemLotTraceOriginSchema = z
- .object({
- stockInLineId: z.number(),
- type: z.string(),
- refCode: z.string(),
- refId: nullableNum,
- supplierCode: z.string(),
- supplierName: z.string(),
- dnNo: z.string(),
- receiptDate: nullableStr,
- acceptedQty: z.number(),
- status: z.string(),
- })
- .passthrough();
-
- const ItemLotTraceQcResultSchema = z
- .object({
- stockInLineId: z.number(),
- qcPassed: z.boolean(),
- failQty: z.number(),
- acceptedQty: z.number(),
- remarks: z.string(),
- handledBy: z.string(),
- created: nullableStr,
- })
- .passthrough();
-
- const ItemLotTracePutawayEventSchema = z
- .object({
- inventoryLotLineId: z.number(),
- stockInLineId: nullableNum,
- warehouseCode: z.string(),
- qty: z.number(),
- handledBy: z.string(),
- timestamp: nullableStr,
- refType: z.string(),
- refCode: z.string(),
- refId: nullableNum,
- status: z.string().optional(),
- })
- .passthrough();
-
- const ItemLotTraceProductionStepSchema = z
- .object({
- processLineId: z.number(),
- stepName: z.string(),
- description: z.string(),
- equipmentCode: z.string(),
- equipmentName: z.string(),
- operatorName: z.string(),
- startTime: nullableStr,
- endTime: nullableStr,
- outputQty: z.number(),
- scrapQty: z.number(),
- defectQty: z.number(),
- status: z.string(),
- seqNo: nullableNum,
- bomProcessId: nullableNum,
- })
- .passthrough();
-
- const ItemLotTraceMaterialInputSchema: z.ZodType<Record<string, unknown>> = z.lazy(() =>
- z
- .object({
- jobOrderCode: z.string(),
- jobOrderId: nullableNum,
- materialItemCode: z.string(),
- materialItemName: z.string(),
- materialLotNo: z.string(),
- materialStockInLineId: nullableNum,
- materialInventoryLotId: nullableNum,
- materialQty: z.number(),
- materialUom: z.string().optional(),
- bomQtyPerUnit: nullableNum,
- bomProcessId: nullableNum,
- bomProcessSeqNo: nullableNum,
- assignedStepName: z.string().optional(),
- pickOrderCode: z.string(),
- pickOrderId: nullableNum,
- consoCode: z.string(),
- pickedAt: nullableStr,
- stockInOrigin: ItemLotTraceOriginSchema.nullable().optional(),
- purchaseEvents: z.array(z.record(z.unknown())).optional(),
- qcResults: z.array(ItemLotTraceQcResultSchema),
- putawayEvents: z.array(ItemLotTracePutawayEventSchema).optional(),
- nestedJoPrelude: ItemLotTraceJoPreludeSchema.nullable().optional(),
- productionSteps: z.array(ItemLotTraceProductionStepSchema).optional(),
- })
- .passthrough(),
- );
-
- const ItemLotTraceJoPreludeSchema: z.ZodType<Record<string, unknown>> = z.lazy(() =>
- z
- .object({
- jobOrder: z
- .object({
- jobOrderId: z.number(),
- jobOrderCode: z.string(),
- planStart: nullableStr,
- createdAt: nullableStr.optional(),
- reqQty: z.number(),
- status: z.string(),
- })
- .passthrough(),
- pickOrders: z.array(z.record(z.unknown())),
- materialInputs: z.array(ItemLotTraceMaterialInputSchema),
- })
- .passthrough(),
- );
-
- const ItemLotTraceGraphEdgeSchema = z
- .object({
- fromKey: z.string(),
- toKey: z.string(),
- kind: z.string(),
- })
- .passthrough();
-
- const ItemLotTraceGraphNodeRefSchema = z
- .object({
- key: z.string(),
- kind: z.string(),
- scopeKey: nullableStr,
- refCode: nullableStr,
- traceLotNo: nullableStr,
- traceItemCode: nullableStr,
- warehouseCode: nullableStr,
- })
- .passthrough();
-
- const ItemLotTraceGraphSchema = z
- .object({
- nodes: z.array(ItemLotTraceGraphNodeRefSchema),
- edges: z.array(ItemLotTraceGraphEdgeSchema),
- })
- .passthrough()
- .nullable()
- .optional();
-
- export const ItemLotTraceResponseSchema = z
- .object({
- lot: z
- .object({
- inventoryLotId: z.number(),
- lotNo: z.string(),
- itemId: z.number(),
- itemCode: z.string(),
- itemName: z.string(),
- expiryDate: nullableStr,
- productionDate: nullableStr,
- stockInDate: nullableStr,
- uom: z.string(),
- primaryStockInLineId: nullableNum,
- })
- .passthrough(),
- warehouseLines: z.array(z.record(z.unknown())),
- origins: z.array(ItemLotTraceOriginSchema),
- purchaseEvents: z.array(z.record(z.unknown())).optional(),
- qcResults: z.array(ItemLotTraceQcResultSchema),
- putawayEvents: z.array(ItemLotTracePutawayEventSchema),
- movements: z.array(z.record(z.unknown())),
- outboundUsage: z.array(z.record(z.unknown())),
- stockTakeEvents: z.array(z.record(z.unknown())),
- adjustments: z.array(z.record(z.unknown())),
- transfers: z.array(z.record(z.unknown())),
- bomTrace: z.record(z.unknown()),
- joPrelude: ItemLotTraceJoPreludeSchema.nullable(),
- productionSteps: z.array(ItemLotTraceProductionStepSchema),
- byproductLots: z.array(z.record(z.unknown())),
- openMovements: z.array(z.record(z.unknown())),
- failEvents: z.array(z.record(z.unknown())),
- doDeliveries: z.array(z.record(z.unknown())),
- replenishmentEvents: z.array(z.record(z.unknown())).optional(),
- returnEvents: z.array(z.record(z.unknown())),
- lotRelations: z.array(z.record(z.unknown())),
- alternateLocations: z.array(z.record(z.unknown())),
- locationBlocks: z.array(z.record(z.unknown())).optional(),
- traceGraph: ItemLotTraceGraphSchema,
- issueTrace: z
- .object({
- whereUsed: z.array(z.record(z.unknown())).optional(),
- downstreamDeliveries: z.array(z.record(z.unknown())).optional(),
- downstreamReplenishments: z.array(z.record(z.unknown())).optional(),
- })
- .passthrough()
- .optional(),
- })
- .passthrough();
-
- export type ItemLotTraceResponseParsed = z.infer<typeof ItemLotTraceResponseSchema>;
-
- export const parseItemLotTraceResponse = (data: unknown): ItemLotTraceResponseParsed =>
- ItemLotTraceResponseSchema.parse(data);
-
- /** Collect dot-path keys for contract snapshot tests. */
- export const collectObjectPaths = (
- obj: unknown,
- prefix = "",
- depth = 0,
- maxDepth = 6,
- ): string[] => {
- if (obj == null || depth > maxDepth) return prefix ? [prefix] : [];
- if (Array.isArray(obj)) {
- if (obj.length === 0) return prefix ? [prefix] : [];
- return collectObjectPaths(obj[0], prefix ? `${prefix}[]` : "[]", depth + 1, maxDepth);
- }
- if (typeof obj !== "object") return prefix ? [prefix] : [];
- const paths: string[] = prefix ? [prefix] : [];
- Object.keys(obj as Record<string, unknown>).sort().forEach((key) => {
- const next = prefix ? `${prefix}.${key}` : key;
- paths.push(...collectObjectPaths((obj as Record<string, unknown>)[key], next, depth + 1, maxDepth));
- });
- return paths;
- };
|