@blackcode_sa/metaestetics-api 1.14.32 → 1.14.36
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/admin/index.d.mts +9 -18
- package/dist/admin/index.d.ts +9 -18
- package/dist/admin/index.js +20 -33
- package/dist/admin/index.mjs +20 -33
- package/dist/backoffice/index.d.mts +41 -54
- package/dist/backoffice/index.d.ts +41 -54
- package/dist/backoffice/index.js +23 -38
- package/dist/backoffice/index.mjs +23 -38
- package/dist/index.d.mts +21 -34
- package/dist/index.d.ts +21 -34
- package/dist/index.js +27 -40
- package/dist/index.mjs +27 -40
- package/package.json +1 -1
- package/src/admin/mailing/patientInvite/patientInvite.mailing.ts +3 -3
- package/src/admin/mailing/patientInvite/templates/invitation.template.ts +13 -28
- package/src/backoffice/services/brand.service.ts +4 -17
- package/src/backoffice/services/product.service.ts +12 -17
- package/src/backoffice/services/technology.service.ts +3 -1
- package/src/backoffice/types/brand.types.ts +0 -2
- package/src/backoffice/types/product.types.ts +18 -28
- package/src/services/analytics/analytics.service.ts +10 -4
|
@@ -14,7 +14,6 @@ import { z } from 'zod';
|
|
|
14
14
|
* @property manufacturer - Naziv proizvođača
|
|
15
15
|
* @property description - Detaljan opis brenda i njegovih proizvoda
|
|
16
16
|
* @property website - Web stranica brenda
|
|
17
|
-
* @property category - Kategorija brenda (npr. "laser", "peeling", "injectables") - za filtriranje
|
|
18
17
|
* @property isActive - Da li je brend aktivan u sistemu
|
|
19
18
|
* @property createdAt - Datum kreiranja
|
|
20
19
|
* @property updatedAt - Datum poslednjeg ažuriranja
|
|
@@ -29,7 +28,6 @@ interface Brand {
|
|
|
29
28
|
isActive: boolean;
|
|
30
29
|
website?: string;
|
|
31
30
|
description?: string;
|
|
32
|
-
category?: string;
|
|
33
31
|
}
|
|
34
32
|
/**
|
|
35
33
|
* Kolekcija u Firestore bazi gde se čuvaju brendovi
|
|
@@ -67,26 +65,23 @@ declare class BrandService extends BaseService {
|
|
|
67
65
|
isActive: boolean;
|
|
68
66
|
website?: string | undefined;
|
|
69
67
|
description?: string | undefined;
|
|
70
|
-
category?: string | undefined;
|
|
71
68
|
id: string;
|
|
72
69
|
}>;
|
|
73
70
|
/**
|
|
74
|
-
* Gets a paginated list of active brands, optionally filtered by name
|
|
71
|
+
* Gets a paginated list of active brands, optionally filtered by name.
|
|
75
72
|
* @param rowsPerPage - The number of brands to fetch.
|
|
76
73
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
77
74
|
* @param lastVisible - An optional document snapshot to use as a cursor for pagination.
|
|
78
|
-
* @param category - An optional category to filter brands by.
|
|
79
75
|
*/
|
|
80
|
-
getAll(rowsPerPage: number, searchTerm?: string, lastVisible?: any
|
|
76
|
+
getAll(rowsPerPage: number, searchTerm?: string, lastVisible?: any): Promise<{
|
|
81
77
|
brands: Brand[];
|
|
82
78
|
lastVisible: _firebase_firestore.QueryDocumentSnapshot<DocumentData, DocumentData>;
|
|
83
79
|
}>;
|
|
84
80
|
/**
|
|
85
|
-
* Gets the total count of active brands, optionally filtered by name
|
|
81
|
+
* Gets the total count of active brands, optionally filtered by name.
|
|
86
82
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
87
|
-
* @param category - An optional category to filter brands by.
|
|
88
83
|
*/
|
|
89
|
-
getBrandsCount(searchTerm?: string
|
|
84
|
+
getBrandsCount(searchTerm?: string): Promise<number>;
|
|
90
85
|
/**
|
|
91
86
|
* Gets all active brands for filter dropdowns (not paginated).
|
|
92
87
|
*/
|
|
@@ -632,20 +627,15 @@ interface UpdateDocumentTemplateData {
|
|
|
632
627
|
|
|
633
628
|
/**
|
|
634
629
|
* Product used in procedures
|
|
635
|
-
*
|
|
630
|
+
* Simplified structure with only essential fields and flexible metadata
|
|
636
631
|
*
|
|
637
632
|
* @property id - Unique identifier of the product
|
|
638
633
|
* @property name - Name of the product
|
|
639
|
-
* @property brandId -
|
|
640
|
-
* @property brandName -
|
|
634
|
+
* @property brandId - Reference to the Brand document ID
|
|
635
|
+
* @property brandName - Display name of the brand (denormalized for performance)
|
|
636
|
+
* @property description - Detailed description of the product
|
|
641
637
|
* @property assignedTechnologyIds - Array of technology IDs this product is assigned to
|
|
642
|
-
* @property
|
|
643
|
-
* @property technicalDetails - Technical details and specifications
|
|
644
|
-
* @property warnings - List of warnings related to product use
|
|
645
|
-
* @property dosage - Dosage information (if applicable)
|
|
646
|
-
* @property composition - Product composition
|
|
647
|
-
* @property indications - List of indications for use
|
|
648
|
-
* @property contraindications - List of contraindications
|
|
638
|
+
* @property metadata - Flexible key-value pairs for additional product information
|
|
649
639
|
* @property isActive - Whether the product is active in the system
|
|
650
640
|
* @property createdAt - Creation date
|
|
651
641
|
* @property updatedAt - Last update date
|
|
@@ -655,17 +645,13 @@ interface Product {
|
|
|
655
645
|
name: string;
|
|
656
646
|
brandId: string;
|
|
657
647
|
brandName: string;
|
|
648
|
+
description: string;
|
|
649
|
+
category?: string;
|
|
658
650
|
assignedTechnologyIds?: string[];
|
|
651
|
+
metadata?: Record<string, string | number | boolean>;
|
|
652
|
+
isActive: boolean;
|
|
659
653
|
createdAt: Date;
|
|
660
654
|
updatedAt: Date;
|
|
661
|
-
isActive: boolean;
|
|
662
|
-
description?: string;
|
|
663
|
-
technicalDetails?: string;
|
|
664
|
-
warnings?: string[];
|
|
665
|
-
dosage?: string;
|
|
666
|
-
composition?: string;
|
|
667
|
-
indications?: string[];
|
|
668
|
-
contraindications?: ContraindicationDynamic[];
|
|
669
655
|
/** Present only in subcollections - synced from technology metadata */
|
|
670
656
|
technologyId?: string;
|
|
671
657
|
/** Present only in subcollections - synced from technology name */
|
|
@@ -688,11 +674,10 @@ declare const PRODUCTS_COLLECTION = "products";
|
|
|
688
674
|
interface IProductService {
|
|
689
675
|
/**
|
|
690
676
|
* Creates a new product in the top-level collection
|
|
691
|
-
* @param brandId - ID of the brand that manufactures this product
|
|
692
677
|
* @param product - Product data
|
|
693
678
|
* @param technologyIds - Optional array of technology IDs to assign this product to
|
|
694
679
|
*/
|
|
695
|
-
createTopLevel(
|
|
680
|
+
createTopLevel(product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
|
|
696
681
|
/**
|
|
697
682
|
* Gets all products from the top-level collection
|
|
698
683
|
* @param options - Query options
|
|
@@ -701,6 +686,7 @@ interface IProductService {
|
|
|
701
686
|
rowsPerPage: number;
|
|
702
687
|
lastVisible?: any;
|
|
703
688
|
brandId?: string;
|
|
689
|
+
category?: string;
|
|
704
690
|
}): Promise<{
|
|
705
691
|
products: Product[];
|
|
706
692
|
lastVisible: any;
|
|
@@ -715,7 +701,7 @@ interface IProductService {
|
|
|
715
701
|
* @param productId - ID of the product to update
|
|
716
702
|
* @param product - Updated product data
|
|
717
703
|
*/
|
|
718
|
-
updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'
|
|
704
|
+
updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'>>): Promise<Product | null>;
|
|
719
705
|
/**
|
|
720
706
|
* Deletes a product from the top-level collection (soft delete)
|
|
721
707
|
* @param productId - ID of the product to delete
|
|
@@ -1754,7 +1740,7 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1754
1740
|
/**
|
|
1755
1741
|
* Creates a new product in the top-level collection
|
|
1756
1742
|
*/
|
|
1757
|
-
createTopLevel(
|
|
1743
|
+
createTopLevel(product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
|
|
1758
1744
|
/**
|
|
1759
1745
|
* Gets all products from the top-level collection
|
|
1760
1746
|
*/
|
|
@@ -1762,6 +1748,7 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1762
1748
|
rowsPerPage: number;
|
|
1763
1749
|
lastVisible?: any;
|
|
1764
1750
|
brandId?: string;
|
|
1751
|
+
category?: string;
|
|
1765
1752
|
}): Promise<{
|
|
1766
1753
|
products: Product[];
|
|
1767
1754
|
lastVisible: any;
|
|
@@ -1773,7 +1760,7 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1773
1760
|
/**
|
|
1774
1761
|
* Updates a product in the top-level collection
|
|
1775
1762
|
*/
|
|
1776
|
-
updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'
|
|
1763
|
+
updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'>>): Promise<Product | null>;
|
|
1777
1764
|
/**
|
|
1778
1765
|
* Deletes a product from the top-level collection (soft delete)
|
|
1779
1766
|
*/
|
|
@@ -2074,15 +2061,15 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2074
2061
|
isActive: boolean;
|
|
2075
2062
|
description: string;
|
|
2076
2063
|
family: ProcedureFamily;
|
|
2077
|
-
technicalDetails?: string | undefined;
|
|
2078
|
-
contraindications: ContraindicationDynamic[];
|
|
2079
2064
|
categoryId: string;
|
|
2080
2065
|
subcategoryId: string;
|
|
2066
|
+
technicalDetails?: string | undefined;
|
|
2081
2067
|
requirements: {
|
|
2082
2068
|
pre: Requirement[];
|
|
2083
2069
|
post: Requirement[];
|
|
2084
2070
|
};
|
|
2085
2071
|
blockingConditions: BlockingCondition[];
|
|
2072
|
+
contraindications: ContraindicationDynamic[];
|
|
2086
2073
|
benefits: TreatmentBenefitDynamic[];
|
|
2087
2074
|
certificationRequirement: CertificationRequirement;
|
|
2088
2075
|
documentationTemplates?: TechnologyDocumentationTemplate[] | undefined;
|
|
@@ -5240,11 +5227,6 @@ declare const technologySchema: z.ZodObject<{
|
|
|
5240
5227
|
name: string;
|
|
5241
5228
|
isActive: boolean;
|
|
5242
5229
|
family: ProcedureFamily;
|
|
5243
|
-
contraindications: {
|
|
5244
|
-
id: string;
|
|
5245
|
-
name: string;
|
|
5246
|
-
description?: string | undefined;
|
|
5247
|
-
}[];
|
|
5248
5230
|
categoryId: string;
|
|
5249
5231
|
subcategoryId: string;
|
|
5250
5232
|
requirements: {
|
|
@@ -5274,6 +5256,11 @@ declare const technologySchema: z.ZodObject<{
|
|
|
5274
5256
|
}[];
|
|
5275
5257
|
};
|
|
5276
5258
|
blockingConditions: BlockingCondition[];
|
|
5259
|
+
contraindications: {
|
|
5260
|
+
id: string;
|
|
5261
|
+
name: string;
|
|
5262
|
+
description?: string | undefined;
|
|
5263
|
+
}[];
|
|
5277
5264
|
benefits: {
|
|
5278
5265
|
id: string;
|
|
5279
5266
|
name: string;
|
|
@@ -5386,14 +5373,14 @@ declare const technologySchema: z.ZodObject<{
|
|
|
5386
5373
|
}, {
|
|
5387
5374
|
name: string;
|
|
5388
5375
|
family: ProcedureFamily;
|
|
5376
|
+
categoryId: string;
|
|
5377
|
+
subcategoryId: string;
|
|
5378
|
+
blockingConditions: BlockingCondition[];
|
|
5389
5379
|
contraindications: {
|
|
5390
5380
|
id: string;
|
|
5391
5381
|
name: string;
|
|
5392
5382
|
description?: string | undefined;
|
|
5393
5383
|
}[];
|
|
5394
|
-
categoryId: string;
|
|
5395
|
-
subcategoryId: string;
|
|
5396
|
-
blockingConditions: BlockingCondition[];
|
|
5397
5384
|
benefits: {
|
|
5398
5385
|
id: string;
|
|
5399
5386
|
name: string;
|
|
@@ -6257,14 +6244,9 @@ declare const technologyUpdateSchema: z.ZodObject<{
|
|
|
6257
6244
|
isActive?: boolean | undefined;
|
|
6258
6245
|
description?: string | undefined;
|
|
6259
6246
|
family?: ProcedureFamily | undefined;
|
|
6260
|
-
technicalDetails?: string | undefined;
|
|
6261
|
-
contraindications?: {
|
|
6262
|
-
id: string;
|
|
6263
|
-
name: string;
|
|
6264
|
-
description?: string | undefined;
|
|
6265
|
-
}[] | undefined;
|
|
6266
6247
|
categoryId?: string | undefined;
|
|
6267
6248
|
subcategoryId?: string | undefined;
|
|
6249
|
+
technicalDetails?: string | undefined;
|
|
6268
6250
|
requirements?: {
|
|
6269
6251
|
pre: {
|
|
6270
6252
|
name: string;
|
|
@@ -6292,6 +6274,11 @@ declare const technologyUpdateSchema: z.ZodObject<{
|
|
|
6292
6274
|
}[];
|
|
6293
6275
|
} | undefined;
|
|
6294
6276
|
blockingConditions?: BlockingCondition[] | undefined;
|
|
6277
|
+
contraindications?: {
|
|
6278
|
+
id: string;
|
|
6279
|
+
name: string;
|
|
6280
|
+
description?: string | undefined;
|
|
6281
|
+
}[] | undefined;
|
|
6295
6282
|
benefits?: {
|
|
6296
6283
|
id: string;
|
|
6297
6284
|
name: string;
|
|
@@ -6404,14 +6391,9 @@ declare const technologyUpdateSchema: z.ZodObject<{
|
|
|
6404
6391
|
isActive?: boolean | undefined;
|
|
6405
6392
|
description?: string | undefined;
|
|
6406
6393
|
family?: ProcedureFamily | undefined;
|
|
6407
|
-
technicalDetails?: string | undefined;
|
|
6408
|
-
contraindications?: {
|
|
6409
|
-
id: string;
|
|
6410
|
-
name: string;
|
|
6411
|
-
description?: string | undefined;
|
|
6412
|
-
}[] | undefined;
|
|
6413
6394
|
categoryId?: string | undefined;
|
|
6414
6395
|
subcategoryId?: string | undefined;
|
|
6396
|
+
technicalDetails?: string | undefined;
|
|
6415
6397
|
requirements?: {
|
|
6416
6398
|
pre: {
|
|
6417
6399
|
name: string;
|
|
@@ -6439,6 +6421,11 @@ declare const technologyUpdateSchema: z.ZodObject<{
|
|
|
6439
6421
|
}[];
|
|
6440
6422
|
} | undefined;
|
|
6441
6423
|
blockingConditions?: BlockingCondition[] | undefined;
|
|
6424
|
+
contraindications?: {
|
|
6425
|
+
id: string;
|
|
6426
|
+
name: string;
|
|
6427
|
+
description?: string | undefined;
|
|
6428
|
+
}[] | undefined;
|
|
6442
6429
|
benefits?: {
|
|
6443
6430
|
id: string;
|
|
6444
6431
|
name: string;
|
package/dist/backoffice/index.js
CHANGED
|
@@ -162,13 +162,12 @@ var BrandService = class extends BaseService {
|
|
|
162
162
|
return { id: docRef.id, ...newBrand };
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
-
* Gets a paginated list of active brands, optionally filtered by name
|
|
165
|
+
* Gets a paginated list of active brands, optionally filtered by name.
|
|
166
166
|
* @param rowsPerPage - The number of brands to fetch.
|
|
167
167
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
168
168
|
* @param lastVisible - An optional document snapshot to use as a cursor for pagination.
|
|
169
|
-
* @param category - An optional category to filter brands by.
|
|
170
169
|
*/
|
|
171
|
-
async getAll(rowsPerPage, searchTerm, lastVisible
|
|
170
|
+
async getAll(rowsPerPage, searchTerm, lastVisible) {
|
|
172
171
|
const constraints = [
|
|
173
172
|
(0, import_firestore.where)("isActive", "==", true),
|
|
174
173
|
(0, import_firestore.orderBy)("name_lowercase")
|
|
@@ -180,9 +179,6 @@ var BrandService = class extends BaseService {
|
|
|
180
179
|
(0, import_firestore.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
181
180
|
);
|
|
182
181
|
}
|
|
183
|
-
if (category) {
|
|
184
|
-
constraints.push((0, import_firestore.where)("category", "==", category));
|
|
185
|
-
}
|
|
186
182
|
if (lastVisible) {
|
|
187
183
|
constraints.push((0, import_firestore.startAfter)(lastVisible));
|
|
188
184
|
}
|
|
@@ -199,11 +195,10 @@ var BrandService = class extends BaseService {
|
|
|
199
195
|
return { brands, lastVisible: newLastVisible };
|
|
200
196
|
}
|
|
201
197
|
/**
|
|
202
|
-
* Gets the total count of active brands, optionally filtered by name
|
|
198
|
+
* Gets the total count of active brands, optionally filtered by name.
|
|
203
199
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
204
|
-
* @param category - An optional category to filter brands by.
|
|
205
200
|
*/
|
|
206
|
-
async getBrandsCount(searchTerm
|
|
201
|
+
async getBrandsCount(searchTerm) {
|
|
207
202
|
const constraints = [(0, import_firestore.where)("isActive", "==", true)];
|
|
208
203
|
if (searchTerm) {
|
|
209
204
|
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
@@ -212,9 +207,6 @@ var BrandService = class extends BaseService {
|
|
|
212
207
|
(0, import_firestore.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
213
208
|
);
|
|
214
209
|
}
|
|
215
|
-
if (category) {
|
|
216
|
-
constraints.push((0, import_firestore.where)("category", "==", category));
|
|
217
|
-
}
|
|
218
210
|
const q = (0, import_firestore.query)(this.getBrandsRef(), ...constraints);
|
|
219
211
|
const snapshot = await (0, import_firestore.getCountFromServer)(q);
|
|
220
212
|
return snapshot.data().count;
|
|
@@ -284,7 +276,6 @@ var BrandService = class extends BaseService {
|
|
|
284
276
|
"id",
|
|
285
277
|
"name",
|
|
286
278
|
"manufacturer",
|
|
287
|
-
"category",
|
|
288
279
|
"website",
|
|
289
280
|
"description",
|
|
290
281
|
"isActive"
|
|
@@ -315,15 +306,14 @@ var BrandService = class extends BaseService {
|
|
|
315
306
|
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
316
307
|
}
|
|
317
308
|
brandToCsvRow(brand) {
|
|
318
|
-
var _a, _b, _c, _d, _e, _f
|
|
309
|
+
var _a, _b, _c, _d, _e, _f;
|
|
319
310
|
const values = [
|
|
320
311
|
(_a = brand.id) != null ? _a : "",
|
|
321
312
|
(_b = brand.name) != null ? _b : "",
|
|
322
313
|
(_c = brand.manufacturer) != null ? _c : "",
|
|
323
|
-
(_d = brand.
|
|
324
|
-
(_e = brand.
|
|
325
|
-
(_f = brand.
|
|
326
|
-
String((_g = brand.isActive) != null ? _g : "")
|
|
314
|
+
(_d = brand.website) != null ? _d : "",
|
|
315
|
+
(_e = brand.description) != null ? _e : "",
|
|
316
|
+
String((_f = brand.isActive) != null ? _f : "")
|
|
327
317
|
];
|
|
328
318
|
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
329
319
|
}
|
|
@@ -1871,11 +1861,10 @@ var ProductService = class extends BaseService {
|
|
|
1871
1861
|
/**
|
|
1872
1862
|
* Creates a new product in the top-level collection
|
|
1873
1863
|
*/
|
|
1874
|
-
async createTopLevel(
|
|
1864
|
+
async createTopLevel(product, technologyIds = []) {
|
|
1875
1865
|
const now = /* @__PURE__ */ new Date();
|
|
1876
1866
|
const newProduct = {
|
|
1877
1867
|
...product,
|
|
1878
|
-
brandId,
|
|
1879
1868
|
assignedTechnologyIds: technologyIds,
|
|
1880
1869
|
createdAt: now,
|
|
1881
1870
|
updatedAt: now,
|
|
@@ -1888,11 +1877,14 @@ var ProductService = class extends BaseService {
|
|
|
1888
1877
|
* Gets all products from the top-level collection
|
|
1889
1878
|
*/
|
|
1890
1879
|
async getAllTopLevel(options) {
|
|
1891
|
-
const { rowsPerPage, lastVisible, brandId } = options;
|
|
1880
|
+
const { rowsPerPage, lastVisible, brandId, category } = options;
|
|
1892
1881
|
const constraints = [(0, import_firestore8.where)("isActive", "==", true), (0, import_firestore8.orderBy)("name")];
|
|
1893
1882
|
if (brandId) {
|
|
1894
1883
|
constraints.push((0, import_firestore8.where)("brandId", "==", brandId));
|
|
1895
1884
|
}
|
|
1885
|
+
if (category) {
|
|
1886
|
+
constraints.push((0, import_firestore8.where)("category", "==", category));
|
|
1887
|
+
}
|
|
1896
1888
|
if (lastVisible) {
|
|
1897
1889
|
constraints.push((0, import_firestore8.startAfter)(lastVisible));
|
|
1898
1890
|
}
|
|
@@ -2033,14 +2025,10 @@ var ProductService = class extends BaseService {
|
|
|
2033
2025
|
"name",
|
|
2034
2026
|
"brandId",
|
|
2035
2027
|
"brandName",
|
|
2028
|
+
"category",
|
|
2036
2029
|
"assignedTechnologyIds",
|
|
2037
2030
|
"description",
|
|
2038
|
-
"
|
|
2039
|
-
"dosage",
|
|
2040
|
-
"composition",
|
|
2041
|
-
"indications",
|
|
2042
|
-
"contraindications",
|
|
2043
|
-
"warnings",
|
|
2031
|
+
"metadata",
|
|
2044
2032
|
"isActive"
|
|
2045
2033
|
];
|
|
2046
2034
|
const rows = [];
|
|
@@ -2069,21 +2057,17 @@ var ProductService = class extends BaseService {
|
|
|
2069
2057
|
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
2070
2058
|
}
|
|
2071
2059
|
productToCsvRow(product) {
|
|
2072
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
2060
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2073
2061
|
const values = [
|
|
2074
2062
|
(_a = product.id) != null ? _a : "",
|
|
2075
2063
|
(_b = product.name) != null ? _b : "",
|
|
2076
2064
|
(_c = product.brandId) != null ? _c : "",
|
|
2077
2065
|
(_d = product.brandName) != null ? _d : "",
|
|
2078
|
-
(
|
|
2079
|
-
(_g = product.
|
|
2080
|
-
(_h = product.
|
|
2081
|
-
|
|
2082
|
-
(
|
|
2083
|
-
(_l = (_k = product.indications) == null ? void 0 : _k.join(";")) != null ? _l : "",
|
|
2084
|
-
(_n = (_m = product.contraindications) == null ? void 0 : _m.map((c) => c.name).join(";")) != null ? _n : "",
|
|
2085
|
-
(_p = (_o = product.warnings) == null ? void 0 : _o.join(";")) != null ? _p : "",
|
|
2086
|
-
String((_q = product.isActive) != null ? _q : "")
|
|
2066
|
+
(_e = product.category) != null ? _e : "",
|
|
2067
|
+
(_g = (_f = product.assignedTechnologyIds) == null ? void 0 : _f.join(";")) != null ? _g : "",
|
|
2068
|
+
(_h = product.description) != null ? _h : "",
|
|
2069
|
+
product.metadata ? JSON.stringify(product.metadata) : "",
|
|
2070
|
+
String((_i = product.isActive) != null ? _i : "")
|
|
2087
2071
|
];
|
|
2088
2072
|
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
2089
2073
|
}
|
|
@@ -3415,7 +3399,8 @@ var TechnologyService = class extends BaseService {
|
|
|
3415
3399
|
const products = await this.getAssignedProducts(technologyId);
|
|
3416
3400
|
const byBrand = {};
|
|
3417
3401
|
products.forEach((product) => {
|
|
3418
|
-
|
|
3402
|
+
const brandName = product.brandName || "Unknown";
|
|
3403
|
+
byBrand[brandName] = (byBrand[brandName] || 0) + 1;
|
|
3419
3404
|
});
|
|
3420
3405
|
return {
|
|
3421
3406
|
totalAssigned: products.length,
|
|
@@ -68,13 +68,12 @@ var BrandService = class extends BaseService {
|
|
|
68
68
|
return { id: docRef.id, ...newBrand };
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
* Gets a paginated list of active brands, optionally filtered by name
|
|
71
|
+
* Gets a paginated list of active brands, optionally filtered by name.
|
|
72
72
|
* @param rowsPerPage - The number of brands to fetch.
|
|
73
73
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
74
74
|
* @param lastVisible - An optional document snapshot to use as a cursor for pagination.
|
|
75
|
-
* @param category - An optional category to filter brands by.
|
|
76
75
|
*/
|
|
77
|
-
async getAll(rowsPerPage, searchTerm, lastVisible
|
|
76
|
+
async getAll(rowsPerPage, searchTerm, lastVisible) {
|
|
78
77
|
const constraints = [
|
|
79
78
|
where("isActive", "==", true),
|
|
80
79
|
orderBy("name_lowercase")
|
|
@@ -86,9 +85,6 @@ var BrandService = class extends BaseService {
|
|
|
86
85
|
where("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
87
86
|
);
|
|
88
87
|
}
|
|
89
|
-
if (category) {
|
|
90
|
-
constraints.push(where("category", "==", category));
|
|
91
|
-
}
|
|
92
88
|
if (lastVisible) {
|
|
93
89
|
constraints.push(startAfter(lastVisible));
|
|
94
90
|
}
|
|
@@ -105,11 +101,10 @@ var BrandService = class extends BaseService {
|
|
|
105
101
|
return { brands, lastVisible: newLastVisible };
|
|
106
102
|
}
|
|
107
103
|
/**
|
|
108
|
-
* Gets the total count of active brands, optionally filtered by name
|
|
104
|
+
* Gets the total count of active brands, optionally filtered by name.
|
|
109
105
|
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
110
|
-
* @param category - An optional category to filter brands by.
|
|
111
106
|
*/
|
|
112
|
-
async getBrandsCount(searchTerm
|
|
107
|
+
async getBrandsCount(searchTerm) {
|
|
113
108
|
const constraints = [where("isActive", "==", true)];
|
|
114
109
|
if (searchTerm) {
|
|
115
110
|
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
@@ -118,9 +113,6 @@ var BrandService = class extends BaseService {
|
|
|
118
113
|
where("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
119
114
|
);
|
|
120
115
|
}
|
|
121
|
-
if (category) {
|
|
122
|
-
constraints.push(where("category", "==", category));
|
|
123
|
-
}
|
|
124
116
|
const q = query(this.getBrandsRef(), ...constraints);
|
|
125
117
|
const snapshot = await getCountFromServer(q);
|
|
126
118
|
return snapshot.data().count;
|
|
@@ -190,7 +182,6 @@ var BrandService = class extends BaseService {
|
|
|
190
182
|
"id",
|
|
191
183
|
"name",
|
|
192
184
|
"manufacturer",
|
|
193
|
-
"category",
|
|
194
185
|
"website",
|
|
195
186
|
"description",
|
|
196
187
|
"isActive"
|
|
@@ -221,15 +212,14 @@ var BrandService = class extends BaseService {
|
|
|
221
212
|
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
222
213
|
}
|
|
223
214
|
brandToCsvRow(brand) {
|
|
224
|
-
var _a, _b, _c, _d, _e, _f
|
|
215
|
+
var _a, _b, _c, _d, _e, _f;
|
|
225
216
|
const values = [
|
|
226
217
|
(_a = brand.id) != null ? _a : "",
|
|
227
218
|
(_b = brand.name) != null ? _b : "",
|
|
228
219
|
(_c = brand.manufacturer) != null ? _c : "",
|
|
229
|
-
(_d = brand.
|
|
230
|
-
(_e = brand.
|
|
231
|
-
(_f = brand.
|
|
232
|
-
String((_g = brand.isActive) != null ? _g : "")
|
|
220
|
+
(_d = brand.website) != null ? _d : "",
|
|
221
|
+
(_e = brand.description) != null ? _e : "",
|
|
222
|
+
String((_f = brand.isActive) != null ? _f : "")
|
|
233
223
|
];
|
|
234
224
|
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
235
225
|
}
|
|
@@ -1847,11 +1837,10 @@ var ProductService = class extends BaseService {
|
|
|
1847
1837
|
/**
|
|
1848
1838
|
* Creates a new product in the top-level collection
|
|
1849
1839
|
*/
|
|
1850
|
-
async createTopLevel(
|
|
1840
|
+
async createTopLevel(product, technologyIds = []) {
|
|
1851
1841
|
const now = /* @__PURE__ */ new Date();
|
|
1852
1842
|
const newProduct = {
|
|
1853
1843
|
...product,
|
|
1854
|
-
brandId,
|
|
1855
1844
|
assignedTechnologyIds: technologyIds,
|
|
1856
1845
|
createdAt: now,
|
|
1857
1846
|
updatedAt: now,
|
|
@@ -1864,11 +1853,14 @@ var ProductService = class extends BaseService {
|
|
|
1864
1853
|
* Gets all products from the top-level collection
|
|
1865
1854
|
*/
|
|
1866
1855
|
async getAllTopLevel(options) {
|
|
1867
|
-
const { rowsPerPage, lastVisible, brandId } = options;
|
|
1856
|
+
const { rowsPerPage, lastVisible, brandId, category } = options;
|
|
1868
1857
|
const constraints = [where6("isActive", "==", true), orderBy6("name")];
|
|
1869
1858
|
if (brandId) {
|
|
1870
1859
|
constraints.push(where6("brandId", "==", brandId));
|
|
1871
1860
|
}
|
|
1861
|
+
if (category) {
|
|
1862
|
+
constraints.push(where6("category", "==", category));
|
|
1863
|
+
}
|
|
1872
1864
|
if (lastVisible) {
|
|
1873
1865
|
constraints.push(startAfter5(lastVisible));
|
|
1874
1866
|
}
|
|
@@ -2009,14 +2001,10 @@ var ProductService = class extends BaseService {
|
|
|
2009
2001
|
"name",
|
|
2010
2002
|
"brandId",
|
|
2011
2003
|
"brandName",
|
|
2004
|
+
"category",
|
|
2012
2005
|
"assignedTechnologyIds",
|
|
2013
2006
|
"description",
|
|
2014
|
-
"
|
|
2015
|
-
"dosage",
|
|
2016
|
-
"composition",
|
|
2017
|
-
"indications",
|
|
2018
|
-
"contraindications",
|
|
2019
|
-
"warnings",
|
|
2007
|
+
"metadata",
|
|
2020
2008
|
"isActive"
|
|
2021
2009
|
];
|
|
2022
2010
|
const rows = [];
|
|
@@ -2045,21 +2033,17 @@ var ProductService = class extends BaseService {
|
|
|
2045
2033
|
return includeBom ? "\uFEFF" + csvBody : csvBody;
|
|
2046
2034
|
}
|
|
2047
2035
|
productToCsvRow(product) {
|
|
2048
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
2036
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2049
2037
|
const values = [
|
|
2050
2038
|
(_a = product.id) != null ? _a : "",
|
|
2051
2039
|
(_b = product.name) != null ? _b : "",
|
|
2052
2040
|
(_c = product.brandId) != null ? _c : "",
|
|
2053
2041
|
(_d = product.brandName) != null ? _d : "",
|
|
2054
|
-
(
|
|
2055
|
-
(_g = product.
|
|
2056
|
-
(_h = product.
|
|
2057
|
-
|
|
2058
|
-
(
|
|
2059
|
-
(_l = (_k = product.indications) == null ? void 0 : _k.join(";")) != null ? _l : "",
|
|
2060
|
-
(_n = (_m = product.contraindications) == null ? void 0 : _m.map((c) => c.name).join(";")) != null ? _n : "",
|
|
2061
|
-
(_p = (_o = product.warnings) == null ? void 0 : _o.join(";")) != null ? _p : "",
|
|
2062
|
-
String((_q = product.isActive) != null ? _q : "")
|
|
2042
|
+
(_e = product.category) != null ? _e : "",
|
|
2043
|
+
(_g = (_f = product.assignedTechnologyIds) == null ? void 0 : _f.join(";")) != null ? _g : "",
|
|
2044
|
+
(_h = product.description) != null ? _h : "",
|
|
2045
|
+
product.metadata ? JSON.stringify(product.metadata) : "",
|
|
2046
|
+
String((_i = product.isActive) != null ? _i : "")
|
|
2063
2047
|
];
|
|
2064
2048
|
return values.map((v) => this.formatCsvValue(v)).join(",");
|
|
2065
2049
|
}
|
|
@@ -3431,7 +3415,8 @@ var TechnologyService = class extends BaseService {
|
|
|
3431
3415
|
const products = await this.getAssignedProducts(technologyId);
|
|
3432
3416
|
const byBrand = {};
|
|
3433
3417
|
products.forEach((product) => {
|
|
3434
|
-
|
|
3418
|
+
const brandName = product.brandName || "Unknown";
|
|
3419
|
+
byBrand[brandName] = (byBrand[brandName] || 0) + 1;
|
|
3435
3420
|
});
|
|
3436
3421
|
return {
|
|
3437
3422
|
totalAssigned: products.length,
|