@blackcode_sa/metaestetics-api 1.12.42 → 1.12.43
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/backoffice/index.d.mts +93 -0
- package/dist/backoffice/index.d.ts +93 -0
- package/dist/backoffice/index.js +500 -0
- package/dist/backoffice/index.mjs +514 -13
- package/dist/index.d.mts +81 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +441 -0
- package/dist/index.mjs +441 -0
- package/package.json +1 -1
- package/src/backoffice/services/brand.service.ts +86 -0
- package/src/backoffice/services/category.service.ts +84 -0
- package/src/backoffice/services/constants.service.ts +77 -0
- package/src/backoffice/services/product.service.ts +100 -0
- package/src/backoffice/services/requirement.service.ts +76 -0
- package/src/backoffice/services/subcategory.service.ts +87 -0
- package/src/backoffice/services/technology.service.ts +120 -0
package/dist/backoffice/index.js
CHANGED
|
@@ -261,6 +261,73 @@ var BrandService = class extends BaseService {
|
|
|
261
261
|
...docSnap.data()
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Exports brands to CSV string, suitable for Excel/Sheets.
|
|
266
|
+
* Includes headers and optional UTF-8 BOM.
|
|
267
|
+
* By default exports only active brands (set includeInactive to true to export all).
|
|
268
|
+
*/
|
|
269
|
+
async exportToCsv(options) {
|
|
270
|
+
var _a, _b;
|
|
271
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
272
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
273
|
+
const headers = [
|
|
274
|
+
"id",
|
|
275
|
+
"name",
|
|
276
|
+
"manufacturer",
|
|
277
|
+
"website",
|
|
278
|
+
"description",
|
|
279
|
+
"isActive"
|
|
280
|
+
];
|
|
281
|
+
const rows = [];
|
|
282
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
283
|
+
const PAGE_SIZE = 1e3;
|
|
284
|
+
let cursor;
|
|
285
|
+
const baseConstraints = [];
|
|
286
|
+
if (!includeInactive) {
|
|
287
|
+
baseConstraints.push((0, import_firestore.where)("isActive", "==", true));
|
|
288
|
+
}
|
|
289
|
+
baseConstraints.push((0, import_firestore.orderBy)("name_lowercase"));
|
|
290
|
+
while (true) {
|
|
291
|
+
const constraints = [...baseConstraints, (0, import_firestore.limit)(PAGE_SIZE)];
|
|
292
|
+
if (cursor) constraints.push((0, import_firestore.startAfter)(cursor));
|
|
293
|
+
const q = (0, import_firestore.query)(this.getBrandsRef(), ...constraints);
|
|
294
|
+
const snapshot = await (0, import_firestore.getDocs)(q);
|
|
295
|
+
if (snapshot.empty) break;
|
|
296
|
+
for (const d of snapshot.docs) {
|
|
297
|
+
const brand = { id: d.id, ...d.data() };
|
|
298
|
+
rows.push(this.brandToCsvRow(brand));
|
|
299
|
+
}
|
|
300
|
+
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
301
|
+
if (snapshot.size < PAGE_SIZE) break;
|
|
302
|
+
}
|
|
303
|
+
const csvBody = rows.join("\r\n");
|
|
304
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
305
|
+
}
|
|
306
|
+
brandToCsvRow(brand) {
|
|
307
|
+
var _a, _b, _c, _d, _e, _f;
|
|
308
|
+
const values = [
|
|
309
|
+
(_a = brand.id) != null ? _a : "",
|
|
310
|
+
(_b = brand.name) != null ? _b : "",
|
|
311
|
+
(_c = brand.manufacturer) != null ? _c : "",
|
|
312
|
+
(_d = brand.website) != null ? _d : "",
|
|
313
|
+
(_e = brand.description) != null ? _e : "",
|
|
314
|
+
String((_f = brand.isActive) != null ? _f : "")
|
|
315
|
+
];
|
|
316
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
317
|
+
}
|
|
318
|
+
formatDateIso(value) {
|
|
319
|
+
if (value instanceof Date) return value.toISOString();
|
|
320
|
+
if (value && typeof value.toDate === "function") {
|
|
321
|
+
const d = value.toDate();
|
|
322
|
+
return d instanceof Date ? d.toISOString() : String(value);
|
|
323
|
+
}
|
|
324
|
+
return String(value != null ? value : "");
|
|
325
|
+
}
|
|
326
|
+
formatCsvValue(value) {
|
|
327
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
328
|
+
const escaped = str.replace(/"/g, '""');
|
|
329
|
+
return `"${escaped}"`;
|
|
330
|
+
}
|
|
264
331
|
};
|
|
265
332
|
|
|
266
333
|
// src/backoffice/services/category.service.ts
|
|
@@ -446,6 +513,71 @@ var CategoryService = class extends BaseService {
|
|
|
446
513
|
...docSnap.data()
|
|
447
514
|
};
|
|
448
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Exports categories to CSV string, suitable for Excel/Sheets.
|
|
518
|
+
* Includes headers and optional UTF-8 BOM.
|
|
519
|
+
* By default exports only active categories (set includeInactive to true to export all).
|
|
520
|
+
*/
|
|
521
|
+
async exportToCsv(options) {
|
|
522
|
+
var _a, _b;
|
|
523
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
524
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
525
|
+
const headers = [
|
|
526
|
+
"id",
|
|
527
|
+
"name",
|
|
528
|
+
"description",
|
|
529
|
+
"family",
|
|
530
|
+
"isActive"
|
|
531
|
+
];
|
|
532
|
+
const rows = [];
|
|
533
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
534
|
+
const PAGE_SIZE = 1e3;
|
|
535
|
+
let cursor;
|
|
536
|
+
const constraints = [];
|
|
537
|
+
if (!includeInactive) {
|
|
538
|
+
constraints.push((0, import_firestore2.where)("isActive", "==", true));
|
|
539
|
+
}
|
|
540
|
+
constraints.push((0, import_firestore2.orderBy)("name"));
|
|
541
|
+
while (true) {
|
|
542
|
+
const queryConstraints = [...constraints, (0, import_firestore2.limit)(PAGE_SIZE)];
|
|
543
|
+
if (cursor) queryConstraints.push((0, import_firestore2.startAfter)(cursor));
|
|
544
|
+
const q = (0, import_firestore2.query)(this.categoriesRef, ...queryConstraints);
|
|
545
|
+
const snapshot = await (0, import_firestore2.getDocs)(q);
|
|
546
|
+
if (snapshot.empty) break;
|
|
547
|
+
for (const d of snapshot.docs) {
|
|
548
|
+
const category = { id: d.id, ...d.data() };
|
|
549
|
+
rows.push(this.categoryToCsvRow(category));
|
|
550
|
+
}
|
|
551
|
+
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
552
|
+
if (snapshot.size < PAGE_SIZE) break;
|
|
553
|
+
}
|
|
554
|
+
const csvBody = rows.join("\r\n");
|
|
555
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
556
|
+
}
|
|
557
|
+
categoryToCsvRow(category) {
|
|
558
|
+
var _a, _b, _c, _d, _e;
|
|
559
|
+
const values = [
|
|
560
|
+
(_a = category.id) != null ? _a : "",
|
|
561
|
+
(_b = category.name) != null ? _b : "",
|
|
562
|
+
(_c = category.description) != null ? _c : "",
|
|
563
|
+
(_d = category.family) != null ? _d : "",
|
|
564
|
+
String((_e = category.isActive) != null ? _e : "")
|
|
565
|
+
];
|
|
566
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
567
|
+
}
|
|
568
|
+
formatDateIso(value) {
|
|
569
|
+
if (value instanceof Date) return value.toISOString();
|
|
570
|
+
if (value && typeof value.toDate === "function") {
|
|
571
|
+
const d = value.toDate();
|
|
572
|
+
return d instanceof Date ? d.toISOString() : String(value);
|
|
573
|
+
}
|
|
574
|
+
return String(value != null ? value : "");
|
|
575
|
+
}
|
|
576
|
+
formatCsvValue(value) {
|
|
577
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
578
|
+
const escaped = str.replace(/"/g, '""');
|
|
579
|
+
return `"${escaped}"`;
|
|
580
|
+
}
|
|
449
581
|
};
|
|
450
582
|
|
|
451
583
|
// src/services/documentation-templates/documentation-template.service.ts
|
|
@@ -1528,6 +1660,87 @@ var ProductService = class extends BaseService {
|
|
|
1528
1660
|
})
|
|
1529
1661
|
);
|
|
1530
1662
|
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Exports products to CSV string, suitable for Excel/Sheets.
|
|
1665
|
+
* Includes headers and optional UTF-8 BOM.
|
|
1666
|
+
* By default exports only active products (set includeInactive to true to export all).
|
|
1667
|
+
*/
|
|
1668
|
+
async exportToCsv(options) {
|
|
1669
|
+
var _a, _b;
|
|
1670
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
1671
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
1672
|
+
const headers = [
|
|
1673
|
+
"id",
|
|
1674
|
+
"name",
|
|
1675
|
+
"brandId",
|
|
1676
|
+
"brandName",
|
|
1677
|
+
"assignedTechnologyIds",
|
|
1678
|
+
"description",
|
|
1679
|
+
"technicalDetails",
|
|
1680
|
+
"dosage",
|
|
1681
|
+
"composition",
|
|
1682
|
+
"indications",
|
|
1683
|
+
"contraindications",
|
|
1684
|
+
"warnings",
|
|
1685
|
+
"isActive"
|
|
1686
|
+
];
|
|
1687
|
+
const rows = [];
|
|
1688
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
1689
|
+
const PAGE_SIZE = 1e3;
|
|
1690
|
+
let cursor;
|
|
1691
|
+
const constraints = [];
|
|
1692
|
+
if (!includeInactive) {
|
|
1693
|
+
constraints.push((0, import_firestore8.where)("isActive", "==", true));
|
|
1694
|
+
}
|
|
1695
|
+
constraints.push((0, import_firestore8.orderBy)("name"));
|
|
1696
|
+
while (true) {
|
|
1697
|
+
const queryConstraints = [...constraints, (0, import_firestore8.limit)(PAGE_SIZE)];
|
|
1698
|
+
if (cursor) queryConstraints.push((0, import_firestore8.startAfter)(cursor));
|
|
1699
|
+
const q = (0, import_firestore8.query)(this.getTopLevelProductsRef(), ...queryConstraints);
|
|
1700
|
+
const snapshot = await (0, import_firestore8.getDocs)(q);
|
|
1701
|
+
if (snapshot.empty) break;
|
|
1702
|
+
for (const d of snapshot.docs) {
|
|
1703
|
+
const product = { id: d.id, ...d.data() };
|
|
1704
|
+
rows.push(this.productToCsvRow(product));
|
|
1705
|
+
}
|
|
1706
|
+
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
1707
|
+
if (snapshot.size < PAGE_SIZE) break;
|
|
1708
|
+
}
|
|
1709
|
+
const csvBody = rows.join("\r\n");
|
|
1710
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
1711
|
+
}
|
|
1712
|
+
productToCsvRow(product) {
|
|
1713
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
1714
|
+
const values = [
|
|
1715
|
+
(_a = product.id) != null ? _a : "",
|
|
1716
|
+
(_b = product.name) != null ? _b : "",
|
|
1717
|
+
(_c = product.brandId) != null ? _c : "",
|
|
1718
|
+
(_d = product.brandName) != null ? _d : "",
|
|
1719
|
+
(_f = (_e = product.assignedTechnologyIds) == null ? void 0 : _e.join(";")) != null ? _f : "",
|
|
1720
|
+
(_g = product.description) != null ? _g : "",
|
|
1721
|
+
(_h = product.technicalDetails) != null ? _h : "",
|
|
1722
|
+
(_i = product.dosage) != null ? _i : "",
|
|
1723
|
+
(_j = product.composition) != null ? _j : "",
|
|
1724
|
+
(_l = (_k = product.indications) == null ? void 0 : _k.join(";")) != null ? _l : "",
|
|
1725
|
+
(_n = (_m = product.contraindications) == null ? void 0 : _m.map((c) => c.name).join(";")) != null ? _n : "",
|
|
1726
|
+
(_p = (_o = product.warnings) == null ? void 0 : _o.join(";")) != null ? _p : "",
|
|
1727
|
+
String((_q = product.isActive) != null ? _q : "")
|
|
1728
|
+
];
|
|
1729
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
1730
|
+
}
|
|
1731
|
+
formatDateIso(value) {
|
|
1732
|
+
if (value instanceof Date) return value.toISOString();
|
|
1733
|
+
if (value && typeof value.toDate === "function") {
|
|
1734
|
+
const d = value.toDate();
|
|
1735
|
+
return d instanceof Date ? d.toISOString() : String(value);
|
|
1736
|
+
}
|
|
1737
|
+
return String(value != null ? value : "");
|
|
1738
|
+
}
|
|
1739
|
+
formatCsvValue(value) {
|
|
1740
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
1741
|
+
const escaped = str.replace(/"/g, '""');
|
|
1742
|
+
return `"${escaped}"`;
|
|
1743
|
+
}
|
|
1531
1744
|
};
|
|
1532
1745
|
|
|
1533
1746
|
// src/backoffice/services/requirement.service.ts
|
|
@@ -1651,6 +1864,65 @@ var RequirementService = class extends BaseService {
|
|
|
1651
1864
|
...docSnap.data()
|
|
1652
1865
|
};
|
|
1653
1866
|
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Exports requirements to CSV string, suitable for Excel/Sheets.
|
|
1869
|
+
* Includes headers and optional UTF-8 BOM.
|
|
1870
|
+
* By default exports only active requirements (set includeInactive to true to export all).
|
|
1871
|
+
*/
|
|
1872
|
+
async exportToCsv(options) {
|
|
1873
|
+
var _a, _b;
|
|
1874
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
1875
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
1876
|
+
const headers = [
|
|
1877
|
+
"id",
|
|
1878
|
+
"type",
|
|
1879
|
+
"name",
|
|
1880
|
+
"description",
|
|
1881
|
+
"timeframe_duration",
|
|
1882
|
+
"timeframe_unit",
|
|
1883
|
+
"timeframe_notifyAt",
|
|
1884
|
+
"importance",
|
|
1885
|
+
"isActive"
|
|
1886
|
+
];
|
|
1887
|
+
const rows = [];
|
|
1888
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
1889
|
+
const q = includeInactive ? (0, import_firestore9.query)(this.requirementsRef, (0, import_firestore9.orderBy)("name")) : (0, import_firestore9.query)(this.requirementsRef, (0, import_firestore9.where)("isActive", "==", true), (0, import_firestore9.orderBy)("name"));
|
|
1890
|
+
const snapshot = await (0, import_firestore9.getDocs)(q);
|
|
1891
|
+
for (const d of snapshot.docs) {
|
|
1892
|
+
const requirement = { id: d.id, ...d.data() };
|
|
1893
|
+
rows.push(this.requirementToCsvRow(requirement));
|
|
1894
|
+
}
|
|
1895
|
+
const csvBody = rows.join("\r\n");
|
|
1896
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
1897
|
+
}
|
|
1898
|
+
requirementToCsvRow(requirement) {
|
|
1899
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
1900
|
+
const values = [
|
|
1901
|
+
(_a = requirement.id) != null ? _a : "",
|
|
1902
|
+
(_b = requirement.type) != null ? _b : "",
|
|
1903
|
+
(_c = requirement.name) != null ? _c : "",
|
|
1904
|
+
(_d = requirement.description) != null ? _d : "",
|
|
1905
|
+
(_g = (_f = (_e = requirement.timeframe) == null ? void 0 : _e.duration) == null ? void 0 : _f.toString()) != null ? _g : "",
|
|
1906
|
+
(_i = (_h = requirement.timeframe) == null ? void 0 : _h.unit) != null ? _i : "",
|
|
1907
|
+
(_l = (_k = (_j = requirement.timeframe) == null ? void 0 : _j.notifyAt) == null ? void 0 : _k.join(";")) != null ? _l : "",
|
|
1908
|
+
(_m = requirement.importance) != null ? _m : "",
|
|
1909
|
+
String((_n = requirement.isActive) != null ? _n : "")
|
|
1910
|
+
];
|
|
1911
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
1912
|
+
}
|
|
1913
|
+
formatDateIso(value) {
|
|
1914
|
+
if (value instanceof Date) return value.toISOString();
|
|
1915
|
+
if (value && typeof value.toDate === "function") {
|
|
1916
|
+
const d = value.toDate();
|
|
1917
|
+
return d instanceof Date ? d.toISOString() : String(value);
|
|
1918
|
+
}
|
|
1919
|
+
return String(value != null ? value : "");
|
|
1920
|
+
}
|
|
1921
|
+
formatCsvValue(value) {
|
|
1922
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
1923
|
+
const escaped = str.replace(/"/g, '""');
|
|
1924
|
+
return `"${escaped}"`;
|
|
1925
|
+
}
|
|
1654
1926
|
};
|
|
1655
1927
|
|
|
1656
1928
|
// src/backoffice/services/subcategory.service.ts
|
|
@@ -1878,6 +2150,74 @@ var SubcategoryService = class extends BaseService {
|
|
|
1878
2150
|
...docSnap.data()
|
|
1879
2151
|
};
|
|
1880
2152
|
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Exports subcategories to CSV string, suitable for Excel/Sheets.
|
|
2155
|
+
* Includes headers and optional UTF-8 BOM.
|
|
2156
|
+
* By default exports only active subcategories (set includeInactive to true to export all).
|
|
2157
|
+
*/
|
|
2158
|
+
async exportToCsv(options) {
|
|
2159
|
+
var _a, _b;
|
|
2160
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
2161
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
2162
|
+
const headers = [
|
|
2163
|
+
"id",
|
|
2164
|
+
"name",
|
|
2165
|
+
"categoryId",
|
|
2166
|
+
"description",
|
|
2167
|
+
"isActive"
|
|
2168
|
+
];
|
|
2169
|
+
const rows = [];
|
|
2170
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
2171
|
+
const PAGE_SIZE = 1e3;
|
|
2172
|
+
let cursor;
|
|
2173
|
+
const constraints = [];
|
|
2174
|
+
if (!includeInactive) {
|
|
2175
|
+
constraints.push((0, import_firestore10.where)("isActive", "==", true));
|
|
2176
|
+
}
|
|
2177
|
+
constraints.push((0, import_firestore10.orderBy)("name"));
|
|
2178
|
+
while (true) {
|
|
2179
|
+
const queryConstraints = [...constraints, (0, import_firestore10.limit)(PAGE_SIZE)];
|
|
2180
|
+
if (cursor) queryConstraints.push((0, import_firestore10.startAfter)(cursor));
|
|
2181
|
+
const q = (0, import_firestore10.query)(
|
|
2182
|
+
(0, import_firestore10.collectionGroup)(this.db, SUBCATEGORIES_COLLECTION),
|
|
2183
|
+
...queryConstraints
|
|
2184
|
+
);
|
|
2185
|
+
const snapshot = await (0, import_firestore10.getDocs)(q);
|
|
2186
|
+
if (snapshot.empty) break;
|
|
2187
|
+
for (const d of snapshot.docs) {
|
|
2188
|
+
const subcategory = { id: d.id, ...d.data() };
|
|
2189
|
+
rows.push(this.subcategoryToCsvRow(subcategory));
|
|
2190
|
+
}
|
|
2191
|
+
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
2192
|
+
if (snapshot.size < PAGE_SIZE) break;
|
|
2193
|
+
}
|
|
2194
|
+
const csvBody = rows.join("\r\n");
|
|
2195
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
2196
|
+
}
|
|
2197
|
+
subcategoryToCsvRow(subcategory) {
|
|
2198
|
+
var _a, _b, _c, _d, _e;
|
|
2199
|
+
const values = [
|
|
2200
|
+
(_a = subcategory.id) != null ? _a : "",
|
|
2201
|
+
(_b = subcategory.name) != null ? _b : "",
|
|
2202
|
+
(_c = subcategory.categoryId) != null ? _c : "",
|
|
2203
|
+
(_d = subcategory.description) != null ? _d : "",
|
|
2204
|
+
String((_e = subcategory.isActive) != null ? _e : "")
|
|
2205
|
+
];
|
|
2206
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
2207
|
+
}
|
|
2208
|
+
formatDateIso(value) {
|
|
2209
|
+
if (value instanceof Date) return value.toISOString();
|
|
2210
|
+
if (value && typeof value.toDate === "function") {
|
|
2211
|
+
const d = value.toDate();
|
|
2212
|
+
return d instanceof Date ? d.toISOString() : String(value);
|
|
2213
|
+
}
|
|
2214
|
+
return String(value != null ? value : "");
|
|
2215
|
+
}
|
|
2216
|
+
formatCsvValue(value) {
|
|
2217
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
2218
|
+
const escaped = str.replace(/"/g, '""');
|
|
2219
|
+
return `"${escaped}"`;
|
|
2220
|
+
}
|
|
1881
2221
|
};
|
|
1882
2222
|
|
|
1883
2223
|
// src/backoffice/services/technology.service.ts
|
|
@@ -2635,6 +2975,106 @@ var TechnologyService = class extends BaseService {
|
|
|
2635
2975
|
}
|
|
2636
2976
|
await batch.commit();
|
|
2637
2977
|
}
|
|
2978
|
+
/**
|
|
2979
|
+
* Exports technologies to CSV string, suitable for Excel/Sheets.
|
|
2980
|
+
* Includes headers and optional UTF-8 BOM.
|
|
2981
|
+
* By default exports only active technologies (set includeInactive to true to export all).
|
|
2982
|
+
* Includes product names from subcollections.
|
|
2983
|
+
*/
|
|
2984
|
+
async exportToCsv(options) {
|
|
2985
|
+
var _a, _b;
|
|
2986
|
+
const includeInactive = (_a = options == null ? void 0 : options.includeInactive) != null ? _a : false;
|
|
2987
|
+
const includeBom = (_b = options == null ? void 0 : options.includeBom) != null ? _b : true;
|
|
2988
|
+
const headers = [
|
|
2989
|
+
"id",
|
|
2990
|
+
"name",
|
|
2991
|
+
"description",
|
|
2992
|
+
"family",
|
|
2993
|
+
"categoryId",
|
|
2994
|
+
"subcategoryId",
|
|
2995
|
+
"technicalDetails",
|
|
2996
|
+
"requirements_pre",
|
|
2997
|
+
"requirements_post",
|
|
2998
|
+
"blockingConditions",
|
|
2999
|
+
"contraindications",
|
|
3000
|
+
"benefits",
|
|
3001
|
+
"certificationMinimumLevel",
|
|
3002
|
+
"certificationRequiredSpecialties",
|
|
3003
|
+
"documentationTemplateIds",
|
|
3004
|
+
"productNames",
|
|
3005
|
+
"isActive"
|
|
3006
|
+
];
|
|
3007
|
+
const rows = [];
|
|
3008
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
3009
|
+
const PAGE_SIZE = 1e3;
|
|
3010
|
+
let cursor;
|
|
3011
|
+
const constraints = [];
|
|
3012
|
+
if (!includeInactive) {
|
|
3013
|
+
constraints.push((0, import_firestore11.where)("isActive", "==", true));
|
|
3014
|
+
}
|
|
3015
|
+
constraints.push((0, import_firestore11.orderBy)("name"));
|
|
3016
|
+
while (true) {
|
|
3017
|
+
const queryConstraints = [...constraints, (0, import_firestore11.limit)(PAGE_SIZE)];
|
|
3018
|
+
if (cursor) queryConstraints.push((0, import_firestore11.startAfter)(cursor));
|
|
3019
|
+
const q = (0, import_firestore11.query)(this.technologiesRef, ...queryConstraints);
|
|
3020
|
+
const snapshot = await (0, import_firestore11.getDocs)(q);
|
|
3021
|
+
if (snapshot.empty) break;
|
|
3022
|
+
for (const d of snapshot.docs) {
|
|
3023
|
+
const technology = { id: d.id, ...d.data() };
|
|
3024
|
+
const productNames = await this.getProductNamesForTechnology(technology.id);
|
|
3025
|
+
rows.push(this.technologyToCsvRow(technology, productNames));
|
|
3026
|
+
}
|
|
3027
|
+
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
3028
|
+
if (snapshot.size < PAGE_SIZE) break;
|
|
3029
|
+
}
|
|
3030
|
+
const csvBody = rows.join("\r\n");
|
|
3031
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
3032
|
+
}
|
|
3033
|
+
/**
|
|
3034
|
+
* Gets product names from the technology's product subcollection
|
|
3035
|
+
*/
|
|
3036
|
+
async getProductNamesForTechnology(technologyId) {
|
|
3037
|
+
try {
|
|
3038
|
+
const productsRef = (0, import_firestore11.collection)(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
3039
|
+
const q = (0, import_firestore11.query)(productsRef, (0, import_firestore11.where)("isActive", "==", true));
|
|
3040
|
+
const snapshot = await (0, import_firestore11.getDocs)(q);
|
|
3041
|
+
return snapshot.docs.map((doc11) => {
|
|
3042
|
+
const product = doc11.data();
|
|
3043
|
+
return product.name || "";
|
|
3044
|
+
}).filter((name) => name);
|
|
3045
|
+
} catch (error) {
|
|
3046
|
+
console.error(`Error fetching products for technology ${technologyId}:`, error);
|
|
3047
|
+
return [];
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
technologyToCsvRow(technology, productNames = []) {
|
|
3051
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
|
|
3052
|
+
const values = [
|
|
3053
|
+
(_a = technology.id) != null ? _a : "",
|
|
3054
|
+
(_b = technology.name) != null ? _b : "",
|
|
3055
|
+
(_c = technology.description) != null ? _c : "",
|
|
3056
|
+
(_d = technology.family) != null ? _d : "",
|
|
3057
|
+
(_e = technology.categoryId) != null ? _e : "",
|
|
3058
|
+
(_f = technology.subcategoryId) != null ? _f : "",
|
|
3059
|
+
(_g = technology.technicalDetails) != null ? _g : "",
|
|
3060
|
+
(_j = (_i = (_h = technology.requirements) == null ? void 0 : _h.pre) == null ? void 0 : _i.map((r) => r.name).join(";")) != null ? _j : "",
|
|
3061
|
+
(_m = (_l = (_k = technology.requirements) == null ? void 0 : _k.post) == null ? void 0 : _l.map((r) => r.name).join(";")) != null ? _m : "",
|
|
3062
|
+
(_o = (_n = technology.blockingConditions) == null ? void 0 : _n.join(";")) != null ? _o : "",
|
|
3063
|
+
(_q = (_p = technology.contraindications) == null ? void 0 : _p.map((c) => c.name).join(";")) != null ? _q : "",
|
|
3064
|
+
(_s = (_r = technology.benefits) == null ? void 0 : _r.map((b) => b.name).join(";")) != null ? _s : "",
|
|
3065
|
+
(_u = (_t = technology.certificationRequirement) == null ? void 0 : _t.minimumLevel) != null ? _u : "",
|
|
3066
|
+
(_x = (_w = (_v = technology.certificationRequirement) == null ? void 0 : _v.requiredSpecialties) == null ? void 0 : _w.join(";")) != null ? _x : "",
|
|
3067
|
+
(_z = (_y = technology.documentationTemplates) == null ? void 0 : _y.map((t) => t.templateId).join(";")) != null ? _z : "",
|
|
3068
|
+
productNames.join(";"),
|
|
3069
|
+
String((_A = technology.isActive) != null ? _A : "")
|
|
3070
|
+
];
|
|
3071
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
3072
|
+
}
|
|
3073
|
+
formatCsvValue(value) {
|
|
3074
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
3075
|
+
const escaped = str.replace(/"/g, '""');
|
|
3076
|
+
return `"${escaped}"`;
|
|
3077
|
+
}
|
|
2638
3078
|
};
|
|
2639
3079
|
|
|
2640
3080
|
// src/backoffice/services/constants.service.ts
|
|
@@ -2867,6 +3307,66 @@ var ConstantsService = class extends BaseService {
|
|
|
2867
3307
|
contraindications: (0, import_firestore12.arrayRemove)(toRemove)
|
|
2868
3308
|
});
|
|
2869
3309
|
}
|
|
3310
|
+
// =================================================================
|
|
3311
|
+
// CSV Export Methods
|
|
3312
|
+
// =================================================================
|
|
3313
|
+
/**
|
|
3314
|
+
* Exports treatment benefits to CSV string, suitable for Excel/Sheets.
|
|
3315
|
+
* Includes headers and optional UTF-8 BOM.
|
|
3316
|
+
*/
|
|
3317
|
+
async exportBenefitsToCsv(options) {
|
|
3318
|
+
var _a;
|
|
3319
|
+
const includeBom = (_a = options == null ? void 0 : options.includeBom) != null ? _a : true;
|
|
3320
|
+
const headers = ["id", "name", "description"];
|
|
3321
|
+
const rows = [];
|
|
3322
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
3323
|
+
const benefits = await this.getAllBenefitsForFilter();
|
|
3324
|
+
for (const benefit of benefits) {
|
|
3325
|
+
rows.push(this.benefitToCsvRow(benefit));
|
|
3326
|
+
}
|
|
3327
|
+
const csvBody = rows.join("\r\n");
|
|
3328
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
3329
|
+
}
|
|
3330
|
+
/**
|
|
3331
|
+
* Exports contraindications to CSV string, suitable for Excel/Sheets.
|
|
3332
|
+
* Includes headers and optional UTF-8 BOM.
|
|
3333
|
+
*/
|
|
3334
|
+
async exportContraindicationsToCsv(options) {
|
|
3335
|
+
var _a;
|
|
3336
|
+
const includeBom = (_a = options == null ? void 0 : options.includeBom) != null ? _a : true;
|
|
3337
|
+
const headers = ["id", "name", "description"];
|
|
3338
|
+
const rows = [];
|
|
3339
|
+
rows.push(headers.map((h) => this.formatCsvValue(h)).join(","));
|
|
3340
|
+
const contraindications = await this.getAllContraindicationsForFilter();
|
|
3341
|
+
for (const contraindication of contraindications) {
|
|
3342
|
+
rows.push(this.contraindicationToCsvRow(contraindication));
|
|
3343
|
+
}
|
|
3344
|
+
const csvBody = rows.join("\r\n");
|
|
3345
|
+
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
3346
|
+
}
|
|
3347
|
+
benefitToCsvRow(benefit) {
|
|
3348
|
+
var _a, _b, _c;
|
|
3349
|
+
const values = [
|
|
3350
|
+
(_a = benefit.id) != null ? _a : "",
|
|
3351
|
+
(_b = benefit.name) != null ? _b : "",
|
|
3352
|
+
(_c = benefit.description) != null ? _c : ""
|
|
3353
|
+
];
|
|
3354
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
3355
|
+
}
|
|
3356
|
+
contraindicationToCsvRow(contraindication) {
|
|
3357
|
+
var _a, _b, _c;
|
|
3358
|
+
const values = [
|
|
3359
|
+
(_a = contraindication.id) != null ? _a : "",
|
|
3360
|
+
(_b = contraindication.name) != null ? _b : "",
|
|
3361
|
+
(_c = contraindication.description) != null ? _c : ""
|
|
3362
|
+
];
|
|
3363
|
+
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
3364
|
+
}
|
|
3365
|
+
formatCsvValue(value) {
|
|
3366
|
+
const str = value === null || value === void 0 ? "" : String(value);
|
|
3367
|
+
const escaped = str.replace(/"/g, '""');
|
|
3368
|
+
return `"${escaped}"`;
|
|
3369
|
+
}
|
|
2870
3370
|
};
|
|
2871
3371
|
|
|
2872
3372
|
// src/backoffice/types/static/blocking-condition.types.ts
|