@open-mercato/core 0.10.1-develop.7708.1.5a5c248637 → 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/dist/modules/workflows/lib/activity-executor.js +78 -51
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/activity-registry.js.map +2 -2
- package/dist/modules/workflows/lib/activity-types.js +4 -1
- package/dist/modules/workflows/lib/activity-types.js.map +2 -2
- package/dist/modules/workflows/lib/activity-worker-handler.js +1 -1
- package/dist/modules/workflows/lib/activity-worker-handler.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
- package/src/modules/workflows/lib/activity-executor.ts +89 -58
- package/src/modules/workflows/lib/activity-registry.ts +1 -0
- package/src/modules/workflows/lib/activity-types.ts +4 -1
- package/src/modules/workflows/lib/activity-worker-handler.ts +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { RefreshCw, ShieldOff } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n StatusBadge,\n type StatusMap,\n} from '@open-mercato/ui/primitives/status-badge'\nimport { ComboboxInput } from '@open-mercato/ui/backend/inputs/ComboboxInput'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport { useWmsInventoryMutationAccess } from '../../../components/backend/useWmsInventoryMutationAccess'\nimport { loadWarehouseOptions } from '../../../components/backend/wmsLookupLoaders'\nimport {\n resolveCatalogVariantLabel,\n resolveWarehouseLabel,\n} from '../../../components/backend/inventoryMutationLoaders'\nimport { ReleaseReservationDialog } from '../../../components/backend/ReleaseReservationDialog'\n\ntype ReservationStatus =\n | 'unreserved'\n | 'partially_reserved'\n | 'fully_reserved'\n\ntype SalesOrderWmsPayload = {\n assignedWarehouseId?: string | null\n assignedWarehouseName?: string | null\n isExplicitlyAssigned?: boolean\n stockSummary?: Array<{\n catalogVariantId?: string\n available?: string\n reserved?: string\n }>\n reservationSummary?: {\n status?: ReservationStatus\n reservationIds?: string[]\n }\n}\n\nexport type SalesOrderRecord = Record<string, unknown> & {\n id?: string\n status?: string | null\n _wms?: SalesOrderWmsPayload\n}\n\nconst reservationStatusMap: StatusMap<ReservationStatus> = {\n unreserved: 'neutral',\n partially_reserved: 'warning',\n fully_reserved: 'success',\n}\n\nfunction formatQuantity(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString()\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n return value\n }\n return '0'\n}\n\nfunction isCancelledOrder(data: SalesOrderRecord | undefined): boolean {\n const status = typeof data?.status === 'string' ? data.status.trim() : ''\n return status === 'canceled' || status === 'cancelled'\n}\n\nfunction resolveOrderId(data: SalesOrderRecord | undefined): string | null {\n return typeof data?.id === 'string' && data.id.length > 0 ? data.id : null\n}\n\nexport default function SalesOrderStockContextWidget(\n props: InjectionWidgetComponentProps<unknown, SalesOrderRecord>,\n) {\n const { data } = props\n const t = useT()\n const router = useRouter()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const access = useWmsInventoryMutationAccess()\n const orderId = resolveOrderId(data)\n const wms = data?._wms\n const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [rerunning, setRerunning] = React.useState(false)\n const [variantLabels, setVariantLabels] = React.useState<Map<string, string>>(new Map())\n const [releaseReservationId, setReleaseReservationId] = React.useState<string | null>(null)\n\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'wms-sales-order-warehouse-assignment',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n\n React.useEffect(() => {\n if (wms?.isExplicitlyAssigned && wms.assignedWarehouseId) {\n setSelectedWarehouseId(wms.assignedWarehouseId)\n return\n }\n setSelectedWarehouseId(null)\n }, [wms?.assignedWarehouseId, wms?.isExplicitlyAssigned])\n\n const stockSummary = React.useMemo(\n () => (Array.isArray(wms?.stockSummary) ? wms.stockSummary : []),\n [wms?.stockSummary],\n )\n\n React.useEffect(() => {\n const variantIds = stockSummary\n .map((item) => item.catalogVariantId)\n .filter((id): id is string => !!id)\n if (variantIds.length === 0) return\n void (async () => {\n const entries = await Promise.all(\n variantIds.map(async (id) => {\n const label = await resolveCatalogVariantLabel(id)\n return [id, label ?? id] as const\n }),\n )\n setVariantLabels(new Map(entries))\n })()\n }, [stockSummary])\n\n const canManageAssignment = access.canRelease\n const assignedLabel =\n wms?.assignedWarehouseName ||\n (wms?.isExplicitlyAssigned ? wms.assignedWarehouseId : null) ||\n t('wms.widgets.sales.stockContext.unassigned', 'Not assigned')\n\n const warehouseSeedOptions = React.useMemo(() => {\n if (!wms?.assignedWarehouseId) return []\n const label = wms.assignedWarehouseName?.trim() || wms.assignedWarehouseId\n return [{ value: wms.assignedWarehouseId, label }]\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const resolveWarehouseComboboxLabel = React.useCallback(async (value: string) => {\n if (wms?.assignedWarehouseId === value && wms.assignedWarehouseName?.trim()) {\n return wms.assignedWarehouseName.trim()\n }\n const label = await resolveWarehouseLabel(value)\n return label ?? value\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const persistAssignment = React.useCallback(\n async (warehouseId: string | null) => {\n if (!orderId || !organizationId || !tenantId) return\n setSaving(true)\n try {\n const mutationPayload = {\n organizationId,\n tenantId,\n warehouseId,\n }\n await runMutation({\n operation: async () => {\n if (warehouseId) {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(mutationPayload),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n } else {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId,\n tenantId,\n }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n }\n },\n context: mutationContext,\n mutationPayload,\n })\n\n router.refresh()\n flash(\n warehouseId\n ? t(\n 'wms.widgets.sales.stockContext.assignSuccess',\n 'Warehouse assignment saved.',\n )\n : t(\n 'wms.widgets.sales.stockContext.unassignSuccess',\n 'Warehouse assignment cleared.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.assignError',\n 'Could not update warehouse assignment.',\n ),\n 'error',\n )\n } finally {\n setSaving(false)\n }\n },\n [mutationContext, orderId, organizationId, router, runMutation, t, tenantId],\n )\n\n const handleRerunReservation = React.useCallback(async () => {\n if (!orderId || !organizationId || !tenantId) return\n setRerunning(true)\n try {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/re-run-reservation`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ organizationId, tenantId }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n router.refresh()\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunSuccess',\n 'Reservation re-run triggered. Stock context will refresh shortly.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunError',\n 'Could not re-run reservation.',\n ),\n 'error',\n )\n } finally {\n setRerunning(false)\n }\n }, [orderId, organizationId, router, t, tenantId])\n\n if (!wms) return null\n\n const reservationStatus = wms.reservationSummary?.status ?? 'unreserved'\n const reservationIds = Array.isArray(wms.reservationSummary?.reservationIds)\n ? (wms.reservationSummary?.reservationIds ?? [])\n : []\n\n const releaseReservation = releaseReservationId\n ? { id: releaseReservationId }\n : null\n\n return (\n <div className=\"rounded-lg border bg-card px-4 py-3 space-y-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">\n {t(\n 'wms.widgets.sales.stockContext.title',\n 'WMS stock context',\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.description',\n 'Live reservation and availability summary for this sales order.',\n )}\n </p>\n </div>\n <StatusBadge\n variant={reservationStatusMap[reservationStatus]}\n dot\n >\n {t(\n `wms.widgets.sales.stockContext.status.${reservationStatus}`,\n reservationStatus,\n )}\n </StatusBadge>\n </div>\n\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-2 sm:col-span-2\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.assignedWarehouse',\n 'Assigned warehouse',\n )}\n </dt>\n <dd>\n {canManageAssignment && orderId ? (\n <ComboboxInput\n value={selectedWarehouseId ?? ''}\n onChange={(value) => {\n const nextValue = value.trim().length > 0 ? value : null\n setSelectedWarehouseId(nextValue)\n void persistAssignment(nextValue)\n }}\n seedOptions={warehouseSeedOptions}\n resolveLabel={resolveWarehouseComboboxLabel}\n loadSuggestions={async (query) => {\n const options = await loadWarehouseOptions(query)\n return options.map((option) => ({\n value: option.value,\n label: option.label,\n }))\n }}\n placeholder={t(\n 'wms.widgets.sales.stockContext.warehousePlaceholder',\n 'Select a warehouse',\n )}\n allowCustomValues={false}\n disabled={saving}\n />\n ) : (\n <span className=\"font-medium\">{assignedLabel}</span>\n )}\n </dd>\n {wms.isExplicitlyAssigned ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.explicitAssignmentHint',\n 'Explicit assignment overrides reservation-derived warehouse context.',\n )}\n </p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationCount',\n 'Reservation records',\n )}\n </dt>\n <dd className=\"font-medium\">{reservationIds.length}</dd>\n </div>\n </dl>\n\n {stockSummary.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.linesTitle',\n 'Variant availability',\n )}\n </p>\n <div className=\"space-y-2\">\n {stockSummary.map((item) => {\n const id = item.catalogVariantId ?? 'unknown'\n const label = variantLabels.get(id) ?? id\n return (\n <div\n key={id}\n className=\"rounded-md border border-border/70 bg-background px-3 py-2\"\n >\n <p className=\"text-sm font-medium\">{label}</p>\n <div className=\"mt-1 flex flex-wrap gap-4 text-xs text-muted-foreground\">\n <span>\n {t(\n 'wms.widgets.sales.stockContext.available',\n 'Available',\n )}\n {': '}\n {formatQuantity(item.available)}\n </span>\n <span>\n {t(\n 'wms.widgets.sales.stockContext.reserved',\n 'Reserved',\n )}\n {': '}\n {formatQuantity(item.reserved)}\n </span>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.empty',\n 'No WMS stock summary is available for this order yet.',\n )}\n </p>\n )}\n\n {access.canRelease && reservationIds.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationsTitle',\n 'Active reservations',\n )}\n </p>\n <div className=\"space-y-1\">\n {reservationIds.map((rid) => (\n <div\n key={rid}\n className=\"flex items-center justify-between gap-2 rounded-md border border-border/70 bg-background px-3 py-1.5\"\n >\n <span className=\"font-mono text-xs text-muted-foreground truncate\">{rid}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-xs text-status-error-fg hover:text-status-error-fg\"\n onClick={() => setReleaseReservationId(rid)}\n >\n <ShieldOff className=\"size-3 mr-1\" />\n {t('wms.widgets.sales.stockContext.releaseBtn', 'Release')}\n </Button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n {reservationStatus !== 'fully_reserved' && access.canRelease && orderId && !isCancelledOrder(data) ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={rerunning}\n onClick={() => void handleRerunReservation()}\n >\n <RefreshCw className={`size-3 mr-1.5 ${rerunning ? 'animate-spin' : ''}`} />\n {t(\n 'wms.widgets.sales.stockContext.actions.rerunReservation',\n 'Re-run reservation',\n )}\n </Button>\n ) : null}\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/inventory\">\n {t(\n 'wms.widgets.sales.stockContext.actions.inventory',\n 'Open inventory console',\n )}\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/reservations\">\n {t(\n 'wms.widgets.sales.stockContext.actions.reservations',\n 'Open reservations',\n )}\n </Link>\n </Button>\n </div>\n\n {access.canRelease ? (\n <ReleaseReservationDialog\n open={releaseReservationId !== null}\n onOpenChange={(open) => {\n if (!open) setReleaseReservationId(null)\n }}\n access={access}\n reservation={releaseReservation}\n onSuccess={() => {\n setReleaseReservationId(null)\n router.refresh()\n }}\n />\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { RefreshCw, ShieldOff } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n StatusBadge,\n type StatusMap,\n} from '@open-mercato/ui/primitives/status-badge'\nimport { ComboboxInput } from '@open-mercato/ui/backend/inputs/ComboboxInput'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport { useWmsInventoryMutationAccess } from '../../../components/backend/useWmsInventoryMutationAccess'\nimport { loadWarehouseOptions } from '../../../components/backend/wmsLookupLoaders'\nimport {\n resolveCatalogVariantLabel,\n resolveWarehouseLabel,\n} from '../../../components/backend/inventoryMutationLoaders'\nimport { ReleaseReservationDialog } from '../../../components/backend/ReleaseReservationDialog'\n\ntype ReservationStatus =\n | 'unreserved'\n | 'partially_reserved'\n | 'fully_reserved'\n\ntype SalesOrderWmsPayload = {\n assignedWarehouseId?: string | null\n assignedWarehouseName?: string | null\n isExplicitlyAssigned?: boolean\n stockSummary?: Array<{\n catalogVariantId?: string\n available?: string\n reserved?: string\n }>\n reservationSummary?: {\n status?: ReservationStatus\n reservationIds?: string[]\n reservations?: Array<{\n id?: string\n reservationLabel?: string\n catalogVariantId?: string\n warehouseId?: string | null\n warehouseName?: string | null\n quantity?: string\n variantName?: string | null\n variantSku?: string | null\n }>\n }\n}\n\nexport type SalesOrderRecord = Record<string, unknown> & {\n id?: string\n status?: string | null\n _wms?: SalesOrderWmsPayload\n}\n\nconst reservationStatusMap: StatusMap<ReservationStatus> = {\n unreserved: 'neutral',\n partially_reserved: 'warning',\n fully_reserved: 'success',\n}\n\nfunction formatQuantity(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString()\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n return value\n }\n return '0'\n}\n\nfunction isCancelledOrder(data: SalesOrderRecord | undefined): boolean {\n const status = typeof data?.status === 'string' ? data.status.trim() : ''\n return status === 'canceled' || status === 'cancelled'\n}\n\nfunction resolveOrderId(data: SalesOrderRecord | undefined): string | null {\n return typeof data?.id === 'string' && data.id.length > 0 ? data.id : null\n}\n\nexport default function SalesOrderStockContextWidget(\n props: InjectionWidgetComponentProps<unknown, SalesOrderRecord>,\n) {\n const { data } = props\n const t = useT()\n const router = useRouter()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const access = useWmsInventoryMutationAccess()\n const orderId = resolveOrderId(data)\n const wms = data?._wms\n const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [rerunning, setRerunning] = React.useState(false)\n const [variantLabels, setVariantLabels] = React.useState<Map<string, string>>(new Map())\n const [releaseReservationId, setReleaseReservationId] = React.useState<string | null>(null)\n\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'wms-sales-order-warehouse-assignment',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n\n React.useEffect(() => {\n if (wms?.isExplicitlyAssigned && wms.assignedWarehouseId) {\n setSelectedWarehouseId(wms.assignedWarehouseId)\n return\n }\n setSelectedWarehouseId(null)\n }, [wms?.assignedWarehouseId, wms?.isExplicitlyAssigned])\n\n const stockSummary = React.useMemo(\n () => (Array.isArray(wms?.stockSummary) ? wms.stockSummary : []),\n [wms?.stockSummary],\n )\n\n const activeReservations = React.useMemo(() => {\n const enriched = Array.isArray(wms?.reservationSummary?.reservations)\n ? (wms.reservationSummary?.reservations ?? [])\n : []\n const fromEnriched = enriched\n .map((item) => {\n const id = typeof item?.id === 'string' ? item.id : null\n if (!id) return null\n const reservationLabel =\n typeof item.reservationLabel === 'string' && item.reservationLabel.trim().length > 0\n ? item.reservationLabel.trim()\n : id\n return {\n id,\n reservationLabel,\n warehouse_name: item.warehouseName ?? null,\n variant_name: item.variantName ?? null,\n variant_sku: item.variantSku ?? null,\n quantity: item.quantity ?? null,\n }\n })\n .filter((item): item is NonNullable<typeof item> => item !== null)\n if (fromEnriched.length > 0) return fromEnriched\n\n const ids = Array.isArray(wms?.reservationSummary?.reservationIds)\n ? (wms.reservationSummary?.reservationIds ?? [])\n : []\n return ids\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map((id) => ({\n id,\n reservationLabel: id,\n warehouse_name: null,\n variant_name: null,\n variant_sku: null,\n quantity: null,\n }))\n }, [wms?.reservationSummary?.reservationIds, wms?.reservationSummary?.reservations])\n\n const releaseReservation = React.useMemo(() => {\n if (!releaseReservationId) return null\n const match = activeReservations.find((item) => item.id === releaseReservationId)\n return match ?? { id: releaseReservationId }\n }, [activeReservations, releaseReservationId])\n\n React.useEffect(() => {\n const variantIds = stockSummary\n .map((item) => item.catalogVariantId)\n .filter((id): id is string => !!id)\n if (variantIds.length === 0) return\n void (async () => {\n const entries = await Promise.all(\n variantIds.map(async (id) => {\n const label = await resolveCatalogVariantLabel(id)\n return [id, label ?? id] as const\n }),\n )\n setVariantLabels(new Map(entries))\n })()\n }, [stockSummary])\n\n const canManageAssignment = access.canRelease\n const assignedLabel =\n wms?.assignedWarehouseName ||\n (wms?.isExplicitlyAssigned ? wms.assignedWarehouseId : null) ||\n t('wms.widgets.sales.stockContext.unassigned', 'Not assigned')\n\n const warehouseSeedOptions = React.useMemo(() => {\n if (!wms?.assignedWarehouseId) return []\n const label = wms.assignedWarehouseName?.trim() || wms.assignedWarehouseId\n return [{ value: wms.assignedWarehouseId, label }]\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const resolveWarehouseComboboxLabel = React.useCallback(async (value: string) => {\n if (wms?.assignedWarehouseId === value && wms.assignedWarehouseName?.trim()) {\n return wms.assignedWarehouseName.trim()\n }\n const label = await resolveWarehouseLabel(value)\n return label ?? value\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const persistAssignment = React.useCallback(\n async (warehouseId: string | null) => {\n if (!orderId || !organizationId || !tenantId) return\n setSaving(true)\n try {\n const mutationPayload = {\n organizationId,\n tenantId,\n warehouseId,\n }\n await runMutation({\n operation: async () => {\n if (warehouseId) {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(mutationPayload),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n } else {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId,\n tenantId,\n }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n }\n },\n context: mutationContext,\n mutationPayload,\n })\n\n router.refresh()\n flash(\n warehouseId\n ? t(\n 'wms.widgets.sales.stockContext.assignSuccess',\n 'Warehouse assignment saved.',\n )\n : t(\n 'wms.widgets.sales.stockContext.unassignSuccess',\n 'Warehouse assignment cleared.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.assignError',\n 'Could not update warehouse assignment.',\n ),\n 'error',\n )\n } finally {\n setSaving(false)\n }\n },\n [mutationContext, orderId, organizationId, router, runMutation, t, tenantId],\n )\n\n const handleRerunReservation = React.useCallback(async () => {\n if (!orderId || !organizationId || !tenantId) return\n setRerunning(true)\n try {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/re-run-reservation`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ organizationId, tenantId }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n router.refresh()\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunSuccess',\n 'Reservation re-run triggered. Stock context will refresh shortly.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunError',\n 'Could not re-run reservation.',\n ),\n 'error',\n )\n } finally {\n setRerunning(false)\n }\n }, [orderId, organizationId, router, t, tenantId])\n\n if (!wms) return null\n\n const reservationStatus = wms.reservationSummary?.status ?? 'unreserved'\n\n return (\n <div className=\"rounded-lg border bg-card px-4 py-3 space-y-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">\n {t(\n 'wms.widgets.sales.stockContext.title',\n 'WMS stock context',\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.description',\n 'Live reservation and availability summary for this sales order.',\n )}\n </p>\n </div>\n <StatusBadge\n variant={reservationStatusMap[reservationStatus]}\n dot\n >\n {t(\n `wms.widgets.sales.stockContext.status.${reservationStatus}`,\n reservationStatus,\n )}\n </StatusBadge>\n </div>\n\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-2 sm:col-span-2\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.assignedWarehouse',\n 'Assigned warehouse',\n )}\n </dt>\n <dd>\n {canManageAssignment && orderId ? (\n <ComboboxInput\n value={selectedWarehouseId ?? ''}\n onChange={(value) => {\n const nextValue = value.trim().length > 0 ? value : null\n setSelectedWarehouseId(nextValue)\n void persistAssignment(nextValue)\n }}\n seedOptions={warehouseSeedOptions}\n resolveLabel={resolveWarehouseComboboxLabel}\n loadSuggestions={async (query) => {\n const options = await loadWarehouseOptions(query)\n return options.map((option) => ({\n value: option.value,\n label: option.label,\n }))\n }}\n placeholder={t(\n 'wms.widgets.sales.stockContext.warehousePlaceholder',\n 'Select a warehouse',\n )}\n allowCustomValues={false}\n disabled={saving}\n />\n ) : (\n <span className=\"font-medium\">{assignedLabel}</span>\n )}\n </dd>\n {wms.isExplicitlyAssigned ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.explicitAssignmentHint',\n 'Explicit assignment overrides reservation-derived warehouse context.',\n )}\n </p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationCount',\n 'Reservation records',\n )}\n </dt>\n <dd className=\"font-medium\">{activeReservations.length}</dd>\n </div>\n </dl>\n\n {stockSummary.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.linesTitle',\n 'Variant availability',\n )}\n </p>\n <div className=\"space-y-2\">\n {stockSummary.map((item) => {\n const id = item.catalogVariantId ?? 'unknown'\n const label = variantLabels.get(id) ?? id\n return (\n <div\n key={id}\n className=\"rounded-md border border-border/70 bg-background px-3 py-2\"\n >\n <p className=\"text-sm font-medium\">{label}</p>\n <div className=\"mt-1 flex flex-wrap gap-4 text-xs text-muted-foreground\">\n <span>\n {t(\n 'wms.widgets.sales.stockContext.available',\n 'Available',\n )}\n {': '}\n {formatQuantity(item.available)}\n </span>\n <span>\n {t(\n 'wms.widgets.sales.stockContext.reserved',\n 'Reserved',\n )}\n {': '}\n {formatQuantity(item.reserved)}\n </span>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.empty',\n 'No WMS stock summary is available for this order yet.',\n )}\n </p>\n )}\n\n {access.canRelease && activeReservations.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationsTitle',\n 'Active reservations',\n )}\n </p>\n <div className=\"space-y-1\">\n {activeReservations.map((reservation) => (\n <div\n key={reservation.id}\n className=\"flex items-center justify-between gap-2 rounded-md border border-border/70 bg-background px-3 py-1.5\"\n >\n <span className=\"text-xs text-foreground truncate\" title={reservation.reservationLabel}>\n {reservation.reservationLabel}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-xs text-status-error-fg hover:text-status-error-fg\"\n onClick={() => setReleaseReservationId(reservation.id)}\n >\n <ShieldOff className=\"size-3 mr-1\" />\n {t('wms.widgets.sales.stockContext.releaseBtn', 'Release')}\n </Button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n {reservationStatus !== 'fully_reserved' && access.canRelease && orderId && !isCancelledOrder(data) ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={rerunning}\n onClick={() => void handleRerunReservation()}\n >\n <RefreshCw className={`size-3 mr-1.5 ${rerunning ? 'animate-spin' : ''}`} />\n {t(\n 'wms.widgets.sales.stockContext.actions.rerunReservation',\n 'Re-run reservation',\n )}\n </Button>\n ) : null}\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/inventory\">\n {t(\n 'wms.widgets.sales.stockContext.actions.inventory',\n 'Open inventory console',\n )}\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/reservations\">\n {t(\n 'wms.widgets.sales.stockContext.actions.reservations',\n 'Open reservations',\n )}\n </Link>\n </Button>\n </div>\n\n {access.canRelease ? (\n <ReleaseReservationDialog\n open={releaseReservationId !== null}\n onOpenChange={(open) => {\n if (!open) setReleaseReservationId(null)\n }}\n access={access}\n reservation={releaseReservation}\n onSuccess={() => {\n setReleaseReservationId(null)\n router.refresh()\n }}\n />\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -170,7 +170,7 @@ async function enqueueActivity(em, activity, context) {
|
|
|
170
170
|
workflowContext,
|
|
171
171
|
stepContext,
|
|
172
172
|
retryPolicy: activity.retryPolicy,
|
|
173
|
-
timeoutMs: activity
|
|
173
|
+
timeoutMs: resolveActivityTimeoutMs(activity),
|
|
174
174
|
tenantId: workflowInstance.tenantId,
|
|
175
175
|
organizationId: workflowInstance.organizationId,
|
|
176
176
|
userId: context.userId
|
|
@@ -458,7 +458,8 @@ async function executeActivityByType(em, container, activity, context, signal) {
|
|
|
458
458
|
return await entry.execute(interpolatedConfig, context, {
|
|
459
459
|
em,
|
|
460
460
|
container,
|
|
461
|
-
signal
|
|
461
|
+
signal,
|
|
462
|
+
timeoutMs: resolveActivityTimeoutMs(activity)
|
|
462
463
|
});
|
|
463
464
|
}
|
|
464
465
|
async function executeSendEmail(config, context, container, signal) {
|
|
@@ -669,6 +670,34 @@ async function resolveDictionaryEntryId(em, dictionaryKey, value, tenantId, orga
|
|
|
669
670
|
return null;
|
|
670
671
|
}
|
|
671
672
|
}
|
|
673
|
+
const WEBHOOK_TIMEOUT_MS = 3e4;
|
|
674
|
+
const WEBHOOK_MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
675
|
+
async function readWebhookResponse(response, signal) {
|
|
676
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
677
|
+
if (declaredLength > WEBHOOK_MAX_RESPONSE_BYTES) {
|
|
678
|
+
throw new Error(`[internal] CALL_WEBHOOK response exceeds ${WEBHOOK_MAX_RESPONSE_BYTES} bytes`);
|
|
679
|
+
}
|
|
680
|
+
if (!response.body) return "";
|
|
681
|
+
const reader = response.body.getReader();
|
|
682
|
+
const chunks = [];
|
|
683
|
+
let totalBytes = 0;
|
|
684
|
+
try {
|
|
685
|
+
for (; ; ) {
|
|
686
|
+
throwIfAborted(signal);
|
|
687
|
+
const { done, value } = await raceAbortable(reader.read(), signal);
|
|
688
|
+
if (done) break;
|
|
689
|
+
totalBytes += value.byteLength;
|
|
690
|
+
if (totalBytes > WEBHOOK_MAX_RESPONSE_BYTES) {
|
|
691
|
+
throw new Error(`[internal] CALL_WEBHOOK response exceeds ${WEBHOOK_MAX_RESPONSE_BYTES} bytes`);
|
|
692
|
+
}
|
|
693
|
+
chunks.push(value);
|
|
694
|
+
}
|
|
695
|
+
return new TextDecoder().decode(Buffer.concat(chunks, totalBytes));
|
|
696
|
+
} finally {
|
|
697
|
+
void reader.cancel().catch(() => void 0);
|
|
698
|
+
reader.releaseLock();
|
|
699
|
+
}
|
|
700
|
+
}
|
|
672
701
|
async function executeCallWebhook(config, context, deps = {}) {
|
|
673
702
|
const parsed = callWebhookConfigSchema.safeParse(config);
|
|
674
703
|
if (!parsed.success) {
|
|
@@ -678,58 +707,56 @@ async function executeCallWebhook(config, context, deps = {}) {
|
|
|
678
707
|
const { url, method, headers: rawHeaders, body } = parsed.data;
|
|
679
708
|
const headers = rawHeaders ?? {};
|
|
680
709
|
const allowPrivate = deps.allowPrivate ?? isAllowPrivateWorkflowWebhookUrlsEnabled();
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
710
|
+
return executeWithTimeout(async (deadlineSignal) => {
|
|
711
|
+
const signal = deps.signal ? AbortSignal.any([deadlineSignal, deps.signal]) : deadlineSignal;
|
|
712
|
+
throwIfAborted(signal);
|
|
713
|
+
let response;
|
|
714
|
+
try {
|
|
715
|
+
response = await raceAbortable(safeOutboundFetch(
|
|
716
|
+
url,
|
|
717
|
+
{
|
|
718
|
+
method,
|
|
719
|
+
headers: {
|
|
720
|
+
"Content-Type": "application/json",
|
|
721
|
+
...headers
|
|
722
|
+
},
|
|
723
|
+
body: body !== void 0 && body !== null ? JSON.stringify(body) : void 0,
|
|
724
|
+
redirect: "manual",
|
|
725
|
+
signal
|
|
690
726
|
},
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
727
|
+
{
|
|
728
|
+
subject: "Workflow webhook URL",
|
|
729
|
+
allowPrivate,
|
|
730
|
+
lookupHost: deps.lookupHost,
|
|
731
|
+
fetchImpl: deps.fetchImpl
|
|
732
|
+
}
|
|
733
|
+
), signal);
|
|
734
|
+
if (response.status >= 300 && response.status < 400) {
|
|
735
|
+
const location = response.headers.get("location");
|
|
736
|
+
throw new Error(
|
|
737
|
+
`CALL_WEBHOOK refused to follow redirect ${response.status} to ${location ?? "(no Location header)"}`
|
|
738
|
+
);
|
|
700
739
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
740
|
+
const text = await readWebhookResponse(response, signal);
|
|
741
|
+
const contentType = response.headers.get("content-type");
|
|
742
|
+
const result = contentType?.includes("application/json") ? JSON.parse(text) : text;
|
|
743
|
+
if (!response.ok) {
|
|
744
|
+
throw new Error(
|
|
745
|
+
`Webhook request failed with status ${response.status}: ${JSON.stringify(result)}`
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
return { status: response.status, statusText: response.statusText, result };
|
|
749
|
+
} catch (error) {
|
|
750
|
+
if (error instanceof UnsafeOutboundUrlError) {
|
|
751
|
+
throw new Error(
|
|
752
|
+
`CALL_WEBHOOK rejected unsafe URL (reason=${error.reason}): ${error.message}`
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
throw error;
|
|
756
|
+
} finally {
|
|
757
|
+
void response?.body?.cancel().catch(() => void 0);
|
|
707
758
|
}
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
if (response.status >= 300 && response.status < 400) {
|
|
711
|
-
const location = response.headers.get("location");
|
|
712
|
-
throw new Error(
|
|
713
|
-
`CALL_WEBHOOK refused to follow redirect ${response.status} to ${location ?? "(no Location header)"}`
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
let result;
|
|
717
|
-
const contentType = response.headers.get("content-type");
|
|
718
|
-
if (contentType && contentType.includes("application/json")) {
|
|
719
|
-
result = await response.json();
|
|
720
|
-
} else {
|
|
721
|
-
result = await response.text();
|
|
722
|
-
}
|
|
723
|
-
if (!response.ok) {
|
|
724
|
-
throw new Error(
|
|
725
|
-
`Webhook request failed with status ${response.status}: ${JSON.stringify(result)}`
|
|
726
|
-
);
|
|
727
|
-
}
|
|
728
|
-
return {
|
|
729
|
-
status: response.status,
|
|
730
|
-
statusText: response.statusText,
|
|
731
|
-
result
|
|
732
|
-
};
|
|
759
|
+
}, deps.timeoutMs && deps.timeoutMs > 0 ? deps.timeoutMs : WEBHOOK_TIMEOUT_MS);
|
|
733
760
|
}
|
|
734
761
|
async function executeFunction(config, context, container, signal) {
|
|
735
762
|
const { functionName, args = {} } = config;
|