@flowselections/floriday-verkoop-module 1.0.17 → 1.0.18
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 +6 -4
- package/dist-lib/components/verkoop/EditLocalOrderDialog.d.ts +6 -0
- package/dist-lib/components/verkoop/EditLocalOrderDialog.d.ts.map +1 -0
- package/dist-lib/components/verkoop/EditLocalOrderDialog.js +102 -0
- package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
- package/dist-lib/components/verkoop/OrderKarindelingCard.js +26 -28
- package/dist-lib/components/verkoop/OrderShipmentsCard.d.ts +5 -0
- package/dist-lib/components/verkoop/OrderShipmentsCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/OrderShipmentsCard.js +137 -0
- package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailPage.js +8 -2
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts +4 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +2 -2
- package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +43 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +381 -150
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +381 -150
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +381 -150
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +397 -154
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/cart-lock.functions.d.ts +381 -150
- package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-replan.functions.d.ts +789 -327
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
- package/dist-lib/lib/create-order.functions.d.ts +38897 -1457
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/create-order.functions.js +792 -52
- package/dist-lib/lib/expand-group-order-items.d.ts +13 -0
- package/dist-lib/lib/expand-group-order-items.d.ts.map +1 -0
- package/dist-lib/lib/expand-group-order-items.js +216 -0
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +1174 -481
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +381 -150
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-public.functions.d.ts +2701 -1084
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-writes.functions.d.ts +1939 -784
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-shipments.functions.d.ts +47158 -0
- package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -0
- package/dist-lib/lib/order-shipments.functions.js +178 -0
- package/dist-lib/lib/salesorders-mapping.d.ts +1 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.d.ts +1174 -481
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/tradeitems.functions.d.ts +381 -150
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +39 -2
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,eAAe,4CA6d9B"}
|
|
@@ -56,6 +56,7 @@ export function CreateOrderPage() {
|
|
|
56
56
|
const [pickupLocationId, setPickupLocationId] = useState(null);
|
|
57
57
|
const [carrierId, setCarrierId] = useState(null);
|
|
58
58
|
const [deliveryDate, setDeliveryDate] = useState("");
|
|
59
|
+
const [isReservation, setIsReservation] = useState(false);
|
|
59
60
|
const [notes, setNotes] = useState("");
|
|
60
61
|
const [lines, setLines] = useState([
|
|
61
62
|
{ product_id: null, product_name: "", quantity: null, unit: "stuks", unit_price: null },
|
|
@@ -132,7 +133,7 @@ export function CreateOrderPage() {
|
|
|
132
133
|
throw new Error("Selecteer een afhaallocatie (tuin)");
|
|
133
134
|
if (!carrierId)
|
|
134
135
|
throw new Error("Selecteer een vervoerder");
|
|
135
|
-
if (!deliveryDate)
|
|
136
|
+
if (!isReservation && !deliveryDate)
|
|
136
137
|
throw new Error("Selecteer een leverdatum");
|
|
137
138
|
const validLines = lines.filter((l) => l.product_id && (l.quantity ?? 0) > 0);
|
|
138
139
|
if (validLines.length === 0)
|
|
@@ -152,7 +153,8 @@ export function CreateOrderPage() {
|
|
|
152
153
|
deliveryLocationId,
|
|
153
154
|
pickupLocationId,
|
|
154
155
|
carrierId,
|
|
155
|
-
deliveryDate,
|
|
156
|
+
deliveryDate: isReservation ? null : deliveryDate,
|
|
157
|
+
isReservation,
|
|
156
158
|
notes: notes.trim() ? notes.trim() : null,
|
|
157
159
|
lines: validLines.map((l) => {
|
|
158
160
|
const p = products.find((x) => x.id === l.product_id);
|
|
@@ -203,7 +205,7 @@ export function CreateOrderPage() {
|
|
|
203
205
|
: "Kies vervoerder...", disabled: !deliveryLocationId, allowClear: false, options: carriers.map((c) => ({
|
|
204
206
|
value: c.id,
|
|
205
207
|
label: c.name + (c.is_default ? " (standaard)" : ""),
|
|
206
|
-
})), onChange: setCarrierId }), selectedLocation?.carrier_id && carrierId && carrierId !== selectedLocation.carrier_id && (_jsx("div", { className: "text-xs text-muted-foreground", children: "Wijkt af van standaard vervoerder van deze locatie \u2014 geldt alleen voor deze bestelling." }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs(Label, { className: "flex items-center gap-2", children: ["Leverdatum ", _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx(Input, { type: "date", value: canPickDate ? deliveryDate : "", min: canPickDate ? earliestISO : undefined, disabled: !canPickDate, onChange: (e) => {
|
|
208
|
+
})), onChange: setCarrierId }), selectedLocation?.carrier_id && carrierId && carrierId !== selectedLocation.carrier_id && (_jsx("div", { className: "text-xs text-muted-foreground", children: "Wijkt af van standaard vervoerder van deze locatie \u2014 geldt alleen voor deze bestelling." }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs(Label, { className: "flex items-center gap-2", children: ["Leverdatum ", !isReservation && _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx(Input, { type: "date", value: !isReservation && canPickDate ? deliveryDate : "", min: canPickDate ? earliestISO : undefined, disabled: isReservation || !canPickDate, onChange: (e) => {
|
|
207
209
|
const v = e.target.value || "";
|
|
208
210
|
if (v && v < earliestISO) {
|
|
209
211
|
toast.error(`Eerst mogelijke leverdatum is ${earliestLabel}.`);
|
|
@@ -211,7 +213,7 @@ export function CreateOrderPage() {
|
|
|
211
213
|
return;
|
|
212
214
|
}
|
|
213
215
|
setDeliveryDate(v);
|
|
214
|
-
} }), !canPickDate ? (_jsx("div", { className: "text-xs text-muted-foreground", children: "Selecteer eerst klant, afleverlocatie, afhaallocatie en vervoerder." })) : (_jsxs("div", { className: "text-xs text-muted-foreground", children: ["Eerst beschikbare leverdatum is ", earliestLabel, ", o.b.v. orderpicktijd (", pickDays, "d) en levertijd vervoerder (", carrierDeliveryDays, "d)."] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Bestelregels" }), _jsxs("div", { className: "grid grid-cols-12 gap-2 text-xs text-muted-foreground px-1", children: [_jsx("div", { className: "col-span-5", children: "Product" }), _jsx("div", { className: "col-span-2", children: "Planten" }), _jsx("div", { className: "col-span-2", children: "Fusten" }), _jsx("div", { className: "col-span-2", children: "Prijs" }), _jsx("div", { className: "col-span-1" })] }), lines.map((line, idx) => {
|
|
216
|
+
} }), _jsxs("label", { className: "mt-1 flex items-center gap-2 text-sm text-foreground", children: [_jsx("input", { type: "checkbox", checked: isReservation, onChange: (e) => setIsReservation(e.target.checked), className: "h-4 w-4 rounded border-input" }), "Reservering (nog geen vaste leverdatum)"] }), isReservation ? (_jsx("div", { className: "text-xs text-muted-foreground", children: "De bestelling wordt als reservering aangemaakt zonder leverdatumvalidatie." })) : !canPickDate ? (_jsx("div", { className: "text-xs text-muted-foreground", children: "Selecteer eerst klant, afleverlocatie, afhaallocatie en vervoerder." })) : (_jsxs("div", { className: "text-xs text-muted-foreground", children: ["Eerst beschikbare leverdatum is ", earliestLabel, ", o.b.v. orderpicktijd (", pickDays, "d) en levertijd vervoerder (", carrierDeliveryDays, "d)."] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Bestelregels" }), _jsxs("div", { className: "grid grid-cols-12 gap-2 text-xs text-muted-foreground px-1", children: [_jsx("div", { className: "col-span-5", children: "Product" }), _jsx("div", { className: "col-span-2", children: "Planten" }), _jsx("div", { className: "col-span-2", children: "Fusten" }), _jsx("div", { className: "col-span-2", children: "Prijs" }), _jsx("div", { className: "col-span-1" })] }), lines.map((line, idx) => {
|
|
215
217
|
const product = line.product_id ? products.find((p) => p.id === line.product_id) : null;
|
|
216
218
|
const ppc = Math.max(1, Number(product?.plants_per_crate ?? 1));
|
|
217
219
|
const plants = line.quantity ?? null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditLocalOrderDialog.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/EditLocalOrderDialog.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,IAAI,EACJ,YAAY,GACb,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,kDAyMA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Button, Input, toast } from "@flowselections/core";
|
|
4
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
5
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
6
|
+
import { getLocalOrderForEdit, updateLocalOrder, } from "../../lib/create-order.functions";
|
|
7
|
+
export function EditLocalOrderDialog({ orderId, open, onOpenChange, }) {
|
|
8
|
+
const load = useServerFn(getLocalOrderForEdit);
|
|
9
|
+
const save = useServerFn(updateLocalOrder);
|
|
10
|
+
const queryClient = useQueryClient();
|
|
11
|
+
const [loading, setLoading] = useState(false);
|
|
12
|
+
const [saving, setSaving] = useState(false);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [deliveryDate, setDeliveryDate] = useState("");
|
|
15
|
+
const [isReservation, setIsReservation] = useState(false);
|
|
16
|
+
const [items, setItems] = useState([]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!open)
|
|
19
|
+
return;
|
|
20
|
+
let cancelled = false;
|
|
21
|
+
setLoading(true);
|
|
22
|
+
setError(null);
|
|
23
|
+
load({ data: { orderId } })
|
|
24
|
+
.then((r) => {
|
|
25
|
+
if (cancelled)
|
|
26
|
+
return;
|
|
27
|
+
setDeliveryDate((r.deliveryDate ?? "").slice(0, 10));
|
|
28
|
+
setIsReservation(!!r.isReservation);
|
|
29
|
+
setItems(r.items.map((it) => ({
|
|
30
|
+
id: it.id,
|
|
31
|
+
productName: it.productName,
|
|
32
|
+
quantity: it.quantity,
|
|
33
|
+
unit: it.unit,
|
|
34
|
+
plantsPerCrate: it.plantsPerCrate ?? 1,
|
|
35
|
+
minQuantity: Number(it.minQuantity ?? 0),
|
|
36
|
+
shippedQuantity: Number(it.shippedQuantity ?? 0),
|
|
37
|
+
plannedQuantity: Number(it.plannedQuantity ?? 0),
|
|
38
|
+
})));
|
|
39
|
+
})
|
|
40
|
+
.catch((e) => !cancelled && setError(e?.message ?? "Laden mislukt"))
|
|
41
|
+
.finally(() => !cancelled && setLoading(false));
|
|
42
|
+
return () => {
|
|
43
|
+
cancelled = true;
|
|
44
|
+
};
|
|
45
|
+
}, [open, orderId, load]);
|
|
46
|
+
if (!open)
|
|
47
|
+
return null;
|
|
48
|
+
const setPlants = (idx, plants) => {
|
|
49
|
+
setItems((prev) => prev.map((p, i) => (i === idx ? { ...p, quantity: Number.isFinite(plants) ? Math.max(0, plants) : 0 } : p)));
|
|
50
|
+
};
|
|
51
|
+
const setFusten = (idx, fusten) => {
|
|
52
|
+
setItems((prev) => prev.map((p, i) => {
|
|
53
|
+
if (i !== idx)
|
|
54
|
+
return p;
|
|
55
|
+
const ppc = Math.max(1, p.plantsPerCrate);
|
|
56
|
+
const f = Number.isFinite(fusten) ? Math.max(0, fusten) : 0;
|
|
57
|
+
return { ...p, quantity: f * ppc };
|
|
58
|
+
}));
|
|
59
|
+
};
|
|
60
|
+
const handleSave = async () => {
|
|
61
|
+
for (const it of items) {
|
|
62
|
+
const ppc = Math.max(1, it.plantsPerCrate);
|
|
63
|
+
if (it.quantity < ppc || it.quantity % ppc !== 0) {
|
|
64
|
+
toast.error(`"${it.productName}" moet per hele fust besteld worden (min. 1 fust = ${ppc} planten).`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (it.quantity < it.minQuantity) {
|
|
68
|
+
toast.error(`"${it.productName}" kan niet lager dan ${it.minQuantity} — er is al ${it.shippedQuantity} geleverd en ${it.plannedQuantity} gepland op bezorgmomenten.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
setSaving(true);
|
|
74
|
+
await save({
|
|
75
|
+
data: {
|
|
76
|
+
orderId,
|
|
77
|
+
deliveryDate: !isReservation && deliveryDate ? deliveryDate : undefined,
|
|
78
|
+
items: items.map((i) => ({ itemId: i.id, quantity: Math.round(i.quantity) })),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
toast.success("Bestelling bijgewerkt");
|
|
82
|
+
await Promise.all([
|
|
83
|
+
queryClient.invalidateQueries({ queryKey: ["floriday", "salesorders-cache"] }),
|
|
84
|
+
queryClient.invalidateQueries({ queryKey: ["order-shipments", orderId] }),
|
|
85
|
+
queryClient.invalidateQueries({ queryKey: ["order-carts", orderId] }),
|
|
86
|
+
queryClient.invalidateQueries({ queryKey: ["salesorder-detail", orderId] }),
|
|
87
|
+
]);
|
|
88
|
+
onOpenChange(false);
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
toast.error(e?.message ?? "Bijwerken mislukt");
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
setSaving(false);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", onClick: () => !saving && onOpenChange(false), children: _jsxs("div", { className: "w-full max-w-xl rounded-lg border border-border bg-card p-6 shadow-lg", onClick: (e) => e.stopPropagation(), children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Bestelling bewerken" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Pas de leverdatum en het aantal planten of fusten per regel aan. Voorraad en karindeling worden automatisch bijgewerkt." }), loading ? (_jsx("div", { className: "mt-6 text-sm text-muted-foreground", children: "Laden\u2026" })) : error ? (_jsx("div", { className: "mt-6 rounded border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive", children: error })) : (_jsxs("div", { className: "mt-5 space-y-4", children: [!isReservation && (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-foreground", children: "Leverdatum" }), _jsx(Input, { type: "date", value: deliveryDate, onChange: (e) => setDeliveryDate(e.target.value) })] })), isReservation && (_jsx("div", { className: "rounded border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: "Dit is een reservering \u2014 er is nog geen leverdatum. Voeg een bezorgmoment toe om (deels) uit te leveren." })), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium text-foreground", children: "Regels" }), _jsxs("div", { className: "grid grid-cols-12 gap-2 px-1 text-xs text-muted-foreground", children: [_jsx("div", { className: "col-span-6", children: "Product" }), _jsx("div", { className: "col-span-3", children: "Planten" }), _jsx("div", { className: "col-span-3", children: "Fusten" })] }), _jsxs("div", { className: "mt-1 space-y-2", children: [items.map((it, idx) => {
|
|
98
|
+
const ppc = Math.max(1, it.plantsPerCrate);
|
|
99
|
+
const fusten = ppc > 0 ? Math.ceil(it.quantity / ppc) : 0;
|
|
100
|
+
return (_jsxs("div", { className: "grid grid-cols-12 items-start gap-2 rounded border border-border p-2", children: [_jsxs("div", { className: "col-span-6 min-w-0 text-sm", children: [_jsx("div", { className: "truncate font-medium text-foreground", children: it.productName }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [ppc, " planten per fust"] }), it.minQuantity > 0 && (_jsxs("div", { className: "text-xs text-primary", children: ["min. ", it.minQuantity, " (reeds ", it.shippedQuantity, " geleverd, ", it.plannedQuantity, " gepland)"] }))] }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { type: "number", min: 0, step: ppc, value: it.quantity, onChange: (e) => setPlants(idx, Number(e.target.value)) }) }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { type: "number", min: 0, step: 1, value: fusten, onChange: (e) => setFusten(idx, Number(e.target.value)) }) })] }, it.id));
|
|
101
|
+
}), items.length === 0 && (_jsx("div", { className: "text-sm text-muted-foreground", children: "Geen regels op deze bestelling." }))] })] })] })), _jsxs("div", { className: "mt-6 flex justify-end gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false), disabled: saving, children: "Annuleren" }), _jsx(Button, { size: "sm", onClick: handleSave, disabled: saving || loading || !!error, children: saving ? "Bezig…" : "Opslaan" })] })] }) }));
|
|
102
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"OrderKarindelingCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderKarindelingCard.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA8F/D,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,2CAgLvE"}
|
|
@@ -9,6 +9,7 @@ import { Badge, Card, CardContent, CardHeader, CardTitle, Table, TableBody, Tabl
|
|
|
9
9
|
import { CheckCircle2, Lock } from "lucide-react";
|
|
10
10
|
import { supabase } from "../../integrations/supabase/client";
|
|
11
11
|
import { planCarts } from "../../lib/cart-planner";
|
|
12
|
+
import { expandOrderItemsForPlanner } from "../../lib/expand-group-order-items";
|
|
12
13
|
function deriveCartsFromFloriday(order) {
|
|
13
14
|
const o = order.raw.order ?? {};
|
|
14
15
|
const pack = o?.packingConfiguration ?? {};
|
|
@@ -74,6 +75,7 @@ export function OrderKarindelingCard({ order }) {
|
|
|
74
75
|
const orderId = typeof rawId === "string" ? rawId.replace(/^(local:|mailbox-proposal:)/, "") : rawId;
|
|
75
76
|
const [lockedAt, setLockedAt] = useState(null);
|
|
76
77
|
const [dbItems, setDbItems] = useState(null);
|
|
78
|
+
const [plannerInputs, setPlannerInputs] = useState(null);
|
|
77
79
|
// Laadt order_items + gekoppelde products (voorraad-belading) en
|
|
78
80
|
// ververst live bij mutaties op order_items, orders of products.
|
|
79
81
|
useEffect(() => {
|
|
@@ -90,8 +92,24 @@ export function OrderKarindelingCard({ order }) {
|
|
|
90
92
|
]);
|
|
91
93
|
if (!active)
|
|
92
94
|
return;
|
|
93
|
-
|
|
95
|
+
const items = itemRows ?? [];
|
|
96
|
+
setDbItems(items);
|
|
94
97
|
setLockedAt(orderRow?.plan_locked_at ?? null);
|
|
98
|
+
// Alle order_items doorgeven — expand-helper resolveert zelf groepen
|
|
99
|
+
// (via product_id óf via naamprefix "[Groep] ...") en losse artikelen.
|
|
100
|
+
const raws = items.map((it) => ({
|
|
101
|
+
id: it.id,
|
|
102
|
+
product_id: it.product_id,
|
|
103
|
+
product_name: it.product_name,
|
|
104
|
+
quantity: Number(it.quantity ?? 0),
|
|
105
|
+
plants_per_crate: Math.max(1, Number(it.products?.plants_per_crate ?? 1)),
|
|
106
|
+
crates_per_layer: Math.max(1, Number(it.products?.crates_per_layer ?? 1)),
|
|
107
|
+
layers_per_cart: Math.max(1, Number(it.products?.layers_per_cart ?? 1)),
|
|
108
|
+
}));
|
|
109
|
+
const expanded = await expandOrderItemsForPlanner(supabase, raws);
|
|
110
|
+
if (!active)
|
|
111
|
+
return;
|
|
112
|
+
setPlannerInputs(expanded);
|
|
95
113
|
};
|
|
96
114
|
void load();
|
|
97
115
|
const channel = supabase
|
|
@@ -105,36 +123,16 @@ export function OrderKarindelingCard({ order }) {
|
|
|
105
123
|
void supabase.removeChannel(channel);
|
|
106
124
|
};
|
|
107
125
|
}, [orderId]);
|
|
108
|
-
// Bouw plannerinput
|
|
109
|
-
//
|
|
126
|
+
// Bouw plannerinput. Bij een groep-order_item zijn de sub-items al
|
|
127
|
+
// opgesplitst met member-belading; anders is er één regel per item.
|
|
110
128
|
const plannerCarts = useMemo(() => {
|
|
111
|
-
if (!
|
|
129
|
+
if (!plannerInputs || plannerInputs.length === 0) {
|
|
130
|
+
if (dbItems && dbItems.length > 0)
|
|
131
|
+
return null;
|
|
112
132
|
return null;
|
|
113
|
-
const inputs = [];
|
|
114
|
-
for (const it of dbItems) {
|
|
115
|
-
const p = it.products;
|
|
116
|
-
if (!it.product_id || !p)
|
|
117
|
-
continue;
|
|
118
|
-
const ppc = Math.max(1, Number(p.plants_per_crate ?? 0));
|
|
119
|
-
const cpl = Math.max(1, Number(p.crates_per_layer ?? 0));
|
|
120
|
-
const lpc = Math.max(1, Number(p.layers_per_cart ?? 0));
|
|
121
|
-
const plants = Math.max(0, Number(it.quantity ?? 0));
|
|
122
|
-
if (plants <= 0)
|
|
123
|
-
continue;
|
|
124
|
-
inputs.push({
|
|
125
|
-
order_item_id: it.id,
|
|
126
|
-
product_id: it.product_id,
|
|
127
|
-
product_name: it.product_name,
|
|
128
|
-
plants,
|
|
129
|
-
plants_per_crate: ppc,
|
|
130
|
-
crates_per_layer: cpl,
|
|
131
|
-
layers_per_cart: lpc,
|
|
132
|
-
});
|
|
133
133
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return planCarts(inputs).carts;
|
|
137
|
-
}, [dbItems]);
|
|
134
|
+
return planCarts(plannerInputs).carts;
|
|
135
|
+
}, [plannerInputs, dbItems]);
|
|
138
136
|
const floridayCarts = useMemo(() => deriveCartsFromFloriday(order), [order]);
|
|
139
137
|
const usingVoorraad = plannerCarts !== null;
|
|
140
138
|
const carts = usingVoorraad
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderShipmentsCard.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/OrderShipmentsCard.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA4C/D,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,kDASrE"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Bezorgmomenten (deelleveringen) voor een bestelling.
|
|
3
|
+
// Toont totalen (besteld / gepland / geleverd / openstaand), lijst met shipments
|
|
4
|
+
// en knoppen om nieuwe bezorgmomenten aan te maken en te markeren als geleverd.
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, } from "@flowselections/core";
|
|
7
|
+
import { CalendarPlus, CheckCircle2, Trash2, Truck } from "lucide-react";
|
|
8
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
9
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
10
|
+
import { cancelShipment, createShipment, listOrderShipments, markShipmentShipped, } from "../../lib/order-shipments.functions";
|
|
11
|
+
function formatDate(iso) {
|
|
12
|
+
if (!iso)
|
|
13
|
+
return "—";
|
|
14
|
+
const d = new Date(iso);
|
|
15
|
+
if (Number.isNaN(d.getTime()))
|
|
16
|
+
return iso;
|
|
17
|
+
return d.toLocaleDateString("nl-NL", { day: "numeric", month: "short", year: "numeric" });
|
|
18
|
+
}
|
|
19
|
+
export function OrderShipmentsCard({ order }) {
|
|
20
|
+
// Alleen lokale (en dus reserveer-bare) orders ondersteunen deelleveringen.
|
|
21
|
+
const rawId = order.isLocal && order.id.startsWith("local:")
|
|
22
|
+
? order.id.slice("local:".length)
|
|
23
|
+
: null;
|
|
24
|
+
if (!rawId)
|
|
25
|
+
return null;
|
|
26
|
+
return _jsx(OrderShipmentsInner, { orderId: rawId });
|
|
27
|
+
}
|
|
28
|
+
function OrderShipmentsInner({ orderId }) {
|
|
29
|
+
const list = useServerFn(listOrderShipments);
|
|
30
|
+
const create = useServerFn(createShipment);
|
|
31
|
+
const markShipped = useServerFn(markShipmentShipped);
|
|
32
|
+
const cancel = useServerFn(cancelShipment);
|
|
33
|
+
const queryClient = useQueryClient();
|
|
34
|
+
const [openCreate, setOpenCreate] = useState(false);
|
|
35
|
+
const { data, isLoading } = useQuery({
|
|
36
|
+
queryKey: ["order-shipments", orderId],
|
|
37
|
+
queryFn: () => list({ data: { orderId } }),
|
|
38
|
+
});
|
|
39
|
+
const totals = data?.totals ?? [];
|
|
40
|
+
const shipments = data?.shipments ?? [];
|
|
41
|
+
const summed = useMemo(() => {
|
|
42
|
+
return totals.reduce((a, t) => ({
|
|
43
|
+
ordered: a.ordered + t.ordered,
|
|
44
|
+
shipped: a.shipped + t.shipped,
|
|
45
|
+
planned: a.planned + t.planned,
|
|
46
|
+
outstanding: a.outstanding + t.outstanding,
|
|
47
|
+
}), { ordered: 0, shipped: 0, planned: 0, outstanding: 0 });
|
|
48
|
+
}, [totals]);
|
|
49
|
+
const refresh = () => {
|
|
50
|
+
queryClient.invalidateQueries({ queryKey: ["order-shipments", orderId] });
|
|
51
|
+
queryClient.invalidateQueries({ queryKey: ["floriday", "salesorders-cache"] });
|
|
52
|
+
};
|
|
53
|
+
const hasOpen = totals.some((t) => t.remaining > 0);
|
|
54
|
+
const allShipped = totals.length > 0 && summed.outstanding === 0;
|
|
55
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between", children: [_jsx(CardTitle, { className: "text-base", children: "Bezorgmomenten & deelleveringen" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Badge, { variant: allShipped ? "default" : "secondary", children: [summed.shipped, " / ", summed.ordered, " geleverd"] }), _jsxs(Button, { size: "sm", onClick: () => setOpenCreate(true), disabled: !hasOpen, title: hasOpen ? "" : "Er zijn geen openstaande aantallen meer.", children: [_jsx(CalendarPlus, { className: "mr-2 h-4 w-4" }), "Nieuw bezorgmoment"] })] })] }), _jsx(CardContent, { className: "space-y-6", children: isLoading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Laden\u2026" })) : (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium", children: "Voortgang per artikel" }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Besteld" }), _jsx(TableHead, { className: "text-right", children: "Gepland" }), _jsx(TableHead, { className: "text-right", children: "Geleverd" }), _jsx(TableHead, { className: "text-right", children: "Nog te leveren" })] }) }), _jsx(TableBody, { children: totals.map((t) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-medium", children: t.product_name }), _jsx(TableCell, { className: "text-right", children: t.ordered }), _jsx(TableCell, { className: "text-right", children: t.planned }), _jsx(TableCell, { className: "text-right", children: t.shipped }), _jsx(TableCell, { className: "text-right", children: _jsx("span", { className: t.outstanding > 0 ? "font-semibold text-primary" : "text-muted-foreground", children: t.outstanding }) })] }, t.order_item_id))) })] })] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium", children: "Bezorgmomenten" }), shipments.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen bezorgmomenten aangemaakt. Maak er \u00E9\u00E9n aan om (deels) uit te leveren." })) : (_jsx("div", { className: "space-y-3", children: shipments.map((s) => (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border bg-muted/30 px-3 py-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "font-mono font-medium", children: ["Levering #", s.shipment_number] }), _jsx("span", { className: "text-muted-foreground", children: formatDate(s.delivery_date) }), _jsxs(Badge, { variant: s.status === "shipped" ? "default" : "secondary", className: "gap-1", children: [s.status === "shipped" && _jsx(CheckCircle2, { className: "h-3 w-3" }), s.status === "shipped"
|
|
56
|
+
? "Geleverd"
|
|
57
|
+
: s.status === "cancelled"
|
|
58
|
+
? "Geannuleerd"
|
|
59
|
+
: "Gepland"] })] }), _jsx("div", { className: "flex gap-2", children: s.status === "planned" && (_jsxs(_Fragment, { children: [_jsxs(Button, { size: "sm", variant: "default", onClick: async () => {
|
|
60
|
+
try {
|
|
61
|
+
await markShipped({ data: { shipmentId: s.id } });
|
|
62
|
+
toast.success("Bezorgmoment geleverd");
|
|
63
|
+
refresh();
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
toast.error(e?.message ?? "Markeren mislukt");
|
|
67
|
+
}
|
|
68
|
+
}, children: [_jsx(Truck, { className: "mr-2 h-4 w-4" }), "Markeer geleverd"] }), _jsx(Button, { size: "sm", variant: "outline", onClick: async () => {
|
|
69
|
+
if (!confirm("Bezorgmoment verwijderen?"))
|
|
70
|
+
return;
|
|
71
|
+
try {
|
|
72
|
+
await cancel({ data: { shipmentId: s.id } });
|
|
73
|
+
toast.success("Bezorgmoment verwijderd");
|
|
74
|
+
refresh();
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
toast.error(e?.message ?? "Verwijderen mislukt");
|
|
78
|
+
}
|
|
79
|
+
}, children: _jsx(Trash2, { className: "h-4 w-4" }) })] })) })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Aantal" })] }) }), _jsx(TableBody, { children: s.order_shipment_items.map((i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: i.product_name }), _jsx(TableCell, { className: "text-right", children: i.quantity })] }, i.id))) })] })] }, s.id))) }))] })] })) })] }), openCreate && (_jsx(CreateShipmentDialog, { orderId: orderId, totals: totals.filter((t) => t.remaining > 0), onClose: () => setOpenCreate(false), onCreated: () => {
|
|
80
|
+
setOpenCreate(false);
|
|
81
|
+
refresh();
|
|
82
|
+
}, create: create }))] }));
|
|
83
|
+
}
|
|
84
|
+
function CreateShipmentDialog({ orderId, totals, onClose, onCreated, create, }) {
|
|
85
|
+
const [deliveryDate, setDeliveryDate] = useState(() => {
|
|
86
|
+
const d = new Date();
|
|
87
|
+
d.setDate(d.getDate() + 1);
|
|
88
|
+
return d.toISOString().slice(0, 10);
|
|
89
|
+
});
|
|
90
|
+
const [qtyByItem, setQtyByItem] = useState(() => {
|
|
91
|
+
const init = {};
|
|
92
|
+
for (const t of totals)
|
|
93
|
+
init[t.order_item_id] = 0;
|
|
94
|
+
return init;
|
|
95
|
+
});
|
|
96
|
+
const [saving, setSaving] = useState(false);
|
|
97
|
+
const items = totals.map((t) => ({
|
|
98
|
+
total: t,
|
|
99
|
+
qty: qtyByItem[t.order_item_id] ?? 0,
|
|
100
|
+
}));
|
|
101
|
+
const canSave = items.some((i) => i.qty > 0) && !!deliveryDate;
|
|
102
|
+
const handleSave = async () => {
|
|
103
|
+
setSaving(true);
|
|
104
|
+
try {
|
|
105
|
+
const selected = items.filter((i) => i.qty > 0);
|
|
106
|
+
await create({
|
|
107
|
+
data: {
|
|
108
|
+
orderId,
|
|
109
|
+
deliveryDate,
|
|
110
|
+
items: selected.map((i) => ({
|
|
111
|
+
orderItemId: i.total.order_item_id,
|
|
112
|
+
productId: i.total.product_id,
|
|
113
|
+
productName: i.total.product_name,
|
|
114
|
+
quantity: i.qty,
|
|
115
|
+
})),
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
toast.success("Bezorgmoment aangemaakt");
|
|
119
|
+
onCreated();
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
toast.error(e?.message ?? "Aanmaken mislukt");
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setSaving(false);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", onClick: () => !saving && onClose(), children: _jsxs("div", { className: "w-full max-w-xl rounded-lg border border-border bg-card p-6 shadow-lg", onClick: (e) => e.stopPropagation(), children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Nieuw bezorgmoment" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Geef aan wat er op deze datum wordt geleverd. Aantallen mogen niet hoger zijn dan het openstaande aantal." }), _jsxs("div", { className: "mt-5 space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium", children: "Bezorgdatum" }), _jsx(Input, { type: "date", value: deliveryDate, onChange: (e) => setDeliveryDate(e.target.value) })] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium", children: "Regels" }), _jsxs("div", { className: "space-y-2", children: [items.map((i) => {
|
|
129
|
+
const ppc = Math.max(1, i.total.plants_per_crate ?? 1);
|
|
130
|
+
const remainingFusten = Math.floor(i.total.remaining / ppc);
|
|
131
|
+
const qtyFusten = Math.floor(i.qty / ppc);
|
|
132
|
+
return (_jsxs("div", { className: "grid grid-cols-12 items-center gap-2 rounded border border-border p-2", children: [_jsxs("div", { className: "col-span-6 min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium", children: i.total.product_name }), _jsxs("div", { className: "text-xs text-muted-foreground", children: ["openstaand: ", remainingFusten, " fusten (", i.total.remaining, " planten) \u00B7 ", ppc, "/fust"] })] }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { type: "number", min: 0, max: remainingFusten, step: 1, value: qtyFusten, onChange: (e) => {
|
|
133
|
+
const f = Math.max(0, Math.min(remainingFusten, Number(e.target.value) || 0));
|
|
134
|
+
setQtyByItem((prev) => ({ ...prev, [i.total.order_item_id]: f * ppc }));
|
|
135
|
+
} }) }), _jsx("div", { className: "col-span-1 text-xs text-muted-foreground", children: "fusten" }), _jsx("div", { className: "col-span-2 flex gap-1", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setQtyByItem((prev) => ({ ...prev, [i.total.order_item_id]: remainingFusten * ppc })), children: "Alles" }) })] }, i.total.order_item_id));
|
|
136
|
+
}), items.length === 0 && (_jsx("div", { className: "text-sm text-muted-foreground", children: "Geen openstaande aantallen." }))] })] })] }), _jsxs("div", { className: "mt-6 flex justify-end gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: onClose, disabled: saving, children: "Annuleren" }), _jsx(Button, { size: "sm", onClick: handleSave, disabled: !canSave || saving, children: saving ? "Bezig…" : "Aanmaken" })] })] }) }));
|
|
137
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrderDetailPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SalesOrderDetailPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailPage.tsx"],"names":[],"mappings":"AAQA,wBAAgB,oBAAoB,4CA0DnC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
2
3
|
import { Link, useParams } from "@tanstack/react-router";
|
|
3
4
|
import { Button } from "@flowselections/core";
|
|
4
|
-
import { ArrowLeft } from "lucide-react";
|
|
5
|
+
import { ArrowLeft, Pencil } from "lucide-react";
|
|
5
6
|
import { SalesOrderDetailView } from "../../components/verkoop/SalesOrderDetailView";
|
|
7
|
+
import { EditLocalOrderDialog } from "../../components/verkoop/EditLocalOrderDialog";
|
|
6
8
|
import { useSalesOrdersQuery } from "../../lib/useSalesOrdersQuery";
|
|
7
9
|
export function SalesOrderDetailPage() {
|
|
8
10
|
const { salesOrderId } = useParams({
|
|
@@ -10,5 +12,9 @@ export function SalesOrderDetailPage() {
|
|
|
10
12
|
});
|
|
11
13
|
const { data, isLoading, error } = useSalesOrdersQuery();
|
|
12
14
|
const order = data?.orders.find((o) => o.id === salesOrderId) ?? null;
|
|
13
|
-
|
|
15
|
+
const [editOpen, setEditOpen] = useState(false);
|
|
16
|
+
const rawLocalId = order?.isLocal && order.id.startsWith("local:")
|
|
17
|
+
? order.id.slice("local:".length)
|
|
18
|
+
: null;
|
|
19
|
+
return (_jsxs("main", { className: "space-y-5 p-6", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", 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"] }) }), rawLocalId && (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => setEditOpen(true), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Bestelling bewerken"] }))] }), isLoading && (_jsx("div", { className: "rounded-lg border border-border bg-card p-8 text-sm text-muted-foreground", children: "Laden\u2026" })), error && (_jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: error.message })), !isLoading && !error && !order && (_jsx("div", { className: "rounded-lg border border-border bg-card p-8 text-sm text-muted-foreground", children: "Order niet gevonden." })), order && (_jsx(SalesOrderDetailView, { order: order, sellerFallback: data?.sellerFallback ?? null })), rawLocalId && (_jsx(EditLocalOrderDialog, { orderId: rawLocalId, open: editOpen, onOpenChange: setEditOpen }))] }));
|
|
14
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAiInE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,GACf,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,2CAgSA"}
|
|
@@ -3,6 +3,7 @@ import { CheckCircle2, ImageIcon } from "lucide-react";
|
|
|
3
3
|
import { OrderKarindelingCard } from "./OrderKarindelingCard";
|
|
4
4
|
import { OrderAfleverbrievenCard } from "./OrderAfleverbrievenCard";
|
|
5
5
|
import { AutoFulfillmentStatusCard } from "./AutoFulfillmentStatusCard";
|
|
6
|
+
import { OrderShipmentsCard } from "./OrderShipmentsCard";
|
|
6
7
|
const eurFlex = new Intl.NumberFormat("nl-NL", {
|
|
7
8
|
style: "currency",
|
|
8
9
|
currency: "EUR",
|
|
@@ -212,5 +213,5 @@ export function SalesOrderDetailView({ order, sellerFallback, }) {
|
|
|
212
213
|
const bestellingLabel = order.status.isCancelled
|
|
213
214
|
? "Geannuleerd"
|
|
214
215
|
: STATUS_LABELS[statusKey] ?? (order.status.isShipped ? "Verzonden" : order.status.isConfirmed ? "Order bevestigd" : "Open");
|
|
215
|
-
return (_jsxs("div", { className: "space-y-6", children: [_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: [order.fustCount, " fusten"] }), _jsxs("div", { children: [order.karCount, " karren"] })] }) }), _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] })) : ("—") })] }), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Levering" }), _jsx(Row, { label: "Afleverdatum", children: fmtDateTime(order.deliveryAt) }), _jsx(Row, { label: "Incoterm", children: incoterm }), _jsx(Row, { label: "Levering", children: _jsxs("div", { className: "inline-flex max-w-xs items-start gap-3 rounded-md border border-border bg-card p-3", children: [_jsx("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M3 11l9-8 9 8" }), _jsx("path", { d: "M5 10v10h14V10" }), _jsx("path", { d: "M10 20v-6h4v6" })] }) }), _jsxs("div", { className: "text-sm", children: [_jsx("div", { children: addr.line || "—" }), _jsx("div", { children: [addr.postal, addr.city].filter(Boolean).join(" ") || "—" }), _jsx("div", { children: countryLabel ?? "" }), addr.gln && (_jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: addr.gln }))] })] }) })] }), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Klant" }), _jsx(Row, { label: "Naam", children: _jsx("span", { className: "font-medium", children: customerName }) }), _jsx(Row, { label: "GLN", children: customerGln }), _jsx(Row, { label: "Administratienummer", children: customerAdmin }), _jsx(Row, { label: "Telefoonnummer", children: customerPhone })] })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "rounded-md border border-border p-4", children: [_jsx("div", { className: "mb-3 text-sm font-semibold", children: "Prijs per stuk" }), _jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Product" }), _jsxs("span", { children: [oldProductPrice !== null && (_jsx("span", { className: "mr-2 text-destructive line-through", children: eurFlex.format(oldProductPrice) })), eurFlex.format(productUnit)] })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Transportkosten" }), _jsx("span", { children: eurFlex.format(transportPerPiece) })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Inkoopprijs" }), _jsx("span", { children: eurFlex.format(purchaseUnit) })] }), _jsxs("div", { className: "mt-2 flex justify-between border-t border-border pt-2 font-semibold", children: [_jsx("span", { children: "Totaal" }), _jsxs("span", { children: [_jsxs("span", { className: "mr-2 text-xs font-normal text-muted-foreground", children: ["(", packages, " \u00D7 ", piecesPerPackage, " \u00D7 ", eurFlex.format(productUnit), ")"] }), eurFlex.format(totalAmount)] })] })] })] }), _jsxs("div", { className: "rounded-md border border-border p-4", children: [_jsx("div", { className: "mb-3 text-sm font-semibold", children: "Status" }), _jsxs("div", { className: "space-y-3 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Bestelling" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), bestellingLabel] })] }), hasCorrection && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Correctie" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), "Correctie is verwerkt"] })] }))] })] })] })] }), _jsx(OrderKarindelingCard, { order: order }), o?.salesOrderId ? (_jsxs(_Fragment, { children: [_jsx(AutoFulfillmentStatusCard, { salesOrderId: String(o.salesOrderId) }), _jsx(OrderAfleverbrievenCard, { salesOrderId: String(o.salesOrderId) })] })) : null] }));
|
|
216
|
+
return (_jsxs("div", { className: "space-y-6", children: [_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: [order.fustCount, " fusten"] }), _jsxs("div", { children: [order.karCount, " karren"] })] }) }), _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] })) : ("—") })] }), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Levering" }), _jsx(Row, { label: "Afleverdatum", children: fmtDateTime(order.deliveryAt) }), _jsx(Row, { label: "Incoterm", children: incoterm }), _jsx(Row, { label: "Levering", children: _jsxs("div", { className: "inline-flex max-w-xs items-start gap-3 rounded-md border border-border bg-card p-3", children: [_jsx("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M3 11l9-8 9 8" }), _jsx("path", { d: "M5 10v10h14V10" }), _jsx("path", { d: "M10 20v-6h4v6" })] }) }), _jsxs("div", { className: "text-sm", children: [_jsx("div", { children: addr.line || "—" }), _jsx("div", { children: [addr.postal, addr.city].filter(Boolean).join(" ") || "—" }), _jsx("div", { children: countryLabel ?? "" }), addr.gln && (_jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: addr.gln }))] })] }) })] }), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Klant" }), _jsx(Row, { label: "Naam", children: _jsx("span", { className: "font-medium", children: customerName }) }), _jsx(Row, { label: "GLN", children: customerGln }), _jsx(Row, { label: "Administratienummer", children: customerAdmin }), _jsx(Row, { label: "Telefoonnummer", children: customerPhone })] })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "rounded-md border border-border p-4", children: [_jsx("div", { className: "mb-3 text-sm font-semibold", children: "Prijs per stuk" }), _jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Product" }), _jsxs("span", { children: [oldProductPrice !== null && (_jsx("span", { className: "mr-2 text-destructive line-through", children: eurFlex.format(oldProductPrice) })), eurFlex.format(productUnit)] })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Transportkosten" }), _jsx("span", { children: eurFlex.format(transportPerPiece) })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-muted-foreground", children: "Inkoopprijs" }), _jsx("span", { children: eurFlex.format(purchaseUnit) })] }), _jsxs("div", { className: "mt-2 flex justify-between border-t border-border pt-2 font-semibold", children: [_jsx("span", { children: "Totaal" }), _jsxs("span", { children: [_jsxs("span", { className: "mr-2 text-xs font-normal text-muted-foreground", children: ["(", packages, " \u00D7 ", piecesPerPackage, " \u00D7 ", eurFlex.format(productUnit), ")"] }), eurFlex.format(totalAmount)] })] })] })] }), _jsxs("div", { className: "rounded-md border border-border p-4", children: [_jsx("div", { className: "mb-3 text-sm font-semibold", children: "Status" }), _jsxs("div", { className: "space-y-3 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Bestelling" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), bestellingLabel] })] }), hasCorrection && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Correctie" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), "Correctie is verwerkt"] })] }))] })] })] })] }), _jsx(OrderShipmentsCard, { order: order }), _jsx(OrderKarindelingCard, { order: order }), o?.salesOrderId ? (_jsxs(_Fragment, { children: [_jsx(AutoFulfillmentStatusCard, { salesOrderId: String(o.salesOrderId) }), _jsx(OrderAfleverbrievenCard, { salesOrderId: String(o.salesOrderId) })] })) : null] }));
|
|
216
217
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { SalesOrderDTO } from "../../lib/salesorders-mapping";
|
|
2
|
-
export declare function SalesOrdersTable({ orders, loading, onSelectOrder, }: {
|
|
2
|
+
export declare function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder, onEditOrder, onConfirmOrder, }: {
|
|
3
3
|
orders: SalesOrderDTO[];
|
|
4
4
|
loading?: boolean;
|
|
5
5
|
onSelectOrder?: (order: SalesOrderDTO) => void;
|
|
6
|
+
onDeleteOrder?: (order: SalesOrderDTO) => void;
|
|
7
|
+
onEditOrder?: (order: SalesOrderDTO) => void;
|
|
8
|
+
onConfirmOrder?: (order: SalesOrderDTO) => void;
|
|
6
9
|
}): import("react/jsx-runtime").JSX.Element;
|
|
7
10
|
//# sourceMappingURL=SalesOrdersTable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAsEnE,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,
|
|
1
|
+
{"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAsEnE,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,GACf,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;CACjD,2CAsKA"}
|
|
@@ -45,7 +45,7 @@ function StatusTag({ status, rawOrder, }) {
|
|
|
45
45
|
}
|
|
46
46
|
return (_jsx(Badge, { variant: "outline", className: "border-muted-foreground/30 bg-muted text-muted-foreground", children: "Nog picken" }));
|
|
47
47
|
}
|
|
48
|
-
export function SalesOrdersTable({ orders, loading, onSelectOrder, }) {
|
|
48
|
+
export function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder, onEditOrder, onConfirmOrder, }) {
|
|
49
49
|
const [selected, setSelected] = useState(new Set());
|
|
50
50
|
const allChecked = orders.length > 0 && selected.size === orders.length;
|
|
51
51
|
const toggle = (id) => setSelected((s) => {
|
|
@@ -57,6 +57,6 @@ export function SalesOrdersTable({ orders, loading, onSelectOrder, }) {
|
|
|
57
57
|
Array.from({ length: 6 }).map((_, i) => (_jsx(TableRow, { children: Array.from({ length: 9 }).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: 9, className: "py-12 text-center text-muted-foreground", children: "Geen verkooporders gevonden." }) })), !loading &&
|
|
58
58
|
orders.map((o) => {
|
|
59
59
|
const ordered = formatDateShort(o.orderedAt);
|
|
60
|
-
return (_jsxs(TableRow, { className: "align-top cursor-pointer", onClick: () => onSelectOrder?.(o), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(o.id), onCheckedChange: () => toggle(o.id) }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "font-medium text-foreground", children: ["\u20AC ", o.revenue.toFixed(2)] }), o.orderNumber && (_jsx("div", { className: "text-xs text-muted-foreground", children: o.orderNumber }))] }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Package, { className: "h-4 w-4 text-primary" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: ordered.time })] })] }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.karCount }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.fustCount }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: o.customer.name }), o.isLocal && (_jsx(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: "Lokaal" }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [o.customer.postalCode, o.customer.city].filter(Boolean).join(" ") })] }), _jsx(TableCell, { className: "text-sm text-foreground", children: formatDateLong(o.deliveryAt) }), _jsx(TableCell, { children: _jsx(StatusTag, { status: o.status, rawOrder: o.raw?.order }) }), _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, { children: "Bewerken" }), _jsx(DropdownMenuItem, { children: "Details bekijken" }), _jsx(DropdownMenuItem, { children: "Bevestigen" }), _jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", children: "
|
|
60
|
+
return (_jsxs(TableRow, { className: "align-top cursor-pointer", onClick: () => onSelectOrder?.(o), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(o.id), onCheckedChange: () => toggle(o.id) }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "font-medium text-foreground", children: ["\u20AC ", o.revenue.toFixed(2)] }), o.orderNumber && (_jsx("div", { className: "text-xs text-muted-foreground", children: o.orderNumber }))] }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Package, { className: "h-4 w-4 text-primary" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: ordered.time })] })] }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.karCount }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.fustCount }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: o.customer.name }), o.isLocal && (_jsx(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: "Lokaal" })), o.isReservation && (_jsx(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: "Reservering" }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [o.customer.postalCode, o.customer.city].filter(Boolean).join(" ") })] }), _jsx(TableCell, { className: "text-sm text-foreground", children: formatDateLong(o.deliveryAt) }), _jsx(TableCell, { children: _jsx(StatusTag, { status: o.status, rawOrder: o.raw?.order }) }), _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: !o.isLocal, onClick: () => o.isLocal && onEditOrder?.(o), title: o.isLocal ? undefined : "FO-orders kunnen niet bewerkt worden.", children: "Bewerken" }), _jsx(DropdownMenuItem, { onClick: () => onSelectOrder?.(o), children: "Details bekijken" }), _jsx(DropdownMenuItem, { onClick: () => onConfirmOrder?.(o), children: "Bevestigen" }), o.isLocal ? (_jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onClick: () => onDeleteOrder?.(o), children: "Verwijderen" })) : (_jsx(DropdownMenuItem, { disabled: true, title: "FO-orders kunnen niet verwijderd worden.", children: "Verwijderen (FO)" }))] })] }) })] }, o.id));
|
|
61
61
|
})] })] }) }));
|
|
62
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerkoopOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/VerkoopOrdersPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VerkoopOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/VerkoopOrdersPage.tsx"],"names":[],"mappings":"AAkEA,wBAAgB,iBAAiB,4CAyahC"}
|