@flowselections/floriday-verkoop-module 1.0.21 → 1.0.24

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 (80) 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 +1531 -592
  22. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  23. package/dist-lib/integrations/supabase/client.d.ts +1531 -592
  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 +1531 -592
  27. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  28. package/dist-lib/integrations/supabase/types.d.ts +1542 -577
  29. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  30. package/dist-lib/integrations/supabase/types.js +3 -9
  31. package/dist-lib/lib/cart-lock.functions.d.ts +1531 -592
  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 +140842 -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 +15808 -1111
  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 +19021 -7753
  43. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  44. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +4558 -1741
  45. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
  46. package/dist-lib/lib/floriday-auto-fulfillment.server.js +1 -1
  47. package/dist-lib/lib/floriday-central-token.server.d.ts +12 -0
  48. package/dist-lib/lib/floriday-central-token.server.d.ts.map +1 -0
  49. package/dist-lib/lib/floriday-central-token.server.js +58 -0
  50. package/dist-lib/lib/floriday-gateway.server.d.ts +2 -2
  51. package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
  52. package/dist-lib/lib/floriday-gateway.server.js +10 -37
  53. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +1531 -592
  54. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
  55. package/dist-lib/lib/floriday-logistic-labels.functions.js +14 -4
  56. package/dist-lib/lib/floriday-mirror.functions.d.ts +12806 -0
  57. package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -0
  58. package/dist-lib/lib/floriday-mirror.functions.js +278 -0
  59. package/dist-lib/lib/floriday-public.functions.d.ts +10986 -4413
  60. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
  61. package/dist-lib/lib/floriday-sync.d.ts +0 -1
  62. package/dist-lib/lib/floriday-sync.d.ts.map +1 -1
  63. package/dist-lib/lib/floriday-sync.js +1 -1
  64. package/dist-lib/lib/floriday-writes.functions.d.ts +7772 -3077
  65. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  66. package/dist-lib/lib/order-buffers.functions.d.ts +38420 -0
  67. package/dist-lib/lib/order-buffers.functions.d.ts.map +1 -0
  68. package/dist-lib/lib/order-buffers.functions.js +244 -0
  69. package/dist-lib/lib/order-shipments.functions.d.ts +6165 -2409
  70. package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
  71. package/dist-lib/lib/salesorders-mapping.d.ts +3 -0
  72. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  73. package/dist-lib/lib/salesorders.functions.d.ts +7774 -3077
  74. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  75. package/dist-lib/lib/salesorders.functions.js +129 -3
  76. package/dist-lib/lib/tradeitems.functions.d.ts +1531 -592
  77. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  78. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
  79. package/dist-lib/lib/useSalesOrdersQuery.js +37 -2
  80. package/package.json +5 -5
@@ -0,0 +1,244 @@
1
+ // Bepaalt en beheert "orderbuffers": groepen orders die volgens de
2
+ // Karindeling-instelling samen op karren ingedeeld moeten worden.
3
+ import { createServerFn } from "@tanstack/react-start";
4
+ import { z } from "zod";
5
+ import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
6
+ function normalizeBufferPart(value) {
7
+ if (value == null)
8
+ return null;
9
+ if (Array.isArray(value)) {
10
+ for (const item of value) {
11
+ const normalized = normalizeBufferPart(item);
12
+ if (normalized)
13
+ return normalized;
14
+ }
15
+ return null;
16
+ }
17
+ if (typeof value === "object") {
18
+ const obj = value;
19
+ return pickFirstString(obj.gln, obj.locationGln, obj.warehouseId, obj.id, obj.name, obj.location, obj.address?.addressLine);
20
+ }
21
+ const raw = String(value).trim();
22
+ if (!raw)
23
+ return null;
24
+ return raw.toLowerCase().replace(/\s+/g, " ");
25
+ }
26
+ function pickFirstString(...values) {
27
+ for (const value of values) {
28
+ const normalized = normalizeBufferPart(value);
29
+ if (normalized)
30
+ return normalized;
31
+ }
32
+ return null;
33
+ }
34
+ function isUuid(value) {
35
+ return !!value && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
36
+ }
37
+ /** Bouwt de deterministische buffer-sleutel voor een order op basis van de modus. */
38
+ export function buildBufferKey(order, mode) {
39
+ const cf = order.custom_fields ?? {};
40
+ const pickup_date = pickFirstString(cf.pickup_moment, cf.pickup_date, cf.pickup_datetime, order.delivery_date);
41
+ // De bufferlocatie is de afleverlocatie/bestemming. Voorheen werd hier de
42
+ // afhaallocatie gebruikt, waardoor orders voor dezelfde rit maar met dezelfde
43
+ // tuin niet betrouwbaar op bestemming werden samengevoegd.
44
+ const delivery_location = pickFirstString(cf.delivery_location_gln, cf.destination_gln, cf.region_gln, cf.location_gln, cf.delivery_location_id, cf.delivery_location);
45
+ const customer_id = normalizeBufferPart(order.customer_id);
46
+ switch (mode) {
47
+ case "same_pickup_and_location":
48
+ return {
49
+ key: `pl|${pickup_date ?? "-"}|${delivery_location ?? "-"}`,
50
+ pickup_date,
51
+ pickup_location: delivery_location,
52
+ };
53
+ case "same_pickup":
54
+ return {
55
+ key: `p|${pickup_date ?? "-"}`,
56
+ pickup_date,
57
+ pickup_location: delivery_location,
58
+ };
59
+ case "same_location":
60
+ return {
61
+ key: `l|${delivery_location ?? "-"}`,
62
+ pickup_date,
63
+ pickup_location: delivery_location,
64
+ };
65
+ case "same_customer":
66
+ return {
67
+ key: `c|${customer_id ?? "-"}|${pickup_date ?? "-"}`,
68
+ pickup_date,
69
+ pickup_location: delivery_location,
70
+ };
71
+ case "never":
72
+ default:
73
+ return {
74
+ key: `order-${order.id}`,
75
+ pickup_date,
76
+ pickup_location: delivery_location,
77
+ };
78
+ }
79
+ }
80
+ /** Zorgt dat een order aan de juiste buffer hangt. Retourneert de buffer-id. */
81
+ export async function resolveBufferForOrderInternal(orderId) {
82
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server");
83
+ const [{ data: order }, { data: settings }] = await Promise.all([
84
+ supabaseAdmin
85
+ .from("orders")
86
+ .select("id, customer_id, delivery_date, custom_fields, buffer_id")
87
+ .eq("id", orderId)
88
+ .maybeSingle(),
89
+ supabaseAdmin
90
+ .from("cart_planning_settings")
91
+ .select("buffer_grouping_mode")
92
+ .eq("id", 1)
93
+ .maybeSingle(),
94
+ ]);
95
+ if (!order)
96
+ throw new Error(`Order ${orderId} niet gevonden`);
97
+ const mode = (settings?.buffer_grouping_mode ??
98
+ "same_pickup_and_location");
99
+ const orderForKey = { ...order, custom_fields: { ...(order.custom_fields ?? {}) } };
100
+ const cf = orderForKey.custom_fields ?? {};
101
+ const deliveryLocationId = pickFirstString(cf.delivery_location_id, cf.delivery_location);
102
+ if (!cf.delivery_location_gln && isUuid(deliveryLocationId)) {
103
+ const { data: loc } = await supabaseAdmin
104
+ .from("customer_delivery_locations")
105
+ .select("gln, name, address_line, street, house_number, postal_code, city")
106
+ .eq("id", deliveryLocationId)
107
+ .maybeSingle();
108
+ if (loc) {
109
+ const locAny = loc;
110
+ cf.delivery_location_gln = locAny.gln ?? null;
111
+ cf.delivery_location_name = locAny.name ?? [locAny.address_line, locAny.street, locAny.house_number, locAny.postal_code, locAny.city]
112
+ .filter(Boolean)
113
+ .join(" ");
114
+ }
115
+ }
116
+ const { key, pickup_date, pickup_location } = buildBufferKey(orderForKey, mode);
117
+ // Upsert de buffer.
118
+ const { data: existing } = await supabaseAdmin
119
+ .from("order_buffers")
120
+ .select("id")
121
+ .eq("buffer_key", key)
122
+ .maybeSingle();
123
+ let bufferId = existing?.id;
124
+ if (!bufferId) {
125
+ const { data: created, error } = await supabaseAdmin
126
+ .from("order_buffers")
127
+ .insert({
128
+ buffer_key: key,
129
+ grouping_mode: mode,
130
+ pickup_date,
131
+ pickup_location,
132
+ customer_id: order.customer_id,
133
+ })
134
+ .select("id")
135
+ .single();
136
+ if (error) {
137
+ // Race: someone else inserted first — refetch.
138
+ const { data: retry } = await supabaseAdmin
139
+ .from("order_buffers")
140
+ .select("id")
141
+ .eq("buffer_key", key)
142
+ .maybeSingle();
143
+ bufferId = retry?.id;
144
+ if (!bufferId)
145
+ throw new Error(error.message);
146
+ }
147
+ else {
148
+ bufferId = created.id;
149
+ }
150
+ }
151
+ else {
152
+ await supabaseAdmin.from("order_buffers")
153
+ .update({
154
+ grouping_mode: mode,
155
+ pickup_date,
156
+ pickup_location,
157
+ customer_id: order.customer_id,
158
+ })
159
+ .eq("id", bufferId);
160
+ }
161
+ // Koppel de order aan de buffer als dit nog niet klopt.
162
+ if (order.buffer_id !== bufferId) {
163
+ await supabaseAdmin.from("orders")
164
+ .update({ buffer_id: bufferId })
165
+ .eq("id", orderId);
166
+ }
167
+ return bufferId;
168
+ }
169
+ /** Rebuffer alle orders (bv. na wijziging van buffer_grouping_mode). */
170
+ export async function rebufferAllOrdersInternal() {
171
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server");
172
+ const { data: orders } = await supabaseAdmin
173
+ .from("orders")
174
+ .select("id")
175
+ .is("deleted_at", null);
176
+ const affectedBuffers = new Set();
177
+ let processed = 0;
178
+ for (const row of orders ?? []) {
179
+ try {
180
+ const bufferId = await resolveBufferForOrderInternal(row.id);
181
+ affectedBuffers.add(bufferId);
182
+ processed++;
183
+ }
184
+ catch {
185
+ // skip
186
+ }
187
+ }
188
+ // Verwijder buffers die geen orders meer bevatten (na regroeping).
189
+ const { data: allBuffers } = await supabaseAdmin
190
+ .from("order_buffers")
191
+ .select("id, orders(id)")
192
+ .limit(10000);
193
+ const emptyIds = (allBuffers ?? [])
194
+ .filter((b) => !b.orders || b.orders.length === 0)
195
+ .map((b) => b.id);
196
+ if (emptyIds.length > 0) {
197
+ await supabaseAdmin.from("order_carts").delete().in("buffer_id", emptyIds);
198
+ await supabaseAdmin.from("order_buffers").delete().in("id", emptyIds);
199
+ }
200
+ // Herplan elke aangeraakte buffer direct, zodat karren de nieuwe groepering volgen.
201
+ const { replanBufferInternal } = await import("./cart-replan.functions");
202
+ let buffersReplanned = 0;
203
+ for (const bufferId of affectedBuffers) {
204
+ try {
205
+ await replanBufferInternal(bufferId);
206
+ buffersReplanned++;
207
+ }
208
+ catch {
209
+ // skip; wordt anders door de queue opgepakt
210
+ }
211
+ }
212
+ return { processed, buffersReplanned };
213
+ }
214
+ export const rebufferAllOrders = createServerFn({ method: "POST" })
215
+ .middleware([requireSupabaseAuth])
216
+ .handler(async () => rebufferAllOrdersInternal());
217
+ export const resolveBufferForOrder = createServerFn({ method: "POST" })
218
+ .middleware([requireSupabaseAuth])
219
+ .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
220
+ .handler(async ({ data }) => {
221
+ const bufferId = await resolveBufferForOrderInternal(data.orderId);
222
+ return { bufferId };
223
+ });
224
+ /** Haalt alle orders van dezelfde buffer als de gegeven order. */
225
+ export const listOrdersInBufferOfOrder = createServerFn({ method: "GET" })
226
+ .middleware([requireSupabaseAuth])
227
+ .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
228
+ .handler(async ({ data, context }) => {
229
+ const { data: order } = await context.supabase
230
+ .from("orders")
231
+ .select("buffer_id")
232
+ .eq("id", data.orderId)
233
+ .maybeSingle();
234
+ const bufferId = order?.buffer_id;
235
+ if (!bufferId)
236
+ return { bufferId: null, orders: [] };
237
+ const { data: siblings } = await context.supabase
238
+ .from("orders")
239
+ .select("id, order_number, customer_name, delivery_date, custom_fields")
240
+ .eq("buffer_id", bufferId)
241
+ .is("deleted_at", null)
242
+ .order("created_at");
243
+ return { bufferId, orders: siblings ?? [] };
244
+ });