@flowselections/floriday-verkoop-module 1.0.52 → 1.0.54
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/verkoop/OrderKarindelingCard.d.ts.map +1 -1
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +65 -183
- package/dist-lib/lib/cart-planner.d.ts +9 -0
- package/dist-lib/lib/cart-planner.d.ts.map +1 -1
- package/dist-lib/lib/cart-planner.js +1 -1
- package/dist-lib/lib/cart-replan.functions.d.ts +16 -0
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-replan.functions.js +181 -13
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA4C/D,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,2CA+KvE"}
|
|
@@ -1,208 +1,90 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// Toont karindeling
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
|
|
2
|
+
// Toont de karindeling van de buffer waarin deze order valt.
|
|
3
|
+
//
|
|
4
|
+
// BELANGRIJK: deze kaart LEEST de karren uit `order_carts`/`order_cart_items`
|
|
5
|
+
// via de server-fn `listOrderCarts`. Hij berekent niets zelf — de planner
|
|
6
|
+
// draait server-side (cart-replan v3 / logistics_plan_buffer_sql). Een eigen
|
|
7
|
+
// herberekening in de browser gaf eerder een andere indeling dan de database
|
|
8
|
+
// (één artikel per kar, verkeerde kar-telling) en is daarom verwijderd.
|
|
9
|
+
import { useEffect, useMemo } from "react";
|
|
10
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
11
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
8
12
|
import { Badge, Card, CardContent, CardHeader, CardTitle, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@flowselections/core";
|
|
9
13
|
import { CheckCircle2, Lock } from "lucide-react";
|
|
10
14
|
import { supabase } from "../../integrations/supabase/client";
|
|
11
15
|
import { formatBeladingNotation } from "../../lib/load-carrier-labels";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
function deriveCartsFromFloriday(order) {
|
|
15
|
-
const o = order.raw.order ?? {};
|
|
16
|
-
const pack = o?.packingConfiguration ?? {};
|
|
17
|
-
const ppc = Math.max(1, Number(pack.piecesPerPackage ?? order.quantity.count ?? 1));
|
|
18
|
-
const cpl = Math.max(1, Number(pack.packagesPerLayer ?? 1));
|
|
19
|
-
const lpc = Math.max(1, Number(pack.layersPerLoadCarrier ?? 1));
|
|
20
|
-
const totalPieces = Math.max(0, Number(o.numberOfPieces ?? order.totalPieces ?? 0));
|
|
21
|
-
if (totalPieces <= 0)
|
|
22
|
-
return [];
|
|
23
|
-
const totalCrates = Math.ceil(totalPieces / ppc);
|
|
24
|
-
const cratesPerCart = cpl * lpc;
|
|
25
|
-
const fullCarts = Math.floor(totalCrates / cratesPerCart);
|
|
26
|
-
const remainderCrates = totalCrates - fullCarts * cratesPerCart;
|
|
27
|
-
const carts = [];
|
|
28
|
-
let n = 1;
|
|
29
|
-
for (let i = 0; i < fullCarts; i++) {
|
|
30
|
-
carts.push({
|
|
31
|
-
cart_number: n++,
|
|
32
|
-
is_complete: true,
|
|
33
|
-
occupancy_pct: 100,
|
|
34
|
-
total_layers_used: lpc,
|
|
35
|
-
items: [{
|
|
36
|
-
product_name: order.productName,
|
|
37
|
-
crates: cratesPerCart,
|
|
38
|
-
plants: cratesPerCart * ppc,
|
|
39
|
-
plants_per_crate: ppc,
|
|
40
|
-
crates_per_layer: cpl,
|
|
41
|
-
layers_per_cart: lpc,
|
|
42
|
-
layer_share_pct: 100,
|
|
43
|
-
}],
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
if (remainderCrates > 0) {
|
|
47
|
-
const layersUsed = Math.ceil(remainderCrates / cpl);
|
|
48
|
-
const occ = Math.round(((layersUsed / lpc) * 100) * 100) / 100;
|
|
49
|
-
carts.push({
|
|
50
|
-
cart_number: n,
|
|
51
|
-
is_complete: false,
|
|
52
|
-
occupancy_pct: occ,
|
|
53
|
-
total_layers_used: layersUsed,
|
|
54
|
-
items: [{
|
|
55
|
-
product_name: order.productName,
|
|
56
|
-
crates: remainderCrates,
|
|
57
|
-
plants: remainderCrates * ppc,
|
|
58
|
-
plants_per_crate: ppc,
|
|
59
|
-
crates_per_layer: cpl,
|
|
60
|
-
layers_per_cart: lpc,
|
|
61
|
-
layer_share_pct: occ,
|
|
62
|
-
}],
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return carts;
|
|
66
|
-
}
|
|
16
|
+
import { listOrderCarts } from "../../lib/cart-replan.functions";
|
|
17
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
67
18
|
function belading(i) {
|
|
68
19
|
// Eén notatie in de hele module: lagen × fusten/laag × planten/fust
|
|
69
20
|
// (Floriday-UI-volgorde, bewust anders dan de API-veldvolgorde).
|
|
70
|
-
|
|
71
|
-
|
|
21
|
+
const l = i.layers_per_cart ?? 0;
|
|
22
|
+
const c = i.crates_per_layer ?? 0;
|
|
23
|
+
const p = i.plants_per_crate ?? 0;
|
|
24
|
+
if (!l || !c || !p)
|
|
25
|
+
return "—";
|
|
26
|
+
return formatBeladingNotation(l, c, p) ?? `${l}×${c}×${p}`;
|
|
72
27
|
}
|
|
73
28
|
export function OrderKarindelingCard({ order }) {
|
|
74
29
|
// Lokale/mailbox-orders hebben een prefix (`local:`, `mailbox-proposal:`) in
|
|
75
|
-
// hun DTO-id
|
|
76
|
-
// dus die prefix moet eraf voor de query — anders faalt de UUID-cast en valt
|
|
77
|
-
// de kaart terug op de Floriday-modus met slechts één artikel.
|
|
30
|
+
// hun DTO-id; de DB gebruikt de kale UUID.
|
|
78
31
|
const rawId = order?.id ?? order.raw?.order?.id ?? null;
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
32
|
+
const stripped = typeof rawId === "string" ? rawId.replace(/^(local:|mailbox-proposal:)/, "") : null;
|
|
33
|
+
const orderId = stripped && UUID_RE.test(stripped) ? stripped : null;
|
|
34
|
+
const fetchCarts = useServerFn(listOrderCarts);
|
|
35
|
+
const queryClient = useQueryClient();
|
|
36
|
+
const queryKey = ["order-carts", orderId];
|
|
37
|
+
const { data, isLoading } = useQuery({
|
|
38
|
+
queryKey,
|
|
39
|
+
enabled: !!orderId,
|
|
40
|
+
staleTime: 15000,
|
|
41
|
+
queryFn: async () => fetchCarts({ data: { orderId: orderId } }),
|
|
42
|
+
});
|
|
43
|
+
// Realtime op de karren zelf — niet meer op products/order_items, want die
|
|
44
|
+
// voedden de verwijderde client-planner.
|
|
85
45
|
useEffect(() => {
|
|
86
46
|
if (!orderId)
|
|
87
47
|
return;
|
|
88
|
-
|
|
89
|
-
const load = async () => {
|
|
90
|
-
// 1) Bepaal de buffer van deze order.
|
|
91
|
-
const { data: orderRow } = await supabase
|
|
92
|
-
.from("orders")
|
|
93
|
-
.select("plan_locked_at, buffer_id")
|
|
94
|
-
.eq("id", orderId)
|
|
95
|
-
.maybeSingle();
|
|
96
|
-
if (!active)
|
|
97
|
-
return;
|
|
98
|
-
const bid = orderRow?.buffer_id ?? null;
|
|
99
|
-
setLockedAt(orderRow?.plan_locked_at ?? null);
|
|
100
|
-
setBufferId(bid);
|
|
101
|
-
// 2) Verzamel alle orders in deze buffer (of alleen deze order als er
|
|
102
|
-
// geen buffer bekend is).
|
|
103
|
-
let orderIds = [orderId];
|
|
104
|
-
let siblingOrders = [];
|
|
105
|
-
if (bid) {
|
|
106
|
-
const { data: sibs } = await supabase
|
|
107
|
-
.from("orders")
|
|
108
|
-
.select("id, order_number")
|
|
109
|
-
.eq("buffer_id", bid)
|
|
110
|
-
.is("deleted_at", null);
|
|
111
|
-
siblingOrders = (sibs ?? []).map((s) => ({
|
|
112
|
-
id: s.id,
|
|
113
|
-
order_number: s.order_number,
|
|
114
|
-
}));
|
|
115
|
-
if (siblingOrders.length > 0)
|
|
116
|
-
orderIds = siblingOrders.map((s) => s.id);
|
|
117
|
-
}
|
|
118
|
-
if (!active)
|
|
119
|
-
return;
|
|
120
|
-
setBufferOrders(siblingOrders);
|
|
121
|
-
// 3) Items van alle orders in de buffer.
|
|
122
|
-
const { data: itemRows } = await supabase
|
|
123
|
-
.from("order_items")
|
|
124
|
-
.select("id, order_id, product_id, product_name, quantity, products(plants_per_crate, crates_per_layer, layers_per_cart)")
|
|
125
|
-
.in("order_id", orderIds);
|
|
126
|
-
if (!active)
|
|
127
|
-
return;
|
|
128
|
-
const items = itemRows ?? [];
|
|
129
|
-
setDbItems(items);
|
|
130
|
-
const raws = items.map((it) => ({
|
|
131
|
-
id: it.id,
|
|
132
|
-
product_id: it.product_id,
|
|
133
|
-
product_name: it.product_name,
|
|
134
|
-
quantity: Number(it.quantity ?? 0),
|
|
135
|
-
plants_per_crate: Math.max(1, Number(it.products?.plants_per_crate ?? 1)),
|
|
136
|
-
crates_per_layer: Math.max(1, Number(it.products?.crates_per_layer ?? 1)),
|
|
137
|
-
layers_per_cart: Math.max(1, Number(it.products?.layers_per_cart ?? 1)),
|
|
138
|
-
}));
|
|
139
|
-
const expanded = await expandOrderItemsForPlanner(supabase, raws);
|
|
140
|
-
if (!active)
|
|
141
|
-
return;
|
|
142
|
-
setPlannerInputs(expanded);
|
|
143
|
-
};
|
|
144
|
-
void load();
|
|
48
|
+
const invalidate = () => void queryClient.invalidateQueries({ queryKey: ["order-carts", orderId] });
|
|
145
49
|
const channel = supabase
|
|
146
|
-
.channel(`order-
|
|
147
|
-
.on("postgres_changes", { event: "
|
|
148
|
-
.on("postgres_changes", { event: "*", schema: "public", table: "
|
|
149
|
-
.on("postgres_changes", { event: "UPDATE", schema: "public", table: "
|
|
50
|
+
.channel(`order-carts-${orderId}`)
|
|
51
|
+
.on("postgres_changes", { event: "*", schema: "public", table: "order_carts" }, invalidate)
|
|
52
|
+
.on("postgres_changes", { event: "*", schema: "public", table: "order_cart_items" }, invalidate)
|
|
53
|
+
.on("postgres_changes", { event: "UPDATE", schema: "public", table: "orders" }, invalidate)
|
|
150
54
|
.subscribe();
|
|
151
55
|
return () => {
|
|
152
|
-
active = false;
|
|
153
56
|
void supabase.removeChannel(channel);
|
|
154
57
|
};
|
|
155
|
-
}, [orderId]);
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
58
|
+
}, [orderId, queryClient]);
|
|
59
|
+
const carts = (data?.carts ?? []);
|
|
60
|
+
const orders = data?.orders ?? [];
|
|
61
|
+
const lockedAt = data?.planLockedAt ?? null;
|
|
62
|
+
const blocked = data?.blocked ?? null;
|
|
63
|
+
const orderNumberByItem = useMemo(() => {
|
|
64
|
+
const numberByOrder = new Map();
|
|
65
|
+
for (const o of orders)
|
|
66
|
+
numberByOrder.set(o.id, o.order_number);
|
|
164
67
|
const m = new Map();
|
|
165
|
-
for (const
|
|
166
|
-
m.set(
|
|
68
|
+
for (const it of data?.itemOrders ?? []) {
|
|
69
|
+
m.set(it.id, { orderId: it.order_id, orderNumber: numberByOrder.get(it.order_id) ?? null });
|
|
70
|
+
}
|
|
167
71
|
return m;
|
|
168
|
-
}, [
|
|
169
|
-
|
|
170
|
-
|
|
72
|
+
}, [data, orders]);
|
|
73
|
+
// Bron-badge uit de data: order_carts.source + algorithm_version.
|
|
74
|
+
const sourceLabel = useMemo(() => {
|
|
75
|
+
const srcs = [...new Set(carts.map((c) => c.source ?? "onbekend"))];
|
|
76
|
+
const vers = [...new Set(carts.map((c) => c.algorithm_version).filter((v) => v != null))];
|
|
77
|
+
if (srcs.length === 0)
|
|
171
78
|
return null;
|
|
172
|
-
return
|
|
173
|
-
}, [
|
|
174
|
-
const floridayCarts = useMemo(() => deriveCartsFromFloriday(order), [order]);
|
|
175
|
-
const usingVoorraad = plannerCarts !== null;
|
|
176
|
-
const carts = usingVoorraad
|
|
177
|
-
? plannerCarts.map((c) => {
|
|
178
|
-
const orderIds = new Set();
|
|
179
|
-
const items = c.items.map((i) => {
|
|
180
|
-
const oid = itemToOrder.get(i.order_item_id) ?? null;
|
|
181
|
-
if (oid)
|
|
182
|
-
orderIds.add(oid);
|
|
183
|
-
return {
|
|
184
|
-
product_name: i.product_name,
|
|
185
|
-
crates: i.crates,
|
|
186
|
-
plants: i.plants,
|
|
187
|
-
plants_per_crate: i.plants_per_crate,
|
|
188
|
-
crates_per_layer: i.crates_per_layer,
|
|
189
|
-
layers_per_cart: i.layers_per_cart,
|
|
190
|
-
layer_share_pct: i.layer_share_pct,
|
|
191
|
-
order_id: oid,
|
|
192
|
-
order_number: oid ? orderNumberById.get(oid) ?? null : null,
|
|
193
|
-
};
|
|
194
|
-
});
|
|
195
|
-
return {
|
|
196
|
-
cart_number: c.cart_number,
|
|
197
|
-
is_complete: c.is_complete,
|
|
198
|
-
occupancy_pct: c.occupancy_pct,
|
|
199
|
-
total_layers_used: c.total_layers_used,
|
|
200
|
-
items,
|
|
201
|
-
order_ids: [...orderIds],
|
|
202
|
-
};
|
|
203
|
-
})
|
|
204
|
-
: floridayCarts;
|
|
205
|
-
const source = usingVoorraad ? "voorraad" : "floriday";
|
|
79
|
+
return `${srcs.join(", ")}${vers.length > 0 ? ` · v${vers.join("/")}` : ""}`;
|
|
80
|
+
}, [carts]);
|
|
206
81
|
const lockedDate = lockedAt ? new Date(lockedAt).toLocaleString("nl-NL") : null;
|
|
207
|
-
|
|
82
|
+
const multiOrder = orders.length > 1;
|
|
83
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between", children: [_jsx(CardTitle, { className: "text-base", children: "Karindeling" }), _jsxs("div", { className: "flex items-center gap-2", children: [lockedAt && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Lock, { className: "h-3 w-3" }), "Vergrendeld \u2014 pakbon geprint ", lockedDate] })), multiOrder && (_jsxs(Badge, { variant: "outline", title: orders.map((o) => o.order_number ?? o.id).join(", "), children: ["Buffer \u00B7 ", orders.length, " orders"] })), _jsxs(Badge, { variant: "secondary", children: [carts.length, " kar(ren)", sourceLabel ? ` · bron: ${sourceLabel}` : ""] })] })] }), _jsx(CardContent, { children: isLoading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Karindeling laden\u2026" })) : carts.length === 0 ? (_jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen karindeling beschikbaar voor deze order." }), blocked && (blocked.explanation || blocked.reason) && (_jsxs("p", { className: "text-sm text-destructive", children: [blocked.explanation ?? blocked.reason, blocked.at ? ` (${new Date(blocked.at).toLocaleString("nl-NL")})` : ""] }))] })) : (_jsx("div", { className: "space-y-4", children: carts.map((c) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "font-mono font-medium", children: ["Kar ", c.cart_number] }), _jsxs(Badge, { variant: c.is_complete ? "default" : "secondary", className: "gap-1", children: [c.is_complete && _jsx(CheckCircle2, { className: "h-3 w-3" }), c.is_complete ? "Volledig" : "Deels"] }), c.order_id === null && multiOrder && (_jsx(Badge, { variant: "outline", children: "Gedeelde kar" })), c.carrier_type && (_jsxs(Badge, { variant: "outline", className: "font-mono text-[10px]", children: [c.carrier_type, c.max_layers ? ` · ${c.max_layers} lagen` : ""] }))] }), _jsxs("div", { className: "text-muted-foreground", children: [Number(c.total_layers_used ?? 0), " lagen \u00B7 benutting", " ", Math.round(Number(c.occupancy_pct ?? 0) * 10) / 10, "%"] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { children: "Belading" }), _jsx(TableHead, { className: "text-right", children: "Laag-aandeel" })] }) }), _jsx(TableBody, { children: (c.order_cart_items ?? []).map((i) => {
|
|
84
|
+
const own = i.order_item_id
|
|
85
|
+
? orderNumberByItem.get(i.order_item_id)
|
|
86
|
+
: undefined;
|
|
87
|
+
const crates = Number(i.crates ?? 0);
|
|
88
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { children: i.product_name ?? "—" }), multiOrder && own?.orderNumber && (_jsx(Badge, { variant: own.orderId === orderId ? "default" : "outline", className: "text-[10px]", children: own.orderNumber }))] }) }), _jsx(TableCell, { className: "text-right", children: crates * Number(i.plants_per_crate ?? 0) }), _jsx(TableCell, { className: "text-right", children: crates }), _jsx(TableCell, { className: "font-mono text-xs", children: belading(i) }), _jsxs(TableCell, { className: "text-right", children: [Math.round(Number(i.layer_share_pct ?? 0) * 10) / 10, "%"] })] }, i.id));
|
|
89
|
+
}) })] })] }, c.id))) })) })] }));
|
|
208
90
|
}
|
|
@@ -8,6 +8,13 @@ export interface PlannerInputItem {
|
|
|
8
8
|
plants_per_crate: number | null | undefined;
|
|
9
9
|
crates_per_layer: number | null | undefined;
|
|
10
10
|
layers_per_cart: number | null | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Ladingdrager van de regel (Floriday-code, bv. DANISH_TROLLEY).
|
|
13
|
+
* Uitsluitend informatief binnen de planner: partitioneren op ladingdrager
|
|
14
|
+
* gebeurt door de aanroeper (één planner-run per ladingdrager), zodat een
|
|
15
|
+
* veilingstapelwagen en een Deense container nooit op één kar komen.
|
|
16
|
+
*/
|
|
17
|
+
load_carrier?: string | null;
|
|
11
18
|
}
|
|
12
19
|
export interface PlannedCartItem {
|
|
13
20
|
order_item_id: string;
|
|
@@ -52,6 +59,8 @@ export interface PlannerOptions {
|
|
|
52
59
|
maxBeladingenPerLayer?: number;
|
|
53
60
|
/** Product-ids die nooit gemengd mogen worden. */
|
|
54
61
|
neverMixProductIds?: Set<string>;
|
|
62
|
+
/** Eerste karnummer van deze run (voor doorlopende nummering over partities). */
|
|
63
|
+
startCartNumber?: number;
|
|
55
64
|
}
|
|
56
65
|
export declare function planCarts(inputs: PlannerInputItem[], options?: PlannerOptions): PlannerResult;
|
|
57
66
|
//# sourceMappingURL=cart-planner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart-planner.d.ts","sourceRoot":"","sources":["../../src/lib/cart-planner.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cart-planner.d.ts","sourceRoot":"","sources":["../../src/lib/cart-planner.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAGD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,eAAe,GAAG,sBAAsB,CAAC;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uDAAuD;IACvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,0EAA0E;IAC1E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA+JD,wBAAgB,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAqJ7F"}
|
|
@@ -133,7 +133,7 @@ export function planCarts(inputs, options) {
|
|
|
133
133
|
const warnings = [];
|
|
134
134
|
const blocked = [];
|
|
135
135
|
const carts = [];
|
|
136
|
-
let cartNumber = 1;
|
|
136
|
+
let cartNumber = Math.max(1, Math.round(options?.startCartNumber ?? 1));
|
|
137
137
|
const num = (v) => {
|
|
138
138
|
if (v === null || v === undefined)
|
|
139
139
|
return null;
|
|
@@ -46495,6 +46495,8 @@ export declare const listOrderCarts: import("@tanstack/start-client-core").Optio
|
|
|
46495
46495
|
occupancy_pct: number;
|
|
46496
46496
|
total_layers_used: number;
|
|
46497
46497
|
algorithm_version: number;
|
|
46498
|
+
carrier_type: string;
|
|
46499
|
+
max_layers: number | null;
|
|
46498
46500
|
notes: string | null;
|
|
46499
46501
|
order_cart_items: {
|
|
46500
46502
|
id: string;
|
|
@@ -46510,6 +46512,20 @@ export declare const listOrderCarts: import("@tanstack/start-client-core").Optio
|
|
|
46510
46512
|
}[];
|
|
46511
46513
|
}[];
|
|
46512
46514
|
bufferId: string | null;
|
|
46515
|
+
planLockedAt: string | null;
|
|
46516
|
+
orders: {
|
|
46517
|
+
id: string;
|
|
46518
|
+
order_number: string | null;
|
|
46519
|
+
}[];
|
|
46520
|
+
itemOrders: {
|
|
46521
|
+
id: string;
|
|
46522
|
+
order_id: string;
|
|
46523
|
+
}[];
|
|
46524
|
+
blocked: {
|
|
46525
|
+
reason: string | null;
|
|
46526
|
+
explanation: string | null;
|
|
46527
|
+
at: string | null;
|
|
46528
|
+
} | null;
|
|
46513
46529
|
}>>;
|
|
46514
46530
|
export declare const replanBufferForOrder: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
|
|
46515
46531
|
supabase: import("@supabase/supabase-js").SupabaseClient<import("../integrations/supabase/types").Database, "public", "public", {
|