@flowselections/floriday-verkoop-module 1.0.53 → 1.0.55

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 (66) hide show
  1. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
  2. package/dist-lib/components/verkoop/OrderKarindelingCard.js +68 -183
  3. package/dist-lib/integrations/supabase/auth-middleware.d.ts +42 -0
  4. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  5. package/dist-lib/integrations/supabase/client.d.ts +42 -0
  6. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  7. package/dist-lib/integrations/supabase/client.server.d.ts +42 -0
  8. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  9. package/dist-lib/integrations/supabase/types.d.ts +42 -0
  10. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  11. package/dist-lib/lib/cart-lock.functions.d.ts +42 -0
  12. package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
  13. package/dist-lib/lib/cart-planning-settings.functions.d.ts +462 -0
  14. package/dist-lib/lib/cart-planning-settings.functions.d.ts.map +1 -1
  15. package/dist-lib/lib/cart-replan.functions.d.ts +141 -23
  16. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
  17. package/dist-lib/lib/cart-replan.functions.js +111 -15
  18. package/dist-lib/lib/create-order.functions.d.ts +714 -0
  19. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  20. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +126 -0
  21. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
  22. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +42 -0
  23. package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
  24. package/dist-lib/lib/floriday-mirror.functions.d.ts +42 -0
  25. package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -1
  26. package/dist-lib/lib/floriday-public.functions.d.ts +294 -0
  27. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
  28. package/dist-lib/lib/floriday-writes.functions.d.ts +210 -0
  29. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  30. package/dist-lib/lib/invoice-timing.functions.d.ts +168 -0
  31. package/dist-lib/lib/invoice-timing.functions.d.ts.map +1 -1
  32. package/dist-lib/lib/invoice-timing.functions.js +12 -6
  33. package/dist-lib/lib/load-carriers.functions.d.ts +42 -0
  34. package/dist-lib/lib/load-carriers.functions.d.ts.map +1 -1
  35. package/dist-lib/lib/logistics-engine.functions.d.ts +210 -0
  36. package/dist-lib/lib/logistics-engine.functions.d.ts.map +1 -1
  37. package/dist-lib/lib/logistics-engine.functions.js +10 -5
  38. package/dist-lib/lib/logistics-stock.functions.d.ts +84 -0
  39. package/dist-lib/lib/logistics-stock.functions.d.ts.map +1 -1
  40. package/dist-lib/lib/order-addresses.functions.d.ts +42 -0
  41. package/dist-lib/lib/order-addresses.functions.d.ts.map +1 -1
  42. package/dist-lib/lib/order-addresses.functions.js +15 -9
  43. package/dist-lib/lib/order-buffers.functions.d.ts +126 -0
  44. package/dist-lib/lib/order-buffers.functions.d.ts.map +1 -1
  45. package/dist-lib/lib/order-buffers.functions.js +10 -10
  46. package/dist-lib/lib/order-carrier.functions.d.ts +84 -0
  47. package/dist-lib/lib/order-carrier.functions.d.ts.map +1 -1
  48. package/dist-lib/lib/order-carrier.functions.js +20 -11
  49. package/dist-lib/lib/order-pickup.functions.d.ts +84 -0
  50. package/dist-lib/lib/order-pickup.functions.d.ts.map +1 -1
  51. package/dist-lib/lib/order-pickup.functions.js +20 -11
  52. package/dist-lib/lib/order-row.server.d.ts +24 -0
  53. package/dist-lib/lib/order-row.server.d.ts.map +1 -0
  54. package/dist-lib/lib/order-row.server.js +58 -0
  55. package/dist-lib/lib/order-shipments.functions.d.ts +168 -0
  56. package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
  57. package/dist-lib/lib/order-shipments.functions.js +11 -6
  58. package/dist-lib/lib/salesorders-list.functions.d.ts +42 -0
  59. package/dist-lib/lib/salesorders-list.functions.d.ts.map +1 -1
  60. package/dist-lib/lib/salesorders.functions.d.ts +210 -0
  61. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  62. package/dist-lib/lib/stock-consumption-alerts.functions.d.ts +84 -0
  63. package/dist-lib/lib/stock-consumption-alerts.functions.d.ts.map +1 -1
  64. package/dist-lib/lib/tradeitems.functions.d.ts +42 -0
  65. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  66. package/package.json +1 -1
@@ -6,6 +6,7 @@
6
6
  import { createServerFn } from "@tanstack/react-start";
7
7
  import { z } from "zod";
8
8
  import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
9
+ import { resolveOrderRow } from "./order-row.server";
9
10
  import { CART_PLANNER_VERSION, planCarts, } from "./cart-planner";
10
11
  import { resolveBufferForOrderInternal } from "./order-buffers.functions";
11
12
  export async function replanBufferInternal(bufferId) {
@@ -360,8 +361,12 @@ export async function replanOrderCartsFromCron(orderId) {
360
361
  }
361
362
  export const replanOrderCarts = createServerFn({ method: "POST" })
362
363
  .middleware([requireSupabaseAuth])
363
- .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
364
- .handler(async ({ data }) => replanOrderInternal(data.orderId));
364
+ .inputValidator((input) => z.object({ orderId: z.string().min(1) }).parse(input))
365
+ .handler(async ({ data, context }) => {
366
+ // DTO-id kan een Floriday salesOrderId zijn.
367
+ const order = await resolveOrderRow(context.supabase, data.orderId);
368
+ return replanOrderInternal(order.id);
369
+ });
365
370
  // ─── Queue drain (aangeroepen door pg_cron elke minuut) ─────────────────────
366
371
  export async function drainCartReplanQueue(limit = 50) {
367
372
  const { supabaseAdmin } = await import("../integrations/supabase/client.server");
@@ -401,27 +406,118 @@ export async function drainCartReplanQueue(limit = 50) {
401
406
  // ─── Lezen — voor de UI ─────────────────────────────────────────────────────
402
407
  // Retourneert alle karren van de buffer waarin de order valt, zodat karren
403
408
  // die items van meerdere orders bevatten volledig zichtbaar zijn.
409
+ // Levert ook de order-context (nummers per orderregel) en, als er geen karren
410
+ // zijn, de laatste blokkadereden uit de engine (logistics_decisions /
411
+ // logistics_plan_queue). De UI berekent NIETS zelf: hij toont wat er staat.
404
412
  export const listOrderCarts = createServerFn({ method: "GET" })
405
413
  .middleware([requireSupabaseAuth])
406
- .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
414
+ .inputValidator((input) => z.object({ orderId: z.string().min(1) }).parse(input))
407
415
  .handler(async ({ data, context }) => {
408
- const { data: order } = await context.supabase
416
+ // Elke query faalt HARD. "Geen karren" en "kon niet laden" zijn twee
417
+ // verschillende dingen; stilzwijgend een lege array teruggeven verbergt
418
+ // fouten (RLS, kolomnaam, embed) als "nog geen karindeling".
419
+ const fail = (what, error) => {
420
+ throw new Error(`Karindeling laden mislukt (${what}): ${error?.message ?? "onbekende fout"}`);
421
+ };
422
+ // De DTO-id is voor Floriday-orders het salesOrderId, niet orders.id.
423
+ // resolveOrderRow doet de twee-staps-lookup + botsingswaarschuwing.
424
+ const orderRow = await resolveOrderRow(context.supabase, data.orderId);
425
+ const dbOrderId = orderRow.id;
426
+ const bufferId = orderRow.buffer_id;
427
+ const lockRes = await context.supabase
409
428
  .from("orders")
410
- .select("buffer_id")
411
- .eq("id", data.orderId)
429
+ .select("plan_locked_at")
430
+ .eq("id", dbOrderId)
412
431
  .maybeSingle();
413
- const bufferId = order?.buffer_id;
414
- const 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)";
432
+ if (lockRes.error)
433
+ fail("plan-lock lezen", lockRes.error);
434
+ const planLockedAt = lockRes.data?.plan_locked_at ?? null;
435
+ const select = "id, order_id, buffer_id, cart_number, source, is_complete, occupancy_pct, total_layers_used, algorithm_version, carrier_type, max_layers, 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)";
415
436
  const base = context.supabase.from("order_carts").select(select);
416
- const { data: carts } = await (bufferId
437
+ const cartsRes = await (bufferId
417
438
  ? base.eq("buffer_id", bufferId)
418
- : base.eq("order_id", data.orderId)).order("cart_number");
419
- return { carts: carts ?? [], bufferId };
439
+ : base.eq("order_id", dbOrderId)).order("cart_number");
440
+ if (cartsRes.error)
441
+ fail("karren lezen", cartsRes.error);
442
+ const carts = (cartsRes.data ?? []);
443
+ // Orders in de scope + ordernummer per orderregel (voor de badges).
444
+ let orders = [];
445
+ if (bufferId) {
446
+ const sibs = await context.supabase
447
+ .from("orders")
448
+ .select("id, order_number")
449
+ .eq("buffer_id", bufferId)
450
+ .is("deleted_at", null);
451
+ if (sibs.error)
452
+ fail("orders in buffer lezen", sibs.error);
453
+ orders = (sibs.data ?? []).map((o) => ({
454
+ id: o.id,
455
+ order_number: o.order_number ?? null,
456
+ }));
457
+ }
458
+ if (orders.length === 0) {
459
+ orders = [{ id: dbOrderId, order_number: orderRow.order_number ?? null }];
460
+ }
461
+ const orderIds = orders.map((o) => o.id);
462
+ let itemOrders = [];
463
+ if (orderIds.length > 0) {
464
+ const its = await context.supabase
465
+ .from("order_items")
466
+ .select("id, order_id")
467
+ .in("order_id", orderIds);
468
+ if (its.error)
469
+ fail("orderregels lezen", its.error);
470
+ itemOrders = (its.data ?? []).map((i) => ({
471
+ id: i.id,
472
+ order_id: i.order_id,
473
+ }));
474
+ }
475
+ // Blokkadereden alleen ophalen als er niets gepland staat.
476
+ let blocked = null;
477
+ if (carts.length === 0 && orderIds.length > 0) {
478
+ const dec = await context.supabase
479
+ .from("logistics_decisions")
480
+ .select("subject_id, slot, explanation, result, created_at")
481
+ .in("subject_id", orderIds)
482
+ .order("created_at", { ascending: false })
483
+ .limit(1);
484
+ if (dec.error)
485
+ fail("blokkadereden lezen", dec.error);
486
+ const d = (dec.data ?? [])[0];
487
+ if (d) {
488
+ blocked = {
489
+ reason: d.result?.reason ?? d.slot ?? null,
490
+ explanation: d.explanation ?? null,
491
+ at: d.created_at ?? null,
492
+ };
493
+ }
494
+ if (!blocked) {
495
+ const q = await context.supabase
496
+ .from("logistics_plan_queue")
497
+ .select("order_id, status, reason, error, updated_at")
498
+ .in("order_id", orderIds)
499
+ .order("updated_at", { ascending: false })
500
+ .limit(1);
501
+ if (q.error)
502
+ fail("planqueue lezen", q.error);
503
+ const r = (q.data ?? [])[0];
504
+ if (r && (r.error || r.reason)) {
505
+ blocked = {
506
+ reason: r.reason ?? null,
507
+ explanation: r.error ?? null,
508
+ at: r.updated_at ?? null,
509
+ };
510
+ }
511
+ }
512
+ }
513
+ return { carts, bufferId, orderId: dbOrderId, planLockedAt, orders, itemOrders, blocked };
420
514
  });
421
515
  export const replanBufferForOrder = createServerFn({ method: "POST" })
422
516
  .middleware([requireSupabaseAuth])
423
- .inputValidator((input) => z.object({ orderId: z.string().uuid() }).parse(input))
424
- .handler(async ({ data }) => {
425
- const bufferId = await resolveBufferForOrderInternal(data.orderId);
426
- return replanScopeInternal({ bufferId, orderId: data.orderId });
517
+ .inputValidator((input) => z.object({ orderId: z.string().min(1) }).parse(input))
518
+ .handler(async ({ data, context }) => {
519
+ // DTO-id kan een Floriday salesOrderId zijn.
520
+ const order = await resolveOrderRow(context.supabase, data.orderId);
521
+ const bufferId = await resolveBufferForOrderInternal(order.id);
522
+ return replanScopeInternal({ bufferId, orderId: order.id });
427
523
  });