@blackcode_sa/metaestetics-api 1.12.66 → 1.12.68
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 +73 -0
- package/dist/backoffice/index.d.ts +73 -0
- package/dist/backoffice/index.js +181 -18
- package/dist/backoffice/index.mjs +181 -20
- package/dist/index.d.mts +73 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +184 -21
- package/dist/index.mjs +184 -23
- package/package.json +1 -1
- package/src/backoffice/services/category.service.ts +72 -6
- package/src/backoffice/services/subcategory.service.ts +72 -6
- package/src/backoffice/services/technology.service.ts +74 -6
- package/src/backoffice/types/category.types.ts +5 -0
- package/src/backoffice/types/technology.types.ts +5 -0
- package/src/services/procedure/procedure.service.ts +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -288,6 +288,11 @@ interface ICategoryService {
|
|
|
288
288
|
delete(id: string): Promise<void>;
|
|
289
289
|
reactivate(id: string): Promise<void>;
|
|
290
290
|
getById(id: string): Promise<Category | null>;
|
|
291
|
+
findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
|
|
292
|
+
exportToCsv(options?: {
|
|
293
|
+
includeInactive?: boolean;
|
|
294
|
+
includeBom?: boolean;
|
|
295
|
+
}): Promise<string>;
|
|
291
296
|
}
|
|
292
297
|
|
|
293
298
|
/**
|
|
@@ -1014,6 +1019,11 @@ interface ITechnologyService {
|
|
|
1014
1019
|
getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
|
|
1015
1020
|
getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
|
|
1016
1021
|
getAllForFilter(): Promise<Technology[]>;
|
|
1022
|
+
findByName(name: string): Promise<Technology | null>;
|
|
1023
|
+
exportToCsv(options?: {
|
|
1024
|
+
includeInactive?: boolean;
|
|
1025
|
+
includeBom?: boolean;
|
|
1026
|
+
}): Promise<string>;
|
|
1017
1027
|
}
|
|
1018
1028
|
|
|
1019
1029
|
/**
|
|
@@ -1215,6 +1225,12 @@ declare class BrandService extends BaseService {
|
|
|
1215
1225
|
* });
|
|
1216
1226
|
*/
|
|
1217
1227
|
declare class CategoryService extends BaseService implements ICategoryService {
|
|
1228
|
+
/**
|
|
1229
|
+
* Filters out excluded categories from a list.
|
|
1230
|
+
* @param categories - List of categories to filter
|
|
1231
|
+
* @returns Filtered list without excluded categories
|
|
1232
|
+
*/
|
|
1233
|
+
private filterExcludedCategories;
|
|
1218
1234
|
/**
|
|
1219
1235
|
* Referenca na Firestore kolekciju kategorija
|
|
1220
1236
|
*/
|
|
@@ -1300,6 +1316,21 @@ declare class CategoryService extends BaseService implements ICategoryService {
|
|
|
1300
1316
|
* @returns Kategorija ili null ako ne postoji
|
|
1301
1317
|
*/
|
|
1302
1318
|
getById(id: string): Promise<Category | null>;
|
|
1319
|
+
/**
|
|
1320
|
+
* Internal method to get category by ID without filtering.
|
|
1321
|
+
* Used internally for consultation procedures.
|
|
1322
|
+
* @param id - ID of the category to get
|
|
1323
|
+
* @returns Category or null if not found
|
|
1324
|
+
*/
|
|
1325
|
+
getByIdInternal(id: string): Promise<Category | null>;
|
|
1326
|
+
/**
|
|
1327
|
+
* Finds a category by exact name match within a specific family.
|
|
1328
|
+
* Used for CSV import matching.
|
|
1329
|
+
* @param name - Exact name of the category to find
|
|
1330
|
+
* @param family - Procedure family to search within
|
|
1331
|
+
* @returns Category if found, null otherwise
|
|
1332
|
+
*/
|
|
1333
|
+
findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
|
|
1303
1334
|
/**
|
|
1304
1335
|
* Exports categories to CSV string, suitable for Excel/Sheets.
|
|
1305
1336
|
* Includes headers and optional UTF-8 BOM.
|
|
@@ -1728,6 +1759,12 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1728
1759
|
* });
|
|
1729
1760
|
*/
|
|
1730
1761
|
declare class SubcategoryService extends BaseService {
|
|
1762
|
+
/**
|
|
1763
|
+
* Filters out excluded subcategories from a list.
|
|
1764
|
+
* @param subcategories - List of subcategories to filter
|
|
1765
|
+
* @returns Filtered list without excluded subcategories
|
|
1766
|
+
*/
|
|
1767
|
+
private filterExcludedSubcategories;
|
|
1731
1768
|
/**
|
|
1732
1769
|
* Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
|
|
1733
1770
|
* @param categoryId - ID roditeljske kategorije
|
|
@@ -1822,6 +1859,22 @@ declare class SubcategoryService extends BaseService {
|
|
|
1822
1859
|
* @returns Podkategorija ili null ako ne postoji
|
|
1823
1860
|
*/
|
|
1824
1861
|
getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
|
|
1862
|
+
/**
|
|
1863
|
+
* Internal method to get subcategory by ID without filtering.
|
|
1864
|
+
* Used internally for consultation procedures.
|
|
1865
|
+
* @param categoryId - ID of the category
|
|
1866
|
+
* @param subcategoryId - ID of the subcategory to get
|
|
1867
|
+
* @returns Subcategory or null if not found
|
|
1868
|
+
*/
|
|
1869
|
+
getByIdInternal(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
|
|
1870
|
+
/**
|
|
1871
|
+
* Finds a subcategory by exact name match within a specific category.
|
|
1872
|
+
* Used for CSV import matching.
|
|
1873
|
+
* @param name - Exact name of the subcategory to find
|
|
1874
|
+
* @param categoryId - ID of the category to search within
|
|
1875
|
+
* @returns Subcategory if found, null otherwise
|
|
1876
|
+
*/
|
|
1877
|
+
findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
|
|
1825
1878
|
/**
|
|
1826
1879
|
* Exports subcategories to CSV string, suitable for Excel/Sheets.
|
|
1827
1880
|
* Includes headers and optional UTF-8 BOM.
|
|
@@ -2141,6 +2194,12 @@ interface CreatePractitionerTokenData {
|
|
|
2141
2194
|
* Service for managing technologies.
|
|
2142
2195
|
*/
|
|
2143
2196
|
declare class TechnologyService extends BaseService implements ITechnologyService {
|
|
2197
|
+
/**
|
|
2198
|
+
* Filters out excluded technologies from a list.
|
|
2199
|
+
* @param technologies - List of technologies to filter
|
|
2200
|
+
* @returns Filtered list without excluded technologies
|
|
2201
|
+
*/
|
|
2202
|
+
private filterExcludedTechnologies;
|
|
2144
2203
|
/**
|
|
2145
2204
|
* Reference to the Firestore collection of technologies.
|
|
2146
2205
|
*/
|
|
@@ -2248,6 +2307,20 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2248
2307
|
* @returns The technology or null if it doesn't exist.
|
|
2249
2308
|
*/
|
|
2250
2309
|
getById(id: string): Promise<Technology | null>;
|
|
2310
|
+
/**
|
|
2311
|
+
* Internal method to get technology by ID without filtering.
|
|
2312
|
+
* Used internally for consultation procedures.
|
|
2313
|
+
* @param id - The ID of the requested technology
|
|
2314
|
+
* @returns The technology or null if it doesn't exist
|
|
2315
|
+
*/
|
|
2316
|
+
getByIdInternal(id: string): Promise<Technology | null>;
|
|
2317
|
+
/**
|
|
2318
|
+
* Finds a technology by exact name match.
|
|
2319
|
+
* Used for CSV import duplicate detection.
|
|
2320
|
+
* @param name - Exact name of the technology to find
|
|
2321
|
+
* @returns Technology if found, null otherwise
|
|
2322
|
+
*/
|
|
2323
|
+
findByName(name: string): Promise<Technology | null>;
|
|
2251
2324
|
/**
|
|
2252
2325
|
* Dodaje novi zahtev tehnologiji
|
|
2253
2326
|
* @param technologyId - ID tehnologije
|
package/dist/index.js
CHANGED
|
@@ -17811,9 +17811,9 @@ var ProcedureService = class extends BaseService {
|
|
|
17811
17811
|
var _a, _b;
|
|
17812
17812
|
const procedureId = this.generateId();
|
|
17813
17813
|
const [category, subcategory, technology] = await Promise.all([
|
|
17814
|
-
this.categoryService.
|
|
17815
|
-
this.subcategoryService.
|
|
17816
|
-
this.technologyService.
|
|
17814
|
+
this.categoryService.getByIdInternal(data.categoryId),
|
|
17815
|
+
this.subcategoryService.getByIdInternal(data.categoryId, data.subcategoryId),
|
|
17816
|
+
this.technologyService.getByIdInternal(data.technologyId)
|
|
17817
17817
|
]);
|
|
17818
17818
|
if (!category || !subcategory || !technology) {
|
|
17819
17819
|
throw new Error("One or more required base entities not found");
|
|
@@ -18750,7 +18750,16 @@ var import_firestore59 = require("firebase/firestore");
|
|
|
18750
18750
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
18751
18751
|
|
|
18752
18752
|
// src/backoffice/services/category.service.ts
|
|
18753
|
+
var EXCLUDED_CATEGORY_ID = "consultation";
|
|
18753
18754
|
var CategoryService = class extends BaseService {
|
|
18755
|
+
/**
|
|
18756
|
+
* Filters out excluded categories from a list.
|
|
18757
|
+
* @param categories - List of categories to filter
|
|
18758
|
+
* @returns Filtered list without excluded categories
|
|
18759
|
+
*/
|
|
18760
|
+
filterExcludedCategories(categories) {
|
|
18761
|
+
return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
|
|
18762
|
+
}
|
|
18754
18763
|
/**
|
|
18755
18764
|
* Referenca na Firestore kolekciju kategorija
|
|
18756
18765
|
*/
|
|
@@ -18787,8 +18796,9 @@ var CategoryService = class extends BaseService {
|
|
|
18787
18796
|
(0, import_firestore59.where)("family", "==", family),
|
|
18788
18797
|
(0, import_firestore59.where)("isActive", "==", active)
|
|
18789
18798
|
);
|
|
18790
|
-
const snapshot = await (0, import_firestore59.
|
|
18791
|
-
|
|
18799
|
+
const snapshot = await (0, import_firestore59.getDocs)(q);
|
|
18800
|
+
const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_CATEGORY_ID);
|
|
18801
|
+
counts[family] = filteredDocs.length;
|
|
18792
18802
|
}
|
|
18793
18803
|
return counts;
|
|
18794
18804
|
}
|
|
@@ -18799,12 +18809,13 @@ var CategoryService = class extends BaseService {
|
|
|
18799
18809
|
async getAllForFilter() {
|
|
18800
18810
|
const q = (0, import_firestore59.query)(this.categoriesRef, (0, import_firestore59.where)("isActive", "==", true));
|
|
18801
18811
|
const snapshot = await (0, import_firestore59.getDocs)(q);
|
|
18802
|
-
|
|
18812
|
+
const categories = snapshot.docs.map(
|
|
18803
18813
|
(doc45) => ({
|
|
18804
18814
|
id: doc45.id,
|
|
18805
18815
|
...doc45.data()
|
|
18806
18816
|
})
|
|
18807
18817
|
);
|
|
18818
|
+
return this.filterExcludedCategories(categories);
|
|
18808
18819
|
}
|
|
18809
18820
|
/**
|
|
18810
18821
|
* Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
|
|
@@ -18819,12 +18830,13 @@ var CategoryService = class extends BaseService {
|
|
|
18819
18830
|
(0, import_firestore59.orderBy)("name")
|
|
18820
18831
|
);
|
|
18821
18832
|
const snapshot = await (0, import_firestore59.getDocs)(q);
|
|
18822
|
-
|
|
18833
|
+
const categories = snapshot.docs.map(
|
|
18823
18834
|
(doc45) => ({
|
|
18824
18835
|
id: doc45.id,
|
|
18825
18836
|
...doc45.data()
|
|
18826
18837
|
})
|
|
18827
18838
|
);
|
|
18839
|
+
return this.filterExcludedCategories(categories);
|
|
18828
18840
|
}
|
|
18829
18841
|
/**
|
|
18830
18842
|
* Vraća sve kategorije sa paginacijom
|
|
@@ -18847,8 +18859,9 @@ var CategoryService = class extends BaseService {
|
|
|
18847
18859
|
...doc45.data()
|
|
18848
18860
|
})
|
|
18849
18861
|
);
|
|
18862
|
+
const filteredCategories = this.filterExcludedCategories(categories);
|
|
18850
18863
|
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
18851
|
-
return { categories, lastVisible: newLastVisible };
|
|
18864
|
+
return { categories: filteredCategories, lastVisible: newLastVisible };
|
|
18852
18865
|
}
|
|
18853
18866
|
/**
|
|
18854
18867
|
* Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
|
|
@@ -18873,8 +18886,9 @@ var CategoryService = class extends BaseService {
|
|
|
18873
18886
|
...doc45.data()
|
|
18874
18887
|
})
|
|
18875
18888
|
);
|
|
18889
|
+
const filteredCategories = this.filterExcludedCategories(categories);
|
|
18876
18890
|
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
18877
|
-
return { categories, lastVisible: newLastVisible };
|
|
18891
|
+
return { categories: filteredCategories, lastVisible: newLastVisible };
|
|
18878
18892
|
}
|
|
18879
18893
|
/**
|
|
18880
18894
|
* Ažurira postojeću kategoriju
|
|
@@ -18911,6 +18925,22 @@ var CategoryService = class extends BaseService {
|
|
|
18911
18925
|
* @returns Kategorija ili null ako ne postoji
|
|
18912
18926
|
*/
|
|
18913
18927
|
async getById(id) {
|
|
18928
|
+
if (id === EXCLUDED_CATEGORY_ID) return null;
|
|
18929
|
+
const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
|
|
18930
|
+
const docSnap = await (0, import_firestore59.getDoc)(docRef);
|
|
18931
|
+
if (!docSnap.exists()) return null;
|
|
18932
|
+
return {
|
|
18933
|
+
id: docSnap.id,
|
|
18934
|
+
...docSnap.data()
|
|
18935
|
+
};
|
|
18936
|
+
}
|
|
18937
|
+
/**
|
|
18938
|
+
* Internal method to get category by ID without filtering.
|
|
18939
|
+
* Used internally for consultation procedures.
|
|
18940
|
+
* @param id - ID of the category to get
|
|
18941
|
+
* @returns Category or null if not found
|
|
18942
|
+
*/
|
|
18943
|
+
async getByIdInternal(id) {
|
|
18914
18944
|
const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
|
|
18915
18945
|
const docSnap = await (0, import_firestore59.getDoc)(docRef);
|
|
18916
18946
|
if (!docSnap.exists()) return null;
|
|
@@ -18919,6 +18949,29 @@ var CategoryService = class extends BaseService {
|
|
|
18919
18949
|
...docSnap.data()
|
|
18920
18950
|
};
|
|
18921
18951
|
}
|
|
18952
|
+
/**
|
|
18953
|
+
* Finds a category by exact name match within a specific family.
|
|
18954
|
+
* Used for CSV import matching.
|
|
18955
|
+
* @param name - Exact name of the category to find
|
|
18956
|
+
* @param family - Procedure family to search within
|
|
18957
|
+
* @returns Category if found, null otherwise
|
|
18958
|
+
*/
|
|
18959
|
+
async findByNameAndFamily(name, family) {
|
|
18960
|
+
const q = (0, import_firestore59.query)(
|
|
18961
|
+
this.categoriesRef,
|
|
18962
|
+
(0, import_firestore59.where)("name", "==", name),
|
|
18963
|
+
(0, import_firestore59.where)("family", "==", family),
|
|
18964
|
+
(0, import_firestore59.where)("isActive", "==", true)
|
|
18965
|
+
);
|
|
18966
|
+
const snapshot = await (0, import_firestore59.getDocs)(q);
|
|
18967
|
+
if (snapshot.empty) return null;
|
|
18968
|
+
const doc45 = snapshot.docs[0];
|
|
18969
|
+
if (doc45.id === EXCLUDED_CATEGORY_ID) return null;
|
|
18970
|
+
return {
|
|
18971
|
+
id: doc45.id,
|
|
18972
|
+
...doc45.data()
|
|
18973
|
+
};
|
|
18974
|
+
}
|
|
18922
18975
|
/**
|
|
18923
18976
|
* Exports categories to CSV string, suitable for Excel/Sheets.
|
|
18924
18977
|
* Includes headers and optional UTF-8 BOM.
|
|
@@ -18951,6 +19004,7 @@ var CategoryService = class extends BaseService {
|
|
|
18951
19004
|
const snapshot = await (0, import_firestore59.getDocs)(q);
|
|
18952
19005
|
if (snapshot.empty) break;
|
|
18953
19006
|
for (const d of snapshot.docs) {
|
|
19007
|
+
if (d.id === EXCLUDED_CATEGORY_ID) continue;
|
|
18954
19008
|
const category = { id: d.id, ...d.data() };
|
|
18955
19009
|
rows.push(this.categoryToCsvRow(category));
|
|
18956
19010
|
}
|
|
@@ -18993,7 +19047,16 @@ var import_firestore60 = require("firebase/firestore");
|
|
|
18993
19047
|
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
18994
19048
|
|
|
18995
19049
|
// src/backoffice/services/subcategory.service.ts
|
|
19050
|
+
var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
|
|
18996
19051
|
var SubcategoryService = class extends BaseService {
|
|
19052
|
+
/**
|
|
19053
|
+
* Filters out excluded subcategories from a list.
|
|
19054
|
+
* @param subcategories - List of subcategories to filter
|
|
19055
|
+
* @returns Filtered list without excluded subcategories
|
|
19056
|
+
*/
|
|
19057
|
+
filterExcludedSubcategories(subcategories) {
|
|
19058
|
+
return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
|
|
19059
|
+
}
|
|
18997
19060
|
/**
|
|
18998
19061
|
* Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
|
|
18999
19062
|
* @param categoryId - ID roditeljske kategorije
|
|
@@ -19040,8 +19103,9 @@ var SubcategoryService = class extends BaseService {
|
|
|
19040
19103
|
const categoryId = categoryDoc.id;
|
|
19041
19104
|
const subcategoriesRef = this.getSubcategoriesRef(categoryId);
|
|
19042
19105
|
const q = (0, import_firestore60.query)(subcategoriesRef, (0, import_firestore60.where)("isActive", "==", active));
|
|
19043
|
-
const snapshot = await (0, import_firestore60.
|
|
19044
|
-
|
|
19106
|
+
const snapshot = await (0, import_firestore60.getDocs)(q);
|
|
19107
|
+
const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_SUBCATEGORY_ID);
|
|
19108
|
+
counts[categoryId] = filteredDocs.length;
|
|
19045
19109
|
}
|
|
19046
19110
|
return counts;
|
|
19047
19111
|
}
|
|
@@ -19067,8 +19131,9 @@ var SubcategoryService = class extends BaseService {
|
|
|
19067
19131
|
...doc45.data()
|
|
19068
19132
|
})
|
|
19069
19133
|
);
|
|
19134
|
+
const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
|
|
19070
19135
|
const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
|
|
19071
|
-
return { subcategories, lastVisible: newLastVisible };
|
|
19136
|
+
return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
|
|
19072
19137
|
}
|
|
19073
19138
|
/**
|
|
19074
19139
|
* Vraća sve podkategorije sa paginacijom koristeći collection group query.
|
|
@@ -19097,8 +19162,9 @@ var SubcategoryService = class extends BaseService {
|
|
|
19097
19162
|
...doc45.data()
|
|
19098
19163
|
})
|
|
19099
19164
|
);
|
|
19165
|
+
const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
|
|
19100
19166
|
const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
|
|
19101
|
-
return { subcategories, lastVisible: newLastVisible };
|
|
19167
|
+
return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
|
|
19102
19168
|
}
|
|
19103
19169
|
/**
|
|
19104
19170
|
* Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
|
|
@@ -19111,12 +19177,13 @@ var SubcategoryService = class extends BaseService {
|
|
|
19111
19177
|
(0, import_firestore60.where)("isActive", "==", true)
|
|
19112
19178
|
);
|
|
19113
19179
|
const querySnapshot = await (0, import_firestore60.getDocs)(q);
|
|
19114
|
-
|
|
19180
|
+
const subcategories = querySnapshot.docs.map(
|
|
19115
19181
|
(doc45) => ({
|
|
19116
19182
|
id: doc45.id,
|
|
19117
19183
|
...doc45.data()
|
|
19118
19184
|
})
|
|
19119
19185
|
);
|
|
19186
|
+
return this.filterExcludedSubcategories(subcategories);
|
|
19120
19187
|
}
|
|
19121
19188
|
/**
|
|
19122
19189
|
* Vraća sve subkategorije za potrebe filtera (bez paginacije)
|
|
@@ -19128,12 +19195,13 @@ var SubcategoryService = class extends BaseService {
|
|
|
19128
19195
|
(0, import_firestore60.where)("isActive", "==", true)
|
|
19129
19196
|
);
|
|
19130
19197
|
const querySnapshot = await (0, import_firestore60.getDocs)(q);
|
|
19131
|
-
|
|
19198
|
+
const subcategories = querySnapshot.docs.map(
|
|
19132
19199
|
(doc45) => ({
|
|
19133
19200
|
id: doc45.id,
|
|
19134
19201
|
...doc45.data()
|
|
19135
19202
|
})
|
|
19136
19203
|
);
|
|
19204
|
+
return this.filterExcludedSubcategories(subcategories);
|
|
19137
19205
|
}
|
|
19138
19206
|
/**
|
|
19139
19207
|
* Ažurira postojeću podkategoriju
|
|
@@ -19203,6 +19271,23 @@ var SubcategoryService = class extends BaseService {
|
|
|
19203
19271
|
* @returns Podkategorija ili null ako ne postoji
|
|
19204
19272
|
*/
|
|
19205
19273
|
async getById(categoryId, subcategoryId) {
|
|
19274
|
+
if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
|
|
19275
|
+
const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
19276
|
+
const docSnap = await (0, import_firestore60.getDoc)(docRef);
|
|
19277
|
+
if (!docSnap.exists()) return null;
|
|
19278
|
+
return {
|
|
19279
|
+
id: docSnap.id,
|
|
19280
|
+
...docSnap.data()
|
|
19281
|
+
};
|
|
19282
|
+
}
|
|
19283
|
+
/**
|
|
19284
|
+
* Internal method to get subcategory by ID without filtering.
|
|
19285
|
+
* Used internally for consultation procedures.
|
|
19286
|
+
* @param categoryId - ID of the category
|
|
19287
|
+
* @param subcategoryId - ID of the subcategory to get
|
|
19288
|
+
* @returns Subcategory or null if not found
|
|
19289
|
+
*/
|
|
19290
|
+
async getByIdInternal(categoryId, subcategoryId) {
|
|
19206
19291
|
const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
19207
19292
|
const docSnap = await (0, import_firestore60.getDoc)(docRef);
|
|
19208
19293
|
if (!docSnap.exists()) return null;
|
|
@@ -19211,6 +19296,28 @@ var SubcategoryService = class extends BaseService {
|
|
|
19211
19296
|
...docSnap.data()
|
|
19212
19297
|
};
|
|
19213
19298
|
}
|
|
19299
|
+
/**
|
|
19300
|
+
* Finds a subcategory by exact name match within a specific category.
|
|
19301
|
+
* Used for CSV import matching.
|
|
19302
|
+
* @param name - Exact name of the subcategory to find
|
|
19303
|
+
* @param categoryId - ID of the category to search within
|
|
19304
|
+
* @returns Subcategory if found, null otherwise
|
|
19305
|
+
*/
|
|
19306
|
+
async findByNameAndCategory(name, categoryId) {
|
|
19307
|
+
const q = (0, import_firestore60.query)(
|
|
19308
|
+
this.getSubcategoriesRef(categoryId),
|
|
19309
|
+
(0, import_firestore60.where)("name", "==", name),
|
|
19310
|
+
(0, import_firestore60.where)("isActive", "==", true)
|
|
19311
|
+
);
|
|
19312
|
+
const querySnapshot = await (0, import_firestore60.getDocs)(q);
|
|
19313
|
+
if (querySnapshot.empty) return null;
|
|
19314
|
+
const doc45 = querySnapshot.docs[0];
|
|
19315
|
+
if (doc45.id === EXCLUDED_SUBCATEGORY_ID) return null;
|
|
19316
|
+
return {
|
|
19317
|
+
id: doc45.id,
|
|
19318
|
+
...doc45.data()
|
|
19319
|
+
};
|
|
19320
|
+
}
|
|
19214
19321
|
/**
|
|
19215
19322
|
* Exports subcategories to CSV string, suitable for Excel/Sheets.
|
|
19216
19323
|
* Includes headers and optional UTF-8 BOM.
|
|
@@ -19246,6 +19353,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
19246
19353
|
const snapshot = await (0, import_firestore60.getDocs)(q);
|
|
19247
19354
|
if (snapshot.empty) break;
|
|
19248
19355
|
for (const d of snapshot.docs) {
|
|
19356
|
+
if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
|
|
19249
19357
|
const subcategory = { id: d.id, ...d.data() };
|
|
19250
19358
|
rows.push(this.subcategoryToCsvRow(subcategory));
|
|
19251
19359
|
}
|
|
@@ -19288,11 +19396,20 @@ var import_firestore61 = require("firebase/firestore");
|
|
|
19288
19396
|
var PRODUCTS_COLLECTION = "products";
|
|
19289
19397
|
|
|
19290
19398
|
// src/backoffice/services/technology.service.ts
|
|
19399
|
+
var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
|
|
19291
19400
|
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
19292
19401
|
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
19293
19402
|
requiredSpecialties: []
|
|
19294
19403
|
};
|
|
19295
19404
|
var TechnologyService = class extends BaseService {
|
|
19405
|
+
/**
|
|
19406
|
+
* Filters out excluded technologies from a list.
|
|
19407
|
+
* @param technologies - List of technologies to filter
|
|
19408
|
+
* @returns Filtered list without excluded technologies
|
|
19409
|
+
*/
|
|
19410
|
+
filterExcludedTechnologies(technologies) {
|
|
19411
|
+
return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
|
|
19412
|
+
}
|
|
19296
19413
|
/**
|
|
19297
19414
|
* Reference to the Firestore collection of technologies.
|
|
19298
19415
|
*/
|
|
@@ -19341,6 +19458,7 @@ var TechnologyService = class extends BaseService {
|
|
|
19341
19458
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19342
19459
|
const counts = {};
|
|
19343
19460
|
snapshot.docs.forEach((doc45) => {
|
|
19461
|
+
if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
|
|
19344
19462
|
const tech = doc45.data();
|
|
19345
19463
|
counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
|
|
19346
19464
|
});
|
|
@@ -19356,6 +19474,7 @@ var TechnologyService = class extends BaseService {
|
|
|
19356
19474
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19357
19475
|
const counts = {};
|
|
19358
19476
|
snapshot.docs.forEach((doc45) => {
|
|
19477
|
+
if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
|
|
19359
19478
|
const tech = doc45.data();
|
|
19360
19479
|
counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
|
|
19361
19480
|
});
|
|
@@ -19382,8 +19501,9 @@ var TechnologyService = class extends BaseService {
|
|
|
19382
19501
|
...doc45.data()
|
|
19383
19502
|
})
|
|
19384
19503
|
);
|
|
19504
|
+
const filteredTechnologies = this.filterExcludedTechnologies(technologies);
|
|
19385
19505
|
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
19386
|
-
return { technologies, lastVisible: newLastVisible };
|
|
19506
|
+
return { technologies: filteredTechnologies, lastVisible: newLastVisible };
|
|
19387
19507
|
}
|
|
19388
19508
|
/**
|
|
19389
19509
|
* Returns all technologies for a specific category with pagination.
|
|
@@ -19408,8 +19528,9 @@ var TechnologyService = class extends BaseService {
|
|
|
19408
19528
|
...doc45.data()
|
|
19409
19529
|
})
|
|
19410
19530
|
);
|
|
19531
|
+
const filteredTechnologies = this.filterExcludedTechnologies(technologies);
|
|
19411
19532
|
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
19412
|
-
return { technologies, lastVisible: newLastVisible };
|
|
19533
|
+
return { technologies: filteredTechnologies, lastVisible: newLastVisible };
|
|
19413
19534
|
}
|
|
19414
19535
|
/**
|
|
19415
19536
|
* Returns all technologies for a specific subcategory with pagination.
|
|
@@ -19434,8 +19555,9 @@ var TechnologyService = class extends BaseService {
|
|
|
19434
19555
|
...doc45.data()
|
|
19435
19556
|
})
|
|
19436
19557
|
);
|
|
19558
|
+
const filteredTechnologies = this.filterExcludedTechnologies(technologies);
|
|
19437
19559
|
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
19438
|
-
return { technologies, lastVisible: newLastVisible };
|
|
19560
|
+
return { technologies: filteredTechnologies, lastVisible: newLastVisible };
|
|
19439
19561
|
}
|
|
19440
19562
|
/**
|
|
19441
19563
|
* Updates an existing technology.
|
|
@@ -19493,6 +19615,22 @@ var TechnologyService = class extends BaseService {
|
|
|
19493
19615
|
* @returns The technology or null if it doesn't exist.
|
|
19494
19616
|
*/
|
|
19495
19617
|
async getById(id) {
|
|
19618
|
+
if (id === EXCLUDED_TECHNOLOGY_ID) return null;
|
|
19619
|
+
const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
|
|
19620
|
+
const docSnap = await (0, import_firestore61.getDoc)(docRef);
|
|
19621
|
+
if (!docSnap.exists()) return null;
|
|
19622
|
+
return {
|
|
19623
|
+
id: docSnap.id,
|
|
19624
|
+
...docSnap.data()
|
|
19625
|
+
};
|
|
19626
|
+
}
|
|
19627
|
+
/**
|
|
19628
|
+
* Internal method to get technology by ID without filtering.
|
|
19629
|
+
* Used internally for consultation procedures.
|
|
19630
|
+
* @param id - The ID of the requested technology
|
|
19631
|
+
* @returns The technology or null if it doesn't exist
|
|
19632
|
+
*/
|
|
19633
|
+
async getByIdInternal(id) {
|
|
19496
19634
|
const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
|
|
19497
19635
|
const docSnap = await (0, import_firestore61.getDoc)(docRef);
|
|
19498
19636
|
if (!docSnap.exists()) return null;
|
|
@@ -19501,6 +19639,27 @@ var TechnologyService = class extends BaseService {
|
|
|
19501
19639
|
...docSnap.data()
|
|
19502
19640
|
};
|
|
19503
19641
|
}
|
|
19642
|
+
/**
|
|
19643
|
+
* Finds a technology by exact name match.
|
|
19644
|
+
* Used for CSV import duplicate detection.
|
|
19645
|
+
* @param name - Exact name of the technology to find
|
|
19646
|
+
* @returns Technology if found, null otherwise
|
|
19647
|
+
*/
|
|
19648
|
+
async findByName(name) {
|
|
19649
|
+
const q = (0, import_firestore61.query)(
|
|
19650
|
+
this.technologiesRef,
|
|
19651
|
+
(0, import_firestore61.where)("name", "==", name),
|
|
19652
|
+
(0, import_firestore61.where)("isActive", "==", true)
|
|
19653
|
+
);
|
|
19654
|
+
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19655
|
+
if (snapshot.empty) return null;
|
|
19656
|
+
const doc45 = snapshot.docs[0];
|
|
19657
|
+
if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return null;
|
|
19658
|
+
return {
|
|
19659
|
+
id: doc45.id,
|
|
19660
|
+
...doc45.data()
|
|
19661
|
+
};
|
|
19662
|
+
}
|
|
19504
19663
|
/**
|
|
19505
19664
|
* Dodaje novi zahtev tehnologiji
|
|
19506
19665
|
* @param technologyId - ID tehnologije
|
|
@@ -19861,12 +20020,13 @@ var TechnologyService = class extends BaseService {
|
|
|
19861
20020
|
(0, import_firestore61.orderBy)("name")
|
|
19862
20021
|
);
|
|
19863
20022
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19864
|
-
|
|
20023
|
+
const technologies = snapshot.docs.map(
|
|
19865
20024
|
(doc45) => ({
|
|
19866
20025
|
id: doc45.id,
|
|
19867
20026
|
...doc45.data()
|
|
19868
20027
|
})
|
|
19869
20028
|
);
|
|
20029
|
+
return this.filterExcludedTechnologies(technologies);
|
|
19870
20030
|
}
|
|
19871
20031
|
/**
|
|
19872
20032
|
* Gets all active technologies for a subcategory for filter dropdowns.
|
|
@@ -19882,12 +20042,13 @@ var TechnologyService = class extends BaseService {
|
|
|
19882
20042
|
(0, import_firestore61.orderBy)("name")
|
|
19883
20043
|
);
|
|
19884
20044
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19885
|
-
|
|
20045
|
+
const technologies = snapshot.docs.map(
|
|
19886
20046
|
(doc45) => ({
|
|
19887
20047
|
id: doc45.id,
|
|
19888
20048
|
...doc45.data()
|
|
19889
20049
|
})
|
|
19890
20050
|
);
|
|
20051
|
+
return this.filterExcludedTechnologies(technologies);
|
|
19891
20052
|
}
|
|
19892
20053
|
/**
|
|
19893
20054
|
* Gets all active technologies for filter dropdowns.
|
|
@@ -19899,12 +20060,13 @@ var TechnologyService = class extends BaseService {
|
|
|
19899
20060
|
(0, import_firestore61.orderBy)("name")
|
|
19900
20061
|
);
|
|
19901
20062
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19902
|
-
|
|
20063
|
+
const technologies = snapshot.docs.map(
|
|
19903
20064
|
(doc45) => ({
|
|
19904
20065
|
id: doc45.id,
|
|
19905
20066
|
...doc45.data()
|
|
19906
20067
|
})
|
|
19907
20068
|
);
|
|
20069
|
+
return this.filterExcludedTechnologies(technologies);
|
|
19908
20070
|
}
|
|
19909
20071
|
// ==========================================
|
|
19910
20072
|
// NEW METHODS: Product assignment management
|
|
@@ -20070,6 +20232,7 @@ var TechnologyService = class extends BaseService {
|
|
|
20070
20232
|
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
20071
20233
|
if (snapshot.empty) break;
|
|
20072
20234
|
for (const d of snapshot.docs) {
|
|
20235
|
+
if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
|
|
20073
20236
|
const technology = { id: d.id, ...d.data() };
|
|
20074
20237
|
const productNames = await this.getProductNamesForTechnology(technology.id);
|
|
20075
20238
|
rows.push(this.technologyToCsvRow(technology, productNames));
|