@flowselections/floriday-verkoop-module 1.0.74 → 1.0.77

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 (32) hide show
  1. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
  2. package/dist-lib/components/verkoop/OrderKarindelingCard.js +36 -114
  3. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts +6 -0
  4. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts.map +1 -0
  5. package/dist-lib/components/verkoop/PlanCoverageBadge.js +23 -0
  6. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  7. package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -1
  8. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  9. package/dist-lib/components/verkoop/SalesOrdersTable.js +2 -1
  10. package/dist-lib/integrations/supabase/types.d.ts +483 -3
  11. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  12. package/dist-lib/lib/cart-replan.functions.d.ts +2 -22
  13. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
  14. package/dist-lib/lib/cart-replan.functions.js +10 -163
  15. package/dist-lib/lib/create-order.functions.d.ts +0 -57
  16. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  17. package/dist-lib/lib/create-order.functions.js +1 -205
  18. package/dist-lib/lib/logistics-engine.server.d.ts.map +1 -1
  19. package/dist-lib/lib/logistics-engine.server.js +8 -3
  20. package/dist-lib/lib/plan-coverage.d.ts +56 -0
  21. package/dist-lib/lib/plan-coverage.d.ts.map +1 -0
  22. package/dist-lib/lib/plan-coverage.js +120 -0
  23. package/dist-lib/lib/plan-coverage.server.d.ts +3 -0
  24. package/dist-lib/lib/plan-coverage.server.d.ts.map +1 -0
  25. package/dist-lib/lib/plan-coverage.server.js +97 -0
  26. package/dist-lib/lib/salesorders-list.server.d.ts.map +1 -1
  27. package/dist-lib/lib/salesorders-list.server.js +43 -82
  28. package/dist-lib/lib/salesorders-mapping.d.ts +5 -0
  29. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  30. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  31. package/dist-lib/lib/salesorders.functions.js +21 -18
  32. package/package.json +1 -1
@@ -0,0 +1,120 @@
1
+ // Indelingsstatus per order zoals de Logistiek Engine die levert via
2
+ // public.logistics_order_plan_coverage. Alleen types en een veilige parser —
3
+ // browser-veilig, geen databasecode. Deze module telt nooit zelf karren.
4
+ const STATES = ["ingedeeld", "deels", "geen_indeling", "geen_regels"];
5
+ const PICK = ["geen_pickrij", "open", "bezig", "gepickt"];
6
+ const str = (v) => typeof v === "string" && v.trim() !== "" ? v : typeof v === "number" ? String(v) : null;
7
+ const num = (v) => {
8
+ const n = Number(v);
9
+ return v != null && Number.isFinite(n) ? n : null;
10
+ };
11
+ export function defaultLabel(state) {
12
+ switch (state) {
13
+ case "ingedeeld":
14
+ return "Ingedeeld";
15
+ case "deels":
16
+ return "Deels ingedeeld";
17
+ case "geen_indeling":
18
+ return "Geen indeling";
19
+ case "geen_regels":
20
+ return "Geen regels";
21
+ default:
22
+ return "Indeling onbekend";
23
+ }
24
+ }
25
+ export function unknownCoverage(error) {
26
+ return {
27
+ state: "onbekend",
28
+ label: defaultLabel("onbekend"),
29
+ progressPct: null,
30
+ reason: null,
31
+ carts: [],
32
+ pickRows: [],
33
+ pickStatus: null,
34
+ pickedAt: null,
35
+ error,
36
+ };
37
+ }
38
+ /** Leest het jsonb-antwoord defensief in; ontbrekende velden worden leeg. */
39
+ export function parsePlanCoverage(raw) {
40
+ const d = raw && typeof raw === "object" ? raw : null;
41
+ if (!d)
42
+ return unknownCoverage("Leeg antwoord van de Engine");
43
+ const state = STATES.includes(d.state) ? d.state : "onbekend";
44
+ const carts = (Array.isArray(d.carts) ? d.carts : [])
45
+ .filter((c) => c && str(c.cartId))
46
+ .map((c) => ({
47
+ cartId: String(c.cartId),
48
+ cartNumber: num(c.cartNumber),
49
+ bufferId: str(c.bufferId),
50
+ shared: Boolean(c.shared),
51
+ carrierType: str(c.carrierType),
52
+ lines: (Array.isArray(c.lines) ? c.lines : []).map((l) => ({
53
+ orderItemId: str(l?.orderItemId),
54
+ productId: str(l?.productId),
55
+ productName: str(l?.productName),
56
+ crates: num(l?.crates) ?? 0,
57
+ boxes: num(l?.boxes) ?? 0,
58
+ })),
59
+ }));
60
+ const pickRows = (Array.isArray(d.pickRows) ? d.pickRows : []).map((p) => ({
61
+ queueItemId: str(p?.queueItemId),
62
+ documentNumber: str(p?.documentNumber),
63
+ cartId: str(p?.cartId),
64
+ printedAt: str(p?.printedAt),
65
+ completedAt: str(p?.completedAt),
66
+ }));
67
+ return {
68
+ state,
69
+ label: str(d.label) ?? defaultLabel(state),
70
+ progressPct: num(d.progressPct),
71
+ reason: str(d.reason),
72
+ carts,
73
+ pickRows,
74
+ pickStatus: PICK.includes(d.pickStatus) ? d.pickStatus : null,
75
+ pickedAt: str(d.pickedAt),
76
+ error: state === "onbekend" ? "Onbekende indelingsstatus van de Engine" : null,
77
+ };
78
+ }
79
+ /** Leest één rij van logistics_order_plan_coverage_list (platte kolommen, geen karregels). */
80
+ export function parsePlanCoverageListRow(r) {
81
+ if (!r || typeof r !== "object")
82
+ return unknownCoverage("Leeg antwoord van de Engine");
83
+ const state = STATES.includes(r.state) ? r.state : "onbekend";
84
+ return {
85
+ state,
86
+ label: str(r.label) ?? defaultLabel(state),
87
+ progressPct: num(r.progress_pct ?? r.progressPct),
88
+ reason: str(r.reason),
89
+ carts: [],
90
+ pickRows: [],
91
+ pickStatus: PICK.includes(r.pick_status) ? r.pick_status : null,
92
+ pickedAt: str(r.picked_at),
93
+ cartCount: num(r.cart_count),
94
+ shared: str(r.buffer_id) != null,
95
+ error: state === "onbekend" ? "Onbekende indelingsstatus van de Engine" : null,
96
+ };
97
+ }
98
+ const RANK = {
99
+ onbekend: 0,
100
+ geen_indeling: 1,
101
+ deels: 2,
102
+ ingedeeld: 3,
103
+ geen_regels: 4,
104
+ };
105
+ export function summarize(c) {
106
+ return {
107
+ state: c.state,
108
+ label: c.label,
109
+ progressPct: c.progressPct,
110
+ reason: c.reason ?? c.error ?? null,
111
+ shared: Boolean(c.shared) || c.carts.some((k) => k.shared),
112
+ };
113
+ }
114
+ export function mergeSummaries(list) {
115
+ const xs = list.filter((x) => !!x);
116
+ if (!xs.length)
117
+ return null;
118
+ const worst = [...xs].sort((a, b) => RANK[a.state] - RANK[b.state])[0];
119
+ return { ...worst, shared: xs.some((x) => x.shared) };
120
+ }
@@ -0,0 +1,3 @@
1
+ import { type PlanCoverage } from "./plan-coverage";
2
+ export declare function loadPlanCoverage(supabase: any, orderIds: string[], mode?: "list" | "detail"): Promise<Map<string, PlanCoverage>>;
3
+ //# sourceMappingURL=plan-coverage.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-coverage.server.d.ts","sourceRoot":"","sources":["../../src/lib/plan-coverage.server.ts"],"names":[],"mappings":"AASA,OAAO,EAAgE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAqClH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,GAAE,MAAM,GAAG,QAAmB,GACjC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CA6CpC"}
@@ -0,0 +1,97 @@
1
+ // Haalt de indelingsstatus per order op bij de Logistiek Engine.
2
+ //
3
+ // - Alleen lezen; schrijft nooit iets.
4
+ // - Leest nooit zelf order_carts/order_cart_items.
5
+ // - Lijst (mode "list"): lijstversie logistics_order_plan_coverage_list in één
6
+ // aanroep voor de zichtbare orders; ontbreekt die, dan per order beperkt parallel.
7
+ // - Details (mode "detail"): per order, want alleen die geeft karren en pickrijen.
8
+ // - Kort geheugen per order-id zodat opnieuw tekenen geen nieuwe vragen doet.
9
+ // - Fail closed: een fout geeft "Indeling onbekend", nooit "Geen indeling".
10
+ import { parsePlanCoverage, parsePlanCoverageListRow, unknownCoverage } from "./plan-coverage";
11
+ const TTL_MS = 30000;
12
+ const CONCURRENCY = 12;
13
+ const cache = new Map(); // sleutel: mode:orderId
14
+ let listFnMissingUntil = 0;
15
+ const LIST_FN = "logistics_order_plan_coverage_list";
16
+ const SINGLE_FN = "logistics_order_plan_coverage";
17
+ function isMissingFunction(err) {
18
+ const code = String(err?.code ?? "");
19
+ const msg = String(err?.message ?? "");
20
+ return code === "PGRST202" || code === "42883" || /could not find the function|does not exist/i.test(msg);
21
+ }
22
+ async function tryListVersion(supabase, ids) {
23
+ if (Date.now() < listFnMissingUntil)
24
+ return null;
25
+ const { data, error } = await supabase.rpc(LIST_FN, { p_order_ids: ids });
26
+ if (error) {
27
+ if (isMissingFunction(error)) {
28
+ listFnMissingUntil = Date.now() + 5 * 60000;
29
+ return null;
30
+ }
31
+ throw new Error(error.message);
32
+ }
33
+ const out = new Map();
34
+ const rows = Array.isArray(data) ? data : [];
35
+ for (const r of rows) {
36
+ const oid = r?.order_id ?? null;
37
+ if (!oid)
38
+ continue;
39
+ out.set(String(oid), parsePlanCoverageListRow(r));
40
+ }
41
+ for (const id of ids)
42
+ if (!out.has(id))
43
+ out.set(id, unknownCoverage("Geen antwoord van de Engine voor deze order"));
44
+ return out;
45
+ }
46
+ export async function loadPlanCoverage(supabase, orderIds, mode = "detail") {
47
+ const ids = Array.from(new Set(orderIds.filter(Boolean)));
48
+ const out = new Map();
49
+ const now = Date.now();
50
+ const todo = [];
51
+ for (const id of ids) {
52
+ const hit = cache.get(`${mode}:${id}`);
53
+ if (hit && now - hit.at < TTL_MS)
54
+ out.set(id, hit.value);
55
+ else
56
+ todo.push(id);
57
+ }
58
+ if (!todo.length)
59
+ return out;
60
+ let fetched = null;
61
+ try {
62
+ if (mode === "list")
63
+ fetched = await tryListVersion(supabase, todo);
64
+ }
65
+ catch (e) {
66
+ const msg = `Indeling niet beschikbaar: ${e?.message ?? e}`;
67
+ for (const id of todo)
68
+ out.set(id, unknownCoverage(msg));
69
+ return out;
70
+ }
71
+ if (!fetched) {
72
+ fetched = new Map();
73
+ let i = 0;
74
+ const worker = async () => {
75
+ while (i < todo.length) {
76
+ const id = todo[i++];
77
+ try {
78
+ const { data, error } = await supabase.rpc(SINGLE_FN, { p_order_id: id });
79
+ if (error)
80
+ throw new Error(error.message);
81
+ fetched.set(id, parsePlanCoverage(data));
82
+ }
83
+ catch (e) {
84
+ fetched.set(id, unknownCoverage(`Indeling niet beschikbaar: ${e?.message ?? e}`));
85
+ }
86
+ }
87
+ };
88
+ await Promise.all(Array.from({ length: Math.min(CONCURRENCY, todo.length) }, worker));
89
+ }
90
+ for (const [id, v] of fetched) {
91
+ out.set(id, v);
92
+ // Fouten niet bewaren: de volgende keer opnieuw proberen.
93
+ if (v.state !== "onbekend")
94
+ cache.set(`${mode}:${id}`, { at: Date.now(), value: v });
95
+ }
96
+ return out;
97
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"salesorders-list.server.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-list.server.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKjF,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AA8ID,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,UAAU,EAClB,kBAAkB,GAAE,cAAyB,GAC5C,OAAO,CAAC,UAAU,CAAC,CAgiCrB"}
1
+ {"version":3,"file":"salesorders-list.server.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-list.server.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKjF,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AA8ID,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,UAAU,EAClB,kBAAkB,GAAE,cAAyB,GAC5C,OAAO,CAAC,UAAU,CAAC,CAggCrB"}
@@ -1,11 +1,11 @@
1
1
  import { unlinkedFloridayProducts } from "./floriday-unlinked-products";
2
- import { productNameForStorage, resolveProductName } from "./product-name";
2
+ import { resolveProductName } from "./product-name";
3
3
  import { centralOrderNumber, computeTotals, mapJsonbToSalesOrderDTO, packingConfigFromFloridayPacking, } from "./salesorders-mapping";
4
4
  import { cratePackageName, loadCarrierName, mergeTypeNames } from "./load-carrier-labels";
5
5
  import { engineLoadCarrierLabel, normalizeLoadCarrierCode } from "./load-carriers";
6
6
  import { normalizeTime, resolveDeliveryTimeForDate } from "./carrier-availability";
7
- import { expandOrderItemsForPlanner } from "./expand-group-order-items";
8
- import { planCarts } from "./cart-planner";
7
+ import { loadPlanCoverage } from "./plan-coverage.server";
8
+ import { mergeSummaries, summarize } from "./plan-coverage";
9
9
  import { resolveOrderNumbers } from "./order-numbers.server";
10
10
  import { mergeStages, resolveOrderStage } from "./order-status";
11
11
  import { buildPickupOptions } from "./order-pickup.functions";
@@ -637,7 +637,9 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
637
637
  crateNames.push(cratePackageName(cfg?.package?.vbnPackageCode ?? cfg?.package?.customPackageId ?? null, crateDescriptions));
638
638
  cartNames.push(loadCarrierName(cfg?.loadCarrier ?? null));
639
639
  }
640
- const karCount = karTotalRaw > 0 ? Math.max(1, Math.ceil(karTotalRaw)) : totalQuantity > 0 ? 1 : 0;
640
+ // Geen eigen karrentelling: het aantal karren komt alleen uit de Engine.
641
+ void karTotalRaw;
642
+ const karCount = 0;
641
643
  const fustCount = fustTotal > 0 ? fustTotal : totalQuantity;
642
644
  const unitPrice = firstLine ? toNumber(firstLine.unit_price) : total;
643
645
  const rawOrderDate = r.order_date ?? "";
@@ -767,52 +769,8 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
767
769
  catch (e) {
768
770
  warnings.push(`Engine-orderoverzicht niet beschikbaar: ${e?.message ?? e}`);
769
771
  }
770
- // 12a-ter) Ladingdragers: type én aantal komen uit de werkelijk ingedeelde
771
- // karren (public.order_carts). Dat is dezelfde bron als de Karindeling-kaart
772
- // in het orderdetail, zodat lijst en detail nooit uiteenlopen. Zonder
773
- // indeling tonen we bewust géén type (liever niets dan een verkeerd type).
774
- try {
775
- const dtoByOrderId = new Map();
776
- for (const o of all) {
777
- const oid = o.id.startsWith("local:")
778
- ? o.id.slice("local:".length)
779
- : (localRowByFoId.get(o.id)?.id ?? null);
780
- if (!oid)
781
- continue;
782
- const key = String(oid);
783
- const arr = dtoByOrderId.get(key) ?? [];
784
- arr.push(o);
785
- dtoByOrderId.set(key, arr);
786
- }
787
- const orderIds = Array.from(dtoByOrderId.keys());
788
- if (orderIds.length) {
789
- // Tellen via de karregels: gedeelde bufferkarren hebben order_id = NULL.
790
- const { loadCartsByOrder } = await import("./order-cart-count.server");
791
- const info = await loadCartsByOrder(supabase, orderIds);
792
- const cartsByOrder = new Map();
793
- const sharedByOrder = new Map();
794
- for (const [oid, ci] of info) {
795
- cartsByOrder.set(oid, ci.carrierTypes);
796
- sharedByOrder.set(oid, ci.sharedCount);
797
- }
798
- for (const [oid, dtos] of dtoByOrderId) {
799
- const carts = cartsByOrder.get(oid);
800
- for (const o of dtos) {
801
- if (carts && carts.length > 0) {
802
- o.karCount = carts.length;
803
- o.karShared = (sharedByOrder.get(oid) ?? 0) > 0;
804
- o.cartTypeName = mergeTypeNames(carts.map((code) => engineLoadCarrierLabel(normalizeLoadCarrierCode(code) ?? code) ?? null));
805
- }
806
- else {
807
- o.cartTypeName = null;
808
- }
809
- }
810
- }
811
- }
812
- }
813
- catch (e) {
814
- warnings.push(`Ladingdragers niet beschikbaar: ${e?.message ?? e}`);
815
- }
772
+ // 12a-ter) Ladingdragers en indelingsstatus komen uit de Engine
773
+ // (logistics_order_plan_coverage), alleen voor de zichtbare rijen — zie stap 14.
816
774
  // 12a-bis) Ophaalmoment per order (vervoerder + gekozen moment), kort label.
817
775
  {
818
776
  const shortPickup = (dateISO, time) => {
@@ -911,6 +869,7 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
911
869
  carrierName: head.carrierName ?? members.find((m) => m.carrierName)?.carrierName ?? null,
912
870
  incomplete,
913
871
  engineCounts: members.some((m) => m.engineCounts),
872
+ planCoverage: mergeSummaries(members.map((m) => m.planCoverage)),
914
873
  shifted: members.some((m) => m.shifted),
915
874
  printedAt: members.map((m) => m.printedAt).find((v) => !!v) ?? null,
916
875
  pickDate: members
@@ -1038,41 +997,43 @@ export async function buildSalesOrdersList(supabase, params, connectionSupabase
1038
997
  const pageGroups = params.all
1039
998
  ? filteredGroups.slice(0, EXPORT_CAP)
1040
999
  : filteredGroups.slice((page - 1) * pageSize, page * pageSize);
1041
- // 14) Karindeling alleen voor de zichtbare rijen (begrensd werk).
1000
+ // 14) Indelingsstatus + karren uit de Engine (logistics_order_plan_coverage),
1001
+ // alleen voor de zichtbare rijen, in één keer opgehaald. Deze module telt
1002
+ // nooit zelf karren en leest order_carts/order_cart_items niet zelf.
1042
1003
  if (!params.all) {
1043
- const localById = new Map(localOrderRows.map((r) => [String(r.id), r]));
1044
- await Promise.all(pageGroups
1045
- .flat()
1046
- .filter((o) => o.id.startsWith("local:") && !o.engineCounts)
1047
- .map(async (o) => {
1048
- const r = localById.get(o.id.slice("local:".length));
1049
- const lineItems = (Array.isArray(r?.order_items) ? r.order_items : []).filter((it) => !it?.quarantined_at);
1050
- if (!lineItems.length)
1051
- return;
1052
- const raws = lineItems.map((it, idx) => {
1053
- const packing = resolveLinePacking(it);
1054
- return {
1055
- id: String(it?.id ?? `${r.id}#${idx}`),
1056
- product_id: it?.product_id ?? null,
1057
- product_name: productNameForStorage(it?.product_name),
1058
- quantity: Number(it?.quantity ?? 0),
1059
- plants_per_crate: Math.max(1, Number(packing?.plants_per_crate ?? 1)),
1060
- crates_per_layer: Math.max(1, Number(packing?.crates_per_layer ?? 1)),
1061
- layers_per_cart: Math.max(1, Number(packing?.layers_per_cart ?? 1)),
1062
- };
1063
- });
1064
- try {
1065
- const expanded = await expandOrderItemsForPlanner(supabase, raws);
1066
- if (!expanded.length)
1067
- return;
1068
- const planned = planCarts(expanded);
1069
- if (planned.carts.length > 0)
1070
- o.karCount = planned.carts.length;
1004
+ const visible = pageGroups.flat();
1005
+ const idFor = (o) => o.id.startsWith("local:")
1006
+ ? o.id.slice("local:".length)
1007
+ : (localRowByFoId.get(o.id)?.id ? String(localRowByFoId.get(o.id).id) : null);
1008
+ const ids = visible.map(idFor).filter((v) => !!v);
1009
+ if (ids.length) {
1010
+ const coverage = await loadPlanCoverage(supabase, ids, "list");
1011
+ let failed = 0;
1012
+ for (const o of visible) {
1013
+ const oid = idFor(o);
1014
+ const c = oid ? coverage.get(oid) : undefined;
1015
+ if (!c)
1016
+ continue;
1017
+ o.planCoverage = summarize(c);
1018
+ if (c.state === "onbekend") {
1019
+ failed++;
1020
+ continue; // fail closed: bestaande Engine-telling laten staan
1021
+ }
1022
+ o.karCount = c.cartCount ?? c.carts.length;
1023
+ o.karShared = Boolean(c.shared) || c.carts.some((k) => k.shared);
1024
+ // Lijstversie levert geen dragertype: bestaand type laten staan.
1025
+ if (c.carts.length > 0 || (c.cartCount ?? 0) === 0)
1026
+ o.cartTypeName =
1027
+ c.carts.length > 0
1028
+ ? mergeTypeNames(c.carts.map((k) => engineLoadCarrierLabel(normalizeLoadCarrierCode(k.carrierType) ?? k.carrierType ?? "") ??
1029
+ null))
1030
+ : null;
1031
+ o.engineCounts = true;
1071
1032
  }
1072
- catch {
1073
- /* fallback: reeds berekende karCount */
1033
+ if (failed > 0) {
1034
+ warnings.push(`Indelingsstatus van ${failed} order(s) niet beschikbaar bij de Logistiek Engine — getoond als "Indeling onbekend".`);
1074
1035
  }
1075
- }));
1036
+ }
1076
1037
  }
1077
1038
  const rows = pageGroups.map(mergeGroup);
1078
1039
  // Totalen over de volledige gefilterde set (alle orders in elke buffer).
@@ -75,6 +75,11 @@ export interface SalesOrderDTO {
75
75
  printedAt?: string | null;
76
76
  /** Karren/planten komen uit de Engine-index (logistics_order_overview). */
77
77
  engineCounts?: boolean;
78
+ /**
79
+ * Indelingsstatus uit logistics_order_plan_coverage (alleen voor zichtbare
80
+ * rijen opgehaald). Ontbreekt = niet opgevraagd.
81
+ */
82
+ planCoverage?: import("./plan-coverage").PlanCoverageSummary | null;
78
83
  /**
79
84
  * Achterstand zoals de Logistiek Engine die meldt (logistics_order_backlog_info).
80
85
  * Nooit zelf berekend; `backlogUnknown` betekent dat de vraag niet lukte.
@@ -1 +1 @@
1
- {"version":3,"file":"salesorders-mapping.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-mapping.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"salesorders-mapping.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders-mapping.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"salesorders.functions.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders.functions.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAqD/B,wBAAsB,0BAA0B;QAlB1C,OAAO;cACD,OAAO;cACP,MAAM;GAkBjB;AAGD,eAAO,MAAM,kBAAkB;;;;;QAvBzB,OAAO;cACD,OAAO;cACP,MAAM;GAuB+B,CAAC;AA6BlD,eAAO,MAAM,gBAAgB;;;;6CAEJ,OAAO;;;;;;;;;;;;;GAmC5B,CAAC;AAGL,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDnC,CAAC;AASL,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;0CAEV,OAAO;;mCAsXzB,CAAC;AAQL,eAAO,MAAM,uBAAuB;;;;0CAEd,OAAO;;;;;GAQzB,CAAC;AAOL,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAIF,eAAO,MAAM,qBAAqB;;;;6EA4E9B,CAAC"}
1
+ {"version":3,"file":"salesorders.functions.d.ts","sourceRoot":"","sources":["../../src/lib/salesorders.functions.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAqD/B,wBAAsB,0BAA0B;QAlB1C,OAAO;cACD,OAAO;cACP,MAAM;GAkBjB;AAGD,eAAO,MAAM,kBAAkB;;;;;QAvBzB,OAAO;cACD,OAAO;cACP,MAAM;GAuB+B,CAAC;AA6BlD,eAAO,MAAM,gBAAgB;;;;6CAEJ,OAAO;;;;;;;;;;;;;GAmC5B,CAAC;AAGL,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDnC,CAAC;AASL,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;0CAEV,OAAO;;mCA2XzB,CAAC;AAQL,eAAO,MAAM,uBAAuB;;;;0CAEd,OAAO;;;;;GAQzB,CAAC;AAOL,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAIF,eAAO,MAAM,qBAAqB;;;;6EA4E9B,CAAC"}
@@ -336,25 +336,28 @@ export const getSalesOrderDetail = createServerFn({ method: "POST" })
336
336
  at: reviewCf.floriday_change_detected_at ?? null,
337
337
  }
338
338
  : null;
339
- // Echt aantal ladingdragers uit de indeling (zelfde bron als de
340
- // Karindeling-kaart). Zonder indeling: geen aantal en geen type.
339
+ // Karren en indelingsstatus uit de Engine (logistics_order_plan_coverage).
340
+ // Fail closed: bij een fout "Indeling onbekend" en geen aantal.
341
341
  if (ownRow?.id) {
342
- // Via de karregels: gedeelde bufferkarren hebben order_id = NULL.
343
- const { loadCartsByOrder } = await import("./order-cart-count.server");
344
- const ci = (await loadCartsByOrder(supabase, [String(ownRow.id)])).get(String(ownRow.id));
345
- const carts = ci?.carrierTypes ?? [];
346
- dto.karShared = (ci?.sharedCount ?? 0) > 0;
347
- if (carts.length > 0) {
348
- dto.karCount = carts.length;
349
- const labels = Array.from(new Set(carts
350
- .map((code) => engineLoadCarrierLabel(normalizeLoadCarrierCode(code) ?? code))
351
- .filter((l) => !!l)));
352
- dto.cartTypeName =
353
- labels.length === 0 ? null : labels.length === 1 ? labels[0] : "Gemengd";
354
- }
355
- else {
356
- dto.karCount = 0;
357
- dto.cartTypeName = null;
342
+ const { loadPlanCoverage } = await import("./plan-coverage.server");
343
+ const { summarize } = await import("./plan-coverage");
344
+ const oid = String(ownRow.id);
345
+ const cov = (await loadPlanCoverage(supabase, [oid])).get(oid);
346
+ if (cov) {
347
+ dto.planCoverage = summarize(cov);
348
+ dto.karShared = cov.carts.some((k) => k.shared);
349
+ if (cov.state !== "onbekend" && cov.carts.length > 0) {
350
+ dto.karCount = cov.carts.length;
351
+ const labels = Array.from(new Set(cov.carts
352
+ .map((k) => engineLoadCarrierLabel(normalizeLoadCarrierCode(k.carrierType) ?? k.carrierType ?? ""))
353
+ .filter((l) => !!l)));
354
+ dto.cartTypeName =
355
+ labels.length === 0 ? null : labels.length === 1 ? labels[0] : "Gemengd";
356
+ }
357
+ else {
358
+ dto.karCount = 0;
359
+ dto.cartTypeName = null;
360
+ }
358
361
  }
359
362
  }
360
363
  bufferId = ownRow?.buffer_id ?? null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/floriday-verkoop-module",
3
- "version": "1.0.74",
3
+ "version": "1.0.77",
4
4
  "private": false,
5
5
  "sideEffects": false,
6
6
  "type": "module",