@flowselections/floriday-klanten-module 1.0.36 → 1.0.37

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 (67) hide show
  1. package/dist-lib/components/klanten/BulkStickerUploadDialog.d.ts.map +1 -1
  2. package/dist-lib/components/klanten/BulkStickerUploadDialog.js +30 -8
  3. package/dist-lib/components/klanten/CustomerAssortmentTab.d.ts.map +1 -1
  4. package/dist-lib/components/klanten/CustomerAssortmentTab.js +48 -10
  5. package/dist-lib/integrations/supabase/auth-middleware.d.ts +129 -0
  6. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  7. package/dist-lib/integrations/supabase/client.d.ts +129 -0
  8. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  9. package/dist-lib/integrations/supabase/client.server.d.ts +129 -0
  10. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  11. package/dist-lib/integrations/supabase/types.d.ts +129 -0
  12. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  13. package/dist-lib/lib/accounting/twinfield/client.server.d.ts +7 -8
  14. package/dist-lib/lib/accounting/twinfield/client.server.d.ts.map +1 -1
  15. package/dist-lib/lib/accounting/twinfield/client.server.js +147 -78
  16. package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts +387 -0
  17. package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts.map +1 -1
  18. package/dist-lib/lib/accounting/twinfield/worker.server.d.ts.map +1 -1
  19. package/dist-lib/lib/accounting/twinfield/worker.server.js +17 -0
  20. package/dist-lib/lib/accounting.functions.d.ts +387 -0
  21. package/dist-lib/lib/accounting.functions.d.ts.map +1 -1
  22. package/dist-lib/lib/customer-analytics.functions.d.ts +129 -0
  23. package/dist-lib/lib/customer-analytics.functions.d.ts.map +1 -1
  24. package/dist-lib/lib/customer-assortment.functions.d.ts +132 -3
  25. package/dist-lib/lib/customer-assortment.functions.d.ts.map +1 -1
  26. package/dist-lib/lib/customer-assortment.functions.js +12 -0
  27. package/dist-lib/lib/customer-notes.functions.d.ts +258 -0
  28. package/dist-lib/lib/customer-notes.functions.d.ts.map +1 -1
  29. package/dist-lib/lib/customer-revenue.functions.d.ts +129 -0
  30. package/dist-lib/lib/customer-revenue.functions.d.ts.map +1 -1
  31. package/dist-lib/lib/customer-stickers.functions.d.ts +1165 -0
  32. package/dist-lib/lib/customer-stickers.functions.d.ts.map +1 -1
  33. package/dist-lib/lib/customer-stickers.functions.js +122 -75
  34. package/dist-lib/lib/customers.functions.d.ts +1161 -0
  35. package/dist-lib/lib/customers.functions.d.ts.map +1 -1
  36. package/dist-lib/lib/delivery-locations.functions.d.ts +645 -0
  37. package/dist-lib/lib/delivery-locations.functions.d.ts.map +1 -1
  38. package/dist-lib/lib/external-customers.functions.d.ts +516 -0
  39. package/dist-lib/lib/external-customers.functions.d.ts.map +1 -1
  40. package/dist-lib/lib/floriday-assortment.functions.d.ts +129 -0
  41. package/dist-lib/lib/floriday-assortment.functions.d.ts.map +1 -1
  42. package/dist-lib/lib/floriday-discounts.functions.d.ts +258 -0
  43. package/dist-lib/lib/floriday-discounts.functions.d.ts.map +1 -1
  44. package/dist-lib/lib/floriday-price-import.functions.d.ts +258 -0
  45. package/dist-lib/lib/floriday-price-import.functions.d.ts.map +1 -1
  46. package/dist-lib/lib/floriday-sticker-import.functions.d.ts +27323 -0
  47. package/dist-lib/lib/floriday-sticker-import.functions.d.ts.map +1 -0
  48. package/dist-lib/lib/floriday-sticker-import.functions.js +307 -0
  49. package/dist-lib/lib/floriday-trade-items.functions.d.ts +129 -0
  50. package/dist-lib/lib/floriday-trade-items.functions.d.ts.map +1 -1
  51. package/dist-lib/lib/local-discounts.functions.d.ts +903 -0
  52. package/dist-lib/lib/local-discounts.functions.d.ts.map +1 -1
  53. package/dist-lib/lib/logistics-events.functions.d.ts +129 -0
  54. package/dist-lib/lib/logistics-events.functions.d.ts.map +1 -1
  55. package/dist-lib/lib/logistics-strategy.functions.d.ts +516 -0
  56. package/dist-lib/lib/logistics-strategy.functions.d.ts.map +1 -1
  57. package/dist-lib/lib/overdue-invoices.functions.d.ts +129 -0
  58. package/dist-lib/lib/overdue-invoices.functions.d.ts.map +1 -1
  59. package/dist-lib/lib/price-groups-local.functions.d.ts +1677 -0
  60. package/dist-lib/lib/price-groups-local.functions.d.ts.map +1 -1
  61. package/dist-lib/lib/price-groups.functions.d.ts +129 -0
  62. package/dist-lib/lib/price-groups.functions.d.ts.map +1 -1
  63. package/dist-lib/lib/twinfield-adopt.functions.d.ts +258 -0
  64. package/dist-lib/lib/twinfield-adopt.functions.d.ts.map +1 -1
  65. package/dist-lib/lib/twinfield-ledger.functions.d.ts +129 -0
  66. package/dist-lib/lib/twinfield-ledger.functions.d.ts.map +1 -1
  67. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"BulkStickerUploadDialog.d.ts","sourceRoot":"","sources":["../../../src/components/klanten/BulkStickerUploadDialog.tsx"],"names":[],"mappings":"AA2BA,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAiDF,wBAAgB,uBAAuB,CAAC,EACtC,WAAW,EACX,QAAQ,EACR,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BAoYA"}
1
+ {"version":3,"file":"BulkStickerUploadDialog.d.ts","sourceRoot":"","sources":["../../../src/components/klanten/BulkStickerUploadDialog.tsx"],"names":[],"mappings":"AA2BA,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAiDF,wBAAgB,uBAAuB,CAAC,EACtC,WAAW,EACX,QAAQ,EACR,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BA0cA"}
@@ -28,7 +28,7 @@ async function makeThumbnail(file) {
28
28
  el.onerror = reject;
29
29
  el.src = url;
30
30
  });
31
- const max = 512;
31
+ const max = 1024;
32
32
  const scale = Math.min(1, max / Math.max(img.width || max, img.height || max));
33
33
  const canvas = document.createElement("canvas");
34
34
  canvas.width = Math.max(1, Math.round((img.width || max) * scale));
@@ -40,7 +40,7 @@ async function makeThumbnail(file) {
40
40
  ctx.fillRect(0, 0, canvas.width, canvas.height);
41
41
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
42
42
  URL.revokeObjectURL(url);
43
- return canvas.toDataURL("image/jpeg", 0.7);
43
+ return canvas.toDataURL("image/jpeg", 0.85);
44
44
  }
45
45
  catch {
46
46
  return null;
@@ -52,6 +52,7 @@ export function BulkStickerUploadDialog({ customerKey, products, onDone, }) {
52
52
  const [rows, setRows] = useState([]);
53
53
  const [phase, setPhase] = useState("idle");
54
54
  const [progress, setProgress] = useState({ done: 0, total: 0 });
55
+ const [previewRow, setPreviewRow] = useState(null);
55
56
  const folderRef = useRef(null);
56
57
  const filesRef = useRef(null);
57
58
  const suggest = useServerFn(suggestStickerMatches);
@@ -59,7 +60,7 @@ export function BulkStickerUploadDialog({ customerKey, products, onDone, }) {
59
60
  const discard = useServerFn(discardStickerBatch);
60
61
  const productOptions = useMemo(() => products.map((p) => ({
61
62
  value: p.key,
62
- label: p.name,
63
+ label: (_jsxs("span", { className: "flex min-w-0 flex-col leading-tight", children: [_jsx("span", { className: "truncate", children: p.name }), p.code && (_jsx("span", { className: "truncate text-xs text-muted-foreground", children: p.code }))] })),
63
64
  search: [p.name, p.code, p.vbn, p.botanical].filter(Boolean).join(" "),
64
65
  })), [products]);
65
66
  const productByKey = useMemo(() => new Map(products.map((p) => [p.key, p])), [products]);
@@ -92,6 +93,7 @@ export function BulkStickerUploadDialog({ customerKey, products, onDone, }) {
92
93
  setBatchId(id);
93
94
  setPhase("uploading");
94
95
  setProgress({ done: 0, total: files.length });
96
+ setOpen(false);
95
97
  const staged = [];
96
98
  for (const file of files) {
97
99
  const fileId = crypto.randomUUID();
@@ -141,11 +143,21 @@ export function BulkStickerUploadDialog({ customerKey, products, onDone, }) {
141
143
  })),
142
144
  },
143
145
  });
146
+ if (res.aiError)
147
+ toast.warning(res.aiError);
144
148
  const byId = new Map(res.suggestions.map((s) => [s.fileId, s]));
145
149
  setRows((prev) => prev.map((r) => {
146
150
  const s = byId.get(r.fileId);
147
151
  return s
148
- ? { ...r, tradeItemKey: s.tradeItemKey, confidence: s.confidence, reason: s.reason }
152
+ ? {
153
+ ...r,
154
+ tradeItemKey: s.tradeItemKey,
155
+ confidence: s.confidence,
156
+ reason: s.reason,
157
+ replaceExisting: s.tradeItemKey
158
+ ? (productByKey.get(s.tradeItemKey)?.hasSticker ?? false)
159
+ : false,
160
+ }
149
161
  : r;
150
162
  }));
151
163
  }
@@ -212,20 +224,30 @@ export function BulkStickerUploadDialog({ customerKey, products, onDone, }) {
212
224
  } }), _jsx("input", { ref: filesRef, type: "file", className: "hidden", multiple: true, accept: ACCEPT, onChange: (e) => {
213
225
  void handleFiles(e.target.files);
214
226
  e.target.value = "";
215
- } }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(true), children: [_jsx(Upload, { className: "h-4 w-4 mr-1.5" }), "Stickers in bulk"] }), _jsx(Dialog, { open: open, onOpenChange: (v) => (v ? setOpen(true) : void close(true)), children: _jsxs(DialogContent, { className: "max-w-5xl", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Stickers in bulk uploaden" }) }), phase === "idle" && (_jsxs("div", { className: "rounded-lg border border-dashed p-10 text-center", onDragOver: (e) => e.preventDefault(), onDrop: (e) => {
227
+ } }), phase === "uploading" || phase === "matching" ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", disabled: true, children: [_jsx(Loader2, { className: "h-4 w-4 mr-1.5 animate-spin" }), phase === "uploading"
228
+ ? `Stickers laden… ${progress.done}/${progress.total}`
229
+ : "AI koppelt stickers…"] })) : phase === "review" || phase === "saving" ? (_jsxs(Button, { type: "button", size: "sm", className: "bg-green-600 text-white hover:bg-green-700", onClick: () => setOpen(true), children: [_jsx(Sparkles, { className: "h-4 w-4 mr-1.5" }), "Keuren (", rows.filter((r) => r.tradeItemKey).length, ")"] })) : (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(true), children: [_jsx(Upload, { className: "h-4 w-4 mr-1.5" }), "Stickers in bulk"] })), _jsx(Dialog, { open: open, onOpenChange: (v) => (v ? setOpen(true) : void close(true)), children: _jsxs(DialogContent, { className: "max-w-6xl", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Stickers in bulk uploaden" }) }), phase === "idle" && (_jsxs("div", { className: "rounded-lg border border-dashed p-10 text-center", onDragOver: (e) => e.preventDefault(), onDrop: (e) => {
216
230
  e.preventDefault();
217
231
  void handleFiles(e.dataTransfer.files);
218
232
  }, children: [_jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Sleep een map of losse stickerbestanden hierheen (PDF, PNG, JPG of SVG, max. 10 MB per bestand)." }), _jsxs("div", { className: "flex justify-center gap-2", children: [_jsxs(Button, { type: "button", onClick: () => folderRef.current?.click(), children: [_jsx(FolderOpen, { className: "h-4 w-4 mr-1.5" }), "Map kiezen"] }), _jsx(Button, { type: "button", variant: "outline", onClick: () => filesRef.current?.click(), children: "Bestanden kiezen" })] })] })), (phase === "uploading" || phase === "matching") && (_jsxs("div", { className: "flex items-center gap-3 p-10 justify-center text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), phase === "uploading"
219
233
  ? `Bestanden uploaden… ${progress.done}/${progress.total}`
220
- : "AI zoekt bij elke sticker het juiste product…"] })), (phase === "review" || phase === "saving") && (_jsx("div", { className: "max-h-[60vh] overflow-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "sticky top-0 bg-background", children: _jsxs("tr", { className: "border-b text-left", children: [_jsx("th", { className: "py-2 w-16", children: "Sticker" }), _jsx("th", { className: "py-2", children: "Bestand" }), _jsx("th", { className: "py-2 w-[260px]", children: "Product" }), _jsx("th", { className: "py-2 w-32", children: "Zekerheid" }), _jsx("th", { className: "py-2 w-40", children: "Bestaand" }), _jsx("th", { className: "py-2 w-10" })] }) }), _jsx("tbody", { children: rows.map((r) => {
234
+ : "AI zoekt bij elke sticker het juiste product…"] })), (phase === "review" || phase === "saving") && (_jsx("div", { className: "max-h-[60vh] overflow-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "sticky top-0 bg-background", children: _jsxs("tr", { className: "border-b text-left", children: [_jsx("th", { className: "py-2 w-56", children: "Sticker" }), _jsx("th", { className: "py-2", children: "Bestand" }), _jsx("th", { className: "py-2 w-[340px]", children: "Product" }), _jsx("th", { className: "py-2 w-32", children: "Zekerheid" }), _jsx("th", { className: "py-2 w-40", children: "Bestaand" }), _jsx("th", { className: "py-2 w-10" })] }) }), _jsx("tbody", { children: rows.map((r) => {
221
235
  const product = r.tradeItemKey ? productByKey.get(r.tradeItemKey) : null;
222
236
  const dup = r.tradeItemKey ? duplicates.has(r.tradeItemKey) : false;
223
- return (_jsxs("tr", { className: "border-b align-middle", children: [_jsx("td", { className: "py-2", children: r.thumbnail ? (_jsx("img", { src: r.thumbnail, alt: "", className: "h-10 w-10 rounded border object-contain bg-muted" })) : (_jsx("div", { className: "h-10 w-10 rounded border bg-muted flex items-center justify-center", children: _jsx(FileText, { className: "h-4 w-4 text-muted-foreground" }) })) }), _jsxs("td", { className: "py-2 pr-3", children: [_jsx("div", { className: "truncate max-w-[220px]", title: r.fileName, children: r.fileName }), r.reason && (_jsx("div", { className: "text-xs text-muted-foreground truncate max-w-[220px]", children: r.reason }))] }), _jsxs("td", { className: "py-2 pr-3", children: [_jsx(SearchableSelect, { value: r.tradeItemKey ?? "", options: productOptions, placeholder: "Kies product\u2026", onValueChange: (v) => setRows((prev) => prev.map((x) => x.fileId === r.fileId ? { ...x, tradeItemKey: v || null } : x)) }), dup && (_jsx("div", { className: "text-xs text-destructive mt-1", children: "Meerdere stickers voor dit product" }))] }), _jsx("td", { className: "py-2", children: r.tradeItemKey ? (_jsx(Badge, { variant: r.confidence >= 0.8
237
+ return (_jsxs("tr", { className: "border-b align-middle", children: [_jsx("td", { className: "py-2", children: r.thumbnail ? (_jsx("button", { type: "button", className: "block cursor-zoom-in", title: "Klik om te vergroten", onClick: () => setPreviewRow(r), children: _jsx("img", { src: r.thumbnail, alt: r.fileName, className: "h-44 w-44 rounded border object-contain bg-white hover:ring-2 hover:ring-primary/50" }) })) : (_jsx("div", { className: "h-44 w-44 rounded border bg-muted flex items-center justify-center", children: _jsx(FileText, { className: "h-6 w-6 text-muted-foreground" }) })) }), _jsxs("td", { className: "py-2 pr-3", children: [_jsx("div", { className: "truncate max-w-[220px]", title: r.fileName, children: r.fileName }), r.reason && (_jsx("div", { className: "text-xs text-muted-foreground truncate max-w-[220px]", children: r.reason }))] }), _jsxs("td", { className: "py-2 pr-3", children: [_jsx(SearchableSelect, { value: r.tradeItemKey ?? "", options: productOptions, placeholder: "Kies product\u2026", triggerClassName: "w-full", onValueChange: (v) => setRows((prev) => prev.map((x) => x.fileId === r.fileId
238
+ ? {
239
+ ...x,
240
+ tradeItemKey: v || null,
241
+ replaceExisting: v
242
+ ? (productByKey.get(v)?.hasSticker ?? false)
243
+ : false,
244
+ }
245
+ : x)) }), dup && (_jsx("div", { className: "text-xs text-destructive mt-1", children: "Meerdere stickers voor dit product" }))] }), _jsx("td", { className: "py-2", children: r.tradeItemKey ? (_jsx(Badge, { variant: r.confidence >= 0.8
224
246
  ? "default"
225
247
  : r.confidence >= 0.5
226
248
  ? "secondary"
227
249
  : "outline", children: r.confidence >= 0.8 ? "Hoog" : r.confidence >= 0.5 ? "Middel" : "Laag" })) : (_jsx(Badge, { variant: "outline", children: "Geen match" })) }), _jsx("td", { className: "py-2", children: product?.hasSticker ? (_jsxs("label", { className: "flex items-center gap-2 text-xs", children: [_jsx("input", { type: "checkbox", checked: r.replaceExisting, onChange: (e) => setRows((prev) => prev.map((x) => x.fileId === r.fileId
228
250
  ? { ...x, replaceExisting: e.target.checked }
229
251
  : x)) }), "Vervangen"] })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" })) }), _jsx("td", { className: "py-2", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => setRows((prev) => prev.filter((x) => x.fileId !== r.fileId)), children: _jsx(Trash2, { className: "h-4 w-4" }) }) })] }, r.fileId));
230
- }) })] }) })), _jsxs(DialogFooter, { className: "gap-2 sm:justify-between", children: [_jsx("span", { className: "text-xs text-muted-foreground flex items-center gap-1.5", children: phase === "review" && (_jsxs(_Fragment, { children: [_jsx(Sparkles, { className: "h-3.5 w-3.5" }), rows.filter((r) => r.tradeItemKey).length, " van ", rows.length, " gekoppeld"] })) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { type: "button", variant: "outline", disabled: busy, onClick: () => void close(true), children: "Annuleren" }), (phase === "review" || phase === "saving") && (_jsxs(Button, { type: "button", disabled: busy, onClick: () => void save(), children: [phase === "saving" && _jsx(Loader2, { className: "h-4 w-4 mr-1.5 animate-spin" }), "Bevestigen en opslaan"] }))] })] })] }) })] }));
252
+ }) })] }) })), _jsxs(DialogFooter, { className: "gap-2 sm:justify-between", children: [_jsx("span", { className: "text-xs text-muted-foreground flex items-center gap-1.5", children: phase === "review" && (_jsxs(_Fragment, { children: [_jsx(Sparkles, { className: "h-3.5 w-3.5" }), rows.filter((r) => r.tradeItemKey).length, " van ", rows.length, " gekoppeld"] })) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { type: "button", variant: "outline", disabled: busy, onClick: () => void close(true), children: "Annuleren" }), (phase === "review" || phase === "saving") && (_jsxs(Button, { type: "button", disabled: busy, onClick: () => void save(), children: [phase === "saving" && _jsx(Loader2, { className: "h-4 w-4 mr-1.5 animate-spin" }), "Bevestigen en opslaan"] }))] })] })] }) }), _jsx(Dialog, { open: previewRow !== null, onOpenChange: (v) => !v && setPreviewRow(null), children: _jsxs(DialogContent, { className: "max-w-5xl", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: previewRow?.fileName ?? "Sticker" }) }), previewRow?.thumbnail && (_jsx("div", { className: "flex items-center justify-center rounded border bg-white p-2", children: _jsx("img", { src: previewRow.thumbnail, alt: previewRow.fileName, className: "max-h-[70vh] w-auto max-w-full object-contain" }) }))] }) })] }));
231
253
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CustomerAssortmentTab.d.ts","sourceRoot":"","sources":["../../../src/components/klanten/CustomerAssortmentTab.tsx"],"names":[],"mappings":"AA0BA,wBAAgB,qBAAqB,CAAC,EACpC,WAAW,EACX,cAAc,GACf,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,+BAmQA"}
1
+ {"version":3,"file":"CustomerAssortmentTab.d.ts","sourceRoot":"","sources":["../../../src/components/klanten/CustomerAssortmentTab.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,qBAAqB,CAAC,EACpC,WAAW,EACX,cAAc,GACf,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,+BA6VA"}
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from "react";
3
- import { useQuery, useQueryClient } from "@tanstack/react-query";
3
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
4
  import { useServerFn } from "@tanstack/react-start";
5
- import { Card, CardContent, Badge, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
6
- import { Search, ImageOff } from "lucide-react";
5
+ import { Card, CardContent, Badge, Input, Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
6
+ import { Search, ImageOff, RefreshCw } from "lucide-react";
7
+ import { toast } from "sonner";
7
8
  import { listCustomerAssortment } from "../../lib/customer-assortment.functions";
8
9
  import { listCustomerStickers } from "../../lib/customer-stickers.functions";
10
+ import { importFloridayStickers } from "../../lib/floriday-sticker-import.functions";
9
11
  import { decodeDeep } from "../../lib/decode-html";
10
12
  import { friendlyError } from "../../lib/errors";
11
13
  import { FloridayPriceImportDialog } from "./FloridayPriceImportDialog";
@@ -25,10 +27,12 @@ function money(value, currency) {
25
27
  export function CustomerAssortmentTab({ customerKey, organizationId, }) {
26
28
  const list = useServerFn(listCustomerAssortment);
27
29
  const listStickers = useServerFn(listCustomerStickers);
30
+ const importStickers = useServerFn(importFloridayStickers);
28
31
  const qc = useQueryClient();
29
32
  const [search, setSearch] = useState("");
30
33
  const [onlyPriced, setOnlyPriced] = useState(false);
31
34
  const [onlyWithoutSticker, setOnlyWithoutSticker] = useState(false);
35
+ const [group, setGroup] = useState("own");
32
36
  const { data, isLoading, error } = useQuery({
33
37
  queryKey: ["customer-assortment", customerKey, organizationId ?? null],
34
38
  queryFn: () => list({ data: { customerKey, organizationId: organizationId ?? null } }).then(decodeDeep),
@@ -47,9 +51,30 @@ export function CustomerAssortmentTab({ customerKey, organizationId, }) {
47
51
  return m;
48
52
  }, [stickerData]);
49
53
  const items = data?.items ?? [];
54
+ const ownCount = items.filter((i) => i.in_assortment).length;
55
+ const otherCount = items.length - ownCount;
56
+ const hasOwnAssortment = ownCount > 0;
57
+ const activeGroup = hasOwnAssortment ? group : "other";
58
+ const floridayImport = useMutation({
59
+ mutationFn: () => importStickers({ data: { customerKey, organizationId: organizationId ?? null } }),
60
+ onSuccess: (r) => {
61
+ qc.invalidateQueries({ queryKey: ["customer-stickers", customerKey] });
62
+ qc.invalidateQueries({ queryKey: ["customer-assortment", customerKey] });
63
+ if (r.created || r.updated) {
64
+ toast.success(`${r.created} nieuw, ${r.updated} bijgewerkt, ${r.unchanged} ongewijzigd` +
65
+ (r.skippedManual ? ` · ${r.skippedManual} handmatige stickers behouden` : ""));
66
+ }
67
+ else {
68
+ toast.info(r.message ?? "Geen nieuwe stickers gevonden in Floriday.");
69
+ }
70
+ },
71
+ onError: (e) => toast.error(friendlyError(e, "Ophalen uit Floriday mislukt")),
72
+ });
50
73
  const filtered = useMemo(() => {
51
74
  const q = search.trim().toLowerCase();
52
75
  return items.filter((i) => {
76
+ if (hasOwnAssortment && (activeGroup === "own" ? !i.in_assortment : i.in_assortment))
77
+ return false;
53
78
  if (onlyPriced && i.price == null)
54
79
  return false;
55
80
  if (onlyWithoutSticker && stickerMap.has(i.key))
@@ -61,7 +86,7 @@ export function CustomerAssortmentTab({ customerKey, organizationId, }) {
61
86
  (i.vbn_code ?? "").toLowerCase().includes(q) ||
62
87
  (i.botanical_name ?? "").toLowerCase().includes(q));
63
88
  });
64
- }, [items, search, onlyPriced, onlyWithoutSticker, stickerMap]);
89
+ }, [items, search, onlyPriced, onlyWithoutSticker, stickerMap, activeGroup, hasOwnAssortment]);
65
90
  if (isLoading) {
66
91
  return (_jsx(Card, { children: _jsx(CardContent, { className: "py-8 text-sm text-muted-foreground", children: "Assortiment laden\u2026" }) }));
67
92
  }
@@ -70,37 +95,50 @@ export function CustomerAssortmentTab({ customerKey, organizationId, }) {
70
95
  }
71
96
  const pg = data?.priceGroup ?? null;
72
97
  const currency = pg?.currency ?? "EUR";
98
+ const defaultFormat = stickerData?.format ?? null;
73
99
  if (items.length === 0) {
74
100
  return (_jsx(Card, { children: _jsxs(CardContent, { className: "py-10 text-center space-y-1", children: [_jsx("p", { className: "text-sm font-medium", children: "Nog geen assortiment beschikbaar" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Er staan nog geen handelsartikelen uit Floriday klaar voor deze klant." })] }) }));
75
101
  }
76
102
  return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground", children: [_jsxs("span", { children: [_jsx("strong", { className: "text-foreground", children: data?.summary.total ?? 0 }), " artikelen"] }), _jsxs("span", { children: [_jsx("strong", { className: "text-foreground", children: data?.summary.priced ?? 0 }), " met prijs"] }), pg ? (_jsxs("span", { children: ["Prijsgroep: ", _jsx("strong", { className: "text-foreground", children: pg.name }), pg.pricing_mode === "calculated" && pg.calc_value
77
103
  ? ` (${pg.calc_type === "surcharge" ? "toeslag" : "korting"} ${pg.calc_value}${pg.calc_value_type === "percentage" ? "%" : ` ${currency}`})`
78
- : ""] })) : (_jsx("span", { className: "text-amber-600", children: "Geen prijsgroep ingesteld voor deze klant" })), data?.summary.last_synced_at && (_jsxs("span", { children: ["laatste sync: ", new Date(data.summary.last_synced_at).toLocaleString("nl-NL")] }))] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-muted-foreground", children: [_jsxs("span", { children: ["Stickerformaat:", " ", _jsx("strong", { className: "text-foreground", children: stickerData?.format
79
- ? `${stickerData.format.width_mm} × ${stickerData.format.height_mm} mm`
80
- : "nog niet ingesteld" })] }), _jsx(CustomerStickerFormatDialog, { customerKey: customerKey, format: stickerData?.format ?? null }), _jsxs("span", { children: [_jsx("strong", { className: "text-foreground", children: stickerMap.size }), " artikelen met sticker"] }), _jsx(BulkStickerUploadDialog, { customerKey: customerKey, products: items.map((i) => ({
104
+ : ""] })) : (_jsx("span", { className: "text-amber-600", children: "Geen prijsgroep ingesteld voor deze klant" })), data?.summary.last_synced_at && (_jsxs("span", { children: ["laatste sync: ", new Date(data.summary.last_synced_at).toLocaleString("nl-NL")] }))] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-muted-foreground", children: [_jsxs("span", { children: ["Stickerformaat:", " ", _jsx("strong", { className: "text-foreground", children: defaultFormat
105
+ ? `${defaultFormat.width_mm} × ${defaultFormat.height_mm} mm`
106
+ : "nog niet ingesteld" })] }), _jsx(CustomerStickerFormatDialog, { customerKey: customerKey, format: defaultFormat }), _jsxs("span", { children: [_jsx("strong", { className: "text-foreground", children: stickerMap.size }), " artikelen met sticker"] }), _jsx(BulkStickerUploadDialog, { customerKey: customerKey, products: items.map((i) => ({
81
107
  key: i.key,
82
108
  name: i.name,
83
109
  code: i.supplier_article_code,
84
110
  vbn: i.vbn_code,
85
111
  botanical: i.botanical_name,
86
112
  hasSticker: stickerMap.has(i.key),
87
- })), onDone: () => qc.invalidateQueries({ queryKey: ["customer-stickers", customerKey] }) })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative flex-1 min-w-[240px] max-w-md", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), _jsx(Input, { placeholder: "Zoek op naam, artikelcode of VBN-code\u2026", value: search, onChange: (e) => setSearch(e.target.value), className: "pl-9" })] }), _jsx("button", { type: "button", onClick: () => setOnlyPriced((v) => !v), className: "inline-flex items-center rounded-full border px-3 py-1 text-xs transition-colors " +
113
+ })), onDone: () => qc.invalidateQueries({ queryKey: ["customer-stickers", customerKey] }) }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", disabled: floridayImport.isPending, onClick: () => floridayImport.mutate(), children: [_jsx(RefreshCw, { className: "h-4 w-4 mr-1.5 " + (floridayImport.isPending ? "animate-spin" : "") }), "Stickers ophalen uit Floriday"] })] }), hasOwnAssortment && (_jsx("div", { className: "flex flex-wrap items-center gap-2", children: _jsx("div", { className: "inline-flex rounded-lg border p-0.5", children: [
114
+ ["own", `Eigen assortiment (${ownCount})`],
115
+ ["other", `Overige producten (${otherCount})`],
116
+ ].map(([value, label]) => (_jsx("button", { type: "button", onClick: () => setGroup(value), className: "rounded-md px-3 py-1 text-xs transition-colors " +
117
+ (activeGroup === value
118
+ ? "bg-primary text-primary-foreground"
119
+ : "text-muted-foreground hover:bg-muted"), children: label }, value))) }) })), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative flex-1 min-w-[240px] max-w-md", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), _jsx(Input, { placeholder: "Zoek op naam, artikelcode of VBN-code\u2026", value: search, onChange: (e) => setSearch(e.target.value), className: "pl-9" })] }), _jsx("button", { type: "button", onClick: () => setOnlyPriced((v) => !v), className: "inline-flex items-center rounded-full border px-3 py-1 text-xs transition-colors " +
88
120
  (onlyPriced
89
121
  ? "bg-primary text-primary-foreground border-primary"
90
122
  : "bg-card text-muted-foreground border-border hover:bg-muted"), children: "Alleen met prijs" }), _jsx("button", { type: "button", onClick: () => setOnlyWithoutSticker((v) => !v), className: "inline-flex items-center rounded-full border px-3 py-1 text-xs transition-colors " +
91
123
  (onlyWithoutSticker
92
124
  ? "bg-primary text-primary-foreground border-primary"
93
- : "bg-card text-muted-foreground border-border hover:bg-muted"), children: "Alleen zonder sticker" }), _jsx("div", { className: "ml-auto", children: _jsx(FloridayPriceImportDialog, { customerKey: customerKey, organizationId: organizationId }) })] }), _jsx(Card, { children: _jsx(CardContent, { className: "p-0", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-[64px]" }), _jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { children: "Verpakking" }), _jsx(TableHead, { className: "text-right", children: "Basisprijs" }), _jsx(TableHead, { className: "text-right", children: "Prijs voor klant" }), _jsx(TableHead, { children: "Sticker" })] }) }), _jsx(TableBody, { children: filtered.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 6, className: "text-center py-6 text-muted-foreground text-sm", children: "Geen resultaten voor deze zoekopdracht." }) })) : filtered.map((i) => {
125
+ : "bg-card text-muted-foreground border-border hover:bg-muted"), children: "Alleen zonder sticker" }), _jsx("div", { className: "ml-auto", children: _jsx(FloridayPriceImportDialog, { customerKey: customerKey, organizationId: organizationId }) })] }), _jsx(Card, { children: _jsx(CardContent, { className: "p-0", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-[64px]" }), _jsx(TableHead, { children: "Artikel" }), hasOwnAssortment && _jsx(TableHead, { children: "Assortiment" }), _jsx(TableHead, { children: "Verpakking" }), _jsx(TableHead, { className: "text-right", children: "Basisprijs" }), _jsx(TableHead, { className: "text-right", children: "Prijs voor klant" }), _jsx(TableHead, { children: "Sticker" })] }) }), _jsx(TableBody, { children: filtered.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: hasOwnAssortment ? 7 : 6, className: "text-center py-6 text-muted-foreground text-sm", children: "Geen resultaten voor deze zoekopdracht." }) })) : filtered.map((i) => {
94
126
  const packing = [
95
127
  i.pieces_per_package != null ? `${i.pieces_per_package} per fust` : null,
96
128
  i.packages_per_layer != null ? `${i.packages_per_layer} per laag` : null,
97
129
  i.layers_per_carrier != null ? `${i.layers_per_carrier} lagen` : null,
98
130
  ].filter(Boolean);
131
+ const sticker = stickerMap.get(i.key) ?? null;
132
+ const fmt = sticker?.width_mm != null && sticker?.height_mm != null
133
+ ? `${sticker.width_mm} × ${sticker.height_mm} mm`
134
+ : defaultFormat
135
+ ? `${defaultFormat.width_mm} × ${defaultFormat.height_mm} mm`
136
+ : null;
99
137
  return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: i.image_url ? (_jsx("img", { src: i.image_url, alt: "", loading: "lazy", className: "h-10 w-10 rounded object-cover bg-muted" })) : (_jsx("div", { className: "h-10 w-10 rounded bg-muted flex items-center justify-center text-muted-foreground", children: _jsx(ImageOff, { className: "h-4 w-4" }) })) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "font-medium flex items-center gap-2", children: [i.name, i.restricted && (_jsx(Badge, { variant: "secondary", title: "Alleen voor deze klant beschikbaar", children: "Exclusief" })), i.floriday_source_label && (_jsx(Badge, { variant: i.floriday_source === "contract" ? "default" : "secondary", children: i.floriday_source_label }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [
100
138
  i.supplier_article_code,
101
139
  i.vbn_code ? `VBN ${i.vbn_code}` : null,
102
140
  i.botanical_name,
103
141
  i.country_of_origin,
104
- ].filter(Boolean).join(" · ") || "—" })] }), _jsxs(TableCell, { className: "text-sm text-muted-foreground", children: [_jsx("div", { children: i.packaging ?? "—" }), packing.length > 0 && (_jsx("div", { className: "text-xs", children: packing.join(" · ") }))] }), _jsx(TableCell, { className: "text-right whitespace-nowrap tabular-nums text-muted-foreground", children: money(i.base_price, i.currency) }), _jsxs(TableCell, { className: "text-right whitespace-nowrap tabular-nums", children: [_jsx("div", { className: "font-medium", children: money(i.price, i.currency) }), i.base_price_source && (_jsx("div", { className: "text-[10px] text-muted-foreground", children: i.base_price_source }))] }), _jsx(TableCell, { children: _jsx(CustomerStickerCell, { customerKey: customerKey, tradeItemKey: i.key, sticker: stickerMap.get(i.key) ?? null }) })] }, i.key));
142
+ ].filter(Boolean).join(" · ") || "—" })] }), hasOwnAssortment && (_jsx(TableCell, { children: i.in_assortment ? (_jsx(Badge, { children: "Eigen assortiment" })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: "Overig" })) })), _jsxs(TableCell, { className: "text-sm text-muted-foreground", children: [_jsx("div", { children: i.packaging ?? "—" }), packing.length > 0 && (_jsx("div", { className: "text-xs", children: packing.join(" · ") }))] }), _jsx(TableCell, { className: "text-right whitespace-nowrap tabular-nums text-muted-foreground", children: money(i.base_price, i.currency) }), _jsxs(TableCell, { className: "text-right whitespace-nowrap tabular-nums", children: [_jsx("div", { className: "font-medium", children: money(i.price, i.currency) }), i.base_price_source && (_jsx("div", { className: "text-[10px] text-muted-foreground", children: i.base_price_source }))] }), _jsx(TableCell, { children: _jsxs("div", { className: "space-y-1", children: [_jsx(CustomerStickerCell, { customerKey: customerKey, tradeItemKey: i.key, sticker: sticker }), sticker ? (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(Badge, { variant: sticker.source === "floriday" ? "default" : "secondary", children: sticker.source === "floriday" ? "Uit Floriday" : "Handmatig" }), fmt && _jsx("span", { children: fmt })] })) : (_jsx("div", { className: "text-[10px] text-muted-foreground", children: "Geen sticker" }))] }) })] }, i.key));
105
143
  }) })] }) }) })] }));
106
144
  }
@@ -1823,6 +1823,42 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
1823
1823
  };
1824
1824
  Relationships: [];
1825
1825
  };
1826
+ customer_assortment_items: {
1827
+ Row: {
1828
+ created_at: string;
1829
+ customer_key: string;
1830
+ id: string;
1831
+ in_assortment: boolean;
1832
+ manual_override: boolean;
1833
+ source: string;
1834
+ synced_at: string | null;
1835
+ trade_item_key: string;
1836
+ updated_at: string;
1837
+ };
1838
+ Insert: {
1839
+ created_at?: string;
1840
+ customer_key: string;
1841
+ id?: string;
1842
+ in_assortment?: boolean;
1843
+ manual_override?: boolean;
1844
+ source?: string;
1845
+ synced_at?: string | null;
1846
+ trade_item_key: string;
1847
+ updated_at?: string;
1848
+ };
1849
+ Update: {
1850
+ created_at?: string;
1851
+ customer_key?: string;
1852
+ id?: string;
1853
+ in_assortment?: boolean;
1854
+ manual_override?: boolean;
1855
+ source?: string;
1856
+ synced_at?: string | null;
1857
+ trade_item_key?: string;
1858
+ updated_at?: string;
1859
+ };
1860
+ Relationships: [];
1861
+ };
1826
1862
  customer_audit_log: {
1827
1863
  Row: {
1828
1864
  action: string;
@@ -2227,40 +2263,58 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
2227
2263
  };
2228
2264
  customer_product_stickers: {
2229
2265
  Row: {
2266
+ content_hash: string | null;
2230
2267
  created_at: string;
2231
2268
  customer_key: string;
2232
2269
  file_name: string;
2233
2270
  file_path: string;
2234
2271
  file_size: number | null;
2272
+ floriday_sticker_id: string | null;
2273
+ floriday_synced_at: string | null;
2274
+ height_mm: number | null;
2235
2275
  id: string;
2236
2276
  mime_type: string | null;
2277
+ source: string;
2237
2278
  trade_item_key: string;
2238
2279
  updated_at: string;
2239
2280
  uploaded_by: string | null;
2281
+ width_mm: number | null;
2240
2282
  };
2241
2283
  Insert: {
2284
+ content_hash?: string | null;
2242
2285
  created_at?: string;
2243
2286
  customer_key: string;
2244
2287
  file_name: string;
2245
2288
  file_path: string;
2246
2289
  file_size?: number | null;
2290
+ floriday_sticker_id?: string | null;
2291
+ floriday_synced_at?: string | null;
2292
+ height_mm?: number | null;
2247
2293
  id?: string;
2248
2294
  mime_type?: string | null;
2295
+ source?: string;
2249
2296
  trade_item_key: string;
2250
2297
  updated_at?: string;
2251
2298
  uploaded_by?: string | null;
2299
+ width_mm?: number | null;
2252
2300
  };
2253
2301
  Update: {
2302
+ content_hash?: string | null;
2254
2303
  created_at?: string;
2255
2304
  customer_key?: string;
2256
2305
  file_name?: string;
2257
2306
  file_path?: string;
2258
2307
  file_size?: number | null;
2308
+ floriday_sticker_id?: string | null;
2309
+ floriday_synced_at?: string | null;
2310
+ height_mm?: number | null;
2259
2311
  id?: string;
2260
2312
  mime_type?: string | null;
2313
+ source?: string;
2261
2314
  trade_item_key?: string;
2262
2315
  updated_at?: string;
2263
2316
  uploaded_by?: string | null;
2317
+ width_mm?: number | null;
2264
2318
  };
2265
2319
  Relationships: [];
2266
2320
  };
@@ -11568,6 +11622,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11568
11622
  Row: {
11569
11623
  actor: string | null;
11570
11624
  attempts: number;
11625
+ calc: import("./types").Json | null;
11571
11626
  cart_ref: string | null;
11572
11627
  created_at: string;
11573
11628
  db_action: string | null;
@@ -11578,6 +11633,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11578
11633
  decision: string | null;
11579
11634
  duration_ms: number | null;
11580
11635
  error: string | null;
11636
+ error_class: string | null;
11581
11637
  external_action: string | null;
11582
11638
  external_ref: string | null;
11583
11639
  external_response: import("./types").Json | null;
@@ -11586,6 +11642,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11586
11642
  id: string;
11587
11643
  input: import("./types").Json | null;
11588
11644
  next_attempt_at: string | null;
11645
+ next_step: string | null;
11646
+ node_id: string | null;
11589
11647
  order_ref: string | null;
11590
11648
  order_source: string | null;
11591
11649
  output: import("./types").Json | null;
@@ -11602,6 +11660,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11602
11660
  Insert: {
11603
11661
  actor?: string | null;
11604
11662
  attempts?: number;
11663
+ calc?: import("./types").Json | null;
11605
11664
  cart_ref?: string | null;
11606
11665
  created_at?: string;
11607
11666
  db_action?: string | null;
@@ -11612,6 +11671,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11612
11671
  decision?: string | null;
11613
11672
  duration_ms?: number | null;
11614
11673
  error?: string | null;
11674
+ error_class?: string | null;
11615
11675
  external_action?: string | null;
11616
11676
  external_ref?: string | null;
11617
11677
  external_response?: import("./types").Json | null;
@@ -11620,6 +11680,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11620
11680
  id?: string;
11621
11681
  input?: import("./types").Json | null;
11622
11682
  next_attempt_at?: string | null;
11683
+ next_step?: string | null;
11684
+ node_id?: string | null;
11623
11685
  order_ref?: string | null;
11624
11686
  order_source?: string | null;
11625
11687
  output?: import("./types").Json | null;
@@ -11636,6 +11698,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11636
11698
  Update: {
11637
11699
  actor?: string | null;
11638
11700
  attempts?: number;
11701
+ calc?: import("./types").Json | null;
11639
11702
  cart_ref?: string | null;
11640
11703
  created_at?: string;
11641
11704
  db_action?: string | null;
@@ -11646,6 +11709,7 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11646
11709
  decision?: string | null;
11647
11710
  duration_ms?: number | null;
11648
11711
  error?: string | null;
11712
+ error_class?: string | null;
11649
11713
  external_action?: string | null;
11650
11714
  external_ref?: string | null;
11651
11715
  external_response?: import("./types").Json | null;
@@ -11654,6 +11718,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
11654
11718
  id?: string;
11655
11719
  input?: import("./types").Json | null;
11656
11720
  next_attempt_at?: string | null;
11721
+ next_step?: string | null;
11722
+ node_id?: string | null;
11657
11723
  order_ref?: string | null;
11658
11724
  order_source?: string | null;
11659
11725
  output?: import("./types").Json | null;
@@ -25158,12 +25224,59 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
25158
25224
  };
25159
25225
  Returns: string;
25160
25226
  };
25227
+ logistics_trace_all_orders: {
25228
+ Args: {
25229
+ p_limit?: number;
25230
+ p_search?: string;
25231
+ };
25232
+ Returns: import("./types").Json;
25233
+ };
25161
25234
  logistics_trace_batch: {
25162
25235
  Args: {
25163
25236
  p: import("./types").Json;
25164
25237
  };
25165
25238
  Returns: number;
25166
25239
  };
25240
+ logistics_trace_node: {
25241
+ Args: {
25242
+ p_op?: string;
25243
+ p_status?: string;
25244
+ p_table: string;
25245
+ };
25246
+ Returns: string;
25247
+ };
25248
+ logistics_trace_order_overview: {
25249
+ Args: {
25250
+ p_error_class?: string;
25251
+ p_limit?: number;
25252
+ p_search?: string;
25253
+ p_since?: string;
25254
+ p_source?: string;
25255
+ p_state?: string;
25256
+ p_step?: string;
25257
+ };
25258
+ Returns: import("./types").Json;
25259
+ };
25260
+ logistics_trace_order_state: {
25261
+ Args: {
25262
+ p_order_ref: string;
25263
+ };
25264
+ Returns: import("./types").Json;
25265
+ };
25266
+ logistics_trace_order_step: {
25267
+ Args: {
25268
+ p_class?: string;
25269
+ p_decision?: string;
25270
+ p_error?: string;
25271
+ p_next_step?: string;
25272
+ p_node: string;
25273
+ p_order_id: string;
25274
+ p_reason?: string;
25275
+ p_status: string;
25276
+ p_step: string;
25277
+ };
25278
+ Returns: undefined;
25279
+ };
25167
25280
  logistics_trace_orders: {
25168
25281
  Args: {
25169
25282
  p_limit?: number;
@@ -25186,6 +25299,22 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
25186
25299
  };
25187
25300
  Returns: import("./types").Json;
25188
25301
  };
25302
+ logistics_trace_version_events: {
25303
+ Args: {
25304
+ p_from?: string;
25305
+ p_limit?: number;
25306
+ p_order_ref: string;
25307
+ p_to?: string;
25308
+ p_version_id: string;
25309
+ };
25310
+ Returns: import("./types").Json;
25311
+ };
25312
+ logistics_trace_versions: {
25313
+ Args: {
25314
+ p_order_ref: string;
25315
+ };
25316
+ Returns: import("./types").Json;
25317
+ };
25189
25318
  logistics_upsert_task: {
25190
25319
  Args: {
25191
25320
  p_buffer_ref: string;