@blackcode_sa/metaestetics-api 1.12.67 → 1.12.69

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/index.js CHANGED
@@ -188,13 +188,13 @@ var AppointmentStatus = /* @__PURE__ */ ((AppointmentStatus2) => {
188
188
  AppointmentStatus2["RESCHEDULED_BY_CLINIC"] = "rescheduled_by_clinic";
189
189
  return AppointmentStatus2;
190
190
  })(AppointmentStatus || {});
191
- var PaymentStatus = /* @__PURE__ */ ((PaymentStatus4) => {
192
- PaymentStatus4["UNPAID"] = "unpaid";
193
- PaymentStatus4["PAID"] = "paid";
194
- PaymentStatus4["PARTIALLY_PAID"] = "partially_paid";
195
- PaymentStatus4["REFUNDED"] = "refunded";
196
- PaymentStatus4["NOT_APPLICABLE"] = "not_applicable";
197
- return PaymentStatus4;
191
+ var PaymentStatus = /* @__PURE__ */ ((PaymentStatus3) => {
192
+ PaymentStatus3["UNPAID"] = "unpaid";
193
+ PaymentStatus3["PAID"] = "paid";
194
+ PaymentStatus3["PARTIALLY_PAID"] = "partially_paid";
195
+ PaymentStatus3["REFUNDED"] = "refunded";
196
+ PaymentStatus3["NOT_APPLICABLE"] = "not_applicable";
197
+ return PaymentStatus3;
198
198
  })(PaymentStatus || {});
199
199
  var MediaType = /* @__PURE__ */ ((MediaType2) => {
200
200
  MediaType2["BEFORE_PHOTO"] = "before_photo";
@@ -3430,6 +3430,7 @@ var AppointmentService = class extends BaseService {
3430
3430
  finalbilling: null,
3431
3431
  finalizationNotes: null
3432
3432
  };
3433
+ const shouldUpdatePaymentStatus = finalbilling.finalPrice > 0 && appointment.paymentStatus === "not_applicable" /* NOT_APPLICABLE */;
3433
3434
  const updateData = {
3434
3435
  metadata: {
3435
3436
  selectedZones: currentMetadata.selectedZones,
@@ -3445,6 +3446,9 @@ var AppointmentService = class extends BaseService {
3445
3446
  finalbilling,
3446
3447
  finalizationNotes: currentMetadata.finalizationNotes
3447
3448
  },
3449
+ ...shouldUpdatePaymentStatus && {
3450
+ paymentStatus: "unpaid" /* UNPAID */
3451
+ },
3448
3452
  updatedAt: (0, import_firestore11.serverTimestamp)()
3449
3453
  };
3450
3454
  return await this.updateAppointment(appointmentId, updateData);
@@ -3658,8 +3662,36 @@ var AppointmentService = class extends BaseService {
3658
3662
  showCanceled: false,
3659
3663
  showNoShow: false
3660
3664
  });
3665
+ const now = /* @__PURE__ */ new Date();
3666
+ const allPastAppointments = await this.getPatientAppointments(patientId, {
3667
+ endDate: now,
3668
+ status: [
3669
+ "completed" /* COMPLETED */,
3670
+ "confirmed" /* CONFIRMED */,
3671
+ "checked_in" /* CHECKED_IN */,
3672
+ "in_progress" /* IN_PROGRESS */
3673
+ ]
3674
+ });
3675
+ const appointmentsWithRecommendations = allPastAppointments.appointments.filter(
3676
+ (appointment) => {
3677
+ var _a2, _b2, _c2, _d;
3678
+ const endTime = ((_a2 = appointment.appointmentEndTime) == null ? void 0 : _a2.toMillis) ? appointment.appointmentEndTime.toMillis() : ((_b2 = appointment.appointmentEndTime) == null ? void 0 : _b2.seconds) ? appointment.appointmentEndTime.seconds * 1e3 : null;
3679
+ if (!endTime) return false;
3680
+ const isPastEndTime = endTime < now.getTime();
3681
+ const hasRecommendations = (((_d = (_c2 = appointment.metadata) == null ? void 0 : _c2.recommendedProcedures) == null ? void 0 : _d.length) || 0) > 0;
3682
+ return isPastEndTime && hasRecommendations;
3683
+ }
3684
+ );
3685
+ const allAppointmentsMap = /* @__PURE__ */ new Map();
3686
+ pastAppointments.appointments.forEach((apt) => {
3687
+ allAppointmentsMap.set(apt.id, apt);
3688
+ });
3689
+ appointmentsWithRecommendations.forEach((apt) => {
3690
+ allAppointmentsMap.set(apt.id, apt);
3691
+ });
3692
+ const allAppointments = Array.from(allAppointmentsMap.values());
3661
3693
  const recommendations = [];
3662
- for (const appointment of pastAppointments.appointments) {
3694
+ for (const appointment of allAppointments) {
3663
3695
  if ((options == null ? void 0 : options.clinicBranchId) && appointment.clinicBranchId !== options.clinicBranchId) {
3664
3696
  continue;
3665
3697
  }
@@ -3696,9 +3728,6 @@ var AppointmentService = class extends BaseService {
3696
3728
  return dateB - dateA;
3697
3729
  });
3698
3730
  const limitedRecommendations = (options == null ? void 0 : options.limit) ? recommendations.slice(0, options.limit) : recommendations;
3699
- console.log(
3700
- `[APPOINTMENT_SERVICE] Found ${limitedRecommendations.length} next steps recommendations for patient ${patientId}`
3701
- );
3702
3731
  return limitedRecommendations;
3703
3732
  } catch (error) {
3704
3733
  console.error(
@@ -3967,6 +3996,7 @@ var NotificationType = /* @__PURE__ */ ((NotificationType3) => {
3967
3996
  NotificationType3["FORM_REMINDER"] = "formReminder";
3968
3997
  NotificationType3["FORM_SUBMISSION_CONFIRMATION"] = "formSubmissionConfirmation";
3969
3998
  NotificationType3["REVIEW_REQUEST"] = "reviewRequest";
3999
+ NotificationType3["PROCEDURE_RECOMMENDATION"] = "procedureRecommendation";
3970
4000
  NotificationType3["PAYMENT_DUE"] = "paymentDue";
3971
4001
  NotificationType3["PAYMENT_CONFIRMATION"] = "paymentConfirmation";
3972
4002
  NotificationType3["PAYMENT_FAILED"] = "paymentFailed";
@@ -17491,6 +17521,10 @@ var ProcedureService = class extends BaseService {
17491
17521
  console.log("[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search");
17492
17522
  const searchTerm = filters.nameSearch.trim().toLowerCase();
17493
17523
  const constraints = getBaseConstraints();
17524
+ const hasNestedFilters = !!(filters.procedureTechnology || filters.procedureCategory || filters.procedureSubcategory);
17525
+ if (hasNestedFilters) {
17526
+ console.log("[PROCEDURE_SERVICE] Strategy 1: Has nested filters, will apply client-side after query");
17527
+ }
17494
17528
  constraints.push((0, import_firestore55.where)("nameLower", ">=", searchTerm));
17495
17529
  constraints.push((0, import_firestore55.where)("nameLower", "<=", searchTerm + "\uF8FF"));
17496
17530
  constraints.push((0, import_firestore55.orderBy)("nameLower"));
@@ -17506,9 +17540,12 @@ var ProcedureService = class extends BaseService {
17506
17540
  constraints.push((0, import_firestore55.limit)(filters.pagination || 10));
17507
17541
  const q = (0, import_firestore55.query)((0, import_firestore55.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
17508
17542
  const querySnapshot = await (0, import_firestore55.getDocs)(q);
17509
- const procedures = querySnapshot.docs.map(
17543
+ let procedures = querySnapshot.docs.map(
17510
17544
  (doc45) => ({ ...doc45.data(), id: doc45.id })
17511
17545
  );
17546
+ if (hasNestedFilters) {
17547
+ procedures = this.applyInMemoryFilters(procedures, filters);
17548
+ }
17512
17549
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
17513
17550
  console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
17514
17551
  if (procedures.length < (filters.pagination || 10)) {
@@ -17524,6 +17561,10 @@ var ProcedureService = class extends BaseService {
17524
17561
  console.log("[PROCEDURE_SERVICE] Strategy 2: Trying name field search");
17525
17562
  const searchTerm = filters.nameSearch.trim().toLowerCase();
17526
17563
  const constraints = getBaseConstraints();
17564
+ const hasNestedFilters = !!(filters.procedureTechnology || filters.procedureCategory || filters.procedureSubcategory);
17565
+ if (hasNestedFilters) {
17566
+ console.log("[PROCEDURE_SERVICE] Strategy 2: Has nested filters, will apply client-side after query");
17567
+ }
17527
17568
  constraints.push((0, import_firestore55.where)("name", ">=", searchTerm));
17528
17569
  constraints.push((0, import_firestore55.where)("name", "<=", searchTerm + "\uF8FF"));
17529
17570
  constraints.push((0, import_firestore55.orderBy)("name"));
@@ -17539,9 +17580,12 @@ var ProcedureService = class extends BaseService {
17539
17580
  constraints.push((0, import_firestore55.limit)(filters.pagination || 10));
17540
17581
  const q = (0, import_firestore55.query)((0, import_firestore55.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
17541
17582
  const querySnapshot = await (0, import_firestore55.getDocs)(q);
17542
- const procedures = querySnapshot.docs.map(
17583
+ let procedures = querySnapshot.docs.map(
17543
17584
  (doc45) => ({ ...doc45.data(), id: doc45.id })
17544
17585
  );
17586
+ if (hasNestedFilters) {
17587
+ procedures = this.applyInMemoryFilters(procedures, filters);
17588
+ }
17545
17589
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
17546
17590
  console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
17547
17591
  if (procedures.length < (filters.pagination || 10)) {
@@ -17554,9 +17598,47 @@ var ProcedureService = class extends BaseService {
17554
17598
  }
17555
17599
  try {
17556
17600
  console.log(
17557
- "[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
17601
+ "[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering",
17602
+ {
17603
+ procedureTechnology: filters.procedureTechnology,
17604
+ hasTechnologyFilter: !!filters.procedureTechnology
17605
+ }
17606
+ );
17607
+ const constraints = [];
17608
+ if (filters.isActive !== void 0) {
17609
+ constraints.push((0, import_firestore55.where)("isActive", "==", filters.isActive));
17610
+ } else {
17611
+ constraints.push((0, import_firestore55.where)("isActive", "==", true));
17612
+ }
17613
+ if (filters.procedureFamily) {
17614
+ constraints.push((0, import_firestore55.where)("family", "==", filters.procedureFamily));
17615
+ }
17616
+ if (filters.practitionerId) {
17617
+ constraints.push((0, import_firestore55.where)("practitionerId", "==", filters.practitionerId));
17618
+ }
17619
+ if (filters.clinicId) {
17620
+ constraints.push((0, import_firestore55.where)("clinicBranchId", "==", filters.clinicId));
17621
+ }
17622
+ if (filters.minPrice !== void 0) {
17623
+ constraints.push((0, import_firestore55.where)("price", ">=", filters.minPrice));
17624
+ }
17625
+ if (filters.maxPrice !== void 0) {
17626
+ constraints.push((0, import_firestore55.where)("price", "<=", filters.maxPrice));
17627
+ }
17628
+ if (filters.minRating !== void 0) {
17629
+ constraints.push((0, import_firestore55.where)("reviewInfo.averageRating", ">=", filters.minRating));
17630
+ }
17631
+ if (filters.maxRating !== void 0) {
17632
+ constraints.push((0, import_firestore55.where)("reviewInfo.averageRating", "<=", filters.maxRating));
17633
+ }
17634
+ if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
17635
+ const benefitIdsToMatch = filters.treatmentBenefits;
17636
+ constraints.push((0, import_firestore55.where)("treatmentBenefitIds", "array-contains-any", benefitIdsToMatch));
17637
+ }
17638
+ console.log(
17639
+ "[PROCEDURE_SERVICE] Strategy 3 Firestore constraints (nested filters excluded):",
17640
+ constraints.map((c) => c.fieldPath || "unknown")
17558
17641
  );
17559
- const constraints = getBaseConstraints();
17560
17642
  constraints.push((0, import_firestore55.orderBy)("createdAt", "desc"));
17561
17643
  if (filters.lastDoc) {
17562
17644
  if (typeof filters.lastDoc.data === "function") {
@@ -17573,7 +17655,20 @@ var ProcedureService = class extends BaseService {
17573
17655
  let procedures = querySnapshot.docs.map(
17574
17656
  (doc45) => ({ ...doc45.data(), id: doc45.id })
17575
17657
  );
17658
+ console.log("[PROCEDURE_SERVICE] Before applyInMemoryFilters (Strategy 3):", {
17659
+ procedureCount: procedures.length,
17660
+ procedureTechnology: filters.procedureTechnology,
17661
+ filtersObject: {
17662
+ procedureTechnology: filters.procedureTechnology,
17663
+ procedureFamily: filters.procedureFamily,
17664
+ procedureCategory: filters.procedureCategory,
17665
+ procedureSubcategory: filters.procedureSubcategory
17666
+ }
17667
+ });
17576
17668
  procedures = this.applyInMemoryFilters(procedures, filters);
17669
+ console.log("[PROCEDURE_SERVICE] After applyInMemoryFilters (Strategy 3):", {
17670
+ procedureCount: procedures.length
17671
+ });
17577
17672
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
17578
17673
  console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
17579
17674
  if (procedures.length < (filters.pagination || 10)) {
@@ -17624,6 +17719,12 @@ var ProcedureService = class extends BaseService {
17624
17719
  */
17625
17720
  applyInMemoryFilters(procedures, filters) {
17626
17721
  let filteredProcedures = [...procedures];
17722
+ console.log("[PROCEDURE_SERVICE] applyInMemoryFilters called:", {
17723
+ procedureCount: procedures.length,
17724
+ procedureTechnology: filters.procedureTechnology,
17725
+ hasTechnologyFilter: !!filters.procedureTechnology,
17726
+ allFilterKeys: Object.keys(filters).filter((k) => filters[k] !== void 0 && filters[k] !== null)
17727
+ });
17627
17728
  if (filters.nameSearch && filters.nameSearch.trim()) {
17628
17729
  const searchTerm = filters.nameSearch.trim().toLowerCase();
17629
17730
  filteredProcedures = filteredProcedures.filter((procedure) => {
@@ -17699,6 +17800,7 @@ var ProcedureService = class extends BaseService {
17699
17800
  );
17700
17801
  }
17701
17802
  if (filters.procedureTechnology) {
17803
+ const beforeCount = filteredProcedures.length;
17702
17804
  filteredProcedures = filteredProcedures.filter(
17703
17805
  (procedure) => {
17704
17806
  var _a;
@@ -17706,8 +17808,18 @@ var ProcedureService = class extends BaseService {
17706
17808
  }
17707
17809
  );
17708
17810
  console.log(
17709
- `[PROCEDURE_SERVICE] Applied technology filter, results: ${filteredProcedures.length}`
17811
+ `[PROCEDURE_SERVICE] Applied technology filter (${filters.procedureTechnology}), before: ${beforeCount}, after: ${filteredProcedures.length}`
17710
17812
  );
17813
+ if (beforeCount > filteredProcedures.length) {
17814
+ const filteredOut = procedures.filter((p) => {
17815
+ var _a;
17816
+ return ((_a = p.technology) == null ? void 0 : _a.id) !== filters.procedureTechnology;
17817
+ }).slice(0, 3).map((p) => {
17818
+ var _a;
17819
+ return { id: p.id, techId: (_a = p.technology) == null ? void 0 : _a.id, name: p.name };
17820
+ });
17821
+ console.log("[PROCEDURE_SERVICE] Filtered out sample procedures:", filteredOut);
17822
+ }
17711
17823
  }
17712
17824
  if (filters.practitionerId) {
17713
17825
  filteredProcedures = filteredProcedures.filter(
@@ -17811,9 +17923,9 @@ var ProcedureService = class extends BaseService {
17811
17923
  var _a, _b;
17812
17924
  const procedureId = this.generateId();
17813
17925
  const [category, subcategory, technology] = await Promise.all([
17814
- this.categoryService.getById(data.categoryId),
17815
- this.subcategoryService.getById(data.categoryId, data.subcategoryId),
17816
- this.technologyService.getById(data.technologyId)
17926
+ this.categoryService.getByIdInternal(data.categoryId),
17927
+ this.subcategoryService.getByIdInternal(data.categoryId, data.subcategoryId),
17928
+ this.technologyService.getByIdInternal(data.technologyId)
17817
17929
  ]);
17818
17930
  if (!category || !subcategory || !technology) {
17819
17931
  throw new Error("One or more required base entities not found");
@@ -18750,7 +18862,16 @@ var import_firestore59 = require("firebase/firestore");
18750
18862
  var CATEGORIES_COLLECTION = "backoffice_categories";
18751
18863
 
18752
18864
  // src/backoffice/services/category.service.ts
18865
+ var EXCLUDED_CATEGORY_ID = "consultation";
18753
18866
  var CategoryService = class extends BaseService {
18867
+ /**
18868
+ * Filters out excluded categories from a list.
18869
+ * @param categories - List of categories to filter
18870
+ * @returns Filtered list without excluded categories
18871
+ */
18872
+ filterExcludedCategories(categories) {
18873
+ return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
18874
+ }
18754
18875
  /**
18755
18876
  * Referenca na Firestore kolekciju kategorija
18756
18877
  */
@@ -18787,8 +18908,9 @@ var CategoryService = class extends BaseService {
18787
18908
  (0, import_firestore59.where)("family", "==", family),
18788
18909
  (0, import_firestore59.where)("isActive", "==", active)
18789
18910
  );
18790
- const snapshot = await (0, import_firestore59.getCountFromServer)(q);
18791
- counts[family] = snapshot.data().count;
18911
+ const snapshot = await (0, import_firestore59.getDocs)(q);
18912
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_CATEGORY_ID);
18913
+ counts[family] = filteredDocs.length;
18792
18914
  }
18793
18915
  return counts;
18794
18916
  }
@@ -18799,12 +18921,13 @@ var CategoryService = class extends BaseService {
18799
18921
  async getAllForFilter() {
18800
18922
  const q = (0, import_firestore59.query)(this.categoriesRef, (0, import_firestore59.where)("isActive", "==", true));
18801
18923
  const snapshot = await (0, import_firestore59.getDocs)(q);
18802
- return snapshot.docs.map(
18924
+ const categories = snapshot.docs.map(
18803
18925
  (doc45) => ({
18804
18926
  id: doc45.id,
18805
18927
  ...doc45.data()
18806
18928
  })
18807
18929
  );
18930
+ return this.filterExcludedCategories(categories);
18808
18931
  }
18809
18932
  /**
18810
18933
  * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
@@ -18819,12 +18942,13 @@ var CategoryService = class extends BaseService {
18819
18942
  (0, import_firestore59.orderBy)("name")
18820
18943
  );
18821
18944
  const snapshot = await (0, import_firestore59.getDocs)(q);
18822
- return snapshot.docs.map(
18945
+ const categories = snapshot.docs.map(
18823
18946
  (doc45) => ({
18824
18947
  id: doc45.id,
18825
18948
  ...doc45.data()
18826
18949
  })
18827
18950
  );
18951
+ return this.filterExcludedCategories(categories);
18828
18952
  }
18829
18953
  /**
18830
18954
  * Vraća sve kategorije sa paginacijom
@@ -18847,8 +18971,9 @@ var CategoryService = class extends BaseService {
18847
18971
  ...doc45.data()
18848
18972
  })
18849
18973
  );
18974
+ const filteredCategories = this.filterExcludedCategories(categories);
18850
18975
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
18851
- return { categories, lastVisible: newLastVisible };
18976
+ return { categories: filteredCategories, lastVisible: newLastVisible };
18852
18977
  }
18853
18978
  /**
18854
18979
  * Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
@@ -18873,8 +18998,9 @@ var CategoryService = class extends BaseService {
18873
18998
  ...doc45.data()
18874
18999
  })
18875
19000
  );
19001
+ const filteredCategories = this.filterExcludedCategories(categories);
18876
19002
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
18877
- return { categories, lastVisible: newLastVisible };
19003
+ return { categories: filteredCategories, lastVisible: newLastVisible };
18878
19004
  }
18879
19005
  /**
18880
19006
  * Ažurira postojeću kategoriju
@@ -18911,6 +19037,22 @@ var CategoryService = class extends BaseService {
18911
19037
  * @returns Kategorija ili null ako ne postoji
18912
19038
  */
18913
19039
  async getById(id) {
19040
+ if (id === EXCLUDED_CATEGORY_ID) return null;
19041
+ const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
19042
+ const docSnap = await (0, import_firestore59.getDoc)(docRef);
19043
+ if (!docSnap.exists()) return null;
19044
+ return {
19045
+ id: docSnap.id,
19046
+ ...docSnap.data()
19047
+ };
19048
+ }
19049
+ /**
19050
+ * Internal method to get category by ID without filtering.
19051
+ * Used internally for consultation procedures.
19052
+ * @param id - ID of the category to get
19053
+ * @returns Category or null if not found
19054
+ */
19055
+ async getByIdInternal(id) {
18914
19056
  const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
18915
19057
  const docSnap = await (0, import_firestore59.getDoc)(docRef);
18916
19058
  if (!docSnap.exists()) return null;
@@ -18936,6 +19078,7 @@ var CategoryService = class extends BaseService {
18936
19078
  const snapshot = await (0, import_firestore59.getDocs)(q);
18937
19079
  if (snapshot.empty) return null;
18938
19080
  const doc45 = snapshot.docs[0];
19081
+ if (doc45.id === EXCLUDED_CATEGORY_ID) return null;
18939
19082
  return {
18940
19083
  id: doc45.id,
18941
19084
  ...doc45.data()
@@ -18973,6 +19116,7 @@ var CategoryService = class extends BaseService {
18973
19116
  const snapshot = await (0, import_firestore59.getDocs)(q);
18974
19117
  if (snapshot.empty) break;
18975
19118
  for (const d of snapshot.docs) {
19119
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
18976
19120
  const category = { id: d.id, ...d.data() };
18977
19121
  rows.push(this.categoryToCsvRow(category));
18978
19122
  }
@@ -19015,7 +19159,16 @@ var import_firestore60 = require("firebase/firestore");
19015
19159
  var SUBCATEGORIES_COLLECTION = "subcategories";
19016
19160
 
19017
19161
  // src/backoffice/services/subcategory.service.ts
19162
+ var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
19018
19163
  var SubcategoryService = class extends BaseService {
19164
+ /**
19165
+ * Filters out excluded subcategories from a list.
19166
+ * @param subcategories - List of subcategories to filter
19167
+ * @returns Filtered list without excluded subcategories
19168
+ */
19169
+ filterExcludedSubcategories(subcategories) {
19170
+ return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
19171
+ }
19019
19172
  /**
19020
19173
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
19021
19174
  * @param categoryId - ID roditeljske kategorije
@@ -19062,8 +19215,9 @@ var SubcategoryService = class extends BaseService {
19062
19215
  const categoryId = categoryDoc.id;
19063
19216
  const subcategoriesRef = this.getSubcategoriesRef(categoryId);
19064
19217
  const q = (0, import_firestore60.query)(subcategoriesRef, (0, import_firestore60.where)("isActive", "==", active));
19065
- const snapshot = await (0, import_firestore60.getCountFromServer)(q);
19066
- counts[categoryId] = snapshot.data().count;
19218
+ const snapshot = await (0, import_firestore60.getDocs)(q);
19219
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_SUBCATEGORY_ID);
19220
+ counts[categoryId] = filteredDocs.length;
19067
19221
  }
19068
19222
  return counts;
19069
19223
  }
@@ -19089,8 +19243,9 @@ var SubcategoryService = class extends BaseService {
19089
19243
  ...doc45.data()
19090
19244
  })
19091
19245
  );
19246
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19092
19247
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19093
- return { subcategories, lastVisible: newLastVisible };
19248
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19094
19249
  }
19095
19250
  /**
19096
19251
  * Vraća sve podkategorije sa paginacijom koristeći collection group query.
@@ -19119,8 +19274,9 @@ var SubcategoryService = class extends BaseService {
19119
19274
  ...doc45.data()
19120
19275
  })
19121
19276
  );
19277
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19122
19278
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19123
- return { subcategories, lastVisible: newLastVisible };
19279
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19124
19280
  }
19125
19281
  /**
19126
19282
  * Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
@@ -19133,12 +19289,13 @@ var SubcategoryService = class extends BaseService {
19133
19289
  (0, import_firestore60.where)("isActive", "==", true)
19134
19290
  );
19135
19291
  const querySnapshot = await (0, import_firestore60.getDocs)(q);
19136
- return querySnapshot.docs.map(
19292
+ const subcategories = querySnapshot.docs.map(
19137
19293
  (doc45) => ({
19138
19294
  id: doc45.id,
19139
19295
  ...doc45.data()
19140
19296
  })
19141
19297
  );
19298
+ return this.filterExcludedSubcategories(subcategories);
19142
19299
  }
19143
19300
  /**
19144
19301
  * Vraća sve subkategorije za potrebe filtera (bez paginacije)
@@ -19150,12 +19307,13 @@ var SubcategoryService = class extends BaseService {
19150
19307
  (0, import_firestore60.where)("isActive", "==", true)
19151
19308
  );
19152
19309
  const querySnapshot = await (0, import_firestore60.getDocs)(q);
19153
- return querySnapshot.docs.map(
19310
+ const subcategories = querySnapshot.docs.map(
19154
19311
  (doc45) => ({
19155
19312
  id: doc45.id,
19156
19313
  ...doc45.data()
19157
19314
  })
19158
19315
  );
19316
+ return this.filterExcludedSubcategories(subcategories);
19159
19317
  }
19160
19318
  /**
19161
19319
  * Ažurira postojeću podkategoriju
@@ -19225,6 +19383,23 @@ var SubcategoryService = class extends BaseService {
19225
19383
  * @returns Podkategorija ili null ako ne postoji
19226
19384
  */
19227
19385
  async getById(categoryId, subcategoryId) {
19386
+ if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
19387
+ const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
19388
+ const docSnap = await (0, import_firestore60.getDoc)(docRef);
19389
+ if (!docSnap.exists()) return null;
19390
+ return {
19391
+ id: docSnap.id,
19392
+ ...docSnap.data()
19393
+ };
19394
+ }
19395
+ /**
19396
+ * Internal method to get subcategory by ID without filtering.
19397
+ * Used internally for consultation procedures.
19398
+ * @param categoryId - ID of the category
19399
+ * @param subcategoryId - ID of the subcategory to get
19400
+ * @returns Subcategory or null if not found
19401
+ */
19402
+ async getByIdInternal(categoryId, subcategoryId) {
19228
19403
  const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
19229
19404
  const docSnap = await (0, import_firestore60.getDoc)(docRef);
19230
19405
  if (!docSnap.exists()) return null;
@@ -19249,6 +19424,7 @@ var SubcategoryService = class extends BaseService {
19249
19424
  const querySnapshot = await (0, import_firestore60.getDocs)(q);
19250
19425
  if (querySnapshot.empty) return null;
19251
19426
  const doc45 = querySnapshot.docs[0];
19427
+ if (doc45.id === EXCLUDED_SUBCATEGORY_ID) return null;
19252
19428
  return {
19253
19429
  id: doc45.id,
19254
19430
  ...doc45.data()
@@ -19289,6 +19465,7 @@ var SubcategoryService = class extends BaseService {
19289
19465
  const snapshot = await (0, import_firestore60.getDocs)(q);
19290
19466
  if (snapshot.empty) break;
19291
19467
  for (const d of snapshot.docs) {
19468
+ if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
19292
19469
  const subcategory = { id: d.id, ...d.data() };
19293
19470
  rows.push(this.subcategoryToCsvRow(subcategory));
19294
19471
  }
@@ -19331,11 +19508,20 @@ var import_firestore61 = require("firebase/firestore");
19331
19508
  var PRODUCTS_COLLECTION = "products";
19332
19509
 
19333
19510
  // src/backoffice/services/technology.service.ts
19511
+ var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
19334
19512
  var DEFAULT_CERTIFICATION_REQUIREMENT = {
19335
19513
  minimumLevel: "aesthetician" /* AESTHETICIAN */,
19336
19514
  requiredSpecialties: []
19337
19515
  };
19338
19516
  var TechnologyService = class extends BaseService {
19517
+ /**
19518
+ * Filters out excluded technologies from a list.
19519
+ * @param technologies - List of technologies to filter
19520
+ * @returns Filtered list without excluded technologies
19521
+ */
19522
+ filterExcludedTechnologies(technologies) {
19523
+ return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
19524
+ }
19339
19525
  /**
19340
19526
  * Reference to the Firestore collection of technologies.
19341
19527
  */
@@ -19384,6 +19570,7 @@ var TechnologyService = class extends BaseService {
19384
19570
  const snapshot = await (0, import_firestore61.getDocs)(q);
19385
19571
  const counts = {};
19386
19572
  snapshot.docs.forEach((doc45) => {
19573
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19387
19574
  const tech = doc45.data();
19388
19575
  counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
19389
19576
  });
@@ -19399,6 +19586,7 @@ var TechnologyService = class extends BaseService {
19399
19586
  const snapshot = await (0, import_firestore61.getDocs)(q);
19400
19587
  const counts = {};
19401
19588
  snapshot.docs.forEach((doc45) => {
19589
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19402
19590
  const tech = doc45.data();
19403
19591
  counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
19404
19592
  });
@@ -19425,8 +19613,9 @@ var TechnologyService = class extends BaseService {
19425
19613
  ...doc45.data()
19426
19614
  })
19427
19615
  );
19616
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19428
19617
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19429
- return { technologies, lastVisible: newLastVisible };
19618
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19430
19619
  }
19431
19620
  /**
19432
19621
  * Returns all technologies for a specific category with pagination.
@@ -19451,8 +19640,9 @@ var TechnologyService = class extends BaseService {
19451
19640
  ...doc45.data()
19452
19641
  })
19453
19642
  );
19643
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19454
19644
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19455
- return { technologies, lastVisible: newLastVisible };
19645
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19456
19646
  }
19457
19647
  /**
19458
19648
  * Returns all technologies for a specific subcategory with pagination.
@@ -19477,8 +19667,9 @@ var TechnologyService = class extends BaseService {
19477
19667
  ...doc45.data()
19478
19668
  })
19479
19669
  );
19670
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19480
19671
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19481
- return { technologies, lastVisible: newLastVisible };
19672
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19482
19673
  }
19483
19674
  /**
19484
19675
  * Updates an existing technology.
@@ -19536,6 +19727,22 @@ var TechnologyService = class extends BaseService {
19536
19727
  * @returns The technology or null if it doesn't exist.
19537
19728
  */
19538
19729
  async getById(id) {
19730
+ if (id === EXCLUDED_TECHNOLOGY_ID) return null;
19731
+ const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
19732
+ const docSnap = await (0, import_firestore61.getDoc)(docRef);
19733
+ if (!docSnap.exists()) return null;
19734
+ return {
19735
+ id: docSnap.id,
19736
+ ...docSnap.data()
19737
+ };
19738
+ }
19739
+ /**
19740
+ * Internal method to get technology by ID without filtering.
19741
+ * Used internally for consultation procedures.
19742
+ * @param id - The ID of the requested technology
19743
+ * @returns The technology or null if it doesn't exist
19744
+ */
19745
+ async getByIdInternal(id) {
19539
19746
  const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
19540
19747
  const docSnap = await (0, import_firestore61.getDoc)(docRef);
19541
19748
  if (!docSnap.exists()) return null;
@@ -19559,6 +19766,7 @@ var TechnologyService = class extends BaseService {
19559
19766
  const snapshot = await (0, import_firestore61.getDocs)(q);
19560
19767
  if (snapshot.empty) return null;
19561
19768
  const doc45 = snapshot.docs[0];
19769
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return null;
19562
19770
  return {
19563
19771
  id: doc45.id,
19564
19772
  ...doc45.data()
@@ -19924,12 +20132,13 @@ var TechnologyService = class extends BaseService {
19924
20132
  (0, import_firestore61.orderBy)("name")
19925
20133
  );
19926
20134
  const snapshot = await (0, import_firestore61.getDocs)(q);
19927
- return snapshot.docs.map(
20135
+ const technologies = snapshot.docs.map(
19928
20136
  (doc45) => ({
19929
20137
  id: doc45.id,
19930
20138
  ...doc45.data()
19931
20139
  })
19932
20140
  );
20141
+ return this.filterExcludedTechnologies(technologies);
19933
20142
  }
19934
20143
  /**
19935
20144
  * Gets all active technologies for a subcategory for filter dropdowns.
@@ -19945,12 +20154,13 @@ var TechnologyService = class extends BaseService {
19945
20154
  (0, import_firestore61.orderBy)("name")
19946
20155
  );
19947
20156
  const snapshot = await (0, import_firestore61.getDocs)(q);
19948
- return snapshot.docs.map(
20157
+ const technologies = snapshot.docs.map(
19949
20158
  (doc45) => ({
19950
20159
  id: doc45.id,
19951
20160
  ...doc45.data()
19952
20161
  })
19953
20162
  );
20163
+ return this.filterExcludedTechnologies(technologies);
19954
20164
  }
19955
20165
  /**
19956
20166
  * Gets all active technologies for filter dropdowns.
@@ -19962,12 +20172,13 @@ var TechnologyService = class extends BaseService {
19962
20172
  (0, import_firestore61.orderBy)("name")
19963
20173
  );
19964
20174
  const snapshot = await (0, import_firestore61.getDocs)(q);
19965
- return snapshot.docs.map(
20175
+ const technologies = snapshot.docs.map(
19966
20176
  (doc45) => ({
19967
20177
  id: doc45.id,
19968
20178
  ...doc45.data()
19969
20179
  })
19970
20180
  );
20181
+ return this.filterExcludedTechnologies(technologies);
19971
20182
  }
19972
20183
  // ==========================================
19973
20184
  // NEW METHODS: Product assignment management
@@ -20133,6 +20344,7 @@ var TechnologyService = class extends BaseService {
20133
20344
  const snapshot = await (0, import_firestore61.getDocs)(q);
20134
20345
  if (snapshot.empty) break;
20135
20346
  for (const d of snapshot.docs) {
20347
+ if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
20136
20348
  const technology = { id: d.id, ...d.data() };
20137
20349
  const productNames = await this.getProductNamesForTechnology(technology.id);
20138
20350
  rows.push(this.technologyToCsvRow(technology, productNames));