@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.
- package/dist-lib/components/klanten/BulkStickerUploadDialog.d.ts.map +1 -1
- package/dist-lib/components/klanten/BulkStickerUploadDialog.js +30 -8
- package/dist-lib/components/klanten/CustomerAssortmentTab.d.ts.map +1 -1
- package/dist-lib/components/klanten/CustomerAssortmentTab.js +48 -10
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +129 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +129 -0
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +129 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +129 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/accounting/twinfield/client.server.d.ts +7 -8
- package/dist-lib/lib/accounting/twinfield/client.server.d.ts.map +1 -1
- package/dist-lib/lib/accounting/twinfield/client.server.js +147 -78
- package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts +387 -0
- package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts.map +1 -1
- package/dist-lib/lib/accounting/twinfield/worker.server.d.ts.map +1 -1
- package/dist-lib/lib/accounting/twinfield/worker.server.js +17 -0
- package/dist-lib/lib/accounting.functions.d.ts +387 -0
- package/dist-lib/lib/accounting.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-analytics.functions.d.ts +129 -0
- package/dist-lib/lib/customer-analytics.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-assortment.functions.d.ts +132 -3
- package/dist-lib/lib/customer-assortment.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-assortment.functions.js +12 -0
- package/dist-lib/lib/customer-notes.functions.d.ts +258 -0
- package/dist-lib/lib/customer-notes.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-revenue.functions.d.ts +129 -0
- package/dist-lib/lib/customer-revenue.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-stickers.functions.d.ts +1165 -0
- package/dist-lib/lib/customer-stickers.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-stickers.functions.js +122 -75
- package/dist-lib/lib/customers.functions.d.ts +1161 -0
- package/dist-lib/lib/customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/delivery-locations.functions.d.ts +645 -0
- package/dist-lib/lib/delivery-locations.functions.d.ts.map +1 -1
- package/dist-lib/lib/external-customers.functions.d.ts +516 -0
- package/dist-lib/lib/external-customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-assortment.functions.d.ts +129 -0
- package/dist-lib/lib/floriday-assortment.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-discounts.functions.d.ts +258 -0
- package/dist-lib/lib/floriday-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-price-import.functions.d.ts +258 -0
- package/dist-lib/lib/floriday-price-import.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-sticker-import.functions.d.ts +27323 -0
- package/dist-lib/lib/floriday-sticker-import.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-sticker-import.functions.js +307 -0
- package/dist-lib/lib/floriday-trade-items.functions.d.ts +129 -0
- package/dist-lib/lib/floriday-trade-items.functions.d.ts.map +1 -1
- package/dist-lib/lib/local-discounts.functions.d.ts +903 -0
- package/dist-lib/lib/local-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/logistics-events.functions.d.ts +129 -0
- package/dist-lib/lib/logistics-events.functions.d.ts.map +1 -1
- package/dist-lib/lib/logistics-strategy.functions.d.ts +516 -0
- package/dist-lib/lib/logistics-strategy.functions.d.ts.map +1 -1
- package/dist-lib/lib/overdue-invoices.functions.d.ts +129 -0
- package/dist-lib/lib/overdue-invoices.functions.d.ts.map +1 -1
- package/dist-lib/lib/price-groups-local.functions.d.ts +1677 -0
- package/dist-lib/lib/price-groups-local.functions.d.ts.map +1 -1
- package/dist-lib/lib/price-groups.functions.d.ts +129 -0
- package/dist-lib/lib/price-groups.functions.d.ts.map +1 -1
- package/dist-lib/lib/twinfield-adopt.functions.d.ts +258 -0
- package/dist-lib/lib/twinfield-adopt.functions.d.ts.map +1 -1
- package/dist-lib/lib/twinfield-ledger.functions.d.ts +129 -0
- package/dist-lib/lib/twinfield-ledger.functions.d.ts.map +1 -1
- 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,+
|
|
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 =
|
|
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.
|
|
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
|
-
? {
|
|
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",
|
|
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-
|
|
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:
|
|
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":"
|
|
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:
|
|
79
|
-
? `${
|
|
80
|
-
: "nog niet ingesteld" })] }), _jsx(CustomerStickerFormatDialog, { customerKey: customerKey, format:
|
|
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] }) })
|
|
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:
|
|
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;
|