@flowselections/floriday-afhandeling-module 1.0.25 → 1.0.27
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/afhandeling/CapacityWarning.d.ts +10 -0
- package/dist-lib/components/afhandeling/CapacityWarning.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/CapacityWarning.js +12 -0
- package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControlePage.js +7 -2
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +158 -62
- package/dist-lib/components/afhandeling/LeveringenPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/LeveringenPage.js +2 -10
- package/dist-lib/components/afhandeling/PickAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/PickAgendaView.js +4 -11
- package/dist-lib/components/afhandeling/VervoerdersPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.js +2 -5
- package/dist-lib/components/afhandeling/VerzetOrderDialog.d.ts +14 -0
- package/dist-lib/components/afhandeling/VerzetOrderDialog.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/VerzetOrderDialog.js +203 -0
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +7 -3
- package/dist-lib/components/pickstation/PickstationPage.d.ts.map +1 -1
- package/dist-lib/components/pickstation/PickstationPage.js +1 -0
- package/dist-lib/components/settings/VervoerdersSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/VervoerdersSettingsCard.js +2 -5
- package/dist-lib/hooks/useCapacityCheck.d.ts +10 -0
- package/dist-lib/hooks/useCapacityCheck.d.ts.map +1 -0
- package/dist-lib/hooks/useCapacityCheck.js +22 -0
- package/dist-lib/hooks/useEngineTasks.d.ts +14 -0
- package/dist-lib/hooks/useEngineTasks.d.ts.map +1 -0
- package/dist-lib/hooks/useEngineTasks.js +49 -0
- package/dist-lib/hooks/useOrderPlanning.d.ts +8 -2
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +95 -93
- package/dist-lib/index.d.ts +0 -3
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -5
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +9010 -5433
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +9010 -5433
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +9010 -5433
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +9184 -5544
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +7186 -32
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/carriers.functions.d.ts +17965 -80
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.d.ts +17965 -80
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +35962 -170
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.js +103 -13
- package/dist-lib/lib/floriday.functions.d.ts +9010 -5433
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/logisticsEngine/capacity.d.ts +19 -0
- package/dist-lib/lib/logisticsEngine/capacity.d.ts.map +1 -0
- package/dist-lib/lib/logisticsEngine/capacity.js +91 -0
- package/dist-lib/lib/logisticsEngine/engine.d.ts +99 -0
- package/dist-lib/lib/logisticsEngine/engine.d.ts.map +1 -0
- package/dist-lib/lib/logisticsEngine/engine.js +102 -0
- package/dist-lib/lib/logisticsEngine/reschedule.d.ts +65 -0
- package/dist-lib/lib/logisticsEngine/reschedule.d.ts.map +1 -0
- package/dist-lib/lib/logisticsEngine/reschedule.js +86 -0
- package/dist-lib/lib/logisticsEngine/staffPlanning.d.ts +37 -0
- package/dist-lib/lib/logisticsEngine/staffPlanning.d.ts.map +1 -0
- package/dist-lib/lib/logisticsEngine/staffPlanning.js +100 -0
- package/dist-lib/lib/serverFnError.d.ts +10 -0
- package/dist-lib/lib/serverFnError.d.ts.map +1 -0
- package/dist-lib/lib/serverFnError.js +29 -0
- package/dist-lib/lib/serverRoutes/index.d.ts +0 -1
- package/dist-lib/lib/serverRoutes/index.d.ts.map +1 -1
- package/dist-lib/lib/serverRoutes/index.js +0 -1
- package/dist-lib/lib/timezone.d.ts +27 -0
- package/dist-lib/lib/timezone.d.ts.map +1 -0
- package/dist-lib/lib/timezone.js +68 -0
- package/package.json +6 -21
- package/dist-lib/components/engine/CapaciteitsmaatregelenPage.d.ts +0 -2
- package/dist-lib/components/engine/CapaciteitsmaatregelenPage.d.ts.map +0 -1
- package/dist-lib/components/engine/CapaciteitsmaatregelenPage.js +0 -40
- package/dist-lib/components/engine/CapaciteitsmonitorPage.d.ts +0 -2
- package/dist-lib/components/engine/CapaciteitsmonitorPage.d.ts.map +0 -1
- package/dist-lib/components/engine/CapaciteitsmonitorPage.js +0 -49
- package/dist-lib/components/engine/FormulesPage.d.ts +0 -2
- package/dist-lib/components/engine/FormulesPage.d.ts.map +0 -1
- package/dist-lib/components/engine/FormulesPage.js +0 -252
- package/dist-lib/components/engine/PlaceholderPage.d.ts +0 -6
- package/dist-lib/components/engine/PlaceholderPage.d.ts.map +0 -1
- package/dist-lib/components/engine/PlaceholderPage.js +0 -6
- package/dist-lib/components/engine/StrategieenPage.d.ts +0 -2
- package/dist-lib/components/engine/StrategieenPage.d.ts.map +0 -1
- package/dist-lib/components/engine/StrategieenPage.js +0 -80
- package/dist-lib/lib/logisticsEngine/capacity.functions.d.ts +0 -64978
- package/dist-lib/lib/logisticsEngine/capacity.functions.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/capacity.functions.js +0 -90
- package/dist-lib/lib/logisticsEngine/config.d.ts +0 -140
- package/dist-lib/lib/logisticsEngine/config.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/config.js +0 -488
- package/dist-lib/lib/logisticsEngine/enginePickTime.d.ts +0 -29
- package/dist-lib/lib/logisticsEngine/enginePickTime.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/enginePickTime.js +0 -136
- package/dist-lib/lib/logisticsEngine/evaluate.functions.d.ts +0 -16278
- package/dist-lib/lib/logisticsEngine/evaluate.functions.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/evaluate.functions.js +0 -104
- package/dist-lib/lib/logisticsEngine/expression.d.ts +0 -21
- package/dist-lib/lib/logisticsEngine/expression.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/expression.js +0 -263
- package/dist-lib/lib/logisticsEngine/formulas.functions.d.ts +0 -32512
- package/dist-lib/lib/logisticsEngine/formulas.functions.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/formulas.functions.js +0 -58
- package/dist-lib/lib/logisticsEngine/safetyLayer.d.ts +0 -83
- package/dist-lib/lib/logisticsEngine/safetyLayer.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/safetyLayer.js +0 -182
- package/dist-lib/lib/logisticsEngine/strategies.functions.d.ts +0 -129961
- package/dist-lib/lib/logisticsEngine/strategies.functions.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/strategies.functions.js +0 -176
- package/dist-lib/lib/logisticsEngine/variables.d.ts +0 -29
- package/dist-lib/lib/logisticsEngine/variables.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/variables.js +0 -144
- package/dist-lib/lib/logisticsEngine/wizard.functions.d.ts +0 -64976
- package/dist-lib/lib/logisticsEngine/wizard.functions.d.ts.map +0 -1
- package/dist-lib/lib/logisticsEngine/wizard.functions.js +0 -175
- package/dist-lib/lib/serverRoutes/logisticsTick.handler.d.ts +0 -3
- package/dist-lib/lib/serverRoutes/logisticsTick.handler.d.ts.map +0 -1
- package/dist-lib/lib/serverRoutes/logisticsTick.handler.js +0 -42
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CapacityDay } from "../../lib/logisticsEngine/capacity";
|
|
2
|
+
/**
|
|
3
|
+
* Waarschuwing bij te weinig pickcapaciteit. Alle cijfers komen letterlijk
|
|
4
|
+
* uit de Logistics Engine (logistics_capacity_day_check).
|
|
5
|
+
*/
|
|
6
|
+
export declare function CapacityWarning({ day, className, }: {
|
|
7
|
+
day: CapacityDay | undefined;
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=CapacityWarning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CapacityWarning.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/CapacityWarning.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAE3F;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,SAAc,GACf,EAAE;IACD,GAAG,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,sCAWA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AlertTriangle } from "lucide-react";
|
|
3
|
+
import { capacityWarningText } from "../../lib/logisticsEngine/capacity";
|
|
4
|
+
/**
|
|
5
|
+
* Waarschuwing bij te weinig pickcapaciteit. Alle cijfers komen letterlijk
|
|
6
|
+
* uit de Logistics Engine (logistics_capacity_day_check).
|
|
7
|
+
*/
|
|
8
|
+
export function CapacityWarning({ day, className = "", }) {
|
|
9
|
+
if (!day || day.shortageMinutes <= 0)
|
|
10
|
+
return null;
|
|
11
|
+
return (_jsxs("div", { role: "alert", className: `flex items-start gap-2 rounded-md border border-amber-400 bg-amber-50 px-3 py-2 text-sm text-amber-900 ${className}`, children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: capacityWarningText(day) })] }));
|
|
12
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AA4GA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+
|
|
1
|
+
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AA4GA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BA8uBpE"}
|
|
@@ -73,11 +73,16 @@ export function ControlePage({ onExit } = {}) {
|
|
|
73
73
|
const cartsQ = useQuery({
|
|
74
74
|
queryKey: ["control", "today"],
|
|
75
75
|
queryFn: () => fetchToday(),
|
|
76
|
+
refetchInterval: 60000,
|
|
77
|
+
refetchIntervalInBackground: false,
|
|
78
|
+
refetchOnWindowFocus: true,
|
|
76
79
|
});
|
|
77
80
|
const histQ = useQuery({
|
|
78
81
|
queryKey: ["control", "history"],
|
|
79
82
|
queryFn: () => fetchHistory(),
|
|
80
83
|
enabled: tab === "historie",
|
|
84
|
+
refetchOnMount: "always",
|
|
85
|
+
refetchOnWindowFocus: true,
|
|
81
86
|
});
|
|
82
87
|
const draftQ = useQuery({
|
|
83
88
|
queryKey: controlDraftQueryKey,
|
|
@@ -402,9 +407,9 @@ export function ControlePage({ onExit } = {}) {
|
|
|
402
407
|
? true
|
|
403
408
|
: carts.some((c) => checked.has(controlCartKey(c)))
|
|
404
409
|
? "indeterminate"
|
|
405
|
-
: false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "
|
|
410
|
+
: false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Ophaaldatum" }), _jsx(TableHead, { children: "Uitgeprint" })] }) }), _jsxs(TableBody, { children: [cartsQ.isLoading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !cartsQ.isLoading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Geen karren om vandaag te controleren." }) })), carts.map((c) => {
|
|
406
411
|
const k = controlCartKey(c);
|
|
407
|
-
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }), _jsx(TableCell, { className: "font-mono font-semibold", children: c.
|
|
412
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }), _jsx(TableCell, { className: "font-mono font-semibold", children: (c.orderNumbers?.length ?? 0) > 0 ? (_jsx("div", { className: "flex flex-col gap-0.5", children: c.orderNumbers.map((n) => (_jsx("span", { children: n }, n))) })) : (c.orderNumber || "—") }), _jsx(TableCell, { children: fmtDate(c.pickupDate) }), _jsx(TableCell, { children: (c.printedCount ?? 0) > 0 ? (_jsx(Badge, { variant: "secondary", children: "Ja" })) : (_jsx(Badge, { variant: "outline", children: "Nee" })) })] }, k));
|
|
408
413
|
})] })] }) }), _jsxs("div", { className: "max-w-xl", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { className: "text-sm font-medium", children: "Opmerkingen bij deze controle" }), _jsx("span", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: savingState === "saving"
|
|
409
414
|
? "Opslaan…"
|
|
410
415
|
: savingState === "saved"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAwCjE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAID,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,oBAAoB,sCA8E1F"}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
|
-
import { useQuery,
|
|
3
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
5
|
-
import { Badge, Button, Dialog, DialogTitle, DialogDescription, Input, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
|
|
6
|
-
import { ChevronDown, ChevronRight,
|
|
5
|
+
import { Badge, Checkbox, Button, Dialog, DialogTitle, DialogDescription, Input, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
|
|
6
|
+
import { CalendarClock, ChevronDown, ChevronRight, Printer, Users } from "lucide-react";
|
|
7
7
|
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
8
8
|
import { isSameDay } from "../../lib/pickDate";
|
|
9
|
-
import { getOrderLines,
|
|
10
|
-
import { evaluateCartMove } from "../../lib/cartMoveImpact";
|
|
9
|
+
import { getOrderLines, } from "../../lib/cartAssignments.functions";
|
|
11
10
|
import { renderPakbonHtml } from "../pickstation/PakbonTemplate";
|
|
12
11
|
import { printHtml } from "../pickstation/printDocuments";
|
|
13
12
|
import { printDeliveryNotesMerged } from "../../lib/deliveryNotePrint";
|
|
14
13
|
import { AutoProcessStatus } from "./AutoProcessStatus";
|
|
14
|
+
import { CapacityWarning } from "./CapacityWarning";
|
|
15
|
+
import { useCapacityCheck } from "../../hooks/useCapacityCheck";
|
|
16
|
+
import { toDayKey } from "../../lib/logisticsEngine/capacity";
|
|
17
|
+
import { VerzetOrderDialog } from "./VerzetOrderDialog";
|
|
18
|
+
import { setPickDay } from "../../lib/logisticsEngine/reschedule";
|
|
19
|
+
import { clearDayStaffPlan, computeCapacity, getDayStaffPlan, getEngineStaffDefaults, setDayStaffPlan, toDateKey, } from "../../lib/logisticsEngine/staffPlanning";
|
|
15
20
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { dateStyle: "full" });
|
|
16
21
|
export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
17
22
|
if (!date)
|
|
@@ -55,7 +60,79 @@ export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
|
55
60
|
runningIdx += a.cartCount;
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }),
|
|
63
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsxs(ResponsiveDialogBody, { children: [_jsx(DayCapacityWarning, { date: date }), _jsx(BezettingCard, { date: date, cartsToday: cartRows.length }), _jsxs(Tabs, { defaultValue: "bestellingen", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows }) })] })] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Sluiten" }) })] }) }));
|
|
64
|
+
}
|
|
65
|
+
function BezettingCard({ date, cartsToday }) {
|
|
66
|
+
const queryClient = useQueryClient();
|
|
67
|
+
const dateKey = toDateKey(date);
|
|
68
|
+
const defaultsQuery = useQuery({
|
|
69
|
+
queryKey: ["engine-staff-defaults"],
|
|
70
|
+
queryFn: getEngineStaffDefaults,
|
|
71
|
+
});
|
|
72
|
+
const dayQuery = useQuery({
|
|
73
|
+
queryKey: ["engine-staff-day", dateKey],
|
|
74
|
+
queryFn: () => getDayStaffPlan(date),
|
|
75
|
+
});
|
|
76
|
+
const defaults = defaultsQuery.data;
|
|
77
|
+
const dayPlan = dayQuery.data ?? null;
|
|
78
|
+
const [editing, setEditing] = useState(false);
|
|
79
|
+
const [staff, setStaff] = useState("");
|
|
80
|
+
const [from, setFrom] = useState("");
|
|
81
|
+
const [to, setTo] = useState("");
|
|
82
|
+
const [saving, setSaving] = useState(false);
|
|
83
|
+
const effStaff = dayPlan?.staffCount ?? defaults?.avgStaff ?? null;
|
|
84
|
+
const effFrom = (dayPlan?.startTime ?? defaults?.startTime ?? "06:00").slice(0, 5);
|
|
85
|
+
const effTo = (dayPlan?.endTime ?? defaults?.endTime ?? "16:00").slice(0, 5);
|
|
86
|
+
const capacity = effStaff !== null
|
|
87
|
+
? computeCapacity({
|
|
88
|
+
staffCount: effStaff,
|
|
89
|
+
startTime: effFrom,
|
|
90
|
+
endTime: effTo,
|
|
91
|
+
minutesPerCart: defaults?.minutesPerCart ?? null,
|
|
92
|
+
})
|
|
93
|
+
: null;
|
|
94
|
+
const startEdit = () => {
|
|
95
|
+
setStaff(String(effStaff ?? 0));
|
|
96
|
+
setFrom(effFrom);
|
|
97
|
+
setTo(effTo);
|
|
98
|
+
setEditing(true);
|
|
99
|
+
};
|
|
100
|
+
const save = async () => {
|
|
101
|
+
setSaving(true);
|
|
102
|
+
try {
|
|
103
|
+
await setDayStaffPlan({
|
|
104
|
+
date,
|
|
105
|
+
staffCount: Number(staff) || 0,
|
|
106
|
+
startTime: from || "06:00",
|
|
107
|
+
endTime: to || "16:00",
|
|
108
|
+
});
|
|
109
|
+
await queryClient.invalidateQueries({ queryKey: ["engine-staff-day", dateKey] });
|
|
110
|
+
setEditing(false);
|
|
111
|
+
toast.success("Bezetting voor deze dag opgeslagen");
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
toast.error(err instanceof Error ? err.message : "Opslaan mislukt");
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
setSaving(false);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const reset = async () => {
|
|
121
|
+
setSaving(true);
|
|
122
|
+
try {
|
|
123
|
+
await clearDayStaffPlan(date);
|
|
124
|
+
await queryClient.invalidateQueries({ queryKey: ["engine-staff-day", dateKey] });
|
|
125
|
+
setEditing(false);
|
|
126
|
+
toast.success("Terug naar standaardbezetting van de Logistiek Engine");
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
toast.error(err instanceof Error ? err.message : "Herstellen mislukt");
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
setSaving(false);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
return (_jsxs("div", { className: "mb-4 rounded-lg border bg-muted/30 p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "h-4 w-4 text-muted-foreground" }), _jsxs("div", { children: [_jsx("div", { className: "text-lg font-bold leading-none", children: defaultsQuery.isLoading || dayQuery.isLoading ? "…" : (effStaff ?? "—") }), _jsxs("div", { className: "text-xs text-muted-foreground", children: ["medewerkers ", dayPlan ? "(aangepast voor deze dag)" : "(gemiddelde uit Engine)"] })] })] }), _jsxs("div", { children: [_jsxs("div", { className: "text-lg font-bold leading-none", children: [effFrom, "\u2013", effTo] }), _jsx("div", { className: "text-xs text-muted-foreground", children: "werktijden" })] }), capacity?.capacityCarts !== null && capacity !== null && (_jsxs("div", { children: [_jsxs("div", { className: "text-lg font-bold leading-none", children: [cartsToday, " / ", capacity.capacityCarts] }), _jsx("div", { className: "text-xs text-muted-foreground", children: "karren gepland / capaciteit" })] }))] }), !editing && (_jsx(Button, { size: "sm", variant: "outline", onClick: startEdit, children: "Bezetting aanpassen" }))] }), editing && (_jsxs("div", { className: "mt-4 flex flex-wrap items-end gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Medewerkers" }), _jsx(Input, { type: "number", min: 0, step: 1, value: staff, onChange: (e) => setStaff(e.target.value), className: "w-28" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Van" }), _jsx(Input, { type: "time", value: from, onChange: (e) => setFrom(e.target.value), className: "w-32" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Tot" }), _jsx(Input, { type: "time", value: to, onChange: (e) => setTo(e.target.value), className: "w-32" })] }), _jsx(Button, { size: "sm", onClick: save, disabled: saving, children: saving ? "Opslaan…" : "Opslaan" }), dayPlan && (_jsx(Button, { size: "sm", variant: "ghost", onClick: reset, disabled: saving, children: "Standaard herstellen" })), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => setEditing(false), disabled: saving, children: "Annuleren" })] }))] }));
|
|
59
136
|
}
|
|
60
137
|
function BestellingenTab({ orders, date }) {
|
|
61
138
|
if (orders.length === 0) {
|
|
@@ -69,6 +146,7 @@ function BestellingenTab({ orders, date }) {
|
|
|
69
146
|
function OrderRow({ planned: p, cartsToday }) {
|
|
70
147
|
const [open, setOpen] = useState(false);
|
|
71
148
|
const [printing, setPrinting] = useState(false);
|
|
149
|
+
const [verzetOpen, setVerzetOpen] = useState(false);
|
|
72
150
|
const source = p.order.source;
|
|
73
151
|
const fetchLines = useServerFn(getOrderLines);
|
|
74
152
|
const linesQuery = useQuery({
|
|
@@ -165,7 +243,15 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
165
243
|
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
166
244
|
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
167
245
|
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId })) : null;
|
|
168
|
-
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing, title: "Alle pakbonnen en afleverbrieven van deze bestelling afdrukken", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), printing ? "Bezig…" : "Alle documenten afdrukken"] })
|
|
246
|
+
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing, title: "Alle pakbonnen en afleverbrieven van deze bestelling afdrukken", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), printing ? "Bezig…" : "Alle documenten afdrukken"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: (e) => {
|
|
247
|
+
e.stopPropagation();
|
|
248
|
+
setVerzetOpen(true);
|
|
249
|
+
}, title: "Ophaaldag of ophaaltijd van deze order wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: p.order.orderNumber, carrierTarget: {
|
|
250
|
+
carrierId: p.order.carrierId ?? null,
|
|
251
|
+
country: p.order.country ?? null,
|
|
252
|
+
province: p.order.province ?? null,
|
|
253
|
+
city: p.order.city ?? null,
|
|
254
|
+
}, onOpenChange: setVerzetOpen }), open && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [_jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-3 text-sm", children: [_jsx(Field, { label: "Afleverlocatie", value: "\u2014" }), _jsx(Field, { label: "Ophaallocatie (tuin)", value: "\u2014" }), _jsx(Field, { label: "Vervoerder", value: "\u2014" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Orderregels" }), linesQuery.isLoading && _jsx("p", { className: "text-xs", children: "Regels laden\u2026" }), linesQuery.data && _jsx(OrderLinesTable, { lines: linesQuery.data.lines }), linesQuery.error && _jsx("p", { className: "text-xs text-destructive", children: "Kon regels niet laden" })] })] }))] }));
|
|
169
255
|
}
|
|
170
256
|
function Field({ label, value }) {
|
|
171
257
|
return (_jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: label }), _jsx("div", { children: value })] }));
|
|
@@ -176,66 +262,76 @@ function OrderLinesTable({ lines }) {
|
|
|
176
262
|
}
|
|
177
263
|
return (_jsx("div", { className: "grid gap-2", children: lines.map((l) => (_jsxs("div", { className: "grid gap-2 rounded-md border p-2 text-sm md:grid-cols-[minmax(0,1fr)_auto_auto_auto] md:items-center", children: [_jsx("div", { className: "min-w-0 truncate font-medium", title: l.article, children: l.article }), _jsx(Metric, { label: "Planten", value: l.plants }), _jsx(Metric, { label: "Fusten", value: l.crates ?? "—" }), _jsx(Metric, { label: "Overig", value: l.otherUnits ?? "—" })] }, l.id))) }));
|
|
178
264
|
}
|
|
179
|
-
function KarrenTab({ carts
|
|
180
|
-
const [
|
|
265
|
+
function KarrenTab({ carts }) {
|
|
266
|
+
const [selected, setSelected] = useState(new Set());
|
|
267
|
+
const [bulkOpen, setBulkOpen] = useState(false);
|
|
181
268
|
if (carts.length === 0) {
|
|
182
269
|
return _jsx("p", { className: "text-sm text-muted-foreground", children: "Geen karren ingepland op deze dag." });
|
|
183
270
|
}
|
|
184
|
-
|
|
271
|
+
const toggle = (key) => setSelected((prev) => {
|
|
272
|
+
const next = new Set(prev);
|
|
273
|
+
if (next.has(key))
|
|
274
|
+
next.delete(key);
|
|
275
|
+
else
|
|
276
|
+
next.add(key);
|
|
277
|
+
return next;
|
|
278
|
+
});
|
|
279
|
+
const allSelected = selected.size === carts.length;
|
|
280
|
+
const toggleAll = () => setSelected(allSelected ? new Set() : new Set(carts.map((c) => c.key)));
|
|
281
|
+
const selectedCarts = carts.filter((c) => selected.has(c.key));
|
|
282
|
+
const selectedOrders = Array.from(new Map(selectedCarts.map((c) => [c.order.order.orderNumber, c.order])).values());
|
|
283
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: "mb-3 text-xs text-muted-foreground", children: "De indeling komt uit de Logistics Engine. Verzetten gebeurt per bestelling: alle karren van die bestelling schuiven mee." }), _jsxs("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-3 rounded-md border bg-muted/30 px-3 py-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: allSelected, onCheckedChange: toggleAll }), _jsx("span", { children: selected.size > 0
|
|
284
|
+
? `${selected.size} kar${selected.size === 1 ? "" : "ren"} geselecteerd · ${selectedOrders.length} bestelling${selectedOrders.length === 1 ? "" : "en"}`
|
|
285
|
+
: "Alles selecteren" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [selected.size > 0 && (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => setSelected(new Set()), children: "Selectie wissen" })), _jsxs(Button, { size: "sm", disabled: selected.size === 0, onClick: () => setBulkOpen(true), children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Geselecteerde verzetten"] })] })] }), _jsx("div", { className: "grid gap-3", children: carts.map((c) => (_jsx(KarRow, { cart: c, selected: selected.has(c.key), onToggle: () => toggle(c.key) }, c.key))) }), _jsx(BulkVerzetDialog, { open: bulkOpen, orders: selectedOrders, cartCount: selected.size, onOpenChange: setBulkOpen, onDone: () => setSelected(new Set()) })] }));
|
|
286
|
+
}
|
|
287
|
+
function BulkVerzetDialog({ open, orders, cartCount, onOpenChange, onDone, }) {
|
|
288
|
+
const [day, setDay] = useState("");
|
|
289
|
+
const [busy, setBusy] = useState(false);
|
|
290
|
+
const submit = async () => {
|
|
291
|
+
if (!day)
|
|
292
|
+
return;
|
|
293
|
+
setBusy(true);
|
|
294
|
+
let ok = 0;
|
|
295
|
+
const failed = [];
|
|
296
|
+
for (const p of orders) {
|
|
297
|
+
const ref = p.order.orderNumber || p.order.id;
|
|
298
|
+
try {
|
|
299
|
+
const res = await setPickDay(ref, day);
|
|
300
|
+
if (res.ok)
|
|
301
|
+
ok++;
|
|
302
|
+
else
|
|
303
|
+
failed.push(ref);
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
failed.push(ref);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
setBusy(false);
|
|
310
|
+
if (ok > 0)
|
|
311
|
+
toast.success(`${ok} bestelling${ok === 1 ? "" : "en"} verzet naar ${day}.`);
|
|
312
|
+
if (failed.length > 0)
|
|
313
|
+
toast.error(`Niet gelukt voor: ${failed.join(", ")}`);
|
|
314
|
+
if (failed.length === 0) {
|
|
315
|
+
onDone();
|
|
316
|
+
onOpenChange(false);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { children: [_jsxs(ResponsiveDialogHeader, { children: [_jsx(DialogTitle, { children: "Karren verzetten" }), _jsxs(DialogDescription, { children: [cartCount, " kar", cartCount === 1 ? "" : "ren", " uit ", orders.length, " bestelling", orders.length === 1 ? "" : "en", ". Alle karren van deze bestellingen verschuiven mee."] })] }), _jsx(ResponsiveDialogBody, { children: _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Nieuwe pickdag" }), _jsx(Input, { type: "date", value: day, onChange: (e) => setDay(e.target.value), className: "w-48" }), _jsx("ul", { className: "mt-3 max-h-40 space-y-1 overflow-y-auto text-sm", children: orders.map((p) => (_jsxs("li", { className: "text-muted-foreground", children: [p.order.orderNumber, " \u2014 ", p.order.customerName] }, p.order.id))) })] }) }), _jsxs(ResponsiveDialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: busy, children: "Annuleren" }), _jsx(Button, { onClick: submit, disabled: busy || !day, children: busy ? "Bezig…" : "Verzetten" })] })] }) }));
|
|
320
|
+
}
|
|
321
|
+
function KarRow({ cart: c, selected, onToggle, }) {
|
|
322
|
+
const [verzetOpen, setVerzetOpen] = useState(false);
|
|
323
|
+
return (_jsxs("div", { className: `rounded-md border p-3 ${selected ? "border-primary bg-primary/5" : ""}`, children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { checked: selected, onCheckedChange: onToggle, className: "mt-1" }), _jsxs("div", { className: "grid flex-1 gap-3 lg:grid-cols-[1fr_1.4fr_1fr_auto] lg:items-center", children: [_jsx(Field, { label: "Karnummer", value: c.cartNumber }), _jsx(Field, { label: "Klant", value: c.order.order.customerName }), _jsx(Field, { label: "Bestelling", value: c.order.order.orderNumber }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Badge, { variant: "secondary", children: "Nog te picken" }), _jsxs(Badge, { variant: "outline", children: [c.occupancy, "%"] }), _jsxs(Badge, { variant: "outline", children: [c.layers, " lagen"] }), _jsxs(Badge, { variant: "outline", children: [c.plants, " planten"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => setVerzetOpen(true), title: "Ophaaldag of ophaaltijd van de bestelling van deze kar wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: c.order.order.orderNumber, carrierTarget: {
|
|
324
|
+
carrierId: c.order.order.carrierId ?? null,
|
|
325
|
+
country: c.order.order.country ?? null,
|
|
326
|
+
province: c.order.order.province ?? null,
|
|
327
|
+
city: c.order.order.city ?? null,
|
|
328
|
+
}, onOpenChange: setVerzetOpen })] }));
|
|
185
329
|
}
|
|
186
330
|
function Metric({ label, value }) {
|
|
187
331
|
return (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2 md:block md:text-right", children: [_jsx("span", { className: "text-xs text-muted-foreground md:block", children: label }), _jsx("span", { className: "font-medium", children: value })] }));
|
|
188
332
|
}
|
|
189
|
-
function
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
const mutation = useMutation({
|
|
194
|
-
mutationFn: async () => {
|
|
195
|
-
if (!cart)
|
|
196
|
-
throw new Error("Geen kar geselecteerd");
|
|
197
|
-
if (!newDate)
|
|
198
|
-
throw new Error("Kies eerst een nieuwe pickdatum");
|
|
199
|
-
return move({
|
|
200
|
-
data: {
|
|
201
|
-
orderId: cart.orderId,
|
|
202
|
-
orderSource: cart.orderSource,
|
|
203
|
-
cartIndex: cart.cartIndex,
|
|
204
|
-
newDate,
|
|
205
|
-
fromDate: currentDate,
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
},
|
|
209
|
-
onSuccess: async (res) => {
|
|
210
|
-
const target = new Date(newDate).toLocaleDateString("nl-NL", {
|
|
211
|
-
weekday: "long", day: "numeric", month: "long",
|
|
212
|
-
});
|
|
213
|
-
toast.success(`Kar ${cart?.cartNumber ?? ""} verplaatst naar ${target}`);
|
|
214
|
-
qc.setQueryData(["cart-overrides"], (current) => {
|
|
215
|
-
const overrides = current?.overrides ?? [];
|
|
216
|
-
const next = overrides.filter((o) => !(o.order_id === res.override.order_id &&
|
|
217
|
-
o.order_source === res.override.order_source &&
|
|
218
|
-
o.cart_index === res.override.cart_index));
|
|
219
|
-
return { overrides: [...next, res.override] };
|
|
220
|
-
});
|
|
221
|
-
await Promise.all([
|
|
222
|
-
qc.invalidateQueries({ queryKey: ["floriday", "orders"] }),
|
|
223
|
-
qc.invalidateQueries({ queryKey: ["cart-overrides"] }),
|
|
224
|
-
]);
|
|
225
|
-
await qc.refetchQueries({ queryKey: ["cart-overrides"], type: "active" });
|
|
226
|
-
setNewDate("");
|
|
227
|
-
onClose();
|
|
228
|
-
return res;
|
|
229
|
-
},
|
|
230
|
-
onError: (e) => {
|
|
231
|
-
const msg = e instanceof Error ? e.message : "Verplaatsen mislukt";
|
|
232
|
-
toast.error(msg);
|
|
233
|
-
console.error("[moveCart]", e);
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
if (!cart)
|
|
237
|
-
return null;
|
|
238
|
-
const parsed = newDate ? new Date(newDate) : null;
|
|
239
|
-
const impact = parsed ? evaluateCartMove(parsed, currentDate, cart.order.planning) : null;
|
|
240
|
-
return (_jsx(Dialog, { open: !!cart, onOpenChange: (o) => !o && onClose(), children: _jsxs(ResponsiveDialogContent, { size: "sm", children: [_jsx(ResponsiveDialogHeader, { children: _jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(Truck, { className: "h-4 w-4" }), " Kar verplaatsen"] }) }), _jsxs(ResponsiveDialogBody, { className: "space-y-3 text-sm", children: [_jsxs("div", { className: "rounded-md border bg-muted/40 p-3", children: [_jsx("div", { className: "font-medium", children: cart.cartNumber }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [cart.order.order.customerName, " \u00B7 ", cart.order.order.orderNumber] })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Nieuwe pickdatum" }), _jsx(Input, { type: "date", value: newDate, onChange: (e) => setNewDate(e.target.value) })] }), impact && (_jsxs("div", { className: "space-y-1", children: [impact.blockers.map((b, i) => (_jsxs("p", { className: "text-xs text-destructive", children: ["\u26A0 ", b] }, `b${i}`))), impact.warnings.map((w, i) => (_jsxs("p", { className: "text-xs text-amber-600", children: ["! ", w] }, `w${i}`))), impact.ok && impact.warnings.length === 0 && (_jsx("p", { className: "text-xs text-green-600", children: "\u2713 Verplaatsing is logistiek haalbaar." }))] }))] }), _jsxs(ResponsiveDialogFooter, { children: [_jsx(Button, { variant: "ghost", onClick: onClose, children: "Annuleren" }), _jsx(Button, { onClick: () => mutation.mutate(), disabled: !newDate || (impact ? !impact.ok : false) || mutation.isPending, children: mutation.isPending ? "Bezig…" : "Bevestig verplaatsing" })] })] }) }));
|
|
333
|
+
function DayCapacityWarning({ date }) {
|
|
334
|
+
const key = toDayKey(date);
|
|
335
|
+
const { byDate } = useCapacityCheck(key, key);
|
|
336
|
+
return _jsx(CapacityWarning, { day: byDate.get(key), className: "mb-3" });
|
|
241
337
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LeveringenPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/LeveringenPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LeveringenPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/LeveringenPage.tsx"],"names":[],"mappings":"AAeA,wBAAgB,cAAc,gCA+E7B"}
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast, } from "@flowselections/core";
|
|
5
|
-
import { RefreshCw } from "lucide-react";
|
|
3
|
+
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
6
4
|
import { WeekAgendaView } from "./WeekAgendaView";
|
|
7
5
|
import { useOrderPlanning } from "../../hooks/useOrderPlanning";
|
|
8
|
-
import { invalidatePlanning } from "../../lib/invalidatePlanning";
|
|
9
6
|
const ALL = "__all__";
|
|
10
7
|
export function LeveringenPage() {
|
|
11
8
|
const { planned, isLoading, error, warning, refetch } = useOrderPlanning();
|
|
12
|
-
const qc = useQueryClient();
|
|
13
|
-
const handleRecalc = async () => {
|
|
14
|
-
await invalidatePlanning(qc);
|
|
15
|
-
toast.success("Planning herberekend met actuele instellingen");
|
|
16
|
-
};
|
|
17
9
|
const [customer, setCustomer] = useState(ALL);
|
|
18
10
|
const [deliveryType, setDeliveryType] = useState(ALL);
|
|
19
11
|
const [dateFrom, setDateFrom] = useState("");
|
|
@@ -33,5 +25,5 @@ export function LeveringenPage() {
|
|
|
33
25
|
return true;
|
|
34
26
|
});
|
|
35
27
|
}, [planned, customer, deliveryType, dateFrom, dateTo]);
|
|
36
|
-
return (_jsxs("main", { className: "p-6 space-y-6", children: [
|
|
28
|
+
return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsx("div", { className: "flex flex-wrap items-end justify-between gap-3", children: _jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum vanaf" }), _jsx(Input, { type: "date", value: dateFrom, onChange: (e) => setDateFrom(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum t/m" }), _jsx(Input, { type: "date", value: dateTo, onChange: (e) => setDateTo(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Klant" }), _jsxs(Select, { value: customer, onValueChange: setCustomer, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle klanten" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle klanten" }), customers.map((c) => _jsx(SelectItem, { value: c, children: c }, c))] })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Type levering" }), _jsxs(Select, { value: deliveryType, onValueChange: setDeliveryType, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle types" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle types" }), deliveryTypes.map((t) => _jsx(SelectItem, { value: t, children: t }, t))] })] })] })] }) }), warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: filtered, mode: "delivery", isLoading: isLoading, showPrintButtons: true }))] }));
|
|
37
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PickAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/PickAgendaView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PickAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/PickAgendaView.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED,wBAAgB,cAAc,CAAC,EAAE,YAAY,EAAE,EAAE,mBAAmB,+BAgGnE"}
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast, } from "@flowselections/core";
|
|
5
|
-
import { RefreshCw } from "lucide-react";
|
|
3
|
+
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
6
4
|
import { WeekAgendaView } from "./WeekAgendaView";
|
|
7
5
|
import { DagDetailDialog } from "./DagDetailDialog";
|
|
8
6
|
import { useOrderPlanning } from "../../hooks/useOrderPlanning";
|
|
9
|
-
import { invalidatePlanning } from "../../lib/invalidatePlanning";
|
|
10
7
|
const ALL = "__all__";
|
|
11
8
|
export function PickAgendaView({ onOrderClick }) {
|
|
12
|
-
const { planned, isLoading, error, warning, refetch } = useOrderPlanning();
|
|
13
|
-
const
|
|
9
|
+
const { planned, awaiting, isLoading, error, warning, refetch } = useOrderPlanning();
|
|
10
|
+
const awaitingCount = awaiting.length;
|
|
14
11
|
const [dayDetailDate, setDayDetailDate] = useState(null);
|
|
15
|
-
const handleRecalc = async () => {
|
|
16
|
-
await invalidatePlanning(qc);
|
|
17
|
-
toast.success("Planning herberekend met actuele instellingen");
|
|
18
|
-
};
|
|
19
12
|
const [customer, setCustomer] = useState(ALL);
|
|
20
13
|
const [deliveryType, setDeliveryType] = useState(ALL);
|
|
21
14
|
const [dateFrom, setDateFrom] = useState("");
|
|
@@ -35,5 +28,5 @@ export function PickAgendaView({ onOrderClick }) {
|
|
|
35
28
|
return true;
|
|
36
29
|
});
|
|
37
30
|
}, [planned, customer, deliveryType, dateFrom, dateTo]);
|
|
38
|
-
return (_jsxs("div", { className: "space-y-6", children: [
|
|
31
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsx("div", { className: "flex flex-wrap items-end justify-between gap-3", children: _jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum vanaf" }), _jsx(Input, { type: "date", value: dateFrom, onChange: (e) => setDateFrom(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum t/m" }), _jsx(Input, { type: "date", value: dateTo, onChange: (e) => setDateTo(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Klant" }), _jsxs(Select, { value: customer, onValueChange: setCustomer, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle klanten" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle klanten" }), customers.map((c) => _jsx(SelectItem, { value: c, children: c }, c))] })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Type levering" }), _jsxs(Select, { value: deliveryType, onValueChange: setDeliveryType, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle types" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle types" }), deliveryTypes.map((t) => _jsx(SelectItem, { value: t, children: t }, t))] })] })] })] }) }), awaitingCount > 0 && (_jsxs("div", { className: "rounded-md border border-sky-300 bg-sky-50 p-4 text-sm text-sky-900", children: [awaitingCount, " order", awaitingCount === 1 ? "" : "s", " wacht", awaitingCount === 1 ? "" : "en", " op een indeling van de Logistics Engine en worden daarom nog niet in de agenda gepland."] })), warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: filtered, mode: "pick", isLoading: isLoading, onOrderClick: onOrderClick, onDayClick: setDayDetailDate })), _jsx(DagDetailDialog, { open: !!dayDetailDate, date: dayDetailDate, planned: filtered, onOpenChange: (o) => !o && setDayDetailDate(null) })] }));
|
|
39
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,eAAe,gCA2L9B"}
|
|
@@ -6,6 +6,7 @@ import { ResponsiveAlertDialogBody, ResponsiveAlertDialogContent, ResponsiveAler
|
|
|
6
6
|
import { Link } from "@tanstack/react-router";
|
|
7
7
|
import { useServerFn } from "@tanstack/react-start";
|
|
8
8
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
9
|
+
import { toServerFnError } from "../../lib/serverFnError";
|
|
9
10
|
import { listCarriers, deleteCarrier, reorderCarriers } from "../../lib/carriers.functions";
|
|
10
11
|
import { carrierLeadDaysFromMoments } from "../../lib/carrierPlanning";
|
|
11
12
|
export function VervoerdersPage() {
|
|
@@ -21,11 +22,7 @@ export function VervoerdersPage() {
|
|
|
21
22
|
return await fetchList();
|
|
22
23
|
}
|
|
23
24
|
catch (e) {
|
|
24
|
-
|
|
25
|
-
const text = await e.text().catch(() => e.statusText);
|
|
26
|
-
throw new Error(`${e.status}: ${text}`);
|
|
27
|
-
}
|
|
28
|
-
throw e;
|
|
25
|
+
throw await toServerFnError(e);
|
|
29
26
|
}
|
|
30
27
|
},
|
|
31
28
|
retry: false,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface VerzetOrderDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
orderRef: string;
|
|
4
|
+
/** Order-context om de gekoppelde vervoerder (en diens aanmeldtijden) te bepalen. */
|
|
5
|
+
carrierTarget?: {
|
|
6
|
+
carrierId?: string | null;
|
|
7
|
+
country?: string | null;
|
|
8
|
+
province?: string | null;
|
|
9
|
+
city?: string | null;
|
|
10
|
+
};
|
|
11
|
+
onOpenChange: (open: boolean) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function VerzetOrderDialog({ open, orderRef, carrierTarget, onOpenChange }: VerzetOrderDialogProps): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=VerzetOrderDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerzetOrderDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VerzetOrderDialog.tsx"],"names":[],"mappings":"AA6CA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,aAAa,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACtB,CAAC;IACF,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAmBD,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,sBAAsB,+BAkWxG"}
|