@flowselections/floriday-voorraad 1.0.86 → 1.0.87

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=floriday-fetch-status.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floriday-fetch-status.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/floriday-fetch-status.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { fetchState, fetchStateBlocksTakeover } from "../floriday-fetch-status.js";
3
+ const row = (t, done, ok) => ({
4
+ backfill_target_sequence: t, backfill_done_at: done, last_success_at: ok,
5
+ });
6
+ describe("ophaalstatus artikelen", () => {
7
+ it("lopend ophalen blokkeert overnemen", () => {
8
+ expect(fetchState(row(500, null, "2026-10-20"), 120)).toBe("bezig");
9
+ expect(fetchStateBlocksTakeover(fetchState(row(500, null, null), 0))).toBe(true);
10
+ });
11
+ it("nog nooit gestart blokkeert overnemen", () => {
12
+ expect(fetchState(null, 0)).toBe("nooit_gestart");
13
+ expect(fetchState(row(null, null, null), 0)).toBe("nooit_gestart");
14
+ expect(fetchStateBlocksTakeover("nooit_gestart")).toBe(true);
15
+ });
16
+ it("na afloop met lege target komt de knop vrij", () => {
17
+ expect(fetchState(row(null, "2026-10-20", "2026-10-20"), 50)).toBe("compleet");
18
+ expect(fetchState(row(500, "2026-10-20", "2026-10-20"), 50)).toBe("compleet");
19
+ expect(fetchStateBlocksTakeover(fetchState(row(null, null, "2026-10-20"), 0))).toBe(false);
20
+ });
21
+ it("koppeling van vóór 1.0.95 zonder backfill is compleet", () => {
22
+ expect(fetchState(row(null, null, "2026-09-01"), 300)).toBe("compleet");
23
+ expect(fetchState(null, 300)).toBe("compleet");
24
+ });
25
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Ophaalstatus van Floriday-authenticatie (floriday_sync_state) per entiteit.
3
+ * Dezelfde regel staat in de database (floriday_takeover_fetch_state); houd ze gelijk.
4
+ * - bezig: backfill_target_sequence gevuld én backfill_done_at leeg
5
+ * - nooit gestart: geen statusrij én geen gegevens in de cache, of een rij zonder
6
+ * enige geslaagde ophaling en zonder gegevens
7
+ * - compleet: al het andere (ook target leeg na afloop, of koppeling van vóór 1.0.95)
8
+ */
9
+ export type FetchStateRow = {
10
+ backfill_target_sequence: number | null;
11
+ backfill_done_at: string | null;
12
+ last_success_at: string | null;
13
+ } | null;
14
+ export type FetchState = "bezig" | "nooit_gestart" | "compleet";
15
+ export declare function fetchState(row: FetchStateRow, cachedCount: number): FetchState;
16
+ export declare function fetchStateBlocksTakeover(s: FetchState): boolean;
17
+ //# sourceMappingURL=floriday-fetch-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floriday-fetch-status.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-fetch-status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,GAAG,IAAI,CAAC;AAET,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,eAAe,GAAG,UAAU,CAAC;AAEhE,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAM9E;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAE/D"}
@@ -0,0 +1,14 @@
1
+ export function fetchState(row, cachedCount) {
2
+ if (row && row.backfill_target_sequence != null && !row.backfill_done_at)
3
+ return "bezig";
4
+ if (cachedCount > 0)
5
+ return "compleet";
6
+ if (!row)
7
+ return "nooit_gestart";
8
+ if (row.backfill_done_at || row.last_success_at)
9
+ return "compleet";
10
+ return "nooit_gestart";
11
+ }
12
+ export function fetchStateBlocksTakeover(s) {
13
+ return s !== "compleet";
14
+ }
@@ -1,3 +1,4 @@
1
+ import { type FetchState } from "./floriday-fetch-status.js";
1
2
  export type TakeoverRow = {
2
3
  tradeItemId: string;
3
4
  name: string;
@@ -31,6 +32,16 @@ export type TakeoverRow = {
31
32
  supply_lines: number;
32
33
  customer_offers: number;
33
34
  };
35
+ customerOffers: CustomerOfferView[];
36
+ };
37
+ export type CustomerOfferView = {
38
+ id: string;
39
+ customer: string | null;
40
+ price: number | null;
41
+ currency: string | null;
42
+ pieces: number | null;
43
+ from: string | null;
44
+ to: string | null;
34
45
  };
35
46
  export declare const getFloridayTakeoverPreview: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
36
47
  supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
@@ -44,6 +55,11 @@ export declare const getFloridayTakeoverPreview: import("@tanstack/start-client-
44
55
  week: number;
45
56
  }[];
46
57
  weekError: string | null;
58
+ fetchStatus: {
59
+ tradeItems: FetchState;
60
+ catalogPrices: FetchState;
61
+ customerOffers: FetchState;
62
+ };
47
63
  rows: TakeoverRow[];
48
64
  }>>;
49
65
  //# sourceMappingURL=floriday-takeover.functions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"floriday-takeover.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-takeover.functions.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE;QACL,UAAU,EAAE,OAAO,CAAC;QACpB,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;QACpC,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACjF,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAmBF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;GA8InC,CAAC"}
1
+ {"version":3,"file":"floriday-takeover.functions.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-takeover.functions.ts"],"names":[],"mappings":"AAeA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE;QACL,UAAU,EAAE,OAAO,CAAC;QACpB,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;QACpC,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACjF,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,cAAc,EAAE,iBAAiB,EAAE,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB,CAAC;AA2CF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;oBAmFF,UAAU;uBAAiB,UAAU;wBAAkB,UAAU;;;GAgFlG,CAAC"}
@@ -13,6 +13,31 @@
13
13
  */
14
14
  import { createServerFn } from "@tanstack/react-start";
15
15
  import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
16
+ import { fetchState } from "./floriday-fetch-status.js";
17
+ function offerView(id, d) {
18
+ const pr = d?.pricePerPiece ?? d?.price ?? null;
19
+ const price = typeof pr === "number" ? pr : pr?.value != null ? Number(pr.value) : null;
20
+ const orgs = d?.customerOrganizationIds ?? (d?.customerOrganizationId ? [d.customerOrganizationId] : []);
21
+ return {
22
+ id,
23
+ customer: d?.customerOrganizationName ?? (Array.isArray(orgs) && orgs.length ? orgs.join(", ") : null),
24
+ price: Number.isFinite(price) ? price : null,
25
+ currency: pr?.currency ?? d?.currency ?? null,
26
+ pieces: d?.numberOfPieces != null ? Number(d.numberOfPieces) : d?.availableNumberOfPieces != null ? Number(d.availableNumberOfPieces) : null,
27
+ from: d?.period?.startDateTime ?? d?.startDateTime ?? d?.validFrom ?? null,
28
+ to: d?.period?.endDateTime ?? d?.endDateTime ?? d?.validTo ?? null,
29
+ };
30
+ }
31
+ function offerTradeItems(d) {
32
+ const ids = new Set();
33
+ if (d?.tradeItemId)
34
+ ids.add(String(d.tradeItemId).toLowerCase());
35
+ for (const l of Array.isArray(d?.lines) ? d.lines : Array.isArray(d?.tradeItems) ? d.tradeItems : []) {
36
+ if (l?.tradeItemId)
37
+ ids.add(String(l.tradeItemId).toLowerCase());
38
+ }
39
+ return [...ids];
40
+ }
16
41
  function isoWeek(d) {
17
42
  const t = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
18
43
  const day = t.getUTCDay() || 7;
@@ -38,15 +63,18 @@ export const getFloridayTakeoverPreview = createServerFn({ method: "POST" })
38
63
  const conn = await resolveActiveFloridayConnection(context.supabase);
39
64
  const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
40
65
  const admin = supabaseAdmin;
41
- const [items, products, stock, cont, catalog, lines] = await Promise.all([
66
+ const nowIso = new Date().toISOString();
67
+ const [items, products, stock, cont, catalog, lines, syncRows, offers] = await Promise.all([
42
68
  admin.from("floriday_trade_items_cache").select("floriday_id, data").eq("connection_id", conn.id).eq("is_deleted", false).limit(5000),
43
69
  admin.from("products").select("id, product, barcode, article_number, floriday_trade_item_id, sale_price").limit(10000),
44
70
  admin.from("trade_item_stock").select("trade_item_key, physical_stock").eq("connection_id", conn.id).limit(20000),
45
71
  admin.from("floriday_continuous_stock_cache").select("trade_item_id, number_of_pieces").eq("connection_id", conn.id).limit(5000),
46
- admin.from("floriday_catalog_prices_cache").select("trade_item_id, price, updated_at").eq("connection_id", conn.id).eq("is_deleted", false).order("updated_at", { ascending: false }).limit(20000),
72
+ admin.from("floriday_catalog_prices_cache").select("trade_item_id, price, updated_at").eq("connection_id", conn.id).eq("is_deleted", false).or(`valid_to.is.null,valid_to.gte.${nowIso}`).order("updated_at", { ascending: false }).limit(20000),
47
73
  admin.from("trade_item_supply_lines").select("trade_item_id, supply_type, price_per_piece, updated_at").eq("connection_id", conn.id).order("updated_at", { ascending: false }).limit(20000),
74
+ admin.from("floriday_sync_state").select("entity_type, backfill_target_sequence, backfill_done_at, last_success_at").eq("connection_id", conn.id).in("entity_type", ["trade-items", "catalog-prices", "customer-offers"]),
75
+ admin.from("floriday_customer_offers_cache").select("floriday_id, data").eq("connection_id", conn.id).eq("is_deleted", false).limit(5000),
48
76
  ]);
49
- for (const r of [items, products, stock, cont, catalog, lines])
77
+ for (const r of [items, products, stock, cont, catalog, lines, syncRows, offers])
50
78
  if (r.error)
51
79
  throw new Error(r.error.message);
52
80
  // Weekaanbod: huidige en twee komende weken, live gelezen (1 per seconde).
@@ -108,6 +136,22 @@ export const getFloridayTakeoverPreview = createServerFn({ method: "POST" })
108
136
  }
109
137
  lineBy.set(k, cur);
110
138
  }
139
+ const syncBy = new Map();
140
+ for (const r of syncRows.data ?? [])
141
+ syncBy.set(String(r.entity_type), r);
142
+ const offersBy = new Map();
143
+ for (const o of offers.data ?? []) {
144
+ for (const tid of offerTradeItems(o.data)) {
145
+ const arr = offersBy.get(tid) ?? [];
146
+ arr.push(offerView(String(o.floriday_id), o.data));
147
+ offersBy.set(tid, arr);
148
+ }
149
+ }
150
+ const fetchStatus = {
151
+ tradeItems: fetchState(syncBy.get("trade-items") ?? null, (items.data ?? []).length),
152
+ catalogPrices: fetchState(syncBy.get("catalog-prices") ?? null, (catalog.data ?? []).length),
153
+ customerOffers: fetchState(syncBy.get("customer-offers") ?? null, (offers.data ?? []).length),
154
+ };
111
155
  const cur = weeks[0];
112
156
  const rows = (items.data ?? []).map((it) => {
113
157
  const fid = String(it.floriday_id).toLowerCase();
@@ -170,8 +214,9 @@ export const getFloridayTakeoverPreview = createServerFn({ method: "POST" })
170
214
  weekly: w.length > 0,
171
215
  weeks: w.map(({ year, week, pieces, available }) => ({ year, week, pieces, available })),
172
216
  supply_lines: line.count,
173
- customer_offers: line.customer,
217
+ customer_offers: (offersBy.get(fid) ?? []).length || line.customer,
174
218
  },
219
+ customerOffers: offersBy.get(fid) ?? [],
175
220
  };
176
221
  });
177
222
  rows.sort((a, b) => a.name.localeCompare(b.name, "nl"));
@@ -180,6 +225,7 @@ export const getFloridayTakeoverPreview = createServerFn({ method: "POST" })
180
225
  environment: conn.environment ?? null,
181
226
  weeks,
182
227
  weekError,
228
+ fetchStatus,
183
229
  rows,
184
230
  };
185
231
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/floriday-voorraad",
3
- "version": "1.0.86",
3
+ "version": "1.0.87",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "main": "./dist-lib/index.js",