@flowselections/floriday-verkoop-module 1.0.77 → 1.0.79

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.
Files changed (68) hide show
  1. package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -1
  2. package/dist-lib/components/verkoop/CreateOrderPage.js +33 -8
  3. package/dist-lib/components/verkoop/EditLocalOrderDialog.d.ts.map +1 -1
  4. package/dist-lib/components/verkoop/EditLocalOrderDialog.js +1 -1
  5. package/dist-lib/components/verkoop/FloridayStageLine.d.ts +11 -0
  6. package/dist-lib/components/verkoop/FloridayStageLine.d.ts.map +1 -0
  7. package/dist-lib/components/verkoop/FloridayStageLine.js +17 -0
  8. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts +1 -1
  9. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts.map +1 -1
  10. package/dist-lib/components/verkoop/PlanCoverageBadge.js +5 -2
  11. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  12. package/dist-lib/components/verkoop/SalesOrderDetailView.js +33 -5
  13. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  14. package/dist-lib/components/verkoop/SalesOrdersTable.js +4 -8
  15. package/dist-lib/components/verkoop/VerkoopOrdersPage.js +1 -1
  16. package/dist-lib/integrations/supabase/types.d.ts +1158 -0
  17. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  18. package/dist-lib/lib/belading.server.d.ts +0 -11
  19. package/dist-lib/lib/belading.server.d.ts.map +1 -1
  20. package/dist-lib/lib/belading.server.js +4 -41
  21. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
  22. package/dist-lib/lib/cart-replan.functions.js +3 -22
  23. package/dist-lib/lib/central-secrets.server.d.ts +5 -0
  24. package/dist-lib/lib/central-secrets.server.d.ts.map +1 -0
  25. package/dist-lib/lib/central-secrets.server.js +65 -0
  26. package/dist-lib/lib/create-order.functions.d.ts +15 -0
  27. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  28. package/dist-lib/lib/create-order.functions.js +28 -13
  29. package/dist-lib/lib/engine-block-alerts.d.ts +22 -0
  30. package/dist-lib/lib/engine-block-alerts.d.ts.map +1 -0
  31. package/dist-lib/lib/engine-block-alerts.js +43 -0
  32. package/dist-lib/lib/engine-block-alerts.server.d.ts +7 -0
  33. package/dist-lib/lib/engine-block-alerts.server.d.ts.map +1 -0
  34. package/dist-lib/lib/engine-block-alerts.server.js +75 -0
  35. package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -1
  36. package/dist-lib/lib/floriday-mirror.functions.js +21 -36
  37. package/dist-lib/lib/floriday-status.d.ts +40 -0
  38. package/dist-lib/lib/floriday-status.d.ts.map +1 -0
  39. package/dist-lib/lib/floriday-status.js +80 -0
  40. package/dist-lib/lib/floriday-status.server.d.ts +7 -0
  41. package/dist-lib/lib/floriday-status.server.d.ts.map +1 -0
  42. package/dist-lib/lib/floriday-status.server.js +74 -0
  43. package/dist-lib/lib/load-carriers.server.d.ts +1 -1
  44. package/dist-lib/lib/load-carriers.server.d.ts.map +1 -1
  45. package/dist-lib/lib/load-carriers.server.js +3 -6
  46. package/dist-lib/lib/logistics-engine.server.d.ts.map +1 -1
  47. package/dist-lib/lib/logistics-engine.server.js +2 -22
  48. package/dist-lib/lib/order-block-mail.server.d.ts.map +1 -1
  49. package/dist-lib/lib/order-block-mail.server.js +31 -15
  50. package/dist-lib/lib/order-cancel.server.d.ts +9 -0
  51. package/dist-lib/lib/order-cancel.server.d.ts.map +1 -1
  52. package/dist-lib/lib/order-cancel.server.js +90 -0
  53. package/dist-lib/lib/plan-coverage.check.d.ts +2 -0
  54. package/dist-lib/lib/plan-coverage.check.d.ts.map +1 -0
  55. package/dist-lib/lib/plan-coverage.check.js +17 -0
  56. package/dist-lib/lib/plan-coverage.d.ts +12 -0
  57. package/dist-lib/lib/plan-coverage.d.ts.map +1 -1
  58. package/dist-lib/lib/plan-coverage.js +27 -1
  59. package/dist-lib/lib/plan-coverage.server.d.ts.map +1 -1
  60. package/dist-lib/lib/plan-coverage.server.js +20 -13
  61. package/dist-lib/lib/salesorders-list.server.d.ts.map +1 -1
  62. package/dist-lib/lib/salesorders-list.server.js +54 -0
  63. package/dist-lib/lib/salesorders-mapping.d.ts +11 -0
  64. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  65. package/dist-lib/lib/salesorders.functions.d.ts +1 -5
  66. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  67. package/dist-lib/lib/salesorders.functions.js +26 -2
  68. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AAqFA,wBAAgB,eAAe,gCAmxB9B"}
1
+ {"version":3,"file":"CreateOrderPage.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/CreateOrderPage.tsx"],"names":[],"mappings":"AAqFA,wBAAgB,eAAe,gCAkzB9B"}
@@ -12,10 +12,9 @@ import { ArrowLeft, Plus, Trash2 } from "lucide-react";
12
12
  import { useServerFn } from "@tanstack/react-start";
13
13
  import { SearchableSelect } from "./SearchableSelect";
14
14
  import { computeEarliestDelivery } from "../../lib/carrier-availability.js";
15
- import { listCustomersForCreateOrder, ensureCustomerFromTwinfield, listProductsForCreateOrder, listDeliveryLocationsForCustomerCO, listPickupLocationsCO, listCarriersForCreateOrder, getOrderPickDaysCO, listBeladingOptionsForProducts, createManualOrder, } from "../../lib/create-order.functions.js";
15
+ import { listCustomersForCreateOrder, ensureCustomerFromTwinfield, listProductsForCreateOrder, listDeliveryLocationsForCustomerCO, listPickupLocationsCO, listCarriersForCreateOrder, getOrderPickDaysCO, listBeladingOptionsForProducts, createManualOrder, getEffectivePrices, } from "../../lib/create-order.functions.js";
16
16
  import { checkOrderStockAllowed } from "../../lib/logistics-stock.functions.js";
17
17
  import { useAllowedLoadCarriers } from "../../lib/useAllowedLoadCarriers.js";
18
- import { DISABLED_LOAD_CARRIER_MESSAGE } from "../../lib/load-carriers.js";
19
18
  const beladingKey = (b) => `${b.plants_per_crate}x${b.crates_per_layer}x${b.layers_per_cart}`;
20
19
  const beladingLabel = (b) => `${b.plants_per_crate} planten/fust · ${b.crates_per_layer} fusten/laag · ${b.layers_per_cart} lagen`;
21
20
  /** "Eurokrat · Deense container" — type fust en type kar bij deze belading. */
@@ -42,6 +41,7 @@ export function CreateOrderPage() {
42
41
  const qc = useQueryClient();
43
42
  const fetchCustomers = useServerFn(listCustomersForCreateOrder);
44
43
  const fetchProducts = useServerFn(listProductsForCreateOrder);
44
+ const fetchEffectivePrices = useServerFn(getEffectivePrices);
45
45
  const fetchDeliveryLocations = useServerFn(listDeliveryLocationsForCustomerCO);
46
46
  const fetchPickupLocations = useServerFn(listPickupLocationsCO);
47
47
  const fetchCarriers = useServerFn(listCarriersForCreateOrder);
@@ -266,9 +266,6 @@ export function CreateOrderPage() {
266
266
  throw new Error("Selecteer een vervoerder");
267
267
  if (!isReservation && !deliveryDate)
268
268
  throw new Error("Selecteer een leverdatum");
269
- if (loadCarrierType && !loadCarriersEngine.allowed.includes(loadCarrierType)) {
270
- throw new Error(DISABLED_LOAD_CARRIER_MESSAGE);
271
- }
272
269
  const validLines = lines.filter((l) => l.product_id && (l.quantity ?? 0) > 0);
273
270
  if (validLines.length === 0)
274
271
  throw new Error("Voeg minimaal één product toe");
@@ -435,10 +432,38 @@ export function CreateOrderPage() {
435
432
  unit: next[idx].unit ?? p?.unit ?? "stuks",
436
433
  quantity: normalizedQ,
437
434
  belading: b,
438
- unit_price: next[idx].unit_price ?? (p?.sale_price != null ? Number(p.sale_price) : null),
435
+ unit_price: next[idx].unit_price ?? (p?.sale_price != null && Number(p.sale_price) > 0 ? Number(p.sale_price) : null),
439
436
  };
440
437
  }
441
438
  setLines(next);
439
+ // Prijs uit prijsgroep/klantafspraak/artikel, als die bestaat.
440
+ if (v && customerId && !String(customerId).startsWith("twinfield:")) {
441
+ const lineIdx = idx;
442
+ const hadPrice = next[idx].unit_price;
443
+ fetchEffectivePrices({
444
+ data: {
445
+ customerId,
446
+ onDate: deliveryDate || undefined,
447
+ lines: [{ productId: v, quantity: Number(next[idx].quantity ?? 0) || undefined }],
448
+ },
449
+ })
450
+ .then((res) => {
451
+ const hit = res?.[v];
452
+ if (!hit)
453
+ return;
454
+ setLines((cur) => {
455
+ const copy = [...cur];
456
+ const ln = copy[lineIdx];
457
+ if (!ln || ln.product_id !== v)
458
+ return cur;
459
+ if (ln.unit_price != null && ln.unit_price !== hadPrice)
460
+ return cur;
461
+ copy[lineIdx] = { ...ln, unit_price: hit.price };
462
+ return copy;
463
+ });
464
+ })
465
+ .catch(() => undefined);
466
+ }
442
467
  } }), outOfStock && (_jsx("div", { className: "mt-1 text-xs text-amber-600", children: "Let op: dit product staat momenteel niet op voorraad." })), line.product_id && shortageByProduct.has(line.product_id) && (_jsx("div", { className: `mt-1 text-xs ${stockBlocked ? "text-destructive" : "text-amber-600"}`, children: (() => {
443
468
  const s = shortageByProduct.get(line.product_id);
444
469
  return `${s.product}: besteld ${s.wanted}, beschikbaar ${s.available}, tekort ${s.missing}`;
@@ -483,8 +508,8 @@ export function CreateOrderPage() {
483
508
  const v = e.target.value === "" ? null : Number(e.target.value);
484
509
  next[idx] = { ...next[idx], unit_price: v };
485
510
  setLines(next);
486
- }, placeholder: "\u20AC prijs" }), _jsx(Button, { variant: "ghost", size: "icon", className: "col-span-1", onClick: () => setLines(lines.filter((_, i) => i !== idx)), "aria-label": "Regel verwijderen", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }, idx));
487
- }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setLines([...lines, { product_id: null, product_name: "", quantity: null, unit: "stuks", unit_price: null, belading: null }]), children: [_jsx(Plus, { className: "h-3 w-3 mr-1" }), " Regel toevoegen"] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { children: "Opmerkingen" }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Optionele notities bij deze bestelling", rows: 3 })] }), stockCheck && stockCheck.shortages.length > 0 && (_jsxs("div", { className: `rounded-md border p-3 text-sm ${stockBlocked
511
+ }, placeholder: "\u20AC prijs", "aria-invalid": !!line.product_id && !(Number(line.unit_price) > 0), title: !!line.product_id && !(Number(line.unit_price) > 0) ? "Geen prijs" : undefined }), _jsx(Button, { variant: "ghost", size: "icon", className: "col-span-1", onClick: () => setLines(lines.filter((_, i) => i !== idx)), "aria-label": "Regel verwijderen", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }, idx));
512
+ }), lines.some((l) => l.product_id && !(Number(l.unit_price) > 0)) && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: ["Geen prijs: ", lines.filter((l) => l.product_id && !(Number(l.unit_price) > 0)).length, " regel(s) zonder prijs. Er is geen prijs gevonden in prijsgroep of artikel; vul de prijs in."] })), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setLines([...lines, { product_id: null, product_name: "", quantity: null, unit: "stuks", unit_price: null, belading: null }]), children: [_jsx(Plus, { className: "h-3 w-3 mr-1" }), " Regel toevoegen"] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { children: "Opmerkingen" }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Optionele notities bij deze bestelling", rows: 3 })] }), stockCheck && stockCheck.shortages.length > 0 && (_jsxs("div", { className: `rounded-md border p-3 text-sm ${stockBlocked
488
513
  ? "border-destructive/40 bg-destructive/5 text-destructive"
489
514
  : "border-amber-500/40 bg-amber-500/5 text-amber-700"}`, children: [_jsx("div", { className: "font-medium", children: stockBlocked
490
515
  ? "Bestelling geblokkeerd — onvoldoende voorraad"
@@ -1 +1 @@
1
- {"version":3,"file":"EditLocalOrderDialog.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/EditLocalOrderDialog.tsx"],"names":[],"mappings":"AA6CA,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,sCAkiBA"}
1
+ {"version":3,"file":"EditLocalOrderDialog.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/EditLocalOrderDialog.tsx"],"names":[],"mappings":"AA6CA,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,sCAuiBA"}
@@ -246,7 +246,7 @@ export function EditLocalOrderDialog({ orderId, open, onOpenChange, }) {
246
246
  })() }))] }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { type: "number", min: 0, step: ppc ?? 1, value: it.quantity, disabled: removed, onChange: (e) => setPlants(idx, Number(e.target.value)) }) }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { type: "number", min: 0, step: 1, value: ppc === null ? "" : fusten, disabled: removed || ppc === null, onChange: (e) => setFusten(idx, Number(e.target.value)) }) }), _jsx("div", { className: "col-span-1 flex justify-end", children: canEditProducts && (_jsx(Button, { variant: "ghost", size: "sm", title: removed ? "Verwijderen ongedaan maken" : "Regel verwijderen", onClick: () => setRemovedIds((prev) => prev.includes(it.id)
247
247
  ? prev.filter((x) => x !== it.id)
248
248
  : [...prev, it.id]), children: _jsx(Trash2, { className: "h-4 w-4" }) })) })] }, it.id));
249
- }), newItems.map((n, idx) => {
249
+ }), newItems.some((n) => !(Number(n.unitPrice) > 0)) && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: ["Geen prijs: ", newItems.filter((n) => !(Number(n.unitPrice) > 0)).length, " nieuwe regel(s) zonder prijs in artikel of prijsgroep."] })), newItems.map((n, idx) => {
250
250
  const ppc = Math.max(1, n.plantsPerCrate);
251
251
  const fusten = Math.ceil(n.quantity / ppc);
252
252
  const setNewQty = (plants) => setNewItems((prev) => prev.map((p, i) => i === idx
@@ -0,0 +1,11 @@
1
+ import { type FloridayStatusSummary } from "../../lib/floriday-status.js";
2
+ import type { OrderStage } from "../../lib/order-status.js";
3
+ /** Extra regel "Floriday: …" met een melding als de stand afwijkt. Alleen weergave. */
4
+ export declare function FloridayStageLine({ status, stage, }: {
5
+ status: FloridayStatusSummary | null | undefined;
6
+ stage: OrderStage | undefined;
7
+ }): import("react").JSX.Element | null;
8
+ export declare function MissingPriceBadge({ show }: {
9
+ show: boolean | undefined;
10
+ }): import("react").JSX.Element | null;
11
+ //# sourceMappingURL=FloridayStageLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloridayStageLine.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/FloridayStageLine.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4C,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC7G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;CAC/B,sCAiBA;AAED,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,sCAOxE"}
@@ -0,0 +1,17 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { AlertTriangle } from "lucide-react";
3
+ import { Badge } from "@flowselections/core";
4
+ import { deviatesFromFloriday, floridayStageLabel } from "../../lib/floriday-status.js";
5
+ /** Extra regel "Floriday: …" met een melding als de stand afwijkt. Alleen weergave. */
6
+ export function FloridayStageLine({ status, stage, }) {
7
+ if (!status)
8
+ return null;
9
+ const unknown = status.stage === "onbekend";
10
+ const deviates = deviatesFromFloriday(status.stage, stage);
11
+ return (_jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1 text-xs text-muted-foreground", children: [_jsxs("span", { title: unknown && status.error ? `Niet opgehaald: ${status.error}` : undefined, children: ["Floriday: ", unknown ? "stand onbekend" : floridayStageLabel(status.stage)] }), deviates && (_jsxs(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: [_jsx(AlertTriangle, { className: "mr-1 h-3 w-3" }), "Wijkt af van Floriday"] }))] }));
12
+ }
13
+ export function MissingPriceBadge({ show }) {
14
+ if (!show)
15
+ return null;
16
+ return (_jsx(Badge, { variant: "outline", className: "border-destructive/40 text-destructive", children: "Geen prijs" }));
17
+ }
@@ -1,4 +1,4 @@
1
- import type { PlanCoverageSummary } from "../../lib/plan-coverage.js";
1
+ import { type PlanCoverageSummary } from "../../lib/plan-coverage.js";
2
2
  export declare function PlanCoverageBadge({ coverage, showReason, }: {
3
3
  coverage: PlanCoverageSummary | null | undefined;
4
4
  showReason?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"PlanCoverageBadge.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/PlanCoverageBadge.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,UAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,sCAkCA"}
1
+ {"version":3,"file":"PlanCoverageBadge.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/PlanCoverageBadge.tsx"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGnF,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,UAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,sCAoCA"}
@@ -1,13 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { AlertTriangle } from "lucide-react";
3
+ import { coverageDetailText } from "../../lib/plan-coverage.js";
3
4
  // Indelingsstatus zoals de Logistiek Engine die levert. Alleen weergave.
4
5
  export function PlanCoverageBadge({ coverage, showReason = true, }) {
5
6
  if (!coverage)
6
7
  return null;
7
8
  const { state, label, progressPct, reason, shared } = coverage;
9
+ const detail = coverageDetailText(coverage);
10
+ const tip = reason ? `${reason}\n${detail}` : detail;
8
11
  const base = "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-medium";
9
12
  if (state === "geen_indeling") {
10
- return (_jsxs("div", { className: "mt-1 min-w-0", children: [_jsxs("span", { className: `${base} border-destructive/40 bg-destructive/10 text-destructive`, title: reason ?? undefined, children: [_jsx(AlertTriangle, { className: "h-3 w-3 shrink-0" }), label] }), showReason && reason && _jsx("div", { className: "mt-0.5 text-xs text-destructive", children: reason })] }));
13
+ return (_jsxs("div", { className: "mt-1 min-w-0", children: [_jsxs("span", { className: `${base} border-destructive/40 bg-destructive/10 text-destructive`, title: tip, children: [_jsx(AlertTriangle, { className: "h-3 w-3 shrink-0" }), label] }), showReason && reason && _jsx("div", { className: "mt-0.5 text-xs text-destructive", children: reason })] }));
11
14
  }
12
15
  const tone = state === "deels"
13
16
  ? "border-primary/40 bg-primary/10 text-foreground"
@@ -19,5 +22,5 @@ export function PlanCoverageBadge({ coverage, showReason = true, }) {
19
22
  : state === "ingedeeld" && shared
20
23
  ? `${label} · gedeeld met buffer`
21
24
  : label;
22
- return (_jsx("div", { className: "mt-1", children: _jsx("span", { className: `${base} ${tone}`, title: reason ?? undefined, children: text }) }));
25
+ return (_jsx("div", { className: "mt-1", children: _jsx("span", { className: `${base} ${tone}`, title: tip, children: text }) }));
23
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA2JnE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,EACd,eAAuB,GACxB,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,+BA8YA"}
1
+ {"version":3,"file":"SalesOrderDetailView.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrderDetailView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA4JnE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,EACd,eAAuB,GACxB,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,+BA6cA"}
@@ -13,6 +13,7 @@ import { OrderControlStatusCard } from "./OrderControlStatusCard";
13
13
  import { OrderCarrierPicker } from "./OrderCarrierPicker";
14
14
  import { OrderPickupMomentPicker } from "./OrderPickupMomentPicker";
15
15
  import { PlanCoverageBadge } from "./PlanCoverageBadge";
16
+ import { FloridayStageLine } from "./FloridayStageLine";
16
17
  function AddressCard({ icon, lines, extra, }) {
17
18
  return (_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: icon }), _jsxs("div", { className: "text-sm", children: [lines.length > 0 ? lines.map((l, i) => _jsx("div", { children: l }, i)) : _jsx("div", { children: "\u2014" }), extra && _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: extra })] })] }));
18
19
  }
@@ -145,8 +146,10 @@ export function SalesOrderDetailView({ order, sellerFallback, hideKarindeling =
145
146
  if (lcShort)
146
147
  beladingParts.push(lcShort);
147
148
  const belading = beladingParts.length > 0 ? beladingParts.join(" - ") : "—";
148
- const klantReferentie = pickStr(o.customerOrderId) ?? "—";
149
+ const fsEntry = order.floridayStatus?.entries?.[0] ?? null;
150
+ const klantReferentie = pickStr(o.customerOrderId) ?? pickStr(fsEntry?.customerOrderId) ?? "—";
149
151
  const floridayRef = pickStr(o.salesChannelOrderId) ??
152
+ pickStr(fsEntry?.salesChannelOrderId) ??
150
153
  pickStr(o.batchReference) ??
151
154
  pickStr(o.salesOrderId)?.slice(0, 16) ??
152
155
  "—";
@@ -199,11 +202,34 @@ export function SalesOrderDetailView({ order, sellerFallback, hideKarindeling =
199
202
  const map = { NL: "Nederland", BE: "België", DE: "Duitsland", FR: "Frankrijk", ES: "Spanje", IT: "Italië", GB: "Verenigd Koninkrijk", PL: "Polen", DK: "Denemarken" };
200
203
  return map[addr.country.toUpperCase()] ?? addr.country;
201
204
  })();
202
- const incoterm = pickStr(o.delivery?.incoterm) ?? pickStr(o.incoterm) ?? "—";
205
+ // Ordervelden uit het Floriday-statusoverzicht (alleen weergave).
206
+ const fs = order.floridayStatus ?? null;
207
+ const fe = fs?.entries?.[0] ?? null;
208
+ const incoterm = pickStr(fe?.incoterm) ??
209
+ pickStr(o.delivery?.incoterm) ??
210
+ pickStr(o.incoterm) ??
211
+ (fe ? "niet opgegeven" : "—");
203
212
  const productUnit = Number(o.calculatedFields?.totalPricePerPiece?.value ?? o.pricePerPiece?.value ?? order.quantity.unitPrice) || 0;
204
213
  const purchaseUnit = Number(o.pricePerPiece?.value ?? productUnit) || 0;
205
214
  const transportPerPiece = Number(o.deliveryPricePerPiece ?? Math.max(0, productUnit - purchaseUnit)) || 0;
206
- const totalAmount = Number(o.calculatedFields?.orderAmount?.value ?? order.revenue) || 0;
215
+ const priceLines = (order.priceLines ?? []).filter((l) => l.pieces > 0);
216
+ const linesTotal = priceLines.reduce((sum, l) => sum + l.pieces * l.unitPrice, 0);
217
+ const totalAmount = priceLines.length > 0 && linesTotal > 0
218
+ ? linesTotal
219
+ : Number(o.calculatedFields?.orderAmount?.value ?? order.revenue) || 0;
220
+ // Totaalregel opgebouwd uit de orderregels (nooit uit afgeronde fusten).
221
+ const totalBreakdown = (() => {
222
+ if (priceLines.length === 0) {
223
+ return numberOfPieces > 0 ? `${numberOfPieces.toLocaleString("nl-NL")} stuks × ${eurFlex.format(productUnit)}` : "";
224
+ }
225
+ const byPrice = new Map();
226
+ for (const l of priceLines)
227
+ byPrice.set(l.unitPrice, (byPrice.get(l.unitPrice) ?? 0) + l.pieces);
228
+ return Array.from(byPrice.entries())
229
+ .map(([price, pcs]) => `${pcs.toLocaleString("nl-NL")} stuks × ${eurFlex.format(price)}`)
230
+ .join(" + ");
231
+ })();
232
+ const linesWithoutPrice = priceLines.filter((l) => !(l.unitPrice > 0)).length;
207
233
  let oldProductPrice = null;
208
234
  const mutations = Array.isArray(o.mutations) ? o.mutations : [];
209
235
  const lastCorrection = [...mutations]
@@ -226,7 +252,9 @@ export function SalesOrderDetailView({ order, sellerFallback, hideKarindeling =
226
252
  const bestellingLabel = orderStageLabel(order.stage ?? (order.status.isCancelled ? "cancelled" : "incoming"));
227
253
  return (_jsxs("div", { className: "space-y-6", children: [order.needsManualReview ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Handmatige beoordeling nodig" }), _jsxs("div", { className: "text-muted-foreground", children: [order.needsManualReview.reason, order.needsManualReview.at
228
254
  ? ` (geconstateerd op ${new Date(order.needsManualReview.at).toLocaleString("nl-NL")})`
229
- : ""] })] })) : null, order.mixedDeliveryDates ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Bestellingen met verschillende leverdatums" }), _jsx("div", { className: "text-muted-foreground", children: "Deze order bestaat uit Floriday-bestellingen met verschillende leverdatums. De vroegste leverdatum is aangehouden." })] })) : null, (order.unlinkedProducts?.length ?? 0) > 0 ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Floriday-artikel niet gekoppeld aan product" }), _jsx("ul", { className: "mt-1 space-y-0.5 text-muted-foreground", children: order.unlinkedProducts.map((u, i) => (_jsxs("li", { children: [u.name, " \u2014 trade-item-id ", u.tradeItemId ?? "onbekend"] }, i))) }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Koppel dit trade-item aan een product; de volgende synchronisatie neemt het dan over." })] })) : null, _jsxs("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [_jsx("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted", children: order.imageUrl ? (_jsx("img", { src: order.imageUrl, alt: "", className: "h-full w-full object-cover" })) : (_jsx(ImageIcon, { className: "h-6 w-6 text-muted-foreground" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "truncate text-base font-semibold text-foreground", children: [order.productName, o.tradeItemVersion ? (_jsxs("span", { className: "ml-2 text-xs font-normal text-muted-foreground", children: ["\u00B7 v", o.tradeItemVersion] })) : null] }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: order.orderNumber || order.sku || "—" })] })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-[1fr_360px]", children: [_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsx(SectionTitle, { children: "Verkooporder" }), _jsx(Row, { label: "Ordernummer", children: order.orderNumber || "—" }), _jsx(Row, { label: "Handelsvorm", children: tradingType }), _jsx(Row, { label: "Bestelmoment", children: fmtDateTime(order.orderedAt) }), _jsx(Row, { label: "Aantal", children: _jsxs("div", { className: "flex flex-wrap gap-4", children: [_jsxs("div", { children: [formatLoadUnits(order.fustCount, order.crateTypeName), " fusten"] }), _jsxs("div", { children: [formatLoadUnits(order.karCount, order.cartTypeName), " karren", order.karShared ? " (gedeeld met buffer)" : "", _jsx(PlanCoverageBadge, { coverage: order.planCoverage })] })] }) }), _jsx(Row, { label: "Belading", children: belading }), _jsx(Row, { label: "Klant referentie", children: klantReferentie }), _jsx(Row, { label: "Floriday-referentie", children: floridayRef }), _jsx(Row, { label: "Verkoopkanaal", children: verkoopkanaal }), _jsx(Row, { label: "Financi\u00EBle afhandeling", children: financial }), _jsx(Row, { label: "Verkoper", children: sellerName ? (_jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx("span", { className: "inline-flex h-6 w-6 items-center justify-center rounded-full bg-muted text-[10px] font-semibold text-muted-foreground", children: initials(sellerName) }), sellerName] })) : ("—") })] }), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Levering" }), _jsx(Row, { label: "Afleverdatum", children: fmtDateTime(order.deliveryAt) }), _jsx(Row, { label: "Incoterm", children: incoterm }), _jsx(Row, { label: "Afleveradres", children: _jsx(AddressCard, { icon: _jsx(MapPin, { className: "h-5 w-5" }), lines: resolvedAddresses?.delivery
255
+ : ""] })] })) : null, order.mixedDeliveryDates ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Bestellingen met verschillende leverdatums" }), _jsx("div", { className: "text-muted-foreground", children: "Deze order bestaat uit Floriday-bestellingen met verschillende leverdatums. De vroegste leverdatum is aangehouden." })] })) : null, (order.unlinkedProducts?.length ?? 0) > 0 ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-foreground", children: [_jsx("div", { className: "font-semibold", children: "Floriday-artikel niet gekoppeld aan product" }), _jsx("ul", { className: "mt-1 space-y-0.5 text-muted-foreground", children: order.unlinkedProducts.map((u, i) => (_jsxs("li", { children: [u.name, " \u2014 trade-item-id ", u.tradeItemId ?? "onbekend"] }, i))) }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Koppel dit trade-item aan een product; de volgende synchronisatie neemt het dan over." })] })) : null, _jsxs("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [_jsx("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted", children: order.imageUrl ? (_jsx("img", { src: order.imageUrl, alt: "", className: "h-full w-full object-cover" })) : (_jsx(ImageIcon, { className: "h-6 w-6 text-muted-foreground" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "truncate text-base font-semibold text-foreground", children: [order.productName, o.tradeItemVersion ? (_jsxs("span", { className: "ml-2 text-xs font-normal text-muted-foreground", children: ["\u00B7 v", o.tradeItemVersion] })) : null] }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: order.orderNumber || order.sku || "—" })] })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-[1fr_360px]", children: [_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsx(SectionTitle, { children: "Verkooporder" }), _jsx(Row, { label: "Ordernummer", children: order.orderNumber || "—" }), _jsx(Row, { label: "Handelsvorm", children: tradingType }), _jsx(Row, { label: "Bestelmoment", children: fmtDateTime(order.orderedAt) }), _jsx(Row, { label: "Aantal", children: _jsxs("div", { className: "flex flex-wrap gap-4", children: [_jsxs("div", { children: [formatLoadUnits(order.fustCount, order.crateTypeName), " fusten"] }), _jsxs("div", { children: [formatLoadUnits(order.karCount, order.cartTypeName), " karren", order.karShared ? " (gedeeld met buffer)" : "", _jsx(PlanCoverageBadge, { coverage: order.planCoverage })] })] }) }), _jsx(Row, { label: "Belading", children: belading }), _jsx(Row, { label: "Klant referentie", children: klantReferentie }), _jsx(Row, { label: "Floriday-referentie", children: floridayRef }), _jsx(Row, { label: "Verkoopkanaal", children: verkoopkanaal }), _jsx(Row, { label: "Financi\u00EBle afhandeling", children: financial }), _jsx(Row, { label: "Verkoper", children: sellerName ? (_jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx("span", { className: "inline-flex h-6 w-6 items-center justify-center rounded-full bg-muted text-[10px] font-semibold text-muted-foreground", children: initials(sellerName) }), sellerName] })) : ("—") })] }), fs && (_jsxs("div", { children: [_jsx(SectionTitle, { children: "Floriday" }), _jsx(Row, { label: "Stand", children: _jsx(FloridayStageLine, { status: fs, stage: order.stage }) }), _jsxs(Row, { label: "Herkomst status", children: [order.statusOrigin === "floriday" ? "Floriday" : "ERP", order.statusChangedAt ? ` · ${fmtDateTime(order.statusChangedAt)}` : ""] }), fs.entries.map((e) => (_jsx(Row, { label: `Bestelling ${e.salesOrderId.slice(0, 8)}`, children: _jsxs("div", { className: "space-y-0.5 text-sm", children: [_jsxs("div", { children: ["Floriday-status: ", e.salesOrderStatus ?? "—"] }), _jsxs("div", { children: ["Afleververzoeken: ", e.fulfillmentRequests.length, " \u00B7 Afhandelingen:", " ", e.fulfillmentOrders.length
256
+ ? e.fulfillmentOrders.map((f) => f.status ?? "?").join(", ")
257
+ : "geen"] }), _jsxs("div", { children: ["Verkoopkanaal: ", e.salesChannel ?? "—", " \u00B7 Handelsvorm: ", e.tradeInstrument ?? "—", " \u00B7 Incoterm: ", e.incoterm ?? "niet opgegeven"] }), _jsxs("div", { children: ["Klantreferentie: ", e.customerOrderId ?? "—", " \u00B7 Floriday-referentie: ", e.salesChannelOrderId ?? "—"] }), _jsxs("div", { children: ["Koper: ", e.customerOrganizationId ?? "—", " \u00B7 GLN: ", e.customerGln ?? "—"] }), _jsxs("div", { className: "text-xs text-muted-foreground", children: ["Laatst gewijzigd: ", e.lastModifiedDateTime ? fmtDateTime(e.lastModifiedDateTime) : "—", " \u00B7 Ververst: ", e.cachedAt ? fmtDateTime(e.cachedAt) : "—"] })] }) }, e.salesOrderId)))] })), _jsxs("div", { children: [_jsx(SectionTitle, { children: "Levering" }), _jsx(Row, { label: "Afleverdatum", children: fmtDateTime(order.deliveryAt) }), _jsx(Row, { label: "Incoterm", children: incoterm }), _jsx(Row, { label: "Afleveradres", children: _jsx(AddressCard, { icon: _jsx(MapPin, { className: "h-5 w-5" }), lines: resolvedAddresses?.delivery
230
258
  ? [
231
259
  resolvedAddresses.delivery.name,
232
260
  resolvedAddresses.delivery.line,
@@ -248,5 +276,5 @@ export function SalesOrderDetailView({ order, sellerFallback, hideKarindeling =
248
276
  .join(" "),
249
277
  resolvedAddresses.pickup.country,
250
278
  ].filter((v) => !!v && v.trim().length > 0)
251
- : [], extra: resolvedAddresses?.pickup?.gln ?? null }) }), _jsx(Row, { label: "Vervoerder", children: _jsx(OrderCarrierPicker, { orderId: String(order.id), locked: !!order.isReservation }) }), _jsx(Row, { label: "Ophaalmoment", children: _jsx(OrderPickupMomentPicker, { orderId: String(order.id) }) })] }), _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" }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${orderStageBadgeClass(order.stage ?? "incoming")}`, children: bestellingLabel })] }), order.floridayFulfilled && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Floriday" }), _jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground", title: "Administratief doorgegeven aan Floriday. Dit bepaalt de orderstatus niet.", children: "Doorgegeven aan Floriday" })] })), 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(OrderLinePackingCard, { orderId: String(order.id) }), _jsx(OrderShipmentsCard, { order: order }), !hideKarindeling && _jsx(OrderKarindelingCard, { order: order }), o?.salesOrderId ? (_jsxs(_Fragment, { children: [_jsx(OrderControlStatusCard, { floridayId: String(o.salesOrderId), isControlled: order.status.isControlled, controlledAt: order.status.controlledAt }), _jsx(OrderAfleverbrievenCard, { salesOrderId: String(o.salesOrderId), orderNumber: order.orderNumber ?? undefined })] })) : null] }));
279
+ : [], extra: resolvedAddresses?.pickup?.gln ?? null }) }), _jsx(Row, { label: "Vervoerder", children: _jsx(OrderCarrierPicker, { orderId: String(order.id), locked: !!order.isReservation }) }), _jsx(Row, { label: "Ophaalmoment", children: _jsx(OrderPickupMomentPicker, { orderId: String(order.id) }) })] }), _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: [_jsx("span", { className: "mr-2 text-xs font-normal text-muted-foreground", children: totalBreakdown ? `(${totalBreakdown})` : null }), eurFlex.format(totalAmount)] })] }), (order.missingPrice || (linesWithoutPrice > 0 && !fs)) && (_jsxs("div", { className: "mt-2 rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1 text-xs text-destructive", children: ["Geen prijs: ", linesWithoutPrice || "een of meer", " regel(s) zonder prijs. Vul de prijs in voordat de order wordt bevestigd."] }))] })] }), _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" }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${orderStageBadgeClass(order.stage ?? "incoming")}`, children: bestellingLabel })] }), order.floridayFulfilled && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-muted-foreground", children: "Floriday" }), _jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground", title: "Administratief doorgegeven aan Floriday. Dit bepaalt de orderstatus niet.", children: "Doorgegeven aan Floriday" })] })), 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(OrderLinePackingCard, { orderId: String(order.id) }), _jsx(OrderShipmentsCard, { order: order }), !hideKarindeling && _jsx(OrderKarindelingCard, { order: order }), o?.salesOrderId ? (_jsxs(_Fragment, { children: [_jsx(OrderControlStatusCard, { floridayId: String(o.salesOrderId), isControlled: order.status.isControlled, controlledAt: order.status.controlledAt }), _jsx(OrderAfleverbrievenCard, { salesOrderId: String(o.salesOrderId), orderNumber: order.orderNumber ?? undefined })] })) : null] }));
252
280
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAuBjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAwGnE,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAG1D;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7C,qBA+SA"}
1
+ {"version":3,"file":"SalesOrdersTable.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SalesOrdersTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAsBjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAyGnE,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAG1D;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7C,qBAmSA"}
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useMemo, useState } from "react";
3
3
  import { Badge, Checkbox, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
4
4
  import { formatLoadUnits } from "../../lib/load-carrier-labels.js";
5
- import { useAllowedLoadCarriers } from "../../lib/useAllowedLoadCarriers.js";
6
5
  import { orderStageBadgeClass, orderStageLabel } from "../../lib/order-status.js";
7
6
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@flowselections/core";
8
7
  import { MoreVertical, AlertTriangle, ArrowDown } from "lucide-react";
9
8
  import { PlanCoverageBadge } from "./PlanCoverageBadge";
9
+ import { FloridayStageLine, MissingPriceBadge } from "./FloridayStageLine";
10
10
  function formatDateShort(iso) {
11
11
  if (!iso)
12
12
  return { date: "—", time: "" };
@@ -72,7 +72,6 @@ export function salesOrderRowId(row) {
72
72
  export function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder, onEditOrder, onFulfillOrder, fulfillingId, selectedIds, onSelectionChange, }) {
73
73
  const [internalSelected, setInternalSelected] = useState([]);
74
74
  const selected = useMemo(() => new Set(selectedIds ?? internalSelected), [selectedIds, internalSelected]);
75
- const allowedCarrierCodes = useAllowedLoadCarriers().allowed;
76
75
  const rowIds = useMemo(() => orders.map(salesOrderRowId), [orders]);
77
76
  const allChecked = rowIds.length > 0 && rowIds.every((id) => selected.has(id));
78
77
  const someChecked = !allChecked && rowIds.some((id) => selected.has(id));
@@ -100,17 +99,14 @@ export function SalesOrdersTable({ orders, loading, onSelectOrder, onDeleteOrder
100
99
  const ordered = formatDateShort(row.orderedAt);
101
100
  const delivery = formatDelivery(row.deliveryAt);
102
101
  const reserved = row.reservationCount ?? (row.isReservation ? 1 : 0);
103
- const carrierDisabled = allowedCarrierCodes.length > 0 &&
104
- !!row.loadCarrierType &&
105
- !allowedCarrierCodes.includes(row.loadCarrierType);
106
102
  const incomplete = row.incomplete ?? [];
107
- return (_jsxs(TableRow, { className: `align-top cursor-pointer ${isBuffer ? "bg-muted/20 border-l-2 border-primary/40" : ""}`, onClick: () => onSelectOrder?.(row), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(rowId), onCheckedChange: () => toggle(rowId) }) }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: delivery.date }), delivery.time && (_jsx("div", { className: "text-xs text-muted-foreground", children: delivery.time }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: formatPickDate(row.pickDate) }), row.pickupLabel && (_jsxs("div", { className: "text-xs text-muted-foreground", title: "Ophaalmoment van de vervoerder", children: ["Ophalen: ", row.pickupLabel] })), _jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: row.printedAt && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "Deze order is al uitgeprint.", children: "uitgeprint" })) })] }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: row.customer.name }), isBuffer && (_jsxs(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: ["Buffer \u00B7 ", bufferSize] })), reserved > 0 && (_jsx(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: reserved === bufferSize
103
+ return (_jsxs(TableRow, { className: `align-top cursor-pointer ${isBuffer ? "bg-muted/20 border-l-2 border-primary/40" : ""}`, onClick: () => onSelectOrder?.(row), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(rowId), onCheckedChange: () => toggle(rowId) }) }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: delivery.date }), delivery.time && (_jsx("div", { className: "text-xs text-muted-foreground", children: delivery.time }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: formatPickDate(row.pickDate) }), row.pickupLabel && (_jsxs("div", { className: "text-xs text-muted-foreground", title: "Ophaalmoment van de vervoerder", children: ["Ophalen: ", row.pickupLabel] })), _jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: row.printedAt && (_jsx(Badge, { variant: "outline", className: "border-transparent bg-muted text-[11px] font-normal text-muted-foreground", title: "Deze order is al uitgeprint.", children: "uitgeprint" })) })] }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: row.customer.name }), isBuffer && (_jsxs(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: ["Buffer \u00B7 ", bufferSize] })), _jsx(MissingPriceBadge, { show: row.missingPrice }), reserved > 0 && (_jsx(Badge, { variant: "outline", className: "border-amber-400/40 text-amber-600", children: reserved === bufferSize
108
104
  ? "Reservering"
109
- : `Reservering · ${reserved} van ${bufferSize}` })), carrierDisabled && (_jsx(Badge, { variant: "outline", className: "border-destructive/40 text-destructive", title: "Deze ladingdrager is uitgeschakeld in de Logistiek Engine.", children: "Ladingdrager uitgeschakeld" }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [row.customer.postalCode, row.customer.city].filter(Boolean).join(" ") }), incomplete.length > 0 && (_jsxs("div", { className: "mt-1 inline-flex items-center gap-1 text-xs text-amber-600", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), incomplete.join(" · ")] })), (row.unlinkedProducts?.length ?? 0) > 0 && (_jsxs("div", { className: "mt-1 flex items-start gap-1 text-xs text-destructive", title: row.unlinkedProducts
105
+ : `Reservering · ${reserved} van ${bufferSize}` }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [row.customer.postalCode, row.customer.city].filter(Boolean).join(" ") }), incomplete.length > 0 && (_jsxs("div", { className: "mt-1 inline-flex items-center gap-1 text-xs text-amber-600", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), incomplete.join(" · ")] })), (row.unlinkedProducts?.length ?? 0) > 0 && (_jsxs("div", { className: "mt-1 flex items-start gap-1 text-xs text-destructive", title: row.unlinkedProducts
110
106
  .map((u) => `${u.name} (trade-item ${u.tradeItemId ?? "onbekend"})`)
111
107
  .join("\n"), children: [_jsx(AlertTriangle, { className: "mt-0.5 h-3 w-3 shrink-0" }), _jsxs("span", { children: ["Floriday-artikel niet gekoppeld aan product:", " ", row.unlinkedProducts
112
108
  .map((u) => `${u.name} (trade-item ${u.tradeItemId ?? "onbekend"})`)
113
- .join(", ")] })] }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: row.engineCounts && row.karCount > 0 ? (_jsxs(_Fragment, { children: [formatLoadUnits(row.karCount, row.cartTypeName), row.karShared && (_jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "(gedeeld met buffer)" }))] })) : (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })) }), _jsx(PlanCoverageBadge, { coverage: row.planCoverage })] }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: formatLoadUnits(row.fustCount, row.crateTypeName) }) }), _jsx(TableCell, { className: "text-sm text-foreground", children: row.carrierName || _jsx("span", { className: "text-muted-foreground", children: "\u2014" }) }), _jsx(TableCell, { children: _jsx(StatusTag, { order: row }) }), showRevenue && (_jsxs(TableCell, { className: "font-medium text-foreground", children: ["\u20AC ", Math.round(row.revenue ?? 0).toLocaleString("nl-NL")] })), _jsxs(TableCell, { children: [_jsx("div", { className: "text-sm text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: isBuffer
109
+ .join(", ")] })] }))] }), _jsxs(TableCell, { children: [_jsx("div", { className: "font-medium text-foreground", children: row.engineCounts && row.karCount > 0 ? (_jsxs(_Fragment, { children: [formatLoadUnits(row.karCount, row.cartTypeName), row.karShared && (_jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "(gedeeld met buffer)" }))] })) : (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })) }), _jsx(PlanCoverageBadge, { coverage: row.planCoverage }), _jsx(FloridayStageLine, { status: row.floridayStatus, stage: row.stage })] }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: formatLoadUnits(row.fustCount, row.crateTypeName) }) }), _jsx(TableCell, { className: "text-sm text-foreground", children: row.carrierName || _jsx("span", { className: "text-muted-foreground", children: "\u2014" }) }), _jsx(TableCell, { children: _jsx(StatusTag, { order: row }) }), showRevenue && (_jsxs(TableCell, { className: "font-medium text-foreground", children: ["\u20AC ", Math.round(row.revenue ?? 0).toLocaleString("nl-NL")] })), _jsxs(TableCell, { children: [_jsx("div", { className: "text-sm text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: isBuffer
114
110
  ? `${bufferSize} orders`
115
111
  : row.orderNumber || ordered.time })] }), _jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { disabled: isBuffer || !row.isLocal, onClick: () => !isBuffer && row.isLocal && onEditOrder?.(row), title: isBuffer
116
112
  ? "Buffer-orders kunnen niet gebundeld bewerkt worden."
@@ -315,7 +315,7 @@ export function VerkoopOrdersPage() {
315
315
  (active
316
316
  ? "bg-primary text-primary-foreground"
317
317
  : "bg-muted text-muted-foreground"), children: count })] }, t.id));
318
- }) }) }), _jsxs("div", { className: "shrink-0 flex flex-wrap items-center justify-between gap-3", children: [_jsx(SalesOrdersFilters, { value: filters, onChange: setFilters }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: () => setFilterPanelOpen(true), "aria-label": "Filters", children: [_jsx(Filter, { className: "mr-2 h-4 w-4" }), "Filters", activeFilterCount > 0 && (_jsx("span", { className: "ml-2 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground", children: activeFilterCount }))] }), _jsx(Button, { variant: "outline", size: "icon", onClick: handleSync, disabled: syncing, "aria-label": "Synchroniseren", title: "Synchroniseren", children: _jsx(RefreshCw, { className: "h-4 w-4 " + (syncing ? "animate-spin" : "") }) }), _jsxs(Button, { variant: "outline", size: "sm", onClick: handleExport, children: [_jsx(Download, { className: "mr-2 h-4 w-4" }), " Exporteren"] }), _jsxs(Button, { size: "sm", onClick: () => navigate({ to: "/floriday-verkoop/verkooporders/nieuw" }), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Bestelling aanmaken"] })] })] }), _jsx("div", { className: "shrink-0", children: _jsx(AnalyticsCards, { totals: totals, loading: isLoading }) }), _jsx("div", { className: "shrink-0", children: _jsx(StockConsumptionAlertsBanner, {}) }), error && (_jsxs("div", { className: "shrink-0 flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-destructive" }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "font-medium text-destructive", children: "Bestellingen konden niet geladen worden" }), _jsx("div", { className: "mt-1 text-muted-foreground", children: error.message })] }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => refetch(), disabled: isFetching, children: "Opnieuw proberen" })] })), (warnings.length > 0 || truncated) && (_jsxs("div", { className: "shrink-0 flex items-start gap-3 rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), _jsxs("div", { className: "space-y-1 text-muted-foreground", children: [warnings.map((w) => (_jsx("div", { children: w }, w))), truncated && (_jsx("div", { children: "Niet alle orders konden worden meegenomen. Kies een kortere periode voor een volledig overzicht." }))] })] })), selectedRows.length > 0 && (_jsxs("div", { className: "shrink-0 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-primary/30 bg-primary/5 p-3", children: [_jsxs("div", { className: "text-sm text-foreground", children: [_jsx("span", { className: "font-medium", children: selectedRows.length }), " geselecteerd", selectedPlan.total !== selectedRows.length && (_jsxs("span", { className: "text-muted-foreground", children: [" ", "\u00B7 ", selectedPlan.total, " onderliggende bestelling(en)"] })), selectedPlan.skipped > 0 && (_jsxs("span", { className: "text-muted-foreground", children: [" ", "\u00B7 ", selectedPlan.skipped, " Floriday-order(s) worden overgeslagen"] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSelectedRowIds([]), children: "Selectie wissen" }), _jsx(Button, { size: "sm", className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", disabled: selectedPlan.deletable.length === 0, onClick: () => {
318
+ }) }) }), _jsxs("div", { className: "shrink-0 flex flex-wrap items-center justify-between gap-3", children: [_jsx(SalesOrdersFilters, { value: filters, onChange: setFilters }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: () => setFilterPanelOpen(true), "aria-label": "Filters", children: [_jsx(Filter, { className: "mr-2 h-4 w-4" }), "Filters", activeFilterCount > 0 && (_jsx("span", { className: "ml-2 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground", children: activeFilterCount }))] }), _jsx(Button, { variant: "outline", size: "icon", onClick: handleSync, disabled: syncing, "aria-label": "Synchroniseren", title: "Synchroniseren", children: _jsx(RefreshCw, { className: "h-4 w-4 " + (syncing ? "animate-spin" : "") }) }), _jsxs(Button, { variant: "outline", size: "sm", onClick: handleExport, children: [_jsx(Download, { className: "mr-2 h-4 w-4" }), " Exporteren"] }), _jsxs(Button, { size: "sm", onClick: () => navigate({ to: "/floriday-verkoop/verkooporders/nieuw" }), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Bestelling aanmaken"] })] })] }), _jsx("div", { className: "shrink-0", children: _jsx(AnalyticsCards, { totals: totals, loading: isLoading }) }), _jsx("div", { className: "shrink-0", children: _jsx(StockConsumptionAlertsBanner, {}) }), error && (_jsxs("div", { className: "shrink-0 flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-destructive" }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "font-medium text-destructive", children: "Bestellingen konden niet geladen worden" }), _jsx("div", { className: "mt-1 text-muted-foreground", children: error.message })] }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => refetch(), disabled: isFetching, children: "Opnieuw proberen" })] })), (warnings.length > 0 || truncated) && (_jsxs("div", { className: "shrink-0 flex items-start gap-3 rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), _jsxs("div", { className: "space-y-1 text-muted-foreground", children: [warnings.map((w) => (_jsx("div", { children: w }, w))), truncated && (_jsx("div", { children: "Niet alle orders konden worden meegenomen. Kies een kortere periode voor een volledig overzicht." }))] })] })), selectedRows.length > 0 && (_jsxs("div", { className: "shrink-0 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-primary/30 bg-primary/5 p-3", children: [_jsxs("div", { className: "text-sm text-foreground", children: [_jsx("span", { className: "font-medium", children: selectedRows.length }), " geselecteerd", selectedPlan.total !== selectedRows.length && (_jsxs("span", { className: "text-muted-foreground", children: [" ", "\u00B7 ", selectedPlan.total, " onderliggende bestelling(en)"] })), selectedPlan.skipped > 0 && (_jsxs("span", { className: "text-muted-foreground", children: [" ", "\u00B7 ", selectedPlan.skipped, " Floriday-order(s) worden overgeslagen"] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSelectedRowIds([]), children: "Selectie wissen" }), _jsx(Button, { size: "sm", className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", disabled: selectedPlan.deletable.length === 0, onClick: () => {
319
319
  setCancelReason("");
320
320
  setPendingAction({
321
321
  rows: selectedRows,