@open-mercato/core 0.10.1-develop.7709.1.046124599c → 0.10.1-develop.7714.1.9dbb8200d8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/asn/index.js +19 -0
  3. package/dist/generated/entities/asn/index.js.map +7 -0
  4. package/dist/generated/entities/putaway_task/index.js +25 -0
  5. package/dist/generated/entities/putaway_task/index.js.map +7 -0
  6. package/dist/generated/entities/receiving_line/index.js +21 -0
  7. package/dist/generated/entities/receiving_line/index.js.map +7 -0
  8. package/dist/generated/entities.ids.generated.js +4 -1
  9. package/dist/generated/entities.ids.generated.js.map +2 -2
  10. package/dist/generated/entity-fields-registry.js +34 -0
  11. package/dist/generated/entity-fields-registry.js.map +2 -2
  12. package/dist/modules/communication_channels/lib/sanitize-channel-html.js +22 -3
  13. package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +2 -2
  14. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +40 -11
  15. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +2 -2
  16. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +13 -2
  17. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  18. package/dist/modules/wms/acl.js +2 -0
  19. package/dist/modules/wms/acl.js.map +2 -2
  20. package/dist/modules/wms/api/asns/[id]/complete/route.js +61 -0
  21. package/dist/modules/wms/api/asns/[id]/complete/route.js.map +7 -0
  22. package/dist/modules/wms/api/asns/[id]/receive/route.js +68 -0
  23. package/dist/modules/wms/api/asns/[id]/receive/route.js.map +7 -0
  24. package/dist/modules/wms/api/asns/route.js +197 -0
  25. package/dist/modules/wms/api/asns/route.js.map +7 -0
  26. package/dist/modules/wms/api/inventory/helpers.js +42 -34
  27. package/dist/modules/wms/api/inventory/helpers.js.map +2 -2
  28. package/dist/modules/wms/api/inventory/receive/route.js +1 -1
  29. package/dist/modules/wms/api/inventory/receive/route.js.map +2 -2
  30. package/dist/modules/wms/api/listEnrichers.js +23 -0
  31. package/dist/modules/wms/api/listEnrichers.js.map +2 -2
  32. package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js +56 -0
  33. package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js.map +7 -0
  34. package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js +56 -0
  35. package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js.map +7 -0
  36. package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js +65 -0
  37. package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js.map +7 -0
  38. package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js +56 -0
  39. package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js.map +7 -0
  40. package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js +51 -0
  41. package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js.map +7 -0
  42. package/dist/modules/wms/api/putaway-tasks/route.js +192 -0
  43. package/dist/modules/wms/api/putaway-tasks/route.js.map +7 -0
  44. package/dist/modules/wms/api/receiving-lines/route.js +180 -0
  45. package/dist/modules/wms/api/receiving-lines/route.js.map +7 -0
  46. package/dist/modules/wms/api/scan/putaway/route.js +104 -0
  47. package/dist/modules/wms/api/scan/putaway/route.js.map +7 -0
  48. package/dist/modules/wms/api/scan/receive/route.js +109 -0
  49. package/dist/modules/wms/api/scan/receive/route.js.map +7 -0
  50. package/dist/modules/wms/api/scan/resolve-location/route.js +89 -0
  51. package/dist/modules/wms/api/scan/resolve-location/route.js.map +7 -0
  52. package/dist/modules/wms/api/scan/resolve-lot/route.js +89 -0
  53. package/dist/modules/wms/api/scan/resolve-lot/route.js.map +7 -0
  54. package/dist/modules/wms/backend/wms/asns/[id]/page.js +9 -0
  55. package/dist/modules/wms/backend/wms/asns/[id]/page.js.map +7 -0
  56. package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js +18 -0
  57. package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js.map +7 -0
  58. package/dist/modules/wms/backend/wms/asns/page.js +9 -0
  59. package/dist/modules/wms/backend/wms/asns/page.js.map +7 -0
  60. package/dist/modules/wms/backend/wms/asns/page.meta.js +18 -0
  61. package/dist/modules/wms/backend/wms/asns/page.meta.js.map +7 -0
  62. package/dist/modules/wms/backend/wms/putaway/page.js +9 -0
  63. package/dist/modules/wms/backend/wms/putaway/page.js.map +7 -0
  64. package/dist/modules/wms/backend/wms/putaway/page.meta.js +18 -0
  65. package/dist/modules/wms/backend/wms/putaway/page.meta.js.map +7 -0
  66. package/dist/modules/wms/backend/wms/receiving/page.js +8 -0
  67. package/dist/modules/wms/backend/wms/receiving/page.js.map +7 -0
  68. package/dist/modules/wms/backend/wms/receiving/page.meta.js +18 -0
  69. package/dist/modules/wms/backend/wms/receiving/page.meta.js.map +7 -0
  70. package/dist/modules/wms/ce.js +27 -0
  71. package/dist/modules/wms/ce.js.map +2 -2
  72. package/dist/modules/wms/commands/asn.js +1746 -0
  73. package/dist/modules/wms/commands/asn.js.map +7 -0
  74. package/dist/modules/wms/commands/index.js +2 -0
  75. package/dist/modules/wms/commands/index.js.map +2 -2
  76. package/dist/modules/wms/commands/inventory-actions.js +347 -243
  77. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  78. package/dist/modules/wms/commands/putaway.js +945 -0
  79. package/dist/modules/wms/commands/putaway.js.map +7 -0
  80. package/dist/modules/wms/commands/shared.js +51 -0
  81. package/dist/modules/wms/commands/shared.js.map +2 -2
  82. package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js +278 -0
  83. package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js.map +7 -0
  84. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js +327 -0
  85. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js.map +7 -0
  86. package/dist/modules/wms/components/backend/CreateAsnDialog.js +404 -0
  87. package/dist/modules/wms/components/backend/CreateAsnDialog.js.map +7 -0
  88. package/dist/modules/wms/components/backend/InventoryOperationsSection.js +16 -3
  89. package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +2 -2
  90. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js +476 -0
  91. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js.map +7 -0
  92. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +2 -2
  93. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +2 -2
  94. package/dist/modules/wms/components/backend/WmsAsnDetailPage.js +524 -0
  95. package/dist/modules/wms/components/backend/WmsAsnDetailPage.js.map +7 -0
  96. package/dist/modules/wms/components/backend/WmsAsnsListPage.js +339 -0
  97. package/dist/modules/wms/components/backend/WmsAsnsListPage.js.map +7 -0
  98. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +5 -6
  99. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  100. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +5 -6
  101. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  102. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +14 -10
  103. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  104. package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js +598 -0
  105. package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js.map +7 -0
  106. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +5 -6
  107. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  108. package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js +32 -0
  109. package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js.map +7 -0
  110. package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js +36 -0
  111. package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js.map +7 -0
  112. package/dist/modules/wms/components/backend/inboundStatusUi.js +106 -0
  113. package/dist/modules/wms/components/backend/inboundStatusUi.js.map +7 -0
  114. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +17 -0
  115. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  116. package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js +14 -0
  117. package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js.map +7 -0
  118. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +4 -0
  119. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +2 -2
  120. package/dist/modules/wms/data/enrichers.js +117 -12
  121. package/dist/modules/wms/data/enrichers.js.map +2 -2
  122. package/dist/modules/wms/data/entities.js +150 -1
  123. package/dist/modules/wms/data/entities.js.map +2 -2
  124. package/dist/modules/wms/data/validators.js +214 -0
  125. package/dist/modules/wms/data/validators.js.map +2 -2
  126. package/dist/modules/wms/events.js +12 -1
  127. package/dist/modules/wms/events.js.map +2 -2
  128. package/dist/modules/wms/extension-points.js +3 -1
  129. package/dist/modules/wms/extension-points.js.map +2 -2
  130. package/dist/modules/wms/lib/asnReceiving.js +124 -0
  131. package/dist/modules/wms/lib/asnReceiving.js.map +7 -0
  132. package/dist/modules/wms/lib/asnVendor.js +52 -0
  133. package/dist/modules/wms/lib/asnVendor.js.map +7 -0
  134. package/dist/modules/wms/lib/flashMutationError.js +4 -0
  135. package/dist/modules/wms/lib/flashMutationError.js.map +2 -2
  136. package/dist/modules/wms/lib/inventoryDisplayUi.js +24 -0
  137. package/dist/modules/wms/lib/inventoryDisplayUi.js.map +2 -2
  138. package/dist/modules/wms/lib/inventoryPolicy.js +17 -0
  139. package/dist/modules/wms/lib/inventoryPolicy.js.map +2 -2
  140. package/dist/modules/wms/lib/loadOperationalDashboard.js +67 -1
  141. package/dist/modules/wms/lib/loadOperationalDashboard.js.map +2 -2
  142. package/dist/modules/wms/lib/putaway.js +141 -0
  143. package/dist/modules/wms/lib/putaway.js.map +7 -0
  144. package/dist/modules/wms/lib/roleFeatures.js +3 -1
  145. package/dist/modules/wms/lib/roleFeatures.js.map +2 -2
  146. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +99 -1
  147. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +2 -2
  148. package/dist/modules/wms/lib/scanResolve.js +147 -0
  149. package/dist/modules/wms/lib/scanResolve.js.map +7 -0
  150. package/dist/modules/wms/lib/wmsIntegrationToggles.js +1 -1
  151. package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +2 -2
  152. package/dist/modules/wms/migrations/Migration20260812120000.js +43 -0
  153. package/dist/modules/wms/migrations/Migration20260812120000.js.map +7 -0
  154. package/dist/modules/wms/migrations/Migration20260812130000.js +30 -0
  155. package/dist/modules/wms/migrations/Migration20260812130000.js.map +7 -0
  156. package/dist/modules/wms/migrations/Migration20260822120000.js +17 -0
  157. package/dist/modules/wms/migrations/Migration20260822120000.js.map +7 -0
  158. package/dist/modules/wms/migrations/Migration20260822130000.js +17 -0
  159. package/dist/modules/wms/migrations/Migration20260822130000.js.map +7 -0
  160. package/dist/modules/wms/migrations/Migration20261029120000.js +13 -0
  161. package/dist/modules/wms/migrations/Migration20261029120000.js.map +7 -0
  162. package/dist/modules/wms/search.js +85 -0
  163. package/dist/modules/wms/search.js.map +2 -2
  164. package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js +14 -0
  165. package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js.map +7 -0
  166. package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js +12 -0
  167. package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js.map +7 -0
  168. package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js +163 -0
  169. package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js.map +7 -0
  170. package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js +14 -0
  171. package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js.map +7 -0
  172. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +37 -8
  173. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +2 -2
  174. package/generated/entities/asn/index.ts +8 -0
  175. package/generated/entities/putaway_task/index.ts +11 -0
  176. package/generated/entities/receiving_line/index.ts +9 -0
  177. package/generated/entities.ids.generated.ts +4 -1
  178. package/generated/entity-fields-registry.ts +34 -0
  179. package/package.json +7 -7
  180. package/src/modules/auth/i18n/de.json +2 -0
  181. package/src/modules/auth/i18n/en.json +2 -0
  182. package/src/modules/auth/i18n/es.json +2 -0
  183. package/src/modules/auth/i18n/ko.json +2 -0
  184. package/src/modules/auth/i18n/pl.json +2 -0
  185. package/src/modules/communication_channels/i18n/de.json +2 -0
  186. package/src/modules/communication_channels/i18n/en.json +2 -0
  187. package/src/modules/communication_channels/i18n/es.json +2 -0
  188. package/src/modules/communication_channels/i18n/ko.json +2 -0
  189. package/src/modules/communication_channels/i18n/pl.json +2 -0
  190. package/src/modules/communication_channels/lib/sanitize-channel-html.ts +23 -3
  191. package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +44 -12
  192. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +16 -2
  193. package/src/modules/wms/acl.ts +2 -0
  194. package/src/modules/wms/api/asns/[id]/complete/route.ts +62 -0
  195. package/src/modules/wms/api/asns/[id]/receive/route.ts +74 -0
  196. package/src/modules/wms/api/asns/route.ts +200 -0
  197. package/src/modules/wms/api/inventory/helpers.ts +57 -34
  198. package/src/modules/wms/api/inventory/receive/route.ts +2 -1
  199. package/src/modules/wms/api/listEnrichers.ts +38 -0
  200. package/src/modules/wms/api/putaway-tasks/[id]/assign/route.ts +56 -0
  201. package/src/modules/wms/api/putaway-tasks/[id]/cancel/route.ts +56 -0
  202. package/src/modules/wms/api/putaway-tasks/[id]/complete/route.ts +66 -0
  203. package/src/modules/wms/api/putaway-tasks/[id]/start/route.ts +56 -0
  204. package/src/modules/wms/api/putaway-tasks/create-from-balance/route.ts +50 -0
  205. package/src/modules/wms/api/putaway-tasks/route.ts +199 -0
  206. package/src/modules/wms/api/receiving-lines/route.ts +180 -0
  207. package/src/modules/wms/api/scan/putaway/route.ts +108 -0
  208. package/src/modules/wms/api/scan/receive/route.ts +118 -0
  209. package/src/modules/wms/api/scan/resolve-location/route.ts +92 -0
  210. package/src/modules/wms/api/scan/resolve-lot/route.ts +92 -0
  211. package/src/modules/wms/backend/wms/asns/[id]/page.meta.ts +14 -0
  212. package/src/modules/wms/backend/wms/asns/[id]/page.tsx +5 -0
  213. package/src/modules/wms/backend/wms/asns/page.meta.ts +14 -0
  214. package/src/modules/wms/backend/wms/asns/page.tsx +5 -0
  215. package/src/modules/wms/backend/wms/putaway/page.meta.ts +14 -0
  216. package/src/modules/wms/backend/wms/putaway/page.tsx +5 -0
  217. package/src/modules/wms/backend/wms/receiving/page.meta.ts +14 -0
  218. package/src/modules/wms/backend/wms/receiving/page.tsx +5 -0
  219. package/src/modules/wms/ce.ts +27 -0
  220. package/src/modules/wms/commands/asn.ts +2122 -0
  221. package/src/modules/wms/commands/index.ts +2 -0
  222. package/src/modules/wms/commands/inventory-actions.ts +413 -243
  223. package/src/modules/wms/commands/putaway.ts +1169 -0
  224. package/src/modules/wms/commands/shared.ts +51 -0
  225. package/src/modules/wms/components/backend/AssignPutawayTaskDialog.tsx +328 -0
  226. package/src/modules/wms/components/backend/CompletePutawayTaskDialog.tsx +366 -0
  227. package/src/modules/wms/components/backend/CreateAsnDialog.tsx +427 -0
  228. package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +20 -2
  229. package/src/modules/wms/components/backend/ReceiveAsnLineDialog.tsx +535 -0
  230. package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +2 -2
  231. package/src/modules/wms/components/backend/WmsAsnDetailPage.tsx +647 -0
  232. package/src/modules/wms/components/backend/WmsAsnsListPage.tsx +407 -0
  233. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -5
  234. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -5
  235. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +12 -8
  236. package/src/modules/wms/components/backend/WmsPutawayQueuePage.tsx +677 -0
  237. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -5
  238. package/src/modules/wms/components/backend/asnCompleteOptimisticLock.ts +52 -0
  239. package/src/modules/wms/components/backend/asnReceivingLinesLoader.ts +83 -0
  240. package/src/modules/wms/components/backend/inboundStatusUi.ts +154 -0
  241. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -0
  242. package/src/modules/wms/components/backend/putawayQueueOptimisticLock.ts +20 -0
  243. package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +4 -0
  244. package/src/modules/wms/data/enrichers.ts +175 -13
  245. package/src/modules/wms/data/entities.ts +155 -0
  246. package/src/modules/wms/data/validators.ts +256 -0
  247. package/src/modules/wms/events.ts +11 -0
  248. package/src/modules/wms/extension-points.ts +2 -0
  249. package/src/modules/wms/i18n/de.json +205 -3
  250. package/src/modules/wms/i18n/en.json +205 -3
  251. package/src/modules/wms/i18n/es.json +205 -3
  252. package/src/modules/wms/i18n/ko.json +205 -3
  253. package/src/modules/wms/i18n/pl.json +205 -3
  254. package/src/modules/wms/lib/asnReceiving.ts +226 -0
  255. package/src/modules/wms/lib/asnVendor.ts +80 -0
  256. package/src/modules/wms/lib/flashMutationError.ts +4 -0
  257. package/src/modules/wms/lib/inventoryDisplayUi.ts +46 -0
  258. package/src/modules/wms/lib/inventoryPolicy.ts +31 -1
  259. package/src/modules/wms/lib/loadOperationalDashboard.ts +89 -1
  260. package/src/modules/wms/lib/putaway.ts +210 -0
  261. package/src/modules/wms/lib/roleFeatures.ts +2 -0
  262. package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +150 -1
  263. package/src/modules/wms/lib/scanResolve.ts +185 -0
  264. package/src/modules/wms/lib/wmsIntegrationToggles.ts +2 -1
  265. package/src/modules/wms/migrations/.snapshot-open-mercato.json +1000 -0
  266. package/src/modules/wms/migrations/Migration20260812120000.ts +43 -0
  267. package/src/modules/wms/migrations/Migration20260812130000.ts +28 -0
  268. package/src/modules/wms/migrations/Migration20260822120000.ts +17 -0
  269. package/src/modules/wms/migrations/Migration20260822130000.ts +15 -0
  270. package/src/modules/wms/migrations/Migration20261029120000.ts +11 -0
  271. package/src/modules/wms/search.ts +95 -0
  272. package/src/modules/wms/subscribers/asn-line-received-reevaluate-reservations.ts +21 -0
  273. package/src/modules/wms/subscribers/invalidate-enricher-cache-asn.ts +12 -0
  274. package/src/modules/wms/subscribers/procurement-goods-receipt-created.ts +238 -0
  275. package/src/modules/wms/subscribers/putaway-completed-reevaluate-reservations.ts +21 -0
  276. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +63 -13
@@ -25,6 +25,9 @@ export type InventoryMovementType =
25
25
  | 'cycle_count'
26
26
  | 'return_receive'
27
27
  export type InventoryMovementReferenceType = 'po' | 'so' | 'transfer' | 'manual' | 'qc' | 'rma'
28
+ export type AsnStatus = 'draft' | 'in_transit' | 'received' | 'closed'
29
+ export type ReceivingLineQcStatus = 'pending' | 'passed' | 'failed'
30
+ export type PutawayTaskStatus = 'open' | 'in_progress' | 'done' | 'cancelled'
28
31
  type WmsOptionalProps = 'createdAt' | 'updatedAt' | 'deletedAt' | 'metadata'
29
32
 
30
33
  abstract class WmsScopedEntity {
@@ -434,3 +437,155 @@ export class InventoryMovement extends WmsScopedEntity {
434
437
  @Property({ name: 'idempotency_key', type: 'text', nullable: true })
435
438
  idempotencyKey?: string | null
436
439
  }
440
+
441
+ @Entity({ tableName: 'wms_asns' })
442
+ @Index({ name: 'wms_asns_org_tenant_idx', properties: ['organizationId', 'tenantId'] })
443
+ @Index({
444
+ name: 'wms_asns_org_warehouse_status_expected_idx',
445
+ properties: ['organizationId', 'warehouse', 'status', 'expectedAt'],
446
+ })
447
+ @Index({
448
+ name: 'wms_asns_org_vendor_expected_idx',
449
+ expression:
450
+ 'create index "wms_asns_org_vendor_expected_idx" on "wms_asns" ("organization_id", "vendor_id", "expected_at" desc) where deleted_at is null',
451
+ })
452
+ @Index({
453
+ name: 'wms_asns_org_source_key_unique_idx',
454
+ expression:
455
+ 'create unique index "wms_asns_org_source_key_unique_idx" on "wms_asns" ("organization_id", "source_key") where source_key is not null and deleted_at is null',
456
+ })
457
+ export class Asn extends WmsScopedEntity {
458
+ [OptionalProps]?: WmsOptionalProps | 'vendorId' | 'referenceNumber' | 'notes' | 'status' | 'sourceKey'
459
+
460
+ @ManyToOne(() => Warehouse, { fieldName: 'warehouse_id' })
461
+ warehouse!: Warehouse
462
+
463
+ @Property({ name: 'vendor_id', type: 'uuid', nullable: true })
464
+ vendorId?: string | null
465
+
466
+ @Property({ type: 'text', default: 'draft' })
467
+ status: AsnStatus = 'draft'
468
+
469
+ @Property({ name: 'expected_at', type: Date })
470
+ expectedAt!: Date
471
+
472
+ @Property({ name: 'reference_number', type: 'text', nullable: true })
473
+ referenceNumber?: string | null
474
+
475
+ /** Stable external linkage key (e.g. procurement goods receipt) for find-or-create. */
476
+ @Property({ name: 'source_key', type: 'text', nullable: true })
477
+ sourceKey?: string | null
478
+
479
+ @Property({ type: 'text', nullable: true })
480
+ notes?: string | null
481
+
482
+ @OneToMany(() => ReceivingLine, (line) => line.asn)
483
+ lines = new Collection<ReceivingLine>(this)
484
+ }
485
+
486
+ @Entity({ tableName: 'wms_receiving_lines' })
487
+ @Index({ name: 'wms_receiving_lines_org_tenant_idx', properties: ['organizationId', 'tenantId'] })
488
+ @Index({ name: 'wms_receiving_lines_org_asn_idx', properties: ['organizationId', 'asn'] })
489
+ @Index({
490
+ name: 'wms_receiving_lines_org_variant_qc_idx',
491
+ properties: ['organizationId', 'catalogVariantId', 'qcStatus'],
492
+ })
493
+ export class ReceivingLine extends WmsScopedEntity {
494
+ [OptionalProps]?:
495
+ | WmsOptionalProps
496
+ | 'lotNumber'
497
+ | 'serialNumbers'
498
+ | 'targetStagingLocationId'
499
+ | 'rejectionReason'
500
+ | 'receivedQty'
501
+ | 'qcStatus'
502
+
503
+ @ManyToOne(() => Asn, { fieldName: 'asn_id' })
504
+ asn!: Asn
505
+
506
+ @Property({ name: 'catalog_variant_id', type: 'uuid' })
507
+ catalogVariantId!: string
508
+
509
+ @Property({ name: 'expected_qty', type: 'numeric', precision: 16, scale: 4 })
510
+ expectedQty!: string
511
+
512
+ @Property({ name: 'received_qty', type: 'numeric', precision: 16, scale: 4, default: '0' })
513
+ receivedQty: string = '0'
514
+
515
+ @Property({ name: 'lot_number', type: 'text', nullable: true })
516
+ lotNumber?: string | null
517
+
518
+ @Property({ name: 'serial_numbers', type: 'jsonb', nullable: true })
519
+ serialNumbers?: string[] | null
520
+
521
+ @Property({ name: 'qc_status', type: 'text', default: 'pending' })
522
+ qcStatus: ReceivingLineQcStatus = 'pending'
523
+
524
+ @Property({ name: 'target_staging_location_id', type: 'uuid', nullable: true })
525
+ targetStagingLocationId?: string | null
526
+
527
+ @Property({ name: 'rejection_reason', type: 'text', nullable: true })
528
+ rejectionReason?: string | null
529
+ }
530
+
531
+ @Entity({ tableName: 'wms_putaway_tasks' })
532
+ @Index({ name: 'wms_putaway_tasks_org_tenant_idx', properties: ['organizationId', 'tenantId'] })
533
+ @Index({
534
+ name: 'wms_putaway_tasks_org_warehouse_status_priority_idx',
535
+ properties: ['organizationId', 'warehouse', 'status', 'priority'],
536
+ })
537
+ @Index({
538
+ name: 'wms_putaway_tasks_org_assigned_status_idx',
539
+ properties: ['organizationId', 'assignedTo', 'status'],
540
+ })
541
+ @Index({
542
+ name: 'wms_putaway_tasks_org_putaway_key_unique_idx',
543
+ expression:
544
+ 'create unique index "wms_putaway_tasks_org_putaway_key_unique_idx" on "wms_putaway_tasks" ("organization_id", "putaway_key") where putaway_key is not null and deleted_at is null and status <> \'cancelled\'',
545
+ })
546
+ export class PutawayTask extends WmsScopedEntity {
547
+ [OptionalProps]?:
548
+ | WmsOptionalProps
549
+ | 'targetLocationId'
550
+ | 'lotId'
551
+ | 'serialNumber'
552
+ | 'assignedTo'
553
+ | 'priority'
554
+ | 'status'
555
+ | 'putawayKey'
556
+
557
+ @ManyToOne(() => Warehouse, { fieldName: 'warehouse_id' })
558
+ warehouse!: Warehouse
559
+
560
+ @Property({ name: 'source_location_id', type: 'uuid' })
561
+ sourceLocationId!: string
562
+
563
+ @Property({ name: 'target_location_id', type: 'uuid', nullable: true })
564
+ targetLocationId?: string | null
565
+
566
+ @Property({ name: 'catalog_variant_id', type: 'uuid' })
567
+ catalogVariantId!: string
568
+
569
+ @Property({ name: 'lot_id', type: 'uuid', nullable: true })
570
+ lotId?: string | null
571
+
572
+ /** Set on quantity-one tasks created for a serial-tracked receipt. Null for aggregate tasks. */
573
+ @Property({ name: 'serial_number', type: 'text', nullable: true })
574
+ serialNumber?: string | null
575
+
576
+ @Property({ type: 'numeric', precision: 16, scale: 4 })
577
+ quantity!: string
578
+
579
+ @Property({ type: 'text', default: 'open' })
580
+ status: PutawayTaskStatus = 'open'
581
+
582
+ @Property({ name: 'assigned_to', type: 'uuid', nullable: true })
583
+ assignedTo?: string | null
584
+
585
+ @Property({ type: 'integer', default: 5 })
586
+ priority: number = 5
587
+
588
+ /** Stable ASN-receive attempt key for find-or-create without scanning newest-N metadata. */
589
+ @Property({ name: 'putaway_key', type: 'text', nullable: true })
590
+ putawayKey?: string | null
591
+ }
@@ -228,6 +228,7 @@ export const inventoryReceiveSchema = scopedSchema.extend({
228
228
  receivedAt: z.coerce.date().optional(),
229
229
  performedAt: z.coerce.date().optional(),
230
230
  reason: z.string().trim().max(500).optional(),
231
+ reasonCode: z.string().trim().max(80).optional(),
231
232
  metadata: metadataSchema,
232
233
  })
233
234
 
@@ -325,6 +326,186 @@ export const inventoryMovementCreateSchema = scopedSchema.extend({
325
326
  metadata: metadataSchema,
326
327
  })
327
328
 
329
+ /** Statuses clients may set on create/update — terminal received/closed come from receive/complete. */
330
+ const asnWritableStatusSchema = z.enum(['draft', 'in_transit'])
331
+
332
+ export const receivingLineCreateFieldsSchema = z.object({
333
+ catalogVariantId: uuid(),
334
+ expectedQty: positiveQuantity,
335
+ lotNumber: z.string().trim().max(120).optional().nullable(),
336
+ serialNumbers: z.array(z.string().trim().min(1).max(120)).optional().nullable(),
337
+ targetStagingLocationId: uuid().optional().nullable(),
338
+ metadata: metadataSchema,
339
+ })
340
+
341
+ export const asnCreateSchema = scopedSchema.extend({
342
+ warehouseId: uuid(),
343
+ vendorId: uuid().optional().nullable(),
344
+ status: asnWritableStatusSchema.optional(),
345
+ expectedAt: z.coerce.date(),
346
+ referenceNumber: z.string().trim().max(120).optional().nullable(),
347
+ /**
348
+ * Stable external linkage key; unique per org when set (procurement goods receipt, etc.).
349
+ * Server/system creates only — public HTTP create strips this; authenticated clients cannot set it.
350
+ */
351
+ sourceKey: z.string().trim().min(1).max(200).optional().nullable(),
352
+ notes: z.string().trim().max(2000).optional().nullable(),
353
+ lines: z.array(receivingLineCreateFieldsSchema).optional(),
354
+ metadata: metadataSchema,
355
+ })
356
+
357
+ /** Public ASN create body — omits `sourceKey` so clients cannot spoof procurement linkage. */
358
+ export const asnCreatePublicSchema = asnCreateSchema.omit({ sourceKey: true })
359
+
360
+ export const asnUpdateSchema = z
361
+ .object({ id: uuid() })
362
+ .merge(
363
+ scopedSchema
364
+ .extend({
365
+ warehouseId: uuid(),
366
+ vendorId: uuid().nullable(),
367
+ status: asnWritableStatusSchema,
368
+ expectedAt: z.coerce.date(),
369
+ referenceNumber: z.string().trim().max(120).nullable(),
370
+ notes: z.string().trim().max(2000).nullable(),
371
+ metadata: metadataSchema,
372
+ })
373
+ .partial(),
374
+ )
375
+
376
+ export const receivingLineCreateSchema = scopedSchema.extend({
377
+ asnId: uuid(),
378
+ catalogVariantId: uuid(),
379
+ expectedQty: positiveQuantity,
380
+ lotNumber: z.string().trim().max(120).optional().nullable(),
381
+ serialNumbers: z.array(z.string().trim().min(1).max(120)).optional().nullable(),
382
+ targetStagingLocationId: uuid().optional().nullable(),
383
+ metadata: metadataSchema,
384
+ })
385
+
386
+ // Lifecycle fields (receivedQty / qcStatus / rejectionReason) are intentionally
387
+ // omitted — only `wms.asns.receive-line` may mutate them.
388
+ export const receivingLineUpdateSchema = z
389
+ .object({ id: uuid() })
390
+ .merge(
391
+ scopedSchema
392
+ .extend({
393
+ catalogVariantId: uuid(),
394
+ expectedQty: positiveQuantity,
395
+ lotNumber: z.string().trim().max(120).nullable(),
396
+ serialNumbers: z.array(z.string().trim().min(1).max(120)).nullable(),
397
+ targetStagingLocationId: uuid().nullable(),
398
+ metadata: metadataSchema,
399
+ })
400
+ .partial(),
401
+ )
402
+
403
+ export const asnReceiveLineSchema = scopedSchema
404
+ .extend({
405
+ asnId: uuid(),
406
+ lineId: uuid(),
407
+ receivedQty: positiveQuantity,
408
+ /**
409
+ * Absolute received quantity the client intends after this attempt.
410
+ * Required for QC-pass and QC-fail so retries after success remain
411
+ * idempotent (applyQty=0) even if prior qty advanced. Do not derive from
412
+ * delta alone — QC-fail still advances audit receivedQty.
413
+ */
414
+ targetReceivedQty: positiveQuantity.optional(),
415
+ /** Optional client-stable attempt id; extra stabilizer alongside absolute target. */
416
+ idempotencyKey: uuid().optional(),
417
+ targetStagingLocationId: uuid().optional(),
418
+ lotId: uuid().optional(),
419
+ lotNumber: z.string().trim().max(120).optional(),
420
+ serialNumbers: z.array(z.string().trim().min(1).max(120)).optional(),
421
+ qcStatus: z.enum(['passed', 'failed']),
422
+ rejectionReason: z.string().trim().max(500).optional(),
423
+ performedBy: uuid(),
424
+ receivedAt: z.coerce.date().optional(),
425
+ metadata: metadataSchema,
426
+ })
427
+ .superRefine((value, ctx) => {
428
+ if (value.targetReceivedQty == null) {
429
+ ctx.addIssue({
430
+ code: z.ZodIssueCode.custom,
431
+ path: ['targetReceivedQty'],
432
+ message: 'target_received_qty_required',
433
+ })
434
+ }
435
+ })
436
+
437
+ export const asnCloseSchema = scopedSchema.extend({
438
+ id: uuid(),
439
+ closeWhenShort: z.boolean().optional(),
440
+ })
441
+
442
+ export const putawayTaskCreateSchema = scopedSchema.extend({
443
+ warehouseId: uuid(),
444
+ sourceLocationId: uuid(),
445
+ targetLocationId: uuid().optional().nullable(),
446
+ catalogVariantId: uuid(),
447
+ lotId: uuid().optional().nullable(),
448
+ quantity: positiveQuantity,
449
+ priority: z.coerce.number().int().min(0).max(100).optional(),
450
+ assignedTo: uuid().optional().nullable(),
451
+ metadata: metadataSchema,
452
+ })
453
+
454
+ // Status and assignee transitions are intentionally omitted — only lifecycle
455
+ // commands (assign/start/complete/cancel) may change those fields.
456
+ export const putawayTaskUpdateSchema = z
457
+ .object({ id: uuid() })
458
+ .merge(
459
+ scopedSchema
460
+ .extend({
461
+ warehouseId: uuid(),
462
+ sourceLocationId: uuid(),
463
+ targetLocationId: uuid().nullable(),
464
+ catalogVariantId: uuid(),
465
+ lotId: uuid().nullable(),
466
+ quantity: positiveQuantity,
467
+ priority: z.coerce.number().int().min(0).max(100),
468
+ metadata: metadataSchema,
469
+ })
470
+ .partial(),
471
+ )
472
+
473
+ export const putawayTaskCreateFromBalanceSchema = scopedSchema.extend({
474
+ warehouseId: uuid(),
475
+ sourceLocationId: uuid(),
476
+ targetLocationId: uuid(),
477
+ catalogVariantId: uuid(),
478
+ lotId: uuid().optional(),
479
+ quantity: positiveQuantity,
480
+ priority: z.coerce.number().int().min(0).max(100).optional(),
481
+ assignedTo: uuid().optional().nullable(),
482
+ metadata: metadataSchema,
483
+ })
484
+
485
+ export const putawayTaskAssignSchema = scopedSchema.extend({
486
+ id: uuid(),
487
+ assignedTo: uuid(),
488
+ })
489
+
490
+ export const putawayTaskStartSchema = scopedSchema.extend({
491
+ id: uuid(),
492
+ })
493
+
494
+ export const putawayTaskCompleteSchema = scopedSchema.extend({
495
+ id: uuid(),
496
+ confirmedQuantity: positiveQuantity,
497
+ targetLocationId: uuid(),
498
+ lotId: uuid().optional(),
499
+ performedBy: uuid(),
500
+ performedAt: z.coerce.date().optional(),
501
+ reason: z.string().trim().min(1).max(500).optional(),
502
+ metadata: metadataSchema,
503
+ })
504
+
505
+ export const putawayTaskCancelSchema = scopedSchema.extend({
506
+ id: uuid(),
507
+ })
508
+
328
509
  export type WarehouseCreateInput = z.infer<typeof warehouseCreateSchema>
329
510
  export type WarehouseUpdateInput = z.infer<typeof warehouseUpdateSchema>
330
511
  export type WarehouseZoneCreateInput = z.infer<typeof warehouseZoneCreateSchema>
@@ -342,6 +523,78 @@ export type InventoryReservationAllocateInput = z.infer<typeof inventoryReservat
342
523
  export type InventoryAdjustInput = z.infer<typeof inventoryAdjustSchema>
343
524
  export type InventoryMoveInput = z.infer<typeof inventoryMoveSchema>
344
525
  export type InventoryCycleCountInput = z.infer<typeof inventoryCycleCountSchema>
526
+ export type AsnCreateInput = z.infer<typeof asnCreateSchema>
527
+ export type AsnCreatePublicInput = z.infer<typeof asnCreatePublicSchema>
528
+ export type AsnUpdateInput = z.infer<typeof asnUpdateSchema>
529
+ export type ReceivingLineCreateInput = z.infer<typeof receivingLineCreateSchema>
530
+ export type ReceivingLineUpdateInput = z.infer<typeof receivingLineUpdateSchema>
531
+ export type AsnReceiveLineInput = z.infer<typeof asnReceiveLineSchema>
532
+ export type AsnCloseInput = z.infer<typeof asnCloseSchema>
533
+ export type PutawayTaskCreateInput = z.infer<typeof putawayTaskCreateSchema>
534
+ export type PutawayTaskUpdateInput = z.infer<typeof putawayTaskUpdateSchema>
535
+ export type PutawayTaskCreateFromBalanceInput = z.infer<typeof putawayTaskCreateFromBalanceSchema>
536
+ export type PutawayTaskAssignInput = z.infer<typeof putawayTaskAssignSchema>
537
+ export type PutawayTaskStartInput = z.infer<typeof putawayTaskStartSchema>
538
+ export type PutawayTaskCompleteInput = z.infer<typeof putawayTaskCompleteSchema>
539
+ export type PutawayTaskCancelInput = z.infer<typeof putawayTaskCancelSchema>
540
+
541
+ export const scanResolveLocationSchema = scopedSchema.extend({
542
+ warehouseId: uuid(),
543
+ code: z.string().trim().min(1).max(120),
544
+ })
545
+
546
+ export const scanResolveLotSchema = scopedSchema.extend({
547
+ catalogVariantId: uuid(),
548
+ lotNumber: z.string().trim().min(1).max(120),
549
+ })
550
+
551
+ export const scanReceiveSchema = scopedSchema
552
+ .extend({
553
+ asnId: uuid(),
554
+ lineId: uuid(),
555
+ locationCode: z.string().trim().min(1).max(120),
556
+ lotNumber: z.string().trim().max(120).optional(),
557
+ serialNumbers: z.array(z.string().trim().min(1).max(120)).optional(),
558
+ receivedQty: positiveQuantity,
559
+ /**
560
+ * Absolute received quantity after this attempt. Required for QC-pass and
561
+ * QC-fail so identical retries no-op (applyQty=0). Do not derive as
562
+ * prior+delta in scan resolve — that doubles stock/audit qty on retry.
563
+ */
564
+ targetReceivedQty: positiveQuantity.optional(),
565
+ /** Optional client-stable attempt id; extra stabilizer alongside absolute target. */
566
+ idempotencyKey: uuid().optional(),
567
+ qcStatus: z.enum(['passed', 'failed']),
568
+ rejectionReason: z.string().trim().max(500).optional(),
569
+ performedBy: uuid(),
570
+ receivedAt: z.coerce.date().optional(),
571
+ metadata: metadataSchema,
572
+ })
573
+ .superRefine((value, ctx) => {
574
+ if (value.targetReceivedQty == null) {
575
+ ctx.addIssue({
576
+ code: z.ZodIssueCode.custom,
577
+ path: ['targetReceivedQty'],
578
+ message: 'target_received_qty_required',
579
+ })
580
+ }
581
+ })
582
+
583
+ export const scanPutawaySchema = scopedSchema.extend({
584
+ taskId: uuid(),
585
+ targetLocationCode: z.string().trim().min(1).max(120),
586
+ confirmedQuantity: positiveQuantity,
587
+ lotId: uuid().optional(),
588
+ performedBy: uuid(),
589
+ performedAt: z.coerce.date().optional(),
590
+ reason: z.string().trim().min(1).max(500).optional(),
591
+ metadata: metadataSchema,
592
+ })
593
+
594
+ export type ScanResolveLocationInput = z.infer<typeof scanResolveLocationSchema>
595
+ export type ScanResolveLotInput = z.infer<typeof scanResolveLotSchema>
596
+ export type ScanReceiveInput = z.infer<typeof scanReceiveSchema>
597
+ export type ScanPutawayInput = z.infer<typeof scanPutawaySchema>
345
598
 
346
599
  export const salesOrderWarehouseAssignBodySchema = scopedSchema.extend({
347
600
  warehouseId: uuid(),
@@ -452,7 +705,10 @@ export const operationalDashboardResponseSchema = z.object({
452
705
  variantId: z.string().uuid(),
453
706
  referenceType: z.string().nullable(),
454
707
  referenceId: z.string().nullable(),
708
+ referenceLabel: z.string().nullable().optional(),
455
709
  reason: z.string().nullable(),
710
+ reasonCode: z.string().nullable().optional(),
711
+ source: z.string().nullable().optional(),
456
712
  locationLabel: z.string(),
457
713
  performedAt: z.string(),
458
714
  }),
@@ -29,6 +29,17 @@ const events = [
29
29
  { id: 'wms.inventory.low_stock', label: 'Inventory Low Stock', entity: 'inventory', category: 'lifecycle' },
30
30
  { id: 'wms.inventory.balance_drift', label: 'Inventory Balance Drift', entity: 'inventory', category: 'lifecycle' },
31
31
  { id: 'wms.inventory.reservation_shortfall', label: 'Inventory Reservation Shortfall', entity: 'inventory', category: 'lifecycle' },
32
+ { id: 'wms.inventory.receipt_qc_failed', label: 'Inventory Receipt QC Failed', entity: 'inventory', category: 'custom' },
33
+ { id: 'wms.asn.created', label: 'ASN Created', entity: 'asn', category: 'crud' },
34
+ { id: 'wms.asn.updated', label: 'ASN Updated', entity: 'asn', category: 'crud' },
35
+ { id: 'wms.asn.receiving_started', label: 'ASN Receiving Started', entity: 'asn', category: 'lifecycle' },
36
+ { id: 'wms.asn.line_received', label: 'ASN Line Received', entity: 'asn', category: 'custom' },
37
+ { id: 'wms.asn.received', label: 'ASN Received', entity: 'asn', category: 'lifecycle' },
38
+ { id: 'wms.putaway.created', label: 'Putaway Task Created', entity: 'putaway', category: 'crud' },
39
+ { id: 'wms.putaway.assigned', label: 'Putaway Task Assigned', entity: 'putaway', category: 'lifecycle' },
40
+ { id: 'wms.putaway.started', label: 'Putaway Task Started', entity: 'putaway', category: 'lifecycle' },
41
+ { id: 'wms.putaway.completed', label: 'Putaway Task Completed', entity: 'putaway', category: 'lifecycle' },
42
+ { id: 'wms.putaway.cancelled', label: 'Putaway Task Cancelled', entity: 'putaway', category: 'lifecycle' },
32
43
  ] as const
33
44
 
34
45
  export const eventsConfig = createModuleEvents({
@@ -17,6 +17,8 @@ export const extensionPoints = defineModuleExtensionPoints({
17
17
  lotsTable: dataTableExtensionHost({ tableId: 'wms.lots.list', source: 'components/backend/WmsLotsListPage.tsx' }),
18
18
  skuDistributionTable: dataTableExtensionHost({ tableId: 'wms.sku.distribution', source: 'components/backend/WmsSkuDetailPage.tsx' }),
19
19
  skuActivityTable: dataTableExtensionHost({ tableId: 'wms.sku.activity', source: 'components/backend/WmsSkuDetailPage.tsx' }),
20
+ asnsTable: dataTableExtensionHost({ tableId: 'wms.asns.list', source: 'components/backend/WmsAsnsListPage.tsx' }),
21
+ putawayTasksTable: dataTableExtensionHost({ tableId: 'wms.putaway.tasks', source: 'components/backend/WmsPutawayQueuePage.tsx' }),
20
22
  },
21
23
  })
22
24