@blackcode_sa/metaestetics-api 1.7.29 → 1.7.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +9 -1
- package/dist/admin/index.d.ts +9 -1
- package/dist/admin/index.js +144 -32
- package/dist/admin/index.mjs +142 -31
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +108 -10
- package/dist/index.mjs +108 -10
- package/package.json +1 -1
- package/src/admin/index.ts +3 -0
- package/src/services/practitioner/practitioner.service.ts +120 -13
- package/src/services/procedure/procedure.service.ts +17 -0
package/dist/admin/index.d.mts
CHANGED
|
@@ -2896,4 +2896,12 @@ declare class AppointmentMailingService extends BaseMailingService {
|
|
|
2896
2896
|
sendReviewAddedEmail(data: ReviewAddedEmailData): Promise<any>;
|
|
2897
2897
|
}
|
|
2898
2898
|
|
|
2899
|
-
|
|
2899
|
+
/**
|
|
2900
|
+
* Ensures that the free consultation infrastructure exists in the database
|
|
2901
|
+
* Creates category, subcategory, and technology if they don't exist
|
|
2902
|
+
* @param db - Firestore database instance (optional, defaults to admin.firestore())
|
|
2903
|
+
* @returns Promise<boolean> - Always returns true after ensuring infrastructure exists
|
|
2904
|
+
*/
|
|
2905
|
+
declare function freeConsultationInfrastructure(db?: admin.firestore.Firestore): Promise<boolean>;
|
|
2906
|
+
|
|
2907
|
+
export { APPOINTMENTS_COLLECTION, type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentMediaItem, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateAppointmentData, type CreateAppointmentHttpData, type DoctorInfo, DocumentManagerAdminService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, type LinkedFormInfo, Logger, MediaType, NOTIFICATIONS_COLLECTION, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientReviewInfo, PaymentStatus, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, PractitionerInviteMailingService, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureExtendedInfo, type ProcedureSummaryInfo, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type SearchAppointmentsParams, type TimeInterval, type UpdateAppointmentData, UserRole, freeConsultationInfrastructure };
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -2896,4 +2896,12 @@ declare class AppointmentMailingService extends BaseMailingService {
|
|
|
2896
2896
|
sendReviewAddedEmail(data: ReviewAddedEmailData): Promise<any>;
|
|
2897
2897
|
}
|
|
2898
2898
|
|
|
2899
|
-
|
|
2899
|
+
/**
|
|
2900
|
+
* Ensures that the free consultation infrastructure exists in the database
|
|
2901
|
+
* Creates category, subcategory, and technology if they don't exist
|
|
2902
|
+
* @param db - Firestore database instance (optional, defaults to admin.firestore())
|
|
2903
|
+
* @returns Promise<boolean> - Always returns true after ensuring infrastructure exists
|
|
2904
|
+
*/
|
|
2905
|
+
declare function freeConsultationInfrastructure(db?: admin.firestore.Firestore): Promise<boolean>;
|
|
2906
|
+
|
|
2907
|
+
export { APPOINTMENTS_COLLECTION, type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentMediaItem, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateAppointmentData, type CreateAppointmentHttpData, type DoctorInfo, DocumentManagerAdminService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, type LinkedFormInfo, Logger, MediaType, NOTIFICATIONS_COLLECTION, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientReviewInfo, PaymentStatus, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, PractitionerInviteMailingService, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureExtendedInfo, type ProcedureSummaryInfo, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type SearchAppointmentsParams, type TimeInterval, type UpdateAppointmentData, UserRole, freeConsultationInfrastructure };
|
package/dist/admin/index.js
CHANGED
|
@@ -58,7 +58,8 @@ __export(index_exports, {
|
|
|
58
58
|
PractitionerTokenStatus: () => PractitionerTokenStatus,
|
|
59
59
|
ProcedureAggregationService: () => ProcedureAggregationService,
|
|
60
60
|
ReviewsAggregationService: () => ReviewsAggregationService,
|
|
61
|
-
UserRole: () => UserRole
|
|
61
|
+
UserRole: () => UserRole,
|
|
62
|
+
freeConsultationInfrastructure: () => freeConsultationInfrastructure
|
|
62
63
|
});
|
|
63
64
|
module.exports = __toCommonJS(index_exports);
|
|
64
65
|
|
|
@@ -205,9 +206,9 @@ var Logger = class {
|
|
|
205
206
|
|
|
206
207
|
// src/admin/notifications/notifications.admin.ts
|
|
207
208
|
var NotificationsAdmin = class {
|
|
208
|
-
constructor(
|
|
209
|
+
constructor(firestore16) {
|
|
209
210
|
this.expo = new import_expo_server_sdk.Expo();
|
|
210
|
-
this.db =
|
|
211
|
+
this.db = firestore16 || admin.firestore();
|
|
211
212
|
}
|
|
212
213
|
/**
|
|
213
214
|
* Dohvata notifikaciju po ID-u
|
|
@@ -926,8 +927,8 @@ var ClinicAggregationService = class {
|
|
|
926
927
|
* Constructor for ClinicAggregationService.
|
|
927
928
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
928
929
|
*/
|
|
929
|
-
constructor(
|
|
930
|
-
this.db =
|
|
930
|
+
constructor(firestore16) {
|
|
931
|
+
this.db = firestore16 || admin3.firestore();
|
|
931
932
|
}
|
|
932
933
|
/**
|
|
933
934
|
* Adds clinic information to a clinic group when a new clinic is created
|
|
@@ -1439,8 +1440,8 @@ var ClinicAggregationService = class {
|
|
|
1439
1440
|
var admin4 = __toESM(require("firebase-admin"));
|
|
1440
1441
|
var CALENDAR_SUBCOLLECTION_ID2 = "calendar";
|
|
1441
1442
|
var PractitionerAggregationService = class {
|
|
1442
|
-
constructor(
|
|
1443
|
-
this.db =
|
|
1443
|
+
constructor(firestore16) {
|
|
1444
|
+
this.db = firestore16 || admin4.firestore();
|
|
1444
1445
|
}
|
|
1445
1446
|
/**
|
|
1446
1447
|
* Adds practitioner information to a clinic when a new practitioner is created
|
|
@@ -1775,8 +1776,8 @@ var PractitionerAggregationService = class {
|
|
|
1775
1776
|
var admin5 = __toESM(require("firebase-admin"));
|
|
1776
1777
|
var CALENDAR_SUBCOLLECTION_ID3 = "calendar";
|
|
1777
1778
|
var ProcedureAggregationService = class {
|
|
1778
|
-
constructor(
|
|
1779
|
-
this.db =
|
|
1779
|
+
constructor(firestore16) {
|
|
1780
|
+
this.db = firestore16 || admin5.firestore();
|
|
1780
1781
|
}
|
|
1781
1782
|
/**
|
|
1782
1783
|
* Adds procedure information to a practitioner when a new procedure is created
|
|
@@ -2291,8 +2292,8 @@ var ProcedureAggregationService = class {
|
|
|
2291
2292
|
var admin6 = __toESM(require("firebase-admin"));
|
|
2292
2293
|
var CALENDAR_SUBCOLLECTION_ID4 = "calendar";
|
|
2293
2294
|
var PatientAggregationService = class {
|
|
2294
|
-
constructor(
|
|
2295
|
-
this.db =
|
|
2295
|
+
constructor(firestore16) {
|
|
2296
|
+
this.db = firestore16 || admin6.firestore();
|
|
2296
2297
|
}
|
|
2297
2298
|
// --- Methods for Patient Creation --- >
|
|
2298
2299
|
// No specific aggregations defined for patient creation in the plan.
|
|
@@ -2424,8 +2425,8 @@ var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
|
2424
2425
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
2425
2426
|
var admin7 = __toESM(require("firebase-admin"));
|
|
2426
2427
|
var PatientRequirementsAdminService = class {
|
|
2427
|
-
constructor(
|
|
2428
|
-
this.db =
|
|
2428
|
+
constructor(firestore16) {
|
|
2429
|
+
this.db = firestore16 || admin7.firestore();
|
|
2429
2430
|
this.notificationsAdmin = new NotificationsAdmin(this.db);
|
|
2430
2431
|
}
|
|
2431
2432
|
/**
|
|
@@ -2753,8 +2754,8 @@ var PatientRequirementsAdminService = class {
|
|
|
2753
2754
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2754
2755
|
var admin8 = __toESM(require("firebase-admin"));
|
|
2755
2756
|
var CalendarAdminService = class {
|
|
2756
|
-
constructor(
|
|
2757
|
-
this.db =
|
|
2757
|
+
constructor(firestore16) {
|
|
2758
|
+
this.db = firestore16 || admin8.firestore();
|
|
2758
2759
|
Logger.info("[CalendarAdminService] Initialized.");
|
|
2759
2760
|
}
|
|
2760
2761
|
/**
|
|
@@ -3037,9 +3038,9 @@ var BaseMailingService = class {
|
|
|
3037
3038
|
* @param firestore Firestore instance provided by the caller
|
|
3038
3039
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
3039
3040
|
*/
|
|
3040
|
-
constructor(
|
|
3041
|
+
constructor(firestore16, mailgunClient) {
|
|
3041
3042
|
var _a;
|
|
3042
|
-
this.db =
|
|
3043
|
+
this.db = firestore16;
|
|
3043
3044
|
this.mailgunClient = mailgunClient;
|
|
3044
3045
|
if (!this.db) {
|
|
3045
3046
|
Logger.error("[BaseMailingService] No Firestore instance provided");
|
|
@@ -3183,8 +3184,8 @@ var BaseMailingService = class {
|
|
|
3183
3184
|
var patientAppointmentConfirmedTemplate = "<h1>Appointment Confirmed</h1><p>Dear {{patientName}},</p><p>Your appointment for {{procedureName}} on {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}} at {{clinicName}} has been confirmed.</p><p>Thank you!</p>";
|
|
3184
3185
|
var clinicAppointmentRequestedTemplate = "<h1>New Appointment Request</h1><p>Hello {{clinicName}} Admin,</p><p>A new appointment for {{procedureName}} has been requested by {{patientName}} for {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}}.</p><p>Please review and confirm in the admin panel.</p>";
|
|
3185
3186
|
var AppointmentMailingService = class extends BaseMailingService {
|
|
3186
|
-
constructor(
|
|
3187
|
-
super(
|
|
3187
|
+
constructor(firestore16, mailgunClient) {
|
|
3188
|
+
super(firestore16, mailgunClient);
|
|
3188
3189
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
3189
3190
|
Logger.info("[AppointmentMailingService] Initialized.");
|
|
3190
3191
|
}
|
|
@@ -3333,8 +3334,8 @@ var AppointmentAggregationService = class {
|
|
|
3333
3334
|
* @param mailgunClient - An initialized Mailgun client instance.
|
|
3334
3335
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
3335
3336
|
*/
|
|
3336
|
-
constructor(mailgunClient,
|
|
3337
|
-
this.db =
|
|
3337
|
+
constructor(mailgunClient, firestore16) {
|
|
3338
|
+
this.db = firestore16 || admin10.firestore();
|
|
3338
3339
|
this.appointmentMailingService = new AppointmentMailingService(
|
|
3339
3340
|
this.db,
|
|
3340
3341
|
mailgunClient
|
|
@@ -4590,8 +4591,8 @@ var FilledFormsAggregationService = class {
|
|
|
4590
4591
|
* Constructor for FilledFormsAggregationService.
|
|
4591
4592
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4592
4593
|
*/
|
|
4593
|
-
constructor(
|
|
4594
|
-
this.db =
|
|
4594
|
+
constructor(firestore16) {
|
|
4595
|
+
this.db = firestore16 || admin11.firestore();
|
|
4595
4596
|
Logger.info("[FilledFormsAggregationService] Initialized");
|
|
4596
4597
|
}
|
|
4597
4598
|
/**
|
|
@@ -4785,8 +4786,8 @@ var ReviewsAggregationService = class {
|
|
|
4785
4786
|
* Constructor for ReviewsAggregationService.
|
|
4786
4787
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4787
4788
|
*/
|
|
4788
|
-
constructor(
|
|
4789
|
-
this.db =
|
|
4789
|
+
constructor(firestore16) {
|
|
4790
|
+
this.db = firestore16 || admin12.firestore();
|
|
4790
4791
|
}
|
|
4791
4792
|
/**
|
|
4792
4793
|
* Process a newly created review and update all related entities
|
|
@@ -5331,8 +5332,8 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5331
5332
|
* @param firestore Firestore instance provided by the caller
|
|
5332
5333
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
5333
5334
|
*/
|
|
5334
|
-
constructor(
|
|
5335
|
-
super(
|
|
5335
|
+
constructor(firestore16, mailgunClient) {
|
|
5336
|
+
super(firestore16, mailgunClient);
|
|
5336
5337
|
this.DEFAULT_REGISTRATION_URL = "https://metaesthetics.net/register";
|
|
5337
5338
|
this.DEFAULT_SUBJECT = "You've Been Invited to Join as a Practitioner";
|
|
5338
5339
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
@@ -6006,8 +6007,8 @@ BookingAvailabilityCalculator.DEFAULT_INTERVAL_MINUTES = 15;
|
|
|
6006
6007
|
// src/admin/documentation-templates/document-manager.admin.ts
|
|
6007
6008
|
var admin13 = __toESM(require("firebase-admin"));
|
|
6008
6009
|
var DocumentManagerAdminService = class {
|
|
6009
|
-
constructor(
|
|
6010
|
-
this.db =
|
|
6010
|
+
constructor(firestore16) {
|
|
6011
|
+
this.db = firestore16;
|
|
6011
6012
|
}
|
|
6012
6013
|
/**
|
|
6013
6014
|
* Adds operations to a Firestore batch to initialize all linked forms for a new appointment
|
|
@@ -6176,8 +6177,8 @@ var BookingAdmin = class {
|
|
|
6176
6177
|
* Creates a new BookingAdmin instance
|
|
6177
6178
|
* @param firestore - Firestore instance provided by the caller
|
|
6178
6179
|
*/
|
|
6179
|
-
constructor(
|
|
6180
|
-
this.db =
|
|
6180
|
+
constructor(firestore16) {
|
|
6181
|
+
this.db = firestore16 || admin14.firestore();
|
|
6181
6182
|
this.documentManagerAdmin = new DocumentManagerAdminService(this.db);
|
|
6182
6183
|
}
|
|
6183
6184
|
/**
|
|
@@ -6779,6 +6780,116 @@ var BookingAdmin = class {
|
|
|
6779
6780
|
}
|
|
6780
6781
|
};
|
|
6781
6782
|
|
|
6783
|
+
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6784
|
+
var admin15 = __toESM(require("firebase-admin"));
|
|
6785
|
+
|
|
6786
|
+
// src/backoffice/types/category.types.ts
|
|
6787
|
+
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
6788
|
+
|
|
6789
|
+
// src/backoffice/types/subcategory.types.ts
|
|
6790
|
+
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
6791
|
+
|
|
6792
|
+
// src/backoffice/types/technology.types.ts
|
|
6793
|
+
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
6794
|
+
|
|
6795
|
+
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6796
|
+
async function freeConsultationInfrastructure(db) {
|
|
6797
|
+
const firestore16 = db || admin15.firestore();
|
|
6798
|
+
try {
|
|
6799
|
+
console.log(
|
|
6800
|
+
"[freeConsultationInfrastructure] Checking free consultation infrastructure..."
|
|
6801
|
+
);
|
|
6802
|
+
const technologyRef = firestore16.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6803
|
+
const technologyDoc = await technologyRef.get();
|
|
6804
|
+
if (technologyDoc.exists) {
|
|
6805
|
+
console.log(
|
|
6806
|
+
"[freeConsultationInfrastructure] Free consultation infrastructure already exists"
|
|
6807
|
+
);
|
|
6808
|
+
return true;
|
|
6809
|
+
}
|
|
6810
|
+
console.log(
|
|
6811
|
+
"[freeConsultationInfrastructure] Creating free consultation infrastructure..."
|
|
6812
|
+
);
|
|
6813
|
+
await createFreeConsultationInfrastructure(firestore16);
|
|
6814
|
+
console.log(
|
|
6815
|
+
"[freeConsultationInfrastructure] Successfully created free consultation infrastructure"
|
|
6816
|
+
);
|
|
6817
|
+
return true;
|
|
6818
|
+
} catch (error) {
|
|
6819
|
+
console.error(
|
|
6820
|
+
"[freeConsultationInfrastructure] Error ensuring infrastructure:",
|
|
6821
|
+
error
|
|
6822
|
+
);
|
|
6823
|
+
throw error;
|
|
6824
|
+
}
|
|
6825
|
+
}
|
|
6826
|
+
async function createFreeConsultationInfrastructure(db) {
|
|
6827
|
+
const batch = db.batch();
|
|
6828
|
+
const now = /* @__PURE__ */ new Date();
|
|
6829
|
+
const categoryRef = db.collection(CATEGORIES_COLLECTION).doc("consultation");
|
|
6830
|
+
const categoryData = {
|
|
6831
|
+
id: "consultation",
|
|
6832
|
+
name: "Consultation",
|
|
6833
|
+
description: "Professional consultation services for treatment planning and assessment",
|
|
6834
|
+
family: "aesthetics" /* AESTHETICS */,
|
|
6835
|
+
isActive: true,
|
|
6836
|
+
createdAt: now,
|
|
6837
|
+
updatedAt: now
|
|
6838
|
+
};
|
|
6839
|
+
batch.set(categoryRef, categoryData);
|
|
6840
|
+
const subcategoryRef = db.collection(CATEGORIES_COLLECTION).doc("consultation").collection(SUBCATEGORIES_COLLECTION).doc("free-consultation");
|
|
6841
|
+
const subcategoryData = {
|
|
6842
|
+
id: "free-consultation",
|
|
6843
|
+
name: "Free Consultation",
|
|
6844
|
+
description: "Complimentary initial consultation to discuss treatment options and assess patient needs",
|
|
6845
|
+
categoryId: "consultation",
|
|
6846
|
+
isActive: true,
|
|
6847
|
+
createdAt: now,
|
|
6848
|
+
updatedAt: now
|
|
6849
|
+
};
|
|
6850
|
+
batch.set(subcategoryRef, subcategoryData);
|
|
6851
|
+
const technologyRef = db.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6852
|
+
const technologyData = {
|
|
6853
|
+
id: "free-consultation-tech",
|
|
6854
|
+
name: "Free Consultation Technology",
|
|
6855
|
+
description: "Technology framework for providing free initial consultations to patients",
|
|
6856
|
+
family: "aesthetics" /* AESTHETICS */,
|
|
6857
|
+
categoryId: "consultation",
|
|
6858
|
+
subcategoryId: "free-consultation",
|
|
6859
|
+
technicalDetails: "Standard consultation protocol for initial patient assessment",
|
|
6860
|
+
requirements: {
|
|
6861
|
+
pre: [],
|
|
6862
|
+
// No pre-requirements for consultation
|
|
6863
|
+
post: []
|
|
6864
|
+
// No post-requirements for consultation
|
|
6865
|
+
},
|
|
6866
|
+
blockingConditions: [],
|
|
6867
|
+
// No blocking conditions for consultation
|
|
6868
|
+
contraindications: [],
|
|
6869
|
+
// No contraindications for consultation
|
|
6870
|
+
benefits: [
|
|
6871
|
+
"IMPROVED_PATIENT_UNDERSTANDING",
|
|
6872
|
+
"BETTER_TREATMENT_PLANNING",
|
|
6873
|
+
"ENHANCED_PATIENT_CONFIDENCE"
|
|
6874
|
+
],
|
|
6875
|
+
certificationRequirement: {
|
|
6876
|
+
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
6877
|
+
requiredSpecialties: []
|
|
6878
|
+
// No required specialties for consultation
|
|
6879
|
+
},
|
|
6880
|
+
documentationTemplates: [],
|
|
6881
|
+
isActive: true,
|
|
6882
|
+
createdAt: now,
|
|
6883
|
+
updatedAt: now
|
|
6884
|
+
};
|
|
6885
|
+
batch.set(technologyRef, technologyData);
|
|
6886
|
+
await batch.commit();
|
|
6887
|
+
console.log("[freeConsultationInfrastructure] Successfully created:");
|
|
6888
|
+
console.log(" \u2713 Category: consultation");
|
|
6889
|
+
console.log(" \u2713 Subcategory: free-consultation");
|
|
6890
|
+
console.log(" \u2713 Technology: free-consultation-tech");
|
|
6891
|
+
}
|
|
6892
|
+
|
|
6782
6893
|
// src/admin/index.ts
|
|
6783
6894
|
console.log("[Admin Module] Initialized and services exported.");
|
|
6784
6895
|
TimestampUtils.enableServerMode();
|
|
@@ -6812,5 +6923,6 @@ TimestampUtils.enableServerMode();
|
|
|
6812
6923
|
PractitionerTokenStatus,
|
|
6813
6924
|
ProcedureAggregationService,
|
|
6814
6925
|
ReviewsAggregationService,
|
|
6815
|
-
UserRole
|
|
6926
|
+
UserRole,
|
|
6927
|
+
freeConsultationInfrastructure
|
|
6816
6928
|
});
|
package/dist/admin/index.mjs
CHANGED
|
@@ -148,9 +148,9 @@ var Logger = class {
|
|
|
148
148
|
|
|
149
149
|
// src/admin/notifications/notifications.admin.ts
|
|
150
150
|
var NotificationsAdmin = class {
|
|
151
|
-
constructor(
|
|
151
|
+
constructor(firestore16) {
|
|
152
152
|
this.expo = new Expo();
|
|
153
|
-
this.db =
|
|
153
|
+
this.db = firestore16 || admin.firestore();
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
156
|
* Dohvata notifikaciju po ID-u
|
|
@@ -869,8 +869,8 @@ var ClinicAggregationService = class {
|
|
|
869
869
|
* Constructor for ClinicAggregationService.
|
|
870
870
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
871
871
|
*/
|
|
872
|
-
constructor(
|
|
873
|
-
this.db =
|
|
872
|
+
constructor(firestore16) {
|
|
873
|
+
this.db = firestore16 || admin3.firestore();
|
|
874
874
|
}
|
|
875
875
|
/**
|
|
876
876
|
* Adds clinic information to a clinic group when a new clinic is created
|
|
@@ -1382,8 +1382,8 @@ var ClinicAggregationService = class {
|
|
|
1382
1382
|
import * as admin4 from "firebase-admin";
|
|
1383
1383
|
var CALENDAR_SUBCOLLECTION_ID2 = "calendar";
|
|
1384
1384
|
var PractitionerAggregationService = class {
|
|
1385
|
-
constructor(
|
|
1386
|
-
this.db =
|
|
1385
|
+
constructor(firestore16) {
|
|
1386
|
+
this.db = firestore16 || admin4.firestore();
|
|
1387
1387
|
}
|
|
1388
1388
|
/**
|
|
1389
1389
|
* Adds practitioner information to a clinic when a new practitioner is created
|
|
@@ -1718,8 +1718,8 @@ var PractitionerAggregationService = class {
|
|
|
1718
1718
|
import * as admin5 from "firebase-admin";
|
|
1719
1719
|
var CALENDAR_SUBCOLLECTION_ID3 = "calendar";
|
|
1720
1720
|
var ProcedureAggregationService = class {
|
|
1721
|
-
constructor(
|
|
1722
|
-
this.db =
|
|
1721
|
+
constructor(firestore16) {
|
|
1722
|
+
this.db = firestore16 || admin5.firestore();
|
|
1723
1723
|
}
|
|
1724
1724
|
/**
|
|
1725
1725
|
* Adds procedure information to a practitioner when a new procedure is created
|
|
@@ -2234,8 +2234,8 @@ var ProcedureAggregationService = class {
|
|
|
2234
2234
|
import * as admin6 from "firebase-admin";
|
|
2235
2235
|
var CALENDAR_SUBCOLLECTION_ID4 = "calendar";
|
|
2236
2236
|
var PatientAggregationService = class {
|
|
2237
|
-
constructor(
|
|
2238
|
-
this.db =
|
|
2237
|
+
constructor(firestore16) {
|
|
2238
|
+
this.db = firestore16 || admin6.firestore();
|
|
2239
2239
|
}
|
|
2240
2240
|
// --- Methods for Patient Creation --- >
|
|
2241
2241
|
// No specific aggregations defined for patient creation in the plan.
|
|
@@ -2367,8 +2367,8 @@ var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
|
2367
2367
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
2368
2368
|
import * as admin7 from "firebase-admin";
|
|
2369
2369
|
var PatientRequirementsAdminService = class {
|
|
2370
|
-
constructor(
|
|
2371
|
-
this.db =
|
|
2370
|
+
constructor(firestore16) {
|
|
2371
|
+
this.db = firestore16 || admin7.firestore();
|
|
2372
2372
|
this.notificationsAdmin = new NotificationsAdmin(this.db);
|
|
2373
2373
|
}
|
|
2374
2374
|
/**
|
|
@@ -2696,8 +2696,8 @@ var PatientRequirementsAdminService = class {
|
|
|
2696
2696
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2697
2697
|
import * as admin8 from "firebase-admin";
|
|
2698
2698
|
var CalendarAdminService = class {
|
|
2699
|
-
constructor(
|
|
2700
|
-
this.db =
|
|
2699
|
+
constructor(firestore16) {
|
|
2700
|
+
this.db = firestore16 || admin8.firestore();
|
|
2701
2701
|
Logger.info("[CalendarAdminService] Initialized.");
|
|
2702
2702
|
}
|
|
2703
2703
|
/**
|
|
@@ -2980,9 +2980,9 @@ var BaseMailingService = class {
|
|
|
2980
2980
|
* @param firestore Firestore instance provided by the caller
|
|
2981
2981
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
2982
2982
|
*/
|
|
2983
|
-
constructor(
|
|
2983
|
+
constructor(firestore16, mailgunClient) {
|
|
2984
2984
|
var _a;
|
|
2985
|
-
this.db =
|
|
2985
|
+
this.db = firestore16;
|
|
2986
2986
|
this.mailgunClient = mailgunClient;
|
|
2987
2987
|
if (!this.db) {
|
|
2988
2988
|
Logger.error("[BaseMailingService] No Firestore instance provided");
|
|
@@ -3126,8 +3126,8 @@ var BaseMailingService = class {
|
|
|
3126
3126
|
var patientAppointmentConfirmedTemplate = "<h1>Appointment Confirmed</h1><p>Dear {{patientName}},</p><p>Your appointment for {{procedureName}} on {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}} at {{clinicName}} has been confirmed.</p><p>Thank you!</p>";
|
|
3127
3127
|
var clinicAppointmentRequestedTemplate = "<h1>New Appointment Request</h1><p>Hello {{clinicName}} Admin,</p><p>A new appointment for {{procedureName}} has been requested by {{patientName}} for {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}}.</p><p>Please review and confirm in the admin panel.</p>";
|
|
3128
3128
|
var AppointmentMailingService = class extends BaseMailingService {
|
|
3129
|
-
constructor(
|
|
3130
|
-
super(
|
|
3129
|
+
constructor(firestore16, mailgunClient) {
|
|
3130
|
+
super(firestore16, mailgunClient);
|
|
3131
3131
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
3132
3132
|
Logger.info("[AppointmentMailingService] Initialized.");
|
|
3133
3133
|
}
|
|
@@ -3276,8 +3276,8 @@ var AppointmentAggregationService = class {
|
|
|
3276
3276
|
* @param mailgunClient - An initialized Mailgun client instance.
|
|
3277
3277
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
3278
3278
|
*/
|
|
3279
|
-
constructor(mailgunClient,
|
|
3280
|
-
this.db =
|
|
3279
|
+
constructor(mailgunClient, firestore16) {
|
|
3280
|
+
this.db = firestore16 || admin10.firestore();
|
|
3281
3281
|
this.appointmentMailingService = new AppointmentMailingService(
|
|
3282
3282
|
this.db,
|
|
3283
3283
|
mailgunClient
|
|
@@ -4533,8 +4533,8 @@ var FilledFormsAggregationService = class {
|
|
|
4533
4533
|
* Constructor for FilledFormsAggregationService.
|
|
4534
4534
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4535
4535
|
*/
|
|
4536
|
-
constructor(
|
|
4537
|
-
this.db =
|
|
4536
|
+
constructor(firestore16) {
|
|
4537
|
+
this.db = firestore16 || admin11.firestore();
|
|
4538
4538
|
Logger.info("[FilledFormsAggregationService] Initialized");
|
|
4539
4539
|
}
|
|
4540
4540
|
/**
|
|
@@ -4728,8 +4728,8 @@ var ReviewsAggregationService = class {
|
|
|
4728
4728
|
* Constructor for ReviewsAggregationService.
|
|
4729
4729
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4730
4730
|
*/
|
|
4731
|
-
constructor(
|
|
4732
|
-
this.db =
|
|
4731
|
+
constructor(firestore16) {
|
|
4732
|
+
this.db = firestore16 || admin12.firestore();
|
|
4733
4733
|
}
|
|
4734
4734
|
/**
|
|
4735
4735
|
* Process a newly created review and update all related entities
|
|
@@ -5274,8 +5274,8 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5274
5274
|
* @param firestore Firestore instance provided by the caller
|
|
5275
5275
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
5276
5276
|
*/
|
|
5277
|
-
constructor(
|
|
5278
|
-
super(
|
|
5277
|
+
constructor(firestore16, mailgunClient) {
|
|
5278
|
+
super(firestore16, mailgunClient);
|
|
5279
5279
|
this.DEFAULT_REGISTRATION_URL = "https://metaesthetics.net/register";
|
|
5280
5280
|
this.DEFAULT_SUBJECT = "You've Been Invited to Join as a Practitioner";
|
|
5281
5281
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
@@ -5949,8 +5949,8 @@ BookingAvailabilityCalculator.DEFAULT_INTERVAL_MINUTES = 15;
|
|
|
5949
5949
|
// src/admin/documentation-templates/document-manager.admin.ts
|
|
5950
5950
|
import * as admin13 from "firebase-admin";
|
|
5951
5951
|
var DocumentManagerAdminService = class {
|
|
5952
|
-
constructor(
|
|
5953
|
-
this.db =
|
|
5952
|
+
constructor(firestore16) {
|
|
5953
|
+
this.db = firestore16;
|
|
5954
5954
|
}
|
|
5955
5955
|
/**
|
|
5956
5956
|
* Adds operations to a Firestore batch to initialize all linked forms for a new appointment
|
|
@@ -6119,8 +6119,8 @@ var BookingAdmin = class {
|
|
|
6119
6119
|
* Creates a new BookingAdmin instance
|
|
6120
6120
|
* @param firestore - Firestore instance provided by the caller
|
|
6121
6121
|
*/
|
|
6122
|
-
constructor(
|
|
6123
|
-
this.db =
|
|
6122
|
+
constructor(firestore16) {
|
|
6123
|
+
this.db = firestore16 || admin14.firestore();
|
|
6124
6124
|
this.documentManagerAdmin = new DocumentManagerAdminService(this.db);
|
|
6125
6125
|
}
|
|
6126
6126
|
/**
|
|
@@ -6722,6 +6722,116 @@ var BookingAdmin = class {
|
|
|
6722
6722
|
}
|
|
6723
6723
|
};
|
|
6724
6724
|
|
|
6725
|
+
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6726
|
+
import * as admin15 from "firebase-admin";
|
|
6727
|
+
|
|
6728
|
+
// src/backoffice/types/category.types.ts
|
|
6729
|
+
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
6730
|
+
|
|
6731
|
+
// src/backoffice/types/subcategory.types.ts
|
|
6732
|
+
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
6733
|
+
|
|
6734
|
+
// src/backoffice/types/technology.types.ts
|
|
6735
|
+
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
6736
|
+
|
|
6737
|
+
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6738
|
+
async function freeConsultationInfrastructure(db) {
|
|
6739
|
+
const firestore16 = db || admin15.firestore();
|
|
6740
|
+
try {
|
|
6741
|
+
console.log(
|
|
6742
|
+
"[freeConsultationInfrastructure] Checking free consultation infrastructure..."
|
|
6743
|
+
);
|
|
6744
|
+
const technologyRef = firestore16.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6745
|
+
const technologyDoc = await technologyRef.get();
|
|
6746
|
+
if (technologyDoc.exists) {
|
|
6747
|
+
console.log(
|
|
6748
|
+
"[freeConsultationInfrastructure] Free consultation infrastructure already exists"
|
|
6749
|
+
);
|
|
6750
|
+
return true;
|
|
6751
|
+
}
|
|
6752
|
+
console.log(
|
|
6753
|
+
"[freeConsultationInfrastructure] Creating free consultation infrastructure..."
|
|
6754
|
+
);
|
|
6755
|
+
await createFreeConsultationInfrastructure(firestore16);
|
|
6756
|
+
console.log(
|
|
6757
|
+
"[freeConsultationInfrastructure] Successfully created free consultation infrastructure"
|
|
6758
|
+
);
|
|
6759
|
+
return true;
|
|
6760
|
+
} catch (error) {
|
|
6761
|
+
console.error(
|
|
6762
|
+
"[freeConsultationInfrastructure] Error ensuring infrastructure:",
|
|
6763
|
+
error
|
|
6764
|
+
);
|
|
6765
|
+
throw error;
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
async function createFreeConsultationInfrastructure(db) {
|
|
6769
|
+
const batch = db.batch();
|
|
6770
|
+
const now = /* @__PURE__ */ new Date();
|
|
6771
|
+
const categoryRef = db.collection(CATEGORIES_COLLECTION).doc("consultation");
|
|
6772
|
+
const categoryData = {
|
|
6773
|
+
id: "consultation",
|
|
6774
|
+
name: "Consultation",
|
|
6775
|
+
description: "Professional consultation services for treatment planning and assessment",
|
|
6776
|
+
family: "aesthetics" /* AESTHETICS */,
|
|
6777
|
+
isActive: true,
|
|
6778
|
+
createdAt: now,
|
|
6779
|
+
updatedAt: now
|
|
6780
|
+
};
|
|
6781
|
+
batch.set(categoryRef, categoryData);
|
|
6782
|
+
const subcategoryRef = db.collection(CATEGORIES_COLLECTION).doc("consultation").collection(SUBCATEGORIES_COLLECTION).doc("free-consultation");
|
|
6783
|
+
const subcategoryData = {
|
|
6784
|
+
id: "free-consultation",
|
|
6785
|
+
name: "Free Consultation",
|
|
6786
|
+
description: "Complimentary initial consultation to discuss treatment options and assess patient needs",
|
|
6787
|
+
categoryId: "consultation",
|
|
6788
|
+
isActive: true,
|
|
6789
|
+
createdAt: now,
|
|
6790
|
+
updatedAt: now
|
|
6791
|
+
};
|
|
6792
|
+
batch.set(subcategoryRef, subcategoryData);
|
|
6793
|
+
const technologyRef = db.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6794
|
+
const technologyData = {
|
|
6795
|
+
id: "free-consultation-tech",
|
|
6796
|
+
name: "Free Consultation Technology",
|
|
6797
|
+
description: "Technology framework for providing free initial consultations to patients",
|
|
6798
|
+
family: "aesthetics" /* AESTHETICS */,
|
|
6799
|
+
categoryId: "consultation",
|
|
6800
|
+
subcategoryId: "free-consultation",
|
|
6801
|
+
technicalDetails: "Standard consultation protocol for initial patient assessment",
|
|
6802
|
+
requirements: {
|
|
6803
|
+
pre: [],
|
|
6804
|
+
// No pre-requirements for consultation
|
|
6805
|
+
post: []
|
|
6806
|
+
// No post-requirements for consultation
|
|
6807
|
+
},
|
|
6808
|
+
blockingConditions: [],
|
|
6809
|
+
// No blocking conditions for consultation
|
|
6810
|
+
contraindications: [],
|
|
6811
|
+
// No contraindications for consultation
|
|
6812
|
+
benefits: [
|
|
6813
|
+
"IMPROVED_PATIENT_UNDERSTANDING",
|
|
6814
|
+
"BETTER_TREATMENT_PLANNING",
|
|
6815
|
+
"ENHANCED_PATIENT_CONFIDENCE"
|
|
6816
|
+
],
|
|
6817
|
+
certificationRequirement: {
|
|
6818
|
+
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
6819
|
+
requiredSpecialties: []
|
|
6820
|
+
// No required specialties for consultation
|
|
6821
|
+
},
|
|
6822
|
+
documentationTemplates: [],
|
|
6823
|
+
isActive: true,
|
|
6824
|
+
createdAt: now,
|
|
6825
|
+
updatedAt: now
|
|
6826
|
+
};
|
|
6827
|
+
batch.set(technologyRef, technologyData);
|
|
6828
|
+
await batch.commit();
|
|
6829
|
+
console.log("[freeConsultationInfrastructure] Successfully created:");
|
|
6830
|
+
console.log(" \u2713 Category: consultation");
|
|
6831
|
+
console.log(" \u2713 Subcategory: free-consultation");
|
|
6832
|
+
console.log(" \u2713 Technology: free-consultation-tech");
|
|
6833
|
+
}
|
|
6834
|
+
|
|
6725
6835
|
// src/admin/index.ts
|
|
6726
6836
|
console.log("[Admin Module] Initialized and services exported.");
|
|
6727
6837
|
TimestampUtils.enableServerMode();
|
|
@@ -6754,5 +6864,6 @@ export {
|
|
|
6754
6864
|
PractitionerTokenStatus,
|
|
6755
6865
|
ProcedureAggregationService,
|
|
6756
6866
|
ReviewsAggregationService,
|
|
6757
|
-
UserRole
|
|
6867
|
+
UserRole,
|
|
6868
|
+
freeConsultationInfrastructure
|
|
6758
6869
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -6058,6 +6058,12 @@ declare class ProcedureService extends BaseService {
|
|
|
6058
6058
|
* @returns List of procedures
|
|
6059
6059
|
*/
|
|
6060
6060
|
getProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
|
|
6061
|
+
/**
|
|
6062
|
+
* Gets all inactive procedures for a practitioner
|
|
6063
|
+
* @param practitionerId - The ID of the practitioner
|
|
6064
|
+
* @returns List of inactive procedures
|
|
6065
|
+
*/
|
|
6066
|
+
getInactiveProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
|
|
6061
6067
|
/**
|
|
6062
6068
|
* Updates a procedure
|
|
6063
6069
|
* @param id - The ID of the procedure to update
|
|
@@ -6345,6 +6351,11 @@ declare class PractitionerService extends BaseService {
|
|
|
6345
6351
|
* @returns The created consultation procedure
|
|
6346
6352
|
*/
|
|
6347
6353
|
EnableFreeConsultation(practitionerId: string, clinicId: string): Promise<void>;
|
|
6354
|
+
/**
|
|
6355
|
+
* Ensures that the free consultation infrastructure exists by calling the Cloud Function
|
|
6356
|
+
* @returns Promise<boolean> - True if infrastructure exists or was created successfully
|
|
6357
|
+
*/
|
|
6358
|
+
ensureFreeConsultationInfrastructure(): Promise<boolean>;
|
|
6348
6359
|
/**
|
|
6349
6360
|
* Disables free consultation for a practitioner in a specific clinic
|
|
6350
6361
|
* Finds and deactivates the existing free consultation procedure
|
package/dist/index.d.ts
CHANGED
|
@@ -6058,6 +6058,12 @@ declare class ProcedureService extends BaseService {
|
|
|
6058
6058
|
* @returns List of procedures
|
|
6059
6059
|
*/
|
|
6060
6060
|
getProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
|
|
6061
|
+
/**
|
|
6062
|
+
* Gets all inactive procedures for a practitioner
|
|
6063
|
+
* @param practitionerId - The ID of the practitioner
|
|
6064
|
+
* @returns List of inactive procedures
|
|
6065
|
+
*/
|
|
6066
|
+
getInactiveProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
|
|
6061
6067
|
/**
|
|
6062
6068
|
* Updates a procedure
|
|
6063
6069
|
* @param id - The ID of the procedure to update
|
|
@@ -6345,6 +6351,11 @@ declare class PractitionerService extends BaseService {
|
|
|
6345
6351
|
* @returns The created consultation procedure
|
|
6346
6352
|
*/
|
|
6347
6353
|
EnableFreeConsultation(practitionerId: string, clinicId: string): Promise<void>;
|
|
6354
|
+
/**
|
|
6355
|
+
* Ensures that the free consultation infrastructure exists by calling the Cloud Function
|
|
6356
|
+
* @returns Promise<boolean> - True if infrastructure exists or was created successfully
|
|
6357
|
+
*/
|
|
6358
|
+
ensureFreeConsultationInfrastructure(): Promise<boolean>;
|
|
6348
6359
|
/**
|
|
6349
6360
|
* Disables free consultation for a practitioner in a specific clinic
|
|
6350
6361
|
* Finds and deactivates the existing free consultation procedure
|
package/dist/index.js
CHANGED
|
@@ -5543,6 +5543,7 @@ var PractitionerService = class extends BaseService {
|
|
|
5543
5543
|
*/
|
|
5544
5544
|
async EnableFreeConsultation(practitionerId, clinicId) {
|
|
5545
5545
|
try {
|
|
5546
|
+
await this.ensureFreeConsultationInfrastructure();
|
|
5546
5547
|
const practitioner = await this.getPractitioner(practitionerId);
|
|
5547
5548
|
if (!practitioner) {
|
|
5548
5549
|
throw new Error(`Practitioner ${practitionerId} not found`);
|
|
@@ -5559,17 +5560,32 @@ var PractitionerService = class extends BaseService {
|
|
|
5559
5560
|
`Practitioner ${practitionerId} is not associated with clinic ${clinicId}`
|
|
5560
5561
|
);
|
|
5561
5562
|
}
|
|
5562
|
-
const
|
|
5563
|
-
practitionerId
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5563
|
+
const [activeProcedures, inactiveProcedures] = await Promise.all([
|
|
5564
|
+
this.getProcedureService().getProceduresByPractitioner(practitionerId),
|
|
5565
|
+
this.getProcedureService().getInactiveProceduresByPractitioner(
|
|
5566
|
+
practitionerId
|
|
5567
|
+
)
|
|
5568
|
+
]);
|
|
5569
|
+
const allProcedures = [...activeProcedures, ...inactiveProcedures];
|
|
5570
|
+
const existingConsultation = allProcedures.find(
|
|
5571
|
+
(procedure) => procedure.technology.id === "free-consultation-tech" && procedure.clinicBranchId === clinicId
|
|
5567
5572
|
);
|
|
5568
5573
|
if (existingConsultation) {
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5574
|
+
if (existingConsultation.isActive) {
|
|
5575
|
+
console.log(
|
|
5576
|
+
`Free consultation already active for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
5577
|
+
);
|
|
5578
|
+
return;
|
|
5579
|
+
} else {
|
|
5580
|
+
await this.getProcedureService().updateProcedure(
|
|
5581
|
+
existingConsultation.id,
|
|
5582
|
+
{ isActive: true }
|
|
5583
|
+
);
|
|
5584
|
+
console.log(
|
|
5585
|
+
`Reactivated existing free consultation for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
5586
|
+
);
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5573
5589
|
}
|
|
5574
5590
|
const consultationData = {
|
|
5575
5591
|
name: "Free Consultation",
|
|
@@ -5602,6 +5618,74 @@ var PractitionerService = class extends BaseService {
|
|
|
5602
5618
|
throw error;
|
|
5603
5619
|
}
|
|
5604
5620
|
}
|
|
5621
|
+
/**
|
|
5622
|
+
* Ensures that the free consultation infrastructure exists by calling the Cloud Function
|
|
5623
|
+
* @returns Promise<boolean> - True if infrastructure exists or was created successfully
|
|
5624
|
+
*/
|
|
5625
|
+
async ensureFreeConsultationInfrastructure() {
|
|
5626
|
+
try {
|
|
5627
|
+
console.log(
|
|
5628
|
+
"[PRACTITIONER_SERVICE] Ensuring free consultation infrastructure via HTTP"
|
|
5629
|
+
);
|
|
5630
|
+
const currentUser = this.auth.currentUser;
|
|
5631
|
+
if (!currentUser) {
|
|
5632
|
+
throw new Error(
|
|
5633
|
+
"User must be authenticated to ensure free consultation infrastructure"
|
|
5634
|
+
);
|
|
5635
|
+
}
|
|
5636
|
+
const functionUrl = `https://europe-west6-metaestetics.cloudfunctions.net/bookingApi/ensureFreeConsultationInfrastructure`;
|
|
5637
|
+
const idToken = await currentUser.getIdToken();
|
|
5638
|
+
console.log(
|
|
5639
|
+
`[PRACTITIONER_SERVICE] Making fetch request to ${functionUrl}`
|
|
5640
|
+
);
|
|
5641
|
+
const response = await fetch(functionUrl, {
|
|
5642
|
+
method: "POST",
|
|
5643
|
+
mode: "cors",
|
|
5644
|
+
cache: "no-cache",
|
|
5645
|
+
credentials: "omit",
|
|
5646
|
+
headers: {
|
|
5647
|
+
"Content-Type": "application/json",
|
|
5648
|
+
Authorization: `Bearer ${idToken}`
|
|
5649
|
+
},
|
|
5650
|
+
redirect: "follow",
|
|
5651
|
+
referrerPolicy: "no-referrer",
|
|
5652
|
+
body: JSON.stringify({})
|
|
5653
|
+
// Empty body as no parameters needed
|
|
5654
|
+
});
|
|
5655
|
+
console.log(
|
|
5656
|
+
`[PRACTITIONER_SERVICE] Received response ${response.status}: ${response.statusText}`
|
|
5657
|
+
);
|
|
5658
|
+
if (!response.ok) {
|
|
5659
|
+
const errorText = await response.text();
|
|
5660
|
+
console.error(
|
|
5661
|
+
`[PRACTITIONER_SERVICE] Error response details: ${errorText}`
|
|
5662
|
+
);
|
|
5663
|
+
throw new Error(
|
|
5664
|
+
`Failed to ensure free consultation infrastructure: ${response.status} ${response.statusText} - ${errorText}`
|
|
5665
|
+
);
|
|
5666
|
+
}
|
|
5667
|
+
const result = await response.json();
|
|
5668
|
+
console.log(
|
|
5669
|
+
`[PRACTITIONER_SERVICE] Infrastructure check response:`,
|
|
5670
|
+
result
|
|
5671
|
+
);
|
|
5672
|
+
if (!result.success) {
|
|
5673
|
+
throw new Error(
|
|
5674
|
+
result.error || "Failed to ensure free consultation infrastructure"
|
|
5675
|
+
);
|
|
5676
|
+
}
|
|
5677
|
+
console.log(
|
|
5678
|
+
`[PRACTITIONER_SERVICE] Free consultation infrastructure ensured successfully`
|
|
5679
|
+
);
|
|
5680
|
+
return result.infrastructureExists;
|
|
5681
|
+
} catch (error) {
|
|
5682
|
+
console.error(
|
|
5683
|
+
"[PRACTITIONER_SERVICE] Error ensuring free consultation infrastructure:",
|
|
5684
|
+
error
|
|
5685
|
+
);
|
|
5686
|
+
throw error;
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5605
5689
|
/**
|
|
5606
5690
|
* Disables free consultation for a practitioner in a specific clinic
|
|
5607
5691
|
* Finds and deactivates the existing free consultation procedure
|
|
@@ -5627,7 +5711,7 @@ var PractitionerService = class extends BaseService {
|
|
|
5627
5711
|
practitionerId
|
|
5628
5712
|
);
|
|
5629
5713
|
const freeConsultation = existingProcedures.find(
|
|
5630
|
-
(procedure) => procedure.
|
|
5714
|
+
(procedure) => procedure.technology.id === "free-consultation-tech" && procedure.clinicBranchId === clinicId && procedure.isActive
|
|
5631
5715
|
);
|
|
5632
5716
|
if (!freeConsultation) {
|
|
5633
5717
|
console.log(
|
|
@@ -9001,6 +9085,20 @@ var ProcedureService = class extends BaseService {
|
|
|
9001
9085
|
const snapshot = await (0, import_firestore27.getDocs)(q);
|
|
9002
9086
|
return snapshot.docs.map((doc36) => doc36.data());
|
|
9003
9087
|
}
|
|
9088
|
+
/**
|
|
9089
|
+
* Gets all inactive procedures for a practitioner
|
|
9090
|
+
* @param practitionerId - The ID of the practitioner
|
|
9091
|
+
* @returns List of inactive procedures
|
|
9092
|
+
*/
|
|
9093
|
+
async getInactiveProceduresByPractitioner(practitionerId) {
|
|
9094
|
+
const q = (0, import_firestore27.query)(
|
|
9095
|
+
(0, import_firestore27.collection)(this.db, PROCEDURES_COLLECTION),
|
|
9096
|
+
(0, import_firestore27.where)("practitionerId", "==", practitionerId),
|
|
9097
|
+
(0, import_firestore27.where)("isActive", "==", false)
|
|
9098
|
+
);
|
|
9099
|
+
const snapshot = await (0, import_firestore27.getDocs)(q);
|
|
9100
|
+
return snapshot.docs.map((doc36) => doc36.data());
|
|
9101
|
+
}
|
|
9004
9102
|
/**
|
|
9005
9103
|
* Updates a procedure
|
|
9006
9104
|
* @param id - The ID of the procedure to update
|
package/dist/index.mjs
CHANGED
|
@@ -5447,6 +5447,7 @@ var PractitionerService = class extends BaseService {
|
|
|
5447
5447
|
*/
|
|
5448
5448
|
async EnableFreeConsultation(practitionerId, clinicId) {
|
|
5449
5449
|
try {
|
|
5450
|
+
await this.ensureFreeConsultationInfrastructure();
|
|
5450
5451
|
const practitioner = await this.getPractitioner(practitionerId);
|
|
5451
5452
|
if (!practitioner) {
|
|
5452
5453
|
throw new Error(`Practitioner ${practitionerId} not found`);
|
|
@@ -5463,17 +5464,32 @@ var PractitionerService = class extends BaseService {
|
|
|
5463
5464
|
`Practitioner ${practitionerId} is not associated with clinic ${clinicId}`
|
|
5464
5465
|
);
|
|
5465
5466
|
}
|
|
5466
|
-
const
|
|
5467
|
-
practitionerId
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5467
|
+
const [activeProcedures, inactiveProcedures] = await Promise.all([
|
|
5468
|
+
this.getProcedureService().getProceduresByPractitioner(practitionerId),
|
|
5469
|
+
this.getProcedureService().getInactiveProceduresByPractitioner(
|
|
5470
|
+
practitionerId
|
|
5471
|
+
)
|
|
5472
|
+
]);
|
|
5473
|
+
const allProcedures = [...activeProcedures, ...inactiveProcedures];
|
|
5474
|
+
const existingConsultation = allProcedures.find(
|
|
5475
|
+
(procedure) => procedure.technology.id === "free-consultation-tech" && procedure.clinicBranchId === clinicId
|
|
5471
5476
|
);
|
|
5472
5477
|
if (existingConsultation) {
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5478
|
+
if (existingConsultation.isActive) {
|
|
5479
|
+
console.log(
|
|
5480
|
+
`Free consultation already active for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
5481
|
+
);
|
|
5482
|
+
return;
|
|
5483
|
+
} else {
|
|
5484
|
+
await this.getProcedureService().updateProcedure(
|
|
5485
|
+
existingConsultation.id,
|
|
5486
|
+
{ isActive: true }
|
|
5487
|
+
);
|
|
5488
|
+
console.log(
|
|
5489
|
+
`Reactivated existing free consultation for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
5490
|
+
);
|
|
5491
|
+
return;
|
|
5492
|
+
}
|
|
5477
5493
|
}
|
|
5478
5494
|
const consultationData = {
|
|
5479
5495
|
name: "Free Consultation",
|
|
@@ -5506,6 +5522,74 @@ var PractitionerService = class extends BaseService {
|
|
|
5506
5522
|
throw error;
|
|
5507
5523
|
}
|
|
5508
5524
|
}
|
|
5525
|
+
/**
|
|
5526
|
+
* Ensures that the free consultation infrastructure exists by calling the Cloud Function
|
|
5527
|
+
* @returns Promise<boolean> - True if infrastructure exists or was created successfully
|
|
5528
|
+
*/
|
|
5529
|
+
async ensureFreeConsultationInfrastructure() {
|
|
5530
|
+
try {
|
|
5531
|
+
console.log(
|
|
5532
|
+
"[PRACTITIONER_SERVICE] Ensuring free consultation infrastructure via HTTP"
|
|
5533
|
+
);
|
|
5534
|
+
const currentUser = this.auth.currentUser;
|
|
5535
|
+
if (!currentUser) {
|
|
5536
|
+
throw new Error(
|
|
5537
|
+
"User must be authenticated to ensure free consultation infrastructure"
|
|
5538
|
+
);
|
|
5539
|
+
}
|
|
5540
|
+
const functionUrl = `https://europe-west6-metaestetics.cloudfunctions.net/bookingApi/ensureFreeConsultationInfrastructure`;
|
|
5541
|
+
const idToken = await currentUser.getIdToken();
|
|
5542
|
+
console.log(
|
|
5543
|
+
`[PRACTITIONER_SERVICE] Making fetch request to ${functionUrl}`
|
|
5544
|
+
);
|
|
5545
|
+
const response = await fetch(functionUrl, {
|
|
5546
|
+
method: "POST",
|
|
5547
|
+
mode: "cors",
|
|
5548
|
+
cache: "no-cache",
|
|
5549
|
+
credentials: "omit",
|
|
5550
|
+
headers: {
|
|
5551
|
+
"Content-Type": "application/json",
|
|
5552
|
+
Authorization: `Bearer ${idToken}`
|
|
5553
|
+
},
|
|
5554
|
+
redirect: "follow",
|
|
5555
|
+
referrerPolicy: "no-referrer",
|
|
5556
|
+
body: JSON.stringify({})
|
|
5557
|
+
// Empty body as no parameters needed
|
|
5558
|
+
});
|
|
5559
|
+
console.log(
|
|
5560
|
+
`[PRACTITIONER_SERVICE] Received response ${response.status}: ${response.statusText}`
|
|
5561
|
+
);
|
|
5562
|
+
if (!response.ok) {
|
|
5563
|
+
const errorText = await response.text();
|
|
5564
|
+
console.error(
|
|
5565
|
+
`[PRACTITIONER_SERVICE] Error response details: ${errorText}`
|
|
5566
|
+
);
|
|
5567
|
+
throw new Error(
|
|
5568
|
+
`Failed to ensure free consultation infrastructure: ${response.status} ${response.statusText} - ${errorText}`
|
|
5569
|
+
);
|
|
5570
|
+
}
|
|
5571
|
+
const result = await response.json();
|
|
5572
|
+
console.log(
|
|
5573
|
+
`[PRACTITIONER_SERVICE] Infrastructure check response:`,
|
|
5574
|
+
result
|
|
5575
|
+
);
|
|
5576
|
+
if (!result.success) {
|
|
5577
|
+
throw new Error(
|
|
5578
|
+
result.error || "Failed to ensure free consultation infrastructure"
|
|
5579
|
+
);
|
|
5580
|
+
}
|
|
5581
|
+
console.log(
|
|
5582
|
+
`[PRACTITIONER_SERVICE] Free consultation infrastructure ensured successfully`
|
|
5583
|
+
);
|
|
5584
|
+
return result.infrastructureExists;
|
|
5585
|
+
} catch (error) {
|
|
5586
|
+
console.error(
|
|
5587
|
+
"[PRACTITIONER_SERVICE] Error ensuring free consultation infrastructure:",
|
|
5588
|
+
error
|
|
5589
|
+
);
|
|
5590
|
+
throw error;
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5509
5593
|
/**
|
|
5510
5594
|
* Disables free consultation for a practitioner in a specific clinic
|
|
5511
5595
|
* Finds and deactivates the existing free consultation procedure
|
|
@@ -5531,7 +5615,7 @@ var PractitionerService = class extends BaseService {
|
|
|
5531
5615
|
practitionerId
|
|
5532
5616
|
);
|
|
5533
5617
|
const freeConsultation = existingProcedures.find(
|
|
5534
|
-
(procedure) => procedure.
|
|
5618
|
+
(procedure) => procedure.technology.id === "free-consultation-tech" && procedure.clinicBranchId === clinicId && procedure.isActive
|
|
5535
5619
|
);
|
|
5536
5620
|
if (!freeConsultation) {
|
|
5537
5621
|
console.log(
|
|
@@ -8986,6 +9070,20 @@ var ProcedureService = class extends BaseService {
|
|
|
8986
9070
|
const snapshot = await getDocs16(q);
|
|
8987
9071
|
return snapshot.docs.map((doc36) => doc36.data());
|
|
8988
9072
|
}
|
|
9073
|
+
/**
|
|
9074
|
+
* Gets all inactive procedures for a practitioner
|
|
9075
|
+
* @param practitionerId - The ID of the practitioner
|
|
9076
|
+
* @returns List of inactive procedures
|
|
9077
|
+
*/
|
|
9078
|
+
async getInactiveProceduresByPractitioner(practitionerId) {
|
|
9079
|
+
const q = query16(
|
|
9080
|
+
collection16(this.db, PROCEDURES_COLLECTION),
|
|
9081
|
+
where16("practitionerId", "==", practitionerId),
|
|
9082
|
+
where16("isActive", "==", false)
|
|
9083
|
+
);
|
|
9084
|
+
const snapshot = await getDocs16(q);
|
|
9085
|
+
return snapshot.docs.map((doc36) => doc36.data());
|
|
9086
|
+
}
|
|
8989
9087
|
/**
|
|
8990
9088
|
* Updates a procedure
|
|
8991
9089
|
* @param id - The ID of the procedure to update
|
package/package.json
CHANGED
package/src/admin/index.ts
CHANGED
|
@@ -139,3 +139,6 @@ export * from "./aggregation/reviews/reviews.aggregation.service";
|
|
|
139
139
|
// Re-export types that Cloud Functions might need direct access to
|
|
140
140
|
export * from "../types/appointment";
|
|
141
141
|
// Add other types as needed
|
|
142
|
+
|
|
143
|
+
// Export free consultation utilities
|
|
144
|
+
export * from "./free-consultation/free-consultation-utils.admin";
|
|
@@ -1217,6 +1217,9 @@ export class PractitionerService extends BaseService {
|
|
|
1217
1217
|
clinicId: string
|
|
1218
1218
|
): Promise<void> {
|
|
1219
1219
|
try {
|
|
1220
|
+
// First, ensure the free consultation infrastructure exists
|
|
1221
|
+
await this.ensureFreeConsultationInfrastructure();
|
|
1222
|
+
|
|
1220
1223
|
// Validate that practitioner exists and is active
|
|
1221
1224
|
const practitioner = await this.getPractitioner(practitionerId);
|
|
1222
1225
|
if (!practitioner) {
|
|
@@ -1243,23 +1246,41 @@ export class PractitionerService extends BaseService {
|
|
|
1243
1246
|
);
|
|
1244
1247
|
}
|
|
1245
1248
|
|
|
1246
|
-
//
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
+
// Get all procedures for this practitioner (including inactive ones)
|
|
1250
|
+
const [activeProcedures, inactiveProcedures] = await Promise.all([
|
|
1251
|
+
this.getProcedureService().getProceduresByPractitioner(practitionerId),
|
|
1252
|
+
this.getProcedureService().getInactiveProceduresByPractitioner(
|
|
1249
1253
|
practitionerId
|
|
1250
|
-
)
|
|
1251
|
-
|
|
1254
|
+
),
|
|
1255
|
+
]);
|
|
1256
|
+
|
|
1257
|
+
// Combine active and inactive procedures
|
|
1258
|
+
const allProcedures = [...activeProcedures, ...inactiveProcedures];
|
|
1259
|
+
|
|
1260
|
+
// Check if free consultation already exists (active or inactive)
|
|
1261
|
+
const existingConsultation = allProcedures.find(
|
|
1252
1262
|
(procedure) =>
|
|
1253
|
-
procedure.
|
|
1254
|
-
procedure.clinicBranchId === clinicId
|
|
1255
|
-
procedure.isActive
|
|
1263
|
+
procedure.technology.id === "free-consultation-tech" &&
|
|
1264
|
+
procedure.clinicBranchId === clinicId
|
|
1256
1265
|
);
|
|
1257
1266
|
|
|
1258
1267
|
if (existingConsultation) {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1268
|
+
if (existingConsultation.isActive) {
|
|
1269
|
+
console.log(
|
|
1270
|
+
`Free consultation already active for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
1271
|
+
);
|
|
1272
|
+
return;
|
|
1273
|
+
} else {
|
|
1274
|
+
// Reactivate the existing disabled consultation
|
|
1275
|
+
await this.getProcedureService().updateProcedure(
|
|
1276
|
+
existingConsultation.id,
|
|
1277
|
+
{ isActive: true }
|
|
1278
|
+
);
|
|
1279
|
+
console.log(
|
|
1280
|
+
`Reactivated existing free consultation for practitioner ${practitionerId} in clinic ${clinicId}`
|
|
1281
|
+
);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1263
1284
|
}
|
|
1264
1285
|
|
|
1265
1286
|
// Create procedure data for free consultation (without productId)
|
|
@@ -1297,6 +1318,91 @@ export class PractitionerService extends BaseService {
|
|
|
1297
1318
|
}
|
|
1298
1319
|
}
|
|
1299
1320
|
|
|
1321
|
+
/**
|
|
1322
|
+
* Ensures that the free consultation infrastructure exists by calling the Cloud Function
|
|
1323
|
+
* @returns Promise<boolean> - True if infrastructure exists or was created successfully
|
|
1324
|
+
*/
|
|
1325
|
+
async ensureFreeConsultationInfrastructure(): Promise<boolean> {
|
|
1326
|
+
try {
|
|
1327
|
+
console.log(
|
|
1328
|
+
"[PRACTITIONER_SERVICE] Ensuring free consultation infrastructure via HTTP"
|
|
1329
|
+
);
|
|
1330
|
+
|
|
1331
|
+
// Check if user is authenticated
|
|
1332
|
+
const currentUser = this.auth.currentUser;
|
|
1333
|
+
if (!currentUser) {
|
|
1334
|
+
throw new Error(
|
|
1335
|
+
"User must be authenticated to ensure free consultation infrastructure"
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// Construct the function URL for the Express app endpoint
|
|
1340
|
+
const functionUrl = `https://europe-west6-metaestetics.cloudfunctions.net/bookingApi/ensureFreeConsultationInfrastructure`;
|
|
1341
|
+
|
|
1342
|
+
// Get the authenticated user's ID token
|
|
1343
|
+
const idToken = await currentUser.getIdToken();
|
|
1344
|
+
|
|
1345
|
+
console.log(
|
|
1346
|
+
`[PRACTITIONER_SERVICE] Making fetch request to ${functionUrl}`
|
|
1347
|
+
);
|
|
1348
|
+
|
|
1349
|
+
// Make the HTTP request
|
|
1350
|
+
const response = await fetch(functionUrl, {
|
|
1351
|
+
method: "POST",
|
|
1352
|
+
mode: "cors",
|
|
1353
|
+
cache: "no-cache",
|
|
1354
|
+
credentials: "omit",
|
|
1355
|
+
headers: {
|
|
1356
|
+
"Content-Type": "application/json",
|
|
1357
|
+
Authorization: `Bearer ${idToken}`,
|
|
1358
|
+
},
|
|
1359
|
+
redirect: "follow",
|
|
1360
|
+
referrerPolicy: "no-referrer",
|
|
1361
|
+
body: JSON.stringify({}), // Empty body as no parameters needed
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
console.log(
|
|
1365
|
+
`[PRACTITIONER_SERVICE] Received response ${response.status}: ${response.statusText}`
|
|
1366
|
+
);
|
|
1367
|
+
|
|
1368
|
+
// Check if the request was successful
|
|
1369
|
+
if (!response.ok) {
|
|
1370
|
+
const errorText = await response.text();
|
|
1371
|
+
console.error(
|
|
1372
|
+
`[PRACTITIONER_SERVICE] Error response details: ${errorText}`
|
|
1373
|
+
);
|
|
1374
|
+
throw new Error(
|
|
1375
|
+
`Failed to ensure free consultation infrastructure: ${response.status} ${response.statusText} - ${errorText}`
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// Parse the response
|
|
1380
|
+
const result = await response.json();
|
|
1381
|
+
console.log(
|
|
1382
|
+
`[PRACTITIONER_SERVICE] Infrastructure check response:`,
|
|
1383
|
+
result
|
|
1384
|
+
);
|
|
1385
|
+
|
|
1386
|
+
if (!result.success) {
|
|
1387
|
+
throw new Error(
|
|
1388
|
+
result.error || "Failed to ensure free consultation infrastructure"
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
console.log(
|
|
1393
|
+
`[PRACTITIONER_SERVICE] Free consultation infrastructure ensured successfully`
|
|
1394
|
+
);
|
|
1395
|
+
|
|
1396
|
+
return result.infrastructureExists;
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
console.error(
|
|
1399
|
+
"[PRACTITIONER_SERVICE] Error ensuring free consultation infrastructure:",
|
|
1400
|
+
error
|
|
1401
|
+
);
|
|
1402
|
+
throw error;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1300
1406
|
/**
|
|
1301
1407
|
* Disables free consultation for a practitioner in a specific clinic
|
|
1302
1408
|
* Finds and deactivates the existing free consultation procedure
|
|
@@ -1328,13 +1434,14 @@ export class PractitionerService extends BaseService {
|
|
|
1328
1434
|
}
|
|
1329
1435
|
|
|
1330
1436
|
// Find the free consultation procedure for this practitioner in this clinic
|
|
1437
|
+
// Use the more specific search by technology ID instead of name
|
|
1331
1438
|
const existingProcedures =
|
|
1332
1439
|
await this.getProcedureService().getProceduresByPractitioner(
|
|
1333
1440
|
practitionerId
|
|
1334
1441
|
);
|
|
1335
1442
|
const freeConsultation = existingProcedures.find(
|
|
1336
1443
|
(procedure) =>
|
|
1337
|
-
procedure.
|
|
1444
|
+
procedure.technology.id === "free-consultation-tech" &&
|
|
1338
1445
|
procedure.clinicBranchId === clinicId &&
|
|
1339
1446
|
procedure.isActive
|
|
1340
1447
|
);
|
|
@@ -354,6 +354,23 @@ export class ProcedureService extends BaseService {
|
|
|
354
354
|
return snapshot.docs.map((doc) => doc.data() as Procedure);
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Gets all inactive procedures for a practitioner
|
|
359
|
+
* @param practitionerId - The ID of the practitioner
|
|
360
|
+
* @returns List of inactive procedures
|
|
361
|
+
*/
|
|
362
|
+
async getInactiveProceduresByPractitioner(
|
|
363
|
+
practitionerId: string
|
|
364
|
+
): Promise<Procedure[]> {
|
|
365
|
+
const q = query(
|
|
366
|
+
collection(this.db, PROCEDURES_COLLECTION),
|
|
367
|
+
where("practitionerId", "==", practitionerId),
|
|
368
|
+
where("isActive", "==", false)
|
|
369
|
+
);
|
|
370
|
+
const snapshot = await getDocs(q);
|
|
371
|
+
return snapshot.docs.map((doc) => doc.data() as Procedure);
|
|
372
|
+
}
|
|
373
|
+
|
|
357
374
|
/**
|
|
358
375
|
* Updates a procedure
|
|
359
376
|
* @param id - The ID of the procedure to update
|