@flowselections/floriday-verkoop-module 1.0.82 → 1.0.84
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/verkoop/CreateOrderPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/CreateOrderPage.js +7 -3
- package/dist-lib/components/verkoop/FloridayStageLine.js +2 -2
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +1 -1
- package/dist-lib/components/verkoop/PlanCoverageBadge.js +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +9 -9
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +7 -6
- package/dist-lib/integrations/supabase/types.d.ts +271 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/create-order.functions.js +4 -4
- package/dist-lib/lib/floriday-logistic-labels.functions.js +1 -1
- package/dist-lib/lib/order-cancel.server.js +1 -1
- package/dist-lib/lib/plan-coverage.check.d.ts.map +1 -1
- package/dist-lib/lib/plan-coverage.check.js +15 -2
- package/dist-lib/lib/plan-coverage.d.ts +11 -0
- package/dist-lib/lib/plan-coverage.d.ts.map +1 -1
- package/dist-lib/lib/plan-coverage.js +24 -2
- package/dist-lib/lib/salesorders-list.server.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-list.server.js +29 -6
- package/dist-lib/lib/salesorders-mapping.d.ts +2 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AAqFA,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AAqFA,wBAAgB,eAAe,gCAszB9B"}
|
|
@@ -89,7 +89,8 @@ export function CreateOrderPage() {
|
|
|
89
89
|
qc.invalidateQueries({ queryKey: ["co-customers"] });
|
|
90
90
|
}
|
|
91
91
|
catch (e) {
|
|
92
|
-
|
|
92
|
+
console.error(e);
|
|
93
|
+
toast.error(`Klant ${code} kon niet uit de boekhouding worden overgenomen. Ververs de klantenlijst of maak de klant aan bij Klanten.`);
|
|
93
94
|
setCustomerId(null);
|
|
94
95
|
}
|
|
95
96
|
return;
|
|
@@ -337,7 +338,10 @@ export function CreateOrderPage() {
|
|
|
337
338
|
navigate({ to: "/floriday-verkoop/verkooporders" });
|
|
338
339
|
}
|
|
339
340
|
},
|
|
340
|
-
onError: (e) =>
|
|
341
|
+
onError: (e) => {
|
|
342
|
+
console.error(e);
|
|
343
|
+
toast.error("De order is niet aangemaakt. Controleer de regels en probeer opnieuw.");
|
|
344
|
+
},
|
|
341
345
|
});
|
|
342
346
|
return (_jsxs("main", { className: "space-y-5 p-6", children: [_jsx("div", { children: _jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsxs(Link, { to: "/floriday-verkoop/verkooporders", children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), "Terug naar verkooporders"] }) }) }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Nieuwe Bestelling" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Doorloop de stappen: klant \u2192 afleverlocatie \u2192 afhaallocatie \u2192 vervoerder \u2192 leverdatum \u2192 producten." })] }), _jsxs(CardContent, { className: "space-y-5", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs(Label, { className: "flex items-center gap-2", children: ["Klant ", _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx(SearchableSelect, { value: customerId, placeholder: customersQ.isLoading ? "Laden..." : "Kies klant...", options: customers.map((c) => ({
|
|
343
347
|
value: c.id,
|
|
@@ -513,7 +517,7 @@ export function CreateOrderPage() {
|
|
|
513
517
|
? "border-destructive/40 bg-destructive/5 text-destructive"
|
|
514
518
|
: "border-amber-500/40 bg-amber-500/5 text-amber-700"}`, children: [_jsx("div", { className: "font-medium", children: stockBlocked
|
|
515
519
|
? "Bestelling geblokkeerd — onvoldoende voorraad"
|
|
516
|
-
: "Let op: tekorten (uitleveren zonder voorraad staat aan)" }), _jsx("ul", { className: "mt-1 space-y-0.5", children: stockCheck.shortages.map((s) => (_jsxs("li", { children: [s.product, ": besteld ", s.wanted, ", beschikbaar ", s.available, ", tekort ", s.missing] }, s.productId))) })] })), _jsxs("div", { className: "flex items-center justify-end gap-2 pt-2", children: [_jsx(Button, { variant: "outline", onClick: () => navigate({ to: "/floriday-verkoop/verkooporders" }), disabled: createMut.isPending, children: "Annuleren" }), _jsx(Button, { onClick: () => createMut.mutate(), disabled: createMut.isPending || stockBlocked || stockQ.isFetching, title: stockBlocked ? "Onvoldoende voorraad
|
|
520
|
+
: "Let op: tekorten (uitleveren zonder voorraad staat aan)" }), _jsx("ul", { className: "mt-1 space-y-0.5", children: stockCheck.shortages.map((s) => (_jsxs("li", { children: [s.product, ": besteld ", s.wanted, ", beschikbaar ", s.available, ", tekort ", s.missing] }, s.productId))) })] })), _jsxs("div", { className: "flex items-center justify-end gap-2 pt-2", children: [_jsx(Button, { variant: "outline", onClick: () => navigate({ to: "/floriday-verkoop/verkooporders" }), disabled: createMut.isPending, children: "Annuleren" }), _jsx(Button, { onClick: () => createMut.mutate(), disabled: createMut.isPending || stockBlocked || stockQ.isFetching, title: stockBlocked ? "Onvoldoende voorraad; deze order kan zo niet worden aangemaakt. Pas de aantallen aan." : undefined, children: createMut.isPending
|
|
517
521
|
? "Bezig..."
|
|
518
522
|
: stockQ.isFetching
|
|
519
523
|
? "Voorraad controleren..."
|
|
@@ -11,12 +11,12 @@ export function FloridayStageLine({ status, stage, floridayFulfilled, isFloriday
|
|
|
11
11
|
const bufferHint = bufferSize && bufferSize > 1 && notReportedCount
|
|
12
12
|
? ` (${notReportedCount} van ${bufferSize} nog niet afgemeld)`
|
|
13
13
|
: "";
|
|
14
|
-
const notReported = warn ? (_jsx("div", { className: "mt-1", children: _jsxs(Badge, { variant: "outline", className: "border-amber-400/60 bg-amber-50 text-amber-800", children: [_jsx(AlertTriangle, { className: "mr-1 h-3 w-3" }), "
|
|
14
|
+
const notReported = warn ? (_jsx("div", { className: "mt-1", children: _jsxs(Badge, { variant: "outline", className: "border-amber-400/60 bg-amber-50 text-amber-800", children: [_jsx(AlertTriangle, { className: "mr-1 h-3 w-3" }), "Afgehandeld, nog niet gemeld bij Floriday", nr === "waarschuwing_onbekend" ? " (stand bij Floriday onbekend)" : "", bufferHint] }) })) : nr === "al_afgehandeld" ? (_jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Al afgehandeld in Floriday" })) : null;
|
|
15
15
|
if (!status)
|
|
16
16
|
return notReported;
|
|
17
17
|
const unknown = status.stage === "onbekend";
|
|
18
18
|
const deviates = !warn && deviatesFromFloriday(status.stage, stage);
|
|
19
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1 text-xs text-muted-foreground", children: [_jsxs("span", { title: unknown
|
|
19
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1 text-xs text-muted-foreground", children: [_jsxs("span", { title: unknown ? "Status bij Floriday nu niet beschikbaar." : undefined, children: ["Floriday: ", unknown ? "stand onbekend" : floridayStageLabel(status.stage)] }), deviates && (_jsxs(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: [_jsx(AlertTriangle, { className: "mr-1 h-3 w-3" }), "Wijkt af van Floriday"] }))] }), notReported] }));
|
|
20
20
|
}
|
|
21
21
|
export function MissingPriceBadge({ show }) {
|
|
22
22
|
if (!show)
|
|
@@ -51,7 +51,7 @@ export function OrderKarindelingCard({ order }) {
|
|
|
51
51
|
p.completedAt ? `Afgerond ${fmt(p.completedAt)}` : null,
|
|
52
52
|
]
|
|
53
53
|
.filter(Boolean)
|
|
54
|
-
.join(" · "), children: [p.documentNumber ?? "pickrij", p.completedAt ? " ✓" : ""] }, p.queueItemId ?? i))) })] }))] }), cov.state === "onbekend" && cov.error && (_jsx("p", { className: "text-sm text-muted-foreground", children: cov.error })), carts.map((c) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("button", { type: "button", className: "flex items-center gap-2 rounded-sm text-left hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setLayersFor({ id: c.cartId, number: c.cartNumber ?? 0 }), title: "Bekijk de lagen van deze kar", children: [_jsx(LayoutGrid, { className: "h-4 w-4 text-muted-foreground" }), _jsxs("span", { className: "font-mono font-medium", children: ["Kar ", c.cartNumber ?? "—"] })] }), c.shared && _jsx(Badge, { variant: "outline", children: "
|
|
54
|
+
.join(" · "), children: [p.documentNumber ?? "pickrij", p.completedAt ? " ✓" : ""] }, p.queueItemId ?? i))) })] }))] }), cov.state === "onbekend" && cov.error && (_jsx("p", { className: "text-sm text-muted-foreground", children: cov.error })), carts.map((c) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("button", { type: "button", className: "flex items-center gap-2 rounded-sm text-left hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setLayersFor({ id: c.cartId, number: c.cartNumber ?? 0 }), title: "Bekijk de lagen van deze kar", children: [_jsx(LayoutGrid, { className: "h-4 w-4 text-muted-foreground" }), _jsxs("span", { className: "font-mono font-medium", children: ["Kar ", c.cartNumber ?? "—"] })] }), c.shared && _jsx(Badge, { variant: "outline", children: "Gedeeld met gecombineerde order" }), c.carrierType && (_jsx(Badge, { variant: "outline", className: "font-mono text-[10px]", children: c.carrierType }))] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel (deze order)" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { className: "text-right", children: "Dozen" })] }) }), _jsx(TableBody, { children: (Array.isArray(c.lines) ? c.lines : []).map((l, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: resolveProductName(l.productName) ?? "—" }), _jsx(TableCell, { className: "text-right", children: l.crates }), _jsx(TableCell, { className: "text-right", children: l.boxes })] }, `${l.orderItemId ?? "x"}-${i}`))) })] })] }, c.cartId)))] })) : null }), _jsx(CartLayersDialog, { cartId: layersFor?.id ?? null, cartNumber: layersFor?.number ?? null, open: !!layersFor, onOpenChange: (v) => {
|
|
55
55
|
if (!v)
|
|
56
56
|
setLayersFor(null);
|
|
57
57
|
} })] }));
|
|
@@ -20,7 +20,7 @@ export function PlanCoverageBadge({ coverage, showReason = true, }) {
|
|
|
20
20
|
const text = state === "deels" && progressPct != null
|
|
21
21
|
? `${label} · ${Math.round(progressPct)}%`
|
|
22
22
|
: state === "ingedeeld" && shared
|
|
23
|
-
? `${label} ·
|
|
23
|
+
? `${label} · gecombineerde order`
|
|
24
24
|
: label;
|
|
25
25
|
return (_jsx("div", { className: "mt-1", children: _jsx("span", { className: `${base} ${tone}`, title: tip, children: text }) }));
|
|
26
26
|
}
|
|
@@ -256,7 +256,7 @@ export function SalesOrderDetailView({ order, sellerFallback, hideKarindeling =
|
|
|
256
256
|
const bestellingLabel = orderStageLabel(order.stage ?? (order.status.isCancelled ? "cancelled" : "incoming"));
|
|
257
257
|
return (_jsxs("div", { className: "space-y-6", children: [order.needsManualReview ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Handmatige beoordeling nodig" }), _jsxs("div", { className: "text-muted-foreground", children: [order.needsManualReview.reason, order.needsManualReview.at
|
|
258
258
|
? ` (geconstateerd op ${new Date(order.needsManualReview.at).toLocaleString("nl-NL")})`
|
|
259
|
-
: ""] })] })) : null, order.mixedDeliveryDates ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Bestellingen met verschillende leverdatums" }), _jsx("div", { className: "text-muted-foreground", children: "Deze order bestaat uit Floriday-bestellingen met verschillende leverdatums. De vroegste leverdatum is aangehouden." })] })) : null, (order.unlinkedProducts?.length ?? 0) > 0 ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Floriday-artikel niet gekoppeld aan product" }), _jsx("ul", { className: "mt-1 space-y-0.5 text-muted-foreground", children: order.unlinkedProducts.map((u, i) => (_jsxs("li", { children: [u.name, " \u2014 trade-item-id ", u.tradeItemId ?? "onbekend"] }, i))) }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Koppel dit
|
|
259
|
+
: ""] })] })) : null, order.mixedDeliveryDates ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Bestellingen met verschillende leverdatums" }), _jsx("div", { className: "text-muted-foreground", children: "Deze order bestaat uit Floriday-bestellingen met verschillende leverdatums. De vroegste leverdatum is aangehouden." })] })) : null, (order.unlinkedProducts?.length ?? 0) > 0 ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Floriday-artikel niet gekoppeld aan product" }), _jsx("ul", { className: "mt-1 space-y-0.5 text-muted-foreground", children: order.unlinkedProducts.map((u, i) => (_jsxs("li", { children: [u.name, " \u2014 trade-item-id ", u.tradeItemId ?? "onbekend"] }, i))) }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Koppel dit Floriday-artikel aan een eigen product; bij de volgende update wordt het overgenomen." })] })) : null, _jsxs("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [_jsx("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted", children: order.imageUrl ? (_jsx("img", { src: order.imageUrl, alt: "", className: "h-full w-full object-cover" })) : (_jsx(ImageIcon, { className: "h-6 w-6 text-muted-foreground" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "truncate text-base font-semibold text-foreground", children: [order.productName, o.tradeItemVersion ? (_jsxs("span", { className: "ml-2 text-xs font-normal text-muted-foreground", children: ["\u00B7 v", o.tradeItemVersion] })) : null] }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: order.orderNumber || order.sku || "—" })] })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-[1fr_360px]", children: [_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsx(SectionTitle, { children: "Verkooporder" }), _jsx(Row, { label: "Ordernummer", children: order.orderNumber || "—" }), _jsx(Row, { label: "Handelsvorm", children: tradingType }), _jsx(Row, { label: "Bestelmoment", children: fmtDateTime(order.orderedAt) }), _jsx(Row, { label: "Aantal", children: _jsxs("div", { className: "flex flex-wrap gap-4", children: [_jsxs("div", { children: [formatLoadUnits(order.fustCount, order.crateTypeName), " fusten"] }), _jsxs("div", { children: [formatLoadUnits(order.karCount, order.cartTypeName), " karren", order.karShared ? " (gedeeld met buffer)" : "", _jsx(PlanCoverageBadge, { coverage: order.planCoverage })] })] }) }), _jsx(Row, { label: "Belading", children: belading }), _jsx(Row, { label: "Klant referentie", children: klantReferentie }), _jsx(Row, { label: "Floriday-referentie", children: floridayRef }), _jsx(Row, { label: "Verkoopkanaal", children: verkoopkanaal }), _jsx(Row, { label: "Financi\u00EBle afhandeling", children: financial }), _jsx(Row, { label: "Verkoper", children: sellerName ? (_jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx("span", { className: "inline-flex h-6 w-6 items-center justify-center rounded-full bg-muted text-[10px] font-semibold text-muted-foreground", children: initials(sellerName) }), sellerName] })) : ("—") })] }), fs && (_jsxs("div", { children: [_jsx(SectionTitle, { children: "Floriday" }), _jsx(Row, { label: "Stand", children: _jsx(FloridayStageLine, { status: fs, stage: order.stage, floridayFulfilled: order.floridayFulfilled, isFloriday: true }) }), _jsxs(Row, { label: "Herkomst status", children: [order.statusOrigin === "floriday" ? "Floriday" : "ERP", order.statusChangedAt ? ` · ${fmtDateTime(order.statusChangedAt)}` : ""] }), fs.entries.map((e) => (_jsx(Row, { label: `Bestelling ${e.salesOrderId.slice(0, 8)}`, children: _jsxs("div", { className: "space-y-0.5 text-sm", children: [_jsxs("div", { children: ["Floriday-status: ", e.salesOrderStatus ?? "—"] }), _jsxs("div", { children: ["Afleververzoeken: ", e.fulfillmentRequests.length, " \u00B7 Afhandelingen:", " ", e.fulfillmentOrders.length
|
|
260
260
|
? e.fulfillmentOrders.map((f) => f.status ?? "?").join(", ")
|
|
261
261
|
: "geen"] }), _jsxs("div", { children: ["Verkoopkanaal: ", e.salesChannel ?? "—", " \u00B7 Handelsvorm: ", e.tradeInstrument ?? "—", " \u00B7 Incoterm: ", e.incoterm ?? "niet opgegeven"] }), _jsxs("div", { children: ["Klantreferentie: ", e.customerOrderId ?? "—", " \u00B7 Floriday-referentie: ", e.salesChannelOrderId ?? "—"] }), _jsxs("div", { children: ["Koper: ", e.customerOrganizationId ?? "—", " \u00B7 GLN: ", e.customerGln ?? "—"] }), _jsxs("div", { className: "text-xs text-muted-foreground", children: ["Laatst gewijzigd: ", e.lastModifiedDateTime ? fmtDateTime(e.lastModifiedDateTime) : "—", " \u00B7 Ververst: ", e.cachedAt ? fmtDateTime(e.cachedAt) : "—"] })] }) }, e.salesOrderId)))] })), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Levering" }), _jsx(Row, { label: "Afleverdatum", children: fmtDateTime(order.deliveryAt) }), _jsx(Row, { label: "Incoterm", children: incoterm }), _jsx(Row, { label: "Afleveradres", children: _jsx(AddressCard, { icon: _jsx(MapPin, { className: "h-5 w-5" }), lines: resolvedAddresses?.delivery
|
|
262
262
|
? [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAsBjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAyGnE,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAG1D;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7C,
|
|
1
|
+
{"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAsBjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAyGnE,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAG1D;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7C,qBA+SA"}
|
|
@@ -59,8 +59,8 @@ function StatusTag({ order }) {
|
|
|
59
59
|
return (_jsxs("div", { className: "flex flex-col items-start gap-1", children: [_jsxs(Badge, { variant: "outline", className: `inline-flex items-center gap-1.5 border-transparent ${orderStageBadgeClass(stage)}`, children: [orderStageLabel(stage), _jsx("span", { "aria-label": originTitle, title: originTitle, className: `inline-block size-2 shrink-0 rounded-full ${origin === "floriday" ? "bg-emerald-500" : "bg-blue-500"}` })] }), fulfilledCount > 0 && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "Administratief doorgegeven aan Floriday. Dit bepaalt de orderstatus niet.", children: bufferSize > 1
|
|
60
60
|
? `${fulfilledCount} van ${bufferSize} doorgegeven aan Floriday`
|
|
61
61
|
: "Doorgegeven aan Floriday" })), order.backlog && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-amber-100 text-[11px] font-medium text-amber-900", title: order.backlogLeverdatum
|
|
62
|
-
?
|
|
63
|
-
: "Leverdatum is
|
|
62
|
+
? "Leverdatum is voorbij, maar de order is nog niet gepickt."
|
|
63
|
+
: "Leverdatum is voorbij, maar de order is nog niet gepickt.", children: order.backlogDays != null
|
|
64
64
|
? `Achterstand · ${order.backlogDays} ${order.backlogDays === 1 ? "dag" : "dagen"}`
|
|
65
65
|
: "Achterstand" })), !order.backlog && order.backlogUnknown && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "De achterstand kon niet bij de Logistiek Engine worden opgevraagd", children: "achterstand onbekend" }))] }));
|
|
66
66
|
}
|
|
@@ -89,7 +89,7 @@ export function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder
|
|
|
89
89
|
next.has(id) ? next.delete(id) : next.add(id);
|
|
90
90
|
applySelection(Array.from(next));
|
|
91
91
|
};
|
|
92
|
-
return (_jsx("div", { className: "flex flex-col h-full rounded-lg border border-border bg-card", children: _jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overflow-x-auto overscroll-contain [scrollbar-gutter:stable]", style: { WebkitOverflowScrolling: "touch" }, children: _jsxs(Table, { className: "min-w-[950px] [&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10 [&_thead_th]:bg-card", children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { className: "w-10", children: _jsx(Checkbox, { "aria-label": "Alle bestellingen selecteren", checked: allChecked ? true : someChecked ? "indeterminate" : false, onCheckedChange: (v) => applySelection(v === true ? rowIds : []) }) }), _jsx(TableHead, { children: "Levering" }), _jsx(TableHead, { children: "Pickdag" }), _jsx(TableHead, { children: "Klant" }), _jsx(TableHead, { children: "
|
|
92
|
+
return (_jsx("div", { className: "flex flex-col h-full rounded-lg border border-border bg-card", children: _jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overflow-x-auto overscroll-contain [scrollbar-gutter:stable]", style: { WebkitOverflowScrolling: "touch" }, children: _jsxs(Table, { className: "min-w-[950px] [&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10 [&_thead_th]:bg-card", children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { className: "w-10", children: _jsx(Checkbox, { "aria-label": "Alle bestellingen selecteren", checked: allChecked ? true : someChecked ? "indeterminate" : false, onCheckedChange: (v) => applySelection(v === true ? rowIds : []) }) }), _jsx(TableHead, { children: "Levering" }), _jsx(TableHead, { children: "Pickdag" }), _jsx(TableHead, { children: "Klant" }), _jsx(TableHead, { children: "Karren" }), _jsx(TableHead, { children: "Fusten" }), _jsx(TableHead, { children: "Vervoerder" }), _jsx(TableHead, { children: "Status" }), showRevenue && _jsx(TableHead, { children: "Omzet" }), _jsx(TableHead, { children: _jsxs("span", { className: "inline-flex items-center gap-1", children: ["Besteld ", _jsx(ArrowDown, { className: "h-3 w-3" })] }) }), _jsx(TableHead, { className: "w-10" })] }) }), _jsxs(TableBody, { children: [loading &&
|
|
93
93
|
Array.from({ length: 6 }).map((_, i) => (_jsx(TableRow, { children: Array.from({ length: columnCount + 1 }).map((__, j) => (_jsx(TableCell, { children: _jsx(Skeleton, { className: "h-6 w-full" }) }, j))) }, `s-${i}`))), !loading && orders.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: columnCount + 1, className: "py-12 text-center text-muted-foreground", children: "Geen verkooporders gevonden." }) })), !loading &&
|
|
94
94
|
orders.map((row) => {
|
|
95
95
|
// Buffers zijn serverside al samengevouwen tot één rij.
|
|
@@ -100,26 +100,26 @@ export function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder
|
|
|
100
100
|
const delivery = formatDelivery(row.deliveryAt);
|
|
101
101
|
const reserved = row.reservationCount ?? (row.isReservation ? 1 : 0);
|
|
102
102
|
const incomplete = row.incomplete ?? [];
|
|
103
|
-
return (_jsxs(TableRow, { className: `align-top cursor-pointer ${isBuffer ? "bg-muted/20 border-l-2 border-primary/40" : ""}`, onClick: () => onSelectOrder?.(row), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(rowId), onCheckedChange: () => toggle(rowId) }) }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: delivery.date }), delivery.time && (_jsx("div", { className: "text-xs text-muted-foreground", children: delivery.time }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: formatPickDate(row.pickDate) }), row.pickupLabel && (_jsxs("div", { className: "text-xs text-muted-foreground", title: "Ophaalmoment van de vervoerder", children: ["Ophalen: ", row.pickupLabel] })), _jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: row.printedAt && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "Deze order is al uitgeprint.", children: "uitgeprint" })) })] }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: row.customer.name }), isBuffer && (_jsxs(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: ["
|
|
103
|
+
return (_jsxs(TableRow, { className: `align-top cursor-pointer ${isBuffer ? "bg-muted/20 border-l-2 border-primary/40" : ""}`, onClick: () => onSelectOrder?.(row), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(rowId), onCheckedChange: () => toggle(rowId) }) }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: delivery.date }), delivery.time && (_jsx("div", { className: "text-xs text-muted-foreground", children: delivery.time }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: formatPickDate(row.pickDate) }), row.pickupLabel && (_jsxs("div", { className: "text-xs text-muted-foreground", title: "Ophaalmoment van de vervoerder", children: ["Ophalen: ", row.pickupLabel] })), _jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: row.printedAt && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "Deze order is al uitgeprint.", children: "uitgeprint" })) })] }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: row.customer.name }), isBuffer && (_jsxs(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: ["Gecombineerd \u00B7 ", bufferSize] })), _jsx(MissingPriceBadge, { show: row.missingPrice }), reserved > 0 && (_jsx(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: reserved === bufferSize
|
|
104
104
|
? "Reservering"
|
|
105
105
|
: `Reservering · ${reserved} van ${bufferSize}` }))] }), row.customer.legalName && (_jsx("div", { className: "text-xs text-muted-foreground", children: row.customer.legalName })), _jsx("div", { className: "text-xs text-muted-foreground", children: [row.customer.postalCode, row.customer.city].filter(Boolean).join(" ") }), incomplete.length > 0 && (_jsxs("div", { className: "mt-1 inline-flex items-center gap-1 text-xs text-amber-600", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), incomplete.join(" · ")] })), (row.unlinkedProducts?.length ?? 0) > 0 && (_jsxs("div", { className: "mt-1 flex items-start gap-1 text-xs text-destructive", title: row.unlinkedProducts
|
|
106
106
|
.map((u) => `${u.name} (trade-item ${u.tradeItemId ?? "onbekend"})`)
|
|
107
107
|
.join("\n"), children: [_jsx(AlertTriangle, { className: "mt-0.5 h-3 w-3 shrink-0" }), _jsxs("span", { children: ["Floriday-artikel niet gekoppeld aan product:", " ", row.unlinkedProducts
|
|
108
108
|
.map((u) => `${u.name} (trade-item ${u.tradeItemId ?? "onbekend"})`)
|
|
109
|
-
.join(", ")] })] }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: row.engineCounts && row.karCount > 0 ? (_jsxs(_Fragment, { children: [formatLoadUnits(row.karCount, row.cartTypeName), row.karShared && (_jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "(gedeeld met
|
|
109
|
+
.join(", ")] })] }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: row.karUnknown ? (_jsx("span", { className: "text-muted-foreground", children: "Karren onbekend" })) : row.engineCounts && row.karCount > 0 ? (_jsxs(_Fragment, { children: [formatLoadUnits(row.karCount, row.cartTypeName), row.karShared && isBuffer && (_jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "(gedeeld met gecombineerde order)" }))] })) : (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })) }), _jsx(PlanCoverageBadge, { coverage: row.planCoverage }), _jsx(FloridayStageLine, { status: row.floridayStatus, stage: row.stage, floridayFulfilled: isBuffer ? !row.notReportedToFloriday : row.floridayFulfilled, isFloriday: !!row.notReportedToFloriday || (row.floridayIds?.length ?? 0) > 0, notReportedCount: row.notReportedCount, bufferSize: bufferSize })] }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: formatLoadUnits(row.fustCount, row.crateTypeName) }) }), _jsx(TableCell, { className: "text-sm text-foreground", children: row.carrierName || _jsx("span", { className: "text-muted-foreground", children: "\u2014" }) }), _jsx(TableCell, { children: _jsx(StatusTag, { order: row }) }), showRevenue && (_jsxs(TableCell, { className: "font-medium text-foreground", children: ["\u20AC ", Math.round(row.revenue ?? 0).toLocaleString("nl-NL")] })), _jsxs(TableCell, { children: [_jsx("div", { className: "text-sm text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: isBuffer
|
|
110
110
|
? `${bufferSize} orders`
|
|
111
111
|
: row.orderNumber || ordered.time })] }), _jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { disabled: isBuffer || !row.isLocal, onClick: () => !isBuffer && row.isLocal && onEditOrder?.(row), title: isBuffer
|
|
112
|
-
? "
|
|
112
|
+
? "Een gecombineerde order kun je niet in één keer bewerken."
|
|
113
113
|
: row.isLocal
|
|
114
114
|
? undefined
|
|
115
|
-
: "
|
|
115
|
+
: "Floriday-orders annuleer of wijzig je in Floriday.", children: "Bewerken" }), _jsx(DropdownMenuItem, { onClick: () => onSelectOrder?.(row), children: "Details bekijken" }), _jsx(DropdownMenuItem, { disabled: row.stage === "shipped" ||
|
|
116
116
|
row.stage === "cancelled" ||
|
|
117
117
|
fulfillingId === rowId, onClick: () => onFulfillOrder?.(row), title: "Order afhandelen: karren gereedmelden en status op Verzonden zetten.", children: fulfillingId === rowId
|
|
118
118
|
? "Bezig met afhandelen…"
|
|
119
119
|
: row.stage === "shipped"
|
|
120
120
|
? "Al afgehandeld"
|
|
121
121
|
: "Afhandelen (verzonden)" }), !isBuffer && row.isLocal ? (_jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onClick: () => onDeleteOrder?.(row), children: row.stage === "cancelled" ? "Definitief verwijderen" : "Annuleren" })) : (_jsxs(DropdownMenuItem, { disabled: true, title: isBuffer
|
|
122
|
-
? "
|
|
123
|
-
: "
|
|
122
|
+
? "Een gecombineerde order kun je niet in één keer annuleren."
|
|
123
|
+
: "Floriday-orders annuleer of wijzig je in Floriday.", children: ["Annuleren", isBuffer ? "" : " (FO)"] }))] })] }) })] }, rowId));
|
|
124
124
|
})] })] }) }) }));
|
|
125
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerkoopOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/VerkoopOrdersPage.tsx"],"names":[],"mappings":"AAkFA,wBAAgB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"VerkoopOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/VerkoopOrdersPage.tsx"],"names":[],"mappings":"AAkFA,wBAAgB,iBAAiB,gCA4sBhC"}
|
|
@@ -23,7 +23,7 @@ import { ORDER_STAGES } from "../../lib/order-status";
|
|
|
23
23
|
const BACKLOG_TAB = {
|
|
24
24
|
id: "backlog",
|
|
25
25
|
label: "Te picken (achterstand)",
|
|
26
|
-
hint: "
|
|
26
|
+
hint: "Leverdatum is voorbij, maar de order is nog niet gepickt.",
|
|
27
27
|
};
|
|
28
28
|
const STATUS_TABS = [
|
|
29
29
|
{ id: "all", label: "Alle" },
|
|
@@ -36,7 +36,7 @@ const STATUS_TABS = [
|
|
|
36
36
|
{
|
|
37
37
|
id: "not_reported",
|
|
38
38
|
label: "Nog niet afgemeld bij Floriday",
|
|
39
|
-
hint: "
|
|
39
|
+
hint: "Afgehandeld, nog niet gemeld bij Floriday.",
|
|
40
40
|
},
|
|
41
41
|
];
|
|
42
42
|
// Statusfiltering, buffer-groepering en totalen gebeuren serverside
|
|
@@ -293,13 +293,14 @@ export function VerkoopOrdersPage() {
|
|
|
293
293
|
}
|
|
294
294
|
else {
|
|
295
295
|
toast.success(res.mirrored > 0
|
|
296
|
-
? `${res.mirrored} Floriday-order(s) bijgewerkt.
|
|
296
|
+
? `${res.mirrored} Floriday-order(s) bijgewerkt. De karren worden automatisch verdeeld.`
|
|
297
297
|
: "Alle Floriday-orders zijn al bijgewerkt.");
|
|
298
298
|
}
|
|
299
299
|
await refetch();
|
|
300
300
|
}
|
|
301
301
|
catch (e) {
|
|
302
|
-
|
|
302
|
+
console.error(e);
|
|
303
|
+
toast.error("Floriday-orders bijwerken is niet gelukt. Probeer het zo opnieuw.");
|
|
303
304
|
}
|
|
304
305
|
finally {
|
|
305
306
|
setSyncing(false);
|
|
@@ -334,14 +335,14 @@ export function VerkoopOrdersPage() {
|
|
|
334
335
|
params: { salesOrderId: o.id },
|
|
335
336
|
}), onDeleteOrder: (o) => {
|
|
336
337
|
if (!o.isLocal) {
|
|
337
|
-
toast.error("
|
|
338
|
+
toast.error("Floriday-orders annuleer of wijzig je in Floriday.");
|
|
338
339
|
return;
|
|
339
340
|
}
|
|
340
341
|
setCancelReason("");
|
|
341
342
|
setPendingAction({ rows: [o], mode: o.stage === "cancelled" ? "delete" : "cancel" });
|
|
342
343
|
}, onEditOrder: (o) => {
|
|
343
344
|
if (!o.isLocal) {
|
|
344
|
-
toast.error("
|
|
345
|
+
toast.error("Floriday-orders annuleer of wijzig je in Floriday.");
|
|
345
346
|
return;
|
|
346
347
|
}
|
|
347
348
|
const rawId = o.id.startsWith("local:") ? o.id.slice("local:".length) : o.id;
|