@flowselections/floriday-verkoop-module 1.0.12 → 1.0.13
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/AutoFulfillmentStatusCard.d.ts +4 -0
- package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.js +95 -0
- package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts +6 -0
- package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/CartAssignmentWizard.js +194 -0
- package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/CreateOrderPage.js +14 -4
- package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts +4 -0
- package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/OrderAfleverbrievenCard.js +44 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts +5 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +160 -0
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +6 -3
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +39 -3
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +473 -3
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +473 -3
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +473 -3
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +481 -3
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/cart-lock.functions.d.ts +11225 -0
- package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -0
- package/dist-lib/lib/cart-lock.functions.js +47 -0
- package/dist-lib/lib/cart-planner.d.ts +38 -0
- package/dist-lib/lib/cart-planner.d.ts.map +1 -0
- package/dist-lib/lib/cart-planner.js +217 -0
- package/dist-lib/lib/cart-replan.functions.d.ts +22467 -0
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -0
- package/dist-lib/lib/cart-replan.functions.js +203 -0
- package/dist-lib/lib/create-order.functions.d.ts +25821 -77
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/create-order.functions.js +158 -3
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +33640 -0
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-auto-fulfillment.functions.js +65 -0
- package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts +21 -0
- package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-auto-fulfillment.server.js +352 -0
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +11220 -0
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-logistic-labels.functions.js +171 -0
- package/dist-lib/lib/floriday-public.functions.d.ts +3313 -37
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-public.functions.js +45 -47
- package/dist-lib/lib/floriday-writes.functions.d.ts +2365 -15
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.d.ts +2 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.js +46 -20
- package/dist-lib/lib/salesorders.functions.d.ts +1420 -10
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.js +8 -0
- package/dist-lib/lib/tradeitems.functions.d.ts +473 -3
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.d.ts +1 -0
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +121 -39
- package/package.json +1 -1
|
@@ -153,9 +153,7 @@ export const createManualOrder = createServerFn({ method: "POST" })
|
|
|
153
153
|
}
|
|
154
154
|
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
155
155
|
const total = data.lines.reduce((s, l) => s + (Number(l.unit_price ?? 0) * Number(l.quantity)), 0);
|
|
156
|
-
const orderNumber = `LOC-${Date.now()}`;
|
|
157
156
|
const { data: order, error: orderErr } = await supabaseAdmin.from("orders").insert({
|
|
158
|
-
order_number: orderNumber,
|
|
159
157
|
customer_name: data.customerName,
|
|
160
158
|
customer_id: data.customerId,
|
|
161
159
|
order_date: new Date().toISOString().slice(0, 10),
|
|
@@ -169,7 +167,7 @@ export const createManualOrder = createServerFn({ method: "POST" })
|
|
|
169
167
|
pickup_location: data.pickupLocationId,
|
|
170
168
|
carrier: data.carrierId,
|
|
171
169
|
},
|
|
172
|
-
}).select("id").single();
|
|
170
|
+
}).select("id, order_number").single();
|
|
173
171
|
if (orderErr)
|
|
174
172
|
throw new Error(orderErr.message);
|
|
175
173
|
const items = data.lines.map((l) => ({
|
|
@@ -183,6 +181,163 @@ export const createManualOrder = createServerFn({ method: "POST" })
|
|
|
183
181
|
const { error: itemsErr } = await supabaseAdmin.from("order_items").insert(items);
|
|
184
182
|
if (itemsErr)
|
|
185
183
|
throw new Error(itemsErr.message);
|
|
184
|
+
// Direct karindeling berekenen, zodat het scherm ze meteen kan tonen.
|
|
185
|
+
try {
|
|
186
|
+
const { replanOrderCartsFromCron } = await import("./cart-replan.functions");
|
|
187
|
+
await replanOrderCartsFromCron(order.id);
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
console.error("[createManualOrder] karindeling faalde:", err);
|
|
191
|
+
}
|
|
186
192
|
void context; // reserveren indien later audit-log nodig is
|
|
187
193
|
return { ok: true, orderId: order.id };
|
|
188
194
|
});
|
|
195
|
+
export const planAndSaveAutoCarts = createServerFn({ method: "POST" })
|
|
196
|
+
.middleware([requireSupabaseAuth])
|
|
197
|
+
.inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
|
|
198
|
+
.handler(async ({ data, context }) => {
|
|
199
|
+
const { data: items, error: itErr } = await context.supabase
|
|
200
|
+
.from("order_items")
|
|
201
|
+
.select("id, product_id, product_name, quantity, products(plants_per_crate, crates_per_layer, layers_per_cart)")
|
|
202
|
+
.eq("order_id", data.orderId);
|
|
203
|
+
if (itErr)
|
|
204
|
+
throw new Error(itErr.message);
|
|
205
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
206
|
+
await supabaseAdmin.from("order_carts").delete().eq("order_id", data.orderId).eq("is_auto", true);
|
|
207
|
+
let cartNumber = 1;
|
|
208
|
+
const { data: existingMax } = await supabaseAdmin
|
|
209
|
+
.from("order_carts").select("cart_number").eq("order_id", data.orderId)
|
|
210
|
+
.order("cart_number", { ascending: false }).limit(1);
|
|
211
|
+
if (existingMax && existingMax[0])
|
|
212
|
+
cartNumber = existingMax[0].cart_number + 1;
|
|
213
|
+
const autoCarts = [];
|
|
214
|
+
const remainders = [];
|
|
215
|
+
for (const it of items ?? []) {
|
|
216
|
+
const prod = it.products ?? {};
|
|
217
|
+
const ppc = Math.max(1, Number(prod.plants_per_crate ?? 1));
|
|
218
|
+
const cpl = Math.max(1, Number(prod.crates_per_layer ?? 1));
|
|
219
|
+
const lpc = Math.max(1, Number(prod.layers_per_cart ?? 1));
|
|
220
|
+
const cratesPerCart = cpl * lpc;
|
|
221
|
+
const totalPlants = Math.max(0, Number(it.quantity ?? 0));
|
|
222
|
+
const totalCrates = Math.ceil(totalPlants / ppc);
|
|
223
|
+
const fullCarts = Math.floor(totalCrates / cratesPerCart);
|
|
224
|
+
const remainder = totalCrates - fullCarts * cratesPerCart;
|
|
225
|
+
for (let i = 0; i < fullCarts; i++) {
|
|
226
|
+
const { data: cart, error: cErr } = await supabaseAdmin
|
|
227
|
+
.from("order_carts").insert({
|
|
228
|
+
order_id: data.orderId,
|
|
229
|
+
cart_number: cartNumber,
|
|
230
|
+
is_auto: true,
|
|
231
|
+
is_complete: true,
|
|
232
|
+
}).select("id").single();
|
|
233
|
+
if (cErr)
|
|
234
|
+
throw new Error(cErr.message);
|
|
235
|
+
await supabaseAdmin.from("order_cart_items").insert({
|
|
236
|
+
cart_id: cart.id,
|
|
237
|
+
order_item_id: it.id,
|
|
238
|
+
product_id: it.product_id,
|
|
239
|
+
product_name: it.product_name,
|
|
240
|
+
crates: cratesPerCart,
|
|
241
|
+
plants_per_crate: ppc,
|
|
242
|
+
crates_per_layer: cpl,
|
|
243
|
+
});
|
|
244
|
+
autoCarts.push({
|
|
245
|
+
cart_number: cartNumber,
|
|
246
|
+
product_name: it.product_name,
|
|
247
|
+
crates: cratesPerCart,
|
|
248
|
+
plants: cratesPerCart * ppc,
|
|
249
|
+
capacity: cratesPerCart,
|
|
250
|
+
});
|
|
251
|
+
cartNumber++;
|
|
252
|
+
}
|
|
253
|
+
if (remainder > 0) {
|
|
254
|
+
remainders.push({
|
|
255
|
+
order_item_id: it.id,
|
|
256
|
+
product_id: it.product_id,
|
|
257
|
+
product_name: it.product_name,
|
|
258
|
+
crates_remaining: remainder,
|
|
259
|
+
plants_per_crate: ppc,
|
|
260
|
+
crates_per_layer: cpl,
|
|
261
|
+
layers_per_cart: lpc,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const { data: manualCartsRaw } = await supabaseAdmin
|
|
266
|
+
.from("order_carts")
|
|
267
|
+
.select("id, cart_number, notes, order_cart_items(order_item_id, product_id, product_name, crates, plants_per_crate, crates_per_layer)")
|
|
268
|
+
.eq("order_id", data.orderId).eq("is_auto", false)
|
|
269
|
+
.order("cart_number");
|
|
270
|
+
const existingManualCarts = (manualCartsRaw ?? []).map((c) => ({
|
|
271
|
+
cart_number: c.cart_number,
|
|
272
|
+
notes: c.notes,
|
|
273
|
+
items: (c.order_cart_items ?? []).map((i) => ({
|
|
274
|
+
order_item_id: i.order_item_id,
|
|
275
|
+
product_id: i.product_id,
|
|
276
|
+
product_name: i.product_name,
|
|
277
|
+
crates: Number(i.crates ?? 0),
|
|
278
|
+
plants_per_crate: Number(i.plants_per_crate ?? 1),
|
|
279
|
+
crates_per_layer: Number(i.crates_per_layer ?? 1),
|
|
280
|
+
})),
|
|
281
|
+
}));
|
|
282
|
+
const assignedByItem = {};
|
|
283
|
+
existingManualCarts.forEach((c) => c.items.forEach((i) => {
|
|
284
|
+
if (!i.order_item_id)
|
|
285
|
+
return;
|
|
286
|
+
assignedByItem[i.order_item_id] = (assignedByItem[i.order_item_id] ?? 0) + Number(i.crates ?? 0);
|
|
287
|
+
}));
|
|
288
|
+
const adjustedRemainders = remainders
|
|
289
|
+
.map((r) => ({ ...r, crates_remaining: Math.max(0, r.crates_remaining - (assignedByItem[r.order_item_id] ?? 0)) }))
|
|
290
|
+
.filter((r) => r.crates_remaining > 0);
|
|
291
|
+
return { ok: true, autoCarts, remainders: adjustedRemainders, existingManualCarts, nextCartNumber: cartNumber };
|
|
292
|
+
});
|
|
293
|
+
const ManualCartItemSchema = z.object({
|
|
294
|
+
order_item_id: z.string().uuid().nullable(),
|
|
295
|
+
product_id: z.string().uuid().nullable(),
|
|
296
|
+
product_name: z.string().min(1).max(255),
|
|
297
|
+
crates: z.number().int().min(1),
|
|
298
|
+
plants_per_crate: z.number().int().min(1),
|
|
299
|
+
crates_per_layer: z.number().int().min(1),
|
|
300
|
+
});
|
|
301
|
+
const ManualCartSchema = z.object({
|
|
302
|
+
is_complete: z.boolean().optional(),
|
|
303
|
+
notes: z.string().max(500).nullable().optional(),
|
|
304
|
+
items: z.array(ManualCartItemSchema).min(1),
|
|
305
|
+
});
|
|
306
|
+
export const saveManualCarts = createServerFn({ method: "POST" })
|
|
307
|
+
.middleware([requireSupabaseAuth])
|
|
308
|
+
.inputValidator((input) => z.object({ orderId: z.string().uuid(), carts: z.array(ManualCartSchema) }).parse(input))
|
|
309
|
+
.handler(async ({ data }) => {
|
|
310
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
311
|
+
await supabaseAdmin.from("order_carts").delete()
|
|
312
|
+
.eq("order_id", data.orderId).eq("is_auto", false);
|
|
313
|
+
const { data: existingMax } = await supabaseAdmin
|
|
314
|
+
.from("order_carts").select("cart_number").eq("order_id", data.orderId)
|
|
315
|
+
.order("cart_number", { ascending: false }).limit(1);
|
|
316
|
+
let cartNumber = existingMax && existingMax[0] ? existingMax[0].cart_number + 1 : 1;
|
|
317
|
+
for (const cart of data.carts) {
|
|
318
|
+
const { data: inserted, error: cErr } = await supabaseAdmin
|
|
319
|
+
.from("order_carts").insert({
|
|
320
|
+
order_id: data.orderId,
|
|
321
|
+
cart_number: cartNumber,
|
|
322
|
+
is_auto: false,
|
|
323
|
+
is_complete: !!cart.is_complete,
|
|
324
|
+
notes: cart.notes ?? null,
|
|
325
|
+
}).select("id").single();
|
|
326
|
+
if (cErr)
|
|
327
|
+
throw new Error(cErr.message);
|
|
328
|
+
const rows = cart.items.map((i) => ({
|
|
329
|
+
cart_id: inserted.id,
|
|
330
|
+
order_item_id: i.order_item_id,
|
|
331
|
+
product_id: i.product_id,
|
|
332
|
+
product_name: i.product_name,
|
|
333
|
+
crates: i.crates,
|
|
334
|
+
plants_per_crate: i.plants_per_crate,
|
|
335
|
+
crates_per_layer: i.crates_per_layer,
|
|
336
|
+
}));
|
|
337
|
+
const { error: iErr } = await supabaseAdmin.from("order_cart_items").insert(rows);
|
|
338
|
+
if (iErr)
|
|
339
|
+
throw new Error(iErr.message);
|
|
340
|
+
cartNumber++;
|
|
341
|
+
}
|
|
342
|
+
return { ok: true };
|
|
343
|
+
});
|