@flowselections/mailbox-orders 1.0.40 → 1.0.43
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.js +10 -4
- package/dist-lib/integrations/supabase/types.d.ts +3429 -85
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/mailbox.functions.d.ts +2 -0
- package/dist-lib/lib/mailbox.functions.d.ts.map +1 -1
- package/dist-lib/lib/mailbox.functions.js +7 -5
- package/dist-lib/lib/verkoop-order.d.ts +13 -0
- package/dist-lib/lib/verkoop-order.d.ts.map +1 -1
- package/dist-lib/lib/verkoop-order.js +23 -0
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ import { EmailPreview } from "./EmailPreview.js";
|
|
|
14
14
|
import { TablePagination } from "./TablePagination.js";
|
|
15
15
|
import { MailboxFilterBar, usePersistedState, normalizeText, matchesPeriod } from "./MailboxFilterBar.js";
|
|
16
16
|
import { supabase } from "../integrations/supabase/client.js";
|
|
17
|
-
import { canOverrideLateSignup } from "../lib/verkoop-order.js";
|
|
17
|
+
import { canOverrideLateSignup, checkLinePrices } from "../lib/verkoop-order.js";
|
|
18
18
|
const beladingKey = (b) => `${b.plants_per_crate}x${b.crates_per_layer}x${b.layers_per_cart}|${b.crate_code ?? ""}|${b.carrier_code ?? ""}`;
|
|
19
19
|
const beladingLabel = (b) => `${b.plants_per_crate} planten/fust · ${b.crates_per_layer} fusten/laag · ${b.layers_per_cart} lagen`;
|
|
20
20
|
// Extra regel onder het label: fusten/kar + fusttype + kartype
|
|
@@ -657,6 +657,10 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
657
657
|
useEffect(() => { setRefusal(null); setLateOpen(false); setLateReason(""); }, [deliveryVal, carrierVal, deliveryLocationVal]);
|
|
658
658
|
const orderTotal = lines.reduce((sum, l) => sum + lineTotal(l.quantity ?? null, l.unit_price ?? null), 0);
|
|
659
659
|
const linesWithoutPrice = lines.filter((l) => l.product_id && (l.unit_price === null || l.unit_price === undefined)).length;
|
|
660
|
+
const zeroPriceLines = lines.filter((l) => l.product_id && l.unit_price === 0).length;
|
|
661
|
+
const [zeroConfirmed, setZeroConfirmed] = useState(false);
|
|
662
|
+
useEffect(() => { if (zeroPriceLines === 0)
|
|
663
|
+
setZeroConfirmed(false); }, [zeroPriceLines]);
|
|
660
664
|
const euro = (n) => n.toLocaleString("nl-NL", { style: "currency", currency: "EUR" });
|
|
661
665
|
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
662
666
|
const [submitting, setSubmitting] = useState(false);
|
|
@@ -707,8 +711,9 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
707
711
|
return null;
|
|
708
712
|
}
|
|
709
713
|
}
|
|
710
|
-
|
|
711
|
-
|
|
714
|
+
const priceCheck = checkLinePrices(validLines.map((l) => l.unit_price), zeroConfirmed);
|
|
715
|
+
if (!priceCheck.ok) {
|
|
716
|
+
toast.error(priceCheck.message);
|
|
712
717
|
return null;
|
|
713
718
|
}
|
|
714
719
|
const cust = customers.find((c) => c.id === customerVal);
|
|
@@ -736,6 +741,7 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
736
741
|
customerReference: typeof values["reference"] === "string" ? values["reference"].trim() || null : null,
|
|
737
742
|
momentKey: preview?.chosen?.momentKey ?? null,
|
|
738
743
|
lateSignup: lateOverride ? { reason: lateReason.trim() } : null,
|
|
744
|
+
zeroPriceConfirmed: zeroConfirmed && priceCheck.zeroLines > 0,
|
|
739
745
|
};
|
|
740
746
|
};
|
|
741
747
|
// Stap 1: controleren → bevestigingsdialoog. Pas na bevestigen wordt de
|
|
@@ -941,7 +947,7 @@ function ProposalEditor({ proposal, template, customers, products, allowBackorde
|
|
|
941
947
|
next[idx] = { ...next[idx], needs_sticker: e.target.checked };
|
|
942
948
|
setLines(next);
|
|
943
949
|
} }), "Sticker"] })), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => setLines(lines.filter((_, i) => i !== idx)), children: _jsx(Trash2, { className: "h-4 w-4" }) })] })] }, idx));
|
|
944
|
-
}), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setLines([...lines, { product_id: null, raw_product_text: "", quantity: 1, unit: "stuks", belading: null }]), children: [_jsx(Plus, { className: "h-3 w-3 mr-1" }), " Regel toevoegen"] }), _jsxs("div", { className: "flex justify-between border-t pt-2 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Totaal" }), _jsx("span", { className: "font-medium", children: euro(orderTotal) })] }), linesWithoutPrice > 0 && (_jsxs("div", { className: "rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800", children: ["Geen prijs bekend voor ", linesWithoutPrice, " regel(s). Vul een prijs in; zonder prijs kan de bestelling niet worden aangemaakt."] }))] }), refusal && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm space-y-2", children: [_jsx("div", { className: "font-medium text-destructive", children: "Bestelling niet aangemaakt \u2014 het voorstel blijft open." }), _jsx("div", { className: "text-destructive", children: refusal.message }), _jsx("div", { className: "flex flex-wrap gap-2", children: refusal.nextDeliveryDate && refusal.nextDeliveryDate !== deliveryVal && (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => setVal("delivery_date", refusal.nextDeliveryDate), children: ["Volgend haalbaar moment: ", fmtDate(refusal.nextDeliveryDate)] })) }), refusal.kind === "late_signup" && (_jsx(LateSignupChoice, { open: lateOpen, setOpen: setLateOpen, reason: lateReason, setReason: setLateReason }))] })), _jsxs("div", { className: "flex gap-2 pt-2", children: [_jsxs(Button, { className: "flex-1", onClick: handleApprove, children: [_jsx(Check, { className: "h-4 w-4 mr-1" }), " Controleren & bevestigen"] }), _jsxs(Button, { variant: "destructive", onClick: () => onReject(notesVal || ""), children: [_jsx(X, { className: "h-4 w-4 mr-1" }), " Afwijzen"] })] }), _jsx(Dialog, { open: confirmOpen, onOpenChange: (o) => {
|
|
950
|
+
}), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setLines([...lines, { product_id: null, raw_product_text: "", quantity: 1, unit: "stuks", belading: null }]), children: [_jsx(Plus, { className: "h-3 w-3 mr-1" }), " Regel toevoegen"] }), _jsxs("div", { className: "flex justify-between border-t pt-2 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Totaal" }), _jsx("span", { className: "font-medium", children: euro(orderTotal) })] }), linesWithoutPrice > 0 && (_jsxs("div", { className: "rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800", children: ["Geen prijs bekend voor ", linesWithoutPrice, " regel(s). Vul een prijs in; zonder prijs kan de bestelling niet worden aangemaakt."] })), zeroPriceLines > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive space-y-1", children: [_jsxs("div", { children: [zeroPriceLines, " regel(s) met prijs \u20AC 0. Vul de prijs in, of bevestig dat \u20AC 0 klopt."] }), _jsxs("label", { className: "flex items-center gap-2 text-foreground", children: [_jsx("input", { type: "checkbox", className: "h-4 w-4 accent-primary", checked: zeroConfirmed, onChange: (e) => setZeroConfirmed(e.target.checked) }), _jsx("span", { children: "Prijs \u20AC 0 klopt" }), "Prijs \u20AC 0 klopt"] })] }))] }), refusal && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm space-y-2", children: [_jsx("div", { className: "font-medium text-destructive", children: "Bestelling niet aangemaakt \u2014 het voorstel blijft open." }), _jsx("div", { className: "text-destructive", children: refusal.message }), _jsx("div", { className: "flex flex-wrap gap-2", children: refusal.nextDeliveryDate && refusal.nextDeliveryDate !== deliveryVal && (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => setVal("delivery_date", refusal.nextDeliveryDate), children: ["Volgend haalbaar moment: ", fmtDate(refusal.nextDeliveryDate)] })) }), refusal.kind === "late_signup" && (_jsx(LateSignupChoice, { open: lateOpen, setOpen: setLateOpen, reason: lateReason, setReason: setLateReason }))] })), _jsxs("div", { className: "flex gap-2 pt-2", children: [_jsxs(Button, { className: "flex-1", onClick: handleApprove, children: [_jsx(Check, { className: "h-4 w-4 mr-1" }), " Controleren & bevestigen"] }), _jsxs(Button, { variant: "destructive", onClick: () => onReject(notesVal || ""), children: [_jsx(X, { className: "h-4 w-4 mr-1" }), " Afwijzen"] })] }), _jsx(Dialog, { open: confirmOpen, onOpenChange: (o) => {
|
|
945
951
|
if (submitting)
|
|
946
952
|
return;
|
|
947
953
|
setConfirmOpen(o);
|