nodebb-plugin-equipment-calendar 0.8.2 → 0.8.6
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/library.js +60 -19
- package/package.json +1 -1
- package/plugin.json +1 -1
package/library.js
CHANGED
|
@@ -207,38 +207,75 @@ function isCheckoutPaid(checkout) {
|
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
|
|
210
211
|
async function fetchHelloAssoItems(settings) {
|
|
211
212
|
const org = String(settings.ha_organizationSlug || '').trim();
|
|
212
213
|
const formType = String(settings.ha_itemsFormType || '').trim();
|
|
213
214
|
const formSlug = String(settings.ha_itemsFormSlug || '').trim();
|
|
214
215
|
if (!org || !formType || !formSlug) return [];
|
|
215
216
|
|
|
217
|
+
const token = await getHelloAssoAccessToken(settings);
|
|
218
|
+
const base = (String(settings.ha_apiBaseUrl || '').trim() || 'https://api.helloasso.com').replace(/\/$/, '');
|
|
216
219
|
const cacheKey = `equipmentCalendar:ha:items:${org}:${formType}:${formSlug}`;
|
|
217
|
-
|
|
220
|
+
|
|
221
|
+
// Cache 10 minutes
|
|
222
|
+
const cached = await db.getObject(cacheKey);
|
|
218
223
|
const now = Date.now();
|
|
219
|
-
if (
|
|
220
|
-
try {
|
|
221
|
-
return JSON.parse(cache.payload);
|
|
222
|
-
} catch (e) {}
|
|
224
|
+
if (cached && cached.itemsJson && cached.expMs && now < parseInt(cached.expMs, 10)) {
|
|
225
|
+
try { return JSON.parse(cached.itemsJson); } catch (e) {}
|
|
223
226
|
}
|
|
224
227
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
// IMPORTANT:
|
|
229
|
+
// - /forms/.../items = "articles vendus" (liés aux commandes) => peut renvoyer 0 si aucune commande
|
|
230
|
+
// - /forms/.../public = données publiques détaillées => contient la structure (tiers / products) du formulaire
|
|
231
|
+
const publicUrl = `${base}/v5/organizations/${encodeURIComponent(org)}/forms/${encodeURIComponent(formType)}/${encodeURIComponent(formSlug)}/public`;
|
|
232
|
+
const resp = await fetchFn(publicUrl, { headers: { authorization: `Bearer ${token}`, accept: 'application/json' } });
|
|
228
233
|
if (!resp.ok) {
|
|
229
234
|
const t = await resp.text();
|
|
230
|
-
throw new Error(`HelloAsso
|
|
235
|
+
throw new Error(`HelloAsso public form error: ${resp.status} ${t}`);
|
|
236
|
+
}
|
|
237
|
+
const data = await resp.json();
|
|
238
|
+
|
|
239
|
+
// Extract catalog items:
|
|
240
|
+
// structure differs by formType; common pattern: data.tiers[] or data.tiers[].products[] / items[]
|
|
241
|
+
const out = [];
|
|
242
|
+
const tiers = (data && (data.tiers || data.tiersList || data.prices || data.priceCategories)) || [];
|
|
243
|
+
const tierArr = Array.isArray(tiers) ? tiers : [];
|
|
244
|
+
|
|
245
|
+
function pushItem(it, tierName) {
|
|
246
|
+
if (!it) return;
|
|
247
|
+
const id = String(it.id || it.itemId || it.reference || it.slug || it.code || it.name || '').trim();
|
|
248
|
+
const name = String(it.name || it.label || it.title || '').trim() || (tierName ? String(tierName) : id);
|
|
249
|
+
if (!id || !name) return;
|
|
250
|
+
const amount = it.amount || it.price || it.unitPrice || it.totalAmount || it.initialAmount;
|
|
251
|
+
const priceCents = (typeof amount === 'number' ? amount : parseInt(amount, 10)) || 0;
|
|
252
|
+
out.push({ id, name, priceCents: String(priceCents), location: '' });
|
|
231
253
|
}
|
|
232
|
-
const json = await resp.json();
|
|
233
|
-
// API responses are usually { data: [...] } but keep it flexible
|
|
234
|
-
const list = Array.isArray(json) ? json : (Array.isArray(json.data) ? json.data : []);
|
|
235
254
|
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
255
|
+
// Try a few known layouts
|
|
256
|
+
for (const t of tierArr) {
|
|
257
|
+
const tierName = t && (t.name || t.label || t.title);
|
|
258
|
+
const products = (t && (t.items || t.products || t.prices || t.options)) || [];
|
|
259
|
+
const arr = Array.isArray(products) ? products : [];
|
|
260
|
+
if (arr.length) {
|
|
261
|
+
arr.forEach(p => pushItem(p, tierName));
|
|
262
|
+
} else {
|
|
263
|
+
// sometimes tier itself is the product
|
|
264
|
+
pushItem(t, tierName);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Fallback: some forms expose items directly
|
|
269
|
+
if (!out.length && data && Array.isArray(data.items)) {
|
|
270
|
+
data.items.forEach(p => pushItem(p, ''));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
await db.setObject(cacheKey, {
|
|
274
|
+
itemsJson: JSON.stringify(out),
|
|
275
|
+
expMs: String(Date.now() + 10 * 60 * 1000),
|
|
276
|
+
});
|
|
240
277
|
|
|
241
|
-
return
|
|
278
|
+
return out;
|
|
242
279
|
}
|
|
243
280
|
|
|
244
281
|
function parseItems(itemsJson) {
|
|
@@ -794,6 +831,8 @@ async function handleHelloAssoTest(req, res) {
|
|
|
794
831
|
if (!isAdmin) return helpers.notAllowed(req, res);
|
|
795
832
|
|
|
796
833
|
const settings = await getSettings();
|
|
834
|
+
let sampleItems = [];
|
|
835
|
+
let hasSampleItems = false;
|
|
797
836
|
let ok = false;
|
|
798
837
|
let message = '';
|
|
799
838
|
let count = 0;
|
|
@@ -807,13 +846,14 @@ async function handleHelloAssoTest(req, res) {
|
|
|
807
846
|
const items = await fetchHelloAssoItems(settings);
|
|
808
847
|
const list = Array.isArray(items) ? items : (Array.isArray(items.data) ? items.data : []);
|
|
809
848
|
count = list.length;
|
|
810
|
-
|
|
849
|
+
sampleItems = list.slice(0, 10).map(it => ({
|
|
811
850
|
id: String(it.id || it.itemId || it.reference || it.slug || it.name || '').trim(),
|
|
812
851
|
name: String(it.name || it.label || it.title || '').trim(),
|
|
813
852
|
rawName: String(it.name || it.label || it.title || it.id || '').trim(),
|
|
814
853
|
}));
|
|
854
|
+
hasSampleItems = sampleItems && sampleItems.length > 0;
|
|
815
855
|
ok = true;
|
|
816
|
-
message = `OK: token valide.
|
|
856
|
+
message = `OK: token valide. Catalogue récupéré via /public : ${count} item(s).`;
|
|
817
857
|
} catch (e) {
|
|
818
858
|
ok = false;
|
|
819
859
|
message = (e && e.message) ? e.message : String(e);
|
|
@@ -826,6 +866,7 @@ async function handleHelloAssoTest(req, res) {
|
|
|
826
866
|
count,
|
|
827
867
|
settings,
|
|
828
868
|
sampleItems,
|
|
869
|
+
hasSampleItems,
|
|
829
870
|
hasSampleItems: sampleItems && sampleItems.length > 0,
|
|
830
871
|
});
|
|
831
872
|
}
|
package/package.json
CHANGED