@blackcode_sa/metaestetics-api 1.14.52 → 1.14.54

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.
@@ -1714,6 +1714,7 @@ interface ZoneItemData {
1714
1714
  notesVisibleToPatient?: boolean;
1715
1715
  subtotal?: number;
1716
1716
  ionNumber?: string;
1717
+ expiryDate?: string;
1717
1718
  createdAt?: string;
1718
1719
  updatedAt?: string;
1719
1720
  }
@@ -1714,6 +1714,7 @@ interface ZoneItemData {
1714
1714
  notesVisibleToPatient?: boolean;
1715
1715
  subtotal?: number;
1716
1716
  ionNumber?: string;
1717
+ expiryDate?: string;
1717
1718
  createdAt?: string;
1718
1719
  updatedAt?: string;
1719
1720
  }
package/dist/index.d.mts CHANGED
@@ -5651,6 +5651,7 @@ interface ZoneItemData {
5651
5651
  notesVisibleToPatient?: boolean;
5652
5652
  subtotal?: number;
5653
5653
  ionNumber?: string;
5654
+ expiryDate?: string;
5654
5655
  createdAt?: string;
5655
5656
  updatedAt?: string;
5656
5657
  }
package/dist/index.d.ts CHANGED
@@ -5651,6 +5651,7 @@ interface ZoneItemData {
5651
5651
  notesVisibleToPatient?: boolean;
5652
5652
  subtotal?: number;
5653
5653
  ionNumber?: string;
5654
+ expiryDate?: string;
5654
5655
  createdAt?: string;
5655
5656
  updatedAt?: string;
5656
5657
  }
package/dist/index.js CHANGED
@@ -4843,7 +4843,6 @@ function initializeMetadata(appointment) {
4843
4843
  };
4844
4844
  }
4845
4845
  async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
4846
- var _a;
4847
4846
  validateZoneKeyFormat(zoneId);
4848
4847
  const appointment = await getAppointmentOrThrow(db, appointmentId);
4849
4848
  const metadata = initializeMetadata(appointment);
@@ -4852,15 +4851,19 @@ async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
4852
4851
  zonesData[zoneId] = [];
4853
4852
  }
4854
4853
  const now = (/* @__PURE__ */ new Date()).toISOString();
4854
+ const cleanItem = Object.fromEntries(
4855
+ Object.entries(item).filter(([_, value]) => value !== void 0)
4856
+ );
4857
+ const notesVisibleToPatientValue = cleanItem.notesVisibleToPatient !== void 0 ? cleanItem.notesVisibleToPatient : cleanItem.notes ? false : void 0;
4855
4858
  const itemWithSubtotal = {
4856
- ...item,
4859
+ ...cleanItem,
4857
4860
  parentZone: zoneId,
4858
4861
  // Set parentZone to the zone key
4859
- subtotal: calculateItemSubtotal(item),
4860
- // Set default visibility to false (privacy-first) if notes exist and visibility not explicitly set
4861
- notesVisibleToPatient: (_a = item.notesVisibleToPatient) != null ? _a : item.notes ? false : void 0,
4862
+ subtotal: calculateItemSubtotal(cleanItem),
4862
4863
  createdAt: now,
4863
- updatedAt: now
4864
+ updatedAt: now,
4865
+ // Only include notesVisibleToPatient if it has a defined boolean value
4866
+ ...typeof notesVisibleToPatientValue === "boolean" && { notesVisibleToPatient: notesVisibleToPatientValue }
4864
4867
  };
4865
4868
  zonesData[zoneId].push(itemWithSubtotal);
4866
4869
  const finalbilling = calculateFinalBilling(zonesData, 0.081);
@@ -5366,12 +5369,19 @@ async function addExtendedProcedureUtil(db, appointmentId, procedureId) {
5366
5369
  appointment.practitionerId,
5367
5370
  appointment.clinicBranchId
5368
5371
  );
5369
- updatedLinkedFormIds = [...updatedLinkedFormIds, ...formInitResult.allLinkedFormIds];
5370
- updatedLinkedForms = [...updatedLinkedForms, ...formInitResult.initializedFormsInfo];
5371
- updatedPendingUserFormsIds = [
5372
- ...updatedPendingUserFormsIds,
5373
- ...formInitResult.pendingUserFormsIds
5374
- ];
5372
+ const existingFormIds = new Set(updatedLinkedFormIds);
5373
+ const newFormIds = formInitResult.allLinkedFormIds.filter((id) => !existingFormIds.has(id));
5374
+ updatedLinkedFormIds = [...updatedLinkedFormIds, ...newFormIds];
5375
+ const existingFormIdsInLinkedForms = new Set(updatedLinkedForms.map((f) => f.formId));
5376
+ const newLinkedForms = formInitResult.initializedFormsInfo.filter(
5377
+ (form) => !existingFormIdsInLinkedForms.has(form.formId)
5378
+ );
5379
+ updatedLinkedForms = [...updatedLinkedForms, ...newLinkedForms];
5380
+ const existingPendingIds = new Set(updatedPendingUserFormsIds);
5381
+ const newPendingIds = formInitResult.pendingUserFormsIds.filter(
5382
+ (id) => !existingPendingIds.has(id)
5383
+ );
5384
+ updatedPendingUserFormsIds = [...updatedPendingUserFormsIds, ...newPendingIds];
5375
5385
  }
5376
5386
  const extendedProcedures = [...metadata.extendedProcedures || [], extendedProcedureInfo];
5377
5387
  const appointmentRef = (0, import_firestore10.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -5414,15 +5424,30 @@ async function removeExtendedProcedureUtil(db, appointmentId, procedureId) {
5414
5424
  `\u{1F5D1}\uFE0F [removeExtendedProcedure] Removed ${productsRemovedFromZones} products from zones for procedure ${procedureId}`
5415
5425
  );
5416
5426
  const removedFormIds = await removeFormsForExtendedProcedure(db, appointmentId, procedureId);
5417
- const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter(
5418
- (formId) => !removedFormIds.includes(formId)
5419
- );
5420
- const updatedLinkedForms = (appointment.linkedForms || []).filter(
5421
- (form) => !removedFormIds.includes(form.formId)
5422
- );
5423
- const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter(
5424
- (formId) => !removedFormIds.includes(formId)
5425
- );
5427
+ const removedFormIdsSet = new Set(removedFormIds);
5428
+ const linkedFormIdsSet = /* @__PURE__ */ new Set();
5429
+ const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter((formId) => {
5430
+ if (removedFormIdsSet.has(formId)) return false;
5431
+ if (linkedFormIdsSet.has(formId)) return false;
5432
+ linkedFormIdsSet.add(formId);
5433
+ return true;
5434
+ });
5435
+ const linkedFormsMap = /* @__PURE__ */ new Map();
5436
+ (appointment.linkedForms || []).forEach((form) => {
5437
+ if (!removedFormIdsSet.has(form.formId)) {
5438
+ if (!linkedFormsMap.has(form.formId)) {
5439
+ linkedFormsMap.set(form.formId, form);
5440
+ }
5441
+ }
5442
+ });
5443
+ const updatedLinkedForms = Array.from(linkedFormsMap.values());
5444
+ const pendingIdsSet = /* @__PURE__ */ new Set();
5445
+ const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter((formId) => {
5446
+ if (removedFormIdsSet.has(formId)) return false;
5447
+ if (pendingIdsSet.has(formId)) return false;
5448
+ pendingIdsSet.add(formId);
5449
+ return true;
5450
+ });
5426
5451
  const appointmentRef = (0, import_firestore10.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
5427
5452
  await (0, import_firestore10.updateDoc)(appointmentRef, {
5428
5453
  "metadata.extendedProcedures": metadata.extendedProcedures,
package/dist/index.mjs CHANGED
@@ -4729,7 +4729,6 @@ function initializeMetadata(appointment) {
4729
4729
  };
4730
4730
  }
4731
4731
  async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
4732
- var _a;
4733
4732
  validateZoneKeyFormat(zoneId);
4734
4733
  const appointment = await getAppointmentOrThrow(db, appointmentId);
4735
4734
  const metadata = initializeMetadata(appointment);
@@ -4738,15 +4737,19 @@ async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
4738
4737
  zonesData[zoneId] = [];
4739
4738
  }
4740
4739
  const now = (/* @__PURE__ */ new Date()).toISOString();
4740
+ const cleanItem = Object.fromEntries(
4741
+ Object.entries(item).filter(([_, value]) => value !== void 0)
4742
+ );
4743
+ const notesVisibleToPatientValue = cleanItem.notesVisibleToPatient !== void 0 ? cleanItem.notesVisibleToPatient : cleanItem.notes ? false : void 0;
4741
4744
  const itemWithSubtotal = {
4742
- ...item,
4745
+ ...cleanItem,
4743
4746
  parentZone: zoneId,
4744
4747
  // Set parentZone to the zone key
4745
- subtotal: calculateItemSubtotal(item),
4746
- // Set default visibility to false (privacy-first) if notes exist and visibility not explicitly set
4747
- notesVisibleToPatient: (_a = item.notesVisibleToPatient) != null ? _a : item.notes ? false : void 0,
4748
+ subtotal: calculateItemSubtotal(cleanItem),
4748
4749
  createdAt: now,
4749
- updatedAt: now
4750
+ updatedAt: now,
4751
+ // Only include notesVisibleToPatient if it has a defined boolean value
4752
+ ...typeof notesVisibleToPatientValue === "boolean" && { notesVisibleToPatient: notesVisibleToPatientValue }
4750
4753
  };
4751
4754
  zonesData[zoneId].push(itemWithSubtotal);
4752
4755
  const finalbilling = calculateFinalBilling(zonesData, 0.081);
@@ -5252,12 +5255,19 @@ async function addExtendedProcedureUtil(db, appointmentId, procedureId) {
5252
5255
  appointment.practitionerId,
5253
5256
  appointment.clinicBranchId
5254
5257
  );
5255
- updatedLinkedFormIds = [...updatedLinkedFormIds, ...formInitResult.allLinkedFormIds];
5256
- updatedLinkedForms = [...updatedLinkedForms, ...formInitResult.initializedFormsInfo];
5257
- updatedPendingUserFormsIds = [
5258
- ...updatedPendingUserFormsIds,
5259
- ...formInitResult.pendingUserFormsIds
5260
- ];
5258
+ const existingFormIds = new Set(updatedLinkedFormIds);
5259
+ const newFormIds = formInitResult.allLinkedFormIds.filter((id) => !existingFormIds.has(id));
5260
+ updatedLinkedFormIds = [...updatedLinkedFormIds, ...newFormIds];
5261
+ const existingFormIdsInLinkedForms = new Set(updatedLinkedForms.map((f) => f.formId));
5262
+ const newLinkedForms = formInitResult.initializedFormsInfo.filter(
5263
+ (form) => !existingFormIdsInLinkedForms.has(form.formId)
5264
+ );
5265
+ updatedLinkedForms = [...updatedLinkedForms, ...newLinkedForms];
5266
+ const existingPendingIds = new Set(updatedPendingUserFormsIds);
5267
+ const newPendingIds = formInitResult.pendingUserFormsIds.filter(
5268
+ (id) => !existingPendingIds.has(id)
5269
+ );
5270
+ updatedPendingUserFormsIds = [...updatedPendingUserFormsIds, ...newPendingIds];
5261
5271
  }
5262
5272
  const extendedProcedures = [...metadata.extendedProcedures || [], extendedProcedureInfo];
5263
5273
  const appointmentRef = doc7(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -5300,15 +5310,30 @@ async function removeExtendedProcedureUtil(db, appointmentId, procedureId) {
5300
5310
  `\u{1F5D1}\uFE0F [removeExtendedProcedure] Removed ${productsRemovedFromZones} products from zones for procedure ${procedureId}`
5301
5311
  );
5302
5312
  const removedFormIds = await removeFormsForExtendedProcedure(db, appointmentId, procedureId);
5303
- const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter(
5304
- (formId) => !removedFormIds.includes(formId)
5305
- );
5306
- const updatedLinkedForms = (appointment.linkedForms || []).filter(
5307
- (form) => !removedFormIds.includes(form.formId)
5308
- );
5309
- const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter(
5310
- (formId) => !removedFormIds.includes(formId)
5311
- );
5313
+ const removedFormIdsSet = new Set(removedFormIds);
5314
+ const linkedFormIdsSet = /* @__PURE__ */ new Set();
5315
+ const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter((formId) => {
5316
+ if (removedFormIdsSet.has(formId)) return false;
5317
+ if (linkedFormIdsSet.has(formId)) return false;
5318
+ linkedFormIdsSet.add(formId);
5319
+ return true;
5320
+ });
5321
+ const linkedFormsMap = /* @__PURE__ */ new Map();
5322
+ (appointment.linkedForms || []).forEach((form) => {
5323
+ if (!removedFormIdsSet.has(form.formId)) {
5324
+ if (!linkedFormsMap.has(form.formId)) {
5325
+ linkedFormsMap.set(form.formId, form);
5326
+ }
5327
+ }
5328
+ });
5329
+ const updatedLinkedForms = Array.from(linkedFormsMap.values());
5330
+ const pendingIdsSet = /* @__PURE__ */ new Set();
5331
+ const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter((formId) => {
5332
+ if (removedFormIdsSet.has(formId)) return false;
5333
+ if (pendingIdsSet.has(formId)) return false;
5334
+ pendingIdsSet.add(formId);
5335
+ return true;
5336
+ });
5312
5337
  const appointmentRef = doc7(db, APPOINTMENTS_COLLECTION, appointmentId);
5313
5338
  await updateDoc5(appointmentRef, {
5314
5339
  "metadata.extendedProcedures": metadata.extendedProcedures,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.14.52",
4
+ "version": "1.14.54",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -174,13 +174,25 @@ export async function addExtendedProcedureUtil(
174
174
  appointment.clinicBranchId,
175
175
  );
176
176
 
177
- // Merge form IDs and info
178
- updatedLinkedFormIds = [...updatedLinkedFormIds, ...formInitResult.allLinkedFormIds];
179
- updatedLinkedForms = [...updatedLinkedForms, ...formInitResult.initializedFormsInfo];
180
- updatedPendingUserFormsIds = [
181
- ...updatedPendingUserFormsIds,
182
- ...formInitResult.pendingUserFormsIds,
183
- ];
177
+ // Merge form IDs and info with deduplication
178
+ // Deduplicate linkedFormIds by formId
179
+ const existingFormIds = new Set(updatedLinkedFormIds);
180
+ const newFormIds = formInitResult.allLinkedFormIds.filter(id => !existingFormIds.has(id));
181
+ updatedLinkedFormIds = [...updatedLinkedFormIds, ...newFormIds];
182
+
183
+ // Deduplicate linkedForms by formId (keep existing entries, add only new ones)
184
+ const existingFormIdsInLinkedForms = new Set(updatedLinkedForms.map(f => f.formId));
185
+ const newLinkedForms = formInitResult.initializedFormsInfo.filter(
186
+ form => !existingFormIdsInLinkedForms.has(form.formId)
187
+ );
188
+ updatedLinkedForms = [...updatedLinkedForms, ...newLinkedForms];
189
+
190
+ // Deduplicate pendingUserFormsIds
191
+ const existingPendingIds = new Set(updatedPendingUserFormsIds);
192
+ const newPendingIds = formInitResult.pendingUserFormsIds.filter(
193
+ id => !existingPendingIds.has(id)
194
+ );
195
+ updatedPendingUserFormsIds = [...updatedPendingUserFormsIds, ...newPendingIds];
184
196
  }
185
197
 
186
198
  // Add extended procedure
@@ -259,16 +271,41 @@ export async function removeExtendedProcedureUtil(
259
271
  // Remove forms associated with this procedure
260
272
  const removedFormIds = await removeFormsForExtendedProcedure(db, appointmentId, procedureId);
261
273
 
262
- // Update appointment form arrays
263
- const updatedLinkedFormIds = (appointment.linkedFormIds || []).filter(
264
- formId => !removedFormIds.includes(formId),
265
- );
266
- const updatedLinkedForms = (appointment.linkedForms || []).filter(
267
- form => !removedFormIds.includes(form.formId),
268
- );
269
- const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || []).filter(
270
- formId => !removedFormIds.includes(formId),
271
- );
274
+ // Update appointment form arrays - remove forms that were deleted
275
+ // Also deduplicate to clean up any existing duplicates
276
+ const removedFormIdsSet = new Set(removedFormIds);
277
+
278
+ // Deduplicate and filter linkedFormIds
279
+ const linkedFormIdsSet = new Set<string>();
280
+ const updatedLinkedFormIds = (appointment.linkedFormIds || [])
281
+ .filter(formId => {
282
+ if (removedFormIdsSet.has(formId)) return false;
283
+ if (linkedFormIdsSet.has(formId)) return false; // Deduplicate
284
+ linkedFormIdsSet.add(formId);
285
+ return true;
286
+ });
287
+
288
+ // Deduplicate and filter linkedForms by formId
289
+ const linkedFormsMap = new Map<string, LinkedFormInfo>();
290
+ (appointment.linkedForms || []).forEach(form => {
291
+ if (!removedFormIdsSet.has(form.formId)) {
292
+ // Keep the first occurrence if duplicates exist
293
+ if (!linkedFormsMap.has(form.formId)) {
294
+ linkedFormsMap.set(form.formId, form);
295
+ }
296
+ }
297
+ });
298
+ const updatedLinkedForms = Array.from(linkedFormsMap.values());
299
+
300
+ // Deduplicate and filter pendingUserFormsIds
301
+ const pendingIdsSet = new Set<string>();
302
+ const updatedPendingUserFormsIds = (appointment.pendingUserFormsIds || [])
303
+ .filter(formId => {
304
+ if (removedFormIdsSet.has(formId)) return false;
305
+ if (pendingIdsSet.has(formId)) return false; // Deduplicate
306
+ pendingIdsSet.add(formId);
307
+ return true;
308
+ });
272
309
 
273
310
  // Update appointment
274
311
  const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -159,14 +159,25 @@ export async function addItemToZoneUtil(
159
159
 
160
160
  // Calculate subtotal for the item
161
161
  const now = new Date().toISOString();
162
+
163
+ // Filter out undefined values from item (Firestore doesn't allow undefined)
164
+ const cleanItem = Object.fromEntries(
165
+ Object.entries(item).filter(([_, value]) => value !== undefined)
166
+ ) as Omit<ZoneItemData, 'subtotal' | 'parentZone'>;
167
+
168
+ // Determine notesVisibleToPatient value (privacy-first: default to false if notes exist, otherwise omit)
169
+ const notesVisibleToPatientValue = cleanItem.notesVisibleToPatient !== undefined
170
+ ? cleanItem.notesVisibleToPatient
171
+ : (cleanItem.notes ? false : undefined);
172
+
162
173
  const itemWithSubtotal: ZoneItemData = {
163
- ...item,
174
+ ...cleanItem,
164
175
  parentZone: zoneId, // Set parentZone to the zone key
165
- subtotal: calculateItemSubtotal(item),
166
- // Set default visibility to false (privacy-first) if notes exist and visibility not explicitly set
167
- notesVisibleToPatient: item.notesVisibleToPatient ?? (item.notes ? false : undefined),
176
+ subtotal: calculateItemSubtotal(cleanItem),
168
177
  createdAt: now,
169
178
  updatedAt: now,
179
+ // Only include notesVisibleToPatient if it has a defined boolean value
180
+ ...(typeof notesVisibleToPatientValue === 'boolean' && { notesVisibleToPatient: notesVisibleToPatientValue }),
170
181
  };
171
182
 
172
183
  // Add item to zone
@@ -168,7 +168,8 @@ export interface ZoneItemData {
168
168
  notes?: string;
169
169
  notesVisibleToPatient?: boolean; // Whether notes are visible to patient (privacy-first, default false)
170
170
  subtotal?: number;
171
- ionNumber?: string;
171
+ ionNumber?: string; // Batch/Lot number
172
+ expiryDate?: string; // ISO date string (YYYY-MM-DD)
172
173
  createdAt?: string; // ISO timestamp
173
174
  updatedAt?: string; // ISO timestamp
174
175
  }