@flowselections/floriday-verkoop-module 1.0.12 → 1.0.14

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 (65) hide show
  1. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.d.ts +4 -0
  2. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.d.ts.map +1 -0
  3. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.js +95 -0
  4. package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts +6 -0
  5. package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts.map +1 -0
  6. package/dist-lib/components/verkoop/CartAssignmentWizard.js +194 -0
  7. package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -1
  8. package/dist-lib/components/verkoop/CreateOrderPage.js +14 -4
  9. package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts +4 -0
  10. package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts.map +1 -0
  11. package/dist-lib/components/verkoop/OrderAfleverbrievenCard.js +44 -0
  12. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts +5 -0
  13. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -0
  14. package/dist-lib/components/verkoop/OrderKarindelingCard.js +160 -0
  15. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  16. package/dist-lib/components/verkoop/SalesOrderDetailView.js +6 -3
  17. package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
  18. package/dist-lib/components/verkoop/VerkoopOrdersPage.js +39 -3
  19. package/dist-lib/integrations/supabase/auth-middleware.d.ts +605 -4
  20. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  21. package/dist-lib/integrations/supabase/client.d.ts +605 -4
  22. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  23. package/dist-lib/integrations/supabase/client.server.d.ts +605 -4
  24. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  25. package/dist-lib/integrations/supabase/client.server.js +4 -4
  26. package/dist-lib/integrations/supabase/types.d.ts +613 -4
  27. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  28. package/dist-lib/lib/cart-lock.functions.d.ts +11356 -0
  29. package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -0
  30. package/dist-lib/lib/cart-lock.functions.js +47 -0
  31. package/dist-lib/lib/cart-planner.d.ts +38 -0
  32. package/dist-lib/lib/cart-planner.d.ts.map +1 -0
  33. package/dist-lib/lib/cart-planner.js +217 -0
  34. package/dist-lib/lib/cart-replan.functions.d.ts +22729 -0
  35. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -0
  36. package/dist-lib/lib/cart-replan.functions.js +203 -0
  37. package/dist-lib/lib/create-order.functions.d.ts +26999 -76
  38. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  39. package/dist-lib/lib/create-order.functions.js +158 -3
  40. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +34033 -0
  41. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -0
  42. package/dist-lib/lib/floriday-auto-fulfillment.functions.js +65 -0
  43. package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts +21 -0
  44. package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts.map +1 -0
  45. package/dist-lib/lib/floriday-auto-fulfillment.server.js +352 -0
  46. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +11351 -0
  47. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -0
  48. package/dist-lib/lib/floriday-logistic-labels.functions.js +171 -0
  49. package/dist-lib/lib/floriday-public.functions.d.ts +4237 -44
  50. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
  51. package/dist-lib/lib/floriday-public.functions.js +45 -47
  52. package/dist-lib/lib/floriday-writes.functions.d.ts +3025 -20
  53. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  54. package/dist-lib/lib/salesorders-mapping.d.ts +2 -0
  55. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  56. package/dist-lib/lib/salesorders-mapping.js +46 -20
  57. package/dist-lib/lib/salesorders.functions.d.ts +1831 -28
  58. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  59. package/dist-lib/lib/salesorders.functions.js +8 -0
  60. package/dist-lib/lib/tradeitems.functions.d.ts +605 -4
  61. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  62. package/dist-lib/lib/useSalesOrdersQuery.d.ts +1 -0
  63. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
  64. package/dist-lib/lib/useSalesOrdersQuery.js +121 -39
  65. 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
+ });