@open-mercato/core 0.6.4-develop.4015.1.efaafadf79 → 0.6.4-develop.4038.1.91ce075c8a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,6 +44,139 @@ const toNumber = (value) => {
44
44
  }
45
45
  return 0;
46
46
  };
47
+ async function enrichShipmentListResponse(payload, ctx) {
48
+ const items = Array.isArray(payload.items) ? payload.items : [];
49
+ if (!items.length) return;
50
+ const snapshotMap = /* @__PURE__ */ new Map();
51
+ items.forEach((item) => {
52
+ if (!item || typeof item !== "object") return;
53
+ const id = item.id;
54
+ if (typeof id !== "string") return;
55
+ const snapshot = readShipmentItemsSnapshot(
56
+ item.items_snapshot ?? item.itemsSnapshot ?? null
57
+ );
58
+ if (snapshot.length) {
59
+ snapshotMap.set(id, snapshot);
60
+ }
61
+ });
62
+ const shipmentIds = items.map((item) => {
63
+ if (!item || typeof item !== "object") return null;
64
+ const raw = item.id;
65
+ return typeof raw === "string" ? raw : null;
66
+ }).filter((value) => typeof value === "string");
67
+ if (!shipmentIds.length) return;
68
+ const em = ctx.container.resolve("em");
69
+ const statusIds = Array.from(
70
+ new Set(
71
+ items.map((item) => {
72
+ if (!item || typeof item !== "object") return null;
73
+ const raw = item.status_entry_id;
74
+ return typeof raw === "string" ? raw : null;
75
+ }).filter((value) => typeof value === "string" && value.length > 0)
76
+ )
77
+ );
78
+ const [shipmentItems, shippingMethods, statusEntries] = await Promise.all([
79
+ findWithDecryption(
80
+ em,
81
+ SalesShipmentItem,
82
+ { shipment: { $in: shipmentIds } },
83
+ { populate: ["orderLine"] },
84
+ { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null }
85
+ ),
86
+ (async () => {
87
+ const ids = Array.from(
88
+ new Set(
89
+ items.map((item) => {
90
+ if (!item || typeof item !== "object") return null;
91
+ const raw = item.shipping_method_id;
92
+ return typeof raw === "string" ? raw : null;
93
+ }).filter((value) => typeof value === "string" && value.length > 0)
94
+ )
95
+ );
96
+ if (!ids.length) return [];
97
+ return em.find(SalesShippingMethod, { id: { $in: ids } });
98
+ })(),
99
+ statusIds.length ? em.find(DictionaryEntry, { id: { $in: statusIds } }) : []
100
+ ]);
101
+ const orderLineIds = Array.from(
102
+ new Set(
103
+ shipmentItems.map(
104
+ (entry) => typeof entry.orderLine === "string" ? entry.orderLine : entry.orderLine?.id ?? entry.orderLineId ?? null
105
+ ).filter((value) => typeof value === "string")
106
+ )
107
+ );
108
+ const orderLines = orderLineIds.length ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } }) : [];
109
+ const lineMap = new Map(
110
+ orderLines.map((line) => [
111
+ line.id,
112
+ {
113
+ lineNumber: line.lineNumber ?? null,
114
+ name: line.name ?? (typeof line.catalogSnapshot === "object" && line.catalogSnapshot ? line.catalogSnapshot.name ?? null : null)
115
+ }
116
+ ])
117
+ );
118
+ const grouped = shipmentItems.reduce((acc, entry) => {
119
+ const shipmentId = typeof entry.shipment === "string" ? entry.shipment : entry.shipment?.id ?? entry.shipment_id ?? null;
120
+ const lineId = typeof entry.orderLine === "string" ? entry.orderLine : entry.orderLine?.id ?? entry.order_line_id ?? null;
121
+ if (!shipmentId || !lineId) return acc;
122
+ const line = lineMap.get(lineId);
123
+ const list = acc.get(shipmentId) ?? [];
124
+ list.push({
125
+ id: entry.id,
126
+ orderLineId: lineId,
127
+ orderLineName: line?.name ?? null,
128
+ orderLineNumber: line?.lineNumber ?? null,
129
+ quantity: toNumber(entry.quantity),
130
+ metadata: entry.metadata ?? null
131
+ });
132
+ acc.set(shipmentId, list);
133
+ return acc;
134
+ }, /* @__PURE__ */ new Map());
135
+ const shippingMap = new Map(
136
+ shippingMethods.map((method) => [
137
+ method.id,
138
+ {
139
+ code: method.code ?? null,
140
+ name: method.name ?? method.code ?? null
141
+ }
142
+ ])
143
+ );
144
+ const statusMap = /* @__PURE__ */ new Map();
145
+ statusEntries.forEach(
146
+ (entry) => statusMap.set(entry.id, {
147
+ value: entry.value ?? null,
148
+ label: entry.label ?? entry.value ?? null
149
+ })
150
+ );
151
+ items.forEach((item) => {
152
+ if (!item || typeof item !== "object") return;
153
+ const id = item.id;
154
+ if (typeof id !== "string") return;
155
+ const snapshot = snapshotMap.get(id);
156
+ if (snapshot?.length) {
157
+ ;
158
+ item.items_snapshot = snapshot;
159
+ }
160
+ ;
161
+ item.items = snapshot?.length ? snapshot : grouped.get(id) ?? [];
162
+ const shippingId = item.shipping_method_id;
163
+ if (typeof shippingId === "string" && shippingMap.has(shippingId)) {
164
+ const method = shippingMap.get(shippingId);
165
+ item.shipping_method_code = method?.code ?? null;
166
+ item.shipping_method_name = method?.name ?? null;
167
+ }
168
+ const statusId = item.status_entry_id;
169
+ if (typeof statusId === "string" && statusMap.has(statusId)) {
170
+ const status = statusMap.get(statusId);
171
+ if (!item.status) {
172
+ ;
173
+ item.status = status?.value ?? null;
174
+ }
175
+ ;
176
+ item.status_label = status?.label ?? status?.value ?? null;
177
+ }
178
+ });
179
+ }
47
180
  const crud = makeCrudRoute({
48
181
  metadata: routeMetadata,
49
182
  orm: {
@@ -144,137 +277,7 @@ const crud = makeCrudRoute({
144
277
  }
145
278
  },
146
279
  hooks: {
147
- afterList: async (payload, ctx) => {
148
- const items = Array.isArray(payload.items) ? payload.items : [];
149
- if (!items.length) return;
150
- const snapshotMap = /* @__PURE__ */ new Map();
151
- items.forEach((item) => {
152
- if (!item || typeof item !== "object") return;
153
- const id = item.id;
154
- if (typeof id !== "string") return;
155
- const snapshot = readShipmentItemsSnapshot(
156
- item.items_snapshot ?? item.itemsSnapshot ?? null
157
- );
158
- if (snapshot.length) {
159
- snapshotMap.set(id, snapshot);
160
- }
161
- });
162
- const shipmentIds = items.map((item) => item && typeof item === "object" ? item.id : null).filter((value) => typeof value === "string");
163
- if (!shipmentIds.length) return;
164
- const em = ctx.container.resolve("em");
165
- const [shipmentItems, shippingMethods] = await Promise.all([
166
- findWithDecryption(
167
- em,
168
- SalesShipmentItem,
169
- { shipment: { $in: shipmentIds } },
170
- { populate: ["orderLine"] },
171
- { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null }
172
- ),
173
- (async () => {
174
- const ids = Array.from(
175
- new Set(
176
- items.map((item) => {
177
- if (!item || typeof item !== "object") return null;
178
- const raw = item.shipping_method_id;
179
- return typeof raw === "string" ? raw : null;
180
- }).filter((value) => typeof value === "string" && value.length > 0)
181
- )
182
- );
183
- if (!ids.length) return [];
184
- return em.find(SalesShippingMethod, { id: { $in: ids } });
185
- })()
186
- ]);
187
- const orderLineIds = Array.from(
188
- new Set(
189
- shipmentItems.map(
190
- (entry) => typeof entry.orderLine === "string" ? entry.orderLine : entry.orderLine?.id ?? entry.orderLineId ?? null
191
- ).filter((value) => typeof value === "string")
192
- )
193
- );
194
- const orderLines = orderLineIds.length ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } }) : [];
195
- const lineMap = new Map(
196
- orderLines.map((line) => [
197
- line.id,
198
- {
199
- lineNumber: line.lineNumber ?? null,
200
- name: line.name ?? (typeof line.catalogSnapshot === "object" && line.catalogSnapshot ? line.catalogSnapshot.name ?? null : null)
201
- }
202
- ])
203
- );
204
- const grouped = shipmentItems.reduce((acc, entry) => {
205
- const shipmentId = typeof entry.shipment === "string" ? entry.shipment : entry.shipment?.id ?? entry.shipment_id ?? null;
206
- const lineId = typeof entry.orderLine === "string" ? entry.orderLine : entry.orderLine?.id ?? entry.order_line_id ?? null;
207
- if (!shipmentId || !lineId) return acc;
208
- const line = lineMap.get(lineId);
209
- const list = acc.get(shipmentId) ?? [];
210
- list.push({
211
- id: entry.id,
212
- orderLineId: lineId,
213
- orderLineName: line?.name ?? null,
214
- orderLineNumber: line?.lineNumber ?? null,
215
- quantity: toNumber(entry.quantity),
216
- metadata: entry.metadata ?? null
217
- });
218
- acc.set(shipmentId, list);
219
- return acc;
220
- }, /* @__PURE__ */ new Map());
221
- const shippingMap = new Map(
222
- shippingMethods.map((method) => [
223
- method.id,
224
- {
225
- code: method.code ?? null,
226
- name: method.name ?? method.code ?? null
227
- }
228
- ])
229
- );
230
- const statusIds = Array.from(
231
- new Set(
232
- items.map((item) => {
233
- if (!item || typeof item !== "object") return null;
234
- const raw = item.status_entry_id;
235
- return typeof raw === "string" ? raw : null;
236
- }).filter((value) => typeof value === "string" && value.length > 0)
237
- )
238
- );
239
- const statusMap = /* @__PURE__ */ new Map();
240
- if (statusIds.length) {
241
- const entries = await em.find(DictionaryEntry, { id: { $in: statusIds } });
242
- entries.forEach(
243
- (entry) => statusMap.set(entry.id, {
244
- value: entry.value ?? null,
245
- label: entry.label ?? entry.value ?? null
246
- })
247
- );
248
- }
249
- items.forEach((item) => {
250
- if (!item || typeof item !== "object") return;
251
- const id = item.id;
252
- if (typeof id !== "string") return;
253
- const snapshot = snapshotMap.get(id);
254
- if (snapshot?.length) {
255
- ;
256
- item.items_snapshot = snapshot;
257
- }
258
- ;
259
- item.items = snapshot?.length ? snapshot : grouped.get(id) ?? [];
260
- const shippingId = item.shipping_method_id;
261
- if (typeof shippingId === "string" && shippingMap.has(shippingId)) {
262
- const method = shippingMap.get(shippingId);
263
- item.shipping_method_code = method?.code ?? null;
264
- item.shipping_method_name = method?.name ?? null;
265
- }
266
- const statusId = item.status_entry_id;
267
- if (typeof statusId === "string" && statusMap.has(statusId)) {
268
- const status = statusMap.get(statusId);
269
- if (!item.status) {
270
- ;
271
- item.status = status?.value ?? null;
272
- }
273
- ;
274
- item.status_label = status?.label ?? status?.value ?? null;
275
- }
276
- });
277
- }
280
+ afterList: (payload, ctx) => enrichShipmentListResponse(payload, ctx)
278
281
  }
279
282
  });
280
283
  const { GET, POST, PUT, DELETE } = crud;
@@ -343,6 +346,7 @@ export {
343
346
  GET,
344
347
  POST,
345
348
  PUT,
349
+ enrichShipmentListResponse,
346
350
  metadata,
347
351
  openApi
348
352
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/api/shipments/route.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { SalesOrderLine, SalesShipment, SalesShipmentItem, SalesShippingMethod } from '../../data/entities'\nimport { shipmentCreateSchema, shipmentUpdateSchema } from '../../data/validators'\nimport { withScopedPayload } from '../utils'\nimport { readShipmentItemsSnapshot } from '../../lib/shipments/snapshots'\nimport {\n createPagedListResponseSchema,\n createSalesCrudOpenApi,\n defaultOkResponseSchema,\n} from '../openapi'\nimport { E } from '#generated/entities.ids.generated'\nimport * as F from '#generated/entities/sales_shipment'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(200).default(50),\n orderId: z.string().uuid().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.orders.view'] },\n POST: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n}\n\nconst deleteSchema = shipmentUpdateSchema.pick({\n id: true,\n orderId: true,\n organizationId: true,\n tenantId: true,\n})\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: SalesShipment,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: {\n entityType: E.sales.sales_shipment,\n },\n list: {\n schema: listSchema,\n entityId: E.sales.sales_shipment,\n fields: [\n F.id,\n 'order_id',\n F.shipment_number,\n F.shipping_method_id,\n F.status_entry_id,\n F.status,\n F.carrier_name,\n F.tracking_numbers,\n F.shipped_at,\n F.delivered_at,\n F.weight_value,\n F.weight_unit,\n F.declared_value_net,\n F.declared_value_gross,\n F.currency_code,\n F.notes,\n F.metadata,\n F.items_snapshot,\n F.created_at,\n F.updated_at,\n ],\n decorateCustomFields: { entityIds: [E.sales.sales_shipment] },\n sortFieldMap: {\n createdAt: F.created_at,\n updatedAt: F.updated_at,\n shippedAt: F.shipped_at,\n },\n buildFilters: async (query: any) => {\n const filters: Record<string, any> = {}\n if (query.orderId) filters.order_id = { $eq: query.orderId }\n return filters\n },\n },\n actions: {\n create: {\n commandId: 'sales.shipments.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n const { base, custom } = splitCustomFieldPayload(scoped)\n return shipmentCreateSchema.parse({\n ...base,\n ...(Object.keys(custom).length ? { customFields: custom } : {}),\n })\n },\n response: ({ result }) => ({ id: result?.shipmentId ?? null }),\n status: 201,\n },\n update: {\n commandId: 'sales.shipments.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n const { base, custom } = splitCustomFieldPayload(scoped)\n return shipmentUpdateSchema.parse({\n ...base,\n ...(Object.keys(custom).length ? { customFields: custom } : {}),\n })\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'sales.shipments.delete',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const merged = {\n ...(raw?.body ?? {}),\n ...(raw?.query ?? {}),\n }\n const payload = deleteSchema.parse(withScopedPayload(merged, ctx, translate))\n if (!payload.id || !payload.orderId) {\n throw new CrudHttpError(400, {\n error: translate('sales.shipments.not_found', 'Shipment not found'),\n })\n }\n return payload\n },\n response: () => ({ ok: true }),\n },\n },\n hooks: {\n afterList: async (payload, ctx) => {\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!items.length) return\n const snapshotMap = new Map<string, ReturnType<typeof readShipmentItemsSnapshot>>()\n items.forEach((item: unknown) => {\n if (!item || typeof item !== 'object') return\n const id = (item as Record<string, unknown>).id\n if (typeof id !== 'string') return\n const snapshot = readShipmentItemsSnapshot(\n (item as any).items_snapshot ?? (item as any).itemsSnapshot ?? null\n )\n if (snapshot.length) {\n snapshotMap.set(id, snapshot)\n }\n })\n const shipmentIds = items\n .map((item: unknown) => (item && typeof item === 'object' ? (item as Record<string, unknown>).id : null))\n .filter((value: string | null): value is string => typeof value === 'string')\n if (!shipmentIds.length) return\n const em = ctx.container.resolve('em') as EntityManager\n const [shipmentItems, shippingMethods] = await Promise.all([\n findWithDecryption(\n em,\n SalesShipmentItem,\n { shipment: { $in: shipmentIds } },\n { populate: ['orderLine'] },\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n ),\n (async () => {\n const ids: string[] = Array.from(\n new Set(\n items\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null\n const raw = (item as Record<string, unknown>).shipping_method_id\n return typeof raw === 'string' ? raw : null\n })\n .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n if (!ids.length) return []\n return em.find(SalesShippingMethod, { id: { $in: ids } })\n })(),\n ])\n const orderLineIds = Array.from(\n new Set(\n shipmentItems\n .map((entry) =>\n typeof entry.orderLine === 'string'\n ? entry.orderLine\n : entry.orderLine?.id ?? (entry as any).orderLineId ?? null\n )\n .filter((value): value is string => typeof value === 'string')\n )\n )\n const orderLines = orderLineIds.length\n ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } })\n : []\n const lineMap = new Map(\n orderLines.map((line) => [\n line.id,\n {\n lineNumber: line.lineNumber ?? null,\n name:\n line.name ??\n (typeof line.catalogSnapshot === 'object' && line.catalogSnapshot\n ? ((line.catalogSnapshot as any).name as string | undefined) ?? null\n : null),\n },\n ])\n )\n const grouped = shipmentItems.reduce<Map<string, Array<Record<string, unknown>>>>((acc, entry) => {\n const shipmentId =\n typeof entry.shipment === 'string'\n ? entry.shipment\n : entry.shipment?.id ?? (entry as any).shipment_id ?? null\n const lineId =\n typeof entry.orderLine === 'string'\n ? entry.orderLine\n : entry.orderLine?.id ?? (entry as any).order_line_id ?? null\n if (!shipmentId || !lineId) return acc\n const line = lineMap.get(lineId)\n const list = acc.get(shipmentId) ?? []\n list.push({\n id: entry.id,\n orderLineId: lineId,\n orderLineName: line?.name ?? null,\n orderLineNumber: line?.lineNumber ?? null,\n quantity: toNumber(entry.quantity),\n metadata: entry.metadata ?? null,\n })\n acc.set(shipmentId, list)\n return acc\n }, new Map())\n const shippingMap = new Map(\n shippingMethods.map((method) => [\n method.id,\n {\n code: method.code ?? null,\n name: method.name ?? method.code ?? null,\n },\n ])\n )\n const statusIds: string[] = Array.from(\n new Set(\n items\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null\n const raw = (item as Record<string, unknown>).status_entry_id\n return typeof raw === 'string' ? raw : null\n })\n .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n const statusMap = new Map<string, { value: string | null; label: string | null }>()\n if (statusIds.length) {\n const entries = await em.find(DictionaryEntry, { id: { $in: statusIds } })\n entries.forEach((entry) =>\n statusMap.set(entry.id, {\n value: entry.value ?? null,\n label: entry.label ?? entry.value ?? null,\n })\n )\n }\n items.forEach((item: unknown) => {\n if (!item || typeof item !== 'object') return\n const id = (item as Record<string, unknown>).id\n if (typeof id !== 'string') return\n const snapshot = snapshotMap.get(id)\n if (snapshot?.length) {\n ;(item as Record<string, unknown>).items_snapshot = snapshot\n }\n ;(item as Record<string, unknown>).items = snapshot?.length ? snapshot : grouped.get(id) ?? []\n const shippingId = (item as Record<string, unknown>).shipping_method_id\n if (typeof shippingId === 'string' && shippingMap.has(shippingId)) {\n const method = shippingMap.get(shippingId)\n ;(item as Record<string, unknown>).shipping_method_code = method?.code ?? null\n ;(item as Record<string, unknown>).shipping_method_name = method?.name ?? null\n }\n const statusId = (item as Record<string, unknown>).status_entry_id\n if (typeof statusId === 'string' && statusMap.has(statusId)) {\n const status = statusMap.get(statusId)\n if (!(item as Record<string, unknown>).status) {\n ;(item as Record<string, unknown>).status = status?.value ?? null\n }\n ;(item as Record<string, unknown>).status_label = status?.label ?? status?.value ?? null\n }\n })\n },\n },\n})\n\nconst { GET, POST, PUT, DELETE } = crud\n\nexport const metadata = routeMetadata\nexport { GET, POST, PUT, DELETE }\n\nconst shipmentItemSchema = z.object({\n id: z.string().uuid(),\n orderLineId: z.string().uuid(),\n orderLineName: z.string().nullable().optional(),\n orderLineNumber: z.number().nullable().optional(),\n quantity: z.number(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n})\n\nconst shipmentSchema = z\n .object({\n id: z.string().uuid(),\n order_id: z.string().uuid(),\n shipment_number: z.string().nullable().optional(),\n shipping_method_id: z.string().uuid().nullable().optional(),\n shipping_method_code: z.string().nullable().optional(),\n shipping_method_name: z.string().nullable().optional(),\n status_entry_id: z.string().uuid().nullable().optional(),\n status: z.string().nullable().optional(),\n status_label: z.string().nullable().optional(),\n carrier_name: z.string().nullable().optional(),\n tracking_numbers: z.array(z.string()).nullable().optional(),\n shipped_at: z.string().nullable().optional(),\n delivered_at: z.string().nullable().optional(),\n weight_value: z.number().nullable().optional(),\n weight_unit: z.string().nullable().optional(),\n declared_value_net: z.number().nullable().optional(),\n declared_value_gross: z.number().nullable().optional(),\n currency_code: z.string().nullable().optional(),\n notes: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n custom_values: z.record(z.string(), z.unknown()).nullable().optional(),\n customValues: z.record(z.string(), z.unknown()).nullable().optional(),\n custom_fields: z.array(z.record(z.string(), z.unknown())).nullable().optional(),\n customFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(),\n items_snapshot: z.array(shipmentItemSchema).nullable().optional(),\n itemsSnapshot: z.array(shipmentItemSchema).nullable().optional(),\n created_at: z.string(),\n updated_at: z.string(),\n items: z.array(shipmentItemSchema).optional(),\n })\n .passthrough()\n\nexport const openApi = createSalesCrudOpenApi({\n resourceName: 'Shipment',\n querySchema: listSchema,\n listResponseSchema: createPagedListResponseSchema(shipmentSchema),\n create: {\n schema: shipmentCreateSchema,\n responseSchema: z.object({ id: z.string().uuid().nullable() }),\n description: 'Creates a shipment for an order.',\n },\n update: {\n schema: shipmentUpdateSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Updates a shipment.',\n },\n del: {\n schema: deleteSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Deletes a shipment.',\n },\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { makeCrudRoute, type CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { SalesOrderLine, SalesShipment, SalesShipmentItem, SalesShippingMethod } from '../../data/entities'\nimport { shipmentCreateSchema, shipmentUpdateSchema } from '../../data/validators'\nimport { withScopedPayload } from '../utils'\nimport { readShipmentItemsSnapshot } from '../../lib/shipments/snapshots'\nimport {\n createPagedListResponseSchema,\n createSalesCrudOpenApi,\n defaultOkResponseSchema,\n} from '../openapi'\nimport { E } from '#generated/entities.ids.generated'\nimport * as F from '#generated/entities/sales_shipment'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(200).default(50),\n orderId: z.string().uuid().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.orders.view'] },\n POST: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['sales.shipments.manage'] },\n}\n\nconst deleteSchema = shipmentUpdateSchema.pick({\n id: true,\n orderId: true,\n organizationId: true,\n tenantId: true,\n})\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nexport async function enrichShipmentListResponse(\n payload: { items?: unknown[] },\n ctx: CrudCtx,\n): Promise<void> {\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!items.length) return\n const snapshotMap = new Map<string, ReturnType<typeof readShipmentItemsSnapshot>>()\n items.forEach((item: unknown) => {\n if (!item || typeof item !== 'object') return\n const id = (item as Record<string, unknown>).id\n if (typeof id !== 'string') return\n const snapshot = readShipmentItemsSnapshot(\n (item as any).items_snapshot ?? (item as any).itemsSnapshot ?? null\n )\n if (snapshot.length) {\n snapshotMap.set(id, snapshot)\n }\n })\n const shipmentIds = items\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null\n const raw = (item as Record<string, unknown>).id\n return typeof raw === 'string' ? raw : null\n })\n .filter((value: string | null): value is string => typeof value === 'string')\n if (!shipmentIds.length) return\n const em = ctx.container.resolve('em') as EntityManager\n const statusIds: string[] = Array.from(\n new Set(\n items\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null\n const raw = (item as Record<string, unknown>).status_entry_id\n return typeof raw === 'string' ? raw : null\n })\n .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n const [shipmentItems, shippingMethods, statusEntries] = await Promise.all([\n findWithDecryption(\n em,\n SalesShipmentItem,\n { shipment: { $in: shipmentIds } },\n { populate: ['orderLine'] },\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n ),\n (async () => {\n const ids: string[] = Array.from(\n new Set(\n items\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null\n const raw = (item as Record<string, unknown>).shipping_method_id\n return typeof raw === 'string' ? raw : null\n })\n .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n if (!ids.length) return []\n return em.find(SalesShippingMethod, { id: { $in: ids } })\n })(),\n statusIds.length ? em.find(DictionaryEntry, { id: { $in: statusIds } }) : [],\n ])\n const orderLineIds = Array.from(\n new Set(\n shipmentItems\n .map((entry) =>\n typeof entry.orderLine === 'string'\n ? entry.orderLine\n : entry.orderLine?.id ?? (entry as any).orderLineId ?? null\n )\n .filter((value): value is string => typeof value === 'string')\n )\n )\n const orderLines = orderLineIds.length\n ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } })\n : []\n const lineMap = new Map(\n orderLines.map((line) => [\n line.id,\n {\n lineNumber: line.lineNumber ?? null,\n name:\n line.name ??\n (typeof line.catalogSnapshot === 'object' && line.catalogSnapshot\n ? ((line.catalogSnapshot as any).name as string | undefined) ?? null\n : null),\n },\n ])\n )\n const grouped = shipmentItems.reduce<Map<string, Array<Record<string, unknown>>>>((acc, entry) => {\n const shipmentId =\n typeof entry.shipment === 'string'\n ? entry.shipment\n : entry.shipment?.id ?? (entry as any).shipment_id ?? null\n const lineId =\n typeof entry.orderLine === 'string'\n ? entry.orderLine\n : entry.orderLine?.id ?? (entry as any).order_line_id ?? null\n if (!shipmentId || !lineId) return acc\n const line = lineMap.get(lineId)\n const list = acc.get(shipmentId) ?? []\n list.push({\n id: entry.id,\n orderLineId: lineId,\n orderLineName: line?.name ?? null,\n orderLineNumber: line?.lineNumber ?? null,\n quantity: toNumber(entry.quantity),\n metadata: entry.metadata ?? null,\n })\n acc.set(shipmentId, list)\n return acc\n }, new Map())\n const shippingMap = new Map(\n shippingMethods.map((method) => [\n method.id,\n {\n code: method.code ?? null,\n name: method.name ?? method.code ?? null,\n },\n ])\n )\n const statusMap = new Map<string, { value: string | null; label: string | null }>()\n statusEntries.forEach((entry) =>\n statusMap.set(entry.id, {\n value: entry.value ?? null,\n label: entry.label ?? entry.value ?? null,\n })\n )\n items.forEach((item: unknown) => {\n if (!item || typeof item !== 'object') return\n const id = (item as Record<string, unknown>).id\n if (typeof id !== 'string') return\n const snapshot = snapshotMap.get(id)\n if (snapshot?.length) {\n ;(item as Record<string, unknown>).items_snapshot = snapshot\n }\n ;(item as Record<string, unknown>).items = snapshot?.length ? snapshot : grouped.get(id) ?? []\n const shippingId = (item as Record<string, unknown>).shipping_method_id\n if (typeof shippingId === 'string' && shippingMap.has(shippingId)) {\n const method = shippingMap.get(shippingId)\n ;(item as Record<string, unknown>).shipping_method_code = method?.code ?? null\n ;(item as Record<string, unknown>).shipping_method_name = method?.name ?? null\n }\n const statusId = (item as Record<string, unknown>).status_entry_id\n if (typeof statusId === 'string' && statusMap.has(statusId)) {\n const status = statusMap.get(statusId)\n if (!(item as Record<string, unknown>).status) {\n ;(item as Record<string, unknown>).status = status?.value ?? null\n }\n ;(item as Record<string, unknown>).status_label = status?.label ?? status?.value ?? null\n }\n })\n}\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: SalesShipment,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: {\n entityType: E.sales.sales_shipment,\n },\n list: {\n schema: listSchema,\n entityId: E.sales.sales_shipment,\n fields: [\n F.id,\n 'order_id',\n F.shipment_number,\n F.shipping_method_id,\n F.status_entry_id,\n F.status,\n F.carrier_name,\n F.tracking_numbers,\n F.shipped_at,\n F.delivered_at,\n F.weight_value,\n F.weight_unit,\n F.declared_value_net,\n F.declared_value_gross,\n F.currency_code,\n F.notes,\n F.metadata,\n F.items_snapshot,\n F.created_at,\n F.updated_at,\n ],\n decorateCustomFields: { entityIds: [E.sales.sales_shipment] },\n sortFieldMap: {\n createdAt: F.created_at,\n updatedAt: F.updated_at,\n shippedAt: F.shipped_at,\n },\n buildFilters: async (query: any) => {\n const filters: Record<string, any> = {}\n if (query.orderId) filters.order_id = { $eq: query.orderId }\n return filters\n },\n },\n actions: {\n create: {\n commandId: 'sales.shipments.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n const { base, custom } = splitCustomFieldPayload(scoped)\n return shipmentCreateSchema.parse({\n ...base,\n ...(Object.keys(custom).length ? { customFields: custom } : {}),\n })\n },\n response: ({ result }) => ({ id: result?.shipmentId ?? null }),\n status: 201,\n },\n update: {\n commandId: 'sales.shipments.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n const { base, custom } = splitCustomFieldPayload(scoped)\n return shipmentUpdateSchema.parse({\n ...base,\n ...(Object.keys(custom).length ? { customFields: custom } : {}),\n })\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'sales.shipments.delete',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const merged = {\n ...(raw?.body ?? {}),\n ...(raw?.query ?? {}),\n }\n const payload = deleteSchema.parse(withScopedPayload(merged, ctx, translate))\n if (!payload.id || !payload.orderId) {\n throw new CrudHttpError(400, {\n error: translate('sales.shipments.not_found', 'Shipment not found'),\n })\n }\n return payload\n },\n response: () => ({ ok: true }),\n },\n },\n hooks: {\n afterList: (payload, ctx) => enrichShipmentListResponse(payload, ctx),\n },\n})\n\nconst { GET, POST, PUT, DELETE } = crud\n\nexport const metadata = routeMetadata\nexport { GET, POST, PUT, DELETE }\n\nconst shipmentItemSchema = z.object({\n id: z.string().uuid(),\n orderLineId: z.string().uuid(),\n orderLineName: z.string().nullable().optional(),\n orderLineNumber: z.number().nullable().optional(),\n quantity: z.number(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n})\n\nconst shipmentSchema = z\n .object({\n id: z.string().uuid(),\n order_id: z.string().uuid(),\n shipment_number: z.string().nullable().optional(),\n shipping_method_id: z.string().uuid().nullable().optional(),\n shipping_method_code: z.string().nullable().optional(),\n shipping_method_name: z.string().nullable().optional(),\n status_entry_id: z.string().uuid().nullable().optional(),\n status: z.string().nullable().optional(),\n status_label: z.string().nullable().optional(),\n carrier_name: z.string().nullable().optional(),\n tracking_numbers: z.array(z.string()).nullable().optional(),\n shipped_at: z.string().nullable().optional(),\n delivered_at: z.string().nullable().optional(),\n weight_value: z.number().nullable().optional(),\n weight_unit: z.string().nullable().optional(),\n declared_value_net: z.number().nullable().optional(),\n declared_value_gross: z.number().nullable().optional(),\n currency_code: z.string().nullable().optional(),\n notes: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n custom_values: z.record(z.string(), z.unknown()).nullable().optional(),\n customValues: z.record(z.string(), z.unknown()).nullable().optional(),\n custom_fields: z.array(z.record(z.string(), z.unknown())).nullable().optional(),\n customFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(),\n items_snapshot: z.array(shipmentItemSchema).nullable().optional(),\n itemsSnapshot: z.array(shipmentItemSchema).nullable().optional(),\n created_at: z.string(),\n updated_at: z.string(),\n items: z.array(shipmentItemSchema).optional(),\n })\n .passthrough()\n\nexport const openApi = createSalesCrudOpenApi({\n resourceName: 'Shipment',\n querySchema: listSchema,\n listResponseSchema: createPagedListResponseSchema(shipmentSchema),\n create: {\n schema: shipmentCreateSchema,\n responseSchema: z.object({ id: z.string().uuid().nullable() }),\n description: 'Creates a shipment for an order.',\n },\n update: {\n schema: shipmentUpdateSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Updates a shipment.',\n },\n del: {\n schema: deleteSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Deletes a shipment.',\n },\n})\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.4-develop.4015.1.efaafadf79",
3
+ "version": "0.6.4-develop.4038.1.91ce075c8a",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -243,16 +243,16 @@
243
243
  "zod": "^4.4.3"
244
244
  },
245
245
  "peerDependencies": {
246
- "@open-mercato/ai-assistant": "0.6.4-develop.4015.1.efaafadf79",
247
- "@open-mercato/shared": "0.6.4-develop.4015.1.efaafadf79",
248
- "@open-mercato/ui": "0.6.4-develop.4015.1.efaafadf79",
246
+ "@open-mercato/ai-assistant": "0.6.4-develop.4038.1.91ce075c8a",
247
+ "@open-mercato/shared": "0.6.4-develop.4038.1.91ce075c8a",
248
+ "@open-mercato/ui": "0.6.4-develop.4038.1.91ce075c8a",
249
249
  "react": "^19.0.0",
250
250
  "react-dom": "^19.0.0"
251
251
  },
252
252
  "devDependencies": {
253
- "@open-mercato/ai-assistant": "0.6.4-develop.4015.1.efaafadf79",
254
- "@open-mercato/shared": "0.6.4-develop.4015.1.efaafadf79",
255
- "@open-mercato/ui": "0.6.4-develop.4015.1.efaafadf79",
253
+ "@open-mercato/ai-assistant": "0.6.4-develop.4038.1.91ce075c8a",
254
+ "@open-mercato/shared": "0.6.4-develop.4038.1.91ce075c8a",
255
+ "@open-mercato/ui": "0.6.4-develop.4038.1.91ce075c8a",
256
256
  "@testing-library/dom": "^10.4.1",
257
257
  "@testing-library/jest-dom": "^6.9.1",
258
258
  "@testing-library/react": "^16.3.1",
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod'
2
2
  import type { EntityManager } from '@mikro-orm/postgresql'
3
- import { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'
3
+ import { makeCrudRoute, type CrudCtx } from '@open-mercato/shared/lib/crud/factory'
4
4
  import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
5
5
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
6
6
  import { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'
@@ -53,6 +53,161 @@ const toNumber = (value: unknown): number => {
53
53
  return 0
54
54
  }
55
55
 
56
+ export async function enrichShipmentListResponse(
57
+ payload: { items?: unknown[] },
58
+ ctx: CrudCtx,
59
+ ): Promise<void> {
60
+ const items = Array.isArray(payload.items) ? payload.items : []
61
+ if (!items.length) return
62
+ const snapshotMap = new Map<string, ReturnType<typeof readShipmentItemsSnapshot>>()
63
+ items.forEach((item: unknown) => {
64
+ if (!item || typeof item !== 'object') return
65
+ const id = (item as Record<string, unknown>).id
66
+ if (typeof id !== 'string') return
67
+ const snapshot = readShipmentItemsSnapshot(
68
+ (item as any).items_snapshot ?? (item as any).itemsSnapshot ?? null
69
+ )
70
+ if (snapshot.length) {
71
+ snapshotMap.set(id, snapshot)
72
+ }
73
+ })
74
+ const shipmentIds = items
75
+ .map((item: unknown) => {
76
+ if (!item || typeof item !== 'object') return null
77
+ const raw = (item as Record<string, unknown>).id
78
+ return typeof raw === 'string' ? raw : null
79
+ })
80
+ .filter((value: string | null): value is string => typeof value === 'string')
81
+ if (!shipmentIds.length) return
82
+ const em = ctx.container.resolve('em') as EntityManager
83
+ const statusIds: string[] = Array.from(
84
+ new Set(
85
+ items
86
+ .map((item: unknown) => {
87
+ if (!item || typeof item !== 'object') return null
88
+ const raw = (item as Record<string, unknown>).status_entry_id
89
+ return typeof raw === 'string' ? raw : null
90
+ })
91
+ .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)
92
+ )
93
+ )
94
+ const [shipmentItems, shippingMethods, statusEntries] = await Promise.all([
95
+ findWithDecryption(
96
+ em,
97
+ SalesShipmentItem,
98
+ { shipment: { $in: shipmentIds } },
99
+ { populate: ['orderLine'] },
100
+ { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },
101
+ ),
102
+ (async () => {
103
+ const ids: string[] = Array.from(
104
+ new Set(
105
+ items
106
+ .map((item: unknown) => {
107
+ if (!item || typeof item !== 'object') return null
108
+ const raw = (item as Record<string, unknown>).shipping_method_id
109
+ return typeof raw === 'string' ? raw : null
110
+ })
111
+ .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)
112
+ )
113
+ )
114
+ if (!ids.length) return []
115
+ return em.find(SalesShippingMethod, { id: { $in: ids } })
116
+ })(),
117
+ statusIds.length ? em.find(DictionaryEntry, { id: { $in: statusIds } }) : [],
118
+ ])
119
+ const orderLineIds = Array.from(
120
+ new Set(
121
+ shipmentItems
122
+ .map((entry) =>
123
+ typeof entry.orderLine === 'string'
124
+ ? entry.orderLine
125
+ : entry.orderLine?.id ?? (entry as any).orderLineId ?? null
126
+ )
127
+ .filter((value): value is string => typeof value === 'string')
128
+ )
129
+ )
130
+ const orderLines = orderLineIds.length
131
+ ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } })
132
+ : []
133
+ const lineMap = new Map(
134
+ orderLines.map((line) => [
135
+ line.id,
136
+ {
137
+ lineNumber: line.lineNumber ?? null,
138
+ name:
139
+ line.name ??
140
+ (typeof line.catalogSnapshot === 'object' && line.catalogSnapshot
141
+ ? ((line.catalogSnapshot as any).name as string | undefined) ?? null
142
+ : null),
143
+ },
144
+ ])
145
+ )
146
+ const grouped = shipmentItems.reduce<Map<string, Array<Record<string, unknown>>>>((acc, entry) => {
147
+ const shipmentId =
148
+ typeof entry.shipment === 'string'
149
+ ? entry.shipment
150
+ : entry.shipment?.id ?? (entry as any).shipment_id ?? null
151
+ const lineId =
152
+ typeof entry.orderLine === 'string'
153
+ ? entry.orderLine
154
+ : entry.orderLine?.id ?? (entry as any).order_line_id ?? null
155
+ if (!shipmentId || !lineId) return acc
156
+ const line = lineMap.get(lineId)
157
+ const list = acc.get(shipmentId) ?? []
158
+ list.push({
159
+ id: entry.id,
160
+ orderLineId: lineId,
161
+ orderLineName: line?.name ?? null,
162
+ orderLineNumber: line?.lineNumber ?? null,
163
+ quantity: toNumber(entry.quantity),
164
+ metadata: entry.metadata ?? null,
165
+ })
166
+ acc.set(shipmentId, list)
167
+ return acc
168
+ }, new Map())
169
+ const shippingMap = new Map(
170
+ shippingMethods.map((method) => [
171
+ method.id,
172
+ {
173
+ code: method.code ?? null,
174
+ name: method.name ?? method.code ?? null,
175
+ },
176
+ ])
177
+ )
178
+ const statusMap = new Map<string, { value: string | null; label: string | null }>()
179
+ statusEntries.forEach((entry) =>
180
+ statusMap.set(entry.id, {
181
+ value: entry.value ?? null,
182
+ label: entry.label ?? entry.value ?? null,
183
+ })
184
+ )
185
+ items.forEach((item: unknown) => {
186
+ if (!item || typeof item !== 'object') return
187
+ const id = (item as Record<string, unknown>).id
188
+ if (typeof id !== 'string') return
189
+ const snapshot = snapshotMap.get(id)
190
+ if (snapshot?.length) {
191
+ ;(item as Record<string, unknown>).items_snapshot = snapshot
192
+ }
193
+ ;(item as Record<string, unknown>).items = snapshot?.length ? snapshot : grouped.get(id) ?? []
194
+ const shippingId = (item as Record<string, unknown>).shipping_method_id
195
+ if (typeof shippingId === 'string' && shippingMap.has(shippingId)) {
196
+ const method = shippingMap.get(shippingId)
197
+ ;(item as Record<string, unknown>).shipping_method_code = method?.code ?? null
198
+ ;(item as Record<string, unknown>).shipping_method_name = method?.name ?? null
199
+ }
200
+ const statusId = (item as Record<string, unknown>).status_entry_id
201
+ if (typeof statusId === 'string' && statusMap.has(statusId)) {
202
+ const status = statusMap.get(statusId)
203
+ if (!(item as Record<string, unknown>).status) {
204
+ ;(item as Record<string, unknown>).status = status?.value ?? null
205
+ }
206
+ ;(item as Record<string, unknown>).status_label = status?.label ?? status?.value ?? null
207
+ }
208
+ })
209
+ }
210
+
56
211
  const crud = makeCrudRoute({
57
212
  metadata: routeMetadata,
58
213
  orm: {
@@ -153,155 +308,7 @@ const crud = makeCrudRoute({
153
308
  },
154
309
  },
155
310
  hooks: {
156
- afterList: async (payload, ctx) => {
157
- const items = Array.isArray(payload.items) ? payload.items : []
158
- if (!items.length) return
159
- const snapshotMap = new Map<string, ReturnType<typeof readShipmentItemsSnapshot>>()
160
- items.forEach((item: unknown) => {
161
- if (!item || typeof item !== 'object') return
162
- const id = (item as Record<string, unknown>).id
163
- if (typeof id !== 'string') return
164
- const snapshot = readShipmentItemsSnapshot(
165
- (item as any).items_snapshot ?? (item as any).itemsSnapshot ?? null
166
- )
167
- if (snapshot.length) {
168
- snapshotMap.set(id, snapshot)
169
- }
170
- })
171
- const shipmentIds = items
172
- .map((item: unknown) => (item && typeof item === 'object' ? (item as Record<string, unknown>).id : null))
173
- .filter((value: string | null): value is string => typeof value === 'string')
174
- if (!shipmentIds.length) return
175
- const em = ctx.container.resolve('em') as EntityManager
176
- const [shipmentItems, shippingMethods] = await Promise.all([
177
- findWithDecryption(
178
- em,
179
- SalesShipmentItem,
180
- { shipment: { $in: shipmentIds } },
181
- { populate: ['orderLine'] },
182
- { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },
183
- ),
184
- (async () => {
185
- const ids: string[] = Array.from(
186
- new Set(
187
- items
188
- .map((item: unknown) => {
189
- if (!item || typeof item !== 'object') return null
190
- const raw = (item as Record<string, unknown>).shipping_method_id
191
- return typeof raw === 'string' ? raw : null
192
- })
193
- .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)
194
- )
195
- )
196
- if (!ids.length) return []
197
- return em.find(SalesShippingMethod, { id: { $in: ids } })
198
- })(),
199
- ])
200
- const orderLineIds = Array.from(
201
- new Set(
202
- shipmentItems
203
- .map((entry) =>
204
- typeof entry.orderLine === 'string'
205
- ? entry.orderLine
206
- : entry.orderLine?.id ?? (entry as any).orderLineId ?? null
207
- )
208
- .filter((value): value is string => typeof value === 'string')
209
- )
210
- )
211
- const orderLines = orderLineIds.length
212
- ? await em.find(SalesOrderLine, { id: { $in: orderLineIds } })
213
- : []
214
- const lineMap = new Map(
215
- orderLines.map((line) => [
216
- line.id,
217
- {
218
- lineNumber: line.lineNumber ?? null,
219
- name:
220
- line.name ??
221
- (typeof line.catalogSnapshot === 'object' && line.catalogSnapshot
222
- ? ((line.catalogSnapshot as any).name as string | undefined) ?? null
223
- : null),
224
- },
225
- ])
226
- )
227
- const grouped = shipmentItems.reduce<Map<string, Array<Record<string, unknown>>>>((acc, entry) => {
228
- const shipmentId =
229
- typeof entry.shipment === 'string'
230
- ? entry.shipment
231
- : entry.shipment?.id ?? (entry as any).shipment_id ?? null
232
- const lineId =
233
- typeof entry.orderLine === 'string'
234
- ? entry.orderLine
235
- : entry.orderLine?.id ?? (entry as any).order_line_id ?? null
236
- if (!shipmentId || !lineId) return acc
237
- const line = lineMap.get(lineId)
238
- const list = acc.get(shipmentId) ?? []
239
- list.push({
240
- id: entry.id,
241
- orderLineId: lineId,
242
- orderLineName: line?.name ?? null,
243
- orderLineNumber: line?.lineNumber ?? null,
244
- quantity: toNumber(entry.quantity),
245
- metadata: entry.metadata ?? null,
246
- })
247
- acc.set(shipmentId, list)
248
- return acc
249
- }, new Map())
250
- const shippingMap = new Map(
251
- shippingMethods.map((method) => [
252
- method.id,
253
- {
254
- code: method.code ?? null,
255
- name: method.name ?? method.code ?? null,
256
- },
257
- ])
258
- )
259
- const statusIds: string[] = Array.from(
260
- new Set(
261
- items
262
- .map((item: unknown) => {
263
- if (!item || typeof item !== 'object') return null
264
- const raw = (item as Record<string, unknown>).status_entry_id
265
- return typeof raw === 'string' ? raw : null
266
- })
267
- .filter((value: string | null): value is string => typeof value === 'string' && value.length > 0)
268
- )
269
- )
270
- const statusMap = new Map<string, { value: string | null; label: string | null }>()
271
- if (statusIds.length) {
272
- const entries = await em.find(DictionaryEntry, { id: { $in: statusIds } })
273
- entries.forEach((entry) =>
274
- statusMap.set(entry.id, {
275
- value: entry.value ?? null,
276
- label: entry.label ?? entry.value ?? null,
277
- })
278
- )
279
- }
280
- items.forEach((item: unknown) => {
281
- if (!item || typeof item !== 'object') return
282
- const id = (item as Record<string, unknown>).id
283
- if (typeof id !== 'string') return
284
- const snapshot = snapshotMap.get(id)
285
- if (snapshot?.length) {
286
- ;(item as Record<string, unknown>).items_snapshot = snapshot
287
- }
288
- ;(item as Record<string, unknown>).items = snapshot?.length ? snapshot : grouped.get(id) ?? []
289
- const shippingId = (item as Record<string, unknown>).shipping_method_id
290
- if (typeof shippingId === 'string' && shippingMap.has(shippingId)) {
291
- const method = shippingMap.get(shippingId)
292
- ;(item as Record<string, unknown>).shipping_method_code = method?.code ?? null
293
- ;(item as Record<string, unknown>).shipping_method_name = method?.name ?? null
294
- }
295
- const statusId = (item as Record<string, unknown>).status_entry_id
296
- if (typeof statusId === 'string' && statusMap.has(statusId)) {
297
- const status = statusMap.get(statusId)
298
- if (!(item as Record<string, unknown>).status) {
299
- ;(item as Record<string, unknown>).status = status?.value ?? null
300
- }
301
- ;(item as Record<string, unknown>).status_label = status?.label ?? status?.value ?? null
302
- }
303
- })
304
- },
311
+ afterList: (payload, ctx) => enrichShipmentListResponse(payload, ctx),
305
312
  },
306
313
  })
307
314