@flowselections/floriday-verkoop-module 1.0.20 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts +6 -0
- package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts.map +1 -0
- package/dist-lib/components/verkoop/OrderControlStatusCard.js +41 -0
- package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailPage.js +20 -5
- package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
- package/dist-lib/components/verkoop/SalesOrdersTable.js +4 -1
- package/dist-lib/components/verkoop/VerkoopOrdersPage.js +1 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +16 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +16 -0
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +16 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +16 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/cart-lock.functions.d.ts +16 -0
- package/dist-lib/lib/cart-lock.functions.d.ts.map +1 -1
- package/dist-lib/lib/cart-replan.functions.d.ts +32 -0
- package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
- package/dist-lib/lib/create-order.functions.d.ts +192 -0
- package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +48 -0
- package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts +16 -0
- package/dist-lib/lib/floriday-logistic-labels.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-public.functions.d.ts +115 -0
- package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-public.functions.js +114 -38
- package/dist-lib/lib/floriday-writes.functions.d.ts +80 -0
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/order-shipments.functions.d.ts +64 -0
- package/dist-lib/lib/order-shipments.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.d.ts +2 -0
- package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
- package/dist-lib/lib/salesorders-mapping.js +8 -1
- package/dist-lib/lib/salesorders.functions.d.ts +23767 -0
- package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
- package/dist-lib/lib/salesorders.functions.js +181 -0
- package/dist-lib/lib/tradeitems.functions.d.ts +16 -0
- package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrderDetailQuery.d.ts +2 -0
- package/dist-lib/lib/useSalesOrderDetailQuery.d.ts.map +1 -0
- package/dist-lib/lib/useSalesOrderDetailQuery.js +50 -0
- package/dist-lib/lib/useSalesOrdersQuery.d.ts +2 -2
- package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
- package/dist-lib/lib/useSalesOrdersQuery.js +103 -9
- package/package.json +1 -1
|
@@ -1,11 +1,67 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
1
|
+
import { useEffect, useMemo } from "react";
|
|
2
2
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
3
3
|
import { useServerFn } from "@tanstack/react-start";
|
|
4
4
|
import { supabase } from "../integrations/supabase/client";
|
|
5
5
|
import { getActiveFloridayEnvironment, getFlorydayCachedList } from "./floriday-public.functions";
|
|
6
6
|
import { expandOrderItemsForPlanner } from "./expand-group-order-items";
|
|
7
7
|
import { planCarts } from "./cart-planner";
|
|
8
|
-
import { centralOrderNumber, mapJsonbToSalesOrderDTO, } from "./salesorders-mapping";
|
|
8
|
+
import { centralOrderNumber, isoWeekRange, mapJsonbToSalesOrderDTO, monthRange, } from "./salesorders-mapping";
|
|
9
|
+
// Bepaal het serverside periode-venster op basis van de UI-filters.
|
|
10
|
+
// Retourneert `since`/`until` als ISO-strings + het gekozen dateField.
|
|
11
|
+
// Bij ontbrekende/onvolledige filters geen venster → server past geen
|
|
12
|
+
// periode-filter toe (client-side applyFilters filtert dan alsnog).
|
|
13
|
+
function derivePeriodWindow(filters) {
|
|
14
|
+
const dateField = filters?.dateField ?? "ordered";
|
|
15
|
+
if (!filters)
|
|
16
|
+
return { dateField };
|
|
17
|
+
const ymdToUtc = (ymd) => {
|
|
18
|
+
const [y, m, d] = ymd.split("-").map(Number);
|
|
19
|
+
return new Date(Date.UTC(y, (m ?? 1) - 1, d ?? 1));
|
|
20
|
+
};
|
|
21
|
+
const startOfTodayUtc = () => {
|
|
22
|
+
const now = new Date();
|
|
23
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
24
|
+
};
|
|
25
|
+
let start = null;
|
|
26
|
+
let end = null;
|
|
27
|
+
if (filters.period === "month" && filters.month !== undefined && filters.monthYear !== undefined) {
|
|
28
|
+
const r = monthRange(filters.month, filters.monthYear);
|
|
29
|
+
start = r.start;
|
|
30
|
+
end = r.end;
|
|
31
|
+
}
|
|
32
|
+
else if (filters.period === "day" && filters.day) {
|
|
33
|
+
start = ymdToUtc(filters.day);
|
|
34
|
+
end = new Date(start);
|
|
35
|
+
end.setUTCDate(start.getUTCDate() + 1);
|
|
36
|
+
}
|
|
37
|
+
else if (filters.period === "last7" || filters.period === "last30") {
|
|
38
|
+
const days = filters.period === "last7" ? 7 : 30;
|
|
39
|
+
end = startOfTodayUtc();
|
|
40
|
+
end.setUTCDate(end.getUTCDate() + 1);
|
|
41
|
+
start = new Date(end);
|
|
42
|
+
start.setUTCDate(end.getUTCDate() - days);
|
|
43
|
+
}
|
|
44
|
+
else if (filters.period === "custom" && filters.customFrom && filters.customTo) {
|
|
45
|
+
start = ymdToUtc(filters.customFrom);
|
|
46
|
+
end = ymdToUtc(filters.customTo);
|
|
47
|
+
end.setUTCDate(end.getUTCDate() + 1);
|
|
48
|
+
}
|
|
49
|
+
else if (filters.week && filters.year) {
|
|
50
|
+
const r = isoWeekRange(filters.week, filters.year);
|
|
51
|
+
start = r.start;
|
|
52
|
+
end = r.end;
|
|
53
|
+
}
|
|
54
|
+
// Buffer van 1 dag rond het venster: order/delivery-tijden kunnen net buiten
|
|
55
|
+
// de weekgrens vallen; de client filtert alsnog exact via applyFilters.
|
|
56
|
+
if (start && end) {
|
|
57
|
+
const s = new Date(start);
|
|
58
|
+
s.setUTCDate(s.getUTCDate() - 1);
|
|
59
|
+
const e = new Date(end);
|
|
60
|
+
e.setUTCDate(e.getUTCDate() + 1);
|
|
61
|
+
return { since: s.toISOString(), until: e.toISOString(), dateField };
|
|
62
|
+
}
|
|
63
|
+
return { dateField };
|
|
64
|
+
}
|
|
9
65
|
function pickString(v) {
|
|
10
66
|
if (v == null)
|
|
11
67
|
return null;
|
|
@@ -69,6 +125,8 @@ function statusFlags(statusValue) {
|
|
|
69
125
|
status === "approved" ||
|
|
70
126
|
status === "open" ||
|
|
71
127
|
status === "concept",
|
|
128
|
+
isControlled: false,
|
|
129
|
+
controlledAt: null,
|
|
72
130
|
};
|
|
73
131
|
}
|
|
74
132
|
async function fetchAllLocalOrders() {
|
|
@@ -91,18 +149,25 @@ async function fetchAllLocalOrders() {
|
|
|
91
149
|
}
|
|
92
150
|
return rows;
|
|
93
151
|
}
|
|
94
|
-
export function useSalesOrdersQuery() {
|
|
152
|
+
export function useSalesOrdersQuery(filters) {
|
|
95
153
|
const fetchCachedList = useServerFn(getFlorydayCachedList);
|
|
96
154
|
const fetchActiveEnv = useServerFn(getActiveFloridayEnvironment);
|
|
97
155
|
const queryClient = useQueryClient();
|
|
98
|
-
const
|
|
156
|
+
const periodWindow = useMemo(() => derivePeriodWindow(filters), [filters]);
|
|
157
|
+
const queryKey = useMemo(() => [
|
|
158
|
+
"floriday",
|
|
159
|
+
"salesorders-cache",
|
|
160
|
+
periodWindow.dateField,
|
|
161
|
+
periodWindow.since ?? null,
|
|
162
|
+
periodWindow.until ?? null,
|
|
163
|
+
], [periodWindow.dateField, periodWindow.since, periodWindow.until]);
|
|
99
164
|
useEffect(() => {
|
|
100
165
|
let timer = null;
|
|
101
166
|
const invalidate = () => {
|
|
102
167
|
if (timer)
|
|
103
168
|
clearTimeout(timer);
|
|
104
169
|
timer = setTimeout(() => {
|
|
105
|
-
queryClient.invalidateQueries({ queryKey });
|
|
170
|
+
queryClient.invalidateQueries({ queryKey: ["floriday", "salesorders-cache"] });
|
|
106
171
|
}, 250);
|
|
107
172
|
};
|
|
108
173
|
const channel = supabase
|
|
@@ -125,9 +190,17 @@ export function useSalesOrdersQuery() {
|
|
|
125
190
|
const { environment } = await fetchActiveEnv();
|
|
126
191
|
const dbEnv = environment === "live" ? "live" : "staging";
|
|
127
192
|
// Floriday-data via de centrale gateway (geen directe floriday_*_cache reads).
|
|
128
|
-
const [ordersList,
|
|
129
|
-
fetchCachedList({
|
|
130
|
-
|
|
193
|
+
const [ordersList, tradeItemsList, connectionsRes, localOrderRows, localCustomersRes, mailboxProposalsRes,] = await Promise.all([
|
|
194
|
+
fetchCachedList({
|
|
195
|
+
data: {
|
|
196
|
+
environment,
|
|
197
|
+
entity: "sales-orders",
|
|
198
|
+
limit: 20000,
|
|
199
|
+
since: periodWindow.since,
|
|
200
|
+
until: periodWindow.until,
|
|
201
|
+
dateField: periodWindow.dateField,
|
|
202
|
+
},
|
|
203
|
+
}),
|
|
131
204
|
fetchCachedList({ data: { environment, entity: "trade-items", limit: 5000 } }),
|
|
132
205
|
supabase
|
|
133
206
|
.from("floriday_connections")
|
|
@@ -151,6 +224,27 @@ export function useSalesOrdersQuery() {
|
|
|
151
224
|
throw localCustomersRes.error;
|
|
152
225
|
if (mailboxProposalsRes.error)
|
|
153
226
|
throw mailboxProposalsRes.error;
|
|
227
|
+
// Targeted customer-cache fetch: alleen orgIds die daadwerkelijk in de
|
|
228
|
+
// orders voorkomen. Voorkomt dat we vastlopen op limit 2000 terwijl er
|
|
229
|
+
// tienduizenden klanten in floriday_customers_cache staan.
|
|
230
|
+
const neededOrgIds = Array.from(new Set((ordersList.rows ?? [])
|
|
231
|
+
.map((r) => String(r?.data?.customerOrganizationId ?? ""))
|
|
232
|
+
.filter((id) => id.length > 0)));
|
|
233
|
+
const customerCacheRows = [];
|
|
234
|
+
const orgChunkSize = 500;
|
|
235
|
+
for (let i = 0; i < neededOrgIds.length; i += orgChunkSize) {
|
|
236
|
+
const chunk = neededOrgIds.slice(i, i + orgChunkSize);
|
|
237
|
+
const { data, error } = await supabase
|
|
238
|
+
.from("floriday_customers_cache")
|
|
239
|
+
.select("organization_id, data")
|
|
240
|
+
.in("organization_id", chunk);
|
|
241
|
+
if (error) {
|
|
242
|
+
console.warn("[useSalesOrdersQuery] floriday_customers_cache chunk faalde:", error.message);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
customerCacheRows.push(...(data ?? []));
|
|
246
|
+
}
|
|
247
|
+
const customersList = { rows: customerCacheRows };
|
|
154
248
|
const lookup = new Map();
|
|
155
249
|
// Primair: gekoppelde klanten uit de Klanten Module (customers-tabel).
|
|
156
250
|
for (const c of localCustomersRes.data ?? []) {
|
|
@@ -203,7 +297,7 @@ export function useSalesOrdersQuery() {
|
|
|
203
297
|
pickString(d.articleCode);
|
|
204
298
|
tradeItemLookup.set(id, { name, imageUrl: firstPhoto, sku, raw: d });
|
|
205
299
|
}
|
|
206
|
-
const floridayOrders = (ordersList.rows ?? []).map((r) => mapJsonbToSalesOrderDTO(r.data, lookup, tradeItemLookup));
|
|
300
|
+
const floridayOrders = (ordersList.rows ?? []).map((r) => mapJsonbToSalesOrderDTO({ ...r.data, __controlledAt: r.controlled_at ?? null }, lookup, tradeItemLookup));
|
|
207
301
|
const localCustomerLookup = new Map();
|
|
208
302
|
for (const c of localCustomersRes.data ?? []) {
|
|
209
303
|
localCustomerLookup.set(String(c.id), {
|