@open-mercato/core 0.6.7-develop.6669.1.40b669666b → 0.6.7-develop.6671.1.4b925c5096
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/inventory_balance/index.js +21 -0
- package/dist/generated/entities/inventory_balance/index.js.map +7 -0
- package/dist/generated/entities/inventory_lot/index.js +19 -0
- package/dist/generated/entities/inventory_lot/index.js.map +7 -0
- package/dist/generated/entities/inventory_movement/index.js +35 -0
- package/dist/generated/entities/inventory_movement/index.js.map +7 -0
- package/dist/generated/entities/inventory_reservation/index.js +23 -0
- package/dist/generated/entities/inventory_reservation/index.js.map +7 -0
- package/dist/generated/entities/product_inventory_profile/index.js +21 -0
- package/dist/generated/entities/product_inventory_profile/index.js.map +7 -0
- package/dist/generated/entities/sales_order_warehouse_assignment/index.js +11 -0
- package/dist/generated/entities/sales_order_warehouse_assignment/index.js.map +7 -0
- package/dist/generated/entities/warehouse/index.js +25 -0
- package/dist/generated/entities/warehouse/index.js.map +7 -0
- package/dist/generated/entities/warehouse_location/index.js +21 -0
- package/dist/generated/entities/warehouse_location/index.js.map +7 -0
- package/dist/generated/entities/warehouse_zone/index.js +11 -0
- package/dist/generated/entities/warehouse_zone/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +12 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +98 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +12 -4
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +1 -0
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/auth/services/rbacService.js +16 -17
- package/dist/modules/auth/services/rbacService.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +3 -0
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/api/variants/route.js +3 -0
- package/dist/modules/catalog/api/variants/route.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +6 -6
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +1 -0
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +53 -0
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +51 -2
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/events.js +2 -0
- package/dist/modules/sales/events.js.map +2 -2
- package/dist/modules/sales/widgets/injection/order-items-context.js +11 -0
- package/dist/modules/sales/widgets/injection/order-items-context.js.map +7 -0
- package/dist/modules/wms/acl.js +18 -0
- package/dist/modules/wms/acl.js.map +7 -0
- package/dist/modules/wms/analytics.js +11 -0
- package/dist/modules/wms/analytics.js.map +7 -0
- package/dist/modules/wms/api/dashboard/operational/route.js +80 -0
- package/dist/modules/wms/api/dashboard/operational/route.js.map +7 -0
- package/dist/modules/wms/api/interceptors.js +90 -0
- package/dist/modules/wms/api/interceptors.js.map +7 -0
- package/dist/modules/wms/api/inventory/adjust/route.js +51 -0
- package/dist/modules/wms/api/inventory/adjust/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/allocate/route.js +51 -0
- package/dist/modules/wms/api/inventory/allocate/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/balances/route.js +172 -0
- package/dist/modules/wms/api/inventory/balances/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/cycle-count/route.js +52 -0
- package/dist/modules/wms/api/inventory/cycle-count/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/helpers.js +113 -0
- package/dist/modules/wms/api/inventory/helpers.js.map +7 -0
- package/dist/modules/wms/api/inventory/import/apply/route.js +46 -0
- package/dist/modules/wms/api/inventory/import/apply/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/import/helpers.js +195 -0
- package/dist/modules/wms/api/inventory/import/helpers.js.map +7 -0
- package/dist/modules/wms/api/inventory/import/template/route.js +32 -0
- package/dist/modules/wms/api/inventory/import/template/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/import/validate/route.js +54 -0
- package/dist/modules/wms/api/inventory/import/validate/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/move/route.js +51 -0
- package/dist/modules/wms/api/inventory/move/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/movements/route.js +164 -0
- package/dist/modules/wms/api/inventory/movements/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/receive/route.js +50 -0
- package/dist/modules/wms/api/inventory/receive/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/release/route.js +44 -0
- package/dist/modules/wms/api/inventory/release/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/reservations/route.js +128 -0
- package/dist/modules/wms/api/inventory/reservations/route.js.map +7 -0
- package/dist/modules/wms/api/inventory/reserve/route.js +59 -0
- package/dist/modules/wms/api/inventory/reserve/route.js.map +7 -0
- package/dist/modules/wms/api/inventory-profiles/route.js +178 -0
- package/dist/modules/wms/api/inventory-profiles/route.js.map +7 -0
- package/dist/modules/wms/api/listEnrichers.js +181 -0
- package/dist/modules/wms/api/listEnrichers.js.map +7 -0
- package/dist/modules/wms/api/listSearch.js +77 -0
- package/dist/modules/wms/api/listSearch.js.map +7 -0
- package/dist/modules/wms/api/locations/route.js +172 -0
- package/dist/modules/wms/api/locations/route.js.map +7 -0
- package/dist/modules/wms/api/lots/route.js +204 -0
- package/dist/modules/wms/api/lots/route.js.map +7 -0
- package/dist/modules/wms/api/openapi.js +27 -0
- package/dist/modules/wms/api/openapi.js.map +7 -0
- package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js +54 -0
- package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js.map +7 -0
- package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js +279 -0
- package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js.map +7 -0
- package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js +56 -0
- package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js.map +7 -0
- package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js +43 -0
- package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js.map +7 -0
- package/dist/modules/wms/api/warehouses/route.js +181 -0
- package/dist/modules/wms/api/warehouses/route.js.map +7 -0
- package/dist/modules/wms/api/zones/route.js +159 -0
- package/dist/modules/wms/api/zones/route.js.map +7 -0
- package/dist/modules/wms/backend/config/wms/page.js +9 -0
- package/dist/modules/wms/backend/config/wms/page.js.map +7 -0
- package/dist/modules/wms/backend/config/wms/page.meta.js +18 -0
- package/dist/modules/wms/backend/config/wms/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/page.js +9 -0
- package/dist/modules/wms/backend/page.js.map +7 -0
- package/dist/modules/wms/backend/page.meta.js +16 -0
- package/dist/modules/wms/backend/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/inventory/page.js +9 -0
- package/dist/modules/wms/backend/wms/inventory/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/inventory/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/inventory/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/location/[id]/page.js +9 -0
- package/dist/modules/wms/backend/wms/location/[id]/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/location/[id]/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/location/[id]/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/locations/page.js +10 -0
- package/dist/modules/wms/backend/wms/locations/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/locations/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/locations/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/lot/[id]/page.js +9 -0
- package/dist/modules/wms/backend/wms/lot/[id]/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/lots/page.js +9 -0
- package/dist/modules/wms/backend/wms/lots/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/lots/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/lots/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/movements/page.js +22 -0
- package/dist/modules/wms/backend/wms/movements/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/movements/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/movements/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/reservations/page.js +23 -0
- package/dist/modules/wms/backend/wms/reservations/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/reservations/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/reservations/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/sku/[id]/page.js +9 -0
- package/dist/modules/wms/backend/wms/sku/[id]/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/warehouses/page.js +10 -0
- package/dist/modules/wms/backend/wms/warehouses/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/warehouses/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/warehouses/page.meta.js.map +7 -0
- package/dist/modules/wms/backend/wms/zones/page.js +10 -0
- package/dist/modules/wms/backend/wms/zones/page.js.map +7 -0
- package/dist/modules/wms/backend/wms/zones/page.meta.js +18 -0
- package/dist/modules/wms/backend/wms/zones/page.meta.js.map +7 -0
- package/dist/modules/wms/ce.js +80 -0
- package/dist/modules/wms/ce.js.map +7 -0
- package/dist/modules/wms/cli.js +83 -0
- package/dist/modules/wms/cli.js.map +7 -0
- package/dist/modules/wms/commands/configuration.js +1519 -0
- package/dist/modules/wms/commands/configuration.js.map +7 -0
- package/dist/modules/wms/commands/index.js +4 -0
- package/dist/modules/wms/commands/index.js.map +7 -0
- package/dist/modules/wms/commands/inventory-actions.js +1539 -0
- package/dist/modules/wms/commands/inventory-actions.js.map +7 -0
- package/dist/modules/wms/commands/sales-order-assignment.js +277 -0
- package/dist/modules/wms/commands/sales-order-assignment.js.map +7 -0
- package/dist/modules/wms/commands/shared.js +82 -0
- package/dist/modules/wms/commands/shared.js.map +7 -0
- package/dist/modules/wms/components/backend/AdjustInventoryDialog.js +755 -0
- package/dist/modules/wms/components/backend/AdjustInventoryDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js +269 -0
- package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/CycleCountWizardDialog.js +1783 -0
- package/dist/modules/wms/components/backend/CycleCountWizardDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ImportInventoryDialog.js +766 -0
- package/dist/modules/wms/components/backend/ImportInventoryDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/InventoryOperationsSection.js +119 -0
- package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +7 -0
- package/dist/modules/wms/components/backend/LocationEditDialog.js +140 -0
- package/dist/modules/wms/components/backend/LocationEditDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/MoveInventoryDialog.js +791 -0
- package/dist/modules/wms/components/backend/MoveInventoryDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +656 -0
- package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ReleaseReservationDialog.js +344 -0
- package/dist/modules/wms/components/backend/ReleaseReservationDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/ReserveInventoryDialog.js +475 -0
- package/dist/modules/wms/components/backend/ReserveInventoryDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +1112 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +908 -0
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +1015 -0
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +1049 -0
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +297 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +757 -0
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +975 -0
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +7 -0
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +710 -0
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +7 -0
- package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +79 -0
- package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +7 -0
- package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js +24 -0
- package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js.map +7 -0
- package/dist/modules/wms/components/backend/wmsLookupLoaders.js +55 -0
- package/dist/modules/wms/components/backend/wmsLookupLoaders.js.map +7 -0
- package/dist/modules/wms/data/enrichers.js +501 -0
- package/dist/modules/wms/data/enrichers.js.map +7 -0
- package/dist/modules/wms/data/entities.js +467 -0
- package/dist/modules/wms/data/entities.js.map +7 -0
- package/dist/modules/wms/data/validators.js +399 -0
- package/dist/modules/wms/data/validators.js.map +7 -0
- package/dist/modules/wms/di.js +27 -0
- package/dist/modules/wms/di.js.map +7 -0
- package/dist/modules/wms/events.js +42 -0
- package/dist/modules/wms/events.js.map +7 -0
- package/dist/modules/wms/index.js +17 -0
- package/dist/modules/wms/index.js.map +7 -0
- package/dist/modules/wms/lib/catalogInventoryProfileIntent.js +54 -0
- package/dist/modules/wms/lib/catalogInventoryProfileIntent.js.map +7 -0
- package/dist/modules/wms/lib/catalogInventoryProfileSync.js +144 -0
- package/dist/modules/wms/lib/catalogInventoryProfileSync.js.map +7 -0
- package/dist/modules/wms/lib/expiry.js +29 -0
- package/dist/modules/wms/lib/expiry.js.map +7 -0
- package/dist/modules/wms/lib/flashMutationError.js +51 -0
- package/dist/modules/wms/lib/flashMutationError.js.map +7 -0
- package/dist/modules/wms/lib/inventoryDisplayUi.js +188 -0
- package/dist/modules/wms/lib/inventoryDisplayUi.js.map +7 -0
- package/dist/modules/wms/lib/inventoryIdempotency.js +37 -0
- package/dist/modules/wms/lib/inventoryIdempotency.js.map +7 -0
- package/dist/modules/wms/lib/inventoryImportCsv.js +173 -0
- package/dist/modules/wms/lib/inventoryImportCsv.js.map +7 -0
- package/dist/modules/wms/lib/inventoryImportService.js +468 -0
- package/dist/modules/wms/lib/inventoryImportService.js.map +7 -0
- package/dist/modules/wms/lib/inventoryMutationUi.js +25 -0
- package/dist/modules/wms/lib/inventoryMutationUi.js.map +7 -0
- package/dist/modules/wms/lib/inventoryPolicy.js +61 -0
- package/dist/modules/wms/lib/inventoryPolicy.js.map +7 -0
- package/dist/modules/wms/lib/inventoryReconciliation.js +193 -0
- package/dist/modules/wms/lib/inventoryReconciliation.js.map +7 -0
- package/dist/modules/wms/lib/inventoryTrackingValidation.js +13 -0
- package/dist/modules/wms/lib/inventoryTrackingValidation.js.map +7 -0
- package/dist/modules/wms/lib/loadOperationalDashboard.js +580 -0
- package/dist/modules/wms/lib/loadOperationalDashboard.js.map +7 -0
- package/dist/modules/wms/lib/lowStockBalanceFilter.js +49 -0
- package/dist/modules/wms/lib/lowStockBalanceFilter.js.map +7 -0
- package/dist/modules/wms/lib/primaryWarehousePolicy.js +32 -0
- package/dist/modules/wms/lib/primaryWarehousePolicy.js.map +7 -0
- package/dist/modules/wms/lib/roleFeatures.js +30 -0
- package/dist/modules/wms/lib/roleFeatures.js.map +7 -0
- package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +291 -0
- package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +7 -0
- package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js +54 -0
- package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js.map +7 -0
- package/dist/modules/wms/lib/wmsIntegrationToggles.js +71 -0
- package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260428110546.js +78 -0
- package/dist/modules/wms/migrations/Migration20260428110546.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260527120000.js +15 -0
- package/dist/modules/wms/migrations/Migration20260527120000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260527140000.js +37 -0
- package/dist/modules/wms/migrations/Migration20260527140000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260613120000.js +23 -0
- package/dist/modules/wms/migrations/Migration20260613120000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260616090000.js +13 -0
- package/dist/modules/wms/migrations/Migration20260616090000.js.map +7 -0
- package/dist/modules/wms/migrations/Migration20260707180000.js +15 -0
- package/dist/modules/wms/migrations/Migration20260707180000.js.map +7 -0
- package/dist/modules/wms/notifications.client.js +18 -0
- package/dist/modules/wms/notifications.client.js.map +7 -0
- package/dist/modules/wms/notifications.js +53 -0
- package/dist/modules/wms/notifications.js.map +7 -0
- package/dist/modules/wms/search.js +196 -0
- package/dist/modules/wms/search.js.map +7 -0
- package/dist/modules/wms/setup.js +30 -0
- package/dist/modules/wms/setup.js.map +7 -0
- package/dist/modules/wms/subscribers/low-stock-notification.js +40 -0
- package/dist/modules/wms/subscribers/low-stock-notification.js.map +7 -0
- package/dist/modules/wms/subscribers/reservation-shortfall-notification.js +69 -0
- package/dist/modules/wms/subscribers/reservation-shortfall-notification.js.map +7 -0
- package/dist/modules/wms/subscribers/sales-order-cancelled-release.js +14 -0
- package/dist/modules/wms/subscribers/sales-order-cancelled-release.js.map +7 -0
- package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js +14 -0
- package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js.map +7 -0
- package/dist/modules/wms/translations.js +10 -0
- package/dist/modules/wms/translations.js.map +7 -0
- package/dist/modules/wms/vector.js +9 -0
- package/dist/modules/wms/vector.js.map +7 -0
- package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js +200 -0
- package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js.map +7 -0
- package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js +104 -0
- package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js.map +7 -0
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +389 -0
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +7 -0
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js +16 -0
- package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js.map +7 -0
- package/dist/modules/wms/widgets/injection-table.js +36 -0
- package/dist/modules/wms/widgets/injection-table.js.map +7 -0
- package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js +150 -0
- package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js.map +7 -0
- package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js +186 -0
- package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js.map +7 -0
- package/dist/modules/wms/widgets/notifications/index.js +7 -0
- package/dist/modules/wms/widgets/notifications/index.js.map +7 -0
- package/generated/entities/inventory_balance/index.ts +9 -0
- package/generated/entities/inventory_lot/index.ts +8 -0
- package/generated/entities/inventory_movement/index.ts +16 -0
- package/generated/entities/inventory_reservation/index.ts +10 -0
- package/generated/entities/product_inventory_profile/index.ts +9 -0
- package/generated/entities/sales_order_warehouse_assignment/index.ts +4 -0
- package/generated/entities/warehouse/index.ts +11 -0
- package/generated/entities/warehouse_location/index.ts +9 -0
- package/generated/entities/warehouse_zone/index.ts +4 -0
- package/generated/entities.ids.generated.ts +12 -0
- package/generated/entity-fields-registry.ts +98 -0
- package/package.json +7 -7
- package/src/modules/auth/backend/roles/page.tsx +13 -4
- 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/pl.json +2 -0
- package/src/modules/auth/lib/backendChrome.tsx +1 -0
- package/src/modules/auth/services/rbacService.ts +25 -21
- package/src/modules/catalog/api/products/route.ts +3 -0
- package/src/modules/catalog/api/variants/route.ts +3 -0
- package/src/modules/query_index/lib/engine.ts +18 -6
- package/src/modules/sales/api/documents/factory.ts +1 -0
- package/src/modules/sales/commands/documents.ts +71 -0
- package/src/modules/sales/components/documents/ItemsSection.tsx +58 -0
- package/src/modules/sales/events.ts +2 -0
- package/src/modules/sales/widgets/injection/order-items-context.ts +15 -0
- package/src/modules/wms/acl.ts +14 -0
- package/src/modules/wms/analytics.ts +9 -0
- package/src/modules/wms/api/dashboard/operational/route.ts +83 -0
- package/src/modules/wms/api/interceptors.ts +108 -0
- package/src/modules/wms/api/inventory/adjust/route.ts +50 -0
- package/src/modules/wms/api/inventory/allocate/route.ts +50 -0
- package/src/modules/wms/api/inventory/balances/route.ts +178 -0
- package/src/modules/wms/api/inventory/cycle-count/route.ts +51 -0
- package/src/modules/wms/api/inventory/helpers.ts +128 -0
- package/src/modules/wms/api/inventory/import/apply/route.ts +47 -0
- package/src/modules/wms/api/inventory/import/helpers.ts +223 -0
- package/src/modules/wms/api/inventory/import/template/route.ts +31 -0
- package/src/modules/wms/api/inventory/import/validate/route.ts +56 -0
- package/src/modules/wms/api/inventory/move/route.ts +50 -0
- package/src/modules/wms/api/inventory/movements/route.ts +164 -0
- package/src/modules/wms/api/inventory/receive/route.ts +49 -0
- package/src/modules/wms/api/inventory/release/route.ts +43 -0
- package/src/modules/wms/api/inventory/reservations/route.ts +128 -0
- package/src/modules/wms/api/inventory/reserve/route.ts +59 -0
- package/src/modules/wms/api/inventory-profiles/route.ts +177 -0
- package/src/modules/wms/api/listEnrichers.ts +312 -0
- package/src/modules/wms/api/listSearch.ts +121 -0
- package/src/modules/wms/api/locations/route.ts +171 -0
- package/src/modules/wms/api/lots/route.ts +205 -0
- package/src/modules/wms/api/openapi.ts +28 -0
- package/src/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.ts +58 -0
- package/src/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.ts +306 -0
- package/src/modules/wms/api/sales-orders/assign-warehouse/route.ts +57 -0
- package/src/modules/wms/api/sales-orders/unassign-warehouse/route.ts +43 -0
- package/src/modules/wms/api/warehouses/route.ts +181 -0
- package/src/modules/wms/api/zones/route.ts +158 -0
- package/src/modules/wms/backend/config/wms/page.meta.ts +14 -0
- package/src/modules/wms/backend/config/wms/page.tsx +5 -0
- package/src/modules/wms/backend/page.meta.ts +12 -0
- package/src/modules/wms/backend/page.tsx +5 -0
- package/src/modules/wms/backend/wms/inventory/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/inventory/page.tsx +5 -0
- package/src/modules/wms/backend/wms/location/[id]/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/location/[id]/page.tsx +5 -0
- package/src/modules/wms/backend/wms/locations/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/locations/page.tsx +12 -0
- package/src/modules/wms/backend/wms/lot/[id]/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/lot/[id]/page.tsx +5 -0
- package/src/modules/wms/backend/wms/lots/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/lots/page.tsx +5 -0
- package/src/modules/wms/backend/wms/movements/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/movements/page.tsx +23 -0
- package/src/modules/wms/backend/wms/reservations/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/reservations/page.tsx +24 -0
- package/src/modules/wms/backend/wms/sku/[id]/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/sku/[id]/page.tsx +5 -0
- package/src/modules/wms/backend/wms/warehouses/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/warehouses/page.tsx +12 -0
- package/src/modules/wms/backend/wms/zones/page.meta.ts +14 -0
- package/src/modules/wms/backend/wms/zones/page.tsx +12 -0
- package/src/modules/wms/ce.ts +76 -0
- package/src/modules/wms/cli.ts +96 -0
- package/src/modules/wms/commands/configuration.ts +1844 -0
- package/src/modules/wms/commands/index.ts +3 -0
- package/src/modules/wms/commands/inventory-actions.ts +1866 -0
- package/src/modules/wms/commands/sales-order-assignment.ts +346 -0
- package/src/modules/wms/commands/shared.ts +90 -0
- package/src/modules/wms/components/backend/AdjustInventoryDialog.tsx +820 -0
- package/src/modules/wms/components/backend/ChangeLotStatusDialog.tsx +312 -0
- package/src/modules/wms/components/backend/CycleCountWizardDialog.tsx +2007 -0
- package/src/modules/wms/components/backend/ImportInventoryDialog.tsx +1018 -0
- package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +159 -0
- package/src/modules/wms/components/backend/LocationEditDialog.tsx +185 -0
- package/src/modules/wms/components/backend/MoveInventoryDialog.tsx +907 -0
- package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +695 -0
- package/src/modules/wms/components/backend/ReleaseReservationDialog.tsx +424 -0
- package/src/modules/wms/components/backend/ReserveInventoryDialog.tsx +511 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +1340 -0
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +1132 -0
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +1310 -0
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +1355 -0
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +359 -0
- package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +958 -0
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +1245 -0
- package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +960 -0
- package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +89 -0
- package/src/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.ts +32 -0
- package/src/modules/wms/components/backend/wmsLookupLoaders.ts +78 -0
- package/src/modules/wms/data/enrichers.ts +718 -0
- package/src/modules/wms/data/entities.ts +436 -0
- package/src/modules/wms/data/validators.ts +463 -0
- package/src/modules/wms/di.ts +25 -0
- package/src/modules/wms/events.ts +41 -0
- package/src/modules/wms/i18n/de.json +1051 -0
- package/src/modules/wms/i18n/en.json +1051 -0
- package/src/modules/wms/i18n/es.json +1051 -0
- package/src/modules/wms/i18n/pl.json +1051 -0
- package/src/modules/wms/index.ts +15 -0
- package/src/modules/wms/lib/catalogInventoryProfileIntent.ts +65 -0
- package/src/modules/wms/lib/catalogInventoryProfileSync.ts +199 -0
- package/src/modules/wms/lib/expiry.ts +30 -0
- package/src/modules/wms/lib/flashMutationError.ts +74 -0
- package/src/modules/wms/lib/inventoryDisplayUi.ts +249 -0
- package/src/modules/wms/lib/inventoryIdempotency.ts +54 -0
- package/src/modules/wms/lib/inventoryImportCsv.ts +212 -0
- package/src/modules/wms/lib/inventoryImportService.ts +629 -0
- package/src/modules/wms/lib/inventoryMutationUi.ts +21 -0
- package/src/modules/wms/lib/inventoryPolicy.ts +111 -0
- package/src/modules/wms/lib/inventoryReconciliation.ts +263 -0
- package/src/modules/wms/lib/inventoryTrackingValidation.ts +23 -0
- package/src/modules/wms/lib/loadOperationalDashboard.ts +776 -0
- package/src/modules/wms/lib/lowStockBalanceFilter.ts +74 -0
- package/src/modules/wms/lib/primaryWarehousePolicy.ts +46 -0
- package/src/modules/wms/lib/roleFeatures.ts +32 -0
- package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +390 -0
- package/src/modules/wms/lib/salesOrderWarehouseAssignment.ts +78 -0
- package/src/modules/wms/lib/wmsIntegrationToggles.ts +81 -0
- package/src/modules/wms/migrations/.snapshot-open-mercato.json +2880 -0
- package/src/modules/wms/migrations/Migration20260428110546.ts +91 -0
- package/src/modules/wms/migrations/Migration20260527120000.ts +15 -0
- package/src/modules/wms/migrations/Migration20260527140000.ts +35 -0
- package/src/modules/wms/migrations/Migration20260613120000.ts +21 -0
- package/src/modules/wms/migrations/Migration20260616090000.ts +11 -0
- package/src/modules/wms/migrations/Migration20260707180000.ts +13 -0
- package/src/modules/wms/notifications.client.ts +18 -0
- package/src/modules/wms/notifications.ts +51 -0
- package/src/modules/wms/search.ts +230 -0
- package/src/modules/wms/setup.ts +29 -0
- package/src/modules/wms/subscribers/low-stock-notification.ts +54 -0
- package/src/modules/wms/subscribers/reservation-shortfall-notification.ts +98 -0
- package/src/modules/wms/subscribers/sales-order-cancelled-release.ts +21 -0
- package/src/modules/wms/subscribers/sales-order-confirmed-reserve.ts +21 -0
- package/src/modules/wms/translations.ts +6 -0
- package/src/modules/wms/vector.ts +7 -0
- package/src/modules/wms/widgets/injection/catalog-inventory-profile/widget.ts +238 -0
- package/src/modules/wms/widgets/injection/order-items-stock-column/widget.tsx +153 -0
- package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +476 -0
- package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.ts +15 -0
- package/src/modules/wms/widgets/injection-table.ts +34 -0
- package/src/modules/wms/widgets/notifications/WmsLowStockRenderer.tsx +153 -0
- package/src/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.tsx +194 -0
- package/src/modules/wms/widgets/notifications/index.ts +2 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/wms/components/backend/ImportInventoryDialog.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ArrowRight, Check, FileText } from 'lucide-react'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { flashMutationError } from '../../lib/flashMutationError'\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 { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { KbdShortcut } from '@open-mercato/ui/primitives/kbd'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport {\n countMappedColumns,\n detectColumnMappings,\n mapCsvRowsWithMappings,\n parseCsvText,\n type DetectedColumnMapping,\n type InventoryImportRawRow,\n} from '../../lib/inventoryImportCsv'\nimport type { useWmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\nconst logger = createLogger('wms')\n\ntype ImportAccess = Pick<\n ReturnType<typeof useWmsInventoryMutationAccess>,\n 'organizationId' | 'tenantId' | 'userId' | 'scopeReady'\n>\n\ntype WizardStep = 1 | 2 | 3\n\ntype ValidationRow = {\n rowNumber: number\n status: 'valid' | 'error' | 'warning' | 'skip'\n errors: string[]\n warnings: string[]\n resolved?: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n quantity: number\n delta: number\n currentOnHand?: number\n lotId?: string\n serialNumber?: string\n sku?: string\n locationCode?: string\n warehouseCode?: string\n }\n}\n\ntype ValidationResponse = {\n ok?: boolean\n importBatchId?: string\n summary?: {\n totalRows?: number\n validRows?: number\n errorRows?: number\n warningRows?: number\n skipRows?: number\n }\n rows?: ValidationRow[]\n}\n\ntype ParsedFileMeta = {\n headers: string[]\n rowCount: number\n fileSize: number\n}\n\ntype ImportInventoryDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n access: ImportAccess\n}\n\nconst TARGET_FIELD_KEYS: Array<keyof InventoryImportRawRow> = [\n 'warehouseCode',\n 'locationCode',\n 'sku',\n 'quantity',\n 'lotNumber',\n 'serialNumber',\n]\n\nfunction ImportStepIndicator({ step }: { step: WizardStep }) {\n const steps = [1, 2, 3] as const\n\n return (\n <div className=\"flex items-center gap-1.5 pt-1\" aria-label={`Step ${step} of 3`}>\n {steps.map((stepNumber, index) => {\n const completed = stepNumber < step\n const current = stepNumber === step\n\n return (\n <React.Fragment key={stepNumber}>\n {index > 0 ? (\n <div\n className={cn(\n 'h-0.5 w-4 shrink-0',\n stepNumber <= step ? 'bg-foreground' : 'bg-border',\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <div\n className={cn(\n 'flex size-5 shrink-0 items-center justify-center rounded-full text-xs font-semibold',\n completed || current\n ? 'bg-foreground text-primary-foreground'\n : 'bg-muted text-muted-foreground',\n )}\n aria-current={current ? 'step' : undefined}\n >\n {completed ? <Check className=\"size-3\" aria-hidden=\"true\" /> : stepNumber}\n </div>\n </React.Fragment>\n )\n })}\n </div>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n const kilobytes = bytes / 1024\n if (kilobytes < 1024) return `${Math.round(kilobytes)} KB`\n return `${(kilobytes / 1024).toFixed(1)} MB`\n}\n\nfunction formatRowCount(value: number): string {\n return new Intl.NumberFormat().format(value)\n}\n\nfunction formatImportIssue(\n code: string,\n t: ReturnType<typeof useT>,\n): string {\n const duplicateMatch = /^duplicate_of_row_(\\d+)$/.exec(code)\n if (duplicateMatch) {\n return t(\n 'wms.backend.inventory.import.validation.duplicate_of_row',\n 'Duplicate of row {row}',\n { row: duplicateMatch[1] },\n )\n }\n return t(`wms.backend.inventory.import.validation.${code}`, code)\n}\n\nexport function ImportInventoryDialog({ open, onOpenChange, access }: ImportInventoryDialogProps) {\n const t = useT()\n const queryClient = useQueryClient()\n const fileInputRef = React.useRef<HTMLInputElement>(null)\n const [step, setStep] = React.useState<WizardStep>(1)\n const [selectedFile, setSelectedFile] = React.useState<File | null>(null)\n const [parsedFile, setParsedFile] = React.useState<ParsedFileMeta | null>(null)\n const [columnMappings, setColumnMappings] = React.useState<DetectedColumnMapping[]>([])\n const [validation, setValidation] = React.useState<ValidationResponse | null>(null)\n const [validating, setValidating] = React.useState(false)\n const [applying, setApplying] = React.useState(false)\n const [showIssueDetails, setShowIssueDetails] = React.useState(false)\n const [skipDuplicates, setSkipDuplicates] = React.useState(true)\n const [reconcileMode, setReconcileMode] = React.useState(false)\n const [isDragging, setIsDragging] = React.useState(false)\n const { runMutation, retryLastMutation } = useGuardedMutation({ contextId: 'wms-inventory-import' })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n\n const resetState = React.useCallback(() => {\n setStep(1)\n setSelectedFile(null)\n setParsedFile(null)\n setColumnMappings([])\n setValidation(null)\n setValidating(false)\n setApplying(false)\n setShowIssueDetails(false)\n setSkipDuplicates(true)\n setReconcileMode(false)\n setIsDragging(false)\n }, [])\n\n const closeDialog = React.useCallback(() => {\n onOpenChange(false)\n resetState()\n }, [onOpenChange, resetState])\n\n React.useEffect(() => {\n if (!open) resetState()\n }, [open, resetState])\n\n const targetFieldLabel = React.useCallback(\n (field: keyof InventoryImportRawRow) => {\n const labels: Record<keyof InventoryImportRawRow, string> = {\n warehouseCode: t('wms.backend.inventory.import.mapping.fields.warehouseCode', 'warehouse_code'),\n warehouseId: t('wms.backend.inventory.import.mapping.fields.warehouseId', 'warehouse_id'),\n locationCode: t('wms.backend.inventory.import.mapping.fields.locationCode', 'location_code'),\n locationId: t('wms.backend.inventory.import.mapping.fields.locationId', 'location_id'),\n sku: t('wms.backend.inventory.import.mapping.fields.sku', 'sku'),\n catalogVariantId: t(\n 'wms.backend.inventory.import.mapping.fields.catalogVariantId',\n 'catalog_variant_id',\n ),\n quantity: t('wms.backend.inventory.import.mapping.fields.quantity', 'quantity'),\n lotNumber: t('wms.backend.inventory.import.mapping.fields.lotNumber', 'lot_number'),\n lotId: t('wms.backend.inventory.import.mapping.fields.lotId', 'lot_id'),\n serialNumber: t('wms.backend.inventory.import.mapping.fields.serialNumber', 'serial_number'),\n }\n return labels[field]\n },\n [t],\n )\n\n const parseSelectedFile = React.useCallback(async (file: File) => {\n const text = await file.text()\n const parsed = parseCsvText(text)\n const meta: ParsedFileMeta = {\n headers: parsed.headers,\n rowCount: parsed.rows.length,\n fileSize: file.size,\n }\n setParsedFile(meta)\n setColumnMappings(detectColumnMappings(parsed.headers))\n setValidation(null)\n }, [])\n\n const handleFileSelection = React.useCallback(\n async (file: File | null) => {\n setSelectedFile(file)\n if (!file) {\n setParsedFile(null)\n setColumnMappings([])\n setValidation(null)\n return\n }\n await parseSelectedFile(file)\n },\n [parseSelectedFile],\n )\n\n const handleDownloadTemplate = React.useCallback(() => {\n const anchor = document.createElement('a')\n anchor.href = '/api/wms/inventory/import/template'\n anchor.download = 'wms-inventory-import-template.csv'\n anchor.click()\n }, [])\n\n const handleAutoMap = React.useCallback(() => {\n if (!parsedFile) return\n setColumnMappings(detectColumnMappings(parsedFile.headers))\n }, [parsedFile])\n\n const handleReconcileModeChange = React.useCallback((checked: boolean) => {\n setReconcileMode(checked)\n setValidation(null)\n }, [])\n\n const handleMappingChange = React.useCallback(\n (csvColumn: string, value: string) => {\n setColumnMappings((current) =>\n current.map((mapping) => {\n if (mapping.csvColumn !== csvColumn) return mapping\n if (value === 'skip') {\n return { ...mapping, targetField: null, status: 'skipped' }\n }\n return {\n ...mapping,\n targetField: value as keyof InventoryImportRawRow,\n status: 'mapped',\n }\n }),\n )\n setValidation(null)\n },\n [],\n )\n\n const handleDragOver = React.useCallback((event: React.DragEvent<HTMLButtonElement>) => {\n event.preventDefault()\n event.stopPropagation()\n setIsDragging(true)\n }, [])\n\n const handleDragLeave = React.useCallback((event: React.DragEvent<HTMLButtonElement>) => {\n event.preventDefault()\n event.stopPropagation()\n setIsDragging(false)\n }, [])\n\n const handleDrop = React.useCallback(\n (event: React.DragEvent<HTMLButtonElement>) => {\n event.preventDefault()\n event.stopPropagation()\n setIsDragging(false)\n const file = event.dataTransfer.files?.[0]\n if (file) void handleFileSelection(file)\n },\n [handleFileSelection],\n )\n\n const handleValidate = React.useCallback(async () => {\n if (!access.scopeReady || !access.organizationId || !access.tenantId) {\n flash(t('wms.backend.inventory.import.errors.scope', 'Select organization scope before importing.'), 'error')\n return false\n }\n if (!selectedFile) {\n flash(t('wms.backend.inventory.import.errors.file', 'Choose a CSV file first.'), 'error')\n return false\n }\n\n setValidating(true)\n try {\n const text = await selectedFile.text()\n const parsed = parseCsvText(text)\n const rows = mapCsvRowsWithMappings(parsed.headers, parsed.rows, columnMappings)\n const call = await apiCall<ValidationResponse>('/api/wms/inventory/import/validate', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId: access.organizationId,\n tenantId: access.tenantId,\n skipDuplicates,\n mode: reconcileMode ? 'reconcile' : 'additive',\n rows,\n }),\n })\n if (!call.ok) {\n await raiseCrudError(\n call.response,\n t('wms.backend.inventory.import.errors.validate', 'Validation failed.'),\n )\n }\n setValidation(call.result ?? null)\n if (call.result?.ok) {\n flash(t('wms.backend.inventory.import.flash.validated', 'CSV validated \u2014 review rows before applying.'), 'success')\n } else {\n flash(t('wms.backend.inventory.import.flash.validationErrors', 'Fix validation errors before applying.'), 'error')\n }\n return Boolean(call.result)\n } catch (error) {\n logger.error('validate failed', { component: 'ImportInventoryDialog', err: error })\n flash(t('wms.backend.inventory.import.errors.validate', 'Validation failed.'), 'error')\n return false\n } finally {\n setValidating(false)\n }\n }, [\n access.organizationId,\n access.scopeReady,\n access.tenantId,\n columnMappings,\n reconcileMode,\n selectedFile,\n skipDuplicates,\n t,\n ])\n\n const applyRows = React.useMemo(() => {\n return (validation?.rows ?? [])\n .filter((row) => row.resolved && (row.status === 'valid' || row.status === 'warning' || row.status === 'skip'))\n .map((row) => ({\n rowNumber: row.rowNumber,\n warehouseId: row.resolved!.warehouseId,\n locationId: row.resolved!.locationId,\n catalogVariantId: row.resolved!.catalogVariantId,\n quantity: row.resolved!.quantity,\n delta: row.resolved!.delta,\n lotId: row.resolved!.lotId,\n serialNumber: row.resolved!.serialNumber,\n }))\n }, [validation?.rows])\n\n const overwriteWarningRows = React.useMemo(() => {\n return (validation?.rows ?? []).filter(\n (row) => row.status === 'warning' && row.warnings.includes('overwriting_existing_balance'),\n )\n }, [validation?.rows])\n\n const importableRowCount = React.useMemo(() => {\n return applyRows.filter((row) => Math.abs(row.delta) > 0.000001).length\n }, [applyRows])\n\n const canApply =\n Boolean(validation?.importBatchId) &&\n importableRowCount > 0\n\n const issueRows = React.useMemo(() => {\n return (validation?.rows ?? []).filter(\n (row) => row.status === 'error' || row.status === 'skip' || row.errors.length > 0,\n )\n }, [validation?.rows])\n\n const previewRows = React.useMemo(() => {\n return (validation?.rows ?? [])\n .filter((row) => row.resolved && (row.status === 'valid' || row.status === 'warning'))\n .slice(0, 3)\n }, [validation?.rows])\n\n const mappedColumnCount = countMappedColumns(columnMappings)\n\n const handleApply = React.useCallback(async () => {\n if (!access.scopeReady || !access.organizationId || !access.tenantId) return\n if (!validation?.importBatchId) return\n\n const mutationPayload: Record<string, unknown> = {\n organizationId: access.organizationId,\n tenantId: access.tenantId,\n importBatchId: validation.importBatchId,\n rows: applyRows,\n }\n\n setApplying(true)\n try {\n const result = await runMutation({\n operation: async () => {\n const call = await apiCall<{\n ok?: boolean\n summary?: { applied?: number; skipped?: number; failed?: number }\n }>(\n '/api/wms/inventory/import/apply',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId: access.organizationId,\n tenantId: access.tenantId,\n importBatchId: validation.importBatchId,\n reason: reconcileMode\n ? t('wms.backend.inventory.import.defaultReasonReconcile', 'CSV import opening balance')\n : t('wms.backend.inventory.import.defaultReason', 'CSV import inventory receipt'),\n continueOnError: true,\n mode: reconcileMode ? 'reconcile' : 'additive',\n rows: applyRows,\n }),\n },\n )\n if (!call.ok) {\n await raiseCrudError(\n call.response,\n t('wms.backend.inventory.import.errors.apply', 'Import failed.'),\n )\n }\n return call.result ?? {}\n },\n context: mutationContext,\n mutationPayload,\n })\n\n const applied = result?.summary?.applied ?? 0\n const skipped = result?.summary?.skipped ?? 0\n const failed = result?.summary?.failed ?? 0\n if (failed > 0) {\n flash(\n t(\n 'wms.backend.inventory.import.flash.appliedPartial',\n 'Import finished with errors ({applied} applied, {skipped} skipped, {failed} failed).',\n { applied, skipped, failed },\n ),\n 'warning',\n )\n } else {\n flash(\n t('wms.backend.inventory.import.flash.applied', 'Import finished ({applied} applied, {skipped} skipped).', {\n applied,\n skipped,\n }),\n 'success',\n )\n }\n await queryClient.invalidateQueries({ queryKey: ['wms-inventory-console'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-sku-detail'] })\n closeDialog()\n } catch (error) {\n flashMutationError(error, t('wms.backend.inventory.import.errors.apply', 'Import failed.'), t)\n } finally {\n setApplying(false)\n }\n }, [\n access.organizationId,\n access.scopeReady,\n access.tenantId,\n applyRows,\n closeDialog,\n queryClient,\n mutationContext,\n reconcileMode,\n runMutation,\n t,\n validation?.importBatchId,\n ])\n\n const handlePrimaryAction = React.useCallback(async () => {\n if (step === 1) {\n if (!selectedFile) {\n flash(t('wms.backend.inventory.import.errors.file', 'Choose a CSV file first.'), 'error')\n return\n }\n setStep(2)\n return\n }\n if (step === 2) {\n const validated = await handleValidate()\n if (validated) setStep(3)\n return\n }\n await handleApply()\n }, [handleApply, handleValidate, selectedFile, step, t])\n\n const handleDialogKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n closeDialog()\n return\n }\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (validating || applying) return\n if (step === 3 && !canApply) return\n void handlePrimaryAction()\n }\n },\n [applying, canApply, closeDialog, handlePrimaryAction, step, validating],\n )\n\n const stepSubtitle = React.useMemo(() => {\n if (step === 1) {\n return t('wms.backend.inventory.import.steps.upload.subtitle', 'Step 1 of 3 \u00B7 Upload your file')\n }\n if (step === 2) {\n return t(\n 'wms.backend.inventory.import.steps.mapping.subtitle',\n 'Step 2 of 3 \u00B7 Map CSV columns to fields',\n )\n }\n return t('wms.backend.inventory.import.steps.review.subtitle', 'Step 3 of 3 \u00B7 Review and import')\n }, [step, t])\n\n const shortcutHint = React.useMemo(() => {\n if (step === 3) {\n return t('wms.backend.inventory.import.shortcut.import', 'to import')\n }\n return t('wms.backend.inventory.import.shortcut.continue', 'continue')\n }, [step, t])\n\n const primaryDisabled =\n validating ||\n applying ||\n (step === 1 && !selectedFile) ||\n (step === 3 && !canApply)\n\n const primaryLabel = React.useMemo(() => {\n if (step === 1 || step === 2) {\n return validating\n ? t('wms.backend.inventory.import.actions.validating', 'Validating\u2026')\n : t('wms.backend.inventory.import.actions.next', 'Next')\n }\n return applying\n ? t('wms.backend.inventory.import.actions.applying', 'Importing\u2026')\n : t('wms.backend.inventory.import.actions.importRows', 'Import {count} rows', {\n count: formatRowCount(importableRowCount),\n })\n }, [applying, importableRowCount, step, t, validating])\n\n return (\n <Dialog open={open} onOpenChange={(next) => (next ? onOpenChange(true) : closeDialog())}>\n <DialogContent\n className=\"max-w-2xl gap-0 overflow-hidden p-0\"\n onKeyDown={handleDialogKeyDown}\n >\n <div className=\"border-b px-6 py-4 pr-12\">\n <DialogHeader className=\"space-y-1 text-left\">\n <DialogTitle>{t('wms.backend.inventory.import.dialog.title', 'Import CSV')}</DialogTitle>\n <DialogDescription>{stepSubtitle}</DialogDescription>\n <ImportStepIndicator step={step} />\n </DialogHeader>\n </div>\n\n <div className=\"flex max-h-[min(70vh,640px)] flex-col gap-5 overflow-y-auto px-6 py-6\">\n {step === 1 ? (\n <>\n <button\n type=\"button\"\n className={cn(\n 'flex w-full flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-5 py-8 text-center transition-colors',\n isDragging\n ? 'border-border bg-muted/60'\n : selectedFile\n ? 'border-border bg-muted/40 hover:bg-muted/60'\n : 'border-border bg-muted/20 hover:bg-muted/40',\n )}\n onClick={() => fileInputRef.current?.click()}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {selectedFile ? (\n <>\n <div className=\"flex items-center gap-2\">\n <FileText className=\"size-5 text-foreground\" aria-hidden=\"true\" />\n <p className=\"text-sm font-semibold text-foreground\">{selectedFile.name}</p>\n </div>\n {parsedFile ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.inventory.import.upload.fileMeta',\n '{rows} rows \u00B7 {size} \u00B7 detected',\n {\n rows: formatRowCount(parsedFile.rowCount),\n size: formatFileSize(parsedFile.fileSize),\n },\n )}\n </p>\n ) : null}\n <span className=\"text-xs font-medium text-foreground\">\n {t('wms.backend.inventory.import.actions.chooseDifferent', 'Choose different file')}\n </span>\n </>\n ) : (\n <>\n <FileText className=\"size-5 text-muted-foreground\" aria-hidden=\"true\" />\n <p className=\"text-sm font-medium text-foreground\">\n {t('wms.backend.inventory.import.upload.dropzoneEmpty', 'Choose CSV file or drop here')}\n </p>\n </>\n )}\n </button>\n <Input\n ref={fileInputRef}\n type=\"file\"\n accept=\".csv,text/csv\"\n className=\"hidden\"\n onChange={(event) => {\n void handleFileSelection(event.target.files?.[0] ?? null)\n }}\n />\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <p className=\"text-sm font-semibold text-foreground\">\n {t('wms.backend.inventory.import.upload.format', 'Format')}\n </p>\n <Select value=\"csv-comma\" disabled>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"csv-comma\">\n {t(\n 'wms.backend.inventory.import.upload.formatValue',\n 'CSV \u00B7 comma-separated',\n )}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <p className=\"text-sm font-semibold text-foreground\">\n {t('wms.backend.inventory.import.upload.encoding', 'Encoding')}\n </p>\n <Select value=\"utf8\" disabled>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"utf8\">\n {t(\n 'wms.backend.inventory.import.upload.encodingValue',\n 'UTF-8 (auto-detected)',\n )}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex justify-start\">\n <Button type=\"button\" variant=\"outline\" onClick={() => void handleDownloadTemplate()}>\n {t('wms.backend.inventory.import.actions.template', 'Download template')}\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.inventory.import.upload.skuHint',\n 'The sku column must match an existing catalog product variant in your organization. Warehouse and location codes must already exist in WMS.',\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.inventory.import.upload.quantityHint',\n 'The quantity column is added to whatever stock already exists at that warehouse/location \u2014 it is not a target balance.',\n )}\n </p>\n </div>\n\n <div className=\"flex items-start gap-3 rounded-lg border border-status-warning-border bg-status-warning-bg px-3 py-3\">\n <Switch checked={reconcileMode} onCheckedChange={handleReconcileModeChange} />\n <div className=\"space-y-0.5\">\n <p className=\"text-sm font-semibold text-status-warning-text\">\n {t('wms.backend.inventory.import.upload.reconcileMode', 'Reconcile to exact balance')}\n </p>\n <p className=\"text-xs text-status-warning-text\">\n {t(\n 'wms.backend.inventory.import.upload.reconcileModeHint',\n 'Existing stock at each location is overwritten to match the file exactly \u2014 including reducing it. Use this for a full stocktake or opening-balance import. Leave off to add quantities to existing stock instead.',\n )}\n </p>\n </div>\n </div>\n </>\n ) : null}\n\n {step === 2 ? (\n <>\n <div className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/50 px-3 py-2 text-xs font-medium text-foreground\">\n <p>\n {t(\n 'wms.backend.inventory.import.mapping.summary',\n '{mapped} of {total} columns mapped \u00B7 {rows} rows detected',\n {\n mapped: mappedColumnCount,\n total: columnMappings.length,\n rows: formatRowCount(parsedFile?.rowCount ?? 0),\n },\n )}\n </p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-auto px-1 py-0 text-xs font-medium\"\n onClick={handleAutoMap}\n >\n {t('wms.backend.inventory.import.actions.autoMap', 'Auto-map')}\n <ArrowRight className=\"size-3.5\" aria-hidden=\"true\" />\n </Button>\n </div>\n\n <div className=\"rounded-lg border bg-muted/30 px-3 py-2\">\n <div className=\"grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)_auto] items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n <span>{t('wms.backend.inventory.import.mapping.csvColumn', 'CSV column')}</span>\n <span aria-hidden=\"true\" />\n <span>{t('wms.backend.inventory.import.mapping.targetField', 'Target field')}</span>\n <span className=\"text-right\">\n {t('wms.backend.inventory.import.mapping.status', 'Status')}\n </span>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n {columnMappings.map((mapping) => (\n <div\n key={mapping.csvColumn}\n className=\"grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)_auto] items-center gap-2 rounded-lg border px-3 py-2.5\"\n >\n <p className=\"truncate text-sm font-semibold text-foreground\">{mapping.csvColumn}</p>\n <span className=\"text-sm text-muted-foreground\" aria-hidden=\"true\">\n \u2192\n </span>\n <Select\n value={mapping.targetField ?? 'skip'}\n onValueChange={(value) => handleMappingChange(mapping.csvColumn, value)}\n >\n <SelectTrigger className=\"h-9\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TARGET_FIELD_KEYS.map((field) => (\n <SelectItem key={field} value={field}>\n {targetFieldLabel(field)}\n </SelectItem>\n ))}\n <SelectItem value=\"skip\">\n {t('wms.backend.inventory.import.mapping.skipColumn', '\u2014 skip column')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex justify-end\">\n <StatusBadge variant={mapping.status === 'mapped' ? 'success' : 'neutral'}>\n {mapping.status === 'mapped'\n ? t('wms.backend.inventory.import.mapping.status.mapped', 'Mapped')\n : t('wms.backend.inventory.import.mapping.status.skipped', 'Skipped')}\n </StatusBadge>\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"flex items-start gap-3 rounded-lg border px-3 py-3\">\n <Switch checked={skipDuplicates} onCheckedChange={setSkipDuplicates} />\n <div className=\"space-y-0.5\">\n <p className=\"text-sm font-semibold text-foreground\">\n {t('wms.backend.inventory.import.review.skipDuplicates', 'Skip duplicates')}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.backend.inventory.import.review.skipDuplicatesHint',\n 'Duplicate rows in the CSV file will be skipped instead of failing validation',\n )}\n </p>\n </div>\n </div>\n </>\n ) : null}\n\n {step === 3 && validation ? (\n <>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div className=\"rounded-lg border px-3.5 py-3\">\n <p className=\"text-2xl font-bold tabular-nums text-foreground\">\n {formatRowCount(importableRowCount)}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t('wms.backend.inventory.import.review.stats.rows', 'Rows to import')}\n </p>\n </div>\n <div className=\"rounded-lg border px-3.5 py-3\">\n <p className=\"text-2xl font-bold tabular-nums text-status-success-icon\">\n {mappedColumnCount}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t('wms.backend.inventory.import.review.stats.columns', 'Columns mapped')}\n </p>\n </div>\n <div className=\"rounded-lg border px-3.5 py-3\">\n <p className=\"text-2xl font-bold tabular-nums text-status-warning-icon\">\n {issueRows.length}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t('wms.backend.inventory.import.review.stats.issues', 'Validation issues')}\n </p>\n </div>\n </div>\n\n {issueRows.length > 0 ? (\n <div className=\"rounded-lg border border-status-warning-border bg-status-warning-bg px-4 py-3.5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold text-status-warning-text\">\n {t(\n 'wms.backend.inventory.import.review.banner.title',\n '{count} rows will be skipped on import',\n { count: issueRows.length },\n )}\n </p>\n <div className=\"space-y-0.5 text-xs text-muted-foreground\">\n {(showIssueDetails ? issueRows : issueRows.slice(0, 2)).map((row) => (\n <p key={row.rowNumber}>\n {t(\n 'wms.backend.inventory.import.review.banner.rowIssue',\n 'Row {row}: {issue}',\n {\n row: row.rowNumber,\n issue: [...row.errors, ...row.warnings].map((code) => formatImportIssue(code, t)).join(', ') || row.status,\n },\n )}\n </p>\n ))}\n </div>\n </div>\n {issueRows.length > 2 ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-auto shrink-0 px-1 py-0 text-xs font-medium text-status-warning-text hover:text-status-warning-text\"\n onClick={() => setShowIssueDetails((current) => !current)}\n >\n {showIssueDetails\n ? t('wms.backend.inventory.import.actions.hideDetails', 'Hide details')\n : t('wms.backend.inventory.import.actions.viewDetails', 'View details \u2192')}\n </Button>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {overwriteWarningRows.length > 0 ? (\n <div className=\"rounded-lg border border-status-warning-border bg-status-warning-bg px-4 py-3.5\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold text-status-warning-text\">\n {t(\n 'wms.backend.inventory.import.review.overwriteBanner.title',\n '{count} rows will change existing stock levels',\n { count: overwriteWarningRows.length },\n )}\n </p>\n <div className=\"space-y-0.5 text-xs text-muted-foreground\">\n {overwriteWarningRows.map((row) => {\n const current = row.resolved?.currentOnHand ?? 0\n const quantity = row.resolved?.quantity ?? 0\n const delta = row.resolved?.delta ?? 0\n const signedDelta = delta > 0 ? `+${delta}` : `${delta}`\n return (\n <p key={row.rowNumber}>\n {t(\n 'wms.backend.inventory.import.review.overwriteBanner.rowDetail',\n 'Row {row}: {location} \u2014 {current} \u2192 {quantity} ({delta})',\n {\n row: row.rowNumber,\n location: row.resolved?.locationCode ?? '\u2014',\n current,\n quantity,\n delta: signedDelta,\n },\n )}\n </p>\n )\n })}\n </div>\n </div>\n </div>\n ) : null}\n\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('wms.backend.inventory.import.review.preview.title', 'Preview \u00B7 first 3 rows')}\n </p>\n <div className=\"overflow-hidden rounded-lg border\">\n <div className=\"grid grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)_minmax(0,1fr)_auto] gap-3 border-b bg-muted/40 px-3.5 py-2.5 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n <span>{t('wms.backend.inventory.import.columns.sku', 'SKU')}</span>\n <span>{t('wms.backend.inventory.import.columns.location', 'Location')}</span>\n <span>{t('wms.backend.inventory.import.review.preview.lot', 'Lot')}</span>\n <span className=\"text-right\">\n {t('wms.backend.inventory.import.review.preview.qty', 'Qty')}\n </span>\n </div>\n {previewRows.length > 0 ? (\n previewRows.map((row) => (\n <div\n key={row.rowNumber}\n className=\"grid grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)_minmax(0,1fr)_auto] gap-3 border-b px-3.5 py-2.5 text-xs last:border-b-0\"\n >\n <span className=\"truncate font-medium text-foreground\">\n {row.resolved?.sku ?? '\u2014'}\n </span>\n <span className=\"truncate text-foreground\">\n {row.resolved?.locationCode ?? '\u2014'}\n </span>\n <span className=\"truncate text-muted-foreground\">\n {row.resolved?.serialNumber ?? row.resolved?.lotId ?? '\u2014'}\n </span>\n <span className=\"text-right font-semibold tabular-nums text-foreground\">\n {row.resolved?.quantity ?? '\u2014'}\n </span>\n </div>\n ))\n ) : (\n <p className=\"px-3.5 py-4 text-sm text-muted-foreground\">\n {t('wms.backend.inventory.import.review.preview.empty', 'No preview rows available.')}\n </p>\n )}\n </div>\n </div>\n </>\n ) : null}\n </div>\n\n <DialogFooter bordered={false} className=\"border-t px-6 py-4 sm:justify-between\">\n <p className=\"hidden text-xs text-muted-foreground sm:inline-flex sm:items-center sm:gap-1.5\">\n <KbdShortcut keys={['\u2318', 'Enter']} />\n <span>/</span>\n <KbdShortcut keys={['Ctrl', 'Enter']} />\n <span>{shortcutHint}</span>\n </p>\n <div className=\"flex w-full flex-col-reverse gap-2 sm:w-auto sm:flex-row\">\n {step === 1 ? (\n <Button type=\"button\" variant=\"outline\" onClick={closeDialog} disabled={validating || applying}>\n {t('wms.backend.inventory.import.actions.cancel', 'Cancel')}\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setStep((current) => (current === 3 ? 2 : 1))}\n disabled={validating || applying}\n >\n {t('wms.backend.inventory.import.actions.back', 'Back')}\n </Button>\n )}\n <Button\n type=\"button\"\n disabled={primaryDisabled}\n onClick={() => void handlePrimaryAction()}\n >\n {primaryLabel}\n {step !== 3 ? <ArrowRight className=\"size-4\" aria-hidden=\"true\" /> : null}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
6
|
+
import { ArrowDown, ArrowLeftRight, ClipboardList, ShieldCheck, SlidersHorizontal, Upload } from "lucide-react";
|
|
7
|
+
import { AdjustInventoryDialog } from "./AdjustInventoryDialog.js";
|
|
8
|
+
import { CycleCountWizardDialog } from "./CycleCountWizardDialog.js";
|
|
9
|
+
import { ImportInventoryDialog } from "./ImportInventoryDialog.js";
|
|
10
|
+
import { MoveInventoryDialog } from "./MoveInventoryDialog.js";
|
|
11
|
+
import { ReceiveInventoryDialog } from "./ReceiveInventoryDialog.js";
|
|
12
|
+
import { ReserveInventoryDialog } from "./ReserveInventoryDialog.js";
|
|
13
|
+
function SectionCard({
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
children
|
|
17
|
+
}) {
|
|
18
|
+
return /* @__PURE__ */ jsx("section", { className: "rounded-lg border bg-card p-5 text-card-foreground shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold", children: title }),
|
|
21
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
22
|
+
] }),
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children })
|
|
24
|
+
] }) });
|
|
25
|
+
}
|
|
26
|
+
function InventoryOperationsSection({
|
|
27
|
+
access
|
|
28
|
+
}) {
|
|
29
|
+
const t = useT();
|
|
30
|
+
const [adjustOpen, setAdjustOpen] = React.useState(false);
|
|
31
|
+
const [receiveOpen, setReceiveOpen] = React.useState(false);
|
|
32
|
+
const [reserveOpen, setReserveOpen] = React.useState(false);
|
|
33
|
+
const [moveOpen, setMoveOpen] = React.useState(false);
|
|
34
|
+
const [cycleOpen, setCycleOpen] = React.useState(false);
|
|
35
|
+
const [importOpen, setImportOpen] = React.useState(false);
|
|
36
|
+
const [putawayContext, setPutawayContext] = React.useState(null);
|
|
37
|
+
const handleReceiveSuccess = React.useCallback(
|
|
38
|
+
(ctx) => {
|
|
39
|
+
if (access.canMove) {
|
|
40
|
+
setPutawayContext(ctx);
|
|
41
|
+
setMoveOpen(true);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
[access.canMove]
|
|
45
|
+
);
|
|
46
|
+
if (!access.scopeReady) return null;
|
|
47
|
+
if (!access.canAdjust && !access.canReceive && !access.canReserve && !access.canMove && !access.canCycleCount && !access.canImport) return null;
|
|
48
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
|
+
/* @__PURE__ */ jsxs(
|
|
50
|
+
SectionCard,
|
|
51
|
+
{
|
|
52
|
+
title: t("wms.backend.inventory.operations.title", "Inventory operations"),
|
|
53
|
+
description: t(
|
|
54
|
+
"wms.backend.inventory.operations.description",
|
|
55
|
+
"Receive inbound stock, reserve or move stock, post adjustments, or run a cycle count."
|
|
56
|
+
),
|
|
57
|
+
children: [
|
|
58
|
+
access.canImport ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", onClick: () => setImportOpen(true), children: [
|
|
59
|
+
/* @__PURE__ */ jsx(Upload, { className: "size-4" }),
|
|
60
|
+
t("wms.backend.inventory.operations.import", "Import CSV")
|
|
61
|
+
] }) : null,
|
|
62
|
+
access.canAdjust ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", onClick: () => setAdjustOpen(true), children: [
|
|
63
|
+
/* @__PURE__ */ jsx(SlidersHorizontal, { className: "size-4" }),
|
|
64
|
+
t("wms.backend.inventory.operations.adjust", "Adjust inventory")
|
|
65
|
+
] }) : null,
|
|
66
|
+
access.canCycleCount ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", onClick: () => setCycleOpen(true), children: [
|
|
67
|
+
/* @__PURE__ */ jsx(ClipboardList, { className: "size-4" }),
|
|
68
|
+
t("wms.backend.inventory.operations.cycleCount", "Cycle count")
|
|
69
|
+
] }) : null,
|
|
70
|
+
access.canMove ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", onClick: () => setMoveOpen(true), children: [
|
|
71
|
+
/* @__PURE__ */ jsx(ArrowLeftRight, { className: "size-4" }),
|
|
72
|
+
t("wms.backend.inventory.operations.move", "Move stock")
|
|
73
|
+
] }) : null,
|
|
74
|
+
access.canReserve ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", onClick: () => setReserveOpen(true), children: [
|
|
75
|
+
/* @__PURE__ */ jsx(ShieldCheck, { className: "size-4" }),
|
|
76
|
+
t("wms.backend.inventory.operations.reserve", "Reserve")
|
|
77
|
+
] }) : null,
|
|
78
|
+
access.canReceive ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "default", onClick: () => setReceiveOpen(true), children: [
|
|
79
|
+
/* @__PURE__ */ jsx(ArrowDown, { className: "size-4" }),
|
|
80
|
+
t("wms.backend.inventory.operations.receive", "Receive stock")
|
|
81
|
+
] }) : null
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
access.canImport ? /* @__PURE__ */ jsx(ImportInventoryDialog, { open: importOpen, onOpenChange: setImportOpen, access }) : null,
|
|
86
|
+
access.canAdjust ? /* @__PURE__ */ jsx(AdjustInventoryDialog, { open: adjustOpen, onOpenChange: setAdjustOpen, access }) : null,
|
|
87
|
+
access.canReceive ? /* @__PURE__ */ jsx(
|
|
88
|
+
ReceiveInventoryDialog,
|
|
89
|
+
{
|
|
90
|
+
open: receiveOpen,
|
|
91
|
+
onOpenChange: setReceiveOpen,
|
|
92
|
+
access,
|
|
93
|
+
onSuccess: handleReceiveSuccess
|
|
94
|
+
}
|
|
95
|
+
) : null,
|
|
96
|
+
access.canReserve ? /* @__PURE__ */ jsx(ReserveInventoryDialog, { open: reserveOpen, onOpenChange: setReserveOpen, access }) : null,
|
|
97
|
+
access.canMove ? /* @__PURE__ */ jsx(
|
|
98
|
+
MoveInventoryDialog,
|
|
99
|
+
{
|
|
100
|
+
open: moveOpen,
|
|
101
|
+
onOpenChange: (next) => {
|
|
102
|
+
setMoveOpen(next);
|
|
103
|
+
if (!next) setPutawayContext(null);
|
|
104
|
+
},
|
|
105
|
+
access,
|
|
106
|
+
initialCatalogVariantId: putawayContext?.catalogVariantId,
|
|
107
|
+
initialWarehouseId: putawayContext?.warehouseId,
|
|
108
|
+
initialFromLocationId: putawayContext?.locationId,
|
|
109
|
+
movementType: putawayContext ? "putaway" : "transfer",
|
|
110
|
+
lockSourceContext: Boolean(putawayContext)
|
|
111
|
+
}
|
|
112
|
+
) : null,
|
|
113
|
+
access.canCycleCount ? /* @__PURE__ */ jsx(CycleCountWizardDialog, { open: cycleOpen, onOpenChange: setCycleOpen, access }) : null
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
InventoryOperationsSection
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=InventoryOperationsSection.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/wms/components/backend/InventoryOperationsSection.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { ArrowDown, ArrowLeftRight, ClipboardList, ShieldCheck, SlidersHorizontal, Upload } from 'lucide-react'\nimport { AdjustInventoryDialog } from './AdjustInventoryDialog'\nimport { CycleCountWizardDialog } from './CycleCountWizardDialog'\nimport { ImportInventoryDialog } from './ImportInventoryDialog'\nimport { MoveInventoryDialog } from './MoveInventoryDialog'\nimport { ReceiveInventoryDialog } from './ReceiveInventoryDialog'\nimport { ReserveInventoryDialog } from './ReserveInventoryDialog'\nimport type { WmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\nfunction SectionCard({\n title,\n description,\n children,\n}: {\n title: string\n description: string\n children: React.ReactNode\n}) {\n return (\n <section className=\"rounded-lg border bg-card p-5 text-card-foreground shadow-sm\">\n <div className=\"mb-4 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0 space-y-1\">\n <h2 className=\"text-xl font-semibold\">{title}</h2>\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">{children}</div>\n </div>\n </section>\n )\n}\n\nexport function InventoryOperationsSection({\n access,\n}: {\n access: WmsInventoryMutationAccess\n}) {\n const t = useT()\n const [adjustOpen, setAdjustOpen] = React.useState(false)\n const [receiveOpen, setReceiveOpen] = React.useState(false)\n const [reserveOpen, setReserveOpen] = React.useState(false)\n const [moveOpen, setMoveOpen] = React.useState(false)\n const [cycleOpen, setCycleOpen] = React.useState(false)\n const [importOpen, setImportOpen] = React.useState(false)\n const [putawayContext, setPutawayContext] = React.useState<{\n catalogVariantId: string\n warehouseId: string\n locationId: string\n quantity: number\n } | null>(null)\n\n const handleReceiveSuccess = React.useCallback(\n (ctx: { catalogVariantId: string; warehouseId: string; locationId: string; quantity: number }) => {\n if (access.canMove) {\n setPutawayContext(ctx)\n setMoveOpen(true)\n }\n },\n [access.canMove],\n )\n\n if (!access.scopeReady) return null\n if (\n !access.canAdjust &&\n !access.canReceive &&\n !access.canReserve &&\n !access.canMove &&\n !access.canCycleCount &&\n !access.canImport\n ) return null\n\n return (\n <>\n <SectionCard\n title={t('wms.backend.inventory.operations.title', 'Inventory operations')}\n description={t(\n 'wms.backend.inventory.operations.description',\n 'Receive inbound stock, reserve or move stock, post adjustments, or run a cycle count.',\n )}\n >\n {access.canImport ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setImportOpen(true)}>\n <Upload className=\"size-4\" />\n {t('wms.backend.inventory.operations.import', 'Import CSV')}\n </Button>\n ) : null}\n {access.canAdjust ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setAdjustOpen(true)}>\n <SlidersHorizontal className=\"size-4\" />\n {t('wms.backend.inventory.operations.adjust', 'Adjust inventory')}\n </Button>\n ) : null}\n {access.canCycleCount ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setCycleOpen(true)}>\n <ClipboardList className=\"size-4\" />\n {t('wms.backend.inventory.operations.cycleCount', 'Cycle count')}\n </Button>\n ) : null}\n {access.canMove ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setMoveOpen(true)}>\n <ArrowLeftRight className=\"size-4\" />\n {t('wms.backend.inventory.operations.move', 'Move stock')}\n </Button>\n ) : null}\n {access.canReserve ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => setReserveOpen(true)}>\n <ShieldCheck className=\"size-4\" />\n {t('wms.backend.inventory.operations.reserve', 'Reserve')}\n </Button>\n ) : null}\n {access.canReceive ? (\n <Button type=\"button\" variant=\"default\" onClick={() => setReceiveOpen(true)}>\n <ArrowDown className=\"size-4\" />\n {t('wms.backend.inventory.operations.receive', 'Receive stock')}\n </Button>\n ) : null}\n </SectionCard>\n {access.canImport ? (\n <ImportInventoryDialog open={importOpen} onOpenChange={setImportOpen} access={access} />\n ) : null}\n {access.canAdjust ? (\n <AdjustInventoryDialog open={adjustOpen} onOpenChange={setAdjustOpen} access={access} />\n ) : null}\n {access.canReceive ? (\n <ReceiveInventoryDialog\n open={receiveOpen}\n onOpenChange={setReceiveOpen}\n access={access}\n onSuccess={handleReceiveSuccess}\n />\n ) : null}\n {access.canReserve ? (\n <ReserveInventoryDialog open={reserveOpen} onOpenChange={setReserveOpen} access={access} />\n ) : null}\n {access.canMove ? (\n <MoveInventoryDialog\n open={moveOpen}\n onOpenChange={(next) => {\n setMoveOpen(next)\n if (!next) setPutawayContext(null)\n }}\n access={access}\n initialCatalogVariantId={putawayContext?.catalogVariantId}\n initialWarehouseId={putawayContext?.warehouseId}\n initialFromLocationId={putawayContext?.locationId}\n movementType={putawayContext ? 'putaway' : 'transfer'}\n lockSourceContext={Boolean(putawayContext)}\n />\n ) : null}\n {access.canCycleCount ? (\n <CycleCountWizardDialog open={cycleOpen} onOpenChange={setCycleOpen} access={access} />\n ) : null}\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
|
|
6
|
+
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
7
|
+
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
8
|
+
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
|
|
9
|
+
import { raiseCrudError } from "@open-mercato/ui/backend/utils/serverErrors";
|
|
10
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
|
|
11
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
12
|
+
import { E } from "../../../../generated/entities.ids.generated.js";
|
|
13
|
+
import { flashMutationError } from "../../lib/flashMutationError.js";
|
|
14
|
+
import { loadWarehouseOptions } from "./wmsLookupLoaders.js";
|
|
15
|
+
const locationFormSchema = z.object({
|
|
16
|
+
warehouseId: z.string().uuid(),
|
|
17
|
+
code: z.string().trim().min(1),
|
|
18
|
+
type: z.enum(["zone", "aisle", "rack", "bin", "slot", "dock", "staging"]),
|
|
19
|
+
capacityUnits: z.coerce.number().min(0).optional(),
|
|
20
|
+
capacityWeight: z.coerce.number().min(0).optional(),
|
|
21
|
+
isActive: z.boolean().default(true)
|
|
22
|
+
});
|
|
23
|
+
function LocationEditDialog({ open, onOpenChange, mode, row, onSaved }) {
|
|
24
|
+
const t = useT();
|
|
25
|
+
const { runMutation } = useGuardedMutation({ contextId: "wms-config-locations" });
|
|
26
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
27
|
+
const warehouseSeedOptions = React.useMemo(() => {
|
|
28
|
+
if (mode !== "edit" || !row?.warehouse_id) return void 0;
|
|
29
|
+
const label = row.warehouse_name?.trim() || row.warehouse_code?.trim() || "";
|
|
30
|
+
if (!label) return void 0;
|
|
31
|
+
return [{ value: row.warehouse_id, label }];
|
|
32
|
+
}, [mode, row]);
|
|
33
|
+
const fields = React.useMemo(() => [
|
|
34
|
+
{
|
|
35
|
+
id: "warehouseId",
|
|
36
|
+
type: "combobox",
|
|
37
|
+
label: t("wms.backend.config.locations.form.warehouse", "Warehouse"),
|
|
38
|
+
required: true,
|
|
39
|
+
loadOptions: loadWarehouseOptions,
|
|
40
|
+
allowCustomValues: false,
|
|
41
|
+
seedOptions: warehouseSeedOptions
|
|
42
|
+
},
|
|
43
|
+
{ id: "code", type: "text", label: t("wms.backend.config.locations.form.code", "Code"), required: true },
|
|
44
|
+
{
|
|
45
|
+
id: "type",
|
|
46
|
+
type: "select",
|
|
47
|
+
label: t("wms.backend.config.locations.form.type", "Type"),
|
|
48
|
+
required: true,
|
|
49
|
+
options: [
|
|
50
|
+
{ value: "zone", label: t("wms.backend.config.locations.type.zone", "Zone") },
|
|
51
|
+
{ value: "aisle", label: t("wms.backend.config.locations.type.aisle", "Aisle") },
|
|
52
|
+
{ value: "rack", label: t("wms.backend.config.locations.type.rack", "Rack") },
|
|
53
|
+
{ value: "bin", label: t("wms.backend.config.locations.type.bin", "Bin") },
|
|
54
|
+
{ value: "slot", label: t("wms.backend.config.locations.type.slot", "Slot") },
|
|
55
|
+
{ value: "dock", label: t("wms.backend.config.locations.type.dock", "Dock") },
|
|
56
|
+
{ value: "staging", label: t("wms.backend.config.locations.type.staging", "Staging") }
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{ id: "capacityUnits", type: "number", label: t("wms.backend.config.locations.form.capacityUnits", "Capacity units") },
|
|
60
|
+
{ id: "capacityWeight", type: "number", label: t("wms.backend.config.locations.form.capacityWeight", "Capacity weight") },
|
|
61
|
+
{ id: "isActive", type: "checkbox", label: t("wms.backend.config.locations.form.active", "Active") }
|
|
62
|
+
], [t, warehouseSeedOptions]);
|
|
63
|
+
const initialValues = React.useMemo(() => {
|
|
64
|
+
if (mode === "edit" && row) {
|
|
65
|
+
return {
|
|
66
|
+
warehouseId: row.warehouse_id || "",
|
|
67
|
+
code: row.code || "",
|
|
68
|
+
type: row.type || "bin",
|
|
69
|
+
capacityUnits: row.capacity_units == null ? void 0 : Number(row.capacity_units),
|
|
70
|
+
capacityWeight: row.capacity_weight == null ? void 0 : Number(row.capacity_weight),
|
|
71
|
+
isActive: row.is_active !== false
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
warehouseId: "",
|
|
76
|
+
code: "",
|
|
77
|
+
type: "bin",
|
|
78
|
+
capacityUnits: void 0,
|
|
79
|
+
capacityWeight: void 0,
|
|
80
|
+
isActive: true
|
|
81
|
+
};
|
|
82
|
+
}, [mode, row]);
|
|
83
|
+
const handleSubmit = React.useCallback(async (values) => {
|
|
84
|
+
setSubmitting(true);
|
|
85
|
+
try {
|
|
86
|
+
await runMutation({
|
|
87
|
+
operation: async () => {
|
|
88
|
+
const call = await apiCall(
|
|
89
|
+
"/api/wms/locations",
|
|
90
|
+
{
|
|
91
|
+
method: mode === "edit" ? "PUT" : "POST",
|
|
92
|
+
headers: { "x-om-forbidden-redirect": "0" },
|
|
93
|
+
body: JSON.stringify(mode === "edit" && row ? { id: row.id, ...values } : values)
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
if (!call.ok) {
|
|
97
|
+
await raiseCrudError(call.response, t("wms.backend.config.locations.errors.save", "Failed to save location."));
|
|
98
|
+
}
|
|
99
|
+
return call;
|
|
100
|
+
},
|
|
101
|
+
context: {},
|
|
102
|
+
mutationPayload: mode === "edit" && row ? { id: row.id, ...values } : values
|
|
103
|
+
});
|
|
104
|
+
flash(
|
|
105
|
+
mode === "edit" ? t("wms.backend.config.locations.flash.updated", "Location updated") : t("wms.backend.config.locations.flash.created", "Location created"),
|
|
106
|
+
"success"
|
|
107
|
+
);
|
|
108
|
+
onOpenChange(false);
|
|
109
|
+
await onSaved?.();
|
|
110
|
+
} catch (error) {
|
|
111
|
+
flashMutationError(error, t("wms.backend.config.locations.errors.save", "Failed to save location."), t);
|
|
112
|
+
} finally {
|
|
113
|
+
setSubmitting(false);
|
|
114
|
+
}
|
|
115
|
+
}, [mode, onOpenChange, onSaved, row, runMutation, t]);
|
|
116
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-3xl", children: [
|
|
117
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: mode === "edit" ? t("wms.backend.config.locations.dialog.edit", "Edit location") : t("wms.backend.config.locations.dialog.create", "Create location") }) }),
|
|
118
|
+
/* @__PURE__ */ jsx(
|
|
119
|
+
CrudForm,
|
|
120
|
+
{
|
|
121
|
+
schema: locationFormSchema,
|
|
122
|
+
fields,
|
|
123
|
+
entityId: E.wms.warehouse_location,
|
|
124
|
+
initialValues,
|
|
125
|
+
submitLabel: t("common.save", "Save"),
|
|
126
|
+
onSubmit: handleSubmit,
|
|
127
|
+
embedded: true,
|
|
128
|
+
disableInitialFocus: true,
|
|
129
|
+
isLoading: submitting,
|
|
130
|
+
twoColumn: true,
|
|
131
|
+
optimisticLockUpdatedAt: mode === "edit" ? row?.updatedAt ?? row?.updated_at ?? null : void 0
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
] }) });
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
LocationEditDialog,
|
|
138
|
+
locationFormSchema
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=LocationEditDialog.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/wms/components/backend/LocationEditDialog.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'\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 { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { E } from '#generated/entities.ids.generated'\nimport { flashMutationError } from '../../lib/flashMutationError'\nimport { loadWarehouseOptions } from './wmsLookupLoaders'\n\nexport type LocationDialogRow = {\n id: string\n warehouse_id?: string | null\n warehouse_name?: string | null\n warehouse_code?: string | null\n code?: string | null\n type?: string | null\n capacity_units?: string | number | null\n capacity_weight?: string | number | null\n is_active?: boolean | null\n updated_at?: string | null\n updatedAt?: string | null\n}\n\nexport type LocationFormValues = {\n warehouseId: string\n code: string\n type: 'zone' | 'aisle' | 'rack' | 'bin' | 'slot' | 'dock' | 'staging'\n capacityUnits?: number\n capacityWeight?: number\n isActive: boolean\n}\n\nexport const locationFormSchema = z.object({\n warehouseId: z.string().uuid(),\n code: z.string().trim().min(1),\n type: z.enum(['zone', 'aisle', 'rack', 'bin', 'slot', 'dock', 'staging']),\n capacityUnits: z.coerce.number().min(0).optional(),\n capacityWeight: z.coerce.number().min(0).optional(),\n isActive: z.boolean().default(true),\n})\n\ntype LocationEditDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n mode: 'create' | 'edit'\n row?: LocationDialogRow | null\n onSaved?: () => void | Promise<void>\n}\n\nexport function LocationEditDialog({ open, onOpenChange, mode, row, onSaved }: LocationEditDialogProps) {\n const t = useT()\n const { runMutation } = useGuardedMutation<Record<string, unknown>>({ contextId: 'wms-config-locations' })\n const [submitting, setSubmitting] = React.useState(false)\n\n const warehouseSeedOptions = React.useMemo(() => {\n if (mode !== 'edit' || !row?.warehouse_id) return undefined\n const label = row.warehouse_name?.trim() || row.warehouse_code?.trim() || ''\n if (!label) return undefined\n return [{ value: row.warehouse_id, label }]\n }, [mode, row])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'warehouseId',\n type: 'combobox',\n label: t('wms.backend.config.locations.form.warehouse', 'Warehouse'),\n required: true,\n loadOptions: loadWarehouseOptions,\n allowCustomValues: false,\n seedOptions: warehouseSeedOptions,\n },\n { id: 'code', type: 'text', label: t('wms.backend.config.locations.form.code', 'Code'), required: true },\n {\n id: 'type',\n type: 'select',\n label: t('wms.backend.config.locations.form.type', 'Type'),\n required: true,\n options: [\n { value: 'zone', label: t('wms.backend.config.locations.type.zone', 'Zone') },\n { value: 'aisle', label: t('wms.backend.config.locations.type.aisle', 'Aisle') },\n { value: 'rack', label: t('wms.backend.config.locations.type.rack', 'Rack') },\n { value: 'bin', label: t('wms.backend.config.locations.type.bin', 'Bin') },\n { value: 'slot', label: t('wms.backend.config.locations.type.slot', 'Slot') },\n { value: 'dock', label: t('wms.backend.config.locations.type.dock', 'Dock') },\n { value: 'staging', label: t('wms.backend.config.locations.type.staging', 'Staging') },\n ],\n },\n { id: 'capacityUnits', type: 'number', label: t('wms.backend.config.locations.form.capacityUnits', 'Capacity units') },\n { id: 'capacityWeight', type: 'number', label: t('wms.backend.config.locations.form.capacityWeight', 'Capacity weight') },\n { id: 'isActive', type: 'checkbox', label: t('wms.backend.config.locations.form.active', 'Active') },\n ], [t, warehouseSeedOptions])\n\n const initialValues = React.useMemo<LocationFormValues>(() => {\n if (mode === 'edit' && row) {\n return {\n warehouseId: row.warehouse_id || '',\n code: row.code || '',\n type: (row.type as LocationFormValues['type']) || 'bin',\n capacityUnits: row.capacity_units == null ? undefined : Number(row.capacity_units),\n capacityWeight: row.capacity_weight == null ? undefined : Number(row.capacity_weight),\n isActive: row.is_active !== false,\n }\n }\n return {\n warehouseId: '',\n code: '',\n type: 'bin',\n capacityUnits: undefined,\n capacityWeight: undefined,\n isActive: true,\n }\n }, [mode, row])\n\n const handleSubmit = React.useCallback(async (values: LocationFormValues) => {\n setSubmitting(true)\n try {\n await runMutation({\n operation: async () => {\n // Opt out of apiFetch's global 403 flash so flashMutationError can\n // surface a translated, permission-specific toast instead of a bare\n // \"Forbidden\" followed by a second generic Access denied banner.\n const call = await apiCall(\n '/api/wms/locations',\n {\n method: mode === 'edit' ? 'PUT' : 'POST',\n headers: { 'x-om-forbidden-redirect': '0' },\n body: JSON.stringify(mode === 'edit' && row ? { id: row.id, ...values } : values),\n },\n )\n if (!call.ok) {\n await raiseCrudError(call.response, t('wms.backend.config.locations.errors.save', 'Failed to save location.'))\n }\n return call\n },\n context: {},\n mutationPayload: mode === 'edit' && row ? { id: row.id, ...values } : values,\n })\n flash(\n mode === 'edit'\n ? t('wms.backend.config.locations.flash.updated', 'Location updated')\n : t('wms.backend.config.locations.flash.created', 'Location created'),\n 'success',\n )\n onOpenChange(false)\n await onSaved?.()\n } catch (error) {\n flashMutationError(error, t('wms.backend.config.locations.errors.save', 'Failed to save location.'), t)\n } finally {\n setSubmitting(false)\n }\n }, [mode, onOpenChange, onSaved, row, runMutation, t])\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-3xl\">\n <DialogHeader>\n <DialogTitle>\n {mode === 'edit'\n ? t('wms.backend.config.locations.dialog.edit', 'Edit location')\n : t('wms.backend.config.locations.dialog.create', 'Create location')}\n </DialogTitle>\n </DialogHeader>\n <CrudForm<LocationFormValues>\n schema={locationFormSchema}\n fields={fields}\n entityId={E.wms.warehouse_location}\n initialValues={initialValues}\n submitLabel={t('common.save', 'Save')}\n onSubmit={handleSubmit}\n embedded\n disableInitialFocus\n isLoading={submitting}\n twoColumn\n optimisticLockUpdatedAt={mode === 'edit' ? (row?.updatedAt ?? row?.updated_at ?? null) : undefined}\n />\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|