@flowselections/floriday-verkoop-module 1.0.20 → 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.
- package/dist-lib/components/karindeling/AfmetingenTab.d.ts +6 -0
- package/dist-lib/components/karindeling/AfmetingenTab.d.ts.map +1 -0
- package/dist-lib/components/karindeling/AfmetingenTab.js +128 -0
- package/dist-lib/components/karindeling/KarindelingPage.d.ts +2 -0
- package/dist-lib/components/karindeling/KarindelingPage.d.ts.map +1 -0
- package/dist-lib/components/karindeling/KarindelingPage.js +102 -0
- package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts +6 -0
- package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/OrderControlStatusCard.js +41 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +83 -37
- package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailPage.js +74 -8
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts +2 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +3 -2
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +40 -5
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +19 -3
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +12 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1536 -581
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1536 -581
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.js +24 -9
- package/dist-lib/integrations/supabase/client.server.d.ts +1536 -581
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1543 -562
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +3 -9
- package/dist-lib/lib/cart-lock.functions.d.ts +1536 -581
- package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-planner.d.ts +9 -1
- package/dist-lib/lib/cart-planner.d.ts.map +1 -1
- package/dist-lib/lib/cart-planner.js +21 -4
- package/dist-lib/lib/cart-planning-settings.functions.d.ts +140842 -0
- package/dist-lib/lib/cart-planning-settings.functions.d.ts.map +1 -0
- package/dist-lib/lib/cart-planning-settings.functions.js +375 -0
- package/dist-lib/lib/cart-replan.functions.d.ts +15811 -1082
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-replan.functions.js +85 -27
- package/dist-lib/lib/create-order.functions.d.ts +19021 -7561
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +4558 -1693
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-auto-fulfillment.server.js +1 -1
- package/dist-lib/lib/floriday-central-token.server.d.ts +12 -0
- package/dist-lib/lib/floriday-central-token.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-central-token.server.js +58 -0
- package/dist-lib/lib/floriday-gateway.server.d.ts +2 -2
- package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.server.js +10 -37
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +1536 -581
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-logistic-labels.functions.js +14 -4
- package/dist-lib/lib/floriday-mirror.functions.d.ts +12806 -0
- package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-mirror.functions.js +278 -0
- package/dist-lib/lib/floriday-public.functions.d.ts +10989 -4301
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-public.functions.js +114 -38
- package/dist-lib/lib/floriday-sync.d.ts +0 -1
- package/dist-lib/lib/floriday-sync.d.ts.map +1 -1
- package/dist-lib/lib/floriday-sync.js +1 -1
- package/dist-lib/lib/floriday-writes.functions.d.ts +7772 -2997
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-buffers.functions.d.ts +38420 -0
- package/dist-lib/lib/order-buffers.functions.d.ts.map +1 -0
- package/dist-lib/lib/order-buffers.functions.js +244 -0
- package/dist-lib/lib/order-shipments.functions.d.ts +6165 -2345
- package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.d.ts +5 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.js +8 -1
- package/dist-lib/lib/salesorders.functions.d.ts +30443 -1979
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.js +307 -0
- package/dist-lib/lib/tradeitems.functions.d.ts +1536 -581
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrderDetailQuery.d.ts +2 -0
- package/dist-lib/lib/useSalesOrderDetailQuery.d.ts.map +1 -0
- package/dist-lib/lib/useSalesOrderDetailQuery.js +50 -0
- package/dist-lib/lib/useSalesOrdersQuery.d.ts +2 -2
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +139 -10
- 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
|
+
});
|