@flowselections/logistiek-engine 1.0.212 → 1.0.216

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":"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"}
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
  }
@@ -524,82 +526,40 @@ export function ladingdragerUitVerpakking(waarde, actieveCodes) {
524
526
  return c && actieveCodes.has(c) ? c : null;
525
527
  }
526
528
  /**
527
- * Ladingdrager per planregel: handmatige keuze → orderregel → primaire verpakking
528
- * van het product. Geen standaardtype: zonder bron blijft de regel leeg (blokkeren).
529
+ * 1.0.215: ladingdrager per planregel via de gedeelde databasefunctie
530
+ * logistics_ladingdrager_kies (zelfde keuze als het productoordeel):
531
+ * handmatige keuze → orderregel → artikel → gekoppeld voorraadartikel
532
+ * (products.floriday_trade_item_id) → Floriday-verpakking → werkwijze (met waarschuwing).
533
+ * Fail-closed: lukt de keuze niet, dan blijft de regel leeg (blokkeren).
529
534
  */
530
- async function bepaalLadingdragers(sb, inputs, rawRows, profiles, handmatig, standaardGebruikt, standaardCode) {
535
+ async function bepaalLadingdragers(sb, inputs, rawRows, profiles, handmatig, standaardGebruikt, _standaardCode) {
531
536
  const codes = new Set(profiles.map((p) => String(p.code)));
532
537
  const uit = new Map();
533
- const perRegel = new Map();
538
+ const handmatigeCode = handmatig && codes.has(handmatig) ? handmatig : null;
539
+ const regelCode = new Map();
534
540
  for (const r of rawRows)
535
- perRegel.set(String(r.id), ladingdragerUitVerpakking(r.load_carrier_type, codes));
536
- const productIds = Array.from(new Set(inputs.map((i) => i.product_id).filter((x) => !!x)));
537
- const perProduct = new Map();
538
- if (productIds.length > 0) {
539
- const { data, error } = await sb
540
- .from("product_packings")
541
- .select("product_id, load_carrier, is_primary, sort_order")
542
- .in("product_id", productIds);
543
- if (error)
544
- throw new Error(`Verpakkingen konden niet worden gelezen: ${error.message}`);
545
- const rijen = (Array.isArray(data) ? data : []).sort((a, b) => Number(Boolean(b.is_primary)) - Number(Boolean(a.is_primary)) || Number(a.sort_order ?? 0) - Number(b.sort_order ?? 0));
546
- for (const r of rijen) {
547
- const pid = String(r.product_id);
548
- if (perProduct.get(pid))
549
- continue;
550
- perProduct.set(pid, ladingdragerUitVerpakking(r.load_carrier, codes));
551
- }
552
- }
553
- // 1.0.190: eerst de Floriday-verpakking van het artikel
554
- // (floriday_trade_items_cache.data.packingConfigurations[].loadCarrier, primaire eerst).
555
- const perFloriday = new Map();
556
- if (productIds.length > 0) {
557
- const { data: prods } = await sb
558
- .from("products")
559
- .select("id, floriday_trade_item_id")
560
- .in("id", productIds);
561
- const tiPerProduct = new Map();
562
- for (const p of (Array.isArray(prods) ? prods : [])) {
563
- if (p?.floriday_trade_item_id)
564
- tiPerProduct.set(String(p.id), String(p.floriday_trade_item_id));
565
- }
566
- const tiIds = Array.from(new Set(tiPerProduct.values()));
567
- if (tiIds.length > 0) {
568
- const { data: tis } = await sb
569
- .from("floriday_trade_items_cache")
570
- .select("floriday_id, data, is_deleted")
571
- .in("floriday_id", tiIds);
572
- const lcPerTi = new Map();
573
- for (const t of (Array.isArray(tis) ? tis : [])) {
574
- if (t?.is_deleted)
575
- continue;
576
- const confs = Array.isArray(t?.data?.packingConfigurations) ? t.data.packingConfigurations : [];
577
- const sorted = [...confs].sort((a, b) => Number(Boolean(b?.primary)) - Number(Boolean(a?.primary)));
578
- let code = null;
579
- for (const c of sorted) {
580
- code = ladingdragerUitVerpakking(c?.loadCarrier, codes);
581
- if (code)
582
- break;
583
- }
584
- lcPerTi.set(String(t.floriday_id), code);
585
- }
586
- for (const [pid, ti] of tiPerProduct)
587
- perFloriday.set(pid, lcPerTi.get(ti) ?? null);
588
- }
541
+ regelCode.set(String(r.id), r.load_carrier_type == null ? null : String(r.load_carrier_type));
542
+ if (handmatigeCode) {
543
+ for (const i of inputs)
544
+ uit.set(i.order_item_id, handmatigeCode);
545
+ return uit;
589
546
  }
590
- const handmatigeCode = handmatig && codes.has(handmatig) ? handmatig : null;
591
- const terugval = standaardCode && codes.has(standaardCode) ? standaardCode : null;
592
- for (const i of inputs) {
547
+ const regels = inputs.map((i) => {
593
548
  const base = i.order_item_id.includes("::") ? i.order_item_id.split("::")[0] : i.order_item_id;
594
- const pid = i.product_id ? String(i.product_id) : null;
595
- const uitFloriday = pid ? perFloriday.get(pid) || null : null;
596
- const uitProduct = pid ? perProduct.get(pid) || null : null;
597
- let code = handmatigeCode || perRegel.get(base) || uitFloriday || uitProduct || null;
598
- if (!code && terugval) {
599
- code = terugval;
600
- standaardGebruikt?.add(i.order_item_id);
549
+ return { key: i.order_item_id, regel_code: regelCode.get(base) ?? null, product_id: i.product_id ?? null };
550
+ });
551
+ for (let s = 0; s < regels.length; s += 1000) {
552
+ const { data, error } = await sb.rpc("logistics_ladingdrager_kies", { p_regels: regels.slice(s, s + 1000) });
553
+ if (error)
554
+ throw new Error(`Ladingdrager kon niet worden bepaald: ${error.message}`);
555
+ const map = (data && typeof data === "object" ? data : {});
556
+ for (const r of regels.slice(s, s + 1000)) {
557
+ const k = map[r.key];
558
+ const code = k?.code && codes.has(String(k.code)) ? String(k.code) : null;
559
+ if (code && k?.bron === "werkwijze")
560
+ standaardGebruikt?.add(r.key);
561
+ uit.set(r.key, code);
601
562
  }
602
- uit.set(i.order_item_id, code);
603
563
  }
604
564
  return uit;
605
565
  }
@@ -1318,7 +1278,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1318
1278
  beladingWaarschuwingen.push({
1319
1279
  order_id: oid || null,
1320
1280
  sleutel: "ladingdrager_standaard",
1321
- tekst: `Ladingdrager niet bekend uit verpakking, standaard gebruikt (${namen.slice(0, 5).join(", ")}).`,
1281
+ tekst: `Ladingdrager uit de werkwijze, niet uit het artikel (${namen.slice(0, 5).join(", ")}).`,
1322
1282
  });
1323
1283
  }
1324
1284
  }
@@ -1368,7 +1328,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1368
1328
  }
1369
1329
  // Groepsregel naast ledenregels: niet ingedeeld, wel zichtbaar gemeld bij de order.
1370
1330
  for (const n of expandNotes) {
1371
- if (!n.order_id)
1331
+ if (!n.order_id || options.dryRun)
1372
1332
  continue;
1373
1333
  const { error: noteError } = await sb.rpc("logistics_trace_order_step", {
1374
1334
  p_order_id: n.order_id,
@@ -1533,9 +1493,9 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1533
1493
  }
1534
1494
  if (options.carrierType && !bekendeCodes.has(options.carrierType))
1535
1495
  nietInBeheer.set(options.carrierType, []);
1536
- if (nietInBeheer.size > 0 && !options.dryRun) {
1496
+ if (nietInBeheer.size > 0) {
1537
1497
  const reason = ladingdragerNietInBeheerTekst(nietInBeheer);
1538
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1498
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1539
1499
  p_order_ids: orderIds,
1540
1500
  p_reason: reason,
1541
1501
  p_details: {
@@ -1599,9 +1559,9 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1599
1559
  // 1.0.198: gewicht alleen relevant als de ladingdrager een kg-grens heeft.
1600
1560
  const heeftKgGrens = Number(guardProfile.max_weight_kg) > 0;
1601
1561
  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) {
1562
+ if (zonderGewicht.length > 0 && rules?.gewichtVerplicht === true) {
1603
1563
  const reason = gewichtOnbekendTekst(zonderGewicht.map((i) => i.product_name));
1604
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1564
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1605
1565
  p_order_ids: orderIds,
1606
1566
  p_reason: reason,
1607
1567
  p_details: { reason_code: "gewicht_onbekend", bufferId, path: "typescript",
@@ -1629,7 +1589,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1629
1589
  }
1630
1590
  // Planten per fust is altijd nodig (ook zonder lagenmodel): fusten = planten / planten per fust.
1631
1591
  const blokkeerOnvolledig = onvolledig.filter((o) => o.velden.includes("plants_per_crate") || (needsBelading && !useDimensions));
1632
- if ((blokkeerOnvolledig.length > 0 || onbekendePlanten.length > 0) && !options.dryRun) {
1592
+ if ((blokkeerOnvolledig.length > 0 || onbekendePlanten.length > 0)) {
1633
1593
  const delen = [
1634
1594
  ...blokkeerOnvolledig.slice(0, 10).map((o) => `${o.item.product_name}: ${o.velden.map((v) => VELD_NAAM[v]).join(", ")} onbekend`),
1635
1595
  ...onbekendePlanten.slice(0, 10).map((o) => `${o.naam}: eenheid fust zonder planten per fust`),
@@ -1637,7 +1597,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1637
1597
  const reason = `Belading onvolledig voor ${blokkeerOnvolledig.length + onbekendePlanten.length} orderregel(s): ${delen.join("; ")}. ` +
1638
1598
  WAAR_INVULLEN;
1639
1599
  console.error(`[logistiek-engine] buffer ${bufferId} geblokkeerd: ${reason}`);
1640
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1600
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1641
1601
  p_order_ids: orderIds,
1642
1602
  p_reason: reason,
1643
1603
  p_details: {
@@ -1668,16 +1628,18 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1668
1628
  };
1669
1629
  }
1670
1630
  // 1.0.179 (punt 3): plausibiliteit, alle ordersoorten. Eén bevestiging per order en verpakking.
1671
- if (!options.dryRun) {
1631
+ // 1.0.213: ook in droge modus rekenen (alleen lezen); schrijven alleen buiten droge modus.
1632
+ {
1672
1633
  const oordeel = await beladingOnwaarschijnlijk(sb, inputs, rawRows, guardProfile, profielPerRegel);
1673
1634
  const onwaarschijnlijk = oordeel.blokkeren;
1674
1635
  // 1.0.197: fysiek onmogelijk = altijd blokkeren, niet te bevestigen; alleen gegevens aanpassen helpt.
1675
1636
  if (oordeel.onmogelijk.length > 0) {
1676
1637
  beladingWaarschuwingen.push(...oordeel.waarschuwingen);
1677
- await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1638
+ if (!options.dryRun)
1639
+ await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1678
1640
  const reason = `Belading fysiek onmogelijk: ${oordeel.onmogelijk.slice(0, 10).map((o) => o.redenen.join("; ")).join(" | ")}. ` +
1679
1641
  "Pas de gegevens aan in Beheer → Gegevens voor karindeling; bevestigen is hier niet mogelijk.";
1680
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1642
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1681
1643
  p_order_ids: orderIds,
1682
1644
  p_reason: reason,
1683
1645
  p_details: {
@@ -1707,11 +1669,12 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1707
1669
  beladingWaarschuwingen.push(...oordeel.waarschuwingen);
1708
1670
  for (const w of beladingWaarschuwingen)
1709
1671
  warnings.push(w.tekst);
1710
- await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1672
+ if (!options.dryRun)
1673
+ await bewaarBeladingWaarschuwingen(sb, orderIds, beladingWaarschuwingen, warnings);
1711
1674
  if (onwaarschijnlijk.length > 0) {
1712
1675
  const reason = `Belading onwaarschijnlijk: ${onwaarschijnlijk.slice(0, 10).map((o) => `${o.product}: ${o.redenen.join("; ")}`).join(" | ")}. ` +
1713
1676
  "Kantoor moet dit bevestigen voordat er wordt ingedeeld.";
1714
- const { error: blockError } = await sb.rpc("logistics_plan_block", {
1677
+ const { error: blockError } = options.dryRun ? { error: null } : await sb.rpc("logistics_plan_block", {
1715
1678
  p_order_ids: orderIds,
1716
1679
  p_reason: reason,
1717
1680
  p_details: { reason_code: "belading_onwaarschijnlijk", bufferId, path: "typescript", bevestigen: onwaarschijnlijk.slice(0, 50) },
@@ -1838,6 +1801,7 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1838
1801
  }
1839
1802
  else {
1840
1803
  // Ladingdrager per orderregel bepalen en per type een ronde draaien.
1804
+ const geenLadingdrager = [];
1841
1805
  const groups = new Map();
1842
1806
  for (const input of inputs) {
1843
1807
  const code = ladingdragerPerRegel.get(input.order_item_id) ?? defaultProfile.code;
@@ -1871,12 +1835,34 @@ async function replanBufferUnlocked(sb, bufferId, options = {}) {
1871
1835
  ownCarrierFromLayers: settings?.own_cart_from_layers ?? null,
1872
1836
  sortOrder: "none",
1873
1837
  });
1838
+ if (profile.capacity_model === "none" && list.length > 0) {
1839
+ geenLadingdrager.push(...list.map((x) => x.product_name));
1840
+ continue;
1841
+ }
1874
1842
  plannedCarts = plannedCarts.concat(result.carts);
1875
1843
  warnings.push(...result.warnings);
1876
1844
  }
1877
1845
  plannedCarts.forEach((c, idx) => {
1878
1846
  c.cart_number = idx + 1;
1879
1847
  });
1848
+ // 1.0.213: een product zonder ladingdrager (NONE / losse levering) kan niet op een kar: geen indeling.
1849
+ if (geenLadingdrager.length > 0) {
1850
+ const namen = Array.from(new Set(geenLadingdrager)).slice(0, 10).join(", ");
1851
+ const reason = `Geen indeling: ladingdrager ontbreekt (${namen}). Stel de ladingdrager van de hoofdverpakking in.`;
1852
+ if (!options.dryRun) {
1853
+ const { error: blockError } = await sb.rpc("logistics_plan_block", {
1854
+ p_order_ids: orderIds,
1855
+ p_reason: reason,
1856
+ p_details: { reason_code: "ladingdrager_ontbreekt", bufferId, path: "typescript", producten: Array.from(new Set(geenLadingdrager)).slice(0, 50) },
1857
+ });
1858
+ if (blockError)
1859
+ warnings.push(`Blokkade kon niet worden vastgelegd: ${blockError.message}`);
1860
+ }
1861
+ return {
1862
+ ok: false, bufferId, orderIds, cartsCreated: 0, replacedManualCount: 0, usedFloridayPacking,
1863
+ warnings: [...warnings, reason], skipped: "blocked", blockedReason: reason, beladingSources,
1864
+ };
1865
+ }
1880
1866
  }
1881
1867
  // Veiligheidsgrens: een onrealistisch grote uitkomst wordt niet afgekapt maar
1882
1868
  // geblokkeerd. Een half plan laat planten stilzwijgend uit de pickstroom vallen.
@@ -1,2 +1,2 @@
1
- export declare const MODULE_VERSION = "1.0.212";
1
+ export declare const MODULE_VERSION = "1.0.216";
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.212";
2
+ export const MODULE_VERSION = "1.0.216";
@@ -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.212",
3
+ "version": "1.0.216",
4
4
  "flowselections": {
5
5
  "moduleId": "logistiek-engine",
6
6
  "pages": [
@@ -52,6 +52,12 @@
52
52
  "export": "BeheerPage",
53
53
  "route": "logistiek-engine/beheer",
54
54
  "title": "Beheer"
55
+ },
56
+ {
57
+ "export": "ProefindelingPage",
58
+ "route": "logistiek-engine/proefindeling",
59
+ "title": "Proefindeling",
60
+ "nav": false
55
61
  }
56
62
  ],
57
63
  "serverRoutes": [