@flowselections/floriday-verkoop-module 1.0.21 → 1.0.25

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 (95) hide show
  1. package/dist-lib/components/karindeling/AfmetingenTab.d.ts +6 -0
  2. package/dist-lib/components/karindeling/AfmetingenTab.d.ts.map +1 -0
  3. package/dist-lib/components/karindeling/AfmetingenTab.js +128 -0
  4. package/dist-lib/components/karindeling/KarindelingPage.d.ts +2 -0
  5. package/dist-lib/components/karindeling/KarindelingPage.d.ts.map +1 -0
  6. package/dist-lib/components/karindeling/KarindelingPage.js +102 -0
  7. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
  8. package/dist-lib/components/verkoop/OrderKarindelingCard.js +83 -37
  9. package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
  10. package/dist-lib/components/verkoop/SalesOrderDetailPage.js +59 -8
  11. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts +2 -1
  12. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  13. package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -2
  14. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  15. package/dist-lib/components/verkoop/SalesOrdersTable.js +36 -4
  16. package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
  17. package/dist-lib/components/verkoop/VerkoopOrdersPage.js +18 -2
  18. package/dist-lib/index.d.ts +1 -0
  19. package/dist-lib/index.d.ts.map +1 -1
  20. package/dist-lib/index.js +12 -1
  21. package/dist-lib/integrations/supabase/auth-middleware.d.ts +2353 -374
  22. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  23. package/dist-lib/integrations/supabase/client.d.ts +2353 -374
  24. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  25. package/dist-lib/integrations/supabase/client.js +24 -9
  26. package/dist-lib/integrations/supabase/client.server.d.ts +2353 -374
  27. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  28. package/dist-lib/integrations/supabase/types.d.ts +2406 -376
  29. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  30. package/dist-lib/integrations/supabase/types.js +11 -9
  31. package/dist-lib/lib/cart-lock.functions.d.ts +2353 -374
  32. package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
  33. package/dist-lib/lib/cart-planner.d.ts +9 -1
  34. package/dist-lib/lib/cart-planner.d.ts.map +1 -1
  35. package/dist-lib/lib/cart-planner.js +21 -4
  36. package/dist-lib/lib/cart-planning-settings.functions.d.ts +152282 -0
  37. package/dist-lib/lib/cart-planning-settings.functions.d.ts.map +1 -0
  38. package/dist-lib/lib/cart-planning-settings.functions.js +375 -0
  39. package/dist-lib/lib/cart-replan.functions.d.ts +18468 -651
  40. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
  41. package/dist-lib/lib/cart-replan.functions.js +85 -27
  42. package/dist-lib/lib/create-order.functions.d.ts +25367 -1619
  43. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  44. package/dist-lib/lib/cron/index.d.ts +5 -0
  45. package/dist-lib/lib/cron/index.d.ts.map +1 -0
  46. package/dist-lib/lib/cron/index.js +4 -0
  47. package/dist-lib/lib/cron/mirror-floriday-orders.d.ts +4 -0
  48. package/dist-lib/lib/cron/mirror-floriday-orders.d.ts.map +1 -0
  49. package/dist-lib/lib/cron/mirror-floriday-orders.js +23 -0
  50. package/dist-lib/lib/cron/replan-carts.d.ts +4 -0
  51. package/dist-lib/lib/cron/replan-carts.d.ts.map +1 -0
  52. package/dist-lib/lib/cron/replan-carts.js +18 -0
  53. package/dist-lib/lib/cron/sync-salesorders.d.ts +4 -0
  54. package/dist-lib/lib/cron/sync-salesorders.d.ts.map +1 -0
  55. package/dist-lib/lib/cron/sync-salesorders.js +18 -0
  56. package/dist-lib/lib/cron/sync-tradeitems.d.ts +4 -0
  57. package/dist-lib/lib/cron/sync-tradeitems.d.ts.map +1 -0
  58. package/dist-lib/lib/cron/sync-tradeitems.js +18 -0
  59. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +6539 -602
  60. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
  61. package/dist-lib/lib/floriday-auto-fulfillment.server.js +1 -1
  62. package/dist-lib/lib/floriday-central-token.server.d.ts +12 -0
  63. package/dist-lib/lib/floriday-central-token.server.d.ts.map +1 -0
  64. package/dist-lib/lib/floriday-central-token.server.js +58 -0
  65. package/dist-lib/lib/floriday-gateway.server.d.ts +2 -2
  66. package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
  67. package/dist-lib/lib/floriday-gateway.server.js +10 -37
  68. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +2353 -374
  69. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
  70. package/dist-lib/lib/floriday-logistic-labels.functions.js +14 -4
  71. package/dist-lib/lib/floriday-mirror.functions.d.ts +13846 -0
  72. package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -0
  73. package/dist-lib/lib/floriday-mirror.functions.js +278 -0
  74. package/dist-lib/lib/floriday-public.functions.d.ts +14907 -1054
  75. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
  76. package/dist-lib/lib/floriday-sync.d.ts +0 -1
  77. package/dist-lib/lib/floriday-sync.d.ts.map +1 -1
  78. package/dist-lib/lib/floriday-sync.js +1 -1
  79. package/dist-lib/lib/floriday-writes.functions.d.ts +10723 -828
  80. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  81. package/dist-lib/lib/order-buffers.functions.d.ts +41540 -0
  82. package/dist-lib/lib/order-buffers.functions.d.ts.map +1 -0
  83. package/dist-lib/lib/order-buffers.functions.js +244 -0
  84. package/dist-lib/lib/order-shipments.functions.d.ts +8631 -715
  85. package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
  86. package/dist-lib/lib/salesorders-mapping.d.ts +3 -0
  87. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  88. package/dist-lib/lib/salesorders.functions.d.ts +10725 -828
  89. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  90. package/dist-lib/lib/salesorders.functions.js +129 -3
  91. package/dist-lib/lib/tradeitems.functions.d.ts +2353 -374
  92. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  93. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
  94. package/dist-lib/lib/useSalesOrdersQuery.js +37 -2
  95. package/package.json +27 -5
@@ -7,19 +7,21 @@ import { createServerFn } from "@tanstack/react-start";
7
7
  import { z } from "zod";
8
8
  import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
9
9
  import { CART_PLANNER_VERSION, planCarts, } from "./cart-planner";
10
- async function replanOrderInternal(orderId) {
10
+ import { resolveBufferForOrderInternal } from "./order-buffers.functions";
11
+ export async function replanBufferInternal(bufferId) {
11
12
  const { supabaseAdmin } = await import("../integrations/supabase/client.server");
12
- // Order-metadata ophalen (voor FO-detectie / packingConfiguration fallback).
13
- const { data: orderRow } = await supabaseAdmin
13
+ const { data: orders } = await supabaseAdmin
14
14
  .from("orders")
15
15
  .select("id, custom_fields, plan_locked_at")
16
- .eq("id", orderId)
17
- .maybeSingle();
18
- // Als de order al vergrendeld is (eerste pakbon geprint), niets doen.
19
- if (orderRow?.plan_locked_at) {
16
+ .eq("buffer_id", bufferId)
17
+ .is("deleted_at", null);
18
+ const orderRows = (orders ?? []);
19
+ const orderIds = orderRows.map((o) => o.id);
20
+ if (orderRows.some((o) => o.plan_locked_at)) {
20
21
  return {
21
22
  ok: true,
22
- orderId,
23
+ bufferId,
24
+ orderIds,
23
25
  cartsCreated: 0,
24
26
  replacedManualCount: 0,
25
27
  usedFloridayPacking: false,
@@ -27,13 +29,11 @@ async function replanOrderInternal(orderId) {
27
29
  skipped: "locked",
28
30
  };
29
31
  }
30
- const custom = orderRow?.custom_fields ?? {};
31
- const floridayPacking = custom?.floriday_packing ?? null;
32
- // Items + belading uit products-tabel.
32
+ // Items van alle orders in de buffer.
33
33
  const { data: items, error: itErr } = await supabaseAdmin
34
34
  .from("order_items")
35
- .select("id, product_id, product_name, quantity, products(plants_per_crate, crates_per_layer, layers_per_cart)")
36
- .eq("order_id", orderId);
35
+ .select("id, order_id, product_id, product_name, quantity, products(plants_per_crate, crates_per_layer, layers_per_cart)")
36
+ .in("order_id", orderIds.length > 0 ? orderIds : ["00000000-0000-0000-0000-000000000000"]);
37
37
  if (itErr)
38
38
  throw new Error(itErr.message);
39
39
  const inputs = (items ?? []).map((it) => {
@@ -48,26 +48,33 @@ async function replanOrderInternal(orderId) {
48
48
  layers_per_cart: Math.max(1, Number(prod.layers_per_cart ?? 1)),
49
49
  };
50
50
  });
51
- // Bestaande karren tellen voordat we alles wissen (voor waarschuwing).
51
+ // Item → order-map voor het toewijzen van cart.order_id bij homogene karren.
52
+ const itemToOrder = new Map();
53
+ for (const it of items ?? []) {
54
+ itemToOrder.set(it.id, it.order_id);
55
+ }
56
+ // Bestaande karren in de buffer tellen (voor waarschuwing) en wissen.
52
57
  const { data: existingCarts } = await supabaseAdmin
53
58
  .from("order_carts")
54
59
  .select("id, source")
55
- .eq("order_id", orderId);
60
+ .eq("buffer_id", bufferId);
56
61
  const replacedManualCount = (existingCarts ?? []).filter((c) => c.source === "manual").length;
57
- // Alles wegvegen — cascade wist order_cart_items.
58
62
  const { error: delErr } = await supabaseAdmin
59
63
  .from("order_carts")
60
64
  .delete()
61
- .eq("order_id", orderId);
65
+ .eq("buffer_id", bufferId);
62
66
  if (delErr)
63
67
  throw new Error(delErr.message);
64
- // FO-fallback: gebruik Floriday packingConfiguration wanneer volledig aanwezig.
68
+ // Floriday-packingConfiguration-fallback: alleen als de buffer precies één
69
+ // order bevat én die order een volledig Floriday-packingConfiguration heeft.
65
70
  let usedFloridayPacking = false;
66
71
  let plannedCarts = [];
67
72
  const warnings = [];
68
- const isFo = custom?.source === "floriday" || floridayPacking?.pieces_per_package;
73
+ const solo = orderRows.length === 1 ? orderRows[0] : null;
74
+ const soloCustom = solo?.custom_fields ?? {};
75
+ const floridayPacking = soloCustom?.floriday_packing ?? null;
76
+ const isFo = solo && (soloCustom?.source === "floriday" || floridayPacking?.pieces_per_package);
69
77
  if (isFo && floridayPacking && Array.isArray(floridayPacking.carts)) {
70
- // Verwacht formaat: { carts: [{ items: [{ order_item_id, crates, plants_per_crate, crates_per_layer, layers_per_cart }] }] }
71
78
  usedFloridayPacking = true;
72
79
  plannedCarts = floridayPacking.carts.map((c, idx) => {
73
80
  const cItems = (c.items ?? []).map((i) => ({
@@ -93,17 +100,36 @@ async function replanOrderInternal(orderId) {
93
100
  });
94
101
  }
95
102
  else {
96
- const result = planCarts(inputs);
103
+ const [{ data: settings }, { data: overrides }] = await Promise.all([
104
+ supabaseAdmin.from("cart_planning_settings").select("*").eq("id", 1).maybeSingle(),
105
+ supabaseAdmin.from("cart_planning_product_overrides").select("product_id, never_mix"),
106
+ ]);
107
+ const neverMix = new Set((overrides ?? [])
108
+ .filter((o) => o.never_mix && o.product_id)
109
+ .map((o) => o.product_id));
110
+ const result = planCarts(inputs, {
111
+ maxPartySharePerLayerPct: settings?.max_party_share_per_layer_pct ?? 50,
112
+ maxBeladingenPerLayer: settings?.max_beladingen_per_layer ?? 2,
113
+ neverMixProductIds: neverMix,
114
+ });
97
115
  plannedCarts = result.carts;
98
116
  warnings.push(...result.warnings);
99
117
  }
100
- // Wegschrijven.
101
118
  let cartsCreated = 0;
102
119
  for (const cart of plannedCarts) {
120
+ // Bepaal cart.order_id: null bij mix van orders, anders die ene order.
121
+ const orderIdsOnCart = new Set();
122
+ for (const i of cart.items) {
123
+ const oid = itemToOrder.get(i.order_item_id);
124
+ if (oid)
125
+ orderIdsOnCart.add(oid);
126
+ }
127
+ const singleOrderId = orderIdsOnCart.size === 1 ? [...orderIdsOnCart][0] : null;
103
128
  const { data: inserted, error: cErr } = await supabaseAdmin
104
129
  .from("order_carts")
105
130
  .insert({
106
- order_id: orderId,
131
+ order_id: singleOrderId,
132
+ buffer_id: bufferId,
107
133
  cart_number: cart.cart_number,
108
134
  is_auto: true,
109
135
  is_complete: cart.is_complete,
@@ -139,13 +165,28 @@ async function replanOrderInternal(orderId) {
139
165
  }
140
166
  return {
141
167
  ok: true,
142
- orderId,
168
+ bufferId,
169
+ orderIds,
143
170
  cartsCreated,
144
171
  replacedManualCount,
145
172
  usedFloridayPacking,
146
173
  warnings,
147
174
  };
148
175
  }
176
+ async function replanOrderInternal(orderId) {
177
+ // Resolve (of maak) de buffer voor de order en plan de hele buffer opnieuw.
178
+ const bufferId = await resolveBufferForOrderInternal(orderId);
179
+ const res = await replanBufferInternal(bufferId);
180
+ return {
181
+ ok: res.ok,
182
+ orderId,
183
+ cartsCreated: res.cartsCreated,
184
+ replacedManualCount: res.replacedManualCount,
185
+ usedFloridayPacking: res.usedFloridayPacking,
186
+ warnings: res.warnings,
187
+ skipped: res.skipped,
188
+ };
189
+ }
149
190
  export async function replanOrderCartsFromCron(orderId) {
150
191
  return replanOrderInternal(orderId);
151
192
  }
@@ -190,14 +231,31 @@ export async function drainCartReplanQueue(limit = 50) {
190
231
  return { ok: failed === 0, processed, failed, results };
191
232
  }
192
233
  // ─── Lezen — voor de UI ─────────────────────────────────────────────────────
234
+ // Retourneert alle karren van de buffer waarin de order valt, zodat karren
235
+ // die items van meerdere orders bevatten volledig zichtbaar zijn.
193
236
  export const listOrderCarts = createServerFn({ method: "GET" })
194
237
  .middleware([requireSupabaseAuth])
195
238
  .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
196
239
  .handler(async ({ data, context }) => {
240
+ const { data: order } = await context.supabase
241
+ .from("orders")
242
+ .select("buffer_id")
243
+ .eq("id", data.orderId)
244
+ .maybeSingle();
245
+ const bufferId = order?.buffer_id;
246
+ if (!bufferId)
247
+ return { carts: [], bufferId: null };
197
248
  const { data: carts } = await context.supabase
198
249
  .from("order_carts")
199
- .select("id, cart_number, source, is_complete, occupancy_pct, total_layers_used, algorithm_version, notes, order_cart_items(id, order_item_id, product_id, product_name, crates, plants_per_crate, crates_per_layer, layers_per_cart, layer_fraction, layer_share_pct)")
200
- .eq("order_id", data.orderId)
250
+ .select("id, order_id, buffer_id, cart_number, source, is_complete, occupancy_pct, total_layers_used, algorithm_version, notes, order_cart_items(id, order_item_id, product_id, product_name, crates, plants_per_crate, crates_per_layer, layers_per_cart, layer_fraction, layer_share_pct)")
251
+ .eq("buffer_id", bufferId)
201
252
  .order("cart_number");
202
- return { carts: carts ?? [] };
253
+ return { carts: carts ?? [], bufferId };
254
+ });
255
+ export const replanBufferForOrder = createServerFn({ method: "POST" })
256
+ .middleware([requireSupabaseAuth])
257
+ .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
258
+ .handler(async ({ data }) => {
259
+ const bufferId = await resolveBufferForOrderInternal(data.orderId);
260
+ return replanBufferInternal(bufferId);
203
261
  });