@flowselections/mailbox-orders 1.0.10 → 1.0.12
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/MailboxProposalsPage.d.ts +16 -0
- package/dist-lib/components/MailboxProposalsPage.d.ts.map +1 -1
- package/dist-lib/components/MailboxProposalsPage.js +101 -10
- package/dist-lib/integrations/supabase/client.d.ts +162 -4
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +162 -4
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +163 -5
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +12 -1
- package/dist-lib/lib/ai-config.server.d.ts +14 -0
- package/dist-lib/lib/ai-config.server.d.ts.map +1 -1
- package/dist-lib/lib/ai-config.server.js +32 -19
- package/dist-lib/lib/mailbox-ai.server.d.ts +7 -0
- package/dist-lib/lib/mailbox-ai.server.d.ts.map +1 -1
- package/dist-lib/lib/mailbox-ai.server.js +83 -38
- package/dist-lib/lib/mailbox-ingest.server.d.ts +13 -0
- package/dist-lib/lib/mailbox-ingest.server.d.ts.map +1 -1
- package/dist-lib/lib/mailbox-ingest.server.js +77 -12
- package/dist-lib/lib/mailbox.functions.d.ts +23 -5
- package/dist-lib/lib/mailbox.functions.d.ts.map +1 -1
- package/dist-lib/lib/mailbox.functions.js +97 -4
- package/package.json +3 -3
- package/dist-lib/components/CartAssignmentWizard.d.ts +0 -6
- package/dist-lib/components/CartAssignmentWizard.d.ts.map +0 -1
- package/dist-lib/components/CartAssignmentWizard.js +0 -199
- package/dist-lib/components/MailboxInboxPage.d.ts +0 -2
- package/dist-lib/components/MailboxInboxPage.d.ts.map +0 -1
- package/dist-lib/components/MailboxInboxPage.js +0 -120
- package/dist-lib/components/settings/ImapAccountsCard.d.ts +0 -2
- package/dist-lib/components/settings/ImapAccountsCard.d.ts.map +0 -1
- package/dist-lib/components/settings/ImapAccountsCard.js +0 -136
- package/dist-lib/components/settings/ImapProfilesCard.d.ts +0 -2
- package/dist-lib/components/settings/ImapProfilesCard.d.ts.map +0 -1
- package/dist-lib/components/settings/ImapProfilesCard.js +0 -101
- package/dist-lib/components/settings/MailboxSettingsCard.d.ts +0 -2
- package/dist-lib/components/settings/MailboxSettingsCard.d.ts.map +0 -1
- package/dist-lib/components/settings/MailboxSettingsCard.js +0 -85
- package/dist-lib/lib/imap.functions.d.ts +0 -32852
- package/dist-lib/lib/imap.functions.d.ts.map +0 -1
- package/dist-lib/lib/imap.functions.js +0 -235
- package/dist-lib/lib/mailbox-auto.server.d.ts +0 -9
- package/dist-lib/lib/mailbox-auto.server.d.ts.map +0 -1
- package/dist-lib/lib/mailbox-auto.server.js +0 -198
|
@@ -1,2 +1,18 @@
|
|
|
1
|
+
/** Klantoptie uit de gecombineerde lijst (lokaal + Twinfield + Floriday). */
|
|
2
|
+
export interface CustomerOption {
|
|
3
|
+
id: string;
|
|
4
|
+
group_key?: string;
|
|
5
|
+
is_local?: boolean;
|
|
6
|
+
company_name: string;
|
|
7
|
+
email?: string | null;
|
|
8
|
+
city?: string | null;
|
|
9
|
+
country?: string | null;
|
|
10
|
+
gln?: string | null;
|
|
11
|
+
street?: string | null;
|
|
12
|
+
house_number?: string | null;
|
|
13
|
+
postal_code?: string | null;
|
|
14
|
+
phone?: string | null;
|
|
15
|
+
providers?: string[];
|
|
16
|
+
}
|
|
1
17
|
export declare function MailboxProposalsPage(): import("react").JSX.Element;
|
|
2
18
|
//# sourceMappingURL=MailboxProposalsPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MailboxProposalsPage.d.ts","sourceRoot":"","sources":["../../src/components/MailboxProposalsPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MailboxProposalsPage.d.ts","sourceRoot":"","sources":["../../src/components/MailboxProposalsPage.tsx"],"names":[],"mappings":"AAyFA,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AA2CD,wBAAgB,oBAAoB,gCAwYnC"}
|
|
@@ -5,7 +5,7 @@ import { useServerFn } from "@tanstack/react-start";
|
|
|
5
5
|
import { Button, Badge, Card, CardContent, CardHeader, CardTitle, Input, Label, Textarea, Switch, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Dialog, DialogContent, DialogHeader, DialogTitle, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, } from "@flowselections/core";
|
|
6
6
|
import { Check, X, Trash2, Plus, AlertTriangle, RefreshCw } from "lucide-react";
|
|
7
7
|
import { computeEarliestDelivery, isValidDeliveryDate } from "../lib/delivery-date";
|
|
8
|
-
import { listProposals, approveProposal, rejectProposal, listCustomersForPicker, listProductsForPicker, listDeliveryLocationsForCustomer, listPickupLocations, listCarriersForPicker, getOrderPickDays, getActiveOrdersMailbox, syncMailboxNow, getLastIngestRun, refreshProposalsForAgentChange, reparseProposalNow, listBeladingOptionsForProducts, listAllowedLoadCarriers, } from "../lib/mailbox.functions";
|
|
8
|
+
import { listProposals, approveProposal, rejectProposal, listCustomersForPicker, createCustomerFromGroup, listProductsForPicker, listDeliveryLocationsForCustomer, listPickupLocations, listCarriersForPicker, getOrderPickDays, getActiveOrdersMailbox, syncMailboxNow, getLastIngestRun, refreshProposalsForAgentChange, reparseProposalNow, listBeladingOptionsForProducts, listAllowedLoadCarriers, } from "../lib/mailbox.functions";
|
|
9
9
|
import { enabledLoadCarriers, normalizeAllowedLoadCarriers, EMPTY_LOAD_CARRIERS } from "../lib/load-carriers";
|
|
10
10
|
import { listTemplateFields, listPlantTypesForPicker, listSuppliersForPicker, } from "../lib/mailbox-template.functions";
|
|
11
11
|
import { SearchableSelect } from "./SearchableSelect";
|
|
@@ -38,16 +38,24 @@ const beladingAllowedByEngine = (b, allowed) => {
|
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
41
|
+
/** Alleen een echte lokale klant kan aan een bestelling worden gekoppeld. */
|
|
42
|
+
const isLocalCustomerId = (v) => typeof v === "string" && UUID_RE.test(v);
|
|
43
|
+
const providerLabel = (p) => p === "local" ? "Lokaal" : p === "twinfield" ? "Twinfield" : p === "floriday" ? "Floriday" : p;
|
|
44
|
+
const customerHint = (c) => [c.email, c.city, (c.providers ?? []).map(providerLabel).join(" + ")]
|
|
45
|
+
.filter(Boolean).join(" · ");
|
|
41
46
|
/**
|
|
42
|
-
* Zet een klantwaarde (id óf door AI geschreven klantnaam) om naar een
|
|
43
|
-
*
|
|
47
|
+
* Zet een klantwaarde (id óf door AI geschreven klantnaam) om naar een geldige
|
|
48
|
+
* keuze uit de klantenlijst. Lokale klanten hebben voorrang.
|
|
44
49
|
*/
|
|
45
50
|
function resolveCustomerId(raw, customers, fallbackId) {
|
|
46
|
-
const
|
|
51
|
+
const all = Array.isArray(customers) ? customers : [];
|
|
52
|
+
const list = [...all.filter((c) => c.is_local !== false), ...all.filter((c) => c.is_local === false)];
|
|
47
53
|
if (typeof raw === "string" && raw.trim()) {
|
|
48
54
|
const v = raw.trim();
|
|
49
55
|
if (UUID_RE.test(v))
|
|
50
56
|
return v;
|
|
57
|
+
if (v.startsWith("grp:") && list.some((c) => c.id === v))
|
|
58
|
+
return v;
|
|
51
59
|
const norm = v.toLowerCase();
|
|
52
60
|
const byName = list.find((c) => (c.company_name ?? "").trim().toLowerCase() === norm);
|
|
53
61
|
if (byName)
|
|
@@ -387,10 +395,19 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
387
395
|
const deliveryVal = values["delivery_date"];
|
|
388
396
|
const notesVal = values["notes"];
|
|
389
397
|
const setVal = (key, v) => setValues((prev) => ({ ...prev, [key]: v }));
|
|
398
|
+
// Externe klant gekozen die nog niet lokaal bestaat → verplichte aanmaakdialoog.
|
|
399
|
+
const [newCustomer, setNewCustomer] = useState(null);
|
|
400
|
+
const handleSelectCustomer = (v) => {
|
|
401
|
+
setVal("customer", v);
|
|
402
|
+
if (v && !isLocalCustomerId(v)) {
|
|
403
|
+
const c = customers.find((x) => x.id === v) ?? null;
|
|
404
|
+
setNewCustomer(c);
|
|
405
|
+
}
|
|
406
|
+
};
|
|
390
407
|
const fetchDeliveryLocations = useServerFn(listDeliveryLocationsForCustomer);
|
|
391
408
|
const { data: deliveryLocData } = useQuery({
|
|
392
409
|
queryKey: ["mailbox-delivery-locations", customerVal],
|
|
393
|
-
enabled:
|
|
410
|
+
enabled: isLocalCustomerId(customerVal),
|
|
394
411
|
queryFn: async () => {
|
|
395
412
|
try {
|
|
396
413
|
return await fetchDeliveryLocations({ data: { customerId: customerVal } });
|
|
@@ -537,6 +554,11 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
537
554
|
toast.error(`Verplichte velden ontbreken: ${missing.map((m) => m.label).join(", ")}`);
|
|
538
555
|
return null;
|
|
539
556
|
}
|
|
557
|
+
if (customerVal && !isLocalCustomerId(customerVal)) {
|
|
558
|
+
toast.error("Maak deze klant eerst aan voordat je de bestelling verwerkt.");
|
|
559
|
+
setNewCustomer(customers.find((c) => c.id === customerVal) ?? null);
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
540
562
|
if (!deliveryLocationVal) {
|
|
541
563
|
toast.error("Selecteer een afleverlocatie.");
|
|
542
564
|
return null;
|
|
@@ -603,12 +625,15 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
603
625
|
};
|
|
604
626
|
const deliveryDateField = visibleFields.find((f) => f.key === "delivery_date");
|
|
605
627
|
const otherFields = visibleFields.filter((f) => f.key !== "customer" && f.key !== "delivery_date");
|
|
606
|
-
const renderField = (field) => (_jsx(DynamicField, { field: field, value: values[field.key], meta: fvMap[field.key], onChange: (v) => setVal(field.key, v), customers: customers, products: products, plantTypes: plantTypes, suppliers: suppliers }, field.key));
|
|
628
|
+
const renderField = (field) => (_jsx(DynamicField, { field: field, value: values[field.key], meta: fvMap[field.key], onChange: (v) => setVal(field.key, v), customers: customers, products: products, plantTypes: plantTypes, suppliers: suppliers, onSelectCustomer: handleSelectCustomer }, field.key));
|
|
629
|
+
const customerNotLocal = !!customerVal && !isLocalCustomerId(customerVal);
|
|
607
630
|
const payload = (proposal.parsed_payload ?? {});
|
|
608
631
|
const autoMatched = payload.auto_matched_customer === true;
|
|
609
632
|
const matchWarning = typeof payload.auto_match_warning === "string" ? payload.auto_match_warning : null;
|
|
610
633
|
const ai = (payload.ai ?? null);
|
|
611
|
-
return (_jsxs(_Fragment, { children: [ai && ai.ok === false && (
|
|
634
|
+
return (_jsxs(_Fragment, { children: [ai && ai.ok === false && (_jsx("div", { className: "rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800", children: ai.retry_pending
|
|
635
|
+
? "De AI-dienst was even bezet — we proberen deze mail automatisch opnieuw. Je kunt de velden intussen zelf invullen."
|
|
636
|
+
: "Deze mail is niet automatisch uitgelezen — vul de velden handmatig in." })), matchWarning && (_jsx("div", { className: "rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800", children: matchWarning })), customerField && renderField(customerField), customerNotLocal && (_jsxs("div", { className: "rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800 flex items-center justify-between gap-2", children: [_jsx("span", { children: "Deze klant bestaat nog niet lokaal. Maak de klant eerst aan." }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => setNewCustomer(customers.find((c) => c.id === customerVal) ?? null), children: "Klant aanmaken" })] })), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { children: "Locatie" }), _jsx(SearchableSelect, { value: deliveryLocationVal, placeholder: !customerVal
|
|
612
637
|
? "Selecteer eerst een klant"
|
|
613
638
|
: deliveryLocations.length
|
|
614
639
|
? "Kies locatie..."
|
|
@@ -742,9 +767,71 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
742
767
|
setConfirmOpen(o);
|
|
743
768
|
if (!o)
|
|
744
769
|
setCheckedOk(false);
|
|
745
|
-
}, children: _jsxs(DialogContent, { className: "max-w-lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Bestelling bevestigen" }) }), _jsxs("div", { className: "space-y-3 text-sm", children: [_jsx("p", { className: "text-muted-foreground", children: "De bestelling wordt pas aangemaakt in Bestellingen nadat je hem hebt gecontroleerd en bevestigd." }), _jsxs("div", { className: "rounded-md border p-3 space-y-1", children: [_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Klant:" }), " ", customers.find((c) => c.id === customerVal)?.company_name ?? "-"] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Bezorgdatum:" }), " ", deliveryVal || "-"] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Bestelregels:" }), " ", lines.filter((l) => l.product_id && (l.quantity ?? 0) > 0).length] })] }), _jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", className: "mt-1", checked: checkedOk, onChange: (e) => setCheckedOk(e.target.checked) }), _jsx("span", { children: "Ik heb deze bestelling gecontroleerd en de gegevens kloppen." })] })] }), _jsxs("div", { className: "flex gap-2 pt-2", children: [_jsxs(Button, { className: "flex-1", disabled: !checkedOk || submitting, onClick: handleConfirm, children: [_jsx(Check, { className: "h-4 w-4 mr-1" }), submitting ? "Bezig…" : "Bevestigen en bestelling aanmaken"] }), _jsx(Button, { variant: "outline", disabled: submitting, onClick: () => setConfirmOpen(false), children: "Annuleren" })] })] }) })] })] })] }));
|
|
770
|
+
}, children: _jsxs(DialogContent, { className: "max-w-lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Bestelling bevestigen" }) }), _jsxs("div", { className: "space-y-3 text-sm", children: [_jsx("p", { className: "text-muted-foreground", children: "De bestelling wordt pas aangemaakt in Bestellingen nadat je hem hebt gecontroleerd en bevestigd." }), _jsxs("div", { className: "rounded-md border p-3 space-y-1", children: [_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Klant:" }), " ", customers.find((c) => c.id === customerVal)?.company_name ?? "-"] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Bezorgdatum:" }), " ", deliveryVal || "-"] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Bestelregels:" }), " ", lines.filter((l) => l.product_id && (l.quantity ?? 0) > 0).length] })] }), _jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", className: "mt-1", checked: checkedOk, onChange: (e) => setCheckedOk(e.target.checked) }), _jsx("span", { children: "Ik heb deze bestelling gecontroleerd en de gegevens kloppen." })] })] }), _jsxs("div", { className: "flex gap-2 pt-2", children: [_jsxs(Button, { className: "flex-1", disabled: !checkedOk || submitting, onClick: handleConfirm, children: [_jsx(Check, { className: "h-4 w-4 mr-1" }), submitting ? "Bezig…" : "Bevestigen en bestelling aanmaken"] }), _jsx(Button, { variant: "outline", disabled: submitting, onClick: () => setConfirmOpen(false), children: "Annuleren" })] })] }) }), _jsx(NewCustomerDialog, { candidate: newCustomer, onClose: () => setNewCustomer(null), onCreated: (id) => { setNewCustomer(null); setVal("customer", id); } })] })] })] }));
|
|
771
|
+
}
|
|
772
|
+
/** Verplichte bevestiging: externe klant eerst als lokale klant aanmaken. */
|
|
773
|
+
function NewCustomerDialog({ candidate, onClose, onCreated, }) {
|
|
774
|
+
const qc = useQueryClient();
|
|
775
|
+
const createCustomer = useServerFn(createCustomerFromGroup);
|
|
776
|
+
const [form, setForm] = useState({});
|
|
777
|
+
const [busy, setBusy] = useState(false);
|
|
778
|
+
useEffect(() => {
|
|
779
|
+
if (!candidate)
|
|
780
|
+
return;
|
|
781
|
+
setForm({
|
|
782
|
+
companyName: candidate.company_name ?? "",
|
|
783
|
+
email: candidate.email ?? "",
|
|
784
|
+
street: candidate.street ?? "",
|
|
785
|
+
houseNumber: candidate.house_number ?? "",
|
|
786
|
+
postalCode: candidate.postal_code ?? "",
|
|
787
|
+
city: candidate.city ?? "",
|
|
788
|
+
country: candidate.country ?? "",
|
|
789
|
+
gln: candidate.gln ?? "",
|
|
790
|
+
phone: candidate.phone ?? "",
|
|
791
|
+
});
|
|
792
|
+
}, [candidate?.id]);
|
|
793
|
+
const set = (k, v) => setForm((p) => ({ ...p, [k]: v }));
|
|
794
|
+
const field = (k, label, required = false) => (_jsxs("div", { className: "space-y-1", children: [_jsxs(Label, { children: [label, required && _jsx("span", { className: "text-destructive", children: " *" })] }), _jsx(Input, { value: form[k] ?? "", onChange: (e) => set(k, e.target.value) })] }));
|
|
795
|
+
const submit = async () => {
|
|
796
|
+
if (!candidate)
|
|
797
|
+
return;
|
|
798
|
+
if (!(form["companyName"] ?? "").trim()) {
|
|
799
|
+
toast.error("Bedrijfsnaam is verplicht.");
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
setBusy(true);
|
|
803
|
+
try {
|
|
804
|
+
const res = await createCustomer({
|
|
805
|
+
data: {
|
|
806
|
+
groupKey: candidate.group_key ?? candidate.id,
|
|
807
|
+
companyName: form["companyName"].trim(),
|
|
808
|
+
email: (form["email"] ?? "").trim() || null,
|
|
809
|
+
street: (form["street"] ?? "").trim() || null,
|
|
810
|
+
houseNumber: (form["houseNumber"] ?? "").trim() || null,
|
|
811
|
+
postalCode: (form["postalCode"] ?? "").trim() || null,
|
|
812
|
+
city: (form["city"] ?? "").trim() || null,
|
|
813
|
+
country: (form["country"] ?? "").trim() || null,
|
|
814
|
+
gln: (form["gln"] ?? "").trim() || null,
|
|
815
|
+
phone: (form["phone"] ?? "").trim() || null,
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
if (!res?.id)
|
|
819
|
+
throw new Error("Klant kon niet worden aangemaakt.");
|
|
820
|
+
await qc.invalidateQueries({ queryKey: ["mailbox-customers"] });
|
|
821
|
+
toast.success(res.created ? "Klant aangemaakt." : "Bestaande klant gekoppeld.");
|
|
822
|
+
onCreated(res.id);
|
|
823
|
+
}
|
|
824
|
+
catch (e) {
|
|
825
|
+
toast.error(e?.message ?? "Aanmaken mislukt.");
|
|
826
|
+
}
|
|
827
|
+
finally {
|
|
828
|
+
setBusy(false);
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
return (_jsx(Dialog, { open: !!candidate, onOpenChange: (o) => { if (!o)
|
|
832
|
+
onClose(); }, children: _jsxs(DialogContent, { className: "max-w-xl", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Nieuwe klant aanmaken" }) }), _jsxs("p", { className: "text-sm text-muted-foreground", children: ["Deze klant bestaat alleen in ", (candidate?.providers ?? []).map(providerLabel).join(" + ") || "een externe bron", ". Controleer de gegevens en maak de klant aan voordat je de bestelling verwerkt."] }), _jsxs("div", { className: "grid grid-cols-2 gap-3 py-2", children: [field("companyName", "Bedrijfsnaam", true), field("email", "E-mail"), field("street", "Straat"), field("houseNumber", "Huisnummer"), field("postalCode", "Postcode"), field("city", "Plaats"), field("country", "Land"), field("gln", "GLN"), field("phone", "Telefoon")] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { className: "flex-1", disabled: busy, onClick: submit, children: busy ? "Bezig…" : "Klant aanmaken en koppelen" }), _jsx(Button, { variant: "outline", disabled: busy, onClick: onClose, children: "Annuleren" })] })] }) }));
|
|
746
833
|
}
|
|
747
|
-
function DynamicField({ field, value, meta, onChange, customers, products, plantTypes, suppliers, }) {
|
|
834
|
+
function DynamicField({ field, value, meta, onChange, customers, products, plantTypes, suppliers, onSelectCustomer, }) {
|
|
748
835
|
const reviewClass = meta?.needs_review ? "border-yellow-500 ring-1 ring-yellow-500/40 rounded-md p-2" : "";
|
|
749
836
|
const label = (_jsxs(Label, { className: "flex items-center gap-2", children: [field.label, field.required && _jsx("span", { className: "text-destructive", children: "*" }), meta?.needs_review && (_jsx(Badge, { variant: "outline", className: "text-xs border-yellow-500 text-yellow-700", children: "Controleren" })), typeof meta?.ai_confidence === "number" && (_jsxs("span", { className: "text-xs text-muted-foreground", children: [Math.round(meta.ai_confidence * 100), "%"] }))] }));
|
|
750
837
|
const renderControl = () => {
|
|
@@ -769,7 +856,11 @@ function DynamicField({ field, value, meta, onChange, customers, products, plant
|
|
|
769
856
|
}) }));
|
|
770
857
|
}
|
|
771
858
|
case "customer":
|
|
772
|
-
return (_jsx(SearchableSelect, { value: value ?? null, placeholder: "Kies klant...", options: customers.map((c) => ({
|
|
859
|
+
return (_jsx(SearchableSelect, { value: value ?? null, placeholder: "Kies klant...", options: customers.map((c) => ({
|
|
860
|
+
value: c.id,
|
|
861
|
+
label: c.company_name + (c.is_local === false ? " (nog niet aangemaakt)" : ""),
|
|
862
|
+
hint: customerHint(c),
|
|
863
|
+
})), onChange: (v) => (onSelectCustomer ? onSelectCustomer(v) : onChange(v)) }));
|
|
773
864
|
case "product":
|
|
774
865
|
return (_jsx(SearchableSelect, { value: value ?? null, placeholder: "Kies product...", options: products.map((p) => ({ value: p.id, label: p.product })), onChange: onChange }));
|
|
775
866
|
case "plant_type":
|
|
@@ -1683,7 +1683,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
1683
1683
|
city: string | null;
|
|
1684
1684
|
country: string | null;
|
|
1685
1685
|
created_at: string;
|
|
1686
|
-
customer_id: string
|
|
1686
|
+
customer_id: string;
|
|
1687
1687
|
external_key: string | null;
|
|
1688
1688
|
external_provider: string | null;
|
|
1689
1689
|
floriday_location_id: string | null;
|
|
@@ -1707,7 +1707,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
1707
1707
|
city?: string | null;
|
|
1708
1708
|
country?: string | null;
|
|
1709
1709
|
created_at?: string;
|
|
1710
|
-
customer_id
|
|
1710
|
+
customer_id: string;
|
|
1711
1711
|
external_key?: string | null;
|
|
1712
1712
|
external_provider?: string | null;
|
|
1713
1713
|
floriday_location_id?: string | null;
|
|
@@ -1731,7 +1731,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
1731
1731
|
city?: string | null;
|
|
1732
1732
|
country?: string | null;
|
|
1733
1733
|
created_at?: string;
|
|
1734
|
-
customer_id?: string
|
|
1734
|
+
customer_id?: string;
|
|
1735
1735
|
external_key?: string | null;
|
|
1736
1736
|
external_provider?: string | null;
|
|
1737
1737
|
floriday_location_id?: string | null;
|
|
@@ -12356,22 +12356,27 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12356
12356
|
created_at: string;
|
|
12357
12357
|
documentnaam: string;
|
|
12358
12358
|
documenttype: Database["public"]["Enums"]["doc_layout_type"];
|
|
12359
|
+
extern_job_id: string | null;
|
|
12359
12360
|
foutmelding: string | null;
|
|
12360
12361
|
gebruiker_id: string | null;
|
|
12361
12362
|
gebruiker_naam: string;
|
|
12362
12363
|
gestart_op: string | null;
|
|
12363
12364
|
id: string;
|
|
12365
|
+
idempotentie_sleutel: string | null;
|
|
12364
12366
|
is_herprint: boolean;
|
|
12365
12367
|
kopieen: number;
|
|
12366
12368
|
layout_id: string | null;
|
|
12367
12369
|
opgepakt_op: string | null;
|
|
12368
12370
|
paginas: number;
|
|
12369
12371
|
payload: import("./types").Json;
|
|
12372
|
+
pdf_base64: string | null;
|
|
12373
|
+
pdf_url: string | null;
|
|
12370
12374
|
pogingen: number;
|
|
12371
12375
|
printer_id: string | null;
|
|
12372
12376
|
render_html: string | null;
|
|
12373
12377
|
status: Database["public"]["Enums"]["print_job_status"];
|
|
12374
12378
|
updated_at: string;
|
|
12379
|
+
volgende_poging: string | null;
|
|
12375
12380
|
voltooid_op: string | null;
|
|
12376
12381
|
};
|
|
12377
12382
|
Insert: {
|
|
@@ -12380,22 +12385,27 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12380
12385
|
created_at?: string;
|
|
12381
12386
|
documentnaam?: string;
|
|
12382
12387
|
documenttype?: Database["public"]["Enums"]["doc_layout_type"];
|
|
12388
|
+
extern_job_id?: string | null;
|
|
12383
12389
|
foutmelding?: string | null;
|
|
12384
12390
|
gebruiker_id?: string | null;
|
|
12385
12391
|
gebruiker_naam?: string;
|
|
12386
12392
|
gestart_op?: string | null;
|
|
12387
12393
|
id?: string;
|
|
12394
|
+
idempotentie_sleutel?: string | null;
|
|
12388
12395
|
is_herprint?: boolean;
|
|
12389
12396
|
kopieen?: number;
|
|
12390
12397
|
layout_id?: string | null;
|
|
12391
12398
|
opgepakt_op?: string | null;
|
|
12392
12399
|
paginas?: number;
|
|
12393
12400
|
payload?: import("./types").Json;
|
|
12401
|
+
pdf_base64?: string | null;
|
|
12402
|
+
pdf_url?: string | null;
|
|
12394
12403
|
pogingen?: number;
|
|
12395
12404
|
printer_id?: string | null;
|
|
12396
12405
|
render_html?: string | null;
|
|
12397
12406
|
status?: Database["public"]["Enums"]["print_job_status"];
|
|
12398
12407
|
updated_at?: string;
|
|
12408
|
+
volgende_poging?: string | null;
|
|
12399
12409
|
voltooid_op?: string | null;
|
|
12400
12410
|
};
|
|
12401
12411
|
Update: {
|
|
@@ -12404,22 +12414,27 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12404
12414
|
created_at?: string;
|
|
12405
12415
|
documentnaam?: string;
|
|
12406
12416
|
documenttype?: Database["public"]["Enums"]["doc_layout_type"];
|
|
12417
|
+
extern_job_id?: string | null;
|
|
12407
12418
|
foutmelding?: string | null;
|
|
12408
12419
|
gebruiker_id?: string | null;
|
|
12409
12420
|
gebruiker_naam?: string;
|
|
12410
12421
|
gestart_op?: string | null;
|
|
12411
12422
|
id?: string;
|
|
12423
|
+
idempotentie_sleutel?: string | null;
|
|
12412
12424
|
is_herprint?: boolean;
|
|
12413
12425
|
kopieen?: number;
|
|
12414
12426
|
layout_id?: string | null;
|
|
12415
12427
|
opgepakt_op?: string | null;
|
|
12416
12428
|
paginas?: number;
|
|
12417
12429
|
payload?: import("./types").Json;
|
|
12430
|
+
pdf_base64?: string | null;
|
|
12431
|
+
pdf_url?: string | null;
|
|
12418
12432
|
pogingen?: number;
|
|
12419
12433
|
printer_id?: string | null;
|
|
12420
12434
|
render_html?: string | null;
|
|
12421
12435
|
status?: Database["public"]["Enums"]["print_job_status"];
|
|
12422
12436
|
updated_at?: string;
|
|
12437
|
+
volgende_poging?: string | null;
|
|
12423
12438
|
voltooid_op?: string | null;
|
|
12424
12439
|
};
|
|
12425
12440
|
Relationships: [{
|
|
@@ -12442,6 +12457,36 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12442
12457
|
referencedColumns: ["id"];
|
|
12443
12458
|
}];
|
|
12444
12459
|
};
|
|
12460
|
+
print_queue_runners: {
|
|
12461
|
+
Row: {
|
|
12462
|
+
actief: boolean;
|
|
12463
|
+
basis_url: string;
|
|
12464
|
+
created_at: string;
|
|
12465
|
+
id: string;
|
|
12466
|
+
laatst_gezien: string;
|
|
12467
|
+
tick_sleutel: string;
|
|
12468
|
+
updated_at: string;
|
|
12469
|
+
};
|
|
12470
|
+
Insert: {
|
|
12471
|
+
actief?: boolean;
|
|
12472
|
+
basis_url: string;
|
|
12473
|
+
created_at?: string;
|
|
12474
|
+
id?: string;
|
|
12475
|
+
laatst_gezien?: string;
|
|
12476
|
+
tick_sleutel?: string;
|
|
12477
|
+
updated_at?: string;
|
|
12478
|
+
};
|
|
12479
|
+
Update: {
|
|
12480
|
+
actief?: boolean;
|
|
12481
|
+
basis_url?: string;
|
|
12482
|
+
created_at?: string;
|
|
12483
|
+
id?: string;
|
|
12484
|
+
laatst_gezien?: string;
|
|
12485
|
+
tick_sleutel?: string;
|
|
12486
|
+
updated_at?: string;
|
|
12487
|
+
};
|
|
12488
|
+
Relationships: [];
|
|
12489
|
+
};
|
|
12445
12490
|
print_rules: {
|
|
12446
12491
|
Row: {
|
|
12447
12492
|
actief: boolean;
|
|
@@ -12602,6 +12647,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12602
12647
|
agent_id: string | null;
|
|
12603
12648
|
created_at: string;
|
|
12604
12649
|
driver: string;
|
|
12650
|
+
extern_printer_id: string | null;
|
|
12605
12651
|
id: string;
|
|
12606
12652
|
ip_adres: string | null;
|
|
12607
12653
|
laatst_gezien: string | null;
|
|
@@ -12623,6 +12669,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12623
12669
|
agent_id?: string | null;
|
|
12624
12670
|
created_at?: string;
|
|
12625
12671
|
driver?: string;
|
|
12672
|
+
extern_printer_id?: string | null;
|
|
12626
12673
|
id?: string;
|
|
12627
12674
|
ip_adres?: string | null;
|
|
12628
12675
|
laatst_gezien?: string | null;
|
|
@@ -12644,6 +12691,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
12644
12691
|
agent_id?: string | null;
|
|
12645
12692
|
created_at?: string;
|
|
12646
12693
|
driver?: string;
|
|
12694
|
+
extern_printer_id?: string | null;
|
|
12647
12695
|
id?: string;
|
|
12648
12696
|
ip_adres?: string | null;
|
|
12649
12697
|
laatst_gezien?: string | null;
|
|
@@ -18248,6 +18296,46 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
18248
18296
|
};
|
|
18249
18297
|
Returns: import("./types").Json;
|
|
18250
18298
|
};
|
|
18299
|
+
claim_cloud_print_jobs: {
|
|
18300
|
+
Args: {
|
|
18301
|
+
_max?: number;
|
|
18302
|
+
};
|
|
18303
|
+
Returns: {
|
|
18304
|
+
agent_id: string | null;
|
|
18305
|
+
bron_job_id: string | null;
|
|
18306
|
+
created_at: string;
|
|
18307
|
+
documentnaam: string;
|
|
18308
|
+
documenttype: Database["public"]["Enums"]["doc_layout_type"];
|
|
18309
|
+
extern_job_id: string | null;
|
|
18310
|
+
foutmelding: string | null;
|
|
18311
|
+
gebruiker_id: string | null;
|
|
18312
|
+
gebruiker_naam: string;
|
|
18313
|
+
gestart_op: string | null;
|
|
18314
|
+
id: string;
|
|
18315
|
+
idempotentie_sleutel: string | null;
|
|
18316
|
+
is_herprint: boolean;
|
|
18317
|
+
kopieen: number;
|
|
18318
|
+
layout_id: string | null;
|
|
18319
|
+
opgepakt_op: string | null;
|
|
18320
|
+
paginas: number;
|
|
18321
|
+
payload: import("./types").Json;
|
|
18322
|
+
pdf_base64: string | null;
|
|
18323
|
+
pdf_url: string | null;
|
|
18324
|
+
pogingen: number;
|
|
18325
|
+
printer_id: string | null;
|
|
18326
|
+
render_html: string | null;
|
|
18327
|
+
status: Database["public"]["Enums"]["print_job_status"];
|
|
18328
|
+
updated_at: string;
|
|
18329
|
+
volgende_poging: string | null;
|
|
18330
|
+
voltooid_op: string | null;
|
|
18331
|
+
}[];
|
|
18332
|
+
SetofOptions: {
|
|
18333
|
+
from: "*";
|
|
18334
|
+
to: "print_jobs";
|
|
18335
|
+
isOneToOne: false;
|
|
18336
|
+
isSetofReturn: true;
|
|
18337
|
+
};
|
|
18338
|
+
};
|
|
18251
18339
|
claim_floriday_stock_queue: {
|
|
18252
18340
|
Args: {
|
|
18253
18341
|
p_limit?: number;
|
|
@@ -18338,22 +18426,27 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
18338
18426
|
created_at: string;
|
|
18339
18427
|
documentnaam: string;
|
|
18340
18428
|
documenttype: Database["public"]["Enums"]["doc_layout_type"];
|
|
18429
|
+
extern_job_id: string | null;
|
|
18341
18430
|
foutmelding: string | null;
|
|
18342
18431
|
gebruiker_id: string | null;
|
|
18343
18432
|
gebruiker_naam: string;
|
|
18344
18433
|
gestart_op: string | null;
|
|
18345
18434
|
id: string;
|
|
18435
|
+
idempotentie_sleutel: string | null;
|
|
18346
18436
|
is_herprint: boolean;
|
|
18347
18437
|
kopieen: number;
|
|
18348
18438
|
layout_id: string | null;
|
|
18349
18439
|
opgepakt_op: string | null;
|
|
18350
18440
|
paginas: number;
|
|
18351
18441
|
payload: import("./types").Json;
|
|
18442
|
+
pdf_base64: string | null;
|
|
18443
|
+
pdf_url: string | null;
|
|
18352
18444
|
pogingen: number;
|
|
18353
18445
|
printer_id: string | null;
|
|
18354
18446
|
render_html: string | null;
|
|
18355
18447
|
status: Database["public"]["Enums"]["print_job_status"];
|
|
18356
18448
|
updated_at: string;
|
|
18449
|
+
volgende_poging: string | null;
|
|
18357
18450
|
voltooid_op: string | null;
|
|
18358
18451
|
}[];
|
|
18359
18452
|
SetofOptions: {
|
|
@@ -19715,6 +19808,15 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
19715
19808
|
};
|
|
19716
19809
|
Returns: string;
|
|
19717
19810
|
};
|
|
19811
|
+
pick_active_printers: {
|
|
19812
|
+
Args: never;
|
|
19813
|
+
Returns: {
|
|
19814
|
+
id: string;
|
|
19815
|
+
locatie: string;
|
|
19816
|
+
naam: string;
|
|
19817
|
+
online: boolean;
|
|
19818
|
+
}[];
|
|
19819
|
+
};
|
|
19718
19820
|
pick_claim_document: {
|
|
19719
19821
|
Args: {
|
|
19720
19822
|
_queue_item_id: string;
|
|
@@ -19901,6 +20003,52 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
19901
20003
|
};
|
|
19902
20004
|
Returns: undefined;
|
|
19903
20005
|
};
|
|
20006
|
+
pick_reset_print: {
|
|
20007
|
+
Args: {
|
|
20008
|
+
_queue_item_id: string;
|
|
20009
|
+
_session_id: string;
|
|
20010
|
+
};
|
|
20011
|
+
Returns: {
|
|
20012
|
+
announced_at: string;
|
|
20013
|
+
assigned_user_id: string | null;
|
|
20014
|
+
barcode: string | null;
|
|
20015
|
+
cancelled_at: string | null;
|
|
20016
|
+
cart_count: number;
|
|
20017
|
+
completed_at: string | null;
|
|
20018
|
+
country_code: string | null;
|
|
20019
|
+
created_at: string;
|
|
20020
|
+
customer_name: string | null;
|
|
20021
|
+
delivery_address: string | null;
|
|
20022
|
+
document_number: string | null;
|
|
20023
|
+
document_type_id: string | null;
|
|
20024
|
+
due_at: string | null;
|
|
20025
|
+
id: string;
|
|
20026
|
+
is_urgent: boolean;
|
|
20027
|
+
line_count: number;
|
|
20028
|
+
order_number: string | null;
|
|
20029
|
+
order_type: string | null;
|
|
20030
|
+
payload: import("./types").Json;
|
|
20031
|
+
print_count: number;
|
|
20032
|
+
print_job_id: string | null;
|
|
20033
|
+
printed_at: string | null;
|
|
20034
|
+
printed_by: string | null;
|
|
20035
|
+
printer_id: string | null;
|
|
20036
|
+
priority: number;
|
|
20037
|
+
reference: string | null;
|
|
20038
|
+
route: string | null;
|
|
20039
|
+
screen_id: string | null;
|
|
20040
|
+
station_id: string | null;
|
|
20041
|
+
status_id: string | null;
|
|
20042
|
+
updated_at: string;
|
|
20043
|
+
warnings: import("./types").Json;
|
|
20044
|
+
};
|
|
20045
|
+
SetofOptions: {
|
|
20046
|
+
from: "*";
|
|
20047
|
+
to: "pick_queue";
|
|
20048
|
+
isOneToOne: true;
|
|
20049
|
+
isSetofReturn: false;
|
|
20050
|
+
};
|
|
20051
|
+
};
|
|
19904
20052
|
pick_station_dashboard: {
|
|
19905
20053
|
Args: never;
|
|
19906
20054
|
Returns: {
|
|
@@ -20091,6 +20239,12 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
20091
20239
|
};
|
|
20092
20240
|
Returns: import("./types").Json;
|
|
20093
20241
|
};
|
|
20242
|
+
ruim_print_jobs_op: {
|
|
20243
|
+
Args: {
|
|
20244
|
+
_bewaar_dagen?: number;
|
|
20245
|
+
};
|
|
20246
|
+
Returns: number;
|
|
20247
|
+
};
|
|
20094
20248
|
run_floriday_continuous_stock_sync: {
|
|
20095
20249
|
Args: never;
|
|
20096
20250
|
Returns: undefined;
|
|
@@ -20099,6 +20253,10 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
20099
20253
|
Args: never;
|
|
20100
20254
|
Returns: undefined;
|
|
20101
20255
|
};
|
|
20256
|
+
run_print_queue_ticks: {
|
|
20257
|
+
Args: never;
|
|
20258
|
+
Returns: number;
|
|
20259
|
+
};
|
|
20102
20260
|
run_twinfield_queue_tick: {
|
|
20103
20261
|
Args: never;
|
|
20104
20262
|
Returns: undefined;
|
|
@@ -20535,7 +20693,7 @@ export declare const supabase: import("@supabase/supabase-js").SupabaseClient<Da
|
|
|
20535
20693
|
};
|
|
20536
20694
|
Enums: {
|
|
20537
20695
|
ai_import_status: "nieuw" | "verwerken" | "bevestigen" | "klaar" | "mislukt";
|
|
20538
|
-
app_role: "admin" | "planner" | "monteur" | "administratie" | "ai_admin";
|
|
20696
|
+
app_role: "admin" | "planner" | "monteur" | "administratie" | "ai_admin" | "manager" | "warehouse" | "sales" | "developer" | "receptie";
|
|
20539
20697
|
doc_layout_type: "pakbon" | "factuur" | "offerte" | "orderbevestiging" | "etiket" | "verzendlabel" | "productlabel" | "barcode_label" | "magazijnlijst" | "controlelijst" | "transportdocument" | "vrij" | "sticker" | "productiebon";
|
|
20540
20698
|
doc_orientation: "portrait" | "landscape";
|
|
20541
20699
|
exact_env: "staging" | "live";
|