@flowselections/floriday-klanten-module 1.0.15 → 1.0.16
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 +6 -3
- 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 +762 -3
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +762 -3
- 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 +762 -3
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +789 -8
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- 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 +109 -0
- package/dist-lib/lib/accounting/twinfield/worker.functions.d.ts +36318 -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 +2286 -9
- package/dist-lib/lib/accounting.functions.d.ts.map +1 -1
- package/dist-lib/lib/customer-analytics.functions.d.ts +762 -3
- 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 +18241 -99
- 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 +3048 -12
- package/dist-lib/lib/delivery-locations.functions.d.ts.map +1 -1
- package/dist-lib/lib/external-customers.functions.d.ts +3048 -12
- package/dist-lib/lib/external-customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-assortment.functions.d.ts +12127 -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 +1800 -282
- package/dist-lib/lib/floriday-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-trade-items.functions.d.ts +12111 -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 +5336 -23
- package/dist-lib/lib/local-discounts.functions.d.ts.map +1 -1
- package/dist-lib/lib/overdue-invoices.functions.d.ts +762 -3
- package/dist-lib/lib/overdue-invoices.functions.d.ts.map +1 -1
- package/dist-lib/lib/price-groups-local.functions.d.ts +84841 -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 +12120 -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 +6 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { supabaseAdmin } from "../../../integrations/supabase/client.server";
|
|
2
|
+
import { loadActiveConnection, sendProcessXml } from "./client.server";
|
|
3
|
+
import { buildCustomerDimensionXml } from "./mapping";
|
|
4
|
+
const BACKOFF_MINUTES = [1, 5, 30, 120, 360];
|
|
5
|
+
const MAX_ATTEMPTS = 6;
|
|
6
|
+
export async function runTwinfieldPushQueueInternal(limit = 25) {
|
|
7
|
+
const result = { claimed: 0, succeeded: 0, failed: 0, skipped: 0, errors: [] };
|
|
8
|
+
const { data: batch, error } = await supabaseAdmin.rpc("claim_twinfield_push_batch", { _limit: limit });
|
|
9
|
+
if (error)
|
|
10
|
+
throw new Error(error.message);
|
|
11
|
+
const rows = (batch ?? []);
|
|
12
|
+
result.claimed = rows.length;
|
|
13
|
+
if (rows.length === 0)
|
|
14
|
+
return result;
|
|
15
|
+
const conn = await loadActiveConnection(rows[0].connection_id);
|
|
16
|
+
if (!conn) {
|
|
17
|
+
// Zet alles terug op pending — er is momenteel geen bruikbare koppeling
|
|
18
|
+
for (const row of rows) {
|
|
19
|
+
await markFailed(row.id, row.attempts, "Geen actieve Twinfield-koppeling gevonden.");
|
|
20
|
+
result.failed += 1;
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
for (const row of rows) {
|
|
25
|
+
try {
|
|
26
|
+
if (!row.customer_id) {
|
|
27
|
+
await markSuccess(row.id, null);
|
|
28
|
+
result.skipped += 1;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const { data: customer, error: cErr } = await supabaseAdmin
|
|
32
|
+
.from("customers")
|
|
33
|
+
.select("*")
|
|
34
|
+
.eq("id", row.customer_id)
|
|
35
|
+
.maybeSingle();
|
|
36
|
+
if (cErr)
|
|
37
|
+
throw new Error(cErr.message);
|
|
38
|
+
if (!customer) {
|
|
39
|
+
await markSuccess(row.id, null);
|
|
40
|
+
result.skipped += 1;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
// Autogenerate klantcode indien nodig
|
|
44
|
+
let code = customer.twinfield_code;
|
|
45
|
+
if (!code) {
|
|
46
|
+
const { data: gen, error: gErr } = await supabaseAdmin.rpc("next_twinfield_code");
|
|
47
|
+
if (gErr)
|
|
48
|
+
throw new Error(gErr.message);
|
|
49
|
+
code = gen;
|
|
50
|
+
await supabaseAdmin
|
|
51
|
+
.from("customers")
|
|
52
|
+
.update({ twinfield_code: code })
|
|
53
|
+
.eq("id", row.customer_id);
|
|
54
|
+
}
|
|
55
|
+
const input = { ...customer, twinfield_code: code };
|
|
56
|
+
const { xml, hash } = buildCustomerDimensionXml(input, row.office_code || conn.office_code || conn.company_code || "");
|
|
57
|
+
if (row.action === "update" && customer.twinfield_last_hash === hash) {
|
|
58
|
+
await markSuccess(row.id, code);
|
|
59
|
+
result.skipped += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
await sendProcessXml(conn, xml);
|
|
63
|
+
await supabaseAdmin
|
|
64
|
+
.from("customers")
|
|
65
|
+
.update({
|
|
66
|
+
twinfield_code: code,
|
|
67
|
+
twinfield_synced_at: new Date().toISOString(),
|
|
68
|
+
twinfield_last_hash: hash,
|
|
69
|
+
twinfield_sync_error: null,
|
|
70
|
+
})
|
|
71
|
+
.eq("id", row.customer_id);
|
|
72
|
+
await markSuccess(row.id, code);
|
|
73
|
+
result.succeeded += 1;
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
77
|
+
await markFailed(row.id, row.attempts, msg);
|
|
78
|
+
if (row.customer_id) {
|
|
79
|
+
await supabaseAdmin
|
|
80
|
+
.from("customers")
|
|
81
|
+
.update({ twinfield_sync_error: msg })
|
|
82
|
+
.eq("id", row.customer_id);
|
|
83
|
+
}
|
|
84
|
+
result.failed += 1;
|
|
85
|
+
result.errors.push({ queueId: row.id, message: msg });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
async function markSuccess(id, externalId) {
|
|
91
|
+
await supabaseAdmin
|
|
92
|
+
.from("twinfield_push_queue")
|
|
93
|
+
.update({
|
|
94
|
+
status: "success",
|
|
95
|
+
external_id: externalId,
|
|
96
|
+
last_error: null,
|
|
97
|
+
updated_at: new Date().toISOString(),
|
|
98
|
+
})
|
|
99
|
+
.eq("id", id);
|
|
100
|
+
}
|
|
101
|
+
async function markFailed(id, prevAttempts, message) {
|
|
102
|
+
const attempts = prevAttempts + 1;
|
|
103
|
+
const dead = attempts >= MAX_ATTEMPTS;
|
|
104
|
+
const delayMin = BACKOFF_MINUTES[Math.min(attempts - 1, BACKOFF_MINUTES.length - 1)];
|
|
105
|
+
await supabaseAdmin
|
|
106
|
+
.from("twinfield_push_queue")
|
|
107
|
+
.update({
|
|
108
|
+
status: dead ? "dead" : "failed",
|
|
109
|
+
attempts,
|
|
110
|
+
next_attempt_at: dead
|
|
111
|
+
? new Date().toISOString()
|
|
112
|
+
: new Date(Date.now() + delayMin * 60000).toISOString(),
|
|
113
|
+
last_error: message.slice(0, 2000),
|
|
114
|
+
updated_at: new Date().toISOString(),
|
|
115
|
+
})
|
|
116
|
+
.eq("id", id);
|
|
117
|
+
// Bij tijdelijke fout: verplaats terug naar pending voor retry via next_attempt_at
|
|
118
|
+
if (!dead) {
|
|
119
|
+
await supabaseAdmin
|
|
120
|
+
.from("twinfield_push_queue")
|
|
121
|
+
.update({ status: "pending" })
|
|
122
|
+
.eq("id", id);
|
|
123
|
+
}
|
|
124
|
+
}
|