@blackcode_sa/metaestetics-api 1.14.47 → 1.14.50
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 +1 -0
- package/dist/admin/index.d.ts +1 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +87 -26
- package/dist/index.mjs +87 -26
- package/package.json +1 -1
- package/src/services/appointment/appointment.service.ts +75 -19
- package/src/services/appointment/utils/form-initialization.utils.ts +49 -18
- package/src/types/appointment/index.ts +1 -0
package/dist/admin/index.d.mts
CHANGED
package/dist/admin/index.d.ts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -5648,6 +5648,7 @@ interface ZoneItemData {
|
|
|
5648
5648
|
parentZone: string;
|
|
5649
5649
|
subzones: string[];
|
|
5650
5650
|
notes?: string;
|
|
5651
|
+
notesVisibleToPatient?: boolean;
|
|
5651
5652
|
subtotal?: number;
|
|
5652
5653
|
ionNumber?: string;
|
|
5653
5654
|
createdAt?: string;
|
|
@@ -7735,6 +7736,16 @@ declare class AppointmentService extends BaseService {
|
|
|
7735
7736
|
* @returns The updated appointment
|
|
7736
7737
|
*/
|
|
7737
7738
|
updateZonePhotoNoteVisibility(appointmentId: string, zoneId: string, photoIndex: number, noteType: 'before' | 'after', visibleToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7739
|
+
/**
|
|
7740
|
+
* Updates visibility of notes for a zone item (product or standalone note)
|
|
7741
|
+
*
|
|
7742
|
+
* @param appointmentId ID of the appointment
|
|
7743
|
+
* @param zoneId Zone ID
|
|
7744
|
+
* @param itemIndex Index of the item in the zone
|
|
7745
|
+
* @param notesVisibleToPatient Whether the notes should be visible to patient
|
|
7746
|
+
* @returns The updated appointment
|
|
7747
|
+
*/
|
|
7748
|
+
updateZoneItemNoteVisibility(appointmentId: string, zoneId: string, itemIndex: number, notesVisibleToPatient: boolean): Promise<Appointment>;
|
|
7738
7749
|
/**
|
|
7739
7750
|
* Gets a specific photo entry from a zone
|
|
7740
7751
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -5648,6 +5648,7 @@ interface ZoneItemData {
|
|
|
5648
5648
|
parentZone: string;
|
|
5649
5649
|
subzones: string[];
|
|
5650
5650
|
notes?: string;
|
|
5651
|
+
notesVisibleToPatient?: boolean;
|
|
5651
5652
|
subtotal?: number;
|
|
5652
5653
|
ionNumber?: string;
|
|
5653
5654
|
createdAt?: string;
|
|
@@ -7735,6 +7736,16 @@ declare class AppointmentService extends BaseService {
|
|
|
7735
7736
|
* @returns The updated appointment
|
|
7736
7737
|
*/
|
|
7737
7738
|
updateZonePhotoNoteVisibility(appointmentId: string, zoneId: string, photoIndex: number, noteType: 'before' | 'after', visibleToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7739
|
+
/**
|
|
7740
|
+
* Updates visibility of notes for a zone item (product or standalone note)
|
|
7741
|
+
*
|
|
7742
|
+
* @param appointmentId ID of the appointment
|
|
7743
|
+
* @param zoneId Zone ID
|
|
7744
|
+
* @param itemIndex Index of the item in the zone
|
|
7745
|
+
* @param notesVisibleToPatient Whether the notes should be visible to patient
|
|
7746
|
+
* @returns The updated appointment
|
|
7747
|
+
*/
|
|
7748
|
+
updateZoneItemNoteVisibility(appointmentId: string, zoneId: string, itemIndex: number, notesVisibleToPatient: boolean): Promise<Appointment>;
|
|
7738
7749
|
/**
|
|
7739
7750
|
* Gets a specific photo entry from a zone
|
|
7740
7751
|
*
|
package/dist/index.js
CHANGED
|
@@ -4996,21 +4996,15 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4996
4996
|
);
|
|
4997
4997
|
continue;
|
|
4998
4998
|
}
|
|
4999
|
-
if (templateRef.isUserForm) {
|
|
5000
|
-
console.log(
|
|
5001
|
-
`[FormInit] Skipping user form ${templateRef.templateId} for extended procedure ${procedureId}.`
|
|
5002
|
-
);
|
|
5003
|
-
continue;
|
|
5004
|
-
}
|
|
5005
4999
|
const isRequired = templateRef.isRequired;
|
|
5006
|
-
const
|
|
5000
|
+
const isUserForm = templateRef.isUserForm || false;
|
|
5001
|
+
const formSubcollectionPath = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
5007
5002
|
const appointmentRef = (0, import_firestore9.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
5008
5003
|
const formsCollectionRef = (0, import_firestore9.collection)(appointmentRef, formSubcollectionPath);
|
|
5009
5004
|
const filledDocumentData = {
|
|
5010
5005
|
templateId: templateRef.templateId,
|
|
5011
5006
|
templateVersion: template.version,
|
|
5012
|
-
isUserForm
|
|
5013
|
-
// Always false for extended procedures
|
|
5007
|
+
isUserForm,
|
|
5014
5008
|
isRequired,
|
|
5015
5009
|
appointmentId,
|
|
5016
5010
|
procedureId,
|
|
@@ -5025,14 +5019,16 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5025
5019
|
try {
|
|
5026
5020
|
const docRef = await (0, import_firestore9.addDoc)(formsCollectionRef, filledDocumentData);
|
|
5027
5021
|
const filledDocumentId = docRef.id;
|
|
5022
|
+
if (isUserForm && isRequired) {
|
|
5023
|
+
pendingUserFormsIds.push(filledDocumentId);
|
|
5024
|
+
}
|
|
5028
5025
|
allLinkedFormIds.push(filledDocumentId);
|
|
5029
5026
|
const linkedForm = {
|
|
5030
5027
|
formId: filledDocumentId,
|
|
5031
5028
|
templateId: template.id,
|
|
5032
5029
|
templateVersion: template.version,
|
|
5033
5030
|
title: template.title,
|
|
5034
|
-
isUserForm
|
|
5035
|
-
// Always false for extended procedures
|
|
5031
|
+
isUserForm,
|
|
5036
5032
|
isRequired,
|
|
5037
5033
|
sortingOrder: templateRef.sortingOrder,
|
|
5038
5034
|
status: "pending" /* PENDING */,
|
|
@@ -5040,7 +5036,7 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5040
5036
|
};
|
|
5041
5037
|
initializedFormsInfo.push(linkedForm);
|
|
5042
5038
|
console.log(
|
|
5043
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
5039
|
+
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
5044
5040
|
);
|
|
5045
5041
|
} catch (error) {
|
|
5046
5042
|
console.error(
|
|
@@ -5074,6 +5070,26 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
5074
5070
|
);
|
|
5075
5071
|
}
|
|
5076
5072
|
}
|
|
5073
|
+
const userFormsRef = (0, import_firestore9.collection)(appointmentRef, USER_FORMS_SUBCOLLECTION);
|
|
5074
|
+
const userFormsQuery = (0, import_firestore9.query)(
|
|
5075
|
+
userFormsRef,
|
|
5076
|
+
(0, import_firestore9.where)("procedureId", "==", procedureId)
|
|
5077
|
+
);
|
|
5078
|
+
const userFormsSnap = await (0, import_firestore9.getDocs)(userFormsQuery);
|
|
5079
|
+
for (const formDoc of userFormsSnap.docs) {
|
|
5080
|
+
try {
|
|
5081
|
+
await (0, import_firestore9.deleteDoc)(formDoc.ref);
|
|
5082
|
+
removedFormIds.push(formDoc.id);
|
|
5083
|
+
console.log(
|
|
5084
|
+
`[FormInit] Removed user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
5085
|
+
);
|
|
5086
|
+
} catch (error) {
|
|
5087
|
+
console.error(
|
|
5088
|
+
`[FormInit] Error removing user form ${formDoc.id}:`,
|
|
5089
|
+
error
|
|
5090
|
+
);
|
|
5091
|
+
}
|
|
5092
|
+
}
|
|
5077
5093
|
return removedFormIds;
|
|
5078
5094
|
}
|
|
5079
5095
|
|
|
@@ -7005,6 +7021,28 @@ var AppointmentService = class extends BaseService {
|
|
|
7005
7021
|
throw error;
|
|
7006
7022
|
}
|
|
7007
7023
|
}
|
|
7024
|
+
/**
|
|
7025
|
+
* Updates visibility of notes for a zone item (product or standalone note)
|
|
7026
|
+
*
|
|
7027
|
+
* @param appointmentId ID of the appointment
|
|
7028
|
+
* @param zoneId Zone ID
|
|
7029
|
+
* @param itemIndex Index of the item in the zone
|
|
7030
|
+
* @param notesVisibleToPatient Whether the notes should be visible to patient
|
|
7031
|
+
* @returns The updated appointment
|
|
7032
|
+
*/
|
|
7033
|
+
async updateZoneItemNoteVisibility(appointmentId, zoneId, itemIndex, notesVisibleToPatient) {
|
|
7034
|
+
try {
|
|
7035
|
+
console.log(
|
|
7036
|
+
`[APPOINTMENT_SERVICE] Updating zone item note visibility at index ${itemIndex} for zone ${zoneId} to ${notesVisibleToPatient}`
|
|
7037
|
+
);
|
|
7038
|
+
return await updateZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, {
|
|
7039
|
+
notesVisibleToPatient
|
|
7040
|
+
});
|
|
7041
|
+
} catch (error) {
|
|
7042
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating zone item note visibility:`, error);
|
|
7043
|
+
throw error;
|
|
7044
|
+
}
|
|
7045
|
+
}
|
|
7008
7046
|
/**
|
|
7009
7047
|
* Gets a specific photo entry from a zone
|
|
7010
7048
|
*
|
|
@@ -7033,7 +7071,13 @@ var AppointmentService = class extends BaseService {
|
|
|
7033
7071
|
* @returns The updated appointment
|
|
7034
7072
|
*/
|
|
7035
7073
|
async updateFinalizationNotes(appointmentId, sharedNotes, internalNotes) {
|
|
7074
|
+
var _a, _b, _c;
|
|
7036
7075
|
try {
|
|
7076
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] updateFinalizationNotes called:", {
|
|
7077
|
+
appointmentId,
|
|
7078
|
+
sharedNotes,
|
|
7079
|
+
internalNotes
|
|
7080
|
+
});
|
|
7037
7081
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
7038
7082
|
if (!appointment) {
|
|
7039
7083
|
throw new Error(`Appointment ${appointmentId} not found`);
|
|
@@ -7050,23 +7094,40 @@ var AppointmentService = class extends BaseService {
|
|
|
7050
7094
|
finalizationNotesInternal: null,
|
|
7051
7095
|
finalizationNotes: null
|
|
7052
7096
|
};
|
|
7097
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Current metadata:", {
|
|
7098
|
+
finalizationNotesShared: currentMetadata.finalizationNotesShared,
|
|
7099
|
+
finalizationNotesInternal: currentMetadata.finalizationNotesInternal,
|
|
7100
|
+
finalizationNotes: currentMetadata.finalizationNotes
|
|
7101
|
+
});
|
|
7102
|
+
const metadataUpdate = {
|
|
7103
|
+
selectedZones: currentMetadata.selectedZones,
|
|
7104
|
+
zonePhotos: currentMetadata.zonePhotos,
|
|
7105
|
+
zonesData: currentMetadata.zonesData || null,
|
|
7106
|
+
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
7107
|
+
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
7108
|
+
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
7109
|
+
finalbilling: currentMetadata.finalbilling,
|
|
7110
|
+
finalizationNotesShared: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
7111
|
+
finalizationNotesInternal: internalNotes !== void 0 ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
7112
|
+
// Keep deprecated field for backward compatibility during migration
|
|
7113
|
+
finalizationNotes: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
7114
|
+
};
|
|
7115
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Update data metadata:", {
|
|
7116
|
+
finalizationNotesShared: metadataUpdate.finalizationNotesShared,
|
|
7117
|
+
finalizationNotesInternal: metadataUpdate.finalizationNotesInternal,
|
|
7118
|
+
finalizationNotes: metadataUpdate.finalizationNotes
|
|
7119
|
+
});
|
|
7053
7120
|
const updateData = {
|
|
7054
|
-
metadata:
|
|
7055
|
-
selectedZones: currentMetadata.selectedZones,
|
|
7056
|
-
zonePhotos: currentMetadata.zonePhotos,
|
|
7057
|
-
zonesData: currentMetadata.zonesData || null,
|
|
7058
|
-
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
7059
|
-
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
7060
|
-
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
7061
|
-
finalbilling: currentMetadata.finalbilling,
|
|
7062
|
-
finalizationNotesShared: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
7063
|
-
finalizationNotesInternal: internalNotes !== void 0 ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
7064
|
-
// Keep deprecated field for backward compatibility during migration
|
|
7065
|
-
finalizationNotes: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
7066
|
-
},
|
|
7121
|
+
metadata: metadataUpdate,
|
|
7067
7122
|
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
7068
7123
|
};
|
|
7069
|
-
|
|
7124
|
+
const result = await this.updateAppointment(appointmentId, updateData);
|
|
7125
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] After update, result metadata:", {
|
|
7126
|
+
finalizationNotesShared: (_a = result.metadata) == null ? void 0 : _a.finalizationNotesShared,
|
|
7127
|
+
finalizationNotesInternal: (_b = result.metadata) == null ? void 0 : _b.finalizationNotesInternal,
|
|
7128
|
+
finalizationNotes: (_c = result.metadata) == null ? void 0 : _c.finalizationNotes
|
|
7129
|
+
});
|
|
7130
|
+
return result;
|
|
7070
7131
|
} catch (error) {
|
|
7071
7132
|
console.error(`[APPOINTMENT_SERVICE] Error updating finalization notes:`, error);
|
|
7072
7133
|
throw error;
|
package/dist/index.mjs
CHANGED
|
@@ -4882,21 +4882,15 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4882
4882
|
);
|
|
4883
4883
|
continue;
|
|
4884
4884
|
}
|
|
4885
|
-
if (templateRef.isUserForm) {
|
|
4886
|
-
console.log(
|
|
4887
|
-
`[FormInit] Skipping user form ${templateRef.templateId} for extended procedure ${procedureId}.`
|
|
4888
|
-
);
|
|
4889
|
-
continue;
|
|
4890
|
-
}
|
|
4891
4885
|
const isRequired = templateRef.isRequired;
|
|
4892
|
-
const
|
|
4886
|
+
const isUserForm = templateRef.isUserForm || false;
|
|
4887
|
+
const formSubcollectionPath = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
4893
4888
|
const appointmentRef = doc6(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
4894
4889
|
const formsCollectionRef = collection5(appointmentRef, formSubcollectionPath);
|
|
4895
4890
|
const filledDocumentData = {
|
|
4896
4891
|
templateId: templateRef.templateId,
|
|
4897
4892
|
templateVersion: template.version,
|
|
4898
|
-
isUserForm
|
|
4899
|
-
// Always false for extended procedures
|
|
4893
|
+
isUserForm,
|
|
4900
4894
|
isRequired,
|
|
4901
4895
|
appointmentId,
|
|
4902
4896
|
procedureId,
|
|
@@ -4911,14 +4905,16 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4911
4905
|
try {
|
|
4912
4906
|
const docRef = await addDoc(formsCollectionRef, filledDocumentData);
|
|
4913
4907
|
const filledDocumentId = docRef.id;
|
|
4908
|
+
if (isUserForm && isRequired) {
|
|
4909
|
+
pendingUserFormsIds.push(filledDocumentId);
|
|
4910
|
+
}
|
|
4914
4911
|
allLinkedFormIds.push(filledDocumentId);
|
|
4915
4912
|
const linkedForm = {
|
|
4916
4913
|
formId: filledDocumentId,
|
|
4917
4914
|
templateId: template.id,
|
|
4918
4915
|
templateVersion: template.version,
|
|
4919
4916
|
title: template.title,
|
|
4920
|
-
isUserForm
|
|
4921
|
-
// Always false for extended procedures
|
|
4917
|
+
isUserForm,
|
|
4922
4918
|
isRequired,
|
|
4923
4919
|
sortingOrder: templateRef.sortingOrder,
|
|
4924
4920
|
status: "pending" /* PENDING */,
|
|
@@ -4926,7 +4922,7 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4926
4922
|
};
|
|
4927
4923
|
initializedFormsInfo.push(linkedForm);
|
|
4928
4924
|
console.log(
|
|
4929
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
4925
|
+
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
4930
4926
|
);
|
|
4931
4927
|
} catch (error) {
|
|
4932
4928
|
console.error(
|
|
@@ -4960,6 +4956,26 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
4960
4956
|
);
|
|
4961
4957
|
}
|
|
4962
4958
|
}
|
|
4959
|
+
const userFormsRef = collection5(appointmentRef, USER_FORMS_SUBCOLLECTION);
|
|
4960
|
+
const userFormsQuery = query5(
|
|
4961
|
+
userFormsRef,
|
|
4962
|
+
where5("procedureId", "==", procedureId)
|
|
4963
|
+
);
|
|
4964
|
+
const userFormsSnap = await getDocs5(userFormsQuery);
|
|
4965
|
+
for (const formDoc of userFormsSnap.docs) {
|
|
4966
|
+
try {
|
|
4967
|
+
await deleteDoc2(formDoc.ref);
|
|
4968
|
+
removedFormIds.push(formDoc.id);
|
|
4969
|
+
console.log(
|
|
4970
|
+
`[FormInit] Removed user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
4971
|
+
);
|
|
4972
|
+
} catch (error) {
|
|
4973
|
+
console.error(
|
|
4974
|
+
`[FormInit] Error removing user form ${formDoc.id}:`,
|
|
4975
|
+
error
|
|
4976
|
+
);
|
|
4977
|
+
}
|
|
4978
|
+
}
|
|
4963
4979
|
return removedFormIds;
|
|
4964
4980
|
}
|
|
4965
4981
|
|
|
@@ -6891,6 +6907,28 @@ var AppointmentService = class extends BaseService {
|
|
|
6891
6907
|
throw error;
|
|
6892
6908
|
}
|
|
6893
6909
|
}
|
|
6910
|
+
/**
|
|
6911
|
+
* Updates visibility of notes for a zone item (product or standalone note)
|
|
6912
|
+
*
|
|
6913
|
+
* @param appointmentId ID of the appointment
|
|
6914
|
+
* @param zoneId Zone ID
|
|
6915
|
+
* @param itemIndex Index of the item in the zone
|
|
6916
|
+
* @param notesVisibleToPatient Whether the notes should be visible to patient
|
|
6917
|
+
* @returns The updated appointment
|
|
6918
|
+
*/
|
|
6919
|
+
async updateZoneItemNoteVisibility(appointmentId, zoneId, itemIndex, notesVisibleToPatient) {
|
|
6920
|
+
try {
|
|
6921
|
+
console.log(
|
|
6922
|
+
`[APPOINTMENT_SERVICE] Updating zone item note visibility at index ${itemIndex} for zone ${zoneId} to ${notesVisibleToPatient}`
|
|
6923
|
+
);
|
|
6924
|
+
return await updateZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, {
|
|
6925
|
+
notesVisibleToPatient
|
|
6926
|
+
});
|
|
6927
|
+
} catch (error) {
|
|
6928
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating zone item note visibility:`, error);
|
|
6929
|
+
throw error;
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6894
6932
|
/**
|
|
6895
6933
|
* Gets a specific photo entry from a zone
|
|
6896
6934
|
*
|
|
@@ -6919,7 +6957,13 @@ var AppointmentService = class extends BaseService {
|
|
|
6919
6957
|
* @returns The updated appointment
|
|
6920
6958
|
*/
|
|
6921
6959
|
async updateFinalizationNotes(appointmentId, sharedNotes, internalNotes) {
|
|
6960
|
+
var _a, _b, _c;
|
|
6922
6961
|
try {
|
|
6962
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] updateFinalizationNotes called:", {
|
|
6963
|
+
appointmentId,
|
|
6964
|
+
sharedNotes,
|
|
6965
|
+
internalNotes
|
|
6966
|
+
});
|
|
6923
6967
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
6924
6968
|
if (!appointment) {
|
|
6925
6969
|
throw new Error(`Appointment ${appointmentId} not found`);
|
|
@@ -6936,23 +6980,40 @@ var AppointmentService = class extends BaseService {
|
|
|
6936
6980
|
finalizationNotesInternal: null,
|
|
6937
6981
|
finalizationNotes: null
|
|
6938
6982
|
};
|
|
6983
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Current metadata:", {
|
|
6984
|
+
finalizationNotesShared: currentMetadata.finalizationNotesShared,
|
|
6985
|
+
finalizationNotesInternal: currentMetadata.finalizationNotesInternal,
|
|
6986
|
+
finalizationNotes: currentMetadata.finalizationNotes
|
|
6987
|
+
});
|
|
6988
|
+
const metadataUpdate = {
|
|
6989
|
+
selectedZones: currentMetadata.selectedZones,
|
|
6990
|
+
zonePhotos: currentMetadata.zonePhotos,
|
|
6991
|
+
zonesData: currentMetadata.zonesData || null,
|
|
6992
|
+
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
6993
|
+
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
6994
|
+
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
6995
|
+
finalbilling: currentMetadata.finalbilling,
|
|
6996
|
+
finalizationNotesShared: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
6997
|
+
finalizationNotesInternal: internalNotes !== void 0 ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
6998
|
+
// Keep deprecated field for backward compatibility during migration
|
|
6999
|
+
finalizationNotes: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
7000
|
+
};
|
|
7001
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Update data metadata:", {
|
|
7002
|
+
finalizationNotesShared: metadataUpdate.finalizationNotesShared,
|
|
7003
|
+
finalizationNotesInternal: metadataUpdate.finalizationNotesInternal,
|
|
7004
|
+
finalizationNotes: metadataUpdate.finalizationNotes
|
|
7005
|
+
});
|
|
6939
7006
|
const updateData = {
|
|
6940
|
-
metadata:
|
|
6941
|
-
selectedZones: currentMetadata.selectedZones,
|
|
6942
|
-
zonePhotos: currentMetadata.zonePhotos,
|
|
6943
|
-
zonesData: currentMetadata.zonesData || null,
|
|
6944
|
-
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
6945
|
-
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
6946
|
-
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
6947
|
-
finalbilling: currentMetadata.finalbilling,
|
|
6948
|
-
finalizationNotesShared: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
6949
|
-
finalizationNotesInternal: internalNotes !== void 0 ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
6950
|
-
// Keep deprecated field for backward compatibility during migration
|
|
6951
|
-
finalizationNotes: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
6952
|
-
},
|
|
7007
|
+
metadata: metadataUpdate,
|
|
6953
7008
|
updatedAt: serverTimestamp7()
|
|
6954
7009
|
};
|
|
6955
|
-
|
|
7010
|
+
const result = await this.updateAppointment(appointmentId, updateData);
|
|
7011
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] After update, result metadata:", {
|
|
7012
|
+
finalizationNotesShared: (_a = result.metadata) == null ? void 0 : _a.finalizationNotesShared,
|
|
7013
|
+
finalizationNotesInternal: (_b = result.metadata) == null ? void 0 : _b.finalizationNotesInternal,
|
|
7014
|
+
finalizationNotes: (_c = result.metadata) == null ? void 0 : _c.finalizationNotes
|
|
7015
|
+
});
|
|
7016
|
+
return result;
|
|
6956
7017
|
} catch (error) {
|
|
6957
7018
|
console.error(`[APPOINTMENT_SERVICE] Error updating finalization notes:`, error);
|
|
6958
7019
|
throw error;
|
package/package.json
CHANGED
|
@@ -2200,6 +2200,34 @@ export class AppointmentService extends BaseService {
|
|
|
2200
2200
|
}
|
|
2201
2201
|
}
|
|
2202
2202
|
|
|
2203
|
+
/**
|
|
2204
|
+
* Updates visibility of notes for a zone item (product or standalone note)
|
|
2205
|
+
*
|
|
2206
|
+
* @param appointmentId ID of the appointment
|
|
2207
|
+
* @param zoneId Zone ID
|
|
2208
|
+
* @param itemIndex Index of the item in the zone
|
|
2209
|
+
* @param notesVisibleToPatient Whether the notes should be visible to patient
|
|
2210
|
+
* @returns The updated appointment
|
|
2211
|
+
*/
|
|
2212
|
+
async updateZoneItemNoteVisibility(
|
|
2213
|
+
appointmentId: string,
|
|
2214
|
+
zoneId: string,
|
|
2215
|
+
itemIndex: number,
|
|
2216
|
+
notesVisibleToPatient: boolean,
|
|
2217
|
+
): Promise<Appointment> {
|
|
2218
|
+
try {
|
|
2219
|
+
console.log(
|
|
2220
|
+
`[APPOINTMENT_SERVICE] Updating zone item note visibility at index ${itemIndex} for zone ${zoneId} to ${notesVisibleToPatient}`,
|
|
2221
|
+
);
|
|
2222
|
+
return await updateZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, {
|
|
2223
|
+
notesVisibleToPatient,
|
|
2224
|
+
});
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating zone item note visibility:`, error);
|
|
2227
|
+
throw error;
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2203
2231
|
/**
|
|
2204
2232
|
* Gets a specific photo entry from a zone
|
|
2205
2233
|
*
|
|
@@ -2238,6 +2266,12 @@ export class AppointmentService extends BaseService {
|
|
|
2238
2266
|
internalNotes?: string | null,
|
|
2239
2267
|
): Promise<Appointment> {
|
|
2240
2268
|
try {
|
|
2269
|
+
console.log('🔍 [APPOINTMENT_SERVICE] updateFinalizationNotes called:', {
|
|
2270
|
+
appointmentId,
|
|
2271
|
+
sharedNotes,
|
|
2272
|
+
internalNotes,
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2241
2275
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
2242
2276
|
if (!appointment) {
|
|
2243
2277
|
throw new Error(`Appointment ${appointmentId} not found`);
|
|
@@ -2256,29 +2290,51 @@ export class AppointmentService extends BaseService {
|
|
|
2256
2290
|
finalizationNotes: null,
|
|
2257
2291
|
};
|
|
2258
2292
|
|
|
2293
|
+
console.log('🔍 [APPOINTMENT_SERVICE] Current metadata:', {
|
|
2294
|
+
finalizationNotesShared: currentMetadata.finalizationNotesShared,
|
|
2295
|
+
finalizationNotesInternal: currentMetadata.finalizationNotesInternal,
|
|
2296
|
+
finalizationNotes: currentMetadata.finalizationNotes,
|
|
2297
|
+
});
|
|
2298
|
+
|
|
2299
|
+
const metadataUpdate = {
|
|
2300
|
+
selectedZones: currentMetadata.selectedZones,
|
|
2301
|
+
zonePhotos: currentMetadata.zonePhotos,
|
|
2302
|
+
zonesData: currentMetadata.zonesData || null,
|
|
2303
|
+
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
2304
|
+
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
2305
|
+
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
2306
|
+
finalbilling: currentMetadata.finalbilling,
|
|
2307
|
+
finalizationNotesShared:
|
|
2308
|
+
sharedNotes !== undefined ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
2309
|
+
finalizationNotesInternal:
|
|
2310
|
+
internalNotes !== undefined ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
2311
|
+
// Keep deprecated field for backward compatibility during migration
|
|
2312
|
+
finalizationNotes:
|
|
2313
|
+
sharedNotes !== undefined
|
|
2314
|
+
? sharedNotes
|
|
2315
|
+
: currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared,
|
|
2316
|
+
};
|
|
2317
|
+
|
|
2318
|
+
console.log('🔍 [APPOINTMENT_SERVICE] Update data metadata:', {
|
|
2319
|
+
finalizationNotesShared: metadataUpdate.finalizationNotesShared,
|
|
2320
|
+
finalizationNotesInternal: metadataUpdate.finalizationNotesInternal,
|
|
2321
|
+
finalizationNotes: metadataUpdate.finalizationNotes,
|
|
2322
|
+
});
|
|
2323
|
+
|
|
2259
2324
|
const updateData: UpdateAppointmentData = {
|
|
2260
|
-
metadata:
|
|
2261
|
-
selectedZones: currentMetadata.selectedZones,
|
|
2262
|
-
zonePhotos: currentMetadata.zonePhotos,
|
|
2263
|
-
zonesData: currentMetadata.zonesData || null,
|
|
2264
|
-
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
2265
|
-
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
2266
|
-
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
2267
|
-
finalbilling: currentMetadata.finalbilling,
|
|
2268
|
-
finalizationNotesShared:
|
|
2269
|
-
sharedNotes !== undefined ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
2270
|
-
finalizationNotesInternal:
|
|
2271
|
-
internalNotes !== undefined ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
2272
|
-
// Keep deprecated field for backward compatibility during migration
|
|
2273
|
-
finalizationNotes:
|
|
2274
|
-
sharedNotes !== undefined
|
|
2275
|
-
? sharedNotes
|
|
2276
|
-
: currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared,
|
|
2277
|
-
},
|
|
2325
|
+
metadata: metadataUpdate,
|
|
2278
2326
|
updatedAt: serverTimestamp(),
|
|
2279
2327
|
};
|
|
2280
2328
|
|
|
2281
|
-
|
|
2329
|
+
const result = await this.updateAppointment(appointmentId, updateData);
|
|
2330
|
+
|
|
2331
|
+
console.log('🔍 [APPOINTMENT_SERVICE] After update, result metadata:', {
|
|
2332
|
+
finalizationNotesShared: result.metadata?.finalizationNotesShared,
|
|
2333
|
+
finalizationNotesInternal: result.metadata?.finalizationNotesInternal,
|
|
2334
|
+
finalizationNotes: result.metadata?.finalizationNotes,
|
|
2335
|
+
});
|
|
2336
|
+
|
|
2337
|
+
return result;
|
|
2282
2338
|
} catch (error) {
|
|
2283
2339
|
console.error(`[APPOINTMENT_SERVICE] Error updating finalization notes:`, error);
|
|
2284
2340
|
throw error;
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DocumentTemplate,
|
|
4
4
|
FilledDocumentStatus,
|
|
5
5
|
DOCTOR_FORMS_SUBCOLLECTION,
|
|
6
|
+
USER_FORMS_SUBCOLLECTION,
|
|
6
7
|
DOCUMENTATION_TEMPLATES_COLLECTION,
|
|
7
8
|
} from '../../../types/documentation-templates';
|
|
8
9
|
import {
|
|
@@ -77,7 +78,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
// Initialize forms for each template (
|
|
81
|
+
// Initialize forms for each template (both user forms and doctor forms for extended procedures)
|
|
81
82
|
for (const templateRef of technologyTemplates) {
|
|
82
83
|
const template = templatesMap.get(templateRef.templateId);
|
|
83
84
|
if (!template) {
|
|
@@ -87,16 +88,11 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
87
88
|
continue;
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
// Skip user forms - only create doctor forms for extended procedures
|
|
91
|
-
if (templateRef.isUserForm) {
|
|
92
|
-
console.log(
|
|
93
|
-
`[FormInit] Skipping user form ${templateRef.templateId} for extended procedure ${procedureId}.`
|
|
94
|
-
);
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
91
|
const isRequired = templateRef.isRequired;
|
|
99
|
-
const
|
|
92
|
+
const isUserForm = templateRef.isUserForm || false;
|
|
93
|
+
const formSubcollectionPath = isUserForm
|
|
94
|
+
? USER_FORMS_SUBCOLLECTION
|
|
95
|
+
: DOCTOR_FORMS_SUBCOLLECTION;
|
|
100
96
|
|
|
101
97
|
// Create form document in subcollection
|
|
102
98
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
@@ -105,7 +101,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
105
101
|
const filledDocumentData = {
|
|
106
102
|
templateId: templateRef.templateId,
|
|
107
103
|
templateVersion: template.version,
|
|
108
|
-
isUserForm:
|
|
104
|
+
isUserForm: isUserForm,
|
|
109
105
|
isRequired: isRequired,
|
|
110
106
|
appointmentId: appointmentId,
|
|
111
107
|
procedureId: procedureId,
|
|
@@ -122,7 +118,10 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
122
118
|
const docRef = await addDoc(formsCollectionRef, filledDocumentData);
|
|
123
119
|
const filledDocumentId = docRef.id;
|
|
124
120
|
|
|
125
|
-
//
|
|
121
|
+
// Add to pendingUserFormsIds if it's a required user form
|
|
122
|
+
if (isUserForm && isRequired) {
|
|
123
|
+
pendingUserFormsIds.push(filledDocumentId);
|
|
124
|
+
}
|
|
126
125
|
|
|
127
126
|
allLinkedFormIds.push(filledDocumentId);
|
|
128
127
|
|
|
@@ -131,7 +130,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
131
130
|
templateId: template.id,
|
|
132
131
|
templateVersion: template.version,
|
|
133
132
|
title: template.title,
|
|
134
|
-
isUserForm:
|
|
133
|
+
isUserForm: isUserForm,
|
|
135
134
|
isRequired: isRequired,
|
|
136
135
|
sortingOrder: templateRef.sortingOrder,
|
|
137
136
|
status: FilledDocumentStatus.PENDING,
|
|
@@ -140,7 +139,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
140
139
|
initializedFormsInfo.push(linkedForm);
|
|
141
140
|
|
|
142
141
|
console.log(
|
|
143
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
142
|
+
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
144
143
|
);
|
|
145
144
|
} catch (error) {
|
|
146
145
|
console.error(
|
|
@@ -155,6 +154,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
155
154
|
|
|
156
155
|
/**
|
|
157
156
|
* Removes all forms associated with a specific procedure from an appointment
|
|
157
|
+
* Removes both user forms and doctor forms
|
|
158
158
|
* @param db Firestore instance
|
|
159
159
|
* @param appointmentId Appointment ID
|
|
160
160
|
* @param procedureId Procedure ID to remove forms for
|
|
@@ -167,11 +167,10 @@ export async function removeFormsForExtendedProcedure(
|
|
|
167
167
|
): Promise<string[]> {
|
|
168
168
|
const removedFormIds: string[] = [];
|
|
169
169
|
|
|
170
|
-
// Only remove from doctor forms subcollection (no user forms for extended procedures)
|
|
171
170
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
172
|
-
const doctorFormsRef = collection(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
173
171
|
|
|
174
|
-
//
|
|
172
|
+
// Remove from doctor forms subcollection
|
|
173
|
+
const doctorFormsRef = collection(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
175
174
|
const doctorFormsQuery = query(
|
|
176
175
|
doctorFormsRef,
|
|
177
176
|
where('procedureId', '==', procedureId)
|
|
@@ -193,6 +192,29 @@ export async function removeFormsForExtendedProcedure(
|
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
|
|
195
|
+
// Remove from user forms subcollection
|
|
196
|
+
const userFormsRef = collection(appointmentRef, USER_FORMS_SUBCOLLECTION);
|
|
197
|
+
const userFormsQuery = query(
|
|
198
|
+
userFormsRef,
|
|
199
|
+
where('procedureId', '==', procedureId)
|
|
200
|
+
);
|
|
201
|
+
const userFormsSnap = await getDocs(userFormsQuery);
|
|
202
|
+
|
|
203
|
+
for (const formDoc of userFormsSnap.docs) {
|
|
204
|
+
try {
|
|
205
|
+
await deleteDoc(formDoc.ref);
|
|
206
|
+
removedFormIds.push(formDoc.id);
|
|
207
|
+
console.log(
|
|
208
|
+
`[FormInit] Removed user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
209
|
+
);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.error(
|
|
212
|
+
`[FormInit] Error removing user form ${formDoc.id}:`,
|
|
213
|
+
error
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
196
218
|
return removedFormIds;
|
|
197
219
|
}
|
|
198
220
|
|
|
@@ -211,9 +233,9 @@ export async function getFormsForExtendedProcedure(
|
|
|
211
233
|
const formIds: string[] = [];
|
|
212
234
|
|
|
213
235
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
214
|
-
const doctorFormsRef = collection(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
215
236
|
|
|
216
237
|
// Query doctor forms for this procedure
|
|
238
|
+
const doctorFormsRef = collection(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
217
239
|
const doctorFormsQuery = query(
|
|
218
240
|
doctorFormsRef,
|
|
219
241
|
where('procedureId', '==', procedureId)
|
|
@@ -221,5 +243,14 @@ export async function getFormsForExtendedProcedure(
|
|
|
221
243
|
const doctorFormsSnap = await getDocs(doctorFormsQuery);
|
|
222
244
|
doctorFormsSnap.docs.forEach(doc => formIds.push(doc.id));
|
|
223
245
|
|
|
246
|
+
// Query user forms for this procedure
|
|
247
|
+
const userFormsRef = collection(appointmentRef, USER_FORMS_SUBCOLLECTION);
|
|
248
|
+
const userFormsQuery = query(
|
|
249
|
+
userFormsRef,
|
|
250
|
+
where('procedureId', '==', procedureId)
|
|
251
|
+
);
|
|
252
|
+
const userFormsSnap = await getDocs(userFormsQuery);
|
|
253
|
+
userFormsSnap.docs.forEach(doc => formIds.push(doc.id));
|
|
254
|
+
|
|
224
255
|
return formIds;
|
|
225
256
|
}
|
|
@@ -166,6 +166,7 @@ export interface ZoneItemData {
|
|
|
166
166
|
parentZone: string; // Zone key in format "category.zone" (e.g., "face.forehead")
|
|
167
167
|
subzones: string[];
|
|
168
168
|
notes?: string;
|
|
169
|
+
notesVisibleToPatient?: boolean; // Whether notes are visible to patient (privacy-first, default false)
|
|
169
170
|
subtotal?: number;
|
|
170
171
|
ionNumber?: string;
|
|
171
172
|
createdAt?: string; // ISO timestamp
|