@flowselections/logistiek-engine 1.0.34 → 1.0.53

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 (160) hide show
  1. package/README.md +24 -24
  2. package/dist-lib/components/FlowCanvas.d.ts +28 -0
  3. package/dist-lib/components/FlowCanvas.d.ts.map +1 -0
  4. package/dist-lib/components/FlowCanvas.js +429 -0
  5. package/dist-lib/components/FlowOrders.d.ts +8 -0
  6. package/dist-lib/components/FlowOrders.d.ts.map +1 -0
  7. package/dist-lib/components/FlowOrders.js +125 -0
  8. package/dist-lib/components/FlowPage.d.ts +2 -0
  9. package/dist-lib/components/FlowPage.d.ts.map +1 -0
  10. package/dist-lib/components/FlowPage.js +141 -0
  11. package/dist-lib/components/InklapbaarVenster.d.ts +9 -0
  12. package/dist-lib/components/InklapbaarVenster.d.ts.map +1 -0
  13. package/dist-lib/components/InklapbaarVenster.js +10 -0
  14. package/dist-lib/components/LogistiekEnginePage.d.ts.map +1 -1
  15. package/dist-lib/components/LogistiekEnginePage.js +9 -3
  16. package/dist-lib/components/LogistiekEngineQueuePage.d.ts +2 -0
  17. package/dist-lib/components/LogistiekEngineQueuePage.d.ts.map +1 -0
  18. package/dist-lib/components/LogistiekEngineQueuePage.js +11 -0
  19. package/dist-lib/components/NodeTracePanel.d.ts +11 -0
  20. package/dist-lib/components/NodeTracePanel.d.ts.map +1 -0
  21. package/dist-lib/components/NodeTracePanel.js +40 -0
  22. package/dist-lib/components/OrderJourneyBar.d.ts +9 -0
  23. package/dist-lib/components/OrderJourneyBar.d.ts.map +1 -0
  24. package/dist-lib/components/OrderJourneyBar.js +26 -0
  25. package/dist-lib/components/OrderLogboek.d.ts +10 -0
  26. package/dist-lib/components/OrderLogboek.d.ts.map +1 -0
  27. package/dist-lib/components/OrderLogboek.js +92 -0
  28. package/dist-lib/components/OrderStopBanner.d.ts +5 -0
  29. package/dist-lib/components/OrderStopBanner.d.ts.map +1 -0
  30. package/dist-lib/components/OrderStopBanner.js +22 -0
  31. package/dist-lib/components/OrderTraceDetails.d.ts +22 -0
  32. package/dist-lib/components/OrderTraceDetails.d.ts.map +1 -0
  33. package/dist-lib/components/OrderTraceDetails.js +87 -0
  34. package/dist-lib/components/RegiePage.d.ts.map +1 -1
  35. package/dist-lib/components/RegiePage.js +11 -69
  36. package/dist-lib/components/WerktijdenCard.d.ts +2 -0
  37. package/dist-lib/components/WerktijdenCard.d.ts.map +1 -0
  38. package/dist-lib/components/WerktijdenCard.js +37 -0
  39. package/dist-lib/components/WerkwijzeHerindelingCard.d.ts.map +1 -1
  40. package/dist-lib/components/WerkwijzeHerindelingCard.js +100 -6
  41. package/dist-lib/hooks/useLogisticsTrace.d.ts +78 -0
  42. package/dist-lib/hooks/useLogisticsTrace.d.ts.map +1 -0
  43. package/dist-lib/hooks/useLogisticsTrace.js +152 -0
  44. package/dist-lib/hooks/useOrderNodeTrace.d.ts +11 -0
  45. package/dist-lib/hooks/useOrderNodeTrace.d.ts.map +1 -0
  46. package/dist-lib/hooks/useOrderNodeTrace.js +26 -0
  47. package/dist-lib/hooks/useOrderTrace.d.ts +74 -0
  48. package/dist-lib/hooks/useOrderTrace.d.ts.map +1 -0
  49. package/dist-lib/hooks/useOrderTrace.js +134 -0
  50. package/dist-lib/hooks/useOrderVersies.d.ts +47 -0
  51. package/dist-lib/hooks/useOrderVersies.d.ts.map +1 -0
  52. package/dist-lib/hooks/useOrderVersies.js +180 -0
  53. package/dist-lib/hooks/useRuleEngine.d.ts +1 -0
  54. package/dist-lib/hooks/useRuleEngine.d.ts.map +1 -1
  55. package/dist-lib/hooks/useRuleEngine.js +1 -0
  56. package/dist-lib/hooks/useShippingNoteStatus.d.ts +29 -0
  57. package/dist-lib/hooks/useShippingNoteStatus.d.ts.map +1 -0
  58. package/dist-lib/hooks/useShippingNoteStatus.js +107 -0
  59. package/dist-lib/hooks/useWerktijden.d.ts +33 -0
  60. package/dist-lib/hooks/useWerktijden.d.ts.map +1 -0
  61. package/dist-lib/hooks/useWerktijden.js +88 -0
  62. package/dist-lib/hooks/useWerkwijzeStatus.d.ts +12 -1
  63. package/dist-lib/hooks/useWerkwijzeStatus.d.ts.map +1 -1
  64. package/dist-lib/hooks/useWerkwijzeStatus.js +60 -4
  65. package/dist-lib/index.d.ts +13 -0
  66. package/dist-lib/index.d.ts.map +1 -1
  67. package/dist-lib/index.js +13 -0
  68. package/dist-lib/integrations/supabase/auth-middleware.d.ts +1600 -54
  69. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  70. package/dist-lib/integrations/supabase/client.server.d.ts +1600 -54
  71. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  72. package/dist-lib/integrations/supabase/client.server.js +1 -1
  73. package/dist-lib/integrations/supabase/moduleClient.d.ts +1600 -54
  74. package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
  75. package/dist-lib/integrations/supabase/types.d.ts +1618 -50
  76. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  77. package/dist-lib/lib/cartPlanRequests.server.d.ts +1 -1
  78. package/dist-lib/lib/cartPlanRequests.server.d.ts.map +1 -1
  79. package/dist-lib/lib/cartPlanRequests.server.js +49 -8
  80. package/dist-lib/lib/floridayDocuments.functions.d.ts +4644 -6
  81. package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -1
  82. package/dist-lib/lib/floridayDocuments.functions.js +1 -1
  83. package/dist-lib/lib/floridayDocuments.server.d.ts +14 -0
  84. package/dist-lib/lib/floridayDocuments.server.d.ts.map +1 -1
  85. package/dist-lib/lib/floridayDocuments.server.js +58 -0
  86. package/dist-lib/lib/floridayGuard.server.d.ts +1 -1
  87. package/dist-lib/lib/floridayGuard.server.d.ts.map +1 -1
  88. package/dist-lib/lib/floridayGuard.server.js +6 -3
  89. package/dist-lib/lib/floridayPush.functions.d.ts +1600 -54
  90. package/dist-lib/lib/floridayPush.functions.d.ts.map +1 -1
  91. package/dist-lib/lib/floridayPush.functions.js +1 -1
  92. package/dist-lib/lib/flowGraph.d.ts +43 -0
  93. package/dist-lib/lib/flowGraph.d.ts.map +1 -0
  94. package/dist-lib/lib/flowGraph.js +153 -0
  95. package/dist-lib/lib/flowNodes.d.ts +23 -0
  96. package/dist-lib/lib/flowNodes.d.ts.map +1 -0
  97. package/dist-lib/lib/flowNodes.js +58 -0
  98. package/dist-lib/lib/flowRoute.d.ts +107 -0
  99. package/dist-lib/lib/flowRoute.d.ts.map +1 -0
  100. package/dist-lib/lib/flowRoute.js +280 -0
  101. package/dist-lib/lib/flowTree.d.ts +64 -0
  102. package/dist-lib/lib/flowTree.d.ts.map +1 -0
  103. package/dist-lib/lib/flowTree.js +519 -0
  104. package/dist-lib/lib/handlers/index.d.ts +1 -0
  105. package/dist-lib/lib/handlers/index.d.ts.map +1 -1
  106. package/dist-lib/lib/handlers/index.js +1 -0
  107. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts +3 -0
  108. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts.map +1 -0
  109. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.js +100 -0
  110. package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
  111. package/dist-lib/lib/handlers/logistics-tick.server.js +97 -2
  112. package/dist-lib/lib/loadCarrierPlanner.d.ts +2 -0
  113. package/dist-lib/lib/loadCarrierPlanner.d.ts.map +1 -1
  114. package/dist-lib/lib/loadCarrierPlanner.js +18 -0
  115. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +7740 -10
  116. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -1
  117. package/dist-lib/lib/loadCarrierPlanning.functions.js +1 -1
  118. package/dist-lib/lib/loadCarrierPlanning.server.d.ts +9 -0
  119. package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
  120. package/dist-lib/lib/loadCarrierPlanning.server.js +44 -17
  121. package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -1
  122. package/dist-lib/lib/logisticsPlanner.js +14 -2
  123. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +3096 -4
  124. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -1
  125. package/dist-lib/lib/logisticsRecalcJob.functions.js +1 -1
  126. package/dist-lib/lib/logisticsRecalculate.functions.d.ts +1600 -54
  127. package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -1
  128. package/dist-lib/lib/logisticsRecalculate.functions.js +1 -1
  129. package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
  130. package/dist-lib/lib/modulePrompts.js +3459 -2677
  131. package/dist-lib/lib/nodeTrace.d.ts +61 -0
  132. package/dist-lib/lib/nodeTrace.d.ts.map +1 -0
  133. package/dist-lib/lib/nodeTrace.js +191 -0
  134. package/dist-lib/lib/pickQueueCleanup.server.d.ts +14 -0
  135. package/dist-lib/lib/pickQueueCleanup.server.d.ts.map +1 -0
  136. package/dist-lib/lib/pickQueueCleanup.server.js +80 -0
  137. package/dist-lib/lib/planQueue.server.d.ts.map +1 -1
  138. package/dist-lib/lib/planQueue.server.js +140 -0
  139. package/dist-lib/lib/ruleEngineImpact.d.ts.map +1 -1
  140. package/dist-lib/lib/ruleEngineImpact.js +11 -4
  141. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
  142. package/dist-lib/lib/ruleEngineSchema.js +50 -6
  143. package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -1
  144. package/dist-lib/lib/ruleEngineWizard.js +3 -1
  145. package/dist-lib/lib/shippingNoteQueue.server.d.ts +18 -0
  146. package/dist-lib/lib/shippingNoteQueue.server.d.ts.map +1 -0
  147. package/dist-lib/lib/shippingNoteQueue.server.js +304 -0
  148. package/dist-lib/lib/trace.server.d.ts +75 -0
  149. package/dist-lib/lib/trace.server.d.ts.map +1 -0
  150. package/dist-lib/lib/trace.server.js +75 -0
  151. package/dist-lib/lib/vakUitleg.d.ts +19 -0
  152. package/dist-lib/lib/vakUitleg.d.ts.map +1 -0
  153. package/dist-lib/lib/vakUitleg.js +132 -0
  154. package/package.json +26 -2
  155. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +0 -2
  156. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +0 -1
  157. package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +0 -41
  158. package/dist-lib/integrations/supabase/client.d.ts +0 -20293
  159. package/dist-lib/integrations/supabase/client.d.ts.map +0 -1
  160. package/dist-lib/integrations/supabase/client.js +0 -13
@@ -105,6 +105,17 @@ export async function handleLogisticsTick(request, supabase) {
105
105
  catch (e) {
106
106
  buffers = { error: String(e?.message ?? e) };
107
107
  }
108
+ // Na het sluiten of losmaken van een buffer: de pickwachtrij opnieuw vullen,
109
+ // zodat elke eenheid (ook een losgekoppelde order) zijn eigen karaantallen
110
+ // uit het actuele karplan meekrijgt.
111
+ let queueRefresh = null;
112
+ try {
113
+ const { data, error } = await supabase.rpc("logistics_sync_pick_queue");
114
+ queueRefresh = error ? { error: error.message } : data;
115
+ }
116
+ catch (e) {
117
+ queueRefresh = { error: String(e?.message ?? e) };
118
+ }
108
119
  // Floriday-pushwachtrij verwerken binnen dezelfde aanroep, met eigen marge.
109
120
  let push = null;
110
121
  try {
@@ -124,6 +135,53 @@ export async function handleLogisticsTick(request, supabase) {
124
135
  catch (e) {
125
136
  control = { error: String(e?.message ?? e) };
126
137
  }
138
+ // Verzendbrief die meelift met een geprinte pakbon (Floriday-orders).
139
+ // Deze verwerking is verplicht: ontbreekt zij, dan is de draaiende versie te
140
+ // oud en moet de tick dat als fout melden in plaats van "succes".
141
+ let shippingNotes = null;
142
+ let shippingNotesOk = false;
143
+ let shippingNotesBackfill = null;
144
+ try {
145
+ // Inhaalslag: pakbonnen die al in het pickstation staan alsnog van een
146
+ // verzendbrief voorzien. Idempotent, dus veilig bij elke tick.
147
+ const { data: backfill } = await supabase.rpc("logistics_ensure_shipping_notes", {
148
+ p_limit: 200,
149
+ });
150
+ shippingNotesBackfill = backfill ?? null;
151
+ // Zelfherstel: een eigen verzendbrief die bij een Floriday-order hoort wordt
152
+ // geannuleerd en vervangen door de officiele Floriday-aanvraag.
153
+ try {
154
+ await supabase.rpc("logistics_fix_wrong_shipping_notes");
155
+ }
156
+ catch {
157
+ /* zelfherstel mag de ronde niet blokkeren */
158
+ }
159
+ const { runShippingNoteQueue } = await import("../shippingNoteQueue.server.js");
160
+ if (typeof runShippingNoteQueue !== "function") {
161
+ throw new Error("Deze versie van de Logistiek Engine bevat geen verzendbriefverwerking. Werk de module bij.");
162
+ }
163
+ const result = (await runShippingNoteQueue(supabase, { limit: 10 }));
164
+ const verwacht = ["claimed", "printed", "waiting", "retrying", "failed"];
165
+ const ontbreekt = verwacht.filter((k) => typeof result?.[k] !== "number");
166
+ if (ontbreekt.length > 0) {
167
+ throw new Error(`De verzendbriefverwerking levert geen volledige telling (mist: ${ontbreekt.join(", ")}). Werk de module bij.`);
168
+ }
169
+ shippingNotes = {
170
+ found: result["claimed"],
171
+ printed: result["printed"],
172
+ waitingForFloriday: result["waiting"],
173
+ retrying: result["retrying"],
174
+ failed: result["failed"],
175
+ printJobsCreated: result["printed"],
176
+ backfill: shippingNotesBackfill,
177
+ errors: result["errors"] ?? [],
178
+ };
179
+ shippingNotesOk = true;
180
+ }
181
+ catch (e) {
182
+ shippingNotes = { error: String(e?.message ?? e) };
183
+ shippingNotesOk = false;
184
+ }
127
185
  // Seintjes van de pickschermen: karplan ontbreekt. Direct oppakken.
128
186
  let cartPlanRequests = null;
129
187
  try {
@@ -133,6 +191,28 @@ export async function handleLogisticsTick(request, supabase) {
133
191
  catch (e) {
134
192
  cartPlanRequests = { error: String(e?.message ?? e) };
135
193
  }
194
+ // In de karwerkwijze vervangen concrete karregels de oude orderregel. Een
195
+ // reeds geprinte orderregel blijft als historie bestaan, maar mag niet meer
196
+ // als actieve printregel met een verouderde status op het scherm staan.
197
+ let queueCleanup = null;
198
+ try {
199
+ const { retireSupersededOrderRows } = await import("../pickQueueCleanup.server.js");
200
+ queueCleanup = await retireSupersededOrderRows(supabase);
201
+ }
202
+ catch (e) {
203
+ queueCleanup = { error: String(e?.message ?? e) };
204
+ }
205
+ // Pakbonnen zonder kar, of van een kar die na een herindeling niet meer
206
+ // bestaat, kunnen nooit een barcode krijgen. Die worden hier afgesloten met
207
+ // een leesbare reden in plaats van eeuwig te blijven wachten.
208
+ let orphanPrintJobs = null;
209
+ try {
210
+ const { data, error } = await supabase.rpc("logistics_cleanup_orphan_print_jobs");
211
+ orphanPrintJobs = error ? { error: error.message } : data;
212
+ }
213
+ catch (e) {
214
+ orphanPrintJobs = { error: String(e?.message ?? e) };
215
+ }
136
216
  // Barcodeverzoeken van de Layout maker: de Engine bepaalt de kar en levert
137
217
  // de vaste barcode terug in het verzoek én in de printopdracht. Kan het
138
218
  // niet, dan wordt het verzoek geannuleerd met een reden (fail closed).
@@ -146,8 +226,19 @@ export async function handleLogisticsTick(request, supabase) {
146
226
  catch (e) {
147
227
  barcodes = { error: String(e?.message ?? e) };
148
228
  }
229
+ // Laadtoestand per eenheid bijwerken, zodat de pickschermen niet hoeven te
230
+ // wisselen tussen teksten maar een vaste toestand met reden zien.
231
+ let planState = null;
232
+ try {
233
+ const { data, error } = await supabase.rpc("logistics_refresh_plan_state", { p_limit: 500 });
234
+ planState = error ? { error: error.message } : data;
235
+ }
236
+ catch (e) {
237
+ planState = { error: String(e?.message ?? e) };
238
+ }
149
239
  return Response.json({
150
- ok: true,
240
+ ok: shippingNotesOk,
241
+ planState,
151
242
  ticks,
152
243
  status: last?.status ?? "idle",
153
244
  phase: last?.phase ?? null,
@@ -156,10 +247,14 @@ export async function handleLogisticsTick(request, supabase) {
156
247
  orphans,
157
248
  bufferQueue,
158
249
  buffers,
250
+ queueRefresh,
159
251
  pickupMoments,
160
252
  push,
161
253
  control,
254
+ shippingNotes,
162
255
  barcodes,
163
256
  cartPlanRequests,
164
- }, { headers: CORS_HEADERS });
257
+ queueCleanup,
258
+ orphanPrintJobs,
259
+ }, { status: shippingNotesOk ? 200 : 500, headers: CORS_HEADERS });
165
260
  }
@@ -38,6 +38,8 @@ export interface PlannerOptions {
38
38
  maxOrders?: number | null;
39
39
  maxCustomers?: number | null;
40
40
  oneCustomerPerLayer?: boolean;
41
+ /** Maximaal aantal verschillende klanten binnen één laag. */
42
+ maxCustomersPerLayer?: number | null;
41
43
  /** Vanaf zoveel volle lagen krijgt een partij altijd een eigen ladingdrager. */
42
44
  ownCarrierFromLayers?: number | null;
43
45
  sortOrder?: "location" | "customer" | "product" | "size" | "none";
@@ -1 +1 @@
1
- {"version":3,"file":"loadCarrierPlanner.d.ts","sourceRoot":"","sources":["../../src/lib/loadCarrierPlanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loadCarrierPlanner.d.ts","sourceRoot":"","sources":["../../src/lib/loadCarrierPlanner.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,7 @@ function placeAsFreshLayer(cart, batch, batchIdx, crates) {
43
43
  heightPct: batch.layerHeightPct,
44
44
  crateShare: crates / batch.cratesPerLayer,
45
45
  entries: [{ batchIdx, crates }],
46
+ customerIds: new Set(batch.input.customer_id ? [batch.input.customer_id] : []),
46
47
  });
47
48
  cart.totalHeightPct += batch.layerHeightPct;
48
49
  return true;
@@ -65,6 +66,19 @@ function placeInLayer(cart, batch, batchIdx, crates, r) {
65
66
  // REGEL 4 — dezelfde partij niet twee keer in dezelfde laag
66
67
  if (layer.entries.some((e) => e.batchIdx === batchIdx))
67
68
  continue;
69
+ // REGEL 4b — maximaal aantal verschillende klanten op één laag
70
+ const layerCustomerLimit = r.opts.oneCustomerPerLayer
71
+ ? 1
72
+ : r.opts.maxCustomersPerLayer && r.opts.maxCustomersPerLayer > 0
73
+ ? r.opts.maxCustomersPerLayer
74
+ : null;
75
+ const customerId = batch.input.customer_id ?? null;
76
+ if (layerCustomerLimit != null &&
77
+ customerId &&
78
+ !layer.customerIds.has(customerId) &&
79
+ layer.customerIds.size >= layerCustomerLimit) {
80
+ continue;
81
+ }
68
82
  // REGEL 5 — vloeroppervlak van de laag mag niet over 100%
69
83
  if (layer.crateShare + partyShare > 1 + EPS)
70
84
  continue;
@@ -74,6 +88,8 @@ function placeInLayer(cart, batch, batchIdx, crates, r) {
74
88
  if (cart.totalHeightPct + heightDelta > 100 + EPS)
75
89
  continue;
76
90
  layer.entries.push({ batchIdx, crates });
91
+ if (customerId)
92
+ layer.customerIds.add(customerId);
77
93
  layer.crateShare += partyShare;
78
94
  layer.heightPct = newHeight;
79
95
  cart.totalHeightPct += heightDelta;
@@ -265,6 +281,7 @@ export function planLoadUnits(inputs, options) {
265
281
  neverMixProductIds: options.neverMixProductIds ?? new Set(),
266
282
  maxOrders: options.maxOrders ?? null,
267
283
  maxCustomers: options.maxCustomers ?? null,
284
+ maxCustomersPerLayer: options.maxCustomersPerLayer ?? null,
268
285
  oneCustomerPerLayer: options.oneCustomerPerLayer ?? false,
269
286
  ownCarrierFromLayers: options.ownCarrierFromLayers ?? null,
270
287
  sortOrder: options.sortOrder ?? "none",
@@ -356,6 +373,7 @@ export function planLoadUnits(inputs, options) {
356
373
  heightPct: 100,
357
374
  crateShare: 1,
358
375
  entries: [{ batchIdx: bi, crates: batch.cratesRemaining }],
376
+ customerIds: new Set(batch.input.customer_id ? [batch.input.customer_id] : []),
359
377
  });
360
378
  cart.totalHeightPct = 100;
361
379
  registerPlacement(cart, batch, batch.cratesRemaining);