@flowselections/floriday-voorraad 1.0.70 → 1.0.72

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"AA6MA,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,cAAc,EACvB,WAAW,EACX,SAAS,EACT,WAAW,GACZ,GAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,+BAorEL"}
1
+ {"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"AA6MA,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,cAAc,EACvB,WAAW,EACX,SAAS,EACT,WAAW,GACZ,GAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,+BAssEL"}
@@ -291,7 +291,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
291
291
  setProductLoading(true);
292
292
  (async () => {
293
293
  try {
294
- const baseCols = "id,product,barcode,article_number,quantity,image_url,plants_per_crate,crates_per_layer,layers_per_cart,trade_item_key,floriday_trade_item_id,custom_fields";
294
+ const baseCols = "id,product,sale_price,unit,barcode,article_number,quantity,image_url,plants_per_crate,crates_per_layer,layers_per_cart,trade_item_key,floriday_trade_item_id,custom_fields";
295
295
  let { data: product, error } = await supabase
296
296
  .from("products")
297
297
  .select(`${baseCols},floriday_packing_confirmed_at,floriday_packing_source`)
@@ -487,7 +487,10 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
487
487
  : validGtin
488
488
  ? barcode
489
489
  : (payload.gtin ?? ""),
490
- salePricePerPiece: Number(customFields.sale_price ?? customFields.salePrice ?? payload.salePricePerPiece) || 0,
490
+ // M26: de verkoopprijs van het artikel is leidend (zelfde veld als "Prijs opslaan").
491
+ salePricePerPiece: Number(product.sale_price) > 0
492
+ ? Number(product.sale_price)
493
+ : Number(customFields.sale_price ?? customFields.salePrice ?? payload.salePricePerPiece) || 0,
491
494
  // Voorkeur: werkelijke voorraad uit trade_item_stock.
492
495
  // Fallback: opgeslagen payload-waarde. `products.quantity` wordt
493
496
  // bewust NIET meer gelezen — die staat structureel op 0.
@@ -925,18 +928,34 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
925
928
  }, [spec.characteristics]);
926
929
  const wantsPublish = (isEditingPublished && Boolean(tradeItemId)) ||
927
930
  (!isEditingPublished && publishToFloriday);
928
- const readiness = useMemo(() => buildReadinessReport({
929
- data,
930
- spec,
931
- connectionOk: Boolean(activeId) && connectionReadiness.data?.ready === true,
932
- connectionLoading: connLoading || connectionReadiness.isLoading,
933
- environment: activeConnection?.active_environment ?? null,
934
- connectionMessage: connectionReadiness.data?.message ?? null,
935
- schemaReady: schemaQuery.isSuccess,
936
- learnedCharacteristicCodes: serverRequiredCodes,
937
- characteristicLabels,
938
- wantsPublish,
939
- }), [
931
+ const readiness = useMemo(() => {
932
+ const r = buildReadinessReport({
933
+ data,
934
+ spec,
935
+ connectionOk: Boolean(activeId) && connectionReadiness.data?.ready === true,
936
+ connectionLoading: connLoading || connectionReadiness.isLoading,
937
+ environment: activeConnection?.active_environment ?? null,
938
+ connectionMessage: connectionReadiness.data?.message ?? null,
939
+ schemaReady: schemaQuery.isSuccess,
940
+ learnedCharacteristicCodes: serverRequiredCodes,
941
+ characteristicLabels,
942
+ wantsPublish,
943
+ });
944
+ // M26: één controle — elke onvolledige stap (zelfde check als de teller) telt mee.
945
+ const extra = steps
946
+ .filter((s, i) => !stepValidity[i])
947
+ .filter((s) => !r.items.some((it) => it.stepKey === s.key && !it.ok))
948
+ .map((s) => ({
949
+ key: `step-${s.key}`,
950
+ label: `Stap "${s.label}" is nog onvolledig`,
951
+ ok: false,
952
+ stepKey: s.key,
953
+ blocking: true,
954
+ }));
955
+ const items = [...r.items, ...extra];
956
+ const blockers = items.filter((i) => i.blocking && !i.ok);
957
+ return { ok: blockers.length === 0, items, blockers };
958
+ }, [
940
959
  data,
941
960
  spec,
942
961
  activeId,
@@ -948,6 +967,8 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
948
967
  serverRequiredCodes,
949
968
  characteristicLabels,
950
969
  wantsPublish,
970
+ steps,
971
+ stepValidity,
951
972
  ]);
952
973
  const goToStepKey = useCallback((key) => {
953
974
  const idx = visibleSteps(data).findIndex((s) => s.key === key);
@@ -1 +1 @@
1
- {"version":3,"file":"FloridaySentCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FloridaySentCard.tsx"],"names":[],"mappings":"AAUA,KAAK,GAAG,GAAG;IACT,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAUF,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,GAAG,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAC,GAAG,MAAM,CA0BxI;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE;IACD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,+BAmGA"}
1
+ {"version":3,"file":"FloridaySentCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FloridaySentCard.tsx"],"names":[],"mappings":"AAWA,KAAK,GAAG,GAAG;IACT,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAUF,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,GAAG,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAC,GAAG,MAAM,CA0BxI;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE;IACD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,+BA+IA"}
@@ -8,6 +8,7 @@ import { useEffect, useState } from "react";
8
8
  import { Card, CardContent } from "@flowselections/core";
9
9
  import { Send } from "lucide-react";
10
10
  import { supabase } from "../../integrations/supabase/client";
11
+ import { priceProblem } from "../../lib/floriday-base-supply";
11
12
  const MODE_LABEL = {
12
13
  FOLLOW_ERP: "Volgt ERP",
13
14
  MAXIMUM: "Maximum",
@@ -46,6 +47,9 @@ export function resultText(r) {
46
47
  }
47
48
  export function FloridaySentCard({ connectionId, productId, tradeItemId, productType, }) {
48
49
  const [rows, setRows] = useState([]);
50
+ const [weekPrice, setWeekPrice] = useState({});
51
+ const [weekChange, setWeekChange] = useState({});
52
+ const [reason, setReason] = useState(null);
49
53
  useEffect(() => {
50
54
  if (!connectionId || (!productId && !tradeItemId))
51
55
  return;
@@ -76,10 +80,48 @@ export function FloridaySentCard({ connectionId, productId, tradeItemId, product
76
80
  out.push(r);
77
81
  }
78
82
  setRows(out.slice(0, 8));
83
+ // M26: laatst verzonden prijs per week, ook van inmiddels vervangen regels
84
+ // (latere aantal-wijzigingen sturen geen prijs; die blijft in Floriday staan).
85
+ const { data: priced } = await supabase
86
+ .from("floriday_continuous_stock_queue")
87
+ .select("target_year,target_week,price_sent,price_previous,updated_at")
88
+ .eq("connection_id", connectionId)
89
+ .or(ors)
90
+ .not("price_sent", "is", null)
91
+ .order("updated_at", { ascending: false })
92
+ .limit(100);
93
+ const wp = {};
94
+ const wc = {};
95
+ for (const r of (priced ?? [])) {
96
+ const k = `${r.target_year ?? ""}-${r.target_week ?? ""}`;
97
+ if (!(k in wp)) {
98
+ wp[k] = Number(r.price_sent);
99
+ // M27: het ERP heeft een andere prijs in Floriday overschreven.
100
+ if (r.price_previous != null && Math.abs(Number(r.price_previous) - Number(r.price_sent)) > 0.0005)
101
+ wc[k] = `Prijs in Floriday aangepast van € ${Number(r.price_previous).toFixed(2)} naar € ${Number(r.price_sent).toFixed(2)}`;
102
+ }
103
+ }
104
+ // M26: werkelijke reden bij "Prijs ontbreekt" uit het artikel zelf.
105
+ let why = null;
106
+ if (productId) {
107
+ const { data: p } = await supabase
108
+ .from("products").select("sale_price,unit").eq("id", productId).maybeSingle();
109
+ if (p)
110
+ why = priceProblem(p.sale_price, p.unit);
111
+ }
112
+ if (cancelled)
113
+ return;
114
+ setWeekPrice(wp);
115
+ setWeekChange(wc);
116
+ setReason(why);
79
117
  })();
80
118
  return () => {
81
119
  cancelled = true;
82
120
  };
83
121
  }, [connectionId, productId, tradeItemId]);
84
- return (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-3 p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Send, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium", children: "Laatst naar Floriday" })] }), _jsxs("p", { className: "text-xs text-muted-foreground break-all", children: ["Floriday-id: ", tradeItemId ? _jsx("span", { className: "font-mono", children: tradeItemId }) : "nog niet gekoppeld"] }), (productType === "GROUP" || productType === "SET" || productType === "COMPOSITION") && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Productgroep (ERP): leden met eigen voorraad; alleen het totaal gaat naar Floriday. Set (Floriday): \u00E9\u00E9n artikel samengesteld uit onderdelen; de voorraad gaat pas naar Floriday na akkoord." })), rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog niets naar Floriday gestuurd." })) : (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-xs", children: [_jsx("thead", { className: "text-left text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "py-1 pr-3", children: "Week" }), _jsx("th", { className: "py-1 pr-3 text-right", children: "Aantal" }), _jsx("th", { className: "py-1 pr-3 text-right", children: "Prijs (excl. btw)" }), _jsx("th", { className: "py-1 pr-3", children: "Modus" }), _jsx("th", { className: "py-1 pr-3", children: "Tijd" }), _jsx("th", { className: "py-1", children: "Resultaat" })] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { className: "border-t align-top", children: [_jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: r.target_week ? `${r.target_year}-${r.target_week}` : "—" }), _jsx("td", { className: "py-1 pr-3 text-right tabular-nums", children: r.number_of_pieces ?? "—" }), _jsx("td", { className: "py-1 pr-3 text-right tabular-nums", children: r.price_sent != null ? `€ ${Number(r.price_sent).toFixed(2)}` : "—" }), _jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: r.stock_mode ? MODE_LABEL[r.stock_mode] ?? r.stock_mode : "—" }), _jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: new Date(r.sent_at ?? r.updated_at).toLocaleString("nl-NL") }), _jsxs("td", { className: "py-1", children: [resultText(r), r.price_note && r.price_note !== resultText(r) && (_jsx("div", { className: "text-xs text-muted-foreground", children: r.price_note }))] })] }, r.id))) })] }) }))] }) }));
122
+ return (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-3 p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Send, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium", children: "Laatst naar Floriday" })] }), _jsxs("p", { className: "text-xs text-muted-foreground break-all", children: ["Floriday-id: ", tradeItemId ? _jsx("span", { className: "font-mono", children: tradeItemId }) : "nog niet gekoppeld"] }), (productType === "GROUP" || productType === "SET" || productType === "COMPOSITION") && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Productgroep (ERP): leden met eigen voorraad; alleen het totaal gaat naar Floriday. Set (Floriday): \u00E9\u00E9n artikel samengesteld uit onderdelen; de voorraad gaat pas naar Floriday na akkoord." })), rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog niets naar Floriday gestuurd." })) : (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-xs", children: [_jsx("thead", { className: "text-left text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "py-1 pr-3", children: "Week" }), _jsx("th", { className: "py-1 pr-3 text-right", children: "Aantal" }), _jsx("th", { className: "py-1 pr-3 text-right", children: "Prijs (excl. btw)" }), _jsx("th", { className: "py-1 pr-3", children: "Modus" }), _jsx("th", { className: "py-1 pr-3", children: "Tijd" }), _jsx("th", { className: "py-1", children: "Resultaat" })] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { className: "border-t align-top", children: [_jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: r.target_week ? `${r.target_year}-${r.target_week}` : "—" }), _jsx("td", { className: "py-1 pr-3 text-right tabular-nums", children: r.number_of_pieces ?? "—" }), _jsx("td", { className: "py-1 pr-3 text-right tabular-nums", children: (() => {
123
+ const p = r.price_sent ?? weekPrice[`${r.target_year ?? ""}-${r.target_week ?? ""}`];
124
+ return p != null ? `€ ${Number(p).toFixed(2)}` : "—";
125
+ })() }), _jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: r.stock_mode ? MODE_LABEL[r.stock_mode] ?? r.stock_mode : "—" }), _jsx("td", { className: "py-1 pr-3 whitespace-nowrap", children: new Date(r.sent_at ?? r.updated_at).toLocaleString("nl-NL") }), _jsxs("td", { className: "py-1", children: [r.status === "skipped_no_price" && reason ? reason : resultText(r), weekChange[`${r.target_year ?? ""}-${r.target_week ?? ""}`] &&
126
+ weekChange[`${r.target_year ?? ""}-${r.target_week ?? ""}`] !== resultText(r) && (_jsx("div", { className: "text-xs text-muted-foreground", children: weekChange[`${r.target_year ?? ""}-${r.target_week ?? ""}`] })), r.price_note && r.price_note !== resultText(r) && (_jsx("div", { className: "text-xs text-muted-foreground", children: r.price_note }))] })] }, r.id))) })] }) }))] }) }));
85
127
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PriceStatusBadge.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/PriceStatusBadge.tsx"],"names":[],"mappings":"AAGA,KAAK,KAAK,GAAG;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAeF,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,KAAK,sCAkEpE"}
1
+ {"version":3,"file":"PriceStatusBadge.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/PriceStatusBadge.tsx"],"names":[],"mappings":"AAmCA,KAAK,KAAK,GAAG;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAeF,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,KAAK,sCA8EpE"}
@@ -1,6 +1,36 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { CircleDollarSign, Clock, MinusCircle, Loader2 } from "lucide-react";
3
+ import { useEffect, useState } from "react";
3
4
  import { useTradeItemSupplyLine } from "../../hooks/useTradeItemSupplyLine.js";
5
+ import { supabase } from "../../integrations/supabase/client.js";
6
+ /** M26: laatst naar Floriday verzonden weekprijs (weekaanbod), uit de wachtrij. */
7
+ function useLastSentPrice(tradeItemId) {
8
+ const [v, setV] = useState(null);
9
+ useEffect(() => {
10
+ if (!tradeItemId)
11
+ return;
12
+ let cancelled = false;
13
+ const load = async () => {
14
+ const { data } = await supabase
15
+ .from("floriday_continuous_stock_queue")
16
+ .select("price_sent,target_week,target_year,updated_at")
17
+ .eq("trade_item_id", tradeItemId)
18
+ .not("price_sent", "is", null)
19
+ .order("updated_at", { ascending: false })
20
+ .limit(1)
21
+ .maybeSingle();
22
+ if (!cancelled)
23
+ setV(data ? { price: Number(data.price_sent), week: data.target_week, year: data.target_year, at: data.updated_at } : null);
24
+ };
25
+ void load();
26
+ const t = setInterval(load, 30000);
27
+ return () => {
28
+ cancelled = true;
29
+ clearInterval(t);
30
+ };
31
+ }, [tradeItemId]);
32
+ return v;
33
+ }
4
34
  function formatDate(iso) {
5
35
  if (!iso)
6
36
  return "—";
@@ -17,11 +47,15 @@ function formatDate(iso) {
17
47
  }
18
48
  export function PriceStatusBadge({ tradeItemId, offerForSale }) {
19
49
  const { data: supplyLine, isLoading } = useTradeItemSupplyLine(tradeItemId);
50
+ const sent = useLastSentPrice(tradeItemId);
20
51
  if (!tradeItemId)
21
52
  return null;
22
53
  if (isLoading) {
23
54
  return (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), " Prijsstatus laden\u2026"] }));
24
55
  }
56
+ if (!supplyLine && sent) {
57
+ return (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full cursor-help bg-emerald-100 text-emerald-700", title: `Weekaanbod verzonden op ${new Date(sent.at).toLocaleString("nl-NL")}`, children: [_jsx(CircleDollarSign, { className: "h-3 w-3" }), " Prijs live in Floriday \u00B7 week ", sent.week ?? "?", " \u00B7 \u20AC ", sent.price.toFixed(2)] }));
58
+ }
25
59
  const now = Date.now();
26
60
  const endMs = supplyLine?.period_end ? new Date(supplyLine.period_end).getTime() : null;
27
61
  const qty = supplyLine?.available_quantity ?? 0;
@@ -1 +1 @@
1
- {"version":3,"file":"ProductSalePriceField.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductSalePriceField.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,sCAkGA;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,sCAmCtE"}
1
+ {"version":3,"file":"ProductSalePriceField.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductSalePriceField.tsx"],"names":[],"mappings":"AAmBA,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,sCAkGA;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,sCAqCtE"}
@@ -11,6 +11,7 @@ import { Link } from "@tanstack/react-router";
11
11
  import { Button, Input, Label, toast } from "@flowselections/core";
12
12
  import { AlertTriangle, Loader2 } from "lucide-react";
13
13
  import { supabase } from "../../integrations/supabase/client";
14
+ import { priceProblem } from "../../lib/floriday-base-supply";
14
15
  function isPieceUnit(unit) {
15
16
  const u = String(unit ?? "").trim().toLowerCase();
16
17
  return u === "" || u === "stuks" || u === "stuk";
@@ -81,11 +82,12 @@ export function ProductSalePriceField({ productId, onSaved, }) {
81
82
  };
82
83
  if (!exists)
83
84
  return null;
84
- return (_jsxs("div", { id: "verkoopprijs", className: "space-y-2 rounded-md border p-4", children: [_jsx(Label, { htmlFor: `price-${productId}`, children: "Verkoopprijs per stuk (excl. btw)" }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Input, { id: `price-${productId}`, inputMode: "decimal", className: "w-40", placeholder: "Bijv. 1,40", disabled: !loaded || saving, value: value, onChange: (e) => setValue(e.target.value) }), _jsxs(Button, { size: "sm", disabled: !dirty || saving, onClick: () => void save(), children: [saving && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), saving ? "Bezig met opslaan…" : "Prijs opslaan"] })] }), value.trim() !== "" && !valid && (_jsx("p", { className: "text-xs text-destructive", children: "Vul een prijs groter dan 0 in, met maximaal 5 decimalen." })), loaded && !isPieceUnit(unit) && (_jsxs("p", { className: "text-xs text-amber-700", children: ["Eenheid onduidelijk (", unit, "): de prijs telt voor Floriday alleen bij eenheid \"stuks\"."] })), loaded && !(saved && saved > 0) && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Zonder prijs komt dit artikel niet in Floriday (\"Prijs ontbreekt\")." })), error && _jsx("p", { role: "alert", className: "text-xs text-destructive", children: error })] }));
85
+ return (_jsxs("div", { id: "verkoopprijs", className: "space-y-2 rounded-md border p-4", children: [_jsx(Label, { htmlFor: `price-${productId}`, children: "Verkoopprijs per stuk (excl. btw)" }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Input, { id: `price-${productId}`, inputMode: "decimal", className: "w-40", placeholder: "Bijv. 1,40", disabled: !loaded || saving, value: value, onChange: (e) => setValue(e.target.value) }), _jsxs(Button, { size: "sm", disabled: !dirty || saving, onClick: () => void save(), children: [saving && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), saving ? "Bezig met opslaan…" : "Prijs opslaan"] })] }), value.trim() !== "" && !valid && (_jsx("p", { className: "text-xs text-destructive", children: "Vul een prijs groter dan 0 in, met maximaal 5 decimalen." })), loaded && !isPieceUnit(unit) && (_jsxs("p", { className: "text-xs text-amber-700", children: ["Eenheid is geen stuks (nu: ", unit, "): de prijs telt voor Floriday alleen bij eenheid \"stuks\"."] })), loaded && !(saved && saved > 0) && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Zonder prijs komt dit artikel niet in Floriday (\"Prijs ontbreekt\")." })), error && _jsx("p", { role: "alert", className: "text-xs text-destructive", children: error })] }));
85
86
  }
86
87
  /** Melding met directe link naar het prijsveld; toont niets als de prijs in orde is. */
87
88
  export function MissingPriceNotice({ productId }) {
88
89
  const [state, setState] = useState(null);
90
+ const [why, setWhy] = useState(null);
89
91
  useEffect(() => {
90
92
  let cancelled = false;
91
93
  (async () => {
@@ -96,6 +98,7 @@ export function MissingPriceNotice({ productId }) {
96
98
  .maybeSingle();
97
99
  if (cancelled || !data)
98
100
  return;
101
+ setWhy(priceProblem(data.sale_price, data.unit));
99
102
  if (!isPieceUnit(data.unit))
100
103
  setState("unit");
101
104
  else
@@ -107,5 +110,5 @@ export function MissingPriceNotice({ productId }) {
107
110
  }, [productId]);
108
111
  if (state !== "missing" && state !== "unit")
109
112
  return null;
110
- return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-sm text-amber-800", children: [_jsx(AlertTriangle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "flex-1", children: state === "missing" ? "Prijs ontbreekt: dit artikel gaat niet naar Floriday." : "Eenheid onduidelijk: de prijs telt alleen per stuk." }), _jsx(Link, { to: "/voorraad/$id", params: { id: productId }, hash: "verkoopprijs", className: "font-medium underline", children: "Prijs invullen" })] }));
113
+ return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-sm text-amber-800", children: [_jsx(AlertTriangle, { className: "h-4 w-4 shrink-0" }), _jsxs("span", { className: "flex-1", children: [why ?? (state === "missing" ? "Prijs ontbreekt" : "Eenheid is geen stuks"), ": dit artikel gaat niet naar Floriday."] }), _jsx(Link, { to: "/voorraad/$id", params: { id: productId }, hash: "verkoopprijs", className: "font-medium underline", children: "Prijs invullen" })] }));
111
114
  }
@@ -6842,6 +6842,7 @@ export type Database = {
6842
6842
  next_attempt_at: string;
6843
6843
  number_of_pieces: number;
6844
6844
  price_note: string | null;
6845
+ price_previous: number | null;
6845
6846
  price_sent: number | null;
6846
6847
  price_status: string | null;
6847
6848
  product_id: string | null;
@@ -6875,6 +6876,7 @@ export type Database = {
6875
6876
  next_attempt_at?: string;
6876
6877
  number_of_pieces?: number;
6877
6878
  price_note?: string | null;
6879
+ price_previous?: number | null;
6878
6880
  price_sent?: number | null;
6879
6881
  price_status?: string | null;
6880
6882
  product_id?: string | null;
@@ -6908,6 +6910,7 @@ export type Database = {
6908
6910
  next_attempt_at?: string;
6909
6911
  number_of_pieces?: number;
6910
6912
  price_note?: string | null;
6913
+ price_previous?: number | null;
6911
6914
  price_sent?: number | null;
6912
6915
  price_status?: string | null;
6913
6916
  product_id?: string | null;
@@ -12572,6 +12575,27 @@ export type Database = {
12572
12575
  };
12573
12576
  Relationships: [];
12574
12577
  };
12578
+ logistics_order_pick_day: {
12579
+ Row: {
12580
+ order_id: string;
12581
+ pick_date: string;
12582
+ pinned_at: string;
12583
+ source: string;
12584
+ };
12585
+ Insert: {
12586
+ order_id: string;
12587
+ pick_date: string;
12588
+ pinned_at?: string;
12589
+ source?: string;
12590
+ };
12591
+ Update: {
12592
+ order_id?: string;
12593
+ pick_date?: string;
12594
+ pinned_at?: string;
12595
+ source?: string;
12596
+ };
12597
+ Relationships: [];
12598
+ };
12575
12599
  logistics_order_plan_exclusion: {
12576
12600
  Row: {
12577
12601
  created_at: string;
@@ -18640,6 +18664,36 @@ export type Database = {
18640
18664
  };
18641
18665
  Relationships: [];
18642
18666
  };
18667
+ print_computer_status: {
18668
+ Row: {
18669
+ bijgewerkt_op: string;
18670
+ created_at: string;
18671
+ extern_computer_id: string;
18672
+ naam: string | null;
18673
+ status: string | null;
18674
+ updated_at: string;
18675
+ verbonden: boolean;
18676
+ };
18677
+ Insert: {
18678
+ bijgewerkt_op?: string;
18679
+ created_at?: string;
18680
+ extern_computer_id: string;
18681
+ naam?: string | null;
18682
+ status?: string | null;
18683
+ updated_at?: string;
18684
+ verbonden?: boolean;
18685
+ };
18686
+ Update: {
18687
+ bijgewerkt_op?: string;
18688
+ created_at?: string;
18689
+ extern_computer_id?: string;
18690
+ naam?: string | null;
18691
+ status?: string | null;
18692
+ updated_at?: string;
18693
+ verbonden?: boolean;
18694
+ };
18695
+ Relationships: [];
18696
+ };
18643
18697
  print_dedupe_events: {
18644
18698
  Row: {
18645
18699
  bestaande_job_id: string | null;
@@ -18762,16 +18816,21 @@ export type Database = {
18762
18816
  lokale_pdf_print_plek_id: string | null;
18763
18817
  lokale_pdf_status: string | null;
18764
18818
  opgepakt_op: string | null;
18819
+ origineel_sleutel: string | null;
18765
18820
  paginas: number;
18766
18821
  payload: Json;
18767
18822
  pdf_base64: string | null;
18768
18823
  pdf_url: string | null;
18769
18824
  pogingen: number;
18770
18825
  printer_id: string | null;
18826
+ printnode_bericht: string | null;
18827
+ printnode_status: string | null;
18828
+ printnode_status_op: string | null;
18771
18829
  render_html: string | null;
18772
18830
  resultaat_pdf_base64: string | null;
18773
18831
  status: Database["public"]["Enums"]["print_job_status"];
18774
18832
  updated_at: string;
18833
+ verloopt_na_s: number | null;
18775
18834
  verwerkingsfase: string;
18776
18835
  volgende_poging: string | null;
18777
18836
  voltooid_op: string | null;
@@ -18811,16 +18870,21 @@ export type Database = {
18811
18870
  lokale_pdf_print_plek_id?: string | null;
18812
18871
  lokale_pdf_status?: string | null;
18813
18872
  opgepakt_op?: string | null;
18873
+ origineel_sleutel?: string | null;
18814
18874
  paginas?: number;
18815
18875
  payload?: Json;
18816
18876
  pdf_base64?: string | null;
18817
18877
  pdf_url?: string | null;
18818
18878
  pogingen?: number;
18819
18879
  printer_id?: string | null;
18880
+ printnode_bericht?: string | null;
18881
+ printnode_status?: string | null;
18882
+ printnode_status_op?: string | null;
18820
18883
  render_html?: string | null;
18821
18884
  resultaat_pdf_base64?: string | null;
18822
18885
  status?: Database["public"]["Enums"]["print_job_status"];
18823
18886
  updated_at?: string;
18887
+ verloopt_na_s?: number | null;
18824
18888
  verwerkingsfase?: string;
18825
18889
  volgende_poging?: string | null;
18826
18890
  voltooid_op?: string | null;
@@ -18860,16 +18924,21 @@ export type Database = {
18860
18924
  lokale_pdf_print_plek_id?: string | null;
18861
18925
  lokale_pdf_status?: string | null;
18862
18926
  opgepakt_op?: string | null;
18927
+ origineel_sleutel?: string | null;
18863
18928
  paginas?: number;
18864
18929
  payload?: Json;
18865
18930
  pdf_base64?: string | null;
18866
18931
  pdf_url?: string | null;
18867
18932
  pogingen?: number;
18868
18933
  printer_id?: string | null;
18934
+ printnode_bericht?: string | null;
18935
+ printnode_status?: string | null;
18936
+ printnode_status_op?: string | null;
18869
18937
  render_html?: string | null;
18870
18938
  resultaat_pdf_base64?: string | null;
18871
18939
  status?: Database["public"]["Enums"]["print_job_status"];
18872
18940
  updated_at?: string;
18941
+ verloopt_na_s?: number | null;
18873
18942
  verwerkingsfase?: string;
18874
18943
  volgende_poging?: string | null;
18875
18944
  voltooid_op?: string | null;
@@ -26394,6 +26463,7 @@ export type Database = {
26394
26463
  created_by: string;
26395
26464
  customer_id: string | null;
26396
26465
  id: string;
26466
+ offerte_id: string | null;
26397
26467
  payload: Json;
26398
26468
  reden: string | null;
26399
26469
  status: string;
@@ -26409,6 +26479,7 @@ export type Database = {
26409
26479
  created_by?: string;
26410
26480
  customer_id?: string | null;
26411
26481
  id?: string;
26482
+ offerte_id?: string | null;
26412
26483
  payload?: Json;
26413
26484
  reden?: string | null;
26414
26485
  status?: string;
@@ -26424,6 +26495,7 @@ export type Database = {
26424
26495
  created_by?: string;
26425
26496
  customer_id?: string | null;
26426
26497
  id?: string;
26498
+ offerte_id?: string | null;
26427
26499
  payload?: Json;
26428
26500
  reden?: string | null;
26429
26501
  status?: string;
@@ -28026,16 +28098,21 @@ export type Database = {
28026
28098
  lokale_pdf_print_plek_id: string | null;
28027
28099
  lokale_pdf_status: string | null;
28028
28100
  opgepakt_op: string | null;
28101
+ origineel_sleutel: string | null;
28029
28102
  paginas: number;
28030
28103
  payload: Json;
28031
28104
  pdf_base64: string | null;
28032
28105
  pdf_url: string | null;
28033
28106
  pogingen: number;
28034
28107
  printer_id: string | null;
28108
+ printnode_bericht: string | null;
28109
+ printnode_status: string | null;
28110
+ printnode_status_op: string | null;
28035
28111
  render_html: string | null;
28036
28112
  resultaat_pdf_base64: string | null;
28037
28113
  status: Database["public"]["Enums"]["print_job_status"];
28038
28114
  updated_at: string;
28115
+ verloopt_na_s: number | null;
28039
28116
  verwerkingsfase: string;
28040
28117
  volgende_poging: string | null;
28041
28118
  voltooid_op: string | null;
@@ -28087,6 +28164,7 @@ export type Database = {
28087
28164
  next_attempt_at: string;
28088
28165
  number_of_pieces: number;
28089
28166
  price_note: string | null;
28167
+ price_previous: number | null;
28090
28168
  price_sent: number | null;
28091
28169
  price_status: string | null;
28092
28170
  product_id: string | null;
@@ -28216,16 +28294,21 @@ export type Database = {
28216
28294
  lokale_pdf_print_plek_id: string | null;
28217
28295
  lokale_pdf_status: string | null;
28218
28296
  opgepakt_op: string | null;
28297
+ origineel_sleutel: string | null;
28219
28298
  paginas: number;
28220
28299
  payload: Json;
28221
28300
  pdf_base64: string | null;
28222
28301
  pdf_url: string | null;
28223
28302
  pogingen: number;
28224
28303
  printer_id: string | null;
28304
+ printnode_bericht: string | null;
28305
+ printnode_status: string | null;
28306
+ printnode_status_op: string | null;
28225
28307
  render_html: string | null;
28226
28308
  resultaat_pdf_base64: string | null;
28227
28309
  status: Database["public"]["Enums"]["print_job_status"];
28228
28310
  updated_at: string;
28311
+ verloopt_na_s: number | null;
28229
28312
  verwerkingsfase: string;
28230
28313
  volgende_poging: string | null;
28231
28314
  voltooid_op: string | null;
@@ -28277,16 +28360,21 @@ export type Database = {
28277
28360
  lokale_pdf_print_plek_id: string | null;
28278
28361
  lokale_pdf_status: string | null;
28279
28362
  opgepakt_op: string | null;
28363
+ origineel_sleutel: string | null;
28280
28364
  paginas: number;
28281
28365
  payload: Json;
28282
28366
  pdf_base64: string | null;
28283
28367
  pdf_url: string | null;
28284
28368
  pogingen: number;
28285
28369
  printer_id: string | null;
28370
+ printnode_bericht: string | null;
28371
+ printnode_status: string | null;
28372
+ printnode_status_op: string | null;
28286
28373
  render_html: string | null;
28287
28374
  resultaat_pdf_base64: string | null;
28288
28375
  status: Database["public"]["Enums"]["print_job_status"];
28289
28376
  updated_at: string;
28377
+ verloopt_na_s: number | null;
28290
28378
  verwerkingsfase: string;
28291
28379
  volgende_poging: string | null;
28292
28380
  voltooid_op: string | null;
@@ -29693,6 +29781,7 @@ export type Database = {
29693
29781
  _is_herprint?: boolean;
29694
29782
  _kopieen?: number;
29695
29783
  _layout_id?: string;
29784
+ _mislukt_reden?: string;
29696
29785
  _payload?: Json;
29697
29786
  _pdf_base64?: string;
29698
29787
  _pdf_url?: string;
@@ -29810,6 +29899,12 @@ export type Database = {
29810
29899
  };
29811
29900
  Returns: string;
29812
29901
  };
29902
+ logistics_afhandeling_fulfillment_order: {
29903
+ Args: {
29904
+ _order_id: string;
29905
+ };
29906
+ Returns: Json;
29907
+ };
29813
29908
  logistics_allocation_check_changes: {
29814
29909
  Args: {
29815
29910
  p_order_item_ids?: string[];
@@ -30048,6 +30143,12 @@ export type Database = {
30048
30143
  };
30049
30144
  Returns: boolean;
30050
30145
  };
30146
+ logistics_cart_ids_frozen: {
30147
+ Args: {
30148
+ p_cart_ids: string[];
30149
+ };
30150
+ Returns: string[];
30151
+ };
30051
30152
  logistics_cart_index: {
30052
30153
  Args: {
30053
30154
  p_from?: string;
@@ -30074,6 +30175,12 @@ export type Database = {
30074
30175
  task_status: string;
30075
30176
  }[];
30076
30177
  };
30178
+ logistics_cart_is_frozen: {
30179
+ Args: {
30180
+ p_cart_id: string;
30181
+ };
30182
+ Returns: boolean;
30183
+ };
30077
30184
  logistics_cart_is_full: {
30078
30185
  Args: {
30079
30186
  p_cart_id: string;
@@ -31934,6 +32041,14 @@ export type Database = {
31934
32041
  };
31935
32042
  Returns: Json;
31936
32043
  };
32044
+ logistics_shipping_note_wait_reasons: {
32045
+ Args: never;
32046
+ Returns: {
32047
+ order_number: string;
32048
+ reden: string;
32049
+ wacht_sinds: string;
32050
+ }[];
32051
+ };
31937
32052
  logistics_shipping_note_wake: {
31938
32053
  Args: {
31939
32054
  _slip_job_id: string;
@@ -32786,6 +32901,13 @@ export type Database = {
32786
32901
  };
32787
32902
  Returns: string;
32788
32903
  };
32904
+ pick_find_sent_elsewhere: {
32905
+ Args: {
32906
+ _cart_id: string;
32907
+ _queue_item_id: string;
32908
+ };
32909
+ Returns: Json;
32910
+ };
32789
32911
  pick_is_reference_admin: {
32790
32912
  Args: never;
32791
32913
  Returns: boolean;
@@ -35375,6 +35497,13 @@ export type Database = {
35375
35497
  };
35376
35498
  Returns: Json;
35377
35499
  };
35500
+ wo_send_proposal_to_quote: {
35501
+ Args: {
35502
+ _id: string;
35503
+ _overrides?: Json;
35504
+ };
35505
+ Returns: Json;
35506
+ };
35378
35507
  wo_send_to_quote: {
35379
35508
  Args: {
35380
35509
  _werkbon_id: string;