@blackcode_sa/metaestetics-api 1.12.1 → 1.12.3
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 +64 -14
- package/dist/backoffice/index.d.ts +64 -14
- package/dist/backoffice/index.js +72 -53
- package/dist/backoffice/index.mjs +72 -53
- package/dist/index.d.mts +131 -19
- package/dist/index.d.ts +131 -19
- package/dist/index.js +141 -261
- package/dist/index.mjs +141 -261
- package/package.json +1 -1
- package/src/backoffice/services/FIXES_README.md +102 -0
- package/src/backoffice/services/category.service.ts +46 -27
- package/src/backoffice/services/product.service.ts +52 -74
- package/src/backoffice/services/technology.service.ts +99 -116
- package/src/backoffice/types/category.types.ts +28 -2
- package/src/backoffice/types/product.types.ts +10 -9
- package/src/backoffice/types/technology.types.ts +31 -59
- package/src/services/procedure/procedure.service.ts +275 -472
package/dist/index.mjs
CHANGED
|
@@ -15249,9 +15249,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15249
15249
|
return media;
|
|
15250
15250
|
}
|
|
15251
15251
|
if (media instanceof File || media instanceof Blob) {
|
|
15252
|
-
console.log(
|
|
15253
|
-
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
15254
|
-
);
|
|
15252
|
+
console.log(`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`);
|
|
15255
15253
|
const metadata = await this.mediaService.uploadMedia(
|
|
15256
15254
|
media,
|
|
15257
15255
|
ownerId,
|
|
@@ -15273,11 +15271,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15273
15271
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
15274
15272
|
const result = [];
|
|
15275
15273
|
for (const media of mediaArray) {
|
|
15276
|
-
const processedUrl = await this.processMedia(
|
|
15277
|
-
media,
|
|
15278
|
-
ownerId,
|
|
15279
|
-
collectionName
|
|
15280
|
-
);
|
|
15274
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
15281
15275
|
if (processedUrl) {
|
|
15282
15276
|
result.push(processedUrl);
|
|
15283
15277
|
}
|
|
@@ -15293,10 +15287,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15293
15287
|
async transformProductsMetadata(productsMetadata, technologyId) {
|
|
15294
15288
|
const transformedProducts = [];
|
|
15295
15289
|
for (const productData of productsMetadata) {
|
|
15296
|
-
const product = await this.productService.getById(
|
|
15297
|
-
technologyId,
|
|
15298
|
-
productData.productId
|
|
15299
|
-
);
|
|
15290
|
+
const product = await this.productService.getById(technologyId, productData.productId);
|
|
15300
15291
|
if (!product) {
|
|
15301
15292
|
throw new Error(
|
|
15302
15293
|
`Product with ID ${productData.productId} not found for technology ${technologyId}`
|
|
@@ -15323,41 +15314,23 @@ var ProcedureService = class extends BaseService {
|
|
|
15323
15314
|
const procedureId = this.generateId();
|
|
15324
15315
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
15325
15316
|
this.categoryService.getById(validatedData.categoryId),
|
|
15326
|
-
this.subcategoryService.getById(
|
|
15327
|
-
validatedData.categoryId,
|
|
15328
|
-
validatedData.subcategoryId
|
|
15329
|
-
),
|
|
15317
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
15330
15318
|
this.technologyService.getById(validatedData.technologyId),
|
|
15331
|
-
this.productService.getById(
|
|
15332
|
-
validatedData.technologyId,
|
|
15333
|
-
validatedData.productId
|
|
15334
|
-
)
|
|
15319
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId)
|
|
15335
15320
|
]);
|
|
15336
15321
|
if (!category || !subcategory || !technology || !product) {
|
|
15337
15322
|
throw new Error("One or more required base entities not found");
|
|
15338
15323
|
}
|
|
15339
|
-
const clinicRef = doc30(
|
|
15340
|
-
this.db,
|
|
15341
|
-
CLINICS_COLLECTION,
|
|
15342
|
-
validatedData.clinicBranchId
|
|
15343
|
-
);
|
|
15324
|
+
const clinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15344
15325
|
const clinicSnapshot = await getDoc32(clinicRef);
|
|
15345
15326
|
if (!clinicSnapshot.exists()) {
|
|
15346
|
-
throw new Error(
|
|
15347
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15348
|
-
);
|
|
15327
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
15349
15328
|
}
|
|
15350
15329
|
const clinic = clinicSnapshot.data();
|
|
15351
|
-
const practitionerRef = doc30(
|
|
15352
|
-
this.db,
|
|
15353
|
-
PRACTITIONERS_COLLECTION,
|
|
15354
|
-
validatedData.practitionerId
|
|
15355
|
-
);
|
|
15330
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, validatedData.practitionerId);
|
|
15356
15331
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
15357
15332
|
if (!practitionerSnapshot.exists()) {
|
|
15358
|
-
throw new Error(
|
|
15359
|
-
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
15360
|
-
);
|
|
15333
|
+
throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
|
|
15361
15334
|
}
|
|
15362
15335
|
const practitioner = practitionerSnapshot.data();
|
|
15363
15336
|
let processedPhotos = [];
|
|
@@ -15389,9 +15362,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15389
15362
|
rating: ((_a = practitioner.reviewInfo) == null ? void 0 : _a.averageRating) || 0,
|
|
15390
15363
|
services: practitioner.procedures || []
|
|
15391
15364
|
};
|
|
15365
|
+
const { productsMetadata: _, ...validatedDataWithoutProductsMetadata } = validatedData;
|
|
15392
15366
|
const newProcedure = {
|
|
15393
15367
|
id: procedureId,
|
|
15394
|
-
...
|
|
15368
|
+
...validatedDataWithoutProductsMetadata,
|
|
15395
15369
|
// Ensure nameLower is always set even if omitted by client
|
|
15396
15370
|
nameLower: validatedData.nameLower || validatedData.name.toLowerCase(),
|
|
15397
15371
|
photos: processedPhotos,
|
|
@@ -15401,6 +15375,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15401
15375
|
technology,
|
|
15402
15376
|
product,
|
|
15403
15377
|
productsMetadata: transformedProductsMetadata,
|
|
15378
|
+
// Use transformed data, not original
|
|
15404
15379
|
blockingConditions: technology.blockingConditions,
|
|
15405
15380
|
contraindications: technology.contraindications || [],
|
|
15406
15381
|
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
@@ -15454,24 +15429,16 @@ var ProcedureService = class extends BaseService {
|
|
|
15454
15429
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
15455
15430
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
15456
15431
|
this.categoryService.getById(validatedData.categoryId),
|
|
15457
|
-
this.subcategoryService.getById(
|
|
15458
|
-
validatedData.categoryId,
|
|
15459
|
-
validatedData.subcategoryId
|
|
15460
|
-
),
|
|
15432
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
15461
15433
|
this.technologyService.getById(validatedData.technologyId),
|
|
15462
|
-
this.productService.getById(
|
|
15463
|
-
validatedData.technologyId,
|
|
15464
|
-
validatedData.productId
|
|
15465
|
-
),
|
|
15434
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId),
|
|
15466
15435
|
getDoc32(doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
15467
15436
|
]);
|
|
15468
15437
|
if (!category || !subcategory || !technology || !product) {
|
|
15469
15438
|
throw new Error("One or more required base entities not found");
|
|
15470
15439
|
}
|
|
15471
15440
|
if (!clinicSnapshot.exists()) {
|
|
15472
|
-
throw new Error(
|
|
15473
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15474
|
-
);
|
|
15441
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
15475
15442
|
}
|
|
15476
15443
|
const clinic = clinicSnapshot.data();
|
|
15477
15444
|
let processedPhotos = [];
|
|
@@ -15501,12 +15468,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15501
15468
|
}
|
|
15502
15469
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
15503
15470
|
const foundIds = Array.from(practitionersMap.keys());
|
|
15504
|
-
const notFoundIds = practitionerIds.filter(
|
|
15505
|
-
|
|
15506
|
-
);
|
|
15507
|
-
throw new Error(
|
|
15508
|
-
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
15509
|
-
);
|
|
15471
|
+
const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
|
|
15472
|
+
throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
|
|
15510
15473
|
}
|
|
15511
15474
|
const batch = writeBatch6(this.db);
|
|
15512
15475
|
const createdProcedureIds = [];
|
|
@@ -15531,9 +15494,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15531
15494
|
const procedureId = this.generateId();
|
|
15532
15495
|
createdProcedureIds.push(procedureId);
|
|
15533
15496
|
const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
15497
|
+
const { productsMetadata: _, ...validatedDataWithoutProductsMetadata } = validatedData;
|
|
15534
15498
|
const newProcedure = {
|
|
15535
15499
|
id: procedureId,
|
|
15536
|
-
...
|
|
15500
|
+
...validatedDataWithoutProductsMetadata,
|
|
15537
15501
|
nameLower: validatedData.nameLower || validatedData.name.toLowerCase(),
|
|
15538
15502
|
practitionerId,
|
|
15539
15503
|
// Override practitionerId with the correct one
|
|
@@ -15543,6 +15507,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15543
15507
|
technology,
|
|
15544
15508
|
product,
|
|
15545
15509
|
productsMetadata: transformedProductsMetadata,
|
|
15510
|
+
// Use transformed data, not original
|
|
15546
15511
|
blockingConditions: technology.blockingConditions,
|
|
15547
15512
|
contraindications: technology.contraindications || [],
|
|
15548
15513
|
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
@@ -15577,10 +15542,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15577
15542
|
const fetchedProcedures = [];
|
|
15578
15543
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
15579
15544
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
15580
|
-
const q = query29(
|
|
15581
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15582
|
-
where29(documentId2(), "in", chunk)
|
|
15583
|
-
);
|
|
15545
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), where29(documentId2(), "in", chunk));
|
|
15584
15546
|
const snapshot = await getDocs29(q);
|
|
15585
15547
|
snapshot.forEach((doc38) => {
|
|
15586
15548
|
fetchedProcedures.push(doc38.data());
|
|
@@ -15659,12 +15621,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15659
15621
|
}
|
|
15660
15622
|
const existingProcedure = procedureSnapshot.data();
|
|
15661
15623
|
let updatedProcedureData = {};
|
|
15662
|
-
if (validatedData.name !== void 0)
|
|
15663
|
-
updatedProcedureData.name = validatedData.name;
|
|
15624
|
+
if (validatedData.name !== void 0) updatedProcedureData.name = validatedData.name;
|
|
15664
15625
|
if (validatedData.description !== void 0)
|
|
15665
15626
|
updatedProcedureData.description = validatedData.description;
|
|
15666
|
-
if (validatedData.price !== void 0)
|
|
15667
|
-
updatedProcedureData.price = validatedData.price;
|
|
15627
|
+
if (validatedData.price !== void 0) updatedProcedureData.price = validatedData.price;
|
|
15668
15628
|
if (validatedData.currency !== void 0)
|
|
15669
15629
|
updatedProcedureData.currency = validatedData.currency;
|
|
15670
15630
|
if (validatedData.pricingMeasure !== void 0)
|
|
@@ -15689,9 +15649,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15689
15649
|
if (validatedData.productsMetadata !== void 0) {
|
|
15690
15650
|
const technologyId = (_a = validatedData.technologyId) != null ? _a : existingProcedure.technology.id;
|
|
15691
15651
|
if (!technologyId) {
|
|
15692
|
-
throw new Error(
|
|
15693
|
-
"Technology ID is required for updating products metadata"
|
|
15694
|
-
);
|
|
15652
|
+
throw new Error("Technology ID is required for updating products metadata");
|
|
15695
15653
|
}
|
|
15696
15654
|
updatedProcedureData.productsMetadata = await this.transformProductsMetadata(
|
|
15697
15655
|
validatedData.productsMetadata,
|
|
@@ -15707,9 +15665,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15707
15665
|
);
|
|
15708
15666
|
const newPractitionerSnap = await getDoc32(newPractitionerRef);
|
|
15709
15667
|
if (!newPractitionerSnap.exists())
|
|
15710
|
-
throw new Error(
|
|
15711
|
-
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15712
|
-
);
|
|
15668
|
+
throw new Error(`New Practitioner ${validatedData.practitionerId} not found`);
|
|
15713
15669
|
newPractitioner = newPractitionerSnap.data();
|
|
15714
15670
|
updatedProcedureData.doctorInfo = {
|
|
15715
15671
|
id: newPractitioner.id,
|
|
@@ -15723,11 +15679,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15723
15679
|
}
|
|
15724
15680
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15725
15681
|
clinicChanged = true;
|
|
15726
|
-
const newClinicRef = doc30(
|
|
15727
|
-
this.db,
|
|
15728
|
-
CLINICS_COLLECTION,
|
|
15729
|
-
validatedData.clinicBranchId
|
|
15730
|
-
);
|
|
15682
|
+
const newClinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15731
15683
|
const newClinicSnap = await getDoc32(newClinicRef);
|
|
15732
15684
|
if (!newClinicSnap.exists())
|
|
15733
15685
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
@@ -15746,11 +15698,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15746
15698
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15747
15699
|
}
|
|
15748
15700
|
if (validatedData.categoryId) {
|
|
15749
|
-
const category = await this.categoryService.getById(
|
|
15750
|
-
|
|
15751
|
-
);
|
|
15752
|
-
if (!category)
|
|
15753
|
-
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15701
|
+
const category = await this.categoryService.getById(validatedData.categoryId);
|
|
15702
|
+
if (!category) throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15754
15703
|
updatedProcedureData.category = category;
|
|
15755
15704
|
finalCategoryId = category.id;
|
|
15756
15705
|
}
|
|
@@ -15765,17 +15714,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15765
15714
|
);
|
|
15766
15715
|
updatedProcedureData.subcategory = subcategory;
|
|
15767
15716
|
} else if (validatedData.subcategoryId) {
|
|
15768
|
-
console.warn(
|
|
15769
|
-
"Attempted to update subcategory without a valid categoryId"
|
|
15770
|
-
);
|
|
15717
|
+
console.warn("Attempted to update subcategory without a valid categoryId");
|
|
15771
15718
|
}
|
|
15772
15719
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15773
15720
|
if (validatedData.technologyId) {
|
|
15774
|
-
const technology = await this.technologyService.getById(
|
|
15775
|
-
|
|
15776
|
-
);
|
|
15777
|
-
if (!technology)
|
|
15778
|
-
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15721
|
+
const technology = await this.technologyService.getById(validatedData.technologyId);
|
|
15722
|
+
if (!technology) throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15779
15723
|
updatedProcedureData.technology = technology;
|
|
15780
15724
|
finalTechnologyId = technology.id;
|
|
15781
15725
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
@@ -15789,10 +15733,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15789
15733
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15790
15734
|
}
|
|
15791
15735
|
if (validatedData.productId && finalTechnologyId) {
|
|
15792
|
-
const product = await this.productService.getById(
|
|
15793
|
-
finalTechnologyId,
|
|
15794
|
-
validatedData.productId
|
|
15795
|
-
);
|
|
15736
|
+
const product = await this.productService.getById(finalTechnologyId, validatedData.productId);
|
|
15796
15737
|
if (!product)
|
|
15797
15738
|
throw new Error(
|
|
15798
15739
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15874,11 +15815,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15874
15815
|
limit21(pagination)
|
|
15875
15816
|
);
|
|
15876
15817
|
} else {
|
|
15877
|
-
proceduresQuery = query29(
|
|
15878
|
-
proceduresCollection,
|
|
15879
|
-
orderBy17("name"),
|
|
15880
|
-
limit21(pagination)
|
|
15881
|
-
);
|
|
15818
|
+
proceduresQuery = query29(proceduresCollection, orderBy17("name"), limit21(pagination));
|
|
15882
15819
|
}
|
|
15883
15820
|
} else {
|
|
15884
15821
|
proceduresQuery = query29(proceduresCollection, orderBy17("name"));
|
|
@@ -15927,9 +15864,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15927
15864
|
*/
|
|
15928
15865
|
async getProceduresByFilters(filters) {
|
|
15929
15866
|
try {
|
|
15930
|
-
console.log(
|
|
15931
|
-
"[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies"
|
|
15932
|
-
);
|
|
15867
|
+
console.log("[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies");
|
|
15933
15868
|
if (filters.location && filters.radiusInKm) {
|
|
15934
15869
|
console.log("[PROCEDURE_SERVICE] Executing geo query:", {
|
|
15935
15870
|
location: filters.location,
|
|
@@ -15937,10 +15872,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15937
15872
|
serviceName: "ProcedureService"
|
|
15938
15873
|
});
|
|
15939
15874
|
if (!filters.location.latitude || !filters.location.longitude) {
|
|
15940
|
-
console.warn(
|
|
15941
|
-
"[PROCEDURE_SERVICE] Invalid location data:",
|
|
15942
|
-
filters.location
|
|
15943
|
-
);
|
|
15875
|
+
console.warn("[PROCEDURE_SERVICE] Invalid location data:", filters.location);
|
|
15944
15876
|
filters.location = void 0;
|
|
15945
15877
|
filters.radiusInKm = void 0;
|
|
15946
15878
|
}
|
|
@@ -15960,19 +15892,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15960
15892
|
constraints.push(where29("family", "==", filters.procedureFamily));
|
|
15961
15893
|
}
|
|
15962
15894
|
if (filters.procedureCategory) {
|
|
15963
|
-
constraints.push(
|
|
15964
|
-
where29("category.id", "==", filters.procedureCategory)
|
|
15965
|
-
);
|
|
15895
|
+
constraints.push(where29("category.id", "==", filters.procedureCategory));
|
|
15966
15896
|
}
|
|
15967
15897
|
if (filters.procedureSubcategory) {
|
|
15968
|
-
constraints.push(
|
|
15969
|
-
where29("subcategory.id", "==", filters.procedureSubcategory)
|
|
15970
|
-
);
|
|
15898
|
+
constraints.push(where29("subcategory.id", "==", filters.procedureSubcategory));
|
|
15971
15899
|
}
|
|
15972
15900
|
if (filters.procedureTechnology) {
|
|
15973
|
-
constraints.push(
|
|
15974
|
-
where29("technology.id", "==", filters.procedureTechnology)
|
|
15975
|
-
);
|
|
15901
|
+
constraints.push(where29("technology.id", "==", filters.procedureTechnology));
|
|
15976
15902
|
}
|
|
15977
15903
|
if (filters.minPrice !== void 0) {
|
|
15978
15904
|
constraints.push(where29("price", ">=", filters.minPrice));
|
|
@@ -15981,32 +15907,20 @@ var ProcedureService = class extends BaseService {
|
|
|
15981
15907
|
constraints.push(where29("price", "<=", filters.maxPrice));
|
|
15982
15908
|
}
|
|
15983
15909
|
if (filters.minRating !== void 0) {
|
|
15984
|
-
constraints.push(
|
|
15985
|
-
where29("reviewInfo.averageRating", ">=", filters.minRating)
|
|
15986
|
-
);
|
|
15910
|
+
constraints.push(where29("reviewInfo.averageRating", ">=", filters.minRating));
|
|
15987
15911
|
}
|
|
15988
15912
|
if (filters.maxRating !== void 0) {
|
|
15989
|
-
constraints.push(
|
|
15990
|
-
where29("reviewInfo.averageRating", "<=", filters.maxRating)
|
|
15991
|
-
);
|
|
15913
|
+
constraints.push(where29("reviewInfo.averageRating", "<=", filters.maxRating));
|
|
15992
15914
|
}
|
|
15993
15915
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15994
15916
|
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15995
|
-
constraints.push(
|
|
15996
|
-
where29(
|
|
15997
|
-
"treatmentBenefitIds",
|
|
15998
|
-
"array-contains-any",
|
|
15999
|
-
benefitIdsToMatch
|
|
16000
|
-
)
|
|
16001
|
-
);
|
|
15917
|
+
constraints.push(where29("treatmentBenefitIds", "array-contains-any", benefitIdsToMatch));
|
|
16002
15918
|
}
|
|
16003
15919
|
return constraints;
|
|
16004
15920
|
};
|
|
16005
15921
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
16006
15922
|
try {
|
|
16007
|
-
console.log(
|
|
16008
|
-
"[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search"
|
|
16009
|
-
);
|
|
15923
|
+
console.log("[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search");
|
|
16010
15924
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
16011
15925
|
const constraints = getBaseConstraints();
|
|
16012
15926
|
constraints.push(where29("nameLower", ">=", searchTerm));
|
|
@@ -16022,18 +15936,13 @@ var ProcedureService = class extends BaseService {
|
|
|
16022
15936
|
}
|
|
16023
15937
|
}
|
|
16024
15938
|
constraints.push(limit15(filters.pagination || 10));
|
|
16025
|
-
const q = query29(
|
|
16026
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
16027
|
-
...constraints
|
|
16028
|
-
);
|
|
15939
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
16029
15940
|
const querySnapshot = await getDocs29(q);
|
|
16030
15941
|
const procedures = querySnapshot.docs.map(
|
|
16031
15942
|
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
16032
15943
|
);
|
|
16033
15944
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
16034
|
-
console.log(
|
|
16035
|
-
`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`
|
|
16036
|
-
);
|
|
15945
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
|
|
16037
15946
|
if (procedures.length < (filters.pagination || 10)) {
|
|
16038
15947
|
return { procedures, lastDoc: null };
|
|
16039
15948
|
}
|
|
@@ -16044,9 +15953,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16044
15953
|
}
|
|
16045
15954
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
16046
15955
|
try {
|
|
16047
|
-
console.log(
|
|
16048
|
-
"[PROCEDURE_SERVICE] Strategy 2: Trying name field search"
|
|
16049
|
-
);
|
|
15956
|
+
console.log("[PROCEDURE_SERVICE] Strategy 2: Trying name field search");
|
|
16050
15957
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
16051
15958
|
const constraints = getBaseConstraints();
|
|
16052
15959
|
constraints.push(where29("name", ">=", searchTerm));
|
|
@@ -16062,18 +15969,13 @@ var ProcedureService = class extends BaseService {
|
|
|
16062
15969
|
}
|
|
16063
15970
|
}
|
|
16064
15971
|
constraints.push(limit15(filters.pagination || 10));
|
|
16065
|
-
const q = query29(
|
|
16066
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
16067
|
-
...constraints
|
|
16068
|
-
);
|
|
15972
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
16069
15973
|
const querySnapshot = await getDocs29(q);
|
|
16070
15974
|
const procedures = querySnapshot.docs.map(
|
|
16071
15975
|
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
16072
15976
|
);
|
|
16073
15977
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
16074
|
-
console.log(
|
|
16075
|
-
`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`
|
|
16076
|
-
);
|
|
15978
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
|
|
16077
15979
|
if (procedures.length < (filters.pagination || 10)) {
|
|
16078
15980
|
return { procedures, lastDoc: null };
|
|
16079
15981
|
}
|
|
@@ -16098,19 +16000,14 @@ var ProcedureService = class extends BaseService {
|
|
|
16098
16000
|
}
|
|
16099
16001
|
}
|
|
16100
16002
|
constraints.push(limit15(filters.pagination || 10));
|
|
16101
|
-
const q = query29(
|
|
16102
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
16103
|
-
...constraints
|
|
16104
|
-
);
|
|
16003
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
16105
16004
|
const querySnapshot = await getDocs29(q);
|
|
16106
16005
|
let procedures = querySnapshot.docs.map(
|
|
16107
16006
|
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
16108
16007
|
);
|
|
16109
16008
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
16110
16009
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
16111
|
-
console.log(
|
|
16112
|
-
`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`
|
|
16113
|
-
);
|
|
16010
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
|
|
16114
16011
|
if (procedures.length < (filters.pagination || 10)) {
|
|
16115
16012
|
return { procedures, lastDoc: null };
|
|
16116
16013
|
}
|
|
@@ -16125,19 +16022,14 @@ var ProcedureService = class extends BaseService {
|
|
|
16125
16022
|
orderBy17("createdAt", "desc"),
|
|
16126
16023
|
limit15(filters.pagination || 10)
|
|
16127
16024
|
];
|
|
16128
|
-
const q = query29(
|
|
16129
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
16130
|
-
...constraints
|
|
16131
|
-
);
|
|
16025
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
16132
16026
|
const querySnapshot = await getDocs29(q);
|
|
16133
16027
|
let procedures = querySnapshot.docs.map(
|
|
16134
16028
|
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
16135
16029
|
);
|
|
16136
16030
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
16137
16031
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
16138
|
-
console.log(
|
|
16139
|
-
`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`
|
|
16140
|
-
);
|
|
16032
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
|
|
16141
16033
|
if (procedures.length < (filters.pagination || 10)) {
|
|
16142
16034
|
return { procedures, lastDoc: null };
|
|
16143
16035
|
}
|
|
@@ -16145,9 +16037,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16145
16037
|
} catch (error) {
|
|
16146
16038
|
console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
|
|
16147
16039
|
}
|
|
16148
|
-
console.log(
|
|
16149
|
-
"[PROCEDURE_SERVICE] All strategies failed, returning empty result"
|
|
16150
|
-
);
|
|
16040
|
+
console.log("[PROCEDURE_SERVICE] All strategies failed, returning empty result");
|
|
16151
16041
|
return { procedures: [], lastDoc: null };
|
|
16152
16042
|
} catch (error) {
|
|
16153
16043
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
@@ -16167,17 +16057,13 @@ var ProcedureService = class extends BaseService {
|
|
|
16167
16057
|
const nameLower = procedure.nameLower || "";
|
|
16168
16058
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
16169
16059
|
});
|
|
16170
|
-
console.log(
|
|
16171
|
-
`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`
|
|
16172
|
-
);
|
|
16060
|
+
console.log(`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`);
|
|
16173
16061
|
}
|
|
16174
16062
|
if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
|
|
16175
16063
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
16176
16064
|
const price = procedure.price || 0;
|
|
16177
|
-
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
16178
|
-
|
|
16179
|
-
if (filters.maxPrice !== void 0 && price > filters.maxPrice)
|
|
16180
|
-
return false;
|
|
16065
|
+
if (filters.minPrice !== void 0 && price < filters.minPrice) return false;
|
|
16066
|
+
if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
|
|
16181
16067
|
return true;
|
|
16182
16068
|
});
|
|
16183
16069
|
console.log(
|
|
@@ -16188,10 +16074,8 @@ var ProcedureService = class extends BaseService {
|
|
|
16188
16074
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
16189
16075
|
var _a;
|
|
16190
16076
|
const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
|
|
16191
|
-
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
16192
|
-
|
|
16193
|
-
if (filters.maxRating !== void 0 && rating > filters.maxRating)
|
|
16194
|
-
return false;
|
|
16077
|
+
if (filters.minRating !== void 0 && rating < filters.minRating) return false;
|
|
16078
|
+
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
16195
16079
|
return true;
|
|
16196
16080
|
});
|
|
16197
16081
|
console.log(
|
|
@@ -16267,12 +16151,8 @@ var ProcedureService = class extends BaseService {
|
|
|
16267
16151
|
procedure.distance = distance;
|
|
16268
16152
|
return distance <= radiusInKm;
|
|
16269
16153
|
});
|
|
16270
|
-
console.log(
|
|
16271
|
-
|
|
16272
|
-
);
|
|
16273
|
-
filteredProcedures.sort(
|
|
16274
|
-
(a, b) => (a.distance || 0) - (b.distance || 0)
|
|
16275
|
-
);
|
|
16154
|
+
console.log(`[PROCEDURE_SERVICE] Applied geo filter, results: ${filteredProcedures.length}`);
|
|
16155
|
+
filteredProcedures.sort((a, b) => (a.distance || 0) - (b.distance || 0));
|
|
16276
16156
|
}
|
|
16277
16157
|
return filteredProcedures;
|
|
16278
16158
|
}
|
|
@@ -16284,30 +16164,19 @@ var ProcedureService = class extends BaseService {
|
|
|
16284
16164
|
if (!location || !radiusInKm) {
|
|
16285
16165
|
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
16286
16166
|
}
|
|
16287
|
-
const bounds = geohashQueryBounds5(
|
|
16288
|
-
[location.latitude, location.longitude],
|
|
16289
|
-
radiusInKm * 1e3
|
|
16290
|
-
);
|
|
16167
|
+
const bounds = geohashQueryBounds5([location.latitude, location.longitude], radiusInKm * 1e3);
|
|
16291
16168
|
const fetches = bounds.map((b) => {
|
|
16292
16169
|
const constraints = [
|
|
16293
16170
|
where29("clinicInfo.location.geohash", ">=", b[0]),
|
|
16294
16171
|
where29("clinicInfo.location.geohash", "<=", b[1]),
|
|
16295
|
-
where29(
|
|
16296
|
-
"isActive",
|
|
16297
|
-
"==",
|
|
16298
|
-
filters.isActive !== void 0 ? filters.isActive : true
|
|
16299
|
-
)
|
|
16172
|
+
where29("isActive", "==", filters.isActive !== void 0 ? filters.isActive : true)
|
|
16300
16173
|
];
|
|
16301
|
-
return getDocs29(
|
|
16302
|
-
query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints)
|
|
16303
|
-
);
|
|
16174
|
+
return getDocs29(query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints));
|
|
16304
16175
|
});
|
|
16305
16176
|
return Promise.all(fetches).then((snaps) => {
|
|
16306
16177
|
const collected = [];
|
|
16307
16178
|
snaps.forEach((snap) => {
|
|
16308
|
-
snap.docs.forEach(
|
|
16309
|
-
(d) => collected.push({ ...d.data(), id: d.id })
|
|
16310
|
-
);
|
|
16179
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
16311
16180
|
});
|
|
16312
16181
|
const uniqueMap = /* @__PURE__ */ new Map();
|
|
16313
16182
|
for (const p of collected) {
|
|
@@ -16318,9 +16187,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16318
16187
|
const pageSize = filters.pagination || 10;
|
|
16319
16188
|
let startIndex = 0;
|
|
16320
16189
|
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
16321
|
-
const idx = procedures.findIndex(
|
|
16322
|
-
(p) => p.id === filters.lastDoc.id
|
|
16323
|
-
);
|
|
16190
|
+
const idx = procedures.findIndex((p) => p.id === filters.lastDoc.id);
|
|
16324
16191
|
if (idx >= 0) startIndex = idx + 1;
|
|
16325
16192
|
}
|
|
16326
16193
|
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
@@ -16361,11 +16228,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16361
16228
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
16362
16229
|
}
|
|
16363
16230
|
const clinic = clinicSnapshot.data();
|
|
16364
|
-
const practitionerRef = doc30(
|
|
16365
|
-
this.db,
|
|
16366
|
-
PRACTITIONERS_COLLECTION,
|
|
16367
|
-
data.practitionerId
|
|
16368
|
-
);
|
|
16231
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, data.practitionerId);
|
|
16369
16232
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
16370
16233
|
if (!practitionerSnapshot.exists()) {
|
|
16371
16234
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
@@ -16373,11 +16236,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16373
16236
|
const practitioner = practitionerSnapshot.data();
|
|
16374
16237
|
let processedPhotos = [];
|
|
16375
16238
|
if (data.photos && data.photos.length > 0) {
|
|
16376
|
-
processedPhotos = await this.processMediaArray(
|
|
16377
|
-
data.photos,
|
|
16378
|
-
procedureId,
|
|
16379
|
-
"procedure-photos"
|
|
16380
|
-
);
|
|
16239
|
+
processedPhotos = await this.processMediaArray(data.photos, procedureId, "procedure-photos");
|
|
16381
16240
|
}
|
|
16382
16241
|
const transformedProductsMetadata = await this.transformProductsMetadata(
|
|
16383
16242
|
data.productsMetadata,
|
|
@@ -16413,9 +16272,10 @@ var ProcedureService = class extends BaseService {
|
|
|
16413
16272
|
createdAt: /* @__PURE__ */ new Date(),
|
|
16414
16273
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16415
16274
|
};
|
|
16275
|
+
const { productsMetadata: _, ...dataWithoutProductsMetadata } = data;
|
|
16416
16276
|
const newProcedure = {
|
|
16417
16277
|
id: procedureId,
|
|
16418
|
-
...
|
|
16278
|
+
...dataWithoutProductsMetadata,
|
|
16419
16279
|
nameLower: data.nameLower || data.name.toLowerCase(),
|
|
16420
16280
|
photos: processedPhotos,
|
|
16421
16281
|
category,
|
|
@@ -16424,6 +16284,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16424
16284
|
product: consultationProduct,
|
|
16425
16285
|
// Use placeholder product
|
|
16426
16286
|
productsMetadata: transformedProductsMetadata,
|
|
16287
|
+
// Use transformed data, not original
|
|
16427
16288
|
blockingConditions: technology.blockingConditions,
|
|
16428
16289
|
contraindications: technology.contraindications || [],
|
|
16429
16290
|
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
@@ -16968,6 +16829,26 @@ var CategoryService = class extends BaseService {
|
|
|
16968
16829
|
})
|
|
16969
16830
|
);
|
|
16970
16831
|
}
|
|
16832
|
+
/**
|
|
16833
|
+
* Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
|
|
16834
|
+
* @param family - Familija procedura (aesthetics/surgery)
|
|
16835
|
+
* @returns Lista aktivnih kategorija koje pripadaju traženoj familiji
|
|
16836
|
+
*/
|
|
16837
|
+
async getAllForFilterByFamily(family) {
|
|
16838
|
+
const q = query32(
|
|
16839
|
+
this.categoriesRef,
|
|
16840
|
+
where32("family", "==", family),
|
|
16841
|
+
where32("isActive", "==", true),
|
|
16842
|
+
orderBy19("name")
|
|
16843
|
+
);
|
|
16844
|
+
const snapshot = await getDocs32(q);
|
|
16845
|
+
return snapshot.docs.map(
|
|
16846
|
+
(doc38) => ({
|
|
16847
|
+
id: doc38.id,
|
|
16848
|
+
...doc38.data()
|
|
16849
|
+
})
|
|
16850
|
+
);
|
|
16851
|
+
}
|
|
16971
16852
|
/**
|
|
16972
16853
|
* Vraća sve kategorije sa paginacijom
|
|
16973
16854
|
* @param options - Pagination and filter options
|
|
@@ -17631,7 +17512,9 @@ var TechnologyService = class extends BaseService {
|
|
|
17631
17512
|
if (!technology) {
|
|
17632
17513
|
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17633
17514
|
}
|
|
17634
|
-
const updatedContraindications = (technology.contraindications || []).filter(
|
|
17515
|
+
const updatedContraindications = (technology.contraindications || []).filter(
|
|
17516
|
+
(c) => c.id !== contraindication.id
|
|
17517
|
+
);
|
|
17635
17518
|
await updateDoc33(docRef, {
|
|
17636
17519
|
contraindications: updatedContraindications,
|
|
17637
17520
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -17652,9 +17535,7 @@ var TechnologyService = class extends BaseService {
|
|
|
17652
17535
|
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17653
17536
|
}
|
|
17654
17537
|
const contraindications = technology.contraindications || [];
|
|
17655
|
-
const index = contraindications.findIndex(
|
|
17656
|
-
(c) => c.id === contraindication.id
|
|
17657
|
-
);
|
|
17538
|
+
const index = contraindications.findIndex((c) => c.id === contraindication.id);
|
|
17658
17539
|
if (index === -1) {
|
|
17659
17540
|
console.warn(
|
|
17660
17541
|
`Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
|
|
@@ -17703,9 +17584,7 @@ var TechnologyService = class extends BaseService {
|
|
|
17703
17584
|
if (!technology) {
|
|
17704
17585
|
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17705
17586
|
}
|
|
17706
|
-
const updatedBenefits = (technology.benefits || []).filter(
|
|
17707
|
-
(b) => b.id !== benefit.id
|
|
17708
|
-
);
|
|
17587
|
+
const updatedBenefits = (technology.benefits || []).filter((b) => b.id !== benefit.id);
|
|
17709
17588
|
await updateDoc33(docRef, {
|
|
17710
17589
|
benefits: updatedBenefits,
|
|
17711
17590
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -17811,9 +17690,7 @@ var TechnologyService = class extends BaseService {
|
|
|
17811
17690
|
* );
|
|
17812
17691
|
*/
|
|
17813
17692
|
validateCertification(requiredCertification, practitionerCertification) {
|
|
17814
|
-
const doctorLevel = Object.values(CertificationLevel).indexOf(
|
|
17815
|
-
practitionerCertification.level
|
|
17816
|
-
);
|
|
17693
|
+
const doctorLevel = Object.values(CertificationLevel).indexOf(practitionerCertification.level);
|
|
17817
17694
|
const requiredLevel = Object.values(CertificationLevel).indexOf(
|
|
17818
17695
|
requiredCertification.minimumLevel
|
|
17819
17696
|
);
|
|
@@ -17854,18 +17731,11 @@ var TechnologyService = class extends BaseService {
|
|
|
17854
17731
|
async getAllowedTechnologies(practitioner) {
|
|
17855
17732
|
const allTechnologies = await this.getAll();
|
|
17856
17733
|
const allowedTechnologies = allTechnologies.technologies.filter(
|
|
17857
|
-
(technology) => this.validateCertification(
|
|
17858
|
-
technology.certificationRequirement,
|
|
17859
|
-
practitioner.certification
|
|
17860
|
-
)
|
|
17734
|
+
(technology) => this.validateCertification(technology.certificationRequirement, practitioner.certification)
|
|
17861
17735
|
);
|
|
17862
17736
|
const families = [...new Set(allowedTechnologies.map((t) => t.family))];
|
|
17863
|
-
const categories = [
|
|
17864
|
-
|
|
17865
|
-
];
|
|
17866
|
-
const subcategories = [
|
|
17867
|
-
...new Set(allowedTechnologies.map((t) => t.subcategoryId))
|
|
17868
|
-
];
|
|
17737
|
+
const categories = [...new Set(allowedTechnologies.map((t) => t.categoryId))];
|
|
17738
|
+
const subcategories = [...new Set(allowedTechnologies.map((t) => t.subcategoryId))];
|
|
17869
17739
|
return {
|
|
17870
17740
|
technologies: allowedTechnologies,
|
|
17871
17741
|
families,
|
|
@@ -17873,6 +17743,25 @@ var TechnologyService = class extends BaseService {
|
|
|
17873
17743
|
subcategories
|
|
17874
17744
|
};
|
|
17875
17745
|
}
|
|
17746
|
+
/**
|
|
17747
|
+
* Gets all active technologies for a subcategory for filter dropdowns (by subcategory only).
|
|
17748
|
+
* @param subcategoryId - The ID of the subcategory.
|
|
17749
|
+
*/
|
|
17750
|
+
async getAllForFilterBySubcategory(subcategoryId) {
|
|
17751
|
+
const q = query34(
|
|
17752
|
+
collection34(this.db, TECHNOLOGIES_COLLECTION),
|
|
17753
|
+
where34("isActive", "==", true),
|
|
17754
|
+
where34("subcategoryId", "==", subcategoryId),
|
|
17755
|
+
orderBy21("name")
|
|
17756
|
+
);
|
|
17757
|
+
const snapshot = await getDocs34(q);
|
|
17758
|
+
return snapshot.docs.map(
|
|
17759
|
+
(doc38) => ({
|
|
17760
|
+
id: doc38.id,
|
|
17761
|
+
...doc38.data()
|
|
17762
|
+
})
|
|
17763
|
+
);
|
|
17764
|
+
}
|
|
17876
17765
|
/**
|
|
17877
17766
|
* Gets all active technologies for a subcategory for filter dropdowns.
|
|
17878
17767
|
* @param categoryId - The ID of the parent category.
|
|
@@ -17941,12 +17830,7 @@ var ProductService = class extends BaseService {
|
|
|
17941
17830
|
* @returns Firestore collection reference
|
|
17942
17831
|
*/
|
|
17943
17832
|
getProductsRef(technologyId) {
|
|
17944
|
-
return collection35(
|
|
17945
|
-
this.db,
|
|
17946
|
-
TECHNOLOGIES_COLLECTION,
|
|
17947
|
-
technologyId,
|
|
17948
|
-
PRODUCTS_COLLECTION
|
|
17949
|
-
);
|
|
17833
|
+
return collection35(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
17950
17834
|
}
|
|
17951
17835
|
/**
|
|
17952
17836
|
* Creates a new product under technology
|
|
@@ -17961,10 +17845,7 @@ var ProductService = class extends BaseService {
|
|
|
17961
17845
|
updatedAt: now,
|
|
17962
17846
|
isActive: true
|
|
17963
17847
|
};
|
|
17964
|
-
const productRef = await addDoc7(
|
|
17965
|
-
this.getProductsRef(technologyId),
|
|
17966
|
-
newProduct
|
|
17967
|
-
);
|
|
17848
|
+
const productRef = await addDoc7(this.getProductsRef(technologyId), newProduct);
|
|
17968
17849
|
return { id: productRef.id, ...newProduct };
|
|
17969
17850
|
}
|
|
17970
17851
|
/**
|
|
@@ -17972,17 +17853,8 @@ var ProductService = class extends BaseService {
|
|
|
17972
17853
|
* This uses a collectionGroup query to search across all technologies.
|
|
17973
17854
|
*/
|
|
17974
17855
|
async getAll(options) {
|
|
17975
|
-
const {
|
|
17976
|
-
|
|
17977
|
-
lastVisible,
|
|
17978
|
-
categoryId,
|
|
17979
|
-
subcategoryId,
|
|
17980
|
-
technologyId
|
|
17981
|
-
} = options;
|
|
17982
|
-
const constraints = [
|
|
17983
|
-
where35("isActive", "==", true),
|
|
17984
|
-
orderBy22("name")
|
|
17985
|
-
];
|
|
17856
|
+
const { rowsPerPage, lastVisible, categoryId, subcategoryId, technologyId } = options;
|
|
17857
|
+
const constraints = [where35("isActive", "==", true), orderBy22("name")];
|
|
17986
17858
|
if (categoryId) {
|
|
17987
17859
|
constraints.push(where35("categoryId", "==", categoryId));
|
|
17988
17860
|
}
|
|
@@ -17996,10 +17868,7 @@ var ProductService = class extends BaseService {
|
|
|
17996
17868
|
constraints.push(startAfter18(lastVisible));
|
|
17997
17869
|
}
|
|
17998
17870
|
constraints.push(limit20(rowsPerPage));
|
|
17999
|
-
const q = query35(
|
|
18000
|
-
collectionGroup3(this.db, PRODUCTS_COLLECTION),
|
|
18001
|
-
...constraints
|
|
18002
|
-
);
|
|
17871
|
+
const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), ...constraints);
|
|
18003
17872
|
const snapshot = await getDocs35(q);
|
|
18004
17873
|
const products = snapshot.docs.map(
|
|
18005
17874
|
(doc38) => ({
|
|
@@ -18025,10 +17894,7 @@ var ProductService = class extends BaseService {
|
|
|
18025
17894
|
if (technologyId) {
|
|
18026
17895
|
constraints.push(where35("technologyId", "==", technologyId));
|
|
18027
17896
|
}
|
|
18028
|
-
const q = query35(
|
|
18029
|
-
collectionGroup3(this.db, PRODUCTS_COLLECTION),
|
|
18030
|
-
...constraints
|
|
18031
|
-
);
|
|
17897
|
+
const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), ...constraints);
|
|
18032
17898
|
const snapshot = await getCountFromServer6(q);
|
|
18033
17899
|
return snapshot.data().count;
|
|
18034
17900
|
}
|
|
@@ -18037,10 +17903,7 @@ var ProductService = class extends BaseService {
|
|
|
18037
17903
|
* This uses a single collectionGroup query for efficiency.
|
|
18038
17904
|
*/
|
|
18039
17905
|
async getProductCounts() {
|
|
18040
|
-
const q = query35(
|
|
18041
|
-
collectionGroup3(this.db, PRODUCTS_COLLECTION),
|
|
18042
|
-
where35("isActive", "==", true)
|
|
18043
|
-
);
|
|
17906
|
+
const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), where35("isActive", "==", true));
|
|
18044
17907
|
const snapshot = await getDocs35(q);
|
|
18045
17908
|
const counts = {
|
|
18046
17909
|
byCategory: {},
|
|
@@ -18065,6 +17928,23 @@ var ProductService = class extends BaseService {
|
|
|
18065
17928
|
});
|
|
18066
17929
|
return counts;
|
|
18067
17930
|
}
|
|
17931
|
+
/**
|
|
17932
|
+
* Gets all products for a specific technology (non-paginated, for filters/dropdowns)
|
|
17933
|
+
*/
|
|
17934
|
+
async getAllByTechnology(technologyId) {
|
|
17935
|
+
const q = query35(
|
|
17936
|
+
this.getProductsRef(technologyId),
|
|
17937
|
+
where35("isActive", "==", true),
|
|
17938
|
+
orderBy22("name")
|
|
17939
|
+
);
|
|
17940
|
+
const snapshot = await getDocs35(q);
|
|
17941
|
+
return snapshot.docs.map(
|
|
17942
|
+
(doc38) => ({
|
|
17943
|
+
id: doc38.id,
|
|
17944
|
+
...doc38.data()
|
|
17945
|
+
})
|
|
17946
|
+
);
|
|
17947
|
+
}
|
|
18068
17948
|
/**
|
|
18069
17949
|
* Gets all products for a brand by filtering through all technologies
|
|
18070
17950
|
*/
|