@open-mercato/core 0.6.7-develop.6669.1.40b669666b → 0.6.7-develop.6670.1.4efa7961c6

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.
Files changed (473) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/inventory_balance/index.js +21 -0
  3. package/dist/generated/entities/inventory_balance/index.js.map +7 -0
  4. package/dist/generated/entities/inventory_lot/index.js +19 -0
  5. package/dist/generated/entities/inventory_lot/index.js.map +7 -0
  6. package/dist/generated/entities/inventory_movement/index.js +35 -0
  7. package/dist/generated/entities/inventory_movement/index.js.map +7 -0
  8. package/dist/generated/entities/inventory_reservation/index.js +23 -0
  9. package/dist/generated/entities/inventory_reservation/index.js.map +7 -0
  10. package/dist/generated/entities/product_inventory_profile/index.js +21 -0
  11. package/dist/generated/entities/product_inventory_profile/index.js.map +7 -0
  12. package/dist/generated/entities/sales_order_warehouse_assignment/index.js +11 -0
  13. package/dist/generated/entities/sales_order_warehouse_assignment/index.js.map +7 -0
  14. package/dist/generated/entities/warehouse/index.js +25 -0
  15. package/dist/generated/entities/warehouse/index.js.map +7 -0
  16. package/dist/generated/entities/warehouse_location/index.js +21 -0
  17. package/dist/generated/entities/warehouse_location/index.js.map +7 -0
  18. package/dist/generated/entities/warehouse_zone/index.js +11 -0
  19. package/dist/generated/entities/warehouse_zone/index.js.map +7 -0
  20. package/dist/generated/entities.ids.generated.js +12 -0
  21. package/dist/generated/entities.ids.generated.js.map +2 -2
  22. package/dist/generated/entity-fields-registry.js +98 -0
  23. package/dist/generated/entity-fields-registry.js.map +2 -2
  24. package/dist/modules/auth/backend/roles/page.js +12 -4
  25. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  26. package/dist/modules/auth/lib/backendChrome.js +1 -0
  27. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  28. package/dist/modules/auth/services/rbacService.js +16 -17
  29. package/dist/modules/auth/services/rbacService.js.map +2 -2
  30. package/dist/modules/catalog/api/products/route.js +3 -0
  31. package/dist/modules/catalog/api/products/route.js.map +2 -2
  32. package/dist/modules/catalog/api/variants/route.js +3 -0
  33. package/dist/modules/catalog/api/variants/route.js.map +2 -2
  34. package/dist/modules/query_index/lib/engine.js +6 -6
  35. package/dist/modules/query_index/lib/engine.js.map +2 -2
  36. package/dist/modules/sales/api/documents/factory.js +1 -0
  37. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  38. package/dist/modules/sales/commands/documents.js +53 -0
  39. package/dist/modules/sales/commands/documents.js.map +2 -2
  40. package/dist/modules/sales/components/documents/ItemsSection.js +51 -2
  41. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  42. package/dist/modules/sales/events.js +2 -0
  43. package/dist/modules/sales/events.js.map +2 -2
  44. package/dist/modules/sales/widgets/injection/order-items-context.js +11 -0
  45. package/dist/modules/sales/widgets/injection/order-items-context.js.map +7 -0
  46. package/dist/modules/wms/acl.js +18 -0
  47. package/dist/modules/wms/acl.js.map +7 -0
  48. package/dist/modules/wms/analytics.js +11 -0
  49. package/dist/modules/wms/analytics.js.map +7 -0
  50. package/dist/modules/wms/api/dashboard/operational/route.js +80 -0
  51. package/dist/modules/wms/api/dashboard/operational/route.js.map +7 -0
  52. package/dist/modules/wms/api/interceptors.js +90 -0
  53. package/dist/modules/wms/api/interceptors.js.map +7 -0
  54. package/dist/modules/wms/api/inventory/adjust/route.js +51 -0
  55. package/dist/modules/wms/api/inventory/adjust/route.js.map +7 -0
  56. package/dist/modules/wms/api/inventory/allocate/route.js +51 -0
  57. package/dist/modules/wms/api/inventory/allocate/route.js.map +7 -0
  58. package/dist/modules/wms/api/inventory/balances/route.js +172 -0
  59. package/dist/modules/wms/api/inventory/balances/route.js.map +7 -0
  60. package/dist/modules/wms/api/inventory/cycle-count/route.js +52 -0
  61. package/dist/modules/wms/api/inventory/cycle-count/route.js.map +7 -0
  62. package/dist/modules/wms/api/inventory/helpers.js +113 -0
  63. package/dist/modules/wms/api/inventory/helpers.js.map +7 -0
  64. package/dist/modules/wms/api/inventory/import/apply/route.js +46 -0
  65. package/dist/modules/wms/api/inventory/import/apply/route.js.map +7 -0
  66. package/dist/modules/wms/api/inventory/import/helpers.js +195 -0
  67. package/dist/modules/wms/api/inventory/import/helpers.js.map +7 -0
  68. package/dist/modules/wms/api/inventory/import/template/route.js +32 -0
  69. package/dist/modules/wms/api/inventory/import/template/route.js.map +7 -0
  70. package/dist/modules/wms/api/inventory/import/validate/route.js +54 -0
  71. package/dist/modules/wms/api/inventory/import/validate/route.js.map +7 -0
  72. package/dist/modules/wms/api/inventory/move/route.js +51 -0
  73. package/dist/modules/wms/api/inventory/move/route.js.map +7 -0
  74. package/dist/modules/wms/api/inventory/movements/route.js +164 -0
  75. package/dist/modules/wms/api/inventory/movements/route.js.map +7 -0
  76. package/dist/modules/wms/api/inventory/receive/route.js +50 -0
  77. package/dist/modules/wms/api/inventory/receive/route.js.map +7 -0
  78. package/dist/modules/wms/api/inventory/release/route.js +44 -0
  79. package/dist/modules/wms/api/inventory/release/route.js.map +7 -0
  80. package/dist/modules/wms/api/inventory/reservations/route.js +128 -0
  81. package/dist/modules/wms/api/inventory/reservations/route.js.map +7 -0
  82. package/dist/modules/wms/api/inventory/reserve/route.js +59 -0
  83. package/dist/modules/wms/api/inventory/reserve/route.js.map +7 -0
  84. package/dist/modules/wms/api/inventory-profiles/route.js +178 -0
  85. package/dist/modules/wms/api/inventory-profiles/route.js.map +7 -0
  86. package/dist/modules/wms/api/listEnrichers.js +181 -0
  87. package/dist/modules/wms/api/listEnrichers.js.map +7 -0
  88. package/dist/modules/wms/api/listSearch.js +77 -0
  89. package/dist/modules/wms/api/listSearch.js.map +7 -0
  90. package/dist/modules/wms/api/locations/route.js +172 -0
  91. package/dist/modules/wms/api/locations/route.js.map +7 -0
  92. package/dist/modules/wms/api/lots/route.js +204 -0
  93. package/dist/modules/wms/api/lots/route.js.map +7 -0
  94. package/dist/modules/wms/api/openapi.js +27 -0
  95. package/dist/modules/wms/api/openapi.js.map +7 -0
  96. package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js +54 -0
  97. package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js.map +7 -0
  98. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js +279 -0
  99. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js.map +7 -0
  100. package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js +56 -0
  101. package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js.map +7 -0
  102. package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js +43 -0
  103. package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js.map +7 -0
  104. package/dist/modules/wms/api/warehouses/route.js +181 -0
  105. package/dist/modules/wms/api/warehouses/route.js.map +7 -0
  106. package/dist/modules/wms/api/zones/route.js +159 -0
  107. package/dist/modules/wms/api/zones/route.js.map +7 -0
  108. package/dist/modules/wms/backend/config/wms/page.js +9 -0
  109. package/dist/modules/wms/backend/config/wms/page.js.map +7 -0
  110. package/dist/modules/wms/backend/config/wms/page.meta.js +18 -0
  111. package/dist/modules/wms/backend/config/wms/page.meta.js.map +7 -0
  112. package/dist/modules/wms/backend/page.js +9 -0
  113. package/dist/modules/wms/backend/page.js.map +7 -0
  114. package/dist/modules/wms/backend/page.meta.js +16 -0
  115. package/dist/modules/wms/backend/page.meta.js.map +7 -0
  116. package/dist/modules/wms/backend/wms/inventory/page.js +9 -0
  117. package/dist/modules/wms/backend/wms/inventory/page.js.map +7 -0
  118. package/dist/modules/wms/backend/wms/inventory/page.meta.js +18 -0
  119. package/dist/modules/wms/backend/wms/inventory/page.meta.js.map +7 -0
  120. package/dist/modules/wms/backend/wms/location/[id]/page.js +9 -0
  121. package/dist/modules/wms/backend/wms/location/[id]/page.js.map +7 -0
  122. package/dist/modules/wms/backend/wms/location/[id]/page.meta.js +18 -0
  123. package/dist/modules/wms/backend/wms/location/[id]/page.meta.js.map +7 -0
  124. package/dist/modules/wms/backend/wms/locations/page.js +10 -0
  125. package/dist/modules/wms/backend/wms/locations/page.js.map +7 -0
  126. package/dist/modules/wms/backend/wms/locations/page.meta.js +18 -0
  127. package/dist/modules/wms/backend/wms/locations/page.meta.js.map +7 -0
  128. package/dist/modules/wms/backend/wms/lot/[id]/page.js +9 -0
  129. package/dist/modules/wms/backend/wms/lot/[id]/page.js.map +7 -0
  130. package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js +18 -0
  131. package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js.map +7 -0
  132. package/dist/modules/wms/backend/wms/lots/page.js +9 -0
  133. package/dist/modules/wms/backend/wms/lots/page.js.map +7 -0
  134. package/dist/modules/wms/backend/wms/lots/page.meta.js +18 -0
  135. package/dist/modules/wms/backend/wms/lots/page.meta.js.map +7 -0
  136. package/dist/modules/wms/backend/wms/movements/page.js +22 -0
  137. package/dist/modules/wms/backend/wms/movements/page.js.map +7 -0
  138. package/dist/modules/wms/backend/wms/movements/page.meta.js +18 -0
  139. package/dist/modules/wms/backend/wms/movements/page.meta.js.map +7 -0
  140. package/dist/modules/wms/backend/wms/reservations/page.js +23 -0
  141. package/dist/modules/wms/backend/wms/reservations/page.js.map +7 -0
  142. package/dist/modules/wms/backend/wms/reservations/page.meta.js +18 -0
  143. package/dist/modules/wms/backend/wms/reservations/page.meta.js.map +7 -0
  144. package/dist/modules/wms/backend/wms/sku/[id]/page.js +9 -0
  145. package/dist/modules/wms/backend/wms/sku/[id]/page.js.map +7 -0
  146. package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js +18 -0
  147. package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js.map +7 -0
  148. package/dist/modules/wms/backend/wms/warehouses/page.js +10 -0
  149. package/dist/modules/wms/backend/wms/warehouses/page.js.map +7 -0
  150. package/dist/modules/wms/backend/wms/warehouses/page.meta.js +18 -0
  151. package/dist/modules/wms/backend/wms/warehouses/page.meta.js.map +7 -0
  152. package/dist/modules/wms/backend/wms/zones/page.js +10 -0
  153. package/dist/modules/wms/backend/wms/zones/page.js.map +7 -0
  154. package/dist/modules/wms/backend/wms/zones/page.meta.js +18 -0
  155. package/dist/modules/wms/backend/wms/zones/page.meta.js.map +7 -0
  156. package/dist/modules/wms/ce.js +80 -0
  157. package/dist/modules/wms/ce.js.map +7 -0
  158. package/dist/modules/wms/cli.js +83 -0
  159. package/dist/modules/wms/cli.js.map +7 -0
  160. package/dist/modules/wms/commands/configuration.js +1519 -0
  161. package/dist/modules/wms/commands/configuration.js.map +7 -0
  162. package/dist/modules/wms/commands/index.js +4 -0
  163. package/dist/modules/wms/commands/index.js.map +7 -0
  164. package/dist/modules/wms/commands/inventory-actions.js +1539 -0
  165. package/dist/modules/wms/commands/inventory-actions.js.map +7 -0
  166. package/dist/modules/wms/commands/sales-order-assignment.js +277 -0
  167. package/dist/modules/wms/commands/sales-order-assignment.js.map +7 -0
  168. package/dist/modules/wms/commands/shared.js +82 -0
  169. package/dist/modules/wms/commands/shared.js.map +7 -0
  170. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js +755 -0
  171. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js.map +7 -0
  172. package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js +269 -0
  173. package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js.map +7 -0
  174. package/dist/modules/wms/components/backend/CycleCountWizardDialog.js +1783 -0
  175. package/dist/modules/wms/components/backend/CycleCountWizardDialog.js.map +7 -0
  176. package/dist/modules/wms/components/backend/ImportInventoryDialog.js +766 -0
  177. package/dist/modules/wms/components/backend/ImportInventoryDialog.js.map +7 -0
  178. package/dist/modules/wms/components/backend/InventoryOperationsSection.js +119 -0
  179. package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +7 -0
  180. package/dist/modules/wms/components/backend/LocationEditDialog.js +140 -0
  181. package/dist/modules/wms/components/backend/LocationEditDialog.js.map +7 -0
  182. package/dist/modules/wms/components/backend/MoveInventoryDialog.js +791 -0
  183. package/dist/modules/wms/components/backend/MoveInventoryDialog.js.map +7 -0
  184. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +656 -0
  185. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +7 -0
  186. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js +344 -0
  187. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js.map +7 -0
  188. package/dist/modules/wms/components/backend/ReserveInventoryDialog.js +475 -0
  189. package/dist/modules/wms/components/backend/ReserveInventoryDialog.js.map +7 -0
  190. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +1112 -0
  191. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +7 -0
  192. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +908 -0
  193. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +7 -0
  194. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +1015 -0
  195. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +7 -0
  196. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +1049 -0
  197. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +7 -0
  198. package/dist/modules/wms/components/backend/WmsLotsListPage.js +297 -0
  199. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +7 -0
  200. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +757 -0
  201. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +7 -0
  202. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +975 -0
  203. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +7 -0
  204. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +710 -0
  205. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +7 -0
  206. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +79 -0
  207. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +7 -0
  208. package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js +24 -0
  209. package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js.map +7 -0
  210. package/dist/modules/wms/components/backend/wmsLookupLoaders.js +55 -0
  211. package/dist/modules/wms/components/backend/wmsLookupLoaders.js.map +7 -0
  212. package/dist/modules/wms/data/enrichers.js +501 -0
  213. package/dist/modules/wms/data/enrichers.js.map +7 -0
  214. package/dist/modules/wms/data/entities.js +467 -0
  215. package/dist/modules/wms/data/entities.js.map +7 -0
  216. package/dist/modules/wms/data/validators.js +399 -0
  217. package/dist/modules/wms/data/validators.js.map +7 -0
  218. package/dist/modules/wms/di.js +27 -0
  219. package/dist/modules/wms/di.js.map +7 -0
  220. package/dist/modules/wms/events.js +42 -0
  221. package/dist/modules/wms/events.js.map +7 -0
  222. package/dist/modules/wms/index.js +17 -0
  223. package/dist/modules/wms/index.js.map +7 -0
  224. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js +54 -0
  225. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js.map +7 -0
  226. package/dist/modules/wms/lib/catalogInventoryProfileSync.js +144 -0
  227. package/dist/modules/wms/lib/catalogInventoryProfileSync.js.map +7 -0
  228. package/dist/modules/wms/lib/expiry.js +29 -0
  229. package/dist/modules/wms/lib/expiry.js.map +7 -0
  230. package/dist/modules/wms/lib/flashMutationError.js +51 -0
  231. package/dist/modules/wms/lib/flashMutationError.js.map +7 -0
  232. package/dist/modules/wms/lib/inventoryDisplayUi.js +188 -0
  233. package/dist/modules/wms/lib/inventoryDisplayUi.js.map +7 -0
  234. package/dist/modules/wms/lib/inventoryIdempotency.js +37 -0
  235. package/dist/modules/wms/lib/inventoryIdempotency.js.map +7 -0
  236. package/dist/modules/wms/lib/inventoryImportCsv.js +173 -0
  237. package/dist/modules/wms/lib/inventoryImportCsv.js.map +7 -0
  238. package/dist/modules/wms/lib/inventoryImportService.js +468 -0
  239. package/dist/modules/wms/lib/inventoryImportService.js.map +7 -0
  240. package/dist/modules/wms/lib/inventoryMutationUi.js +25 -0
  241. package/dist/modules/wms/lib/inventoryMutationUi.js.map +7 -0
  242. package/dist/modules/wms/lib/inventoryPolicy.js +61 -0
  243. package/dist/modules/wms/lib/inventoryPolicy.js.map +7 -0
  244. package/dist/modules/wms/lib/inventoryReconciliation.js +193 -0
  245. package/dist/modules/wms/lib/inventoryReconciliation.js.map +7 -0
  246. package/dist/modules/wms/lib/inventoryTrackingValidation.js +13 -0
  247. package/dist/modules/wms/lib/inventoryTrackingValidation.js.map +7 -0
  248. package/dist/modules/wms/lib/loadOperationalDashboard.js +580 -0
  249. package/dist/modules/wms/lib/loadOperationalDashboard.js.map +7 -0
  250. package/dist/modules/wms/lib/lowStockBalanceFilter.js +49 -0
  251. package/dist/modules/wms/lib/lowStockBalanceFilter.js.map +7 -0
  252. package/dist/modules/wms/lib/primaryWarehousePolicy.js +32 -0
  253. package/dist/modules/wms/lib/primaryWarehousePolicy.js.map +7 -0
  254. package/dist/modules/wms/lib/roleFeatures.js +30 -0
  255. package/dist/modules/wms/lib/roleFeatures.js.map +7 -0
  256. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +291 -0
  257. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +7 -0
  258. package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js +54 -0
  259. package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js.map +7 -0
  260. package/dist/modules/wms/lib/wmsIntegrationToggles.js +71 -0
  261. package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +7 -0
  262. package/dist/modules/wms/migrations/Migration20260428110546.js +78 -0
  263. package/dist/modules/wms/migrations/Migration20260428110546.js.map +7 -0
  264. package/dist/modules/wms/migrations/Migration20260527120000.js +15 -0
  265. package/dist/modules/wms/migrations/Migration20260527120000.js.map +7 -0
  266. package/dist/modules/wms/migrations/Migration20260527140000.js +37 -0
  267. package/dist/modules/wms/migrations/Migration20260527140000.js.map +7 -0
  268. package/dist/modules/wms/migrations/Migration20260613120000.js +23 -0
  269. package/dist/modules/wms/migrations/Migration20260613120000.js.map +7 -0
  270. package/dist/modules/wms/migrations/Migration20260616090000.js +13 -0
  271. package/dist/modules/wms/migrations/Migration20260616090000.js.map +7 -0
  272. package/dist/modules/wms/migrations/Migration20260707180000.js +15 -0
  273. package/dist/modules/wms/migrations/Migration20260707180000.js.map +7 -0
  274. package/dist/modules/wms/notifications.client.js +18 -0
  275. package/dist/modules/wms/notifications.client.js.map +7 -0
  276. package/dist/modules/wms/notifications.js +53 -0
  277. package/dist/modules/wms/notifications.js.map +7 -0
  278. package/dist/modules/wms/search.js +196 -0
  279. package/dist/modules/wms/search.js.map +7 -0
  280. package/dist/modules/wms/setup.js +30 -0
  281. package/dist/modules/wms/setup.js.map +7 -0
  282. package/dist/modules/wms/subscribers/low-stock-notification.js +40 -0
  283. package/dist/modules/wms/subscribers/low-stock-notification.js.map +7 -0
  284. package/dist/modules/wms/subscribers/reservation-shortfall-notification.js +69 -0
  285. package/dist/modules/wms/subscribers/reservation-shortfall-notification.js.map +7 -0
  286. package/dist/modules/wms/subscribers/sales-order-cancelled-release.js +14 -0
  287. package/dist/modules/wms/subscribers/sales-order-cancelled-release.js.map +7 -0
  288. package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js +14 -0
  289. package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js.map +7 -0
  290. package/dist/modules/wms/translations.js +10 -0
  291. package/dist/modules/wms/translations.js.map +7 -0
  292. package/dist/modules/wms/vector.js +9 -0
  293. package/dist/modules/wms/vector.js.map +7 -0
  294. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js +200 -0
  295. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js.map +7 -0
  296. package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js +104 -0
  297. package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js.map +7 -0
  298. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +389 -0
  299. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +7 -0
  300. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js +16 -0
  301. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js.map +7 -0
  302. package/dist/modules/wms/widgets/injection-table.js +36 -0
  303. package/dist/modules/wms/widgets/injection-table.js.map +7 -0
  304. package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js +150 -0
  305. package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js.map +7 -0
  306. package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js +186 -0
  307. package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js.map +7 -0
  308. package/dist/modules/wms/widgets/notifications/index.js +7 -0
  309. package/dist/modules/wms/widgets/notifications/index.js.map +7 -0
  310. package/generated/entities/inventory_balance/index.ts +9 -0
  311. package/generated/entities/inventory_lot/index.ts +8 -0
  312. package/generated/entities/inventory_movement/index.ts +16 -0
  313. package/generated/entities/inventory_reservation/index.ts +10 -0
  314. package/generated/entities/product_inventory_profile/index.ts +9 -0
  315. package/generated/entities/sales_order_warehouse_assignment/index.ts +4 -0
  316. package/generated/entities/warehouse/index.ts +11 -0
  317. package/generated/entities/warehouse_location/index.ts +9 -0
  318. package/generated/entities/warehouse_zone/index.ts +4 -0
  319. package/generated/entities.ids.generated.ts +12 -0
  320. package/generated/entity-fields-registry.ts +98 -0
  321. package/package.json +7 -7
  322. package/src/modules/auth/backend/roles/page.tsx +13 -4
  323. package/src/modules/auth/i18n/de.json +2 -0
  324. package/src/modules/auth/i18n/en.json +2 -0
  325. package/src/modules/auth/i18n/es.json +2 -0
  326. package/src/modules/auth/i18n/pl.json +2 -0
  327. package/src/modules/auth/lib/backendChrome.tsx +1 -0
  328. package/src/modules/auth/services/rbacService.ts +25 -21
  329. package/src/modules/catalog/api/products/route.ts +3 -0
  330. package/src/modules/catalog/api/variants/route.ts +3 -0
  331. package/src/modules/query_index/lib/engine.ts +18 -6
  332. package/src/modules/sales/api/documents/factory.ts +1 -0
  333. package/src/modules/sales/commands/documents.ts +71 -0
  334. package/src/modules/sales/components/documents/ItemsSection.tsx +58 -0
  335. package/src/modules/sales/events.ts +2 -0
  336. package/src/modules/sales/widgets/injection/order-items-context.ts +15 -0
  337. package/src/modules/wms/acl.ts +14 -0
  338. package/src/modules/wms/analytics.ts +9 -0
  339. package/src/modules/wms/api/dashboard/operational/route.ts +83 -0
  340. package/src/modules/wms/api/interceptors.ts +108 -0
  341. package/src/modules/wms/api/inventory/adjust/route.ts +50 -0
  342. package/src/modules/wms/api/inventory/allocate/route.ts +50 -0
  343. package/src/modules/wms/api/inventory/balances/route.ts +178 -0
  344. package/src/modules/wms/api/inventory/cycle-count/route.ts +51 -0
  345. package/src/modules/wms/api/inventory/helpers.ts +128 -0
  346. package/src/modules/wms/api/inventory/import/apply/route.ts +47 -0
  347. package/src/modules/wms/api/inventory/import/helpers.ts +223 -0
  348. package/src/modules/wms/api/inventory/import/template/route.ts +31 -0
  349. package/src/modules/wms/api/inventory/import/validate/route.ts +56 -0
  350. package/src/modules/wms/api/inventory/move/route.ts +50 -0
  351. package/src/modules/wms/api/inventory/movements/route.ts +164 -0
  352. package/src/modules/wms/api/inventory/receive/route.ts +49 -0
  353. package/src/modules/wms/api/inventory/release/route.ts +43 -0
  354. package/src/modules/wms/api/inventory/reservations/route.ts +128 -0
  355. package/src/modules/wms/api/inventory/reserve/route.ts +59 -0
  356. package/src/modules/wms/api/inventory-profiles/route.ts +177 -0
  357. package/src/modules/wms/api/listEnrichers.ts +312 -0
  358. package/src/modules/wms/api/listSearch.ts +121 -0
  359. package/src/modules/wms/api/locations/route.ts +171 -0
  360. package/src/modules/wms/api/lots/route.ts +205 -0
  361. package/src/modules/wms/api/openapi.ts +28 -0
  362. package/src/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.ts +58 -0
  363. package/src/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.ts +306 -0
  364. package/src/modules/wms/api/sales-orders/assign-warehouse/route.ts +57 -0
  365. package/src/modules/wms/api/sales-orders/unassign-warehouse/route.ts +43 -0
  366. package/src/modules/wms/api/warehouses/route.ts +181 -0
  367. package/src/modules/wms/api/zones/route.ts +158 -0
  368. package/src/modules/wms/backend/config/wms/page.meta.ts +14 -0
  369. package/src/modules/wms/backend/config/wms/page.tsx +5 -0
  370. package/src/modules/wms/backend/page.meta.ts +12 -0
  371. package/src/modules/wms/backend/page.tsx +5 -0
  372. package/src/modules/wms/backend/wms/inventory/page.meta.ts +14 -0
  373. package/src/modules/wms/backend/wms/inventory/page.tsx +5 -0
  374. package/src/modules/wms/backend/wms/location/[id]/page.meta.ts +14 -0
  375. package/src/modules/wms/backend/wms/location/[id]/page.tsx +5 -0
  376. package/src/modules/wms/backend/wms/locations/page.meta.ts +14 -0
  377. package/src/modules/wms/backend/wms/locations/page.tsx +12 -0
  378. package/src/modules/wms/backend/wms/lot/[id]/page.meta.ts +14 -0
  379. package/src/modules/wms/backend/wms/lot/[id]/page.tsx +5 -0
  380. package/src/modules/wms/backend/wms/lots/page.meta.ts +14 -0
  381. package/src/modules/wms/backend/wms/lots/page.tsx +5 -0
  382. package/src/modules/wms/backend/wms/movements/page.meta.ts +14 -0
  383. package/src/modules/wms/backend/wms/movements/page.tsx +23 -0
  384. package/src/modules/wms/backend/wms/reservations/page.meta.ts +14 -0
  385. package/src/modules/wms/backend/wms/reservations/page.tsx +24 -0
  386. package/src/modules/wms/backend/wms/sku/[id]/page.meta.ts +14 -0
  387. package/src/modules/wms/backend/wms/sku/[id]/page.tsx +5 -0
  388. package/src/modules/wms/backend/wms/warehouses/page.meta.ts +14 -0
  389. package/src/modules/wms/backend/wms/warehouses/page.tsx +12 -0
  390. package/src/modules/wms/backend/wms/zones/page.meta.ts +14 -0
  391. package/src/modules/wms/backend/wms/zones/page.tsx +12 -0
  392. package/src/modules/wms/ce.ts +76 -0
  393. package/src/modules/wms/cli.ts +96 -0
  394. package/src/modules/wms/commands/configuration.ts +1844 -0
  395. package/src/modules/wms/commands/index.ts +3 -0
  396. package/src/modules/wms/commands/inventory-actions.ts +1866 -0
  397. package/src/modules/wms/commands/sales-order-assignment.ts +346 -0
  398. package/src/modules/wms/commands/shared.ts +90 -0
  399. package/src/modules/wms/components/backend/AdjustInventoryDialog.tsx +820 -0
  400. package/src/modules/wms/components/backend/ChangeLotStatusDialog.tsx +312 -0
  401. package/src/modules/wms/components/backend/CycleCountWizardDialog.tsx +2007 -0
  402. package/src/modules/wms/components/backend/ImportInventoryDialog.tsx +1018 -0
  403. package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +159 -0
  404. package/src/modules/wms/components/backend/LocationEditDialog.tsx +185 -0
  405. package/src/modules/wms/components/backend/MoveInventoryDialog.tsx +907 -0
  406. package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +695 -0
  407. package/src/modules/wms/components/backend/ReleaseReservationDialog.tsx +424 -0
  408. package/src/modules/wms/components/backend/ReserveInventoryDialog.tsx +511 -0
  409. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +1340 -0
  410. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +1132 -0
  411. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +1310 -0
  412. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +1355 -0
  413. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +359 -0
  414. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +958 -0
  415. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +1245 -0
  416. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +960 -0
  417. package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +89 -0
  418. package/src/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.ts +32 -0
  419. package/src/modules/wms/components/backend/wmsLookupLoaders.ts +78 -0
  420. package/src/modules/wms/data/enrichers.ts +718 -0
  421. package/src/modules/wms/data/entities.ts +436 -0
  422. package/src/modules/wms/data/validators.ts +463 -0
  423. package/src/modules/wms/di.ts +25 -0
  424. package/src/modules/wms/events.ts +41 -0
  425. package/src/modules/wms/i18n/de.json +1051 -0
  426. package/src/modules/wms/i18n/en.json +1051 -0
  427. package/src/modules/wms/i18n/es.json +1051 -0
  428. package/src/modules/wms/i18n/pl.json +1051 -0
  429. package/src/modules/wms/index.ts +15 -0
  430. package/src/modules/wms/lib/catalogInventoryProfileIntent.ts +65 -0
  431. package/src/modules/wms/lib/catalogInventoryProfileSync.ts +199 -0
  432. package/src/modules/wms/lib/expiry.ts +30 -0
  433. package/src/modules/wms/lib/flashMutationError.ts +74 -0
  434. package/src/modules/wms/lib/inventoryDisplayUi.ts +249 -0
  435. package/src/modules/wms/lib/inventoryIdempotency.ts +54 -0
  436. package/src/modules/wms/lib/inventoryImportCsv.ts +212 -0
  437. package/src/modules/wms/lib/inventoryImportService.ts +629 -0
  438. package/src/modules/wms/lib/inventoryMutationUi.ts +21 -0
  439. package/src/modules/wms/lib/inventoryPolicy.ts +111 -0
  440. package/src/modules/wms/lib/inventoryReconciliation.ts +263 -0
  441. package/src/modules/wms/lib/inventoryTrackingValidation.ts +23 -0
  442. package/src/modules/wms/lib/loadOperationalDashboard.ts +776 -0
  443. package/src/modules/wms/lib/lowStockBalanceFilter.ts +74 -0
  444. package/src/modules/wms/lib/primaryWarehousePolicy.ts +46 -0
  445. package/src/modules/wms/lib/roleFeatures.ts +32 -0
  446. package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +390 -0
  447. package/src/modules/wms/lib/salesOrderWarehouseAssignment.ts +78 -0
  448. package/src/modules/wms/lib/wmsIntegrationToggles.ts +81 -0
  449. package/src/modules/wms/migrations/.snapshot-open-mercato.json +2880 -0
  450. package/src/modules/wms/migrations/Migration20260428110546.ts +91 -0
  451. package/src/modules/wms/migrations/Migration20260527120000.ts +15 -0
  452. package/src/modules/wms/migrations/Migration20260527140000.ts +35 -0
  453. package/src/modules/wms/migrations/Migration20260613120000.ts +21 -0
  454. package/src/modules/wms/migrations/Migration20260616090000.ts +11 -0
  455. package/src/modules/wms/migrations/Migration20260707180000.ts +13 -0
  456. package/src/modules/wms/notifications.client.ts +18 -0
  457. package/src/modules/wms/notifications.ts +51 -0
  458. package/src/modules/wms/search.ts +230 -0
  459. package/src/modules/wms/setup.ts +29 -0
  460. package/src/modules/wms/subscribers/low-stock-notification.ts +54 -0
  461. package/src/modules/wms/subscribers/reservation-shortfall-notification.ts +98 -0
  462. package/src/modules/wms/subscribers/sales-order-cancelled-release.ts +21 -0
  463. package/src/modules/wms/subscribers/sales-order-confirmed-reserve.ts +21 -0
  464. package/src/modules/wms/translations.ts +6 -0
  465. package/src/modules/wms/vector.ts +7 -0
  466. package/src/modules/wms/widgets/injection/catalog-inventory-profile/widget.ts +238 -0
  467. package/src/modules/wms/widgets/injection/order-items-stock-column/widget.tsx +153 -0
  468. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +476 -0
  469. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.ts +15 -0
  470. package/src/modules/wms/widgets/injection-table.ts +34 -0
  471. package/src/modules/wms/widgets/notifications/WmsLowStockRenderer.tsx +153 -0
  472. package/src/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.tsx +194 -0
  473. package/src/modules/wms/widgets/notifications/index.ts +2 -0
@@ -0,0 +1,476 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import Link from 'next/link'
5
+ import { useRouter } from 'next/navigation'
6
+ import { RefreshCw, ShieldOff } from 'lucide-react'
7
+ import { Button } from '@open-mercato/ui/primitives/button'
8
+ import {
9
+ StatusBadge,
10
+ type StatusMap,
11
+ } from '@open-mercato/ui/primitives/status-badge'
12
+ import { ComboboxInput } from '@open-mercato/ui/backend/inputs/ComboboxInput'
13
+ import { flash } from '@open-mercato/ui/backend/FlashMessages'
14
+ import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
15
+ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
16
+ import { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'
17
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
18
+ import { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
19
+ import type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'
20
+ import { useWmsInventoryMutationAccess } from '../../../components/backend/useWmsInventoryMutationAccess'
21
+ import { loadWarehouseOptions } from '../../../components/backend/wmsLookupLoaders'
22
+ import {
23
+ resolveCatalogVariantLabel,
24
+ resolveWarehouseLabel,
25
+ } from '../../../components/backend/inventoryMutationLoaders'
26
+ import { ReleaseReservationDialog } from '../../../components/backend/ReleaseReservationDialog'
27
+
28
+ type ReservationStatus =
29
+ | 'unreserved'
30
+ | 'partially_reserved'
31
+ | 'fully_reserved'
32
+
33
+ type SalesOrderWmsPayload = {
34
+ assignedWarehouseId?: string | null
35
+ assignedWarehouseName?: string | null
36
+ isExplicitlyAssigned?: boolean
37
+ stockSummary?: Array<{
38
+ catalogVariantId?: string
39
+ available?: string
40
+ reserved?: string
41
+ }>
42
+ reservationSummary?: {
43
+ status?: ReservationStatus
44
+ reservationIds?: string[]
45
+ }
46
+ }
47
+
48
+ export type SalesOrderRecord = Record<string, unknown> & {
49
+ id?: string
50
+ _wms?: SalesOrderWmsPayload
51
+ }
52
+
53
+ const reservationStatusMap: StatusMap<ReservationStatus> = {
54
+ unreserved: 'neutral',
55
+ partially_reserved: 'warning',
56
+ fully_reserved: 'success',
57
+ }
58
+
59
+ function formatQuantity(value: unknown): string {
60
+ if (typeof value === 'number' && Number.isFinite(value)) {
61
+ return value.toString()
62
+ }
63
+ if (typeof value === 'string' && value.trim().length > 0) {
64
+ return value
65
+ }
66
+ return '0'
67
+ }
68
+
69
+ function resolveOrderId(data: SalesOrderRecord | undefined): string | null {
70
+ return typeof data?.id === 'string' && data.id.length > 0 ? data.id : null
71
+ }
72
+
73
+ export default function SalesOrderStockContextWidget(
74
+ props: InjectionWidgetComponentProps<unknown, SalesOrderRecord>,
75
+ ) {
76
+ const { data } = props
77
+ const t = useT()
78
+ const router = useRouter()
79
+ const { organizationId, tenantId } = useOrganizationScopeDetail()
80
+ const access = useWmsInventoryMutationAccess()
81
+ const orderId = resolveOrderId(data)
82
+ const wms = data?._wms
83
+ const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<string | null>(null)
84
+ const [saving, setSaving] = React.useState(false)
85
+ const [rerunning, setRerunning] = React.useState(false)
86
+ const [variantLabels, setVariantLabels] = React.useState<Map<string, string>>(new Map())
87
+ const [releaseReservationId, setReleaseReservationId] = React.useState<string | null>(null)
88
+
89
+ const { runMutation, retryLastMutation } = useGuardedMutation({
90
+ contextId: 'wms-sales-order-warehouse-assignment',
91
+ })
92
+ const mutationContext = React.useMemo(
93
+ () => ({ retryLastMutation }),
94
+ [retryLastMutation],
95
+ )
96
+
97
+ React.useEffect(() => {
98
+ if (wms?.isExplicitlyAssigned && wms.assignedWarehouseId) {
99
+ setSelectedWarehouseId(wms.assignedWarehouseId)
100
+ return
101
+ }
102
+ setSelectedWarehouseId(null)
103
+ }, [wms?.assignedWarehouseId, wms?.isExplicitlyAssigned])
104
+
105
+ const stockSummary = React.useMemo(
106
+ () => (Array.isArray(wms?.stockSummary) ? wms.stockSummary : []),
107
+ [wms?.stockSummary],
108
+ )
109
+
110
+ React.useEffect(() => {
111
+ const variantIds = stockSummary
112
+ .map((item) => item.catalogVariantId)
113
+ .filter((id): id is string => !!id)
114
+ if (variantIds.length === 0) return
115
+ void (async () => {
116
+ const entries = await Promise.all(
117
+ variantIds.map(async (id) => {
118
+ const label = await resolveCatalogVariantLabel(id)
119
+ return [id, label ?? id] as const
120
+ }),
121
+ )
122
+ setVariantLabels(new Map(entries))
123
+ })()
124
+ }, [stockSummary])
125
+
126
+ const canManageAssignment = access.canRelease
127
+ const assignedLabel =
128
+ wms?.assignedWarehouseName ||
129
+ (wms?.isExplicitlyAssigned ? wms.assignedWarehouseId : null) ||
130
+ t('wms.widgets.sales.stockContext.unassigned', 'Not assigned')
131
+
132
+ const warehouseSeedOptions = React.useMemo(() => {
133
+ if (!wms?.assignedWarehouseId) return []
134
+ const label = wms.assignedWarehouseName?.trim() || wms.assignedWarehouseId
135
+ return [{ value: wms.assignedWarehouseId, label }]
136
+ }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])
137
+
138
+ const resolveWarehouseComboboxLabel = React.useCallback(async (value: string) => {
139
+ if (wms?.assignedWarehouseId === value && wms.assignedWarehouseName?.trim()) {
140
+ return wms.assignedWarehouseName.trim()
141
+ }
142
+ const label = await resolveWarehouseLabel(value)
143
+ return label ?? value
144
+ }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])
145
+
146
+ const persistAssignment = React.useCallback(
147
+ async (warehouseId: string | null) => {
148
+ if (!orderId || !organizationId || !tenantId) return
149
+ setSaving(true)
150
+ try {
151
+ const mutationPayload = {
152
+ organizationId,
153
+ tenantId,
154
+ warehouseId,
155
+ }
156
+ await runMutation({
157
+ operation: async () => {
158
+ if (warehouseId) {
159
+ const response = await apiCall<{ ok?: boolean }>(
160
+ `/api/wms/sales-orders/${orderId}/warehouse-assignment`,
161
+ {
162
+ method: 'PUT',
163
+ headers: { 'content-type': 'application/json' },
164
+ body: JSON.stringify(mutationPayload),
165
+ },
166
+ )
167
+ if (!response.ok) await raiseCrudError(response.response)
168
+ } else {
169
+ const response = await apiCall<{ ok?: boolean }>(
170
+ `/api/wms/sales-orders/${orderId}/warehouse-assignment`,
171
+ {
172
+ method: 'DELETE',
173
+ headers: { 'content-type': 'application/json' },
174
+ body: JSON.stringify({
175
+ organizationId,
176
+ tenantId,
177
+ }),
178
+ },
179
+ )
180
+ if (!response.ok) await raiseCrudError(response.response)
181
+ }
182
+ },
183
+ context: mutationContext,
184
+ mutationPayload,
185
+ })
186
+
187
+ router.refresh()
188
+ flash(
189
+ warehouseId
190
+ ? t(
191
+ 'wms.widgets.sales.stockContext.assignSuccess',
192
+ 'Warehouse assignment saved.',
193
+ )
194
+ : t(
195
+ 'wms.widgets.sales.stockContext.unassignSuccess',
196
+ 'Warehouse assignment cleared.',
197
+ ),
198
+ 'success',
199
+ )
200
+ } catch {
201
+ flash(
202
+ t(
203
+ 'wms.widgets.sales.stockContext.assignError',
204
+ 'Could not update warehouse assignment.',
205
+ ),
206
+ 'error',
207
+ )
208
+ } finally {
209
+ setSaving(false)
210
+ }
211
+ },
212
+ [mutationContext, orderId, organizationId, router, runMutation, t, tenantId],
213
+ )
214
+
215
+ const handleRerunReservation = React.useCallback(async () => {
216
+ if (!orderId || !organizationId || !tenantId) return
217
+ setRerunning(true)
218
+ try {
219
+ const response = await apiCall<{ ok?: boolean }>(
220
+ `/api/wms/sales-orders/${orderId}/re-run-reservation`,
221
+ {
222
+ method: 'POST',
223
+ headers: { 'content-type': 'application/json' },
224
+ body: JSON.stringify({ organizationId, tenantId }),
225
+ },
226
+ )
227
+ if (!response.ok) await raiseCrudError(response.response)
228
+ router.refresh()
229
+ flash(
230
+ t(
231
+ 'wms.widgets.sales.stockContext.rerunSuccess',
232
+ 'Reservation re-run triggered. Stock context will refresh shortly.',
233
+ ),
234
+ 'success',
235
+ )
236
+ } catch {
237
+ flash(
238
+ t(
239
+ 'wms.widgets.sales.stockContext.rerunError',
240
+ 'Could not re-run reservation.',
241
+ ),
242
+ 'error',
243
+ )
244
+ } finally {
245
+ setRerunning(false)
246
+ }
247
+ }, [orderId, organizationId, router, t, tenantId])
248
+
249
+ if (!wms) return null
250
+
251
+ const reservationStatus = wms.reservationSummary?.status ?? 'unreserved'
252
+ const reservationIds = Array.isArray(wms.reservationSummary?.reservationIds)
253
+ ? (wms.reservationSummary?.reservationIds ?? [])
254
+ : []
255
+
256
+ const releaseReservation = releaseReservationId
257
+ ? { id: releaseReservationId }
258
+ : null
259
+
260
+ return (
261
+ <div className="rounded-lg border bg-card px-4 py-3 space-y-4">
262
+ <div className="flex items-start justify-between gap-3">
263
+ <div className="space-y-1">
264
+ <p className="text-sm font-medium">
265
+ {t(
266
+ 'wms.widgets.sales.stockContext.title',
267
+ 'WMS stock context',
268
+ )}
269
+ </p>
270
+ <p className="text-xs text-muted-foreground">
271
+ {t(
272
+ 'wms.widgets.sales.stockContext.description',
273
+ 'Live reservation and availability summary for this sales order.',
274
+ )}
275
+ </p>
276
+ </div>
277
+ <StatusBadge
278
+ variant={reservationStatusMap[reservationStatus]}
279
+ dot
280
+ >
281
+ {t(
282
+ `wms.widgets.sales.stockContext.status.${reservationStatus}`,
283
+ reservationStatus,
284
+ )}
285
+ </StatusBadge>
286
+ </div>
287
+
288
+ <dl className="grid gap-3 text-sm sm:grid-cols-2">
289
+ <div className="space-y-2 sm:col-span-2">
290
+ <dt className="text-xs text-muted-foreground">
291
+ {t(
292
+ 'wms.widgets.sales.stockContext.assignedWarehouse',
293
+ 'Assigned warehouse',
294
+ )}
295
+ </dt>
296
+ <dd>
297
+ {canManageAssignment && orderId ? (
298
+ <ComboboxInput
299
+ value={selectedWarehouseId ?? ''}
300
+ onChange={(value) => {
301
+ const nextValue = value.trim().length > 0 ? value : null
302
+ setSelectedWarehouseId(nextValue)
303
+ void persistAssignment(nextValue)
304
+ }}
305
+ seedOptions={warehouseSeedOptions}
306
+ resolveLabel={resolveWarehouseComboboxLabel}
307
+ loadSuggestions={async (query) => {
308
+ const options = await loadWarehouseOptions(query)
309
+ return options.map((option) => ({
310
+ value: option.value,
311
+ label: option.label,
312
+ }))
313
+ }}
314
+ placeholder={t(
315
+ 'wms.widgets.sales.stockContext.warehousePlaceholder',
316
+ 'Select a warehouse',
317
+ )}
318
+ allowCustomValues={false}
319
+ disabled={saving}
320
+ />
321
+ ) : (
322
+ <span className="font-medium">{assignedLabel}</span>
323
+ )}
324
+ </dd>
325
+ {wms.isExplicitlyAssigned ? (
326
+ <p className="text-xs text-muted-foreground">
327
+ {t(
328
+ 'wms.widgets.sales.stockContext.explicitAssignmentHint',
329
+ 'Explicit assignment overrides reservation-derived warehouse context.',
330
+ )}
331
+ </p>
332
+ ) : null}
333
+ </div>
334
+ <div className="space-y-1">
335
+ <dt className="text-xs text-muted-foreground">
336
+ {t(
337
+ 'wms.widgets.sales.stockContext.reservationCount',
338
+ 'Reservation records',
339
+ )}
340
+ </dt>
341
+ <dd className="font-medium">{reservationIds.length}</dd>
342
+ </div>
343
+ </dl>
344
+
345
+ {stockSummary.length > 0 ? (
346
+ <div className="space-y-2">
347
+ <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
348
+ {t(
349
+ 'wms.widgets.sales.stockContext.linesTitle',
350
+ 'Variant availability',
351
+ )}
352
+ </p>
353
+ <div className="space-y-2">
354
+ {stockSummary.map((item) => {
355
+ const id = item.catalogVariantId ?? 'unknown'
356
+ const label = variantLabels.get(id) ?? id
357
+ return (
358
+ <div
359
+ key={id}
360
+ className="rounded-md border border-border/70 bg-background px-3 py-2"
361
+ >
362
+ <p className="text-sm font-medium">{label}</p>
363
+ <div className="mt-1 flex flex-wrap gap-4 text-xs text-muted-foreground">
364
+ <span>
365
+ {t(
366
+ 'wms.widgets.sales.stockContext.available',
367
+ 'Available',
368
+ )}
369
+ {': '}
370
+ {formatQuantity(item.available)}
371
+ </span>
372
+ <span>
373
+ {t(
374
+ 'wms.widgets.sales.stockContext.reserved',
375
+ 'Reserved',
376
+ )}
377
+ {': '}
378
+ {formatQuantity(item.reserved)}
379
+ </span>
380
+ </div>
381
+ </div>
382
+ )
383
+ })}
384
+ </div>
385
+ </div>
386
+ ) : (
387
+ <p className="text-sm text-muted-foreground">
388
+ {t(
389
+ 'wms.widgets.sales.stockContext.empty',
390
+ 'No WMS stock summary is available for this order yet.',
391
+ )}
392
+ </p>
393
+ )}
394
+
395
+ {access.canRelease && reservationIds.length > 0 ? (
396
+ <div className="space-y-2">
397
+ <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
398
+ {t(
399
+ 'wms.widgets.sales.stockContext.reservationsTitle',
400
+ 'Active reservations',
401
+ )}
402
+ </p>
403
+ <div className="space-y-1">
404
+ {reservationIds.map((rid) => (
405
+ <div
406
+ key={rid}
407
+ className="flex items-center justify-between gap-2 rounded-md border border-border/70 bg-background px-3 py-1.5"
408
+ >
409
+ <span className="font-mono text-xs text-muted-foreground truncate">{rid}</span>
410
+ <Button
411
+ type="button"
412
+ variant="ghost"
413
+ size="sm"
414
+ className="h-6 shrink-0 px-2 text-xs text-status-error-fg hover:text-status-error-fg"
415
+ onClick={() => setReleaseReservationId(rid)}
416
+ >
417
+ <ShieldOff className="size-3 mr-1" />
418
+ {t('wms.widgets.sales.stockContext.releaseBtn', 'Release')}
419
+ </Button>
420
+ </div>
421
+ ))}
422
+ </div>
423
+ </div>
424
+ ) : null}
425
+
426
+ <div className="flex flex-wrap gap-2">
427
+ {reservationStatus !== 'fully_reserved' && access.canRelease && orderId ? (
428
+ <Button
429
+ type="button"
430
+ variant="outline"
431
+ size="sm"
432
+ disabled={rerunning}
433
+ onClick={() => void handleRerunReservation()}
434
+ >
435
+ <RefreshCw className={`size-3 mr-1.5 ${rerunning ? 'animate-spin' : ''}`} />
436
+ {t(
437
+ 'wms.widgets.sales.stockContext.actions.rerunReservation',
438
+ 'Re-run reservation',
439
+ )}
440
+ </Button>
441
+ ) : null}
442
+ <Button asChild variant="outline" size="sm">
443
+ <Link href="/backend/wms/inventory">
444
+ {t(
445
+ 'wms.widgets.sales.stockContext.actions.inventory',
446
+ 'Open inventory console',
447
+ )}
448
+ </Link>
449
+ </Button>
450
+ <Button asChild variant="outline" size="sm">
451
+ <Link href="/backend/wms/reservations">
452
+ {t(
453
+ 'wms.widgets.sales.stockContext.actions.reservations',
454
+ 'Open reservations',
455
+ )}
456
+ </Link>
457
+ </Button>
458
+ </div>
459
+
460
+ {access.canRelease ? (
461
+ <ReleaseReservationDialog
462
+ open={releaseReservationId !== null}
463
+ onOpenChange={(open) => {
464
+ if (!open) setReleaseReservationId(null)
465
+ }}
466
+ access={access}
467
+ reservation={releaseReservation}
468
+ onSuccess={() => {
469
+ setReleaseReservationId(null)
470
+ router.refresh()
471
+ }}
472
+ />
473
+ ) : null}
474
+ </div>
475
+ )
476
+ }
@@ -0,0 +1,15 @@
1
+ import type { InjectionWidgetModule } from '@open-mercato/shared/modules/widgets/injection'
2
+ import SalesOrderStockContextWidget, { type SalesOrderRecord } from './widget.client'
3
+
4
+ const widget: InjectionWidgetModule<unknown, SalesOrderRecord> = {
5
+ metadata: {
6
+ id: 'wms.injection.sales-order-stock-context',
7
+ title: 'WMS stock context',
8
+ description: 'Shows reservation and stock summary on sales orders',
9
+ features: ['wms.view'],
10
+ priority: 80,
11
+ },
12
+ Widget: SalesOrderStockContextWidget,
13
+ }
14
+
15
+ export default widget
@@ -0,0 +1,34 @@
1
+ import type { ModuleInjectionTable } from '@open-mercato/shared/modules/widgets/injection'
2
+
3
+ export const injectionTable: ModuleInjectionTable = {
4
+ 'crud-form:catalog.product:fields': [
5
+ {
6
+ widgetId: 'wms.injection.catalog-inventory-profile',
7
+ kind: 'group',
8
+ column: 2,
9
+ groupLabel: 'wms.widgets.catalog.inventoryProfile.groupLabel',
10
+ groupDescription: 'wms.widgets.catalog.inventoryProfile.groupDescription',
11
+ priority: 120,
12
+ },
13
+ ],
14
+ 'crud-form:catalog.catalog_product_variant:fields': [
15
+ {
16
+ widgetId: 'wms.injection.catalog-inventory-profile',
17
+ kind: 'group',
18
+ column: 2,
19
+ groupLabel: 'wms.widgets.catalog.inventoryProfile.groupLabel',
20
+ groupDescription: 'wms.widgets.catalog.inventoryProfile.groupDescription',
21
+ priority: 120,
22
+ },
23
+ ],
24
+ 'sales.document.detail.order:details': {
25
+ widgetId: 'wms.injection.sales-order-stock-context',
26
+ priority: 80,
27
+ },
28
+ 'data-table:sales.order.items:columns': {
29
+ widgetId: 'wms.injection.order-items-stock-column',
30
+ priority: 50,
31
+ },
32
+ }
33
+
34
+ export default injectionTable
@@ -0,0 +1,153 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { AlertTriangle, ExternalLink, Loader2, X } from 'lucide-react'
5
+ import { useRouter } from 'next/navigation'
6
+ import { Button } from '@open-mercato/ui/primitives/button'
7
+ import { IconButton } from '@open-mercato/ui/primitives/icon-button'
8
+ import { cn } from '@open-mercato/shared/lib/utils'
9
+ import { formatRelativeTime } from '@open-mercato/shared/lib/time'
10
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
11
+ import type { NotificationRendererProps } from '@open-mercato/shared/modules/notifications/types'
12
+
13
+ export function WmsLowStockRenderer({
14
+ notification,
15
+ onAction,
16
+ onDismiss,
17
+ actions = [],
18
+ }: NotificationRendererProps) {
19
+ const t = useT()
20
+ const router = useRouter()
21
+ const [executing, setExecuting] = React.useState(false)
22
+ const isUnread = notification.status === 'unread'
23
+ const availableQuantity = notification.bodyVariables?.availableQuantity
24
+ const reorderPoint = notification.bodyVariables?.reorderPoint
25
+ const state = notification.bodyVariables?.state
26
+
27
+ const viewAction = actions.find((action) => action.id === 'view') ?? actions[0] ?? null
28
+
29
+ const handleView = async () => {
30
+ if (!viewAction) {
31
+ if (notification.linkHref) router.push(notification.linkHref)
32
+ return
33
+ }
34
+ setExecuting(true)
35
+ try {
36
+ await onAction(viewAction.id)
37
+ } finally {
38
+ setExecuting(false)
39
+ }
40
+ }
41
+
42
+ const timeAgo = formatRelativeTime(notification.createdAt, { translate: t }) ?? ''
43
+
44
+ const stateLabel =
45
+ state === 'below_safety_stock'
46
+ ? t('wms.notifications.lowStock.renderer.belowSafetyStock', 'Below safety stock')
47
+ : t('wms.notifications.lowStock.renderer.belowReorderPoint', 'Below reorder point')
48
+
49
+ return (
50
+ <div
51
+ className={cn(
52
+ 'group relative flex gap-4 items-start rounded-xl p-3 transition-colors hover:bg-muted/40 cursor-pointer',
53
+ isUnread && 'bg-muted/20',
54
+ )}
55
+ onClick={handleView}
56
+ onKeyDown={(e) => {
57
+ if (e.key === 'Enter' || e.key === ' ') {
58
+ e.preventDefault()
59
+ handleView()
60
+ }
61
+ }}
62
+ role="button"
63
+ tabIndex={0}
64
+ >
65
+ <div className="relative shrink-0 flex size-10 items-center justify-center rounded-full bg-status-warning-bg">
66
+ <AlertTriangle className="size-5 text-status-warning-icon" aria-hidden="true" />
67
+ {isUnread ? (
68
+ <span
69
+ className="absolute -right-1 -top-1 size-3 rounded-full bg-status-warning-icon ring-2 ring-background"
70
+ aria-hidden="true"
71
+ />
72
+ ) : null}
73
+ </div>
74
+
75
+ <div className="flex min-w-0 flex-1 flex-col gap-1">
76
+ <p className="truncate text-sm font-medium leading-5 tracking-tight text-foreground">
77
+ {notification.title}
78
+ </p>
79
+
80
+ <div className="text-xs leading-4 text-muted-foreground">
81
+ {timeAgo ? (
82
+ <>
83
+ <span className="whitespace-nowrap">{timeAgo}</span>
84
+ <span aria-hidden="true" className="mx-1 text-text-disabled">·</span>
85
+ </>
86
+ ) : null}
87
+ <span className="whitespace-nowrap">{stateLabel}</span>
88
+ {availableQuantity !== undefined ? (
89
+ <>
90
+ <span aria-hidden="true" className="mx-1 text-text-disabled">·</span>
91
+ <span className="whitespace-nowrap font-medium text-foreground">
92
+ {t('wms.notifications.lowStock.renderer.available', 'Available')}: {availableQuantity}
93
+ </span>
94
+ </>
95
+ ) : null}
96
+ {reorderPoint !== undefined ? (
97
+ <>
98
+ <span aria-hidden="true" className="mx-1 text-text-disabled">·</span>
99
+ <span className="whitespace-nowrap">
100
+ {t('wms.notifications.lowStock.renderer.reorderPoint', 'Reorder')}: {reorderPoint}
101
+ </span>
102
+ </>
103
+ ) : null}
104
+ </div>
105
+
106
+ <div className="mt-2 flex items-center gap-2">
107
+ <Button
108
+ type="button"
109
+ variant="default"
110
+ size="sm"
111
+ onClick={(e) => {
112
+ e.stopPropagation()
113
+ handleView()
114
+ }}
115
+ disabled={executing || (!viewAction && !notification.linkHref)}
116
+ >
117
+ <ExternalLink className="size-3.5" aria-hidden="true" />
118
+ {t('wms.notifications.lowStock.renderer.viewSku', 'View SKU')}
119
+ {executing ? <Loader2 className="ml-1 size-3 animate-spin" /> : null}
120
+ </Button>
121
+ <Button
122
+ type="button"
123
+ variant="outline"
124
+ size="sm"
125
+ className="h-8 rounded-md px-2.5"
126
+ onClick={(e) => {
127
+ e.stopPropagation()
128
+ onDismiss()
129
+ }}
130
+ >
131
+ {t('notifications.actions.dismiss', 'Dismiss')}
132
+ </Button>
133
+ </div>
134
+ </div>
135
+
136
+ <IconButton
137
+ type="button"
138
+ variant="ghost"
139
+ size="xs"
140
+ className="absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100"
141
+ onClick={(e) => {
142
+ e.stopPropagation()
143
+ onDismiss()
144
+ }}
145
+ aria-label={t('notifications.actions.dismiss', 'Dismiss')}
146
+ >
147
+ <X className="size-3.5" />
148
+ </IconButton>
149
+ </div>
150
+ )
151
+ }
152
+
153
+ export default WmsLowStockRenderer