@blackcode_sa/metaestetics-api 1.12.34 → 1.12.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1370,44 +1370,30 @@ async function updateAppointmentUtil(db, appointmentId, data) {
1370
1370
  let completedPreRequirements = currentAppointment.completedPreRequirements || [];
1371
1371
  let completedPostRequirements = currentAppointment.completedPostRequirements || [];
1372
1372
  if (data.completedPreRequirements) {
1373
- const validPreReqIds = currentAppointment.preProcedureRequirements.map(
1374
- (req) => req.id
1375
- );
1373
+ const validPreReqIds = currentAppointment.preProcedureRequirements.map((req) => req.id);
1376
1374
  if (Array.isArray(data.completedPreRequirements)) {
1377
1375
  const invalidPreReqIds = data.completedPreRequirements.filter(
1378
1376
  (id) => !validPreReqIds.includes(id)
1379
1377
  );
1380
1378
  if (invalidPreReqIds.length > 0) {
1381
- throw new Error(
1382
- `Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
1383
- );
1379
+ throw new Error(`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`);
1384
1380
  }
1385
1381
  completedPreRequirements = [
1386
- .../* @__PURE__ */ new Set([
1387
- ...completedPreRequirements,
1388
- ...data.completedPreRequirements
1389
- ])
1382
+ .../* @__PURE__ */ new Set([...completedPreRequirements, ...data.completedPreRequirements])
1390
1383
  ];
1391
1384
  }
1392
1385
  }
1393
1386
  if (data.completedPostRequirements) {
1394
- const validPostReqIds = currentAppointment.postProcedureRequirements.map(
1395
- (req) => req.id
1396
- );
1387
+ const validPostReqIds = currentAppointment.postProcedureRequirements.map((req) => req.id);
1397
1388
  if (Array.isArray(data.completedPostRequirements)) {
1398
1389
  const invalidPostReqIds = data.completedPostRequirements.filter(
1399
1390
  (id) => !validPostReqIds.includes(id)
1400
1391
  );
1401
1392
  if (invalidPostReqIds.length > 0) {
1402
- throw new Error(
1403
- `Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
1404
- );
1393
+ throw new Error(`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`);
1405
1394
  }
1406
1395
  completedPostRequirements = [
1407
- .../* @__PURE__ */ new Set([
1408
- ...completedPostRequirements,
1409
- ...data.completedPostRequirements
1410
- ])
1396
+ .../* @__PURE__ */ new Set([...completedPostRequirements, ...data.completedPostRequirements])
1411
1397
  ];
1412
1398
  }
1413
1399
  }
@@ -1427,19 +1413,13 @@ async function updateAppointmentUtil(db, appointmentId, data) {
1427
1413
  updateData.confirmationTime = import_firestore3.Timestamp.now();
1428
1414
  }
1429
1415
  if (currentAppointment.calendarEventId) {
1430
- await updateCalendarEventStatus(
1431
- db,
1432
- currentAppointment.calendarEventId,
1433
- data.status
1434
- );
1416
+ await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
1435
1417
  }
1436
1418
  }
1437
1419
  await (0, import_firestore3.updateDoc)(appointmentRef, updateData);
1438
1420
  const updatedAppointmentDoc = await (0, import_firestore3.getDoc)(appointmentRef);
1439
1421
  if (!updatedAppointmentDoc.exists()) {
1440
- throw new Error(
1441
- `Failed to retrieve updated appointment ${appointmentId}`
1442
- );
1422
+ throw new Error(`Failed to retrieve updated appointment ${appointmentId}`);
1443
1423
  }
1444
1424
  return updatedAppointmentDoc.data();
1445
1425
  } catch (error) {
@@ -1483,9 +1463,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
1483
1463
  }
1484
1464
  async function getAppointmentByIdUtil(db, appointmentId) {
1485
1465
  try {
1486
- const appointmentDoc = await (0, import_firestore3.getDoc)(
1487
- (0, import_firestore3.doc)(db, APPOINTMENTS_COLLECTION, appointmentId)
1488
- );
1466
+ const appointmentDoc = await (0, import_firestore3.getDoc)((0, import_firestore3.doc)(db, APPOINTMENTS_COLLECTION, appointmentId));
1489
1467
  if (!appointmentDoc.exists()) {
1490
1468
  return null;
1491
1469
  }
@@ -1508,18 +1486,10 @@ async function searchAppointmentsUtil(db, params) {
1508
1486
  constraints.push((0, import_firestore3.where)("clinicBranchId", "==", params.clinicBranchId));
1509
1487
  }
1510
1488
  if (params.startDate) {
1511
- constraints.push(
1512
- (0, import_firestore3.where)(
1513
- "appointmentStartTime",
1514
- ">=",
1515
- import_firestore3.Timestamp.fromDate(params.startDate)
1516
- )
1517
- );
1489
+ constraints.push((0, import_firestore3.where)("appointmentStartTime", ">=", import_firestore3.Timestamp.fromDate(params.startDate)));
1518
1490
  }
1519
1491
  if (params.endDate) {
1520
- constraints.push(
1521
- (0, import_firestore3.where)("appointmentStartTime", "<=", import_firestore3.Timestamp.fromDate(params.endDate))
1522
- );
1492
+ constraints.push((0, import_firestore3.where)("appointmentStartTime", "<=", import_firestore3.Timestamp.fromDate(params.endDate)));
1523
1493
  }
1524
1494
  if (params.status) {
1525
1495
  if (Array.isArray(params.status)) {
@@ -1537,9 +1507,7 @@ async function searchAppointmentsUtil(db, params) {
1537
1507
  }
1538
1508
  const q = (0, import_firestore3.query)((0, import_firestore3.collection)(db, APPOINTMENTS_COLLECTION), ...constraints);
1539
1509
  const querySnapshot = await (0, import_firestore3.getDocs)(q);
1540
- const appointments = querySnapshot.docs.map(
1541
- (doc42) => doc42.data()
1542
- );
1510
+ const appointments = querySnapshot.docs.map((doc42) => doc42.data());
1543
1511
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
1544
1512
  return { appointments, lastDoc };
1545
1513
  } catch (error) {
@@ -2867,7 +2835,10 @@ var AppointmentService = class extends BaseService {
2867
2835
  zonesData: currentMetadata.zonesData || null,
2868
2836
  appointmentProducts: currentMetadata.appointmentProducts || [],
2869
2837
  extendedProcedures: currentMetadata.extendedProcedures || [],
2870
- zoneBilling: currentMetadata.zoneBilling,
2838
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
2839
+ ...currentMetadata.zoneBilling !== void 0 && {
2840
+ zoneBilling: currentMetadata.zoneBilling
2841
+ },
2871
2842
  finalbilling: currentMetadata.finalbilling,
2872
2843
  finalizationNotes: currentMetadata.finalizationNotes
2873
2844
  },
@@ -2972,7 +2943,10 @@ var AppointmentService = class extends BaseService {
2972
2943
  zonesData: ((_c = appointment.metadata) == null ? void 0 : _c.zonesData) || null,
2973
2944
  appointmentProducts: ((_d = appointment.metadata) == null ? void 0 : _d.appointmentProducts) || [],
2974
2945
  extendedProcedures: ((_e = appointment.metadata) == null ? void 0 : _e.extendedProcedures) || [],
2975
- zoneBilling: ((_f = appointment.metadata) == null ? void 0 : _f.zoneBilling) || null,
2946
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
2947
+ ...((_f = appointment.metadata) == null ? void 0 : _f.zoneBilling) !== void 0 && {
2948
+ zoneBilling: appointment.metadata.zoneBilling
2949
+ },
2976
2950
  finalbilling: ((_g = appointment.metadata) == null ? void 0 : _g.finalbilling) || null,
2977
2951
  finalizationNotes: ((_h = appointment.metadata) == null ? void 0 : _h.finalizationNotes) || null
2978
2952
  },
@@ -3060,7 +3034,13 @@ var AppointmentService = class extends BaseService {
3060
3034
  console.log(
3061
3035
  `[APPOINTMENT_SERVICE] Overriding price for item ${itemIndex} in zone ${zoneId} to ${newPrice}`
3062
3036
  );
3063
- return await overridePriceForZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, newPrice);
3037
+ return await overridePriceForZoneItemUtil(
3038
+ this.db,
3039
+ appointmentId,
3040
+ zoneId,
3041
+ itemIndex,
3042
+ newPrice
3043
+ );
3064
3044
  } catch (error) {
3065
3045
  console.error(`[APPOINTMENT_SERVICE] Error overriding price:`, error);
3066
3046
  throw error;
@@ -3132,7 +3112,9 @@ var AppointmentService = class extends BaseService {
3132
3112
  */
3133
3113
  async getExtendedProcedures(appointmentId) {
3134
3114
  try {
3135
- console.log(`[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`);
3115
+ console.log(
3116
+ `[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`
3117
+ );
3136
3118
  return await getExtendedProceduresUtil(this.db, appointmentId);
3137
3119
  } catch (error) {
3138
3120
  console.error(`[APPOINTMENT_SERVICE] Error getting extended procedures:`, error);
@@ -3148,7 +3130,9 @@ var AppointmentService = class extends BaseService {
3148
3130
  */
3149
3131
  async getAppointmentProducts(appointmentId) {
3150
3132
  try {
3151
- console.log(`[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`);
3133
+ console.log(
3134
+ `[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`
3135
+ );
3152
3136
  return await getAppointmentProductsUtil(this.db, appointmentId);
3153
3137
  } catch (error) {
3154
3138
  console.error(`[APPOINTMENT_SERVICE] Error getting appointment products:`, error);
@@ -3165,7 +3149,9 @@ var AppointmentService = class extends BaseService {
3165
3149
  async recalculateFinalBilling(appointmentId, taxRate) {
3166
3150
  var _a;
3167
3151
  try {
3168
- console.log(`[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`);
3152
+ console.log(
3153
+ `[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`
3154
+ );
3169
3155
  const appointment = await this.getAppointmentById(appointmentId);
3170
3156
  if (!appointment) {
3171
3157
  throw new Error(`Appointment with ID ${appointmentId} not found`);
@@ -3191,6 +3177,10 @@ var AppointmentService = class extends BaseService {
3191
3177
  zonesData: currentMetadata.zonesData,
3192
3178
  appointmentProducts: currentMetadata.appointmentProducts || [],
3193
3179
  extendedProcedures: currentMetadata.extendedProcedures || [],
3180
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
3181
+ ...currentMetadata.zoneBilling !== void 0 && {
3182
+ zoneBilling: currentMetadata.zoneBilling
3183
+ },
3194
3184
  finalbilling,
3195
3185
  finalizationNotes: currentMetadata.finalizationNotes
3196
3186
  },
package/dist/index.mjs CHANGED
@@ -1269,44 +1269,30 @@ async function updateAppointmentUtil(db, appointmentId, data) {
1269
1269
  let completedPreRequirements = currentAppointment.completedPreRequirements || [];
1270
1270
  let completedPostRequirements = currentAppointment.completedPostRequirements || [];
1271
1271
  if (data.completedPreRequirements) {
1272
- const validPreReqIds = currentAppointment.preProcedureRequirements.map(
1273
- (req) => req.id
1274
- );
1272
+ const validPreReqIds = currentAppointment.preProcedureRequirements.map((req) => req.id);
1275
1273
  if (Array.isArray(data.completedPreRequirements)) {
1276
1274
  const invalidPreReqIds = data.completedPreRequirements.filter(
1277
1275
  (id) => !validPreReqIds.includes(id)
1278
1276
  );
1279
1277
  if (invalidPreReqIds.length > 0) {
1280
- throw new Error(
1281
- `Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
1282
- );
1278
+ throw new Error(`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`);
1283
1279
  }
1284
1280
  completedPreRequirements = [
1285
- .../* @__PURE__ */ new Set([
1286
- ...completedPreRequirements,
1287
- ...data.completedPreRequirements
1288
- ])
1281
+ .../* @__PURE__ */ new Set([...completedPreRequirements, ...data.completedPreRequirements])
1289
1282
  ];
1290
1283
  }
1291
1284
  }
1292
1285
  if (data.completedPostRequirements) {
1293
- const validPostReqIds = currentAppointment.postProcedureRequirements.map(
1294
- (req) => req.id
1295
- );
1286
+ const validPostReqIds = currentAppointment.postProcedureRequirements.map((req) => req.id);
1296
1287
  if (Array.isArray(data.completedPostRequirements)) {
1297
1288
  const invalidPostReqIds = data.completedPostRequirements.filter(
1298
1289
  (id) => !validPostReqIds.includes(id)
1299
1290
  );
1300
1291
  if (invalidPostReqIds.length > 0) {
1301
- throw new Error(
1302
- `Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
1303
- );
1292
+ throw new Error(`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`);
1304
1293
  }
1305
1294
  completedPostRequirements = [
1306
- .../* @__PURE__ */ new Set([
1307
- ...completedPostRequirements,
1308
- ...data.completedPostRequirements
1309
- ])
1295
+ .../* @__PURE__ */ new Set([...completedPostRequirements, ...data.completedPostRequirements])
1310
1296
  ];
1311
1297
  }
1312
1298
  }
@@ -1326,19 +1312,13 @@ async function updateAppointmentUtil(db, appointmentId, data) {
1326
1312
  updateData.confirmationTime = Timestamp2.now();
1327
1313
  }
1328
1314
  if (currentAppointment.calendarEventId) {
1329
- await updateCalendarEventStatus(
1330
- db,
1331
- currentAppointment.calendarEventId,
1332
- data.status
1333
- );
1315
+ await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
1334
1316
  }
1335
1317
  }
1336
1318
  await updateDoc2(appointmentRef, updateData);
1337
1319
  const updatedAppointmentDoc = await getDoc2(appointmentRef);
1338
1320
  if (!updatedAppointmentDoc.exists()) {
1339
- throw new Error(
1340
- `Failed to retrieve updated appointment ${appointmentId}`
1341
- );
1321
+ throw new Error(`Failed to retrieve updated appointment ${appointmentId}`);
1342
1322
  }
1343
1323
  return updatedAppointmentDoc.data();
1344
1324
  } catch (error) {
@@ -1382,9 +1362,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
1382
1362
  }
1383
1363
  async function getAppointmentByIdUtil(db, appointmentId) {
1384
1364
  try {
1385
- const appointmentDoc = await getDoc2(
1386
- doc2(db, APPOINTMENTS_COLLECTION, appointmentId)
1387
- );
1365
+ const appointmentDoc = await getDoc2(doc2(db, APPOINTMENTS_COLLECTION, appointmentId));
1388
1366
  if (!appointmentDoc.exists()) {
1389
1367
  return null;
1390
1368
  }
@@ -1407,18 +1385,10 @@ async function searchAppointmentsUtil(db, params) {
1407
1385
  constraints.push(where2("clinicBranchId", "==", params.clinicBranchId));
1408
1386
  }
1409
1387
  if (params.startDate) {
1410
- constraints.push(
1411
- where2(
1412
- "appointmentStartTime",
1413
- ">=",
1414
- Timestamp2.fromDate(params.startDate)
1415
- )
1416
- );
1388
+ constraints.push(where2("appointmentStartTime", ">=", Timestamp2.fromDate(params.startDate)));
1417
1389
  }
1418
1390
  if (params.endDate) {
1419
- constraints.push(
1420
- where2("appointmentStartTime", "<=", Timestamp2.fromDate(params.endDate))
1421
- );
1391
+ constraints.push(where2("appointmentStartTime", "<=", Timestamp2.fromDate(params.endDate)));
1422
1392
  }
1423
1393
  if (params.status) {
1424
1394
  if (Array.isArray(params.status)) {
@@ -1436,9 +1406,7 @@ async function searchAppointmentsUtil(db, params) {
1436
1406
  }
1437
1407
  const q = query2(collection2(db, APPOINTMENTS_COLLECTION), ...constraints);
1438
1408
  const querySnapshot = await getDocs2(q);
1439
- const appointments = querySnapshot.docs.map(
1440
- (doc42) => doc42.data()
1441
- );
1409
+ const appointments = querySnapshot.docs.map((doc42) => doc42.data());
1442
1410
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
1443
1411
  return { appointments, lastDoc };
1444
1412
  } catch (error) {
@@ -2766,7 +2734,10 @@ var AppointmentService = class extends BaseService {
2766
2734
  zonesData: currentMetadata.zonesData || null,
2767
2735
  appointmentProducts: currentMetadata.appointmentProducts || [],
2768
2736
  extendedProcedures: currentMetadata.extendedProcedures || [],
2769
- zoneBilling: currentMetadata.zoneBilling,
2737
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
2738
+ ...currentMetadata.zoneBilling !== void 0 && {
2739
+ zoneBilling: currentMetadata.zoneBilling
2740
+ },
2770
2741
  finalbilling: currentMetadata.finalbilling,
2771
2742
  finalizationNotes: currentMetadata.finalizationNotes
2772
2743
  },
@@ -2871,7 +2842,10 @@ var AppointmentService = class extends BaseService {
2871
2842
  zonesData: ((_c = appointment.metadata) == null ? void 0 : _c.zonesData) || null,
2872
2843
  appointmentProducts: ((_d = appointment.metadata) == null ? void 0 : _d.appointmentProducts) || [],
2873
2844
  extendedProcedures: ((_e = appointment.metadata) == null ? void 0 : _e.extendedProcedures) || [],
2874
- zoneBilling: ((_f = appointment.metadata) == null ? void 0 : _f.zoneBilling) || null,
2845
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
2846
+ ...((_f = appointment.metadata) == null ? void 0 : _f.zoneBilling) !== void 0 && {
2847
+ zoneBilling: appointment.metadata.zoneBilling
2848
+ },
2875
2849
  finalbilling: ((_g = appointment.metadata) == null ? void 0 : _g.finalbilling) || null,
2876
2850
  finalizationNotes: ((_h = appointment.metadata) == null ? void 0 : _h.finalizationNotes) || null
2877
2851
  },
@@ -2959,7 +2933,13 @@ var AppointmentService = class extends BaseService {
2959
2933
  console.log(
2960
2934
  `[APPOINTMENT_SERVICE] Overriding price for item ${itemIndex} in zone ${zoneId} to ${newPrice}`
2961
2935
  );
2962
- return await overridePriceForZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, newPrice);
2936
+ return await overridePriceForZoneItemUtil(
2937
+ this.db,
2938
+ appointmentId,
2939
+ zoneId,
2940
+ itemIndex,
2941
+ newPrice
2942
+ );
2963
2943
  } catch (error) {
2964
2944
  console.error(`[APPOINTMENT_SERVICE] Error overriding price:`, error);
2965
2945
  throw error;
@@ -3031,7 +3011,9 @@ var AppointmentService = class extends BaseService {
3031
3011
  */
3032
3012
  async getExtendedProcedures(appointmentId) {
3033
3013
  try {
3034
- console.log(`[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`);
3014
+ console.log(
3015
+ `[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`
3016
+ );
3035
3017
  return await getExtendedProceduresUtil(this.db, appointmentId);
3036
3018
  } catch (error) {
3037
3019
  console.error(`[APPOINTMENT_SERVICE] Error getting extended procedures:`, error);
@@ -3047,7 +3029,9 @@ var AppointmentService = class extends BaseService {
3047
3029
  */
3048
3030
  async getAppointmentProducts(appointmentId) {
3049
3031
  try {
3050
- console.log(`[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`);
3032
+ console.log(
3033
+ `[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`
3034
+ );
3051
3035
  return await getAppointmentProductsUtil(this.db, appointmentId);
3052
3036
  } catch (error) {
3053
3037
  console.error(`[APPOINTMENT_SERVICE] Error getting appointment products:`, error);
@@ -3064,7 +3048,9 @@ var AppointmentService = class extends BaseService {
3064
3048
  async recalculateFinalBilling(appointmentId, taxRate) {
3065
3049
  var _a;
3066
3050
  try {
3067
- console.log(`[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`);
3051
+ console.log(
3052
+ `[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`
3053
+ );
3068
3054
  const appointment = await this.getAppointmentById(appointmentId);
3069
3055
  if (!appointment) {
3070
3056
  throw new Error(`Appointment with ID ${appointmentId} not found`);
@@ -3090,6 +3076,10 @@ var AppointmentService = class extends BaseService {
3090
3076
  zonesData: currentMetadata.zonesData,
3091
3077
  appointmentProducts: currentMetadata.appointmentProducts || [],
3092
3078
  extendedProcedures: currentMetadata.extendedProcedures || [],
3079
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
3080
+ ...currentMetadata.zoneBilling !== void 0 && {
3081
+ zoneBilling: currentMetadata.zoneBilling
3082
+ },
3093
3083
  finalbilling,
3094
3084
  finalizationNotes: currentMetadata.finalizationNotes
3095
3085
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.12.34",
4
+ "version": "1.12.36",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -1313,7 +1313,10 @@ export class AppointmentService extends BaseService {
1313
1313
  zonesData: currentMetadata.zonesData || null,
1314
1314
  appointmentProducts: currentMetadata.appointmentProducts || [],
1315
1315
  extendedProcedures: currentMetadata.extendedProcedures || [],
1316
- zoneBilling: currentMetadata.zoneBilling,
1316
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
1317
+ ...(currentMetadata.zoneBilling !== undefined && {
1318
+ zoneBilling: currentMetadata.zoneBilling,
1319
+ }),
1317
1320
  finalbilling: currentMetadata.finalbilling,
1318
1321
  finalizationNotes: currentMetadata.finalizationNotes,
1319
1322
  },
@@ -1448,7 +1451,10 @@ export class AppointmentService extends BaseService {
1448
1451
  zonesData: appointment.metadata?.zonesData || null,
1449
1452
  appointmentProducts: appointment.metadata?.appointmentProducts || [],
1450
1453
  extendedProcedures: appointment.metadata?.extendedProcedures || [],
1451
- zoneBilling: appointment.metadata?.zoneBilling || null,
1454
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
1455
+ ...(appointment.metadata?.zoneBilling !== undefined && {
1456
+ zoneBilling: appointment.metadata.zoneBilling,
1457
+ }),
1452
1458
  finalbilling: appointment.metadata?.finalbilling || null,
1453
1459
  finalizationNotes: appointment.metadata?.finalizationNotes || null,
1454
1460
  },
@@ -1479,7 +1485,7 @@ export class AppointmentService extends BaseService {
1479
1485
  async addItemToZone(
1480
1486
  appointmentId: string,
1481
1487
  zoneId: string,
1482
- item: Omit<ZoneItemData, 'subtotal' | 'parentZone'>
1488
+ item: Omit<ZoneItemData, 'subtotal' | 'parentZone'>,
1483
1489
  ): Promise<Appointment> {
1484
1490
  try {
1485
1491
  console.log(
@@ -1561,7 +1567,13 @@ export class AppointmentService extends BaseService {
1561
1567
  console.log(
1562
1568
  `[APPOINTMENT_SERVICE] Overriding price for item ${itemIndex} in zone ${zoneId} to ${newPrice}`,
1563
1569
  );
1564
- return await overridePriceForZoneItemUtil(this.db, appointmentId, zoneId, itemIndex, newPrice);
1570
+ return await overridePriceForZoneItemUtil(
1571
+ this.db,
1572
+ appointmentId,
1573
+ zoneId,
1574
+ itemIndex,
1575
+ newPrice,
1576
+ );
1565
1577
  } catch (error) {
1566
1578
  console.error(`[APPOINTMENT_SERVICE] Error overriding price:`, error);
1567
1579
  throw error;
@@ -1642,7 +1654,9 @@ export class AppointmentService extends BaseService {
1642
1654
  */
1643
1655
  async getExtendedProcedures(appointmentId: string): Promise<ExtendedProcedureInfo[]> {
1644
1656
  try {
1645
- console.log(`[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`);
1657
+ console.log(
1658
+ `[APPOINTMENT_SERVICE] Getting extended procedures for appointment ${appointmentId}`,
1659
+ );
1646
1660
  return await getExtendedProceduresUtil(this.db, appointmentId);
1647
1661
  } catch (error) {
1648
1662
  console.error(`[APPOINTMENT_SERVICE] Error getting extended procedures:`, error);
@@ -1659,7 +1673,9 @@ export class AppointmentService extends BaseService {
1659
1673
  */
1660
1674
  async getAppointmentProducts(appointmentId: string): Promise<AppointmentProductMetadata[]> {
1661
1675
  try {
1662
- console.log(`[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`);
1676
+ console.log(
1677
+ `[APPOINTMENT_SERVICE] Getting appointment products for appointment ${appointmentId}`,
1678
+ );
1663
1679
  return await getAppointmentProductsUtil(this.db, appointmentId);
1664
1680
  } catch (error) {
1665
1681
  console.error(`[APPOINTMENT_SERVICE] Error getting appointment products:`, error);
@@ -1676,8 +1692,10 @@ export class AppointmentService extends BaseService {
1676
1692
  */
1677
1693
  async recalculateFinalBilling(appointmentId: string, taxRate?: number): Promise<Appointment> {
1678
1694
  try {
1679
- console.log(`[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`);
1680
-
1695
+ console.log(
1696
+ `[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`,
1697
+ );
1698
+
1681
1699
  const appointment = await this.getAppointmentById(appointmentId);
1682
1700
  if (!appointment) {
1683
1701
  throw new Error(`Appointment with ID ${appointmentId} not found`);
@@ -1707,6 +1725,10 @@ export class AppointmentService extends BaseService {
1707
1725
  zonesData: currentMetadata.zonesData,
1708
1726
  appointmentProducts: currentMetadata.appointmentProducts || [],
1709
1727
  extendedProcedures: currentMetadata.extendedProcedures || [],
1728
+ // Only include zoneBilling if it exists (avoid undefined values in Firestore)
1729
+ ...(currentMetadata.zoneBilling !== undefined && {
1730
+ zoneBilling: currentMetadata.zoneBilling,
1731
+ }),
1710
1732
  finalbilling,
1711
1733
  finalizationNotes: currentMetadata.finalizationNotes,
1712
1734
  },
@@ -15,7 +15,7 @@ import {
15
15
  startAfter,
16
16
  QueryConstraint,
17
17
  DocumentSnapshot,
18
- } from "firebase/firestore";
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 "../../../types/appointment";
28
- import { CalendarEvent, CALENDAR_COLLECTION } from "../../../types/calendar";
29
- import { ProcedureSummaryInfo } from "../../../types/procedure";
30
- import {
31
- ClinicInfo,
32
- PatientProfileInfo,
33
- PractitionerProfileInfo,
34
- } from "../../../types/profile";
35
- import { BlockingCondition } from "../../../backoffice/types/static/blocking-condition.types";
36
- import { Requirement } from "../../../backoffice/types/requirement.types";
37
- import { PRACTITIONERS_COLLECTION } from "../../../types/practitioner";
38
- import { CLINICS_COLLECTION } from "../../../types/clinic";
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
- await Promise.all([
77
- getDoc(doc(db, CLINICS_COLLECTION, clinicId)),
78
- getDoc(doc(db, PRACTITIONERS_COLLECTION, practitionerId)),
79
- getDoc(doc(db, PATIENTS_COLLECTION, patientId)),
80
- getDoc(doc(db, PROCEDURES_COLLECTION, procedureId)),
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 || "other",
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("Error fetching aggregated info:", 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
- currentAppointment.completedPreRequirements || [];
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
- (id) => !validPreReqIds.includes(id)
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
- (id) => !validPostReqIds.includes(id)
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((key) => {
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 = "confirmed";
427
+ calendarStatus = 'confirmed';
463
428
  break;
464
429
  case AppointmentStatus.CANCELED_PATIENT:
465
430
  case AppointmentStatus.CANCELED_CLINIC:
466
- calendarStatus = "canceled";
431
+ calendarStatus = 'canceled';
467
432
  break;
468
433
  case AppointmentStatus.RESCHEDULED_BY_CLINIC:
469
- calendarStatus = "rescheduled";
434
+ calendarStatus = 'rescheduled';
470
435
  break;
471
436
  case AppointmentStatus.COMPLETED:
472
- calendarStatus = "completed";
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("patientId", "==", params.patientId));
495
+ constraints.push(where('patientId', '==', params.patientId));
533
496
  }
534
497
 
535
498
  if (params.practitionerId) {
536
- constraints.push(where("practitionerId", "==", params.practitionerId));
499
+ constraints.push(where('practitionerId', '==', params.practitionerId));
537
500
  }
538
501
 
539
502
  if (params.clinicBranchId) {
540
- constraints.push(where("clinicBranchId", "==", params.clinicBranchId));
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("status", "in", params.status));
517
+ constraints.push(where('status', 'in', params.status));
563
518
  } else {
564
519
  // Single status
565
- constraints.push(where("status", "==", params.status));
520
+ constraints.push(where('status', '==', params.status));
566
521
  }
567
522
  }
568
523
 
569
524
  // Add ordering
570
- constraints.push(orderBy("appointmentStartTime", "asc"));
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("Error searching appointments:", error);
549
+ console.error('Error searching appointments:', error);
599
550
  throw error;
600
551
  }
601
552
  }