@flowselections/logistiek-engine 1.0.211 → 1.0.214

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.
@@ -31,6 +31,12 @@ export interface PlannerInputItem {
31
31
  * Afknijpen op layers_per_carrier zou kunstmatig extra karren opleveren.
32
32
  */
33
33
  packing_authoritative?: boolean;
34
+ /**
35
+ * 1.0.213: fysiek maximum aantal lagen op de gekozen ladingdrager =
36
+ * floor(hoogte ladingdrager ÷ max(fusthoogte, planthoogte incl. pot)). Alleen gezet
37
+ * als al die maten bekend zijn; nooit een standaardwaarde.
38
+ */
39
+ fysiek_max_lagen?: number | null;
34
40
  }
35
41
  export interface PlannerOptions {
36
42
  carrier: CarrierProfile;
@@ -160,5 +166,12 @@ export declare function karCapaciteit(productLagen: Array<number | null | undefi
160
166
  };
161
167
  /** Vulgraad in procenten (heel getal), of null als de capaciteit onbekend is. */
162
168
  export declare function karVulgraad(lagen: number, capaciteit: number | null): number | null;
169
+ /**
170
+ * 1.0.213: fysiek maximum aantal lagen = floor(hoogte ladingdrager ÷ laaghoogte),
171
+ * alleen als beide maten bekend zijn (nooit een standaardwaarde). null = niet te controleren.
172
+ */
173
+ export declare function fysiekeMaxLagen(item: PlannerInputItem, _carrier?: CarrierProfile): number | null;
174
+ /** Fysiek maximum lagen uit hoogte ladingdrager en laaghoogte; null als een maat ontbreekt. */
175
+ export declare function berekenFysiekMaxLagen(dragerHoogteCm: number | null | undefined, fustHoogteCm: number | null | undefined, plantHoogteCm: number | null | undefined): number | null;
163
176
  export declare function planLoadUnits(inputs: PlannerInputItem[], options: PlannerOptions): PlannerOutput;
164
177
  //# sourceMappingURL=loadCarrierPlanner.d.ts.map
@@ -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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"}
@@ -210,6 +210,21 @@ export function karVulgraad(lagen, capaciteit) {
210
210
  return null;
211
211
  return Math.round((100 * lagen) / capaciteit);
212
212
  }
213
+ /**
214
+ * 1.0.213: fysiek maximum aantal lagen = floor(hoogte ladingdrager ÷ laaghoogte),
215
+ * alleen als beide maten bekend zijn (nooit een standaardwaarde). null = niet te controleren.
216
+ */
217
+ export function fysiekeMaxLagen(item, _carrier) {
218
+ const n = Number(item.fysiek_max_lagen ?? 0);
219
+ return n >= 1 ? Math.floor(n) : null;
220
+ }
221
+ /** Fysiek maximum lagen uit hoogte ladingdrager en laaghoogte; null als een maat ontbreekt. */
222
+ export function berekenFysiekMaxLagen(dragerHoogteCm, fustHoogteCm, plantHoogteCm) {
223
+ const h = Number(dragerHoogteCm ?? 0), f = Number(fustHoogteCm ?? 0), p = Number(plantHoogteCm ?? 0);
224
+ if (!(h > 0) || !(f > 0) || !(p > 0))
225
+ return null;
226
+ return Math.max(1, Math.floor(h / Math.max(f, p) + 1e-9));
227
+ }
213
228
  function productLagen(item, carrier) {
214
229
  if (carrier.capacity_model === "single")
215
230
  return 1;
@@ -217,6 +232,9 @@ function productLagen(item, carrier) {
217
232
  const grens = carrier.werkwijze_max_lagen;
218
233
  if (typeof grens === "number" && grens > 0 && !item.packing_authoritative)
219
234
  l = Math.min(l, Math.round(grens));
235
+ const fys = fysiekeMaxLagen(item, carrier);
236
+ if (fys != null)
237
+ l = Math.min(l, fys);
220
238
  return l;
221
239
  }
222
240
  function accepteert(kar, rest, crates, r) {
@@ -397,11 +415,9 @@ export function planLoadUnits(inputs, options) {
397
415
  }))
398
416
  .filter((i) => i.plants > 0), r.opts.sortOrder);
399
417
  if (carrier.capacity_model === "none") {
400
- let n = 0;
401
- for (const it of items) {
402
- const crates = Math.ceil(it.plants / it.plants_per_crate);
403
- carts.push(fullCart(it, crates, crates, 1, ++n, r));
404
- }
418
+ // 1.0.213: zonder ladingdrager kan niets op een kar; geen indeling.
419
+ if (items.length > 0)
420
+ warnings.push("ladingdrager ontbreekt");
405
421
  return { carts, warnings };
406
422
  }
407
423
  // STAP A: volle karren per product (capaciteit = lagen per kar van dat product).
@@ -468,6 +484,8 @@ export function planLoadUnits(inputs, options) {
468
484
  }
469
485
  for (const kar of open)
470
486
  carts.push(samenvatten(kar, rests, carts.length + 1, r));
471
- carts.forEach((c, i) => { c.cart_number = i + 1; });
472
- return { carts, warnings };
487
+ // 1.0.213: een kar zonder fusten bestaat niet.
488
+ const gevuld = carts.filter((c) => (Array.isArray(c.items) ? c.items : []).some((x) => Number(x?.crates ?? 0) > 0));
489
+ gevuld.forEach((c, i) => { c.cart_number = i + 1; });
490
+ return { carts: gevuld, warnings };
473
491
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loadCarrierPlanning.server.d.ts","sourceRoot":"","sources":["../../src/lib/loadCarrierPlanning.server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAErF,OAAO,EAAiE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGvH,OAAO,EAWL,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAY1B,wBAAsB,6BAA6B,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwB/G;AAMD,UAAU,QAAQ;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wDAAwD;AACxD,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,SAAS,GACT,MAAM,CAAC;AAgBX;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAQ7E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAazF;AAaD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,wGAAwG;IACxG,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACxB,OAAO,EAAE,QAAQ,GAAG,IAAI,EACxB,WAAW,GAAE,YAAY,GAAG,IAAW,GACtC,gBAAgB,CA+BlB;AAGD,MAAM,WAAW,aAAa;IAC5B,mFAAmF;IACnF,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC5D,kEAAkE;IAClE,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IACzC,iHAAiH;IACjH,gBAAgB,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3F,qEAAqE;IACrE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C;;;OAGG;IACH,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,iEAAiE;IACjE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACtC,gGAAgG;IAChG,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC,CAAC;IAC1E,kFAAkF;IAClF,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjF;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,6FAA6F;AAC7F,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,SAAS,GAAG,KAAK,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,YAAY,EAAE,CAAA;CAAE,GAAG,SAAS,EAClE,YAAY,EAAE,MAAM,GACnB,YAAY,EAAE,GAAG,IAAI,CAmBvB;AAaD;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAChC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsK7B;AAwID,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AA6BD,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAQ9F;AAMD,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAO3F;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAcxD,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAMnG;AA8FD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,8CAA8C;IAC9C,YAAY,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,sGAAsG;IACtG,wBAAwB,EAAE,OAAO,CAAC;IAClC,4FAA4F;IAC5F,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAOD,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA0BzF;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,cAAc,GACjB,OAAO,CAAC,UAAU,GAAG,oBAAoB,CAAC,CAW5C;AAED,2FAA2F;AAC3F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,cAAc,CAcxG;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,EAAE,EAC1B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,QAAQ,GAChB,eAAe,EAAE,CAkEnB;AAUD,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAK1D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,GAClB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4BhC;AAyCD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,eAAe,EAAE,CAwCtF;AAwED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2GAA2G;IAC3G,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACxC,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;CAC3B;AAGD,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0GAA0G;IAC1G,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAGD,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,eAAe,EAAE,EACxB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,eAAe,GAAE,mBAAwB,GACxC,qBAAqB,EAAE,CAoCzB;AAqBD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,cAAc,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAoCnB;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,cAAc,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAyCvB;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,gFAC+C,CAAC;AAygDhF,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAI9B"}
1
+ {"version":3,"file":"loadCarrierPlanning.server.d.ts","sourceRoot":"","sources":["../../src/lib/loadCarrierPlanning.server.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  // draait de pure planner per ladingdragertype en schrijft het resultaat weg
6
6
  // naar order_carts / order_cart_items.
7
7
  // ============================================================================
8
- import { planLoadUnits, LOAD_CARRIER_PLANNER_VERSION, bepaalLaagMenging, } from "./loadCarrierPlanner.js";
8
+ import { planLoadUnits, LOAD_CARRIER_PLANNER_VERSION, bepaalLaagMenging, berekenFysiekMaxLagen, } from "./loadCarrierPlanner.js";
9
9
  import { traceBatch } from "./trace.server.js";
10
10
  import { zonderQuarantaine } from "./quarantaine.js";
11
11
  import { zonderStandaardBelading } from "./hoofdverpakking.js";
@@ -431,6 +431,8 @@ async function beladingOnwaarschijnlijk(sb, inputs, rawRows, profile, profielPer
431
431
  max_crates_per_layer: d?.maxPerLaag ?? (prof.max_crates_per_layer ?? null),
432
432
  standaard_lagen: prof.layers_per_carrier,
433
433
  });
434
+ // 1.0.213: fysieke grens aan de lagen per kar voor de planner (alleen met bekende maten).
435
+ i.fysiek_max_lagen = berekenFysiekMaxLagen(d?.h ?? null, mt?.height_mm ? mt.height_mm / 10 : null, mt?.plant ?? null);
434
436
  for (const w of fysiek.waarschuwen) {
435
437
  waarschuwingen.push({ order_id: i.order_id ?? null, sleutel: `fysiek:${verpakkingSleutel(i.product_id, i)}`, tekst: w });
436
438
  }
@@ -1368,7 +1370,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1368
1370
  }
1369
1371
  // Groepsregel naast ledenregels: niet ingedeeld, wel zichtbaar gemeld bij de order.
1370
1372
  for (const n of expandNotes) {
1371
- if (!n.order_id)
1373
+ if (!n.order_id || options.dryRun)
1372
1374
  continue;
1373
1375
  const { error: noteError } = await sb.rpc("logistics_trace_order_step", {
1374
1376
  p_order_id: n.order_id,
@@ -1533,9 +1535,9 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1533
1535
  }
1534
1536
  if (options.carrierType && !bekendeCodes.has(options.carrierType))
1535
1537
  nietInBeheer.set(options.carrierType, []);
1536
- if (nietInBeheer.size > 0 && !options.dryRun) {
1538
+ if (nietInBeheer.size > 0) {
1537
1539
  const reason = ladingdragerNietInBeheerTekst(nietInBeheer);
1538
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1540
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1539
1541
  p_order_ids: orderIds,
1540
1542
  p_reason: reason,
1541
1543
  p_details: {
@@ -1599,9 +1601,9 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1599
1601
  // 1.0.198: gewicht alleen relevant als de ladingdrager een kg-grens heeft.
1600
1602
  const heeftKgGrens = Number(guardProfile.max_weight_kg) > 0;
1601
1603
  const zonderGewicht = heeftKgGrens ? inputs.filter((i) => !(Number(i.weight_per_crate) > 0) && i.plants > 0) : [];
1602
- if (zonderGewicht.length > 0 && rules?.gewichtVerplicht === true && !options.dryRun) {
1604
+ if (zonderGewicht.length > 0 && rules?.gewichtVerplicht === true) {
1603
1605
  const reason = gewichtOnbekendTekst(zonderGewicht.map((i) => i.product_name));
1604
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1606
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1605
1607
  p_order_ids: orderIds,
1606
1608
  p_reason: reason,
1607
1609
  p_details: { reason_code: "gewicht_onbekend", bufferId, path: "typescript",
@@ -1629,7 +1631,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1629
1631
  }
1630
1632
  // Planten per fust is altijd nodig (ook zonder lagenmodel): fusten = planten / planten per fust.
1631
1633
  const blokkeerOnvolledig = onvolledig.filter((o) => o.velden.includes("plants_per_crate") || (needsBelading && !useDimensions));
1632
- if ((blokkeerOnvolledig.length > 0 || onbekendePlanten.length > 0) && !options.dryRun) {
1634
+ if ((blokkeerOnvolledig.length > 0 || onbekendePlanten.length > 0)) {
1633
1635
  const delen = [
1634
1636
  ...blokkeerOnvolledig.slice(0, 10).map((o) => `${o.item.product_name}: ${o.velden.map((v) => VELD_NAAM[v]).join(", ")} onbekend`),
1635
1637
  ...onbekendePlanten.slice(0, 10).map((o) => `${o.naam}: eenheid fust zonder planten per fust`),
@@ -1637,7 +1639,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1637
1639
  const reason = `Belading onvolledig voor ${blokkeerOnvolledig.length + onbekendePlanten.length} orderregel(s): ${delen.join("; ")}. ` +
1638
1640
  WAAR_INVULLEN;
1639
1641
  console.error(`[logistiek-engine] buffer ${bufferId} geblokkeerd: ${reason}`);
1640
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1642
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1641
1643
  p_order_ids: orderIds,
1642
1644
  p_reason: reason,
1643
1645
  p_details: {
@@ -1668,16 +1670,18 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1668
1670
  };
1669
1671
  }
1670
1672
  // 1.0.179 (punt 3): plausibiliteit, alle ordersoorten. Eén bevestiging per order en verpakking.
1671
- if (!options.dryRun) {
1673
+ // 1.0.213: ook in droge modus rekenen (alleen lezen); schrijven alleen buiten droge modus.
1674
+ {
1672
1675
  const oordeel = await beladingOnwaarschijnlijk(sb, inputs, rawRows, guardProfile, profielPerRegel);
1673
1676
  const onwaarschijnlijk = oordeel.blokkeren;
1674
1677
  // 1.0.197: fysiek onmogelijk = altijd blokkeren, niet te bevestigen; alleen gegevens aanpassen helpt.
1675
1678
  if (oordeel.onmogelijk.length > 0) {
1676
1679
  beladingWaarschuwingen.push(...oordeel.waarschuwingen);
1677
- await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1680
+ if (!options.dryRun)
1681
+ await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1678
1682
  const reason = `Belading fysiek onmogelijk: ${oordeel.onmogelijk.slice(0, 10).map((o) => o.redenen.join("; ")).join(" | ")}. ` +
1679
1683
  "Pas de gegevens aan in Beheer → Gegevens voor karindeling; bevestigen is hier niet mogelijk.";
1680
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1684
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1681
1685
  p_order_ids: orderIds,
1682
1686
  p_reason: reason,
1683
1687
  p_details: {
@@ -1707,11 +1711,12 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1707
1711
  beladingWaarschuwingen.push(...oordeel.waarschuwingen);
1708
1712
  for (const w of beladingWaarschuwingen)
1709
1713
  warnings.push(w.tekst);
1710
- await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1714
+ if (!options.dryRun)
1715
+ await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1711
1716
  if (onwaarschijnlijk.length > 0) {
1712
1717
  const reason = `Belading onwaarschijnlijk: ${onwaarschijnlijk.slice(0, 10).map((o) => `${o.product}: ${o.redenen.join("; ")}`).join(" | ")}. ` +
1713
1718
  "Kantoor moet dit bevestigen voordat er wordt ingedeeld.";
1714
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1719
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1715
1720
  p_order_ids: orderIds,
1716
1721
  p_reason: reason,
1717
1722
  p_details: { reason_code: "belading_onwaarschijnlijk", bufferId, path: "typescript", bevestigen: onwaarschijnlijk.slice(0, 50) },
@@ -1838,6 +1843,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1838
1843
  }
1839
1844
  else {
1840
1845
  // Ladingdrager per orderregel bepalen en per type een ronde draaien.
1846
+ const geenLadingdrager = [];
1841
1847
  const groups = new Map();
1842
1848
  for (const input of inputs) {
1843
1849
  const code = ladingdragerPerRegel.get(input.order_item_id) ?? defaultProfile.code;
@@ -1871,12 +1877,34 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1871
1877
  ownCarrierFromLayers: settings?.own_cart_from_layers ?? null,
1872
1878
  sortOrder: "none",
1873
1879
  });
1880
+ if (profile.capacity_model === "none" && list.length > 0) {
1881
+ geenLadingdrager.push(...list.map((x) => x.product_name));
1882
+ continue;
1883
+ }
1874
1884
  plannedCarts = plannedCarts.concat(result.carts);
1875
1885
  warnings.push(...result.warnings);
1876
1886
  }
1877
1887
  plannedCarts.forEach((c, idx) => {
1878
1888
  c.cart_number = idx + 1;
1879
1889
  });
1890
+ // 1.0.213: een product zonder ladingdrager (NONE / losse levering) kan niet op een kar: geen indeling.
1891
+ if (geenLadingdrager.length > 0) {
1892
+ const namen = Array.from(new Set(geenLadingdrager)).slice(0, 10).join(", ");
1893
+ const reason = `Geen indeling: ladingdrager ontbreekt (${namen}). Stel de ladingdrager van de hoofdverpakking in.`;
1894
+ if (!options.dryRun) {
1895
+ const { error: blockError } = await sb.rpc("logistics_plan_block", {
1896
+ p_order_ids: orderIds,
1897
+ p_reason: reason,
1898
+ p_details: { reason_code: "ladingdrager_ontbreekt", bufferId, path: "typescript", producten: Array.from(new Set(geenLadingdrager)).slice(0, 50) },
1899
+ });
1900
+ if (blockError)
1901
+ warnings.push(`Blokkade kon niet worden vastgelegd: ${blockError.message}`);
1902
+ }
1903
+ return {
1904
+ ok: false, bufferId, orderIds, cartsCreated: 0, replacedManualCount: 0, usedFloridayPacking,
1905
+ warnings: [...warnings, reason], skipped: "blocked", blockedReason: reason, beladingSources,
1906
+ };
1907
+ }
1880
1908
  }
1881
1909
  // Veiligheidsgrens: een onrealistisch grote uitkomst wordt niet afgekapt maar
1882
1910
  // geblokkeerd. Een half plan laat planten stilzwijgend uit de pickstroom vallen.
@@ -1,2 +1,2 @@
1
- export declare const MODULE_VERSION = "1.0.211";
1
+ export declare const MODULE_VERSION = "1.0.214";
2
2
  //# sourceMappingURL=moduleVersion.d.ts.map
@@ -1,2 +1,2 @@
1
1
  // Automatisch gegenereerd door prebuild:lib; niet handmatig aanpassen.
2
- export const MODULE_VERSION = "1.0.211";
2
+ export const MODULE_VERSION = "1.0.214";
@@ -0,0 +1,39 @@
1
+ import type { PlannedLoadUnit } from "./loadCarrierPlanner.js";
2
+ export interface PlanPreviewRegel {
3
+ orderItemId: string;
4
+ product: string;
5
+ fust: number;
6
+ stuks: number;
7
+ }
8
+ export interface PlanPreviewKar {
9
+ karNummer: number;
10
+ ladingdrager: string;
11
+ lagen: number;
12
+ platen: number;
13
+ vulgraadPct: number;
14
+ teHoog: boolean;
15
+ karTekst: string;
16
+ regels: PlanPreviewRegel[];
17
+ }
18
+ export interface PlanPreviewOrder {
19
+ orderId: string;
20
+ orderNummer: string | null;
21
+ ok: boolean;
22
+ reden: string | null;
23
+ waarschuwingen: string[];
24
+ karren: PlanPreviewKar[];
25
+ }
26
+ type DryRun = (sb: any, bufferId: string) => Promise<{
27
+ ok: boolean;
28
+ blockedReason?: string;
29
+ warnings?: string[];
30
+ carts?: PlannedLoadUnit[];
31
+ } | null>;
32
+ /** Vulgraad zoals Floriday: Σ per regel (lagen ÷ lagen per kar van die regel). */
33
+ export declare function vulgraadFloriday(items: PlannedLoadUnit["items"]): number;
34
+ export declare function lagenVanKar(kar: PlannedLoadUnit): number;
35
+ /** Zelfde vorm als karTekst in de database: "6,6 lagen · Deense container + 6 platen · 83 %". */
36
+ export declare function karTekstVan(lagen: number, ladingdrager: string, pct: number): string;
37
+ export declare function bouwPlanPreview(sb: any, orderIds: string[], dryRun: DryRun): Promise<PlanPreviewOrder[]>;
38
+ export {};
39
+ //# sourceMappingURL=planPreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planPreview.d.ts","sourceRoot":"","sources":["../../src/lib/planPreview.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AACD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,KAAK,MAAM,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAIrJ,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,MAAM,CAOxE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAKxD;AAED,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpF;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyD9G"}
@@ -0,0 +1,13 @@
1
+ import { type PlanPreviewOrder } from "./planPreview.js";
2
+ export declare const logisticsPlanPreview: import("@tanstack/start-client-core").RequiredFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, undefined, undefined, undefined, undefined>, import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
3
+ supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
4
+ userId: string;
5
+ claims: import("@supabase/auth-js").User;
6
+ }, undefined, undefined, undefined>], (input: {
7
+ orderIds: string[];
8
+ }) => {
9
+ orderIds: string[];
10
+ }, Promise<{
11
+ orders: PlanPreviewOrder[];
12
+ }>>;
13
+ //# sourceMappingURL=planPreview.functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planPreview.functions.d.ts","sourceRoot":"","sources":["../../src/lib/planPreview.functions.ts"],"names":[],"mappings":"AAMA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIvE,eAAO,MAAM,oBAAoB;;;;8CAEP;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE;;;YAQQ,gBAAgB,EAAE;GAatE,CAAC"}
@@ -0,0 +1,34 @@
1
+ // 1.0.213: logistics_plan_preview — karindeling narekenen zonder iets te schrijven.
2
+ // Zelfde planner en werkwijze als de wachtrij (replanBufferInternal), maar in droge modus:
3
+ // geen karren, geen wachtrij, geen events, geen blokkades, geen bufferbesluit.
4
+ import { createServerFn } from "@tanstack/react-start";
5
+ import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
6
+ import { readableServerErrors } from "./readableServerErrors.js";
7
+ import { bouwPlanPreview } from "./planPreview.js";
8
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9
+ export const logisticsPlanPreview = createServerFn({ method: "POST" })
10
+ .middleware([readableServerErrors, requireSupabaseAuth])
11
+ .inputValidator((input) => {
12
+ const ids = Array.isArray(input?.orderIds) ? input.orderIds.map(String) : [];
13
+ if (ids.length === 0)
14
+ throw new Error("Geef minimaal één order op.");
15
+ if (ids.length > 50)
16
+ throw new Error(`Maximaal 50 orders per voorbeeld (ontvangen: ${ids.length}).`);
17
+ const fout = ids.find((x) => !UUID_RE.test(x));
18
+ if (fout)
19
+ throw new Error(`Ongeldig order-id: ${fout}`);
20
+ return { orderIds: Array.from(new Set(ids)) };
21
+ })
22
+ .handler(async ({ data, context }) => {
23
+ // Toegang: ingelogd, via dezelfde interne guard als de rest van de Engine (fail-closed).
24
+ const { error: gErr } = await context.supabase.rpc("logistics_acc_guard", {
25
+ p_level: "ingelogd",
26
+ p_fn: "logistics_plan_preview",
27
+ });
28
+ if (gErr)
29
+ throw new Error(`Geen toegang: ${gErr.message}`);
30
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
31
+ const { replanBufferInternal } = await import("./loadCarrierPlanning.server.js");
32
+ const orders = await bouwPlanPreview(supabaseAdmin, data.orderIds, (sb, bufferId) => replanBufferInternal(sb, bufferId, { dryRun: true }));
33
+ return { orders };
34
+ });
@@ -0,0 +1,87 @@
1
+ import { extraPlaten } from "./extraPlaten.js";
2
+ const nl1 = (n) => String(Math.round(n * 10) / 10).replace(".", ",");
3
+ /** Vulgraad zoals Floriday: Σ per regel (lagen ÷ lagen per kar van die regel). */
4
+ export function vulgraadFloriday(items) {
5
+ let v = 0;
6
+ for (const it of Array.isArray(items) ? items : []) {
7
+ const cpl = Number(it.crates_per_layer) || 0, lpc = Number(it.layers_per_cart) || 0;
8
+ if (cpl > 0 && lpc > 0)
9
+ v += Number(it.crates) / cpl / lpc;
10
+ }
11
+ return v;
12
+ }
13
+ export function lagenVanKar(kar) {
14
+ const t = Number(kar.total_layers_used);
15
+ if (Number.isFinite(t) && t > 0)
16
+ return t;
17
+ return (Array.isArray(kar.items) ? kar.items : []).reduce((s, it) => s + (Number(it.crates_per_layer) > 0 ? Number(it.crates) / Number(it.crates_per_layer) : 0), 0);
18
+ }
19
+ /** Zelfde vorm als karTekst in de database: "6,6 lagen · Deense container + 6 platen · 83 %". */
20
+ export function karTekstVan(lagen, ladingdrager, pct) {
21
+ const p = extraPlaten(lagen) ?? 0;
22
+ const laagWoord = Math.round(lagen * 10) / 10 === 1 ? "laag" : "lagen";
23
+ const platen = p === 0 ? "" : p === 1 ? " + 1 plaat" : ` + ${p} platen`;
24
+ return `${nl1(lagen)} ${laagWoord} · ${ladingdrager}${platen} · ${Math.round(pct)} %`;
25
+ }
26
+ export async function bouwPlanPreview(sb, orderIds, dryRun) {
27
+ const { data: rows, error } = await sb.from("orders").select("id, order_number, buffer_id").in("id", orderIds);
28
+ if (error)
29
+ throw new Error(`Orders konden niet worden gelezen: ${error.message}`);
30
+ const orders = Array.isArray(rows) ? rows : [];
31
+ const { data: typen } = await sb.from("load_carrier_types").select("code, name");
32
+ const naamVan = new Map((Array.isArray(typen) ? typen : []).map((t) => [String(t.code), String(t.name ?? t.code)]));
33
+ const perBuffer = new Map();
34
+ const uit = [];
35
+ for (const id of orderIds) {
36
+ const o = orders.find((x) => String(x.id) === id);
37
+ if (!o) {
38
+ uit.push({ orderId: id, orderNummer: null, ok: false, reden: "Order niet gevonden.", waarschuwingen: [], karren: [] });
39
+ continue;
40
+ }
41
+ // Geen bufferbesluit nemen in een voorbeeld: dat zou schrijven.
42
+ if (!o.buffer_id) {
43
+ uit.push({ orderId: id, orderNummer: o.order_number ?? null, ok: false,
44
+ reden: "De order heeft nog geen buffer; het voorbeeld neemt dat besluit niet (zou iets opslaan).", waarschuwingen: [], karren: [] });
45
+ continue;
46
+ }
47
+ const bid = String(o.buffer_id);
48
+ if (!perBuffer.has(bid))
49
+ perBuffer.set(bid, await dryRun(sb, bid));
50
+ const res = perBuffer.get(bid);
51
+ const carts = Array.isArray(res?.carts) ? res.carts : [];
52
+ const karren = carts
53
+ .filter((c) => (Array.isArray(c.items) ? c.items : []).some((it) => String(it.order_id ?? "") === id))
54
+ .map((c) => {
55
+ const lagen = lagenVanKar(c);
56
+ const vul = vulgraadFloriday(c.items);
57
+ const drager = naamVan.get(String(c.carrier_type)) ?? String(c.carrier_type ?? "Ladingdrager");
58
+ return {
59
+ karNummer: c.cart_number,
60
+ ladingdrager: drager,
61
+ lagen: Math.round(lagen * 100) / 100,
62
+ platen: extraPlaten(lagen) ?? 0,
63
+ vulgraadPct: Math.round(vul * 100),
64
+ teHoog: vul > 1.001,
65
+ karTekst: karTekstVan(lagen, drager, vul * 100),
66
+ regels: (Array.isArray(c.items) ? c.items : [])
67
+ .filter((it) => String(it.order_id ?? "") === id)
68
+ .map((it) => ({ orderItemId: it.order_item_id, product: it.product_name, fust: Number(it.crates) || 0, stuks: Number(it.plants) || 0 })),
69
+ };
70
+ });
71
+ uit.push({
72
+ orderId: id,
73
+ orderNummer: o.order_number ?? null,
74
+ ok: Boolean(res?.ok),
75
+ reden: res
76
+ ? res.ok
77
+ ? karren.length === 0
78
+ ? "Geen nieuwe karren: alle fusten staan al op vastgelegde karren (geprint, gescand of gecontroleerd); die blijven zoals ze zijn."
79
+ : null
80
+ : res.blockedReason ?? "Niet ingedeeld."
81
+ : "Geen buffer gevonden.",
82
+ waarschuwingen: Array.isArray(res?.warnings) ? res.warnings : [],
83
+ karren,
84
+ });
85
+ }
86
+ return uit;
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/logistiek-engine",
3
- "version": "1.0.211",
3
+ "version": "1.0.214",
4
4
  "flowselections": {
5
5
  "moduleId": "logistiek-engine",
6
6
  "pages": [