@open-mercato/core 0.10.1-develop.7709.1.046124599c → 0.10.1-develop.7714.1.9dbb8200d8
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.
- package/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/asn/index.js +19 -0
- package/dist/generated/entities/asn/index.js.map +7 -0
- package/dist/generated/entities/putaway_task/index.js +25 -0
- package/dist/generated/entities/putaway_task/index.js.map +7 -0
- package/dist/generated/entities/receiving_line/index.js +21 -0
- package/dist/generated/entities/receiving_line/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +4 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +34 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js +22 -3
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +2 -2
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +40 -11
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +13 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/wms/acl.js +2 -0
- package/dist/modules/wms/acl.js.map +2 -2
- package/dist/modules/wms/api/asns/[id]/complete/route.js +61 -0
- package/dist/modules/wms/api/asns/[id]/complete/route.js.map +7 -0
- package/dist/modules/wms/api/asns/[id]/receive/route.js +68 -0
- package/dist/modules/wms/api/asns/[id]/receive/route.js.map +7 -0
- package/dist/modules/wms/api/asns/route.js +197 -0
- package/dist/modules/wms/api/asns/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/helpers.js +42 -34
- package/dist/modules/wms/api/inventory/helpers.js.map +2 -2
- package/dist/modules/wms/api/inventory/receive/route.js +1 -1
- package/dist/modules/wms/api/inventory/receive/route.js.map +2 -2
- package/dist/modules/wms/api/listEnrichers.js +23 -0
- package/dist/modules/wms/api/listEnrichers.js.map +2 -2
- package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js +56 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js.map +7 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js +56 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js.map +7 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js +65 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js.map +7 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js +56 -0
- package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js.map +7 -0
- package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js +51 -0
- package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js.map +7 -0
- package/dist/modules/wms/api/putaway-tasks/route.js +192 -0
- package/dist/modules/wms/api/putaway-tasks/route.js.map +7 -0
- package/dist/modules/wms/api/receiving-lines/route.js +180 -0
- package/dist/modules/wms/api/receiving-lines/route.js.map +7 -0
- package/dist/modules/wms/api/scan/putaway/route.js +104 -0
- package/dist/modules/wms/api/scan/putaway/route.js.map +7 -0
- package/dist/modules/wms/api/scan/receive/route.js +109 -0
- package/dist/modules/wms/api/scan/receive/route.js.map +7 -0
- package/dist/modules/wms/api/scan/resolve-location/route.js +89 -0
- package/dist/modules/wms/api/scan/resolve-location/route.js.map +7 -0
- package/dist/modules/wms/api/scan/resolve-lot/route.js +89 -0
- package/dist/modules/wms/api/scan/resolve-lot/route.js.map +7 -0
- package/dist/modules/wms/backend/wms/asns/[id]/page.js +9 -0
- package/dist/modules/wms/backend/wms/asns/[id]/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/asns/page.js +9 -0
- package/dist/modules/wms/backend/wms/asns/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/asns/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/asns/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/putaway/page.js +9 -0
- package/dist/modules/wms/backend/wms/putaway/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/putaway/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/putaway/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/receiving/page.js +8 -0
- package/dist/modules/wms/backend/wms/receiving/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/receiving/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/receiving/page.meta.js.map +7 -0
- package/dist/modules/wms/ce.js +27 -0
- package/dist/modules/wms/ce.js.map +2 -2
- package/dist/modules/wms/commands/asn.js +1746 -0
- package/dist/modules/wms/commands/asn.js.map +7 -0
- package/dist/modules/wms/commands/index.js +2 -0
- package/dist/modules/wms/commands/index.js.map +2 -2
- package/dist/modules/wms/commands/inventory-actions.js +347 -243
- package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
- package/dist/modules/wms/commands/putaway.js +945 -0
- package/dist/modules/wms/commands/putaway.js.map +7 -0
- package/dist/modules/wms/commands/shared.js +51 -0
- package/dist/modules/wms/commands/shared.js.map +2 -2
- package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js +278 -0
- package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js +327 -0
- package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/CreateAsnDialog.js +404 -0
- package/dist/modules/wms/components/backend/CreateAsnDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/InventoryOperationsSection.js +16 -3
- package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +2 -2
- package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js +476 -0
- package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +2 -2
- package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsAsnDetailPage.js +524 -0
- package/dist/modules/wms/components/backend/WmsAsnDetailPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsAsnsListPage.js +339 -0
- package/dist/modules/wms/components/backend/WmsAsnsListPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +5 -6
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +5 -6
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +14 -10
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js +598 -0
- package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +5 -6
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js +32 -0
- package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js.map +7 -0
- package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js +36 -0
- package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js.map +7 -0
- package/dist/modules/wms/components/backend/inboundStatusUi.js +106 -0
- package/dist/modules/wms/components/backend/inboundStatusUi.js.map +7 -0
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +17 -0
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
- package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js +14 -0
- package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js.map +7 -0
- package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +4 -0
- package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +2 -2
- package/dist/modules/wms/data/enrichers.js +117 -12
- package/dist/modules/wms/data/enrichers.js.map +2 -2
- package/dist/modules/wms/data/entities.js +150 -1
- package/dist/modules/wms/data/entities.js.map +2 -2
- package/dist/modules/wms/data/validators.js +214 -0
- package/dist/modules/wms/data/validators.js.map +2 -2
- package/dist/modules/wms/events.js +12 -1
- package/dist/modules/wms/events.js.map +2 -2
- package/dist/modules/wms/extension-points.js +3 -1
- package/dist/modules/wms/extension-points.js.map +2 -2
- package/dist/modules/wms/lib/asnReceiving.js +124 -0
- package/dist/modules/wms/lib/asnReceiving.js.map +7 -0
- package/dist/modules/wms/lib/asnVendor.js +52 -0
- package/dist/modules/wms/lib/asnVendor.js.map +7 -0
- package/dist/modules/wms/lib/flashMutationError.js +4 -0
- package/dist/modules/wms/lib/flashMutationError.js.map +2 -2
- package/dist/modules/wms/lib/inventoryDisplayUi.js +24 -0
- package/dist/modules/wms/lib/inventoryDisplayUi.js.map +2 -2
- package/dist/modules/wms/lib/inventoryPolicy.js +17 -0
- package/dist/modules/wms/lib/inventoryPolicy.js.map +2 -2
- package/dist/modules/wms/lib/loadOperationalDashboard.js +67 -1
- package/dist/modules/wms/lib/loadOperationalDashboard.js.map +2 -2
- package/dist/modules/wms/lib/putaway.js +141 -0
- package/dist/modules/wms/lib/putaway.js.map +7 -0
- package/dist/modules/wms/lib/roleFeatures.js +3 -1
- package/dist/modules/wms/lib/roleFeatures.js.map +2 -2
- package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +99 -1
- package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +2 -2
- package/dist/modules/wms/lib/scanResolve.js +147 -0
- package/dist/modules/wms/lib/scanResolve.js.map +7 -0
- package/dist/modules/wms/lib/wmsIntegrationToggles.js +1 -1
- package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +2 -2
- package/dist/modules/wms/migrations/Migration20260812120000.js +43 -0
- package/dist/modules/wms/migrations/Migration20260812120000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260812130000.js +30 -0
- package/dist/modules/wms/migrations/Migration20260812130000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260822120000.js +17 -0
- package/dist/modules/wms/migrations/Migration20260822120000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260822130000.js +17 -0
- package/dist/modules/wms/migrations/Migration20260822130000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20261029120000.js +13 -0
- package/dist/modules/wms/migrations/Migration20261029120000.js.map +7 -0
- package/dist/modules/wms/search.js +85 -0
- package/dist/modules/wms/search.js.map +2 -2
- package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js +14 -0
- package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js.map +7 -0
- package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js +12 -0
- package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js.map +7 -0
- package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js +163 -0
- package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js.map +7 -0
- package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js +14 -0
- package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js.map +7 -0
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +37 -8
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +2 -2
- package/generated/entities/asn/index.ts +8 -0
- package/generated/entities/putaway_task/index.ts +11 -0
- package/generated/entities/receiving_line/index.ts +9 -0
- package/generated/entities.ids.generated.ts +4 -1
- package/generated/entity-fields-registry.ts +34 -0
- package/package.json +7 -7
- package/src/modules/auth/i18n/de.json +2 -0
- package/src/modules/auth/i18n/en.json +2 -0
- package/src/modules/auth/i18n/es.json +2 -0
- package/src/modules/auth/i18n/ko.json +2 -0
- package/src/modules/auth/i18n/pl.json +2 -0
- package/src/modules/communication_channels/i18n/de.json +2 -0
- package/src/modules/communication_channels/i18n/en.json +2 -0
- package/src/modules/communication_channels/i18n/es.json +2 -0
- package/src/modules/communication_channels/i18n/ko.json +2 -0
- package/src/modules/communication_channels/i18n/pl.json +2 -0
- package/src/modules/communication_channels/lib/sanitize-channel-html.ts +23 -3
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +44 -12
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +16 -2
- package/src/modules/wms/acl.ts +2 -0
- package/src/modules/wms/api/asns/[id]/complete/route.ts +62 -0
- package/src/modules/wms/api/asns/[id]/receive/route.ts +74 -0
- package/src/modules/wms/api/asns/route.ts +200 -0
- package/src/modules/wms/api/inventory/helpers.ts +57 -34
- package/src/modules/wms/api/inventory/receive/route.ts +2 -1
- package/src/modules/wms/api/listEnrichers.ts +38 -0
- package/src/modules/wms/api/putaway-tasks/[id]/assign/route.ts +56 -0
- package/src/modules/wms/api/putaway-tasks/[id]/cancel/route.ts +56 -0
- package/src/modules/wms/api/putaway-tasks/[id]/complete/route.ts +66 -0
- package/src/modules/wms/api/putaway-tasks/[id]/start/route.ts +56 -0
- package/src/modules/wms/api/putaway-tasks/create-from-balance/route.ts +50 -0
- package/src/modules/wms/api/putaway-tasks/route.ts +199 -0
- package/src/modules/wms/api/receiving-lines/route.ts +180 -0
- package/src/modules/wms/api/scan/putaway/route.ts +108 -0
- package/src/modules/wms/api/scan/receive/route.ts +118 -0
- package/src/modules/wms/api/scan/resolve-location/route.ts +92 -0
- package/src/modules/wms/api/scan/resolve-lot/route.ts +92 -0
- package/src/modules/wms/backend/wms/asns/[id]/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/asns/[id]/page.tsx +5 -0
- package/src/modules/wms/backend/wms/asns/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/asns/page.tsx +5 -0
- package/src/modules/wms/backend/wms/putaway/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/putaway/page.tsx +5 -0
- package/src/modules/wms/backend/wms/receiving/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/receiving/page.tsx +5 -0
- package/src/modules/wms/ce.ts +27 -0
- package/src/modules/wms/commands/asn.ts +2122 -0
- package/src/modules/wms/commands/index.ts +2 -0
- package/src/modules/wms/commands/inventory-actions.ts +413 -243
- package/src/modules/wms/commands/putaway.ts +1169 -0
- package/src/modules/wms/commands/shared.ts +51 -0
- package/src/modules/wms/components/backend/AssignPutawayTaskDialog.tsx +328 -0
- package/src/modules/wms/components/backend/CompletePutawayTaskDialog.tsx +366 -0
- package/src/modules/wms/components/backend/CreateAsnDialog.tsx +427 -0
- package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +20 -2
- package/src/modules/wms/components/backend/ReceiveAsnLineDialog.tsx +535 -0
- package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +2 -2
- package/src/modules/wms/components/backend/WmsAsnDetailPage.tsx +647 -0
- package/src/modules/wms/components/backend/WmsAsnsListPage.tsx +407 -0
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -5
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -5
- package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +12 -8
- package/src/modules/wms/components/backend/WmsPutawayQueuePage.tsx +677 -0
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -5
- package/src/modules/wms/components/backend/asnCompleteOptimisticLock.ts +52 -0
- package/src/modules/wms/components/backend/asnReceivingLinesLoader.ts +83 -0
- package/src/modules/wms/components/backend/inboundStatusUi.ts +154 -0
- package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -0
- package/src/modules/wms/components/backend/putawayQueueOptimisticLock.ts +20 -0
- package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +4 -0
- package/src/modules/wms/data/enrichers.ts +175 -13
- package/src/modules/wms/data/entities.ts +155 -0
- package/src/modules/wms/data/validators.ts +256 -0
- package/src/modules/wms/events.ts +11 -0
- package/src/modules/wms/extension-points.ts +2 -0
- package/src/modules/wms/i18n/de.json +205 -3
- package/src/modules/wms/i18n/en.json +205 -3
- package/src/modules/wms/i18n/es.json +205 -3
- package/src/modules/wms/i18n/ko.json +205 -3
- package/src/modules/wms/i18n/pl.json +205 -3
- package/src/modules/wms/lib/asnReceiving.ts +226 -0
- package/src/modules/wms/lib/asnVendor.ts +80 -0
- package/src/modules/wms/lib/flashMutationError.ts +4 -0
- package/src/modules/wms/lib/inventoryDisplayUi.ts +46 -0
- package/src/modules/wms/lib/inventoryPolicy.ts +31 -1
- package/src/modules/wms/lib/loadOperationalDashboard.ts +89 -1
- package/src/modules/wms/lib/putaway.ts +210 -0
- package/src/modules/wms/lib/roleFeatures.ts +2 -0
- package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +150 -1
- package/src/modules/wms/lib/scanResolve.ts +185 -0
- package/src/modules/wms/lib/wmsIntegrationToggles.ts +2 -1
- package/src/modules/wms/migrations/.snapshot-open-mercato.json +1000 -0
- package/src/modules/wms/migrations/Migration20260812120000.ts +43 -0
- package/src/modules/wms/migrations/Migration20260812130000.ts +28 -0
- package/src/modules/wms/migrations/Migration20260822120000.ts +17 -0
- package/src/modules/wms/migrations/Migration20260822130000.ts +15 -0
- package/src/modules/wms/migrations/Migration20261029120000.ts +11 -0
- package/src/modules/wms/search.ts +95 -0
- package/src/modules/wms/subscribers/asn-line-received-reevaluate-reservations.ts +21 -0
- package/src/modules/wms/subscribers/invalidate-enricher-cache-asn.ts +12 -0
- package/src/modules/wms/subscribers/procurement-goods-receipt-created.ts +238 -0
- package/src/modules/wms/subscribers/putaway-completed-reevaluate-reservations.ts +21 -0
- package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +63 -13
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
4
|
+
import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
5
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
|
+
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
7
|
+
import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
|
|
8
|
+
import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
9
|
+
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
10
|
+
import { createLogger } from '@open-mercato/shared/lib/logger'
|
|
11
|
+
import { asnReceiveLineSchema, scanReceiveSchema } from '../../../data/validators'
|
|
12
|
+
import { resolveScanReceiveCommandInput } from '../../../lib/scanResolve'
|
|
13
|
+
import { executeWmsCustomPostRoute } from '../../inventory/helpers'
|
|
14
|
+
|
|
15
|
+
const logger = createLogger('wms')
|
|
16
|
+
|
|
17
|
+
export const metadata = {
|
|
18
|
+
POST: { requireAuth: true, requireFeatures: ['wms.receive_inventory'] },
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const successSchema = z.object({
|
|
22
|
+
ok: z.literal(true),
|
|
23
|
+
movementIds: z.array(z.string().uuid()),
|
|
24
|
+
putawayTaskIds: z.array(z.string().uuid()),
|
|
25
|
+
receivedQty: z.number().optional(),
|
|
26
|
+
asnUpdatedAt: z.string().datetime().optional(),
|
|
27
|
+
})
|
|
28
|
+
const errorSchema = z.object({ error: z.string() })
|
|
29
|
+
|
|
30
|
+
export async function POST(request: Request) {
|
|
31
|
+
try {
|
|
32
|
+
const container = await createRequestContainer()
|
|
33
|
+
const auth = await getAuthFromRequest(request)
|
|
34
|
+
if (!auth?.tenantId) {
|
|
35
|
+
throw new CrudHttpError(401, { error: 'Unauthorized' })
|
|
36
|
+
}
|
|
37
|
+
const organizationScope = await resolveOrganizationScopeForRequest({
|
|
38
|
+
container,
|
|
39
|
+
auth,
|
|
40
|
+
request,
|
|
41
|
+
})
|
|
42
|
+
const organizationId = organizationScope?.selectedId ?? auth.orgId ?? null
|
|
43
|
+
if (!organizationId) {
|
|
44
|
+
throw new CrudHttpError(400, { error: 'organization_scope_required' })
|
|
45
|
+
}
|
|
46
|
+
const body = await readJsonSafe<Record<string, unknown>>(request, {})
|
|
47
|
+
const parsed = scanReceiveSchema.parse(body)
|
|
48
|
+
if (parsed.tenantId !== auth.tenantId && !auth.isSuperAdmin) {
|
|
49
|
+
throw new CrudHttpError(403, { error: 'Forbidden' })
|
|
50
|
+
}
|
|
51
|
+
// Scope organization from auth/session — never trust body organizationId for
|
|
52
|
+
// ASN/location resolve (same contract as resolve-location / resolve-lot).
|
|
53
|
+
const scoped = {
|
|
54
|
+
...parsed,
|
|
55
|
+
tenantId: auth.tenantId,
|
|
56
|
+
organizationId,
|
|
57
|
+
}
|
|
58
|
+
const em = (container.resolve('em') as EntityManager).fork()
|
|
59
|
+
const commandInput = await resolveScanReceiveCommandInput(em, scoped)
|
|
60
|
+
const scopedRequest = new Request(request.url, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
headers: request.headers,
|
|
63
|
+
body: JSON.stringify(commandInput),
|
|
64
|
+
})
|
|
65
|
+
return executeWmsCustomPostRoute({
|
|
66
|
+
request: scopedRequest,
|
|
67
|
+
routePath: 'wms/scan/receive',
|
|
68
|
+
inputSchema: asnReceiveLineSchema,
|
|
69
|
+
commandId: 'wms.asns.receive-line',
|
|
70
|
+
describeResource: (input) => ({
|
|
71
|
+
resourceKind: 'wms.asn',
|
|
72
|
+
resourceId: input.asnId,
|
|
73
|
+
}),
|
|
74
|
+
mapSuccess: (result: {
|
|
75
|
+
movementIds: string[]
|
|
76
|
+
putawayTaskIds: string[]
|
|
77
|
+
receivedQty?: number
|
|
78
|
+
asnUpdatedAt?: string
|
|
79
|
+
}) => ({
|
|
80
|
+
ok: true,
|
|
81
|
+
movementIds: result.movementIds,
|
|
82
|
+
putawayTaskIds: result.putawayTaskIds,
|
|
83
|
+
receivedQty: result.receivedQty,
|
|
84
|
+
asnUpdatedAt: result.asnUpdatedAt,
|
|
85
|
+
}),
|
|
86
|
+
})
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof CrudHttpError) {
|
|
89
|
+
return NextResponse.json(error.body, { status: error.status })
|
|
90
|
+
}
|
|
91
|
+
if (error instanceof z.ZodError) {
|
|
92
|
+
return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })
|
|
93
|
+
}
|
|
94
|
+
logger.error('scan receive failed', { err: error })
|
|
95
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const openApi: OpenApiRouteDoc = {
|
|
100
|
+
tag: 'WMS',
|
|
101
|
+
summary: 'Scan-assisted ASN receive',
|
|
102
|
+
methods: {
|
|
103
|
+
POST: {
|
|
104
|
+
summary: 'Receive ASN line from scanned location/lot codes',
|
|
105
|
+
description:
|
|
106
|
+
'Resolves scanned location (and optional lot) codes, then executes the same command path as POST /api/wms/asns/:id/receive. Organization is taken from the authenticated session scope, not the request body. Both QC-pass and QC-fail require absolute targetReceivedQty for retry-safe attempts (optional idempotencyKey is an extra stabilizer only).',
|
|
107
|
+
requestBody: { contentType: 'application/json', schema: scanReceiveSchema },
|
|
108
|
+
responses: [{ status: 200, description: 'ASN line received', schema: successSchema }],
|
|
109
|
+
errors: [
|
|
110
|
+
{ status: 400, description: 'Validation failed', schema: errorSchema },
|
|
111
|
+
{ status: 401, description: 'Unauthorized', schema: errorSchema },
|
|
112
|
+
{ status: 404, description: 'ASN or location not found', schema: errorSchema },
|
|
113
|
+
{ status: 409, description: 'Invalid receipt state', schema: errorSchema },
|
|
114
|
+
{ status: 422, description: 'Tracking or QC transition invalid', schema: errorSchema },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
4
|
+
import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
5
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
|
+
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
7
|
+
import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
|
|
8
|
+
import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
9
|
+
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
10
|
+
import { createLogger } from '@open-mercato/shared/lib/logger'
|
|
11
|
+
import { scanResolveLocationSchema } from '../../../data/validators'
|
|
12
|
+
import { resolveLocationByCode } from '../../../lib/scanResolve'
|
|
13
|
+
|
|
14
|
+
const logger = createLogger('wms')
|
|
15
|
+
|
|
16
|
+
export const metadata = {
|
|
17
|
+
POST: { requireAuth: true, requireFeatures: ['wms.view'] },
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const successSchema = z.object({
|
|
21
|
+
ok: z.literal(true),
|
|
22
|
+
locationId: z.string().uuid(),
|
|
23
|
+
code: z.string(),
|
|
24
|
+
type: z.string(),
|
|
25
|
+
})
|
|
26
|
+
const errorSchema = z.object({ error: z.string() })
|
|
27
|
+
|
|
28
|
+
export async function POST(request: Request) {
|
|
29
|
+
try {
|
|
30
|
+
const container = await createRequestContainer()
|
|
31
|
+
const auth = await getAuthFromRequest(request)
|
|
32
|
+
if (!auth?.tenantId) {
|
|
33
|
+
throw new CrudHttpError(401, { error: 'Unauthorized' })
|
|
34
|
+
}
|
|
35
|
+
const organizationScope = await resolveOrganizationScopeForRequest({
|
|
36
|
+
container,
|
|
37
|
+
auth,
|
|
38
|
+
request,
|
|
39
|
+
})
|
|
40
|
+
const organizationId = organizationScope?.selectedId ?? auth.orgId ?? null
|
|
41
|
+
if (!organizationId) {
|
|
42
|
+
throw new CrudHttpError(400, { error: 'organization_scope_required' })
|
|
43
|
+
}
|
|
44
|
+
const body = await readJsonSafe<Record<string, unknown>>(request, {})
|
|
45
|
+
const parsed = scanResolveLocationSchema.parse(body)
|
|
46
|
+
if (parsed.tenantId !== auth.tenantId && !auth.isSuperAdmin) {
|
|
47
|
+
throw new CrudHttpError(403, { error: 'Forbidden' })
|
|
48
|
+
}
|
|
49
|
+
// Scope organization from auth/session — never trust body organizationId for cross-org reads.
|
|
50
|
+
const scoped = {
|
|
51
|
+
...parsed,
|
|
52
|
+
tenantId: auth.tenantId,
|
|
53
|
+
organizationId,
|
|
54
|
+
}
|
|
55
|
+
const em = (container.resolve('em') as EntityManager).fork()
|
|
56
|
+
const resolved = await resolveLocationByCode(em, scoped)
|
|
57
|
+
return NextResponse.json({
|
|
58
|
+
ok: true as const,
|
|
59
|
+
locationId: resolved.locationId,
|
|
60
|
+
code: resolved.code,
|
|
61
|
+
type: resolved.type,
|
|
62
|
+
})
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof CrudHttpError) {
|
|
65
|
+
return NextResponse.json(error.body, { status: error.status })
|
|
66
|
+
}
|
|
67
|
+
if (error instanceof z.ZodError) {
|
|
68
|
+
return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })
|
|
69
|
+
}
|
|
70
|
+
logger.error('scan resolve-location failed', { err: error })
|
|
71
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const openApi: OpenApiRouteDoc = {
|
|
76
|
+
tag: 'WMS',
|
|
77
|
+
summary: 'Resolve scanned location code',
|
|
78
|
+
methods: {
|
|
79
|
+
POST: {
|
|
80
|
+
summary: 'Resolve location by warehouse + barcode/code',
|
|
81
|
+
description:
|
|
82
|
+
'Returns the canonical location id and type for a scanned warehouse location code. Organization is taken from the authenticated session scope, not the request body.',
|
|
83
|
+
requestBody: { contentType: 'application/json', schema: scanResolveLocationSchema },
|
|
84
|
+
responses: [{ status: 200, description: 'Location resolved', schema: successSchema }],
|
|
85
|
+
errors: [
|
|
86
|
+
{ status: 400, description: 'Validation failed', schema: errorSchema },
|
|
87
|
+
{ status: 401, description: 'Unauthorized', schema: errorSchema },
|
|
88
|
+
{ status: 404, description: 'Location not found', schema: errorSchema },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
4
|
+
import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
5
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
|
+
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
7
|
+
import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
|
|
8
|
+
import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
9
|
+
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
10
|
+
import { createLogger } from '@open-mercato/shared/lib/logger'
|
|
11
|
+
import { scanResolveLotSchema } from '../../../data/validators'
|
|
12
|
+
import { resolveLotByNumber } from '../../../lib/scanResolve'
|
|
13
|
+
|
|
14
|
+
const logger = createLogger('wms')
|
|
15
|
+
|
|
16
|
+
export const metadata = {
|
|
17
|
+
POST: { requireAuth: true, requireFeatures: ['wms.view'] },
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const successSchema = z.object({
|
|
21
|
+
ok: z.literal(true),
|
|
22
|
+
lotId: z.string().uuid(),
|
|
23
|
+
lotNumber: z.string(),
|
|
24
|
+
expiresAt: z.string().nullable(),
|
|
25
|
+
})
|
|
26
|
+
const errorSchema = z.object({ error: z.string() })
|
|
27
|
+
|
|
28
|
+
export async function POST(request: Request) {
|
|
29
|
+
try {
|
|
30
|
+
const container = await createRequestContainer()
|
|
31
|
+
const auth = await getAuthFromRequest(request)
|
|
32
|
+
if (!auth?.tenantId) {
|
|
33
|
+
throw new CrudHttpError(401, { error: 'Unauthorized' })
|
|
34
|
+
}
|
|
35
|
+
const organizationScope = await resolveOrganizationScopeForRequest({
|
|
36
|
+
container,
|
|
37
|
+
auth,
|
|
38
|
+
request,
|
|
39
|
+
})
|
|
40
|
+
const organizationId = organizationScope?.selectedId ?? auth.orgId ?? null
|
|
41
|
+
if (!organizationId) {
|
|
42
|
+
throw new CrudHttpError(400, { error: 'organization_scope_required' })
|
|
43
|
+
}
|
|
44
|
+
const body = await readJsonSafe<Record<string, unknown>>(request, {})
|
|
45
|
+
const parsed = scanResolveLotSchema.parse(body)
|
|
46
|
+
if (parsed.tenantId !== auth.tenantId && !auth.isSuperAdmin) {
|
|
47
|
+
throw new CrudHttpError(403, { error: 'Forbidden' })
|
|
48
|
+
}
|
|
49
|
+
// Scope organization from auth/session — never trust body organizationId for cross-org reads.
|
|
50
|
+
const scoped = {
|
|
51
|
+
...parsed,
|
|
52
|
+
tenantId: auth.tenantId,
|
|
53
|
+
organizationId,
|
|
54
|
+
}
|
|
55
|
+
const em = (container.resolve('em') as EntityManager).fork()
|
|
56
|
+
const resolved = await resolveLotByNumber(em, scoped)
|
|
57
|
+
return NextResponse.json({
|
|
58
|
+
ok: true as const,
|
|
59
|
+
lotId: resolved.lotId,
|
|
60
|
+
lotNumber: resolved.lotNumber,
|
|
61
|
+
expiresAt: resolved.expiresAt,
|
|
62
|
+
})
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof CrudHttpError) {
|
|
65
|
+
return NextResponse.json(error.body, { status: error.status })
|
|
66
|
+
}
|
|
67
|
+
if (error instanceof z.ZodError) {
|
|
68
|
+
return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })
|
|
69
|
+
}
|
|
70
|
+
logger.error('scan resolve-lot failed', { err: error })
|
|
71
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const openApi: OpenApiRouteDoc = {
|
|
76
|
+
tag: 'WMS',
|
|
77
|
+
summary: 'Resolve scanned lot number',
|
|
78
|
+
methods: {
|
|
79
|
+
POST: {
|
|
80
|
+
summary: 'Resolve lot by catalog variant + lot number',
|
|
81
|
+
description:
|
|
82
|
+
'Returns the canonical lot id and expiry for a scanned lot number. Organization is taken from the authenticated session scope, not the request body.',
|
|
83
|
+
requestBody: { contentType: 'application/json', schema: scanResolveLotSchema },
|
|
84
|
+
responses: [{ status: 200, description: 'Lot resolved', schema: successSchema }],
|
|
85
|
+
errors: [
|
|
86
|
+
{ status: 400, description: 'Validation failed', schema: errorSchema },
|
|
87
|
+
{ status: 401, description: 'Unauthorized', schema: errorSchema },
|
|
88
|
+
{ status: 404, description: 'Lot not found', schema: errorSchema },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const metadata = {
|
|
2
|
+
requireAuth: true,
|
|
3
|
+
requireFeatures: ['wms.view'],
|
|
4
|
+
pageTitle: 'ASN detail',
|
|
5
|
+
pageTitleKey: 'wms.backend.asns.detail.nav.title',
|
|
6
|
+
pageGroup: 'WMS',
|
|
7
|
+
pageGroupKey: 'wms.nav.group',
|
|
8
|
+
navHidden: true,
|
|
9
|
+
breadcrumb: [
|
|
10
|
+
{ label: 'WMS', labelKey: 'wms.backend.nav.title', href: '/backend/wms' },
|
|
11
|
+
{ label: 'ASNs', labelKey: 'wms.backend.asns.nav.title', href: '/backend/wms/asns' },
|
|
12
|
+
{ label: 'ASN', labelKey: 'wms.backend.asns.detail.nav.title' },
|
|
13
|
+
],
|
|
14
|
+
} as const
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const metadata = {
|
|
2
|
+
requireAuth: true,
|
|
3
|
+
requireFeatures: ['wms.view'],
|
|
4
|
+
pageTitle: 'ASNs',
|
|
5
|
+
pageTitleKey: 'wms.backend.asns.nav.title',
|
|
6
|
+
pageGroup: 'WMS',
|
|
7
|
+
pageGroupKey: 'wms.nav.group',
|
|
8
|
+
pageOrder: 90,
|
|
9
|
+
breadcrumb: [
|
|
10
|
+
{ label: 'WMS', labelKey: 'wms.backend.nav.title', href: '/backend/wms' },
|
|
11
|
+
{ label: 'ASNs', labelKey: 'wms.backend.asns.nav.title' },
|
|
12
|
+
],
|
|
13
|
+
icon: 'clipboard-list',
|
|
14
|
+
} as const
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const metadata = {
|
|
2
|
+
requireAuth: true,
|
|
3
|
+
requireFeatures: ['wms.view'],
|
|
4
|
+
pageTitle: 'Putaway',
|
|
5
|
+
pageTitleKey: 'wms.backend.putaway.nav.title',
|
|
6
|
+
pageGroup: 'WMS',
|
|
7
|
+
pageGroupKey: 'wms.nav.group',
|
|
8
|
+
pageOrder: 95,
|
|
9
|
+
breadcrumb: [
|
|
10
|
+
{ label: 'WMS', labelKey: 'wms.backend.nav.title', href: '/backend/wms' },
|
|
11
|
+
{ label: 'Putaway', labelKey: 'wms.backend.putaway.nav.title' },
|
|
12
|
+
],
|
|
13
|
+
icon: 'package',
|
|
14
|
+
} as const
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const metadata = {
|
|
2
|
+
requireAuth: true,
|
|
3
|
+
requireFeatures: ['wms.view'],
|
|
4
|
+
pageTitle: 'Receiving',
|
|
5
|
+
pageTitleKey: 'wms.backend.receiving.nav.title',
|
|
6
|
+
pageGroup: 'WMS',
|
|
7
|
+
pageGroupKey: 'wms.nav.group',
|
|
8
|
+
pageOrder: 92,
|
|
9
|
+
breadcrumb: [
|
|
10
|
+
{ label: 'WMS', labelKey: 'wms.backend.nav.title', href: '/backend/wms' },
|
|
11
|
+
{ label: 'Receiving', labelKey: 'wms.backend.receiving.nav.title' },
|
|
12
|
+
],
|
|
13
|
+
icon: 'inbox',
|
|
14
|
+
} as const
|
package/src/modules/wms/ce.ts
CHANGED
|
@@ -71,6 +71,33 @@ export const entities = [
|
|
|
71
71
|
defaultEditor: false,
|
|
72
72
|
fields: [],
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
id: 'wms:asn',
|
|
76
|
+
label: 'ASN',
|
|
77
|
+
description: 'Advanced shipping notice for structured inbound receiving.',
|
|
78
|
+
labelField: 'referenceNumber',
|
|
79
|
+
showInSidebar: false,
|
|
80
|
+
defaultEditor: false,
|
|
81
|
+
fields: [],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: 'wms:receiving_line',
|
|
85
|
+
label: 'Receiving Line',
|
|
86
|
+
description: 'Expected/received line against an ASN with QC outcome.',
|
|
87
|
+
labelField: 'catalogVariantId',
|
|
88
|
+
showInSidebar: false,
|
|
89
|
+
defaultEditor: false,
|
|
90
|
+
fields: [],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'wms:putaway_task',
|
|
94
|
+
label: 'Putaway Task',
|
|
95
|
+
description: 'Directed putaway task moving accepted stock from staging into storage.',
|
|
96
|
+
labelField: 'catalogVariantId',
|
|
97
|
+
showInSidebar: false,
|
|
98
|
+
defaultEditor: false,
|
|
99
|
+
fields: [],
|
|
100
|
+
},
|
|
74
101
|
]
|
|
75
102
|
|
|
76
103
|
export default entities
|