@flowselections/logistiek-engine 1.0.90 → 1.0.98
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/FlowOrders.js +1 -1
- package/dist-lib/components/MisluktVerzendbrievenCard.d.ts +2 -0
- package/dist-lib/components/MisluktVerzendbrievenCard.d.ts.map +1 -0
- package/dist-lib/components/MisluktVerzendbrievenCard.js +50 -0
- package/dist-lib/components/RegiePage.d.ts.map +1 -1
- package/dist-lib/components/RegiePage.js +2 -1
- package/dist-lib/components/RuleEnginePage.d.ts.map +1 -1
- package/dist-lib/components/RuleEnginePage.js +3 -1
- package/dist-lib/hooks/useShippingNoteStatus.d.ts +2 -0
- package/dist-lib/hooks/useShippingNoteStatus.d.ts.map +1 -1
- package/dist-lib/hooks/useShippingNoteStatus.js +13 -1
- package/dist-lib/hooks/useShippingNoteStatus.test.d.ts +2 -0
- package/dist-lib/hooks/useShippingNoteStatus.test.d.ts.map +1 -0
- package/dist-lib/hooks/useShippingNoteStatus.test.js +20 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +415 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +415 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +415 -0
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +423 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/cartCoverage.functions.d.ts +415 -0
- package/dist-lib/lib/cartCoverage.functions.d.ts.map +1 -1
- package/dist-lib/lib/controlScan.server.d.ts +2 -0
- package/dist-lib/lib/controlScan.server.d.ts.map +1 -1
- package/dist-lib/lib/controlScan.server.js +59 -53
- package/dist-lib/lib/floridayDocuments.functions.d.ts +1245 -0
- package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -1
- package/dist-lib/lib/floridayPush.functions.d.ts +415 -0
- package/dist-lib/lib/floridayPush.functions.d.ts.map +1 -1
- package/dist-lib/lib/layoutPrint.server.d.ts +27 -0
- package/dist-lib/lib/layoutPrint.server.d.ts.map +1 -0
- package/dist-lib/lib/layoutPrint.server.js +48 -0
- package/dist-lib/lib/layoutPrint.test.d.ts +2 -0
- package/dist-lib/lib/layoutPrint.test.d.ts.map +1 -0
- package/dist-lib/lib/layoutPrint.test.js +47 -0
- package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +2075 -0
- package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -1
- package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
- package/dist-lib/lib/loadCarrierPlanning.server.js +52 -8
- package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +830 -0
- package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -1
- package/dist-lib/lib/logisticsRecalculate.functions.d.ts +415 -0
- package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -1
- package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
- package/dist-lib/lib/modulePrompts.js +54 -0
- package/dist-lib/lib/plannerDiff.functions.d.ts +415 -0
- package/dist-lib/lib/plannerDiff.functions.d.ts.map +1 -1
- package/dist-lib/lib/ruleEngineSchema.js +2 -2
- package/dist-lib/lib/shippingNoteQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/shippingNoteQueue.server.js +40 -49
- package/package.json +1 -1
|
@@ -149,7 +149,7 @@ export function FlowOrders({ onRoute }) {
|
|
|
149
149
|
["fout", "Vastgelopen"],
|
|
150
150
|
["bezig", "Bezig / wachtend"],
|
|
151
151
|
["klaar", "Overig"],
|
|
152
|
-
].map(([w, l]) => (_jsx(Button, { size: "sm", variant: filter === w ? "default" : "outline", onClick: () => setFilter(w), children: l }, w))), _jsx(Button, { size: "sm", variant: "outline", onClick: () => setSortering((s) => (s === "nieuw" ? "oud" : "nieuw")), children: sortering === "nieuw" ? "Nieuwste eerst" : "Oudste eerst" }), _jsxs("span", { className: "ml-auto text-xs text-muted-foreground", children: [gefilterd.length, " orders"] })] })] }), _jsxs(CardContent, { className: "space-y-3", children: [error && (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2", children: [_jsx("p", { className: "text-sm text-destructive", children: error }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void refresh(), disabled: loading, children: [_jsx(RefreshCw, { className: `mr-1 h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` }), "Opnieuw proberen"] })] })), loading && veiligeRows.length === 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" })] })) : gefilterd.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Geen orders gevonden." })) : (_jsx("div", { className: "max-h-[420px] overflow-y-auto rounded-md border border-border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "sticky top-0 bg-muted/60 text-xs text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Order" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Klant" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Bron" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Levering" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Stand" }), _jsx("th", { className: "px-2 py-1.5 text-right font-medium", children: "Versies" }), _jsx("th", { className: "px-2 py-1.5 text-right font-medium", children: "Fouten" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Laatste activiteit" })] }) }), _jsx("tbody", { children: gefilterd.map((r) => {
|
|
152
|
+
].map(([w, l]) => (_jsx(Button, { size: "sm", variant: filter === w ? "default" : "outline", onClick: () => setFilter(w), children: l }, w))), _jsx(Button, { size: "sm", variant: "outline", onClick: () => setSortering((s) => (s === "nieuw" ? "oud" : "nieuw")), children: sortering === "nieuw" ? "Nieuwste eerst" : "Oudste eerst" }), _jsxs("span", { className: "ml-auto text-xs text-muted-foreground", children: [gefilterd.length, " orders"] })] })] }), _jsxs(CardContent, { className: "space-y-3", children: [error && (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2", children: [_jsx("p", { className: "text-sm text-destructive", children: error }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void refresh(), disabled: loading, children: [_jsx(RefreshCw, { className: `mr-1 h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` }), "Opnieuw proberen"] })] })), loading && veiligeRows.length === 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" })] })) : gefilterd.length === 0 ? (error ? null : _jsx("p", { className: "text-sm text-muted-foreground", children: "Geen orders gevonden." })) : (_jsx("div", { className: "max-h-[420px] overflow-y-auto rounded-md border border-border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "sticky top-0 bg-muted/60 text-xs text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Order" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Klant" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Bron" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Levering" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Stand" }), _jsx("th", { className: "px-2 py-1.5 text-right font-medium", children: "Versies" }), _jsx("th", { className: "px-2 py-1.5 text-right font-medium", children: "Fouten" }), _jsx("th", { className: "px-2 py-1.5 text-left font-medium", children: "Laatste activiteit" })] }) }), _jsx("tbody", { children: gefilterd.map((r) => {
|
|
153
153
|
const st = orderStand(r);
|
|
154
154
|
const actief = r.orderNumber === orderRef;
|
|
155
155
|
return (_jsxs("tr", { className: `cursor-pointer border-t border-border hover:bg-muted/40 ${actief ? "bg-primary/10" : ""}`, onClick: () => kies(r.orderNumber), children: [_jsx("td", { className: "px-2 py-1.5 font-medium", children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [actief ? _jsx(ChevronDown, { className: "h-3.5 w-3.5" }) : _jsx(ChevronRight, { className: "h-3.5 w-3.5" }), r.orderNumber] }) }), _jsx("td", { className: "max-w-[180px] truncate px-2 py-1.5", children: r.customerName ?? "—" }), _jsx("td", { className: "px-2 py-1.5", children: r.orderSource === "floriday" ? "Floriday" : r.orderSource ? "Eigen verkoop" : "—" }), _jsx("td", { className: "px-2 py-1.5", children: r.deliveryDate ?? "—" }), _jsxs("td", { className: "px-2 py-1.5", children: [_jsx(Badge, { variant: st.kleur, children: st.label }), r.reasonCode && st.kleur === "destructive" && (_jsx("span", { className: "ml-1 text-xs text-muted-foreground", children: redenTekst(r.reasonCode) }))] }), _jsx("td", { className: "px-2 py-1.5 text-right tabular-nums", children: r.versions }), _jsx("td", { className: `px-2 py-1.5 text-right tabular-nums ${r.errors > 0 ? "text-destructive" : ""}`, children: r.errors }), _jsx("td", { className: "px-2 py-1.5 text-xs text-muted-foreground", children: tijd(r.lastAt ?? r.createdAt) })] }, r.orderNumber));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MisluktVerzendbrievenCard.d.ts","sourceRoot":"","sources":["../../src/components/MisluktVerzendbrievenCard.tsx"],"names":[],"mappings":"AAmBA,wBAAgB,yBAAyB,gCAqExC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// src/components/MisluktVerzendbrievenCard.tsx — mislukte Floriday-verzendbrieven
|
|
4
|
+
// bij een pakbon, met per regel "Opnieuw proberen". Opnieuw scannen is niet nodig.
|
|
5
|
+
// ============================================================================
|
|
6
|
+
import { useCallback, useEffect, useState } from "react";
|
|
7
|
+
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from "@flowselections/core";
|
|
8
|
+
import { RefreshCw } from "lucide-react";
|
|
9
|
+
import { toast } from "sonner";
|
|
10
|
+
import { supabase } from "../integrations/supabase/moduleClient.js";
|
|
11
|
+
export function MisluktVerzendbrievenCard() {
|
|
12
|
+
const [regels, setRegels] = useState([]);
|
|
13
|
+
const [fout, setFout] = useState(null);
|
|
14
|
+
const [bezig, setBezig] = useState(null);
|
|
15
|
+
const laad = useCallback(async () => {
|
|
16
|
+
const { data, error } = await supabase
|
|
17
|
+
.from("logistics_slip_shipping_note")
|
|
18
|
+
.select("id, order_number, error, error_code, updated_at")
|
|
19
|
+
.eq("status", "mislukt")
|
|
20
|
+
.order("updated_at", { ascending: false })
|
|
21
|
+
.limit(25);
|
|
22
|
+
if (error) {
|
|
23
|
+
setFout(error.message);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setFout(null);
|
|
27
|
+
setRegels(Array.isArray(data) ? data : []);
|
|
28
|
+
}, []);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
void laad();
|
|
31
|
+
}, [laad]);
|
|
32
|
+
const opnieuw = async (id) => {
|
|
33
|
+
setBezig(id);
|
|
34
|
+
try {
|
|
35
|
+
const { data, error } = await supabase.rpc("logistics_slip_note_retry", { _id: id });
|
|
36
|
+
const res = (data ?? {});
|
|
37
|
+
if (error || !res.ok) {
|
|
38
|
+
toast.error(error?.message ?? res.error ?? "Opnieuw proberen is niet gelukt.");
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
toast.success("De verzendbrief wordt opnieuw aangevraagd.");
|
|
42
|
+
}
|
|
43
|
+
await laad();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setBezig(null);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Mislukte verzendbrieven" }), _jsx(CardDescription, { children: "Floriday-verzendbrieven bij een pakbon die niet geprint konden worden. Los de oorzaak op en druk op \"Opnieuw proberen\"; de kar hoeft niet opnieuw gescand te worden." })] }), _jsxs(CardContent, { className: "space-y-2", children: [fout && _jsx("p", { className: "text-sm text-destructive", children: fout }), !fout && regels.length === 0 && (_jsx("p", { className: "text-sm text-muted-foreground", children: "Geen mislukte verzendbrieven." })), regels.map((r) => (_jsxs("div", { className: "flex items-start justify-between gap-3 border-b border-border py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium", children: r.order_number ?? "Onbekende order" }), _jsx("p", { className: "text-xs text-muted-foreground break-words", children: r.error ?? r.error_code ?? "Onbekende fout" })] }), _jsxs(Button, { size: "sm", variant: "outline", disabled: bezig === r.id, onClick: () => void opnieuw(r.id), children: [_jsx(RefreshCw, { className: "mr-1 h-3 w-3" }), "Opnieuw proberen"] })] }, r.id)))] })] }));
|
|
50
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegiePage.d.ts","sourceRoot":"","sources":["../../src/components/RegiePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RegiePage.d.ts","sourceRoot":"","sources":["../../src/components/RegiePage.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,SAAS,gCA2FxB"}
|
|
@@ -13,6 +13,7 @@ import { Link } from "@tanstack/react-router";
|
|
|
13
13
|
import { ConsistentieCard } from "./ConsistentieCard";
|
|
14
14
|
import { KarplanStatusCard } from "./KarplanStatusCard";
|
|
15
15
|
import { KardekkingCard } from "./KardekkingCard";
|
|
16
|
+
import { MisluktVerzendbrievenCard } from "./MisluktVerzendbrievenCard";
|
|
16
17
|
import { PlannerDiffCard } from "./PlannerDiffCard";
|
|
17
18
|
import { BeladingsafwijkingenCard } from "./BeladingsafwijkingenCard";
|
|
18
19
|
import { OrderLogboek } from "./OrderLogboek";
|
|
@@ -34,5 +35,5 @@ export function RegiePage() {
|
|
|
34
35
|
useEffect(() => {
|
|
35
36
|
void laden();
|
|
36
37
|
}, [laden]);
|
|
37
|
-
return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Workflow, { className: "h-6 w-6 text-primary" }), "Overzicht & meldingen"] }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Wat er vandaag klaarstaat en waar aandacht voor nodig is." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/logistiek-engine", children: "Terug naar overzicht" }) }), _jsxs(Button, { variant: "outline", onClick: () => void laden(), disabled: loading, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Vernieuwen"] })] })] }), _jsx(InklapbaarVenster, { titel: "Binnengekomen orders", omschrijving: "Klik een order open voor elke stap, beslissing, foutmelding en elk document.", standaardOpen: true, children: _jsx(OrderLogboek, { titel: "Binnengekomen orders" }) }), _jsx(InklapbaarVenster, { titel: "Consistentie", omschrijving: "Controle of alle modules hetzelfde tonen.", children: _jsx(ConsistentieCard, {}) }), _jsx(InklapbaarVenster, { titel: "Beladingsafwijkingen", omschrijving: "Verschillen tussen onze belading en de laatste Floriday-gegevens.", children: _jsx(BeladingsafwijkingenCard, {}) }), _jsx(InklapbaarVenster, { titel: "Karplanstatus", omschrijving: "Stand van de karrenindeling.", children: _jsx(KarplanStatusCard, {}) }),
|
|
38
|
+
return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Workflow, { className: "h-6 w-6 text-primary" }), "Overzicht & meldingen"] }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Wat er vandaag klaarstaat en waar aandacht voor nodig is." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/logistiek-engine", children: "Terug naar overzicht" }) }), _jsxs(Button, { variant: "outline", onClick: () => void laden(), disabled: loading, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Vernieuwen"] })] })] }), _jsx(InklapbaarVenster, { titel: "Binnengekomen orders", omschrijving: "Klik een order open voor elke stap, beslissing, foutmelding en elk document.", standaardOpen: true, children: _jsx(OrderLogboek, { titel: "Binnengekomen orders" }) }), _jsx(InklapbaarVenster, { titel: "Consistentie", omschrijving: "Controle of alle modules hetzelfde tonen.", children: _jsx(ConsistentieCard, {}) }), _jsx(InklapbaarVenster, { titel: "Beladingsafwijkingen", omschrijving: "Verschillen tussen onze belading en de laatste Floriday-gegevens.", children: _jsx(BeladingsafwijkingenCard, {}) }), _jsx(InklapbaarVenster, { titel: "Karplanstatus", omschrijving: "Stand van de karrenindeling.", children: _jsx(KarplanStatusCard, {}) }), _jsxs(InklapbaarVenster, { titel: "Kardekking", omschrijving: "Staat elke bestelregel correct op een kar?", children: [_jsx(KardekkingCard, {}), _jsx(MisluktVerzendbrievenCard, {})] }), _jsx(InklapbaarVenster, { titel: "Vergelijkende planner", omschrijving: "Proefvergelijking: blijft de karindeling gelijk?", children: _jsx(PlannerDiffCard, {}) }), _jsxs(InklapbaarVenster, { titel: "Taken per module", omschrijving: "Openstaande en geplande taken.", children: [telFout && _jsxs("p", { className: "mb-2 text-sm text-destructive", children: ["Telling niet beschikbaar: ", telFout] }), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: Object.keys(LOGISTICS_MODULES).map((key) => (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsx(CardDescription, { children: LOGISTICS_MODULES[key] }), _jsx(CardTitle, { className: "text-2xl", children: perModule[key] ?? 0 })] }), _jsx(CardContent, { className: "text-muted-foreground text-xs", children: "openstaande en geplande taken" })] }, key))) })] })] }));
|
|
38
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuleEnginePage.d.ts","sourceRoot":"","sources":["../../src/components/RuleEnginePage.tsx"],"names":[],"mappings":"AAmEA,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAQD,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EAAE,cAAqB,EACjC,YAAY,EAAE,gBAAuB,GACtC,GAAE,mBAAwB,+
|
|
1
|
+
{"version":3,"file":"RuleEnginePage.d.ts","sourceRoot":"","sources":["../../src/components/RuleEnginePage.tsx"],"names":[],"mappings":"AAmEA,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAQD,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EAAE,cAAqB,EACjC,YAAY,EAAE,gBAAuB,GACtC,GAAE,mBAAwB,+BA+b1B"}
|
|
@@ -121,7 +121,9 @@ export function RuleEnginePage({ strategyId: strategyIdProp = null, strategyName
|
|
|
121
121
|
? "Bezig…"
|
|
122
122
|
: "Opslaan & opnieuw berekenen"] })] })] }), error && (_jsx("p", { className: "rounded-md border border-destructive/50 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: "De gegevens konden niet worden geladen. Probeer het opnieuw." })), showJobLine && (_jsxs("div", { className: `rounded-md border px-3 py-2 text-sm ${job?.status === "error" ? "border-destructive/50 bg-destructive/5 text-destructive" : "border-border"}`, children: [_jsx("span", { children: running
|
|
123
123
|
? `${phaseLabel(job?.phase)} — ${job?.processed ?? 0} verwerkt`
|
|
124
|
-
:
|
|
124
|
+
: `De laatste volledige herberekening${job?.finished_at
|
|
125
|
+
? ` (${new Date(job.finished_at).toLocaleString("nl-NL", { dateStyle: "medium", timeStyle: "short" })})`
|
|
126
|
+
: ""} is niet volledig gelukt. Deze meldingen horen bij die berekening; opnieuw berekenen ververst ze.` }), jobProblems.length > 0 && (_jsx("ul", { className: "mt-1 list-disc pl-5 text-xs", children: jobProblems.map((p, i) => (_jsx("li", { children: p }, i))) }))] })), !loading && activeConfig && !activeConfig.is_active && (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-amber-500/60 bg-amber-500/5 px-3 py-2 text-sm", children: [_jsxs("span", { className: "flex items-start gap-2", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), "Deze werkwijze staat nog op ", _jsx("strong", { children: "concept" }), " en telt nog niet mee bij het inplannen."] }), _jsxs(Button, { size: "sm", onClick: () => activateConfig(activeConfig.id), children: [_jsx(CheckCircle2, { className: "h-4 w-4" }), "Nu activeren"] })] })), loading || (strategyId && !activeConfig && !error) ? (_jsxs("div", { className: "space-y-3", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-64 w-full" })] })) : !activeConfig ? (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Nog geen werkwijze" }), _jsx(CardDescription, { children: "Maak een werkwijze aan om vast te leggen hoe jouw orders verwerkt worden." })] }), _jsx(CardContent, { children: _jsxs(Button, { onClick: () => setCreateOpen(true), children: [_jsx(Plus, { className: "h-4 w-4" }), "Werkwijze aanmaken"] }) })] })) : (_jsxs("div", { className: `grid gap-6 lg:h-[calc(100vh-13rem)] ${sideOpen
|
|
125
127
|
? "lg:grid-cols-[220px_minmax(0,1fr)_320px]"
|
|
126
128
|
: "lg:grid-cols-[220px_minmax(0,1fr)_44px]"}`, children: [_jsx("nav", { className: "space-y-1 lg:overflow-y-auto lg:pr-1", children: WIZARD_STEPS.map((item, index) => (_jsxs("button", { type: "button", onClick: () => setStepIndex(index), className: `flex w-full items-center gap-3 rounded-lg border p-2.5 text-left transition-colors ${index === stepIndex
|
|
127
129
|
? "border-primary bg-primary/5"
|
|
@@ -9,6 +9,8 @@ export interface ShippingNoteStatus {
|
|
|
9
9
|
cartId: string | null;
|
|
10
10
|
orderNumber: string | null;
|
|
11
11
|
}
|
|
12
|
+
/** Zet een nog wachtende status om naar een expliciete fout na de pollimiet. */
|
|
13
|
+
export declare function timedOutStatus(current: ShippingNoteStatus, maxPollMs: number): ShippingNoteStatus;
|
|
12
14
|
/**
|
|
13
15
|
* Zet de verzendbriefverwerking direct aan het werk zodra de pakbon naar het
|
|
14
16
|
* pickstation is gestuurd, zodat niet op de volgende ronde hoeft te worden
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useShippingNoteStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useShippingNoteStatus.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,mBAAmB,GACnB,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"useShippingNoteStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useShippingNoteStatus.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,mBAAmB,GACnB,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAID,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAOpB;AA6BD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAe3D;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO;;;;EAyD1E"}
|
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
import { useCallback, useEffect, useState } from "react";
|
|
6
6
|
import { supabase } from "@flowselections/core";
|
|
7
7
|
const WAITING = new Set(["klaar_voor_print", "wacht_op_floriday"]);
|
|
8
|
+
/** Zet een nog wachtende status om naar een expliciete fout na de pollimiet. */
|
|
9
|
+
export function timedOutStatus(current, maxPollMs) {
|
|
10
|
+
const minuten = Math.round(maxPollMs / 60000);
|
|
11
|
+
return {
|
|
12
|
+
...current,
|
|
13
|
+
status: "mislukt",
|
|
14
|
+
message: `Verzendbriefstatus kon niet worden bepaald na ${minuten} minuten. Controleer de printwachtrij.`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
8
17
|
function safeStatus(value) {
|
|
9
18
|
if (!value || typeof value !== "object")
|
|
10
19
|
return null;
|
|
@@ -98,8 +107,11 @@ export function useShippingNoteStatus(slipJobId, cartId, options = {}) {
|
|
|
98
107
|
useEffect(() => {
|
|
99
108
|
if (!data || !WAITING.has(data.status) || startedAt === null)
|
|
100
109
|
return;
|
|
101
|
-
if (Date.now() - startedAt >= maxPollMs)
|
|
110
|
+
if (Date.now() - startedAt >= maxPollMs) {
|
|
111
|
+
// Nooit stil stoppen: zonder eindstatus na de limiet expliciet een fout tonen.
|
|
112
|
+
setData(timedOutStatus(data, maxPollMs));
|
|
102
113
|
return;
|
|
114
|
+
}
|
|
103
115
|
const timer = window.setTimeout(() => void reload(), pollMs);
|
|
104
116
|
return () => window.clearTimeout(timer);
|
|
105
117
|
}, [data, maxPollMs, pollMs, reload, startedAt]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShippingNoteStatus.test.d.ts","sourceRoot":"","sources":["../../src/hooks/useShippingNoteStatus.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { timedOutStatus } from "./useShippingNoteStatus";
|
|
3
|
+
describe("timedOutStatus", () => {
|
|
4
|
+
it("maakt van een wachtende status na de limiet een expliciete fout", () => {
|
|
5
|
+
const wachtend = {
|
|
6
|
+
status: "klaar_voor_print",
|
|
7
|
+
message: "Verzendbrief wordt klaargezet.",
|
|
8
|
+
attempts: 0,
|
|
9
|
+
nextAttemptAt: null,
|
|
10
|
+
slipJobId: "s",
|
|
11
|
+
shippingNoteJobId: null,
|
|
12
|
+
cartId: "c",
|
|
13
|
+
orderNumber: "HO-1",
|
|
14
|
+
};
|
|
15
|
+
const uit = timedOutStatus(wachtend, 15 * 60000);
|
|
16
|
+
expect(uit.status).toBe("mislukt");
|
|
17
|
+
expect(uit.message).toContain("15 minuten");
|
|
18
|
+
expect(uit.slipJobId).toBe("s");
|
|
19
|
+
});
|
|
20
|
+
});
|