@flowselections/floriday-afhandeling-module 1.0.58 → 1.0.63

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 (49) hide show
  1. package/dist-lib/components/afhandeling/AutoSendStatus.d.ts +12 -0
  2. package/dist-lib/components/afhandeling/AutoSendStatus.d.ts.map +1 -0
  3. package/dist-lib/components/afhandeling/AutoSendStatus.js +86 -0
  4. package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
  5. package/dist-lib/components/afhandeling/DagDetailDialog.js +40 -24
  6. package/dist-lib/components/afhandeling/LeveringenPage.d.ts.map +1 -1
  7. package/dist-lib/components/afhandeling/LeveringenPage.js +3 -1
  8. package/dist-lib/components/afhandeling/NuVersturenButton.d.ts.map +1 -1
  9. package/dist-lib/components/afhandeling/NuVersturenButton.js +4 -4
  10. package/dist-lib/components/afhandeling/PickAgendaView.d.ts.map +1 -1
  11. package/dist-lib/components/afhandeling/PickAgendaView.js +9 -7
  12. package/dist-lib/components/afhandeling/ScanControleView.d.ts.map +1 -1
  13. package/dist-lib/components/afhandeling/ScanControleView.js +2 -2
  14. package/dist-lib/components/afhandeling/VerzetOrderDialog.js +3 -3
  15. package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
  16. package/dist-lib/components/afhandeling/WeekAgendaView.js +60 -10
  17. package/dist-lib/components/settings/AfhandelingSettingsCard.js +1 -1
  18. package/dist-lib/hooks/useConsistencyCheck.d.ts +1 -1
  19. package/dist-lib/hooks/useConsistencyCheck.d.ts.map +1 -1
  20. package/dist-lib/hooks/useConsistencyCheck.js +5 -3
  21. package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
  22. package/dist-lib/hooks/useOrderPlanning.js +7 -6
  23. package/dist-lib/hooks/usePickAgenda.d.ts +4 -0
  24. package/dist-lib/hooks/usePickAgenda.d.ts.map +1 -1
  25. package/dist-lib/hooks/usePickAgenda.js +36 -5
  26. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -1
  27. package/dist-lib/integrations/supabase/previewAuthStorage.js +22 -4
  28. package/dist-lib/integrations/supabase/types.d.ts +609 -2
  29. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  30. package/dist-lib/integrations/supabase/types.js +1 -0
  31. package/dist-lib/lib/cartAssignments.functions.d.ts +4 -0
  32. package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
  33. package/dist-lib/lib/cartAssignments.functions.js +5 -1
  34. package/dist-lib/lib/floriday.functions.d.ts +2 -0
  35. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  36. package/dist-lib/lib/floriday.functions.js +1 -0
  37. package/dist-lib/lib/floridayLoading.functions.d.ts +18 -0
  38. package/dist-lib/lib/floridayLoading.functions.d.ts.map +1 -1
  39. package/dist-lib/lib/floridayLoading.functions.js +28 -9
  40. package/dist-lib/lib/printing.js +1 -1
  41. package/dist-lib/lib/serverRoutes/autoSend.handler.d.ts +3 -0
  42. package/dist-lib/lib/serverRoutes/autoSend.handler.d.ts.map +1 -0
  43. package/dist-lib/lib/serverRoutes/autoSend.handler.js +123 -0
  44. package/dist-lib/lib/serverRoutes/index.d.ts +1 -0
  45. package/dist-lib/lib/serverRoutes/index.d.ts.map +1 -1
  46. package/dist-lib/lib/serverRoutes/index.js +1 -0
  47. package/dist-lib/moduleDefinition.d.ts.map +1 -1
  48. package/dist-lib/moduleDefinition.js +5 -2
  49. package/package.json +13 -2
@@ -39,6 +39,7 @@ export const Constants = {
39
39
  "veilingbon",
40
40
  "afleverbrief",
41
41
  "veilingbrief",
42
+ "traysticker",
42
43
  ],
43
44
  doc_orientation: ["portrait", "landscape"],
44
45
  exact_env: ["staging", "live"],
@@ -102,6 +102,10 @@ export interface DayOrderCoverage {
102
102
  approvedAll: boolean;
103
103
  /** Floriday heeft de belading geaccepteerd (created / already_fulfilled). */
104
104
  floridaySent: boolean;
105
+ /** Unieke kar-id's van deze order (ook gedeelde bufferkarren). */
106
+ cartIds: string[];
107
+ /** Kar-id's met een goedgekeurde controlescan. */
108
+ approvedCartIds: string[];
105
109
  }
106
110
  /**
107
111
  * Karindeling per order via de Engine-leesfunctie `logistics_order_plan_coverage`.
@@ -1 +1 @@
1
- {"version":3,"file":"cartAssignments.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cartAssignments.functions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cartAssignments.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cartAssignments.functions.ts"],"names":[],"mappings":"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"}
@@ -184,6 +184,8 @@ export const getDayCartContents = createServerFn({ method: "POST" })
184
184
  pickedAt: typeof c.pickedAt === "string" ? c.pickedAt : null,
185
185
  approvedAll: false,
186
186
  floridaySent: false,
187
+ cartIds: [],
188
+ approvedCartIds: [],
187
189
  });
188
190
  cartIdsByRef.set(orderRef, arr(c.carts).map((k) => k?.cartId).filter((x) => typeof x === "string"));
189
191
  // Lagen/bezetting alleen als de Engine ze in het karbriefplan levert; anders onbekend.
@@ -237,6 +239,8 @@ export const getDayCartContents = createServerFn({ method: "POST" })
237
239
  const ids = cartIdsByRef.get(o.orderRef) ?? [];
238
240
  o.approvedAll = ids.length > 0 && ids.every((id) => approved.has(id));
239
241
  o.floridaySent = sentRefs.has(o.orderRef);
242
+ o.cartIds = [...new Set(ids)];
243
+ o.approvedCartIds = o.cartIds.filter((id) => approved.has(id));
240
244
  }
241
245
  carts.sort((a, b) => a.orderRef.localeCompare(b.orderRef) || a.cartNumber - b.cartNumber);
242
246
  return { carts, orders };
@@ -275,7 +279,7 @@ export const getPakbonCartInfo = createServerFn({ method: "POST" })
275
279
  if (error)
276
280
  throw new Error(`Kar-barcode niet opgehaald: ${error.message}`);
277
281
  if (typeof bc !== "string" || !bc)
278
- throw new Error("De Engine gaf geen kar-barcode terug.");
282
+ throw new Error("De kar is nog niet ingedeeld. Probeer het over een minuut opnieuw.");
279
283
  barcodes.set(id, bc);
280
284
  }));
281
285
  const { data: jobs, error } = await supabase
@@ -20,6 +20,8 @@ export interface FloridayOrder {
20
20
  hasStickers?: boolean;
21
21
  /** Floriday salesOrderId — nodig voor afleverbrief PDF via gateway. */
22
22
  salesOrderId?: string | null;
23
+ /** Floriday-afmeldstand uit de order (custom_fields.floriday_fulfilled). */
24
+ floridayFulfilled?: boolean;
23
25
  /**
24
26
  * Deze module toont uitsluitend orders uit de orderadministratie van de
25
27
  * Verkoop-module (public.orders). Daarom is dit altijd waar; het veld blijft
@@ -1 +1 @@
1
- {"version":3,"file":"floriday.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floriday.functions.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AA4CD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;8CAEJ,sBAAsB,GAAG,SAAS,8DA+LxD,CAAC;AAEL,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAGD;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;YAEsB,aAAa,EAAE;YAAU,MAAM;GAqB7E,CAAC"}
1
+ {"version":3,"file":"floriday.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floriday.functions.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AA4CD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;8CAEJ,sBAAsB,GAAG,SAAS,8DAgMxD,CAAC;AAEL,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAGD;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;YAEsB,aAAa,EAAE;YAAU,MAAM;GAqB7E,CAAC"}
@@ -190,6 +190,7 @@ export const getFloridayOrders = createServerFn({ method: "GET" })
190
190
  city: deliveryLocation?.city ?? null,
191
191
  hasStickers: salesOrderId ? stickerOrderIds.has(salesOrderId) : false,
192
192
  salesOrderId,
193
+ floridayFulfilled: fields.floriday_fulfilled === true || fields.floriday_fulfilled === "true",
193
194
  mirrored: true,
194
195
  mirroredOrderId: orderId,
195
196
  };
@@ -54,6 +54,13 @@ export interface LoadingPreview {
54
54
  /** Redenen waarom nog niet verstuurd mag worden; leeg = klaar. */
55
55
  blockers: string[];
56
56
  canSend: boolean;
57
+ /** Buffer met nog niet goedgekeurde karren (unieke cart_id); null = geen buffer of compleet. */
58
+ bufferIncomplete: {
59
+ bufferId: string;
60
+ scanned: number;
61
+ total: number;
62
+ missingCartIds: string[];
63
+ } | null;
57
64
  }
58
65
  export interface SendResult {
59
66
  ok: boolean;
@@ -67,6 +74,7 @@ export interface SendResult {
67
74
  }
68
75
  /** Floriday 2026v1 AddLoadCarrierConfiguration.loadCarrierReference: maximaal 14 tekens. */
69
76
  export declare const LOAD_CARRIER_REF_MAX = 14;
77
+ export declare const ACCEPTED: Set<string>;
70
78
  /** Stelt de belading samen en toont de controles. Verstuurt niets. */
71
79
  export declare const prepareFloridayLoading: import("@tanstack/start-client-core").RequiredFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
72
80
  supabase: import("../integrations/supabase/auth-middleware").AuthedSupabaseClient;
@@ -92,4 +100,14 @@ export declare const sendFloridayLoading: import("@tanstack/start-client-core").
92
100
  }) => {
93
101
  orderRef: string;
94
102
  }, Promise<SendResult>>;
103
+ /** Controle vooraf, ook bruikbaar vanuit de getekende auto-send-route. */
104
+ export declare function prepareLoadingServer(supabase: any, orderRef: string): Promise<LoadingPreview>;
105
+ /**
106
+ * De enige verzendkern (AGENTS.md): "Nu versturen" en automatisch versturen
107
+ * gebruiken allebei deze functie met dezelfde vaste kenmerken.
108
+ */
109
+ export declare function runLoadingSend(supabase: any, p: LoadingPreview, actor: {
110
+ userId: string | null;
111
+ source: "manual" | "auto-send";
112
+ }): Promise<SendResult>;
95
113
  //# sourceMappingURL=floridayLoading.functions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"floridayLoading.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floridayLoading.functions.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AACD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AACD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3H;AAQD,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AA+TvC,sEAAsE;AACtE,eAAO,MAAM,sBAAsB;;;;0CAEb;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;2BAC4E,CAAC;AAEvH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;0CAEV;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;uBA0DtC,CAAC"}
1
+ {"version":3,"file":"floridayLoading.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floridayLoading.functions.ts"],"names":[],"mappings":"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"}
@@ -85,7 +85,7 @@ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
85
85
  // Auto-verwerking (1.0.64) neemt alleen aan; deze statussen betekenen dat de oude
86
86
  // route tóch al belading/verzendbrief heeft gedaan → nooit nog eens versturen.
87
87
  const AUTO_ALREADY_SENT = new Set(["sending_fulfillment", "generating_delivery_note", "done"]);
88
- const ACCEPTED = new Set(["created", "already_fulfilled"]);
88
+ export const ACCEPTED = new Set(["created", "already_fulfilled"]);
89
89
  async function buildLoading(supabase, orderRef) {
90
90
  if (!orderRef)
91
91
  throw new Error("Geen order opgegeven.");
@@ -239,7 +239,7 @@ async function buildLoading(supabase, orderRef) {
239
239
  }
240
240
  const allLines = [...carts.values()].flatMap((c) => c.lines);
241
241
  if (allLines.some((l) => !l.packages || l.packages <= 0))
242
- blockers.push("Niet elke regel heeft een aantal fusten van de Engine.");
242
+ blockers.push("Niet elke regel heeft een aantal fusten in de planning.");
243
243
  for (const [, c] of carts) {
244
244
  if (new Set(c.lines.map((l) => l.dl ?? "")).size > 1)
245
245
  blockers.push(`Kar ${c.label} bevat orders van verschillende leveringen; één kar kan maar in één opdracht.`);
@@ -309,7 +309,7 @@ async function buildLoading(supabase, orderRef) {
309
309
  for (const s of shipments) {
310
310
  const nm = s.orderRefs.join(", ");
311
311
  if (!UUID_RE.test(s.fulfillmentOrderId))
312
- blockers.push(`Opdracht voor ${nm} heeft geen geldig opdrachtkenmerk (uuid). [fulfillmentOrderId]`);
312
+ blockers.push(`Order ${nm} kan niet naar Floriday: er ontbreken Floriday-gegevens. Klik op ‘Floriday-orders bijwerken’ en probeer opnieuw. [fulfillmentOrderId]`);
313
313
  if (s.deliveryOrderId && !UUID_RE.test(s.deliveryOrderId))
314
314
  blockers.push(`Levering voor ${nm} heeft geen geldig Floriday-kenmerk (uuid). [deliveryOrderId]`);
315
315
  if (!s.carriers.length)
@@ -354,6 +354,13 @@ async function buildLoading(supabase, orderRef) {
354
354
  lastAttempts,
355
355
  blockers: uniqBlockers,
356
356
  canSend: uniqBlockers.length === 0 && shipments.length > 0,
357
+ bufferIncomplete: (() => {
358
+ const bId = [...coverage.values()].find((c) => c.bufferId)?.bufferId ?? null;
359
+ if (!bId)
360
+ return null;
361
+ const missing = allCartIds.filter((c) => !approvedCarts.has(c));
362
+ return missing.length ? { bufferId: bId, scanned: allCartIds.length - missing.length, total: allCartIds.length, missingCartIds: missing } : null;
363
+ })(),
357
364
  };
358
365
  }
359
366
  /** Stelt de belading samen en toont de controles. Verstuurt niets. */
@@ -371,15 +378,27 @@ export const sendFloridayLoading = createServerFn({ method: "POST" })
371
378
  .middleware([requireSupabaseAuth])
372
379
  .inputValidator((d) => ({ orderRef: String(d?.orderRef ?? "").trim() }))
373
380
  .handler(async ({ data, context }) => {
374
- const supabase = context.supabase;
375
- const p = await buildLoading(supabase, data.orderRef);
381
+ const p = await buildLoading(context.supabase, data.orderRef);
376
382
  if (!p.canSend)
377
383
  throw new Error(`Niet verstuurd: ${p.blockers.join(" ") || "geen opdracht."}`);
384
+ return runLoadingSend(context.supabase, p, { userId: context.userId, source: "manual" });
385
+ });
386
+ /** Controle vooraf, ook bruikbaar vanuit de getekende auto-send-route. */
387
+ export async function prepareLoadingServer(supabase, orderRef) {
388
+ return buildLoading(supabase, orderRef);
389
+ }
390
+ /**
391
+ * De enige verzendkern (AGENTS.md): "Nu versturen" en automatisch versturen
392
+ * gebruiken allebei deze functie met dezelfde vaste kenmerken.
393
+ */
394
+ export async function runLoadingSend(supabase, p, actor) {
378
395
  const { sendFulfillmentOrder, floridayFoutTekst } = await import("./floridayFulfillmentSend.server");
379
396
  const log = async (s, row) => {
397
+ const rs = row.request_summary ?? {};
380
398
  const { error } = await supabase.from("floriday_loading_attempts").insert({
381
399
  fulfillment_order_id: s.fulfillmentOrderId, delivery_order_id: s.deliveryOrderId,
382
- sales_order_ids: s.salesOrderIds, order_refs: s.orderRefs, created_by: context.userId, ...row,
400
+ sales_order_ids: s.salesOrderIds, order_refs: s.orderRefs, created_by: actor.userId, ...row,
401
+ request_summary: { ...rs, source: actor.source },
383
402
  });
384
403
  if (error)
385
404
  console.warn("[belading] log mislukt", error.message);
@@ -418,15 +437,15 @@ export const sendFloridayLoading = createServerFn({ method: "POST" })
418
437
  }
419
438
  const code = String(body?.code ?? (httpStatus && httpStatus < 400 ? "ok" : `http_${httpStatus}`));
420
439
  const accepted = httpStatus === 200 && body?.ok === true && ACCEPTED.has(code);
421
- const message = accepted ? (code === "created" ? "Belading verstuurd, verzendbrief volgt via de Engine." : "Belading was al verstuurd (niets dubbel aangemaakt), verzendbrief volgt via de Engine.")
440
+ const message = accepted ? (code === "created" ? "Belading naar Floriday gestuurd. De verzendbrief wordt automatisch geprint." : "Belading was al verstuurd (niets dubbel aangemaakt), verzendbrief volgt via de Engine.")
422
441
  : floridayFoutTekst("Floriday weigert de opdracht", { httpStatus: httpStatus ?? 0, body });
423
442
  await log(s, {
424
443
  step: "send", http_status: httpStatus, code, message,
425
444
  warnings: arr(body?.warnings), skipped_requests: arr(body?.skippedRequests), request_summary: summary,
426
445
  });
427
446
  // Verzendbrief: eigendom van de Logistieke Engine (runPdf delivery-note + herhalingen).
428
- const deliveryNote = accepted ? "volgt via de Engine" : "—";
447
+ const deliveryNote = accepted ? "wordt automatisch geprint" : "—";
429
448
  results.push({ fulfillmentOrderId: s.fulfillmentOrderId, code, httpStatus, message, deliveryNote });
430
449
  }
431
450
  return { ok: results.every((r) => ACCEPTED.has(r.code)), results };
432
- });
451
+ }
@@ -10,7 +10,7 @@ export class GeenPrinterFout extends Error {
10
10
  }
11
11
  export class PrintApiNietBeschikbaarFout extends Error {
12
12
  constructor(fn) {
13
- super(`De printservice mist functie "${fn}". Werk @flowselections/layout-maker bij in de shell.`);
13
+ super(`Printen werkt nu niet (update nodig). Meld dit bij Flow Selections. [printfunctie ${fn}]`);
14
14
  this.name = "PrintApiNietBeschikbaarFout";
15
15
  }
16
16
  }
@@ -0,0 +1,3 @@
1
+ /** Shell roept aan met (request, supabaseAdmin); voor OPTIONS met (request, null). */
2
+ export declare function handleAutoSend(request: Request, admin?: unknown): Promise<Response>;
3
+ //# sourceMappingURL=autoSend.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoSend.handler.d.ts","sourceRoot":"","sources":["../../../src/lib/serverRoutes/autoSend.handler.ts"],"names":[],"mappings":"AA2BA,sFAAsF;AACtF,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgDzF"}
@@ -0,0 +1,123 @@
1
+ // /api/public/hooks/afhandeling-auto-send — aanroep door de Logistieke Engine
2
+ // (koppelprompt 23). Getekend: x-timestamp (epoch-ms) + x-signature (hex
3
+ // HMAC-SHA256 over "<timestamp>.<rawBody>"), sleutel = Floriday-gatewaygeheim.
4
+ // Fail closed: geen geheim = niets doen. Versturen loopt via runLoadingSend.
5
+ import { z } from "zod";
6
+ const MAX_SKEW_MS = 5 * 60000;
7
+ const bodySchema = z.object({ orderId: z.string().uuid() }).strict();
8
+ const json = (status, body) => Response.json(body, { status });
9
+ function hex(buf) {
10
+ return [...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, "0")).join("");
11
+ }
12
+ function safeEqual(a, b) {
13
+ if (a.length !== b.length)
14
+ return false;
15
+ let d = 0;
16
+ for (let i = 0; i < a.length; i++)
17
+ d |= a.charCodeAt(i) ^ b.charCodeAt(i);
18
+ return d === 0;
19
+ }
20
+ const CORS = {
21
+ "Access-Control-Allow-Origin": "*",
22
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
23
+ "Access-Control-Allow-Headers": "content-type, x-timestamp, x-signature, idempotency-key",
24
+ };
25
+ /** Shell roept aan met (request, supabaseAdmin); voor OPTIONS met (request, null). */
26
+ export async function handleAutoSend(request, admin) {
27
+ if (request.method === "OPTIONS")
28
+ return new Response(null, { status: 204, headers: CORS });
29
+ const rawBody = await request.text();
30
+ const ts = request.headers.get("x-timestamp")?.trim() ?? "";
31
+ const sig = (request.headers.get("x-signature")?.trim() ?? "").toLowerCase();
32
+ if (!/^\d{13}$/.test(ts))
33
+ return json(401, { ok: false, code: "invalid_timestamp", error: "x-timestamp moet epoch-milliseconden zijn." });
34
+ if (Math.abs(Date.now() - Number(ts)) > MAX_SKEW_MS)
35
+ return json(401, { ok: false, code: "timestamp_out_of_range", error: "x-timestamp valt buiten de marge van 5 minuten." });
36
+ let secret;
37
+ try {
38
+ const { getFloridayGatewaySecret } = await import("../centralSecrets.server");
39
+ secret = await getFloridayGatewaySecret();
40
+ }
41
+ catch {
42
+ return json(401, { ok: false, code: "gateway_not_configured", error: "Ondertekeningsgeheim niet beschikbaar; niets verstuurd." });
43
+ }
44
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
45
+ const expected = hex(await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`${ts}.${rawBody}`)));
46
+ if (!sig || !safeEqual(sig, expected))
47
+ return json(401, { ok: false, code: "invalid_signature", error: "Handtekening klopt niet." });
48
+ let parsed;
49
+ try {
50
+ const r = bodySchema.safeParse(JSON.parse(rawBody));
51
+ if (!r.success)
52
+ return json(400, { ok: false, code: "invalid_body", error: "Body moet {\"orderId\":\"<uuid>\"} zijn." });
53
+ parsed = r.data;
54
+ }
55
+ catch {
56
+ return json(400, { ok: false, code: "invalid_body", error: "Body is geen geldige JSON." });
57
+ }
58
+ const orderId = parsed.orderId;
59
+ if (request.headers.get("idempotency-key")?.trim() !== `auto-send:${orderId}`)
60
+ return json(400, { ok: false, code: "invalid_idempotency_key", error: "idempotency-key moet auto-send:<orderId> zijn." });
61
+ try {
62
+ let sbClient = admin ?? null;
63
+ if (!sbClient) {
64
+ try {
65
+ sbClient = (await import("../../integrations/supabase/client.server")).supabaseAdmin;
66
+ }
67
+ catch {
68
+ sbClient = null;
69
+ }
70
+ }
71
+ if (!sbClient)
72
+ return json(401, { ok: false, code: "gateway_not_configured", error: "Databaseverbinding niet beschikbaar; niets verstuurd." });
73
+ return await processOrder(orderId, sbClient);
74
+ }
75
+ catch (e) {
76
+ const msg = e instanceof Error ? e.message : String(e);
77
+ return json(500, { ok: false, code: "internal_error", error: msg || "Onverwachte fout tijdens versturen." });
78
+ }
79
+ }
80
+ async function processOrder(orderId, sb) {
81
+ const { data: order, error: oErr } = await sb.from("orders")
82
+ .select("id, order_number, custom_fields").eq("id", orderId).is("deleted_at", null).maybeSingle();
83
+ if (oErr)
84
+ return json(500, { ok: false, code: "lookup_failed", error: `Order kon niet worden opgezocht: ${oErr.message}` });
85
+ if (!order)
86
+ return json(422, { ok: false, code: "not_floriday", error: "Order niet gevonden." });
87
+ const cf = order.custom_fields ?? {};
88
+ const salesOrderId = typeof cf.floriday_sales_order_id === "string" ? cf.floriday_sales_order_id
89
+ : typeof cf.salesOrderId === "string" ? cf.salesOrderId : null;
90
+ if (!salesOrderId)
91
+ return json(422, { ok: false, code: "not_floriday", error: "Order heeft geen Floriday-id." });
92
+ const { ACCEPTED, prepareLoadingServer, runLoadingSend } = await import("../floridayLoading.functions");
93
+ const ref = order.order_number ?? order.id;
94
+ const already = async () => {
95
+ if (cf.floriday_fulfilled === true)
96
+ return true;
97
+ const { data } = await sb.from("floriday_loading_attempts").select("code")
98
+ .eq("step", "send").contains("order_refs", [ref]).in("code", [...ACCEPTED]).limit(1);
99
+ return Array.isArray(data) && data.length > 0;
100
+ };
101
+ if (await already())
102
+ return json(200, { ok: true, code: "already_sent" });
103
+ let p;
104
+ try {
105
+ p = await prepareLoadingServer(sb, ref);
106
+ }
107
+ catch (e) {
108
+ return json(409, { ok: false, code: "not_ready", error: e instanceof Error ? e.message : String(e) });
109
+ }
110
+ if (p.bufferIncomplete) {
111
+ const b = p.bufferIncomplete;
112
+ return json(409, { ok: false, code: "buffer_incomplete", error: `${b.scanned} van ${b.total} karren gescand; ontbrekend: ${b.missingCartIds.join(", ")}` });
113
+ }
114
+ if (!p.canSend)
115
+ return json(409, { ok: false, code: "not_ready", error: p.blockers.join(" ") || "Geen opdracht." });
116
+ const res = await runLoadingSend(sb, p, { userId: null, source: "auto-send" });
117
+ if (res.ok) {
118
+ const allAlready = res.results.every((r) => r.code === "already_fulfilled");
119
+ return json(200, { ok: true, code: allAlready ? "already_sent" : "sent", results: res.results });
120
+ }
121
+ const fail = res.results.find((r) => !ACCEPTED.has(r.code));
122
+ return json(502, { ok: false, code: "floriday_rejected", error: fail?.message ?? "Floriday weigert de opdracht.", results: res.results });
123
+ }
@@ -2,4 +2,5 @@ export { handlePickstationOrders } from "./pickstationOrders.handler";
2
2
  export { handlePickstationPrint } from "./pickstationPrint.handler";
3
3
  export { handlePickstationStatus } from "./pickstationStatus.handler";
4
4
  export { handleDispatchCarrierSignups } from "./dispatchCarrierSignups.handler";
5
+ export { handleAutoSend } from "./autoSend.handler";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/serverRoutes/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/serverRoutes/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
@@ -5,3 +5,4 @@ export { handlePickstationOrders } from "./pickstationOrders.handler";
5
5
  export { handlePickstationPrint } from "./pickstationPrint.handler";
6
6
  export { handlePickstationStatus } from "./pickstationStatus.handler";
7
7
  export { handleDispatchCarrierSignups } from "./dispatchCarrierSignups.handler";
8
+ export { handleAutoSend } from "./autoSend.handler";
@@ -1 +1 @@
1
- {"version":3,"file":"moduleDefinition.d.ts","sourceRoot":"","sources":["../src/moduleDefinition.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAgBvD,eAAO,MAAM,yBAAyB,EAAE,UAqBvC,CAAC"}
1
+ {"version":3,"file":"moduleDefinition.d.ts","sourceRoot":"","sources":["../src/moduleDefinition.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAgBvD,eAAO,MAAM,yBAAyB,EAAE,UAuBvC,CAAC"}
@@ -23,9 +23,12 @@ export const floridayAfhandelingModule = {
23
23
  const info = getPickMode();
24
24
  if (info.showCartControl)
25
25
  return [...baseChildren, cartControlChild];
26
- if (info.status !== "ok") {
27
- return [...baseChildren, { ...cartControlChild, label: "Controle karren (onbekend)" }];
26
+ if (info.status !== "ok" && info.lastError) {
27
+ return [...baseChildren, { ...cartControlChild, label: "Controle karren (werkwijze niet bereikbaar)" }];
28
28
  }
29
+ // Werkwijze wordt nog opgehaald: zonder toevoeging tonen.
30
+ if (info.status !== "ok")
31
+ return [...baseChildren, cartControlChild];
29
32
  return baseChildren;
30
33
  },
31
34
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/floriday-afhandeling-module",
3
- "version": "1.0.58",
3
+ "version": "1.0.63",
4
4
  "private": false,
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -53,7 +53,7 @@
53
53
  "@rsbuild/core": "^1.0.0",
54
54
  "@tailwindcss/vite": "^4.2.1",
55
55
  "@tanstack/react-query": "^5.83.0",
56
- "@tanstack/router-plugin": "^1.167.10",
56
+ "@tanstack/router-plugin": "1.167.33",
57
57
  "@types/node": "^22.16.5",
58
58
  "@types/react": "^19.2.0",
59
59
  "@types/react-dom": "^19.2.0",
@@ -75,6 +75,17 @@
75
75
  },
76
76
  "flowselections": {
77
77
  "moduleId": "Afhandeling",
78
+ "serverRoutes": [
79
+ {
80
+ "routePath": "/api/public/hooks/afhandeling-auto-send",
81
+ "import": "@flowselections/floriday-afhandeling-module/server-routes",
82
+ "handler": "handleAutoSend",
83
+ "methods": [
84
+ "POST",
85
+ "OPTIONS"
86
+ ]
87
+ }
88
+ ],
78
89
  "pages": [
79
90
  {
80
91
  "export": "LeveringenPage",