@flowselections/floriday-klanten-module 1.0.15 → 1.0.17
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/assets/floriday-logo.png.asset.json +11 -0
- package/dist-lib/components/klanten/BackLink.d.ts +12 -0
- package/dist-lib/components/klanten/BackLink.d.ts.map +1 -0
- package/dist-lib/components/klanten/BackLink.js +12 -0
- package/dist-lib/components/klanten/FloridayAssortmentTab.d.ts +4 -0
- package/dist-lib/components/klanten/FloridayAssortmentTab.d.ts.map +1 -0
- package/dist-lib/components/klanten/FloridayAssortmentTab.js +80 -0
- package/dist-lib/components/klanten/FloridayDeeplinkButton.d.ts +8 -0
- package/dist-lib/components/klanten/FloridayDeeplinkButton.d.ts.map +1 -0
- package/dist-lib/components/klanten/FloridayDeeplinkButton.js +9 -0
- package/dist-lib/components/klanten/GroupedKlantDetail.d.ts.map +1 -1
- package/dist-lib/components/klanten/GroupedKlantDetail.js +19 -5
- package/dist-lib/components/klanten/ImportKlanten.d.ts.map +1 -1
- package/dist-lib/components/klanten/ImportKlanten.js +3 -2
- package/dist-lib/components/klanten/KlantDetail.d.ts.map +1 -1
- package/dist-lib/components/klanten/KlantDetail.js +9 -3
- package/dist-lib/components/klanten/KlantenOverzicht.d.ts.map +1 -1
- package/dist-lib/components/klanten/KlantenOverzicht.js +9 -6
- package/dist-lib/components/klanten/NetwerkPagina.d.ts.map +1 -1
- package/dist-lib/components/klanten/NetwerkPagina.js +21 -18
- package/dist-lib/components/klanten/NieuweKlant.d.ts.map +1 -1
- package/dist-lib/components/klanten/NieuweKlant.js +23 -8
- package/dist-lib/components/klanten/PriceGroupBadges.d.ts +7 -0
- package/dist-lib/components/klanten/PriceGroupBadges.d.ts.map +1 -0
- package/dist-lib/components/klanten/PriceGroupBadges.js +13 -0
- package/dist-lib/components/klanten/SyncStatusChip.d.ts +4 -0
- package/dist-lib/components/klanten/SyncStatusChip.d.ts.map +1 -0
- package/dist-lib/components/klanten/SyncStatusChip.js +49 -0
- package/dist-lib/components/klanten/pricegroups/CustomerPickerDialog.d.ts +8 -0
- package/dist-lib/components/klanten/pricegroups/CustomerPickerDialog.d.ts.map +1 -0
- package/dist-lib/components/klanten/pricegroups/CustomerPickerDialog.js +75 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupFormPage.d.ts +4 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupFormPage.d.ts.map +1 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupFormPage.js +269 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupsPage.d.ts +2 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupsPage.d.ts.map +1 -0
- package/dist-lib/components/klanten/pricegroups/PriceGroupsPage.js +133 -0
- package/dist-lib/components/klanten/pricegroups/ProductPickerDialog.d.ts +8 -0
- package/dist-lib/components/klanten/pricegroups/ProductPickerDialog.d.ts.map +1 -0
- package/dist-lib/components/klanten/pricegroups/ProductPickerDialog.js +18 -0
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +6 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1684 -93
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1684 -93
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.js +4 -3
- package/dist-lib/integrations/supabase/client.server.d.ts +1684 -93
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1712 -72
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +3 -9
- package/dist-lib/lib/accounting/twinfield/client.server.d.ts +21 -0
- package/dist-lib/lib/accounting/twinfield/client.server.d.ts.map +1 -0
- package/dist-lib/lib/accounting/twinfield/client.server.js +171 -0
- package/dist-lib/lib/accounting/twinfield/mapping.d.ts +46 -0
- package/dist-lib/lib/accounting/twinfield/mapping.d.ts.map +1 -0
- package/dist-lib/lib/accounting/twinfield/mapping.js +121 -0
- package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts +38814 -0
- package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts.map +1 -0
- package/dist-lib/lib/accounting/twinfield/worker.functions.js +48 -0
- package/dist-lib/lib/accounting/twinfield/worker.server.d.ts +12 -0
- package/dist-lib/lib/accounting/twinfield/worker.server.d.ts.map +1 -0
- package/dist-lib/lib/accounting/twinfield/worker.server.js +124 -0
- package/dist-lib/lib/accounting.functions.d.ts +4806 -33
- package/dist-lib/lib/accounting.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-analytics.functions.d.ts +1684 -93
- package/dist-lib/lib/customer-analytics.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-schemas.d.ts +2 -0
- package/dist-lib/lib/customer-schemas.d.ts.map +1 -1
- package/dist-lib/lib/customer-schemas.js +1 -0
- package/dist-lib/lib/customers.functions.d.ts +25793 -163
- package/dist-lib/lib/customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/customers.functions.js +92 -4
- package/dist-lib/lib/delivery-locations.functions.d.ts +6408 -44
- package/dist-lib/lib/delivery-locations.functions.d.ts.map +1 -1
- package/dist-lib/lib/external-customers.functions.d.ts +6408 -44
- package/dist-lib/lib/external-customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-assortment.functions.d.ts +12959 -0
- package/dist-lib/lib/floriday-assortment.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-assortment.functions.js +213 -0
- package/dist-lib/lib/floriday-discounts.functions.d.ts +3398 -216
- package/dist-lib/lib/floriday-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-trade-items.functions.d.ts +12943 -0
- package/dist-lib/lib/floriday-trade-items.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-trade-items.functions.js +107 -0
- package/dist-lib/lib/local-discounts.functions.d.ts +11216 -79
- package/dist-lib/lib/local-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/overdue-invoices.functions.d.ts +1684 -93
- package/dist-lib/lib/overdue-invoices.functions.d.ts.map +1 -1
- package/dist-lib/lib/price-groups-local.functions.d.ts +90665 -0
- package/dist-lib/lib/price-groups-local.functions.d.ts.map +1 -0
- package/dist-lib/lib/price-groups-local.functions.js +148 -0
- package/dist-lib/lib/price-groups.functions.d.ts +12952 -0
- package/dist-lib/lib/price-groups.functions.d.ts.map +1 -0
- package/dist-lib/lib/price-groups.functions.js +115 -0
- package/dist-lib/lib/pricing.d.ts +24 -0
- package/dist-lib/lib/pricing.d.ts.map +1 -0
- package/dist-lib/lib/pricing.js +60 -0
- package/package.json +8 -4
- package/public/flowselections-assets/Klanten/floriday-logo.png +0 -0
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
|
|
3
3
|
import { customerCreateSchema, customerUpdateSchema, listFiltersSchema, customerImportSchema, } from "./customer-schemas";
|
|
4
|
+
import { buildPriceGroupsMap } from "./price-groups.functions";
|
|
5
|
+
function checkTwinfieldReady(draft) {
|
|
6
|
+
const missing = [];
|
|
7
|
+
if (!draft.company_name?.trim())
|
|
8
|
+
missing.push("bedrijfsnaam");
|
|
9
|
+
if (!draft.email?.trim())
|
|
10
|
+
missing.push("e-mailadres");
|
|
11
|
+
if (!draft.street?.trim())
|
|
12
|
+
missing.push("straat");
|
|
13
|
+
if (!draft.house_number?.trim())
|
|
14
|
+
missing.push("huisnummer");
|
|
15
|
+
if (!draft.postal_code?.trim())
|
|
16
|
+
missing.push("postcode");
|
|
17
|
+
if (!draft.city?.trim())
|
|
18
|
+
missing.push("plaats");
|
|
19
|
+
if (!draft.country?.trim())
|
|
20
|
+
missing.push("land");
|
|
21
|
+
if (missing.length > 0) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
reason: `Deze klant kan nog niet naar Twinfield: de volgende gegevens ontbreken — ${missing.join(", ")}. Vul deze aan en probeer opnieuw.`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (draft.vat_number && draft.vat_number.trim().length < 4) {
|
|
28
|
+
return { ok: false, reason: "Het BTW-nummer lijkt onvolledig. Controleer het formaat en probeer opnieuw." };
|
|
29
|
+
}
|
|
30
|
+
return { ok: true };
|
|
31
|
+
}
|
|
32
|
+
async function getActiveTwinfieldConnection(supabase) {
|
|
33
|
+
const { data } = await supabase
|
|
34
|
+
.from("twinfield_connections")
|
|
35
|
+
.select("id, office_code, company_code, is_active")
|
|
36
|
+
.eq("is_active", true)
|
|
37
|
+
.order("connected_at", { ascending: false })
|
|
38
|
+
.limit(1)
|
|
39
|
+
.maybeSingle();
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
export const precheckTwinfieldPush = createServerFn({ method: "POST" })
|
|
43
|
+
.middleware([requireSupabaseAuth])
|
|
44
|
+
.inputValidator((input) => input)
|
|
45
|
+
.handler(async ({ data, context }) => {
|
|
46
|
+
const conn = await getActiveTwinfieldConnection(context.supabase);
|
|
47
|
+
if (!conn) {
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
reason: "Er is nog geen actieve Twinfield-koppeling ingesteld. Koppel eerst Twinfield in de instellingen en probeer daarna opnieuw.",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const result = checkTwinfieldReady(data.draft ?? {});
|
|
54
|
+
return result.ok ? { ok: true } : { ok: false, reason: result.reason };
|
|
55
|
+
});
|
|
4
56
|
const OPTIONAL_TEXT_FIELDS = [
|
|
5
57
|
"vat_number", "contact_person", "phone", "postal_code", "city",
|
|
6
58
|
"customer_class", "notes", "customer_number", "language", "website",
|
|
@@ -60,7 +112,18 @@ export const listCustomers = createServerFn({ method: "POST" })
|
|
|
60
112
|
const { data: rows, error } = await q.limit(500);
|
|
61
113
|
if (error)
|
|
62
114
|
throw new Error(error.message);
|
|
63
|
-
|
|
115
|
+
const list = rows ?? [];
|
|
116
|
+
const orgIds = list
|
|
117
|
+
.map((r) => r.floriday_organization_id)
|
|
118
|
+
.filter((v) => typeof v === "string" && !!v);
|
|
119
|
+
const priceGroupsByOrg = await buildPriceGroupsMap(supabase, orgIds);
|
|
120
|
+
const enriched = list.map((r) => ({
|
|
121
|
+
...r,
|
|
122
|
+
price_groups: r.floriday_organization_id
|
|
123
|
+
? priceGroupsByOrg[r.floriday_organization_id] ?? []
|
|
124
|
+
: [],
|
|
125
|
+
}));
|
|
126
|
+
return { customers: enriched };
|
|
64
127
|
});
|
|
65
128
|
export const getCustomer = createServerFn({ method: "POST" })
|
|
66
129
|
.middleware([requireSupabaseAuth])
|
|
@@ -107,14 +170,20 @@ export const getCustomer = createServerFn({ method: "POST" })
|
|
|
107
170
|
.eq("customer_id", data.id)
|
|
108
171
|
.order("order_date", { ascending: false })
|
|
109
172
|
.limit(25);
|
|
173
|
+
const priceGroups = customer.floriday_organization_id
|
|
174
|
+
? (await buildPriceGroupsMap(supabase, [
|
|
175
|
+
customer.floriday_organization_id,
|
|
176
|
+
]))[customer.floriday_organization_id] ?? []
|
|
177
|
+
: [];
|
|
110
178
|
return {
|
|
111
|
-
customer,
|
|
179
|
+
customer: { ...customer, price_groups: priceGroups },
|
|
112
180
|
audit: audit ?? [],
|
|
113
181
|
orders: orders ?? [],
|
|
114
182
|
contacts: contacts ?? [],
|
|
115
183
|
delivery_locations: deliveryLocations ?? [],
|
|
116
184
|
trade_settings: tradeSettings ?? [],
|
|
117
185
|
assortment: assortment ?? [],
|
|
186
|
+
price_groups: priceGroups,
|
|
118
187
|
};
|
|
119
188
|
});
|
|
120
189
|
async function findDuplicates(supabase, input) {
|
|
@@ -169,7 +238,20 @@ export const createCustomer = createServerFn({ method: "POST" })
|
|
|
169
238
|
.single();
|
|
170
239
|
if (error)
|
|
171
240
|
throw new Error(error.message);
|
|
172
|
-
|
|
241
|
+
// De DB-trigger `customers_enqueue_twinfield_push` plaatst automatisch een
|
|
242
|
+
// rij in twinfield_push_queue zodra er een actieve koppeling is; we hoeven
|
|
243
|
+
// hier zelf niets meer te enqueue'en.
|
|
244
|
+
let twinfieldQueued = false;
|
|
245
|
+
if (inserted) {
|
|
246
|
+
const { data: q } = await supabase
|
|
247
|
+
.from("twinfield_push_queue")
|
|
248
|
+
.select("id")
|
|
249
|
+
.eq("customer_id", inserted.id)
|
|
250
|
+
.limit(1)
|
|
251
|
+
.maybeSingle();
|
|
252
|
+
twinfieldQueued = !!q;
|
|
253
|
+
}
|
|
254
|
+
return { customer: inserted, duplicates: [], twinfieldQueued };
|
|
173
255
|
});
|
|
174
256
|
export const updateCustomer = createServerFn({ method: "POST" })
|
|
175
257
|
.middleware([requireSupabaseAuth])
|
|
@@ -232,7 +314,12 @@ export const listFloridayNetwork = createServerFn({ method: "POST" })
|
|
|
232
314
|
const { data: rows, error, count } = await q;
|
|
233
315
|
if (error)
|
|
234
316
|
throw new Error(error.message);
|
|
235
|
-
const
|
|
317
|
+
const rawRows = rows ?? [];
|
|
318
|
+
const orgIds = rawRows
|
|
319
|
+
.map((r) => r.organization_id)
|
|
320
|
+
.filter((v) => typeof v === "string" && !!v);
|
|
321
|
+
const priceGroupsByOrg = await buildPriceGroupsMap(context.supabase, orgIds);
|
|
322
|
+
const organizations = rawRows.map((r) => {
|
|
236
323
|
const d = (r.data ?? {});
|
|
237
324
|
const physical = d.physicalAddress ?? {};
|
|
238
325
|
const mailing = d.mailingAddress ?? {};
|
|
@@ -259,6 +346,7 @@ export const listFloridayNetwork = createServerFn({ method: "POST" })
|
|
|
259
346
|
end_date: endDate,
|
|
260
347
|
is_expired: isExpired,
|
|
261
348
|
fetched_at: r.fetched_at,
|
|
349
|
+
price_groups: r.organization_id ? priceGroupsByOrg[r.organization_id] ?? [] : [],
|
|
262
350
|
};
|
|
263
351
|
});
|
|
264
352
|
organizations.sort((a, b) => {
|