@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.
- 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/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 +59 -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 +2 -2
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +36 -4
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +18 -2
- 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 +2353 -374
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +2353 -374
- 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 +2353 -374
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +2406 -376
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +11 -9
- package/dist-lib/lib/cart-lock.functions.d.ts +2353 -374
- 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 +152282 -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 +18468 -651
- 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 +25367 -1619
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/cron/index.d.ts +5 -0
- package/dist-lib/lib/cron/index.d.ts.map +1 -0
- package/dist-lib/lib/cron/index.js +4 -0
- package/dist-lib/lib/cron/mirror-floriday-orders.d.ts +4 -0
- package/dist-lib/lib/cron/mirror-floriday-orders.d.ts.map +1 -0
- package/dist-lib/lib/cron/mirror-floriday-orders.js +23 -0
- package/dist-lib/lib/cron/replan-carts.d.ts +4 -0
- package/dist-lib/lib/cron/replan-carts.d.ts.map +1 -0
- package/dist-lib/lib/cron/replan-carts.js +18 -0
- package/dist-lib/lib/cron/sync-salesorders.d.ts +4 -0
- package/dist-lib/lib/cron/sync-salesorders.d.ts.map +1 -0
- package/dist-lib/lib/cron/sync-salesorders.js +18 -0
- package/dist-lib/lib/cron/sync-tradeitems.d.ts +4 -0
- package/dist-lib/lib/cron/sync-tradeitems.d.ts.map +1 -0
- package/dist-lib/lib/cron/sync-tradeitems.js +18 -0
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +6539 -602
- 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 +2353 -374
- 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 +13846 -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 +14907 -1054
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- 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 +10723 -828
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-buffers.functions.d.ts +41540 -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 +8631 -715
- package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.d.ts +3 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.d.ts +10725 -828
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.js +129 -3
- package/dist-lib/lib/tradeitems.functions.d.ts +2353 -374
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +37 -2
- 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
|
-
|
|
10
|
+
import { resolveBufferForOrderInternal } from "./order-buffers.functions";
|
|
11
|
+
export async function replanBufferInternal(bufferId) {
|
|
11
12
|
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
12
|
-
|
|
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("
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
.
|
|
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
|
-
//
|
|
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("
|
|
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("
|
|
65
|
+
.eq("buffer_id", bufferId);
|
|
62
66
|
if (delErr)
|
|
63
67
|
throw new Error(delErr.message);
|
|
64
|
-
//
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
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("
|
|
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
|
});
|