@blackcode_sa/metaestetics-api 1.12.33 → 1.12.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1752 -1621
- package/dist/index.mjs +1520 -1389
- package/package.json +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +70 -119
- package/src/services/appointment/utils/extended-procedure.utils.ts +53 -0
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -0
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
startAfter,
|
|
16
16
|
QueryConstraint,
|
|
17
17
|
DocumentSnapshot,
|
|
18
|
-
} from
|
|
18
|
+
} from 'firebase/firestore';
|
|
19
19
|
import {
|
|
20
20
|
Appointment,
|
|
21
21
|
AppointmentStatus,
|
|
@@ -24,25 +24,18 @@ import {
|
|
|
24
24
|
APPOINTMENTS_COLLECTION,
|
|
25
25
|
SearchAppointmentsParams,
|
|
26
26
|
PaymentStatus,
|
|
27
|
-
} from
|
|
28
|
-
import { CalendarEvent, CALENDAR_COLLECTION } from
|
|
29
|
-
import { ProcedureSummaryInfo } from
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} from
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import { PATIENTS_COLLECTION } from "../../../types/patient";
|
|
40
|
-
import { PROCEDURES_COLLECTION } from "../../../types/procedure";
|
|
41
|
-
import {
|
|
42
|
-
Technology,
|
|
43
|
-
TECHNOLOGIES_COLLECTION,
|
|
44
|
-
} from "../../../backoffice/types/technology.types";
|
|
45
|
-
import type { ContraindicationDynamic } from "../../../backoffice";
|
|
27
|
+
} from '../../../types/appointment';
|
|
28
|
+
import { CalendarEvent, CALENDAR_COLLECTION } from '../../../types/calendar';
|
|
29
|
+
import { ProcedureSummaryInfo } from '../../../types/procedure';
|
|
30
|
+
import { ClinicInfo, PatientProfileInfo, PractitionerProfileInfo } from '../../../types/profile';
|
|
31
|
+
import { BlockingCondition } from '../../../backoffice/types/static/blocking-condition.types';
|
|
32
|
+
import { Requirement } from '../../../backoffice/types/requirement.types';
|
|
33
|
+
import { PRACTITIONERS_COLLECTION } from '../../../types/practitioner';
|
|
34
|
+
import { CLINICS_COLLECTION } from '../../../types/clinic';
|
|
35
|
+
import { PATIENTS_COLLECTION } from '../../../types/patient';
|
|
36
|
+
import { PROCEDURES_COLLECTION } from '../../../types/procedure';
|
|
37
|
+
import { Technology, TECHNOLOGIES_COLLECTION } from '../../../backoffice/types/technology.types';
|
|
38
|
+
import type { ContraindicationDynamic } from '../../../backoffice';
|
|
46
39
|
|
|
47
40
|
/**
|
|
48
41
|
* Fetches all the necessary information for an appointment by IDs.
|
|
@@ -59,7 +52,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
59
52
|
clinicId: string,
|
|
60
53
|
practitionerId: string,
|
|
61
54
|
patientId: string,
|
|
62
|
-
procedureId: string
|
|
55
|
+
procedureId: string,
|
|
63
56
|
): Promise<{
|
|
64
57
|
clinicInfo: ClinicInfo;
|
|
65
58
|
practitionerInfo: PractitionerProfileInfo;
|
|
@@ -72,13 +65,12 @@ export async function fetchAggregatedInfoUtil(
|
|
|
72
65
|
}> {
|
|
73
66
|
try {
|
|
74
67
|
// Fetch all data in parallel for efficiency
|
|
75
|
-
const [clinicDoc, practitionerDoc, patientDoc, procedureDoc] =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
]);
|
|
68
|
+
const [clinicDoc, practitionerDoc, patientDoc, procedureDoc] = await Promise.all([
|
|
69
|
+
getDoc(doc(db, CLINICS_COLLECTION, clinicId)),
|
|
70
|
+
getDoc(doc(db, PRACTITIONERS_COLLECTION, practitionerId)),
|
|
71
|
+
getDoc(doc(db, PATIENTS_COLLECTION, patientId)),
|
|
72
|
+
getDoc(doc(db, PROCEDURES_COLLECTION, procedureId)),
|
|
73
|
+
]);
|
|
82
74
|
|
|
83
75
|
// Check if all required entities exist
|
|
84
76
|
if (!clinicDoc.exists()) {
|
|
@@ -102,7 +94,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
102
94
|
// Extract relevant info for ClinicInfo
|
|
103
95
|
const clinicInfo: ClinicInfo = {
|
|
104
96
|
id: clinicId,
|
|
105
|
-
featuredPhoto: clinicData.featuredPhotos?.[0] ||
|
|
97
|
+
featuredPhoto: clinicData.featuredPhotos?.[0] || '',
|
|
106
98
|
name: clinicData.name,
|
|
107
99
|
description: clinicData.description || null,
|
|
108
100
|
location: clinicData.location,
|
|
@@ -113,10 +105,10 @@ export async function fetchAggregatedInfoUtil(
|
|
|
113
105
|
const practitionerInfo: PractitionerProfileInfo = {
|
|
114
106
|
id: practitionerId,
|
|
115
107
|
practitionerPhoto: practitionerData.basicInfo?.profileImageUrl || null,
|
|
116
|
-
name: `${practitionerData.basicInfo?.firstName ||
|
|
117
|
-
practitionerData.basicInfo?.lastName ||
|
|
108
|
+
name: `${practitionerData.basicInfo?.firstName || ''} ${
|
|
109
|
+
practitionerData.basicInfo?.lastName || ''
|
|
118
110
|
}`.trim(),
|
|
119
|
-
email: practitionerData.basicInfo?.email ||
|
|
111
|
+
email: practitionerData.basicInfo?.email || '',
|
|
120
112
|
phone: practitionerData.basicInfo?.phoneNumber || null,
|
|
121
113
|
certification: practitionerData.certification,
|
|
122
114
|
};
|
|
@@ -125,11 +117,11 @@ export async function fetchAggregatedInfoUtil(
|
|
|
125
117
|
// Note: This may need adjustment depending on how patient data is structured
|
|
126
118
|
const patientInfo: PatientProfileInfo = {
|
|
127
119
|
id: patientId,
|
|
128
|
-
fullName: patientData.displayName ||
|
|
129
|
-
email: patientData.email ||
|
|
120
|
+
fullName: patientData.displayName || '',
|
|
121
|
+
email: patientData.email || '',
|
|
130
122
|
phone: patientData.phoneNumber || null,
|
|
131
123
|
dateOfBirth: patientData.dateOfBirth || Timestamp.now(),
|
|
132
|
-
gender: patientData.gender ||
|
|
124
|
+
gender: patientData.gender || 'other',
|
|
133
125
|
};
|
|
134
126
|
|
|
135
127
|
// Extract procedureInfo from the procedure document
|
|
@@ -138,13 +130,13 @@ export async function fetchAggregatedInfoUtil(
|
|
|
138
130
|
id: procedureId,
|
|
139
131
|
name: procedureData.name,
|
|
140
132
|
description: procedureData.description,
|
|
141
|
-
photo: procedureData.photo ||
|
|
133
|
+
photo: procedureData.photo || '',
|
|
142
134
|
family: procedureData.family,
|
|
143
|
-
categoryName: procedureData.category?.name ||
|
|
144
|
-
subcategoryName: procedureData.subcategory?.name ||
|
|
145
|
-
technologyName: procedureData.technology?.name ||
|
|
146
|
-
brandName: procedureData.product?.brand ||
|
|
147
|
-
productName: procedureData.product?.name ||
|
|
135
|
+
categoryName: procedureData.category?.name || '',
|
|
136
|
+
subcategoryName: procedureData.subcategory?.name || '',
|
|
137
|
+
technologyName: procedureData.technology?.name || '',
|
|
138
|
+
brandName: procedureData.product?.brand || '',
|
|
139
|
+
productName: procedureData.product?.name || '',
|
|
148
140
|
price: procedureData.price || 0,
|
|
149
141
|
pricingMeasure: procedureData.pricingMeasure,
|
|
150
142
|
currency: procedureData.currency,
|
|
@@ -156,7 +148,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
156
148
|
};
|
|
157
149
|
|
|
158
150
|
// Fetch the technology document to get procedure requirements
|
|
159
|
-
let technologyId =
|
|
151
|
+
let technologyId = '';
|
|
160
152
|
if (procedureData.technology?.id) {
|
|
161
153
|
technologyId = procedureData.technology.id;
|
|
162
154
|
}
|
|
@@ -168,9 +160,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
168
160
|
|
|
169
161
|
// If we have a technology ID, fetch its details
|
|
170
162
|
if (technologyId) {
|
|
171
|
-
const technologyDoc = await getDoc(
|
|
172
|
-
doc(db, TECHNOLOGIES_COLLECTION, technologyId)
|
|
173
|
-
);
|
|
163
|
+
const technologyDoc = await getDoc(doc(db, TECHNOLOGIES_COLLECTION, technologyId));
|
|
174
164
|
if (technologyDoc.exists()) {
|
|
175
165
|
const technologyData = technologyDoc.data() as Technology;
|
|
176
166
|
|
|
@@ -199,7 +189,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
199
189
|
postProcedureRequirements,
|
|
200
190
|
};
|
|
201
191
|
} catch (error) {
|
|
202
|
-
console.error(
|
|
192
|
+
console.error('Error fetching aggregated info:', error);
|
|
203
193
|
throw error;
|
|
204
194
|
}
|
|
205
195
|
}
|
|
@@ -304,7 +294,7 @@ export async function fetchAggregatedInfoUtil(
|
|
|
304
294
|
export async function updateAppointmentUtil(
|
|
305
295
|
db: Firestore,
|
|
306
296
|
appointmentId: string,
|
|
307
|
-
data: UpdateAppointmentData
|
|
297
|
+
data: UpdateAppointmentData,
|
|
308
298
|
): Promise<Appointment> {
|
|
309
299
|
try {
|
|
310
300
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
@@ -317,62 +307,46 @@ export async function updateAppointmentUtil(
|
|
|
317
307
|
const currentAppointment = appointmentDoc.data() as Appointment;
|
|
318
308
|
|
|
319
309
|
// Handle requirement completion tracking
|
|
320
|
-
let completedPreRequirements =
|
|
321
|
-
|
|
322
|
-
let completedPostRequirements =
|
|
323
|
-
currentAppointment.completedPostRequirements || [];
|
|
310
|
+
let completedPreRequirements = currentAppointment.completedPreRequirements || [];
|
|
311
|
+
let completedPostRequirements = currentAppointment.completedPostRequirements || [];
|
|
324
312
|
|
|
325
313
|
if (data.completedPreRequirements) {
|
|
326
314
|
// Validate that all IDs exist in the pre-requirements
|
|
327
|
-
const validPreReqIds = currentAppointment.preProcedureRequirements.map(
|
|
328
|
-
(req) => req.id
|
|
329
|
-
);
|
|
315
|
+
const validPreReqIds = currentAppointment.preProcedureRequirements.map(req => req.id);
|
|
330
316
|
|
|
331
317
|
// Only perform validation and merging if the input is an array
|
|
332
318
|
if (Array.isArray(data.completedPreRequirements)) {
|
|
333
319
|
const invalidPreReqIds = data.completedPreRequirements.filter(
|
|
334
|
-
|
|
320
|
+
id => !validPreReqIds.includes(id),
|
|
335
321
|
);
|
|
336
322
|
|
|
337
323
|
if (invalidPreReqIds.length > 0) {
|
|
338
|
-
throw new Error(
|
|
339
|
-
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
340
|
-
);
|
|
324
|
+
throw new Error(`Invalid pre-requirement IDs: ${invalidPreReqIds.join(', ')}`);
|
|
341
325
|
}
|
|
342
326
|
|
|
343
327
|
// Update the completed pre-requirements
|
|
344
328
|
completedPreRequirements = [
|
|
345
|
-
...new Set([
|
|
346
|
-
...completedPreRequirements,
|
|
347
|
-
...data.completedPreRequirements,
|
|
348
|
-
]),
|
|
329
|
+
...new Set([...completedPreRequirements, ...data.completedPreRequirements]),
|
|
349
330
|
];
|
|
350
331
|
}
|
|
351
332
|
}
|
|
352
333
|
|
|
353
334
|
if (data.completedPostRequirements) {
|
|
354
335
|
// Validate that all IDs exist in the post-requirements
|
|
355
|
-
const validPostReqIds = currentAppointment.postProcedureRequirements.map(
|
|
356
|
-
(req) => req.id
|
|
357
|
-
);
|
|
336
|
+
const validPostReqIds = currentAppointment.postProcedureRequirements.map(req => req.id);
|
|
358
337
|
|
|
359
338
|
if (Array.isArray(data.completedPostRequirements)) {
|
|
360
339
|
const invalidPostReqIds = data.completedPostRequirements.filter(
|
|
361
|
-
|
|
340
|
+
id => !validPostReqIds.includes(id),
|
|
362
341
|
);
|
|
363
342
|
|
|
364
343
|
if (invalidPostReqIds.length > 0) {
|
|
365
|
-
throw new Error(
|
|
366
|
-
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
367
|
-
);
|
|
344
|
+
throw new Error(`Invalid post-requirement IDs: ${invalidPostReqIds.join(', ')}`);
|
|
368
345
|
}
|
|
369
346
|
|
|
370
347
|
// Update the completed post-requirements
|
|
371
348
|
completedPostRequirements = [
|
|
372
|
-
...new Set([
|
|
373
|
-
...completedPostRequirements,
|
|
374
|
-
...data.completedPostRequirements,
|
|
375
|
-
]),
|
|
349
|
+
...new Set([...completedPostRequirements, ...data.completedPostRequirements]),
|
|
376
350
|
];
|
|
377
351
|
}
|
|
378
352
|
}
|
|
@@ -390,7 +364,7 @@ export async function updateAppointmentUtil(
|
|
|
390
364
|
};
|
|
391
365
|
|
|
392
366
|
// Remove undefined fields
|
|
393
|
-
Object.keys(updateData).forEach(
|
|
367
|
+
Object.keys(updateData).forEach(key => {
|
|
394
368
|
if (updateData[key] === undefined) {
|
|
395
369
|
delete updateData[key];
|
|
396
370
|
}
|
|
@@ -399,20 +373,13 @@ export async function updateAppointmentUtil(
|
|
|
399
373
|
// Handle status changes
|
|
400
374
|
if (data.status && data.status !== currentAppointment.status) {
|
|
401
375
|
// Handle confirmation
|
|
402
|
-
if (
|
|
403
|
-
data.status === AppointmentStatus.CONFIRMED &&
|
|
404
|
-
!updateData.confirmationTime
|
|
405
|
-
) {
|
|
376
|
+
if (data.status === AppointmentStatus.CONFIRMED && !updateData.confirmationTime) {
|
|
406
377
|
updateData.confirmationTime = Timestamp.now();
|
|
407
378
|
}
|
|
408
379
|
|
|
409
380
|
// Update the related calendar event status if needed
|
|
410
381
|
if (currentAppointment.calendarEventId) {
|
|
411
|
-
await updateCalendarEventStatus(
|
|
412
|
-
db,
|
|
413
|
-
currentAppointment.calendarEventId,
|
|
414
|
-
data.status
|
|
415
|
-
);
|
|
382
|
+
await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
|
|
416
383
|
}
|
|
417
384
|
}
|
|
418
385
|
|
|
@@ -422,9 +389,7 @@ export async function updateAppointmentUtil(
|
|
|
422
389
|
// Fetch the updated appointment
|
|
423
390
|
const updatedAppointmentDoc = await getDoc(appointmentRef);
|
|
424
391
|
if (!updatedAppointmentDoc.exists()) {
|
|
425
|
-
throw new Error(
|
|
426
|
-
`Failed to retrieve updated appointment ${appointmentId}`
|
|
427
|
-
);
|
|
392
|
+
throw new Error(`Failed to retrieve updated appointment ${appointmentId}`);
|
|
428
393
|
}
|
|
429
394
|
|
|
430
395
|
return updatedAppointmentDoc.data() as Appointment;
|
|
@@ -444,7 +409,7 @@ export async function updateAppointmentUtil(
|
|
|
444
409
|
async function updateCalendarEventStatus(
|
|
445
410
|
db: Firestore,
|
|
446
411
|
calendarEventId: string,
|
|
447
|
-
appointmentStatus: AppointmentStatus
|
|
412
|
+
appointmentStatus: AppointmentStatus,
|
|
448
413
|
): Promise<void> {
|
|
449
414
|
try {
|
|
450
415
|
const calendarEventRef = doc(db, CALENDAR_COLLECTION, calendarEventId);
|
|
@@ -459,17 +424,17 @@ async function updateCalendarEventStatus(
|
|
|
459
424
|
let calendarStatus;
|
|
460
425
|
switch (appointmentStatus) {
|
|
461
426
|
case AppointmentStatus.CONFIRMED:
|
|
462
|
-
calendarStatus =
|
|
427
|
+
calendarStatus = 'confirmed';
|
|
463
428
|
break;
|
|
464
429
|
case AppointmentStatus.CANCELED_PATIENT:
|
|
465
430
|
case AppointmentStatus.CANCELED_CLINIC:
|
|
466
|
-
calendarStatus =
|
|
431
|
+
calendarStatus = 'canceled';
|
|
467
432
|
break;
|
|
468
433
|
case AppointmentStatus.RESCHEDULED_BY_CLINIC:
|
|
469
|
-
calendarStatus =
|
|
434
|
+
calendarStatus = 'rescheduled';
|
|
470
435
|
break;
|
|
471
436
|
case AppointmentStatus.COMPLETED:
|
|
472
|
-
calendarStatus =
|
|
437
|
+
calendarStatus = 'completed';
|
|
473
438
|
break;
|
|
474
439
|
default:
|
|
475
440
|
// For other states, don't update the calendar status
|
|
@@ -495,12 +460,10 @@ async function updateCalendarEventStatus(
|
|
|
495
460
|
*/
|
|
496
461
|
export async function getAppointmentByIdUtil(
|
|
497
462
|
db: Firestore,
|
|
498
|
-
appointmentId: string
|
|
463
|
+
appointmentId: string,
|
|
499
464
|
): Promise<Appointment | null> {
|
|
500
465
|
try {
|
|
501
|
-
const appointmentDoc = await getDoc(
|
|
502
|
-
doc(db, APPOINTMENTS_COLLECTION, appointmentId)
|
|
503
|
-
);
|
|
466
|
+
const appointmentDoc = await getDoc(doc(db, APPOINTMENTS_COLLECTION, appointmentId));
|
|
504
467
|
|
|
505
468
|
if (!appointmentDoc.exists()) {
|
|
506
469
|
return null;
|
|
@@ -522,52 +485,44 @@ export async function getAppointmentByIdUtil(
|
|
|
522
485
|
*/
|
|
523
486
|
export async function searchAppointmentsUtil(
|
|
524
487
|
db: Firestore,
|
|
525
|
-
params: SearchAppointmentsParams
|
|
488
|
+
params: SearchAppointmentsParams,
|
|
526
489
|
): Promise<{ appointments: Appointment[]; lastDoc: DocumentSnapshot | null }> {
|
|
527
490
|
try {
|
|
528
491
|
const constraints: QueryConstraint[] = [];
|
|
529
492
|
|
|
530
493
|
// Add filters based on provided params
|
|
531
494
|
if (params.patientId) {
|
|
532
|
-
constraints.push(where(
|
|
495
|
+
constraints.push(where('patientId', '==', params.patientId));
|
|
533
496
|
}
|
|
534
497
|
|
|
535
498
|
if (params.practitionerId) {
|
|
536
|
-
constraints.push(where(
|
|
499
|
+
constraints.push(where('practitionerId', '==', params.practitionerId));
|
|
537
500
|
}
|
|
538
501
|
|
|
539
502
|
if (params.clinicBranchId) {
|
|
540
|
-
constraints.push(where(
|
|
503
|
+
constraints.push(where('clinicBranchId', '==', params.clinicBranchId));
|
|
541
504
|
}
|
|
542
505
|
|
|
543
506
|
if (params.startDate) {
|
|
544
|
-
constraints.push(
|
|
545
|
-
where(
|
|
546
|
-
"appointmentStartTime",
|
|
547
|
-
">=",
|
|
548
|
-
Timestamp.fromDate(params.startDate)
|
|
549
|
-
)
|
|
550
|
-
);
|
|
507
|
+
constraints.push(where('appointmentStartTime', '>=', Timestamp.fromDate(params.startDate)));
|
|
551
508
|
}
|
|
552
509
|
|
|
553
510
|
if (params.endDate) {
|
|
554
|
-
constraints.push(
|
|
555
|
-
where("appointmentStartTime", "<=", Timestamp.fromDate(params.endDate))
|
|
556
|
-
);
|
|
511
|
+
constraints.push(where('appointmentStartTime', '<=', Timestamp.fromDate(params.endDate)));
|
|
557
512
|
}
|
|
558
513
|
|
|
559
514
|
if (params.status) {
|
|
560
515
|
if (Array.isArray(params.status)) {
|
|
561
516
|
// If multiple statuses, use in operator
|
|
562
|
-
constraints.push(where(
|
|
517
|
+
constraints.push(where('status', 'in', params.status));
|
|
563
518
|
} else {
|
|
564
519
|
// Single status
|
|
565
|
-
constraints.push(where(
|
|
520
|
+
constraints.push(where('status', '==', params.status));
|
|
566
521
|
}
|
|
567
522
|
}
|
|
568
523
|
|
|
569
524
|
// Add ordering
|
|
570
|
-
constraints.push(orderBy(
|
|
525
|
+
constraints.push(orderBy('appointmentStartTime', 'asc'));
|
|
571
526
|
|
|
572
527
|
// Add pagination if specified
|
|
573
528
|
if (params.limit) {
|
|
@@ -583,19 +538,15 @@ export async function searchAppointmentsUtil(
|
|
|
583
538
|
const querySnapshot = await getDocs(q);
|
|
584
539
|
|
|
585
540
|
// Extract results
|
|
586
|
-
const appointments = querySnapshot.docs.map(
|
|
587
|
-
(doc) => doc.data() as Appointment
|
|
588
|
-
);
|
|
541
|
+
const appointments = querySnapshot.docs.map(doc => doc.data() as Appointment);
|
|
589
542
|
|
|
590
543
|
// Get last document for pagination
|
|
591
544
|
const lastDoc =
|
|
592
|
-
querySnapshot.docs.length > 0
|
|
593
|
-
? querySnapshot.docs[querySnapshot.docs.length - 1]
|
|
594
|
-
: null;
|
|
545
|
+
querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
595
546
|
|
|
596
547
|
return { appointments, lastDoc };
|
|
597
548
|
} catch (error) {
|
|
598
|
-
console.error(
|
|
549
|
+
console.error('Error searching appointments:', error);
|
|
599
550
|
throw error;
|
|
600
551
|
}
|
|
601
552
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '../../../types/appointment';
|
|
8
8
|
import { getAppointmentOrThrow, initializeMetadata } from './zone-management.utils';
|
|
9
9
|
import { PROCEDURES_COLLECTION } from '../../../types/procedure';
|
|
10
|
+
import { initializeFormsForExtendedProcedure, removeFormsForExtendedProcedure } from './form-initialization.utils';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Aggregates products from a procedure into appointmentProducts
|
|
@@ -134,6 +135,16 @@ export async function addExtendedProcedureUtil(
|
|
|
134
135
|
// Create extended procedure info
|
|
135
136
|
const extendedProcedureInfo = await createExtendedProcedureInfo(db, procedureId);
|
|
136
137
|
|
|
138
|
+
// Get procedure data for forms and products
|
|
139
|
+
const procedureRef = doc(db, PROCEDURES_COLLECTION, procedureId);
|
|
140
|
+
const procedureSnap = await getDoc(procedureRef);
|
|
141
|
+
|
|
142
|
+
if (!procedureSnap.exists()) {
|
|
143
|
+
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const procedureData = procedureSnap.data();
|
|
147
|
+
|
|
137
148
|
// Aggregate products
|
|
138
149
|
const updatedProducts = await aggregateProductsFromProcedure(
|
|
139
150
|
db,
|
|
@@ -141,6 +152,28 @@ export async function addExtendedProcedureUtil(
|
|
|
141
152
|
metadata.appointmentProducts || []
|
|
142
153
|
);
|
|
143
154
|
|
|
155
|
+
// Initialize forms for extended procedure
|
|
156
|
+
let updatedLinkedFormIds = appointment.linkedFormIds || [];
|
|
157
|
+
let updatedLinkedForms = appointment.linkedForms || [];
|
|
158
|
+
let updatedPendingUserFormsIds = appointment.pendingUserFormsIds || [];
|
|
159
|
+
|
|
160
|
+
if (procedureData.documentationTemplates && procedureData.documentationTemplates.length > 0) {
|
|
161
|
+
const formInitResult = await initializeFormsForExtendedProcedure(
|
|
162
|
+
db,
|
|
163
|
+
appointmentId,
|
|
164
|
+
procedureId,
|
|
165
|
+
procedureData.documentationTemplates,
|
|
166
|
+
appointment.patientId,
|
|
167
|
+
appointment.practitionerId,
|
|
168
|
+
appointment.clinicBranchId
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// Merge form IDs and info
|
|
172
|
+
updatedLinkedFormIds = [...updatedLinkedFormIds, ...formInitResult.allLinkedFormIds];
|
|
173
|
+
updatedLinkedForms = [...updatedLinkedForms, ...formInitResult.initializedFormsInfo];
|
|
174
|
+
updatedPendingUserFormsIds = [...updatedPendingUserFormsIds, ...formInitResult.pendingUserFormsIds];
|
|
175
|
+
}
|
|
176
|
+
|
|
144
177
|
// Add extended procedure
|
|
145
178
|
const extendedProcedures = [...(metadata.extendedProcedures || []), extendedProcedureInfo];
|
|
146
179
|
|
|
@@ -149,6 +182,9 @@ export async function addExtendedProcedureUtil(
|
|
|
149
182
|
await updateDoc(appointmentRef, {
|
|
150
183
|
'metadata.extendedProcedures': extendedProcedures,
|
|
151
184
|
'metadata.appointmentProducts': updatedProducts,
|
|
185
|
+
linkedFormIds: updatedLinkedFormIds,
|
|
186
|
+
linkedForms: updatedLinkedForms,
|
|
187
|
+
pendingUserFormsIds: updatedPendingUserFormsIds,
|
|
152
188
|
updatedAt: serverTimestamp(),
|
|
153
189
|
});
|
|
154
190
|
|
|
@@ -191,11 +227,28 @@ export async function removeExtendedProcedureUtil(
|
|
|
191
227
|
p => p.procedureId !== procedureId
|
|
192
228
|
);
|
|
193
229
|
|
|
230
|
+
// Remove forms associated with this procedure
|
|
231
|
+
const removedFormIds = await removeFormsForExtendedProcedure(db, appointmentId, procedureId);
|
|
232
|
+
|
|
233
|
+
// Update appointment form arrays
|
|
234
|
+
const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter(
|
|
235
|
+
formId => !removedFormIds.includes(formId)
|
|
236
|
+
);
|
|
237
|
+
const updatedLinkedForms = (appointment.linkedForms || []).filter(
|
|
238
|
+
form => !removedFormIds.includes(form.formId)
|
|
239
|
+
);
|
|
240
|
+
const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter(
|
|
241
|
+
formId => !removedFormIds.includes(formId)
|
|
242
|
+
);
|
|
243
|
+
|
|
194
244
|
// Update appointment
|
|
195
245
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
196
246
|
await updateDoc(appointmentRef, {
|
|
197
247
|
'metadata.extendedProcedures': metadata.extendedProcedures,
|
|
198
248
|
'metadata.appointmentProducts': updatedProducts,
|
|
249
|
+
linkedFormIds: updatedLinkedFormIds,
|
|
250
|
+
linkedForms: updatedLinkedForms,
|
|
251
|
+
pendingUserFormsIds: updatedPendingUserFormsIds,
|
|
199
252
|
updatedAt: serverTimestamp(),
|
|
200
253
|
});
|
|
201
254
|
|