openchs-models 1.33.65 → 1.33.66

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.
@@ -265,7 +265,10 @@ class AbstractEncounter extends _BaseEntity.default {
265
265
  return (0, _Media.findMediaObservations)(_ObservationsHolder.default.clone(this.observations), _ObservationsHolder.default.clone(this.cancelObservations));
266
266
  }
267
267
  replaceMediaObservation(originalValue, newValue, conceptUUID) {
268
- new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
268
+ // Both collections, no short-circuit — findMediaObservations enqueues from both.
269
+ const inObservations = new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
270
+ const inCancelObservations = new _ObservationsHolder.default(this.cancelObservations).replaceMediaObservation(originalValue, newValue, conceptUUID);
271
+ return inObservations || inCancelObservations;
269
272
  }
270
273
  replaceObservation(originalValue, newValue) {
271
274
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
@@ -640,7 +640,7 @@ class Individual extends _BaseEntity.default {
640
640
  return (0, _Media.findMediaObservations)(this.observations);
641
641
  }
642
642
  replaceMediaObservation(originalValue, newValue, conceptUUID) {
643
- new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
643
+ return new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
644
644
  }
645
645
  replaceObservation(originalValue, newValue) {
646
646
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
@@ -515,88 +515,39 @@ class ObservationsHolder {
515
515
  return false;
516
516
  }
517
517
 
518
- // Helper to find and update media in question group
519
- _updateMediaInQuestionGroup(questionGroup, conceptUUID, oldValue, newValue) {
520
- if (!questionGroup || !questionGroup.getValue) return false;
521
- const groupObservations = questionGroup.getValue();
522
- if (!groupObservations || !Array.isArray(groupObservations)) return false;
523
-
524
- // Find media observation either by concept UUID or by value
525
- const mediaObs = _lodash.default.find(groupObservations, obs => obs.concept.uuid === conceptUUID || _Concept.default.dataType.Media.includes(obs.concept.datatype) && obs.getValue && obs.getValue() === oldValue);
526
-
527
- // Update if found
528
- return this._updateMediaValueInObservation(mediaObs, oldValue, newValue);
529
- }
530
-
531
- // Helper to find and update media in repeatable question group
532
- _updateMediaInRepeatableQuestionGroup(repeatableGroup, conceptUUID, oldValue, newValue) {
533
- if (!repeatableGroup || !repeatableGroup.getAllQuestionGroupObservations) return false;
534
- const allGroups = repeatableGroup.getAllQuestionGroupObservations();
535
- if (!allGroups || !allGroups.length) return false;
536
-
537
- // Check each group in the repeatable question group
518
+ // Replaces oldValue in every matching media child of a question-group wrapper (regular or
519
+ // repeatable) — every group/row, every child; does not stop at the first match.
520
+ _replaceMediaInGroupWrapper(wrapper, oldValue, newValue) {
521
+ const groups = wrapper.isRepeatable && wrapper.isRepeatable() ? wrapper.getAllQuestionGroupObservations ? wrapper.getAllQuestionGroupObservations() : [] : [wrapper];
538
522
  let updated = false;
539
- allGroups.forEach(group => {
540
- if (this._updateMediaInQuestionGroup(group, conceptUUID, oldValue, newValue)) {
541
- updated = true;
542
- }
523
+ _lodash.default.forEach(groups, group => {
524
+ const groupObservations = group && group.getValue && group.getValue();
525
+ if (!Array.isArray(groupObservations)) return;
526
+ _lodash.default.forEach(groupObservations, childObs => {
527
+ if (_Concept.default.dataType.Media.includes(childObs.concept.datatype) && this._updateMediaValueInObservation(childObs, oldValue, newValue)) {
528
+ updated = true;
529
+ }
530
+ });
543
531
  });
544
532
  return updated;
545
533
  }
546
534
 
547
- // Helper to process a question group (regular or repeatable) and update media within it
548
- _processQuestionGroupWrapper(wrapper, conceptUUID, oldValue, newValue, sourceName) {
549
- if (!wrapper) return false;
550
-
551
- // Determine if it's a repeatable question group or regular question group
552
- const isRepeatable = wrapper.isRepeatable && wrapper.isRepeatable();
553
-
554
- // Process the appropriate group type
555
- return isRepeatable ? this._updateMediaInRepeatableQuestionGroup(wrapper, conceptUUID, oldValue, newValue) : this._updateMediaInQuestionGroup(wrapper, conceptUUID, oldValue, newValue);
556
- }
535
+ // Replaces oldValue with newValue in EVERY observation referencing it top-level media
536
+ // observations and those inside (repeatable) question groups. The same media value can be
537
+ // referenced by multiple concepts with different select types (e.g. a rule-copied read-only
538
+ // display element), so the scan is value-driven; conceptUUID is retained only for caller
539
+ // compatibility. Returns true if at least one observation was updated.
557
540
  replaceMediaObservation(oldValue, newValue, conceptUUID) {
558
- console.log(`[INFO] Replacing media: ${oldValue} → ${newValue}`);
559
-
560
- // Since conceptUUID is always provided in practice, optimize for that case first
561
- // Try to find direct top-level observation with matching concept UUID
562
- const directObservation = _lodash.default.find(this.observations, obs => obs.concept.uuid === conceptUUID);
563
- if (directObservation) {
564
- // Direct media observation
565
- if (_Concept.default.dataType.Media.includes(directObservation.concept.datatype)) {
566
- if (this._updateMediaValueInObservation(directObservation, oldValue, newValue)) {
567
- console.log(`[INFO] Updated media in direct observation`);
568
- return true;
569
- }
570
- }
571
- // Question Group containing the media
572
- else if (directObservation.concept.datatype === _Concept.default.dataType.QuestionGroup) {
573
- const valueWrapper = directObservation.getValueWrapper();
574
- if (this._processQuestionGroupWrapper(valueWrapper, conceptUUID, oldValue, newValue)) {
575
- console.log(`[INFO] Updated media in question group`);
576
- return true;
577
- }
578
- }
579
- }
580
-
581
- // Check nested structures (this works both with and without conceptUUID)
582
541
  let updated = false;
583
542
  _lodash.default.forEach(this.observations, obs => {
584
- // Only process question groups
585
- if (obs.concept.datatype !== _Concept.default.dataType.QuestionGroup) return;
586
- const valueWrapper = obs.getValueWrapper && obs.getValueWrapper();
587
- if (!valueWrapper) return;
588
- if (this._processQuestionGroupWrapper(valueWrapper, conceptUUID, oldValue, newValue)) {
589
- updated = true;
543
+ if (_Concept.default.dataType.Media.includes(obs.concept.datatype)) {
544
+ if (this._updateMediaValueInObservation(obs, oldValue, newValue)) updated = true;
545
+ } else if (obs.concept.datatype === _Concept.default.dataType.QuestionGroup) {
546
+ const wrapper = obs.getValueWrapper && obs.getValueWrapper();
547
+ if (wrapper && this._replaceMediaInGroupWrapper(wrapper, oldValue, newValue)) updated = true;
590
548
  }
591
549
  });
592
- if (updated) {
593
- console.log(`[INFO] Updated media in nested structure`);
594
- return true;
595
- }
596
-
597
- // As a fallback, use value-based replacement if we couldn't find it by concept
598
- // This ensures backward compatibility and handles edge cases
599
- return this.updateObservationBasedOnValue(oldValue, newValue);
550
+ return updated;
600
551
  }
601
552
  toString(I18n) {
602
553
  let display = "";
@@ -455,7 +455,10 @@ class ProgramEnrolment extends _BaseEntity.default {
455
455
  return (0, _Media.findMediaObservations)(_ObservationsHolder.default.clone(this.observations), _ObservationsHolder.default.clone(this.programExitObservations));
456
456
  }
457
457
  replaceMediaObservation(originalValue, newValue, conceptUUID) {
458
- new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
458
+ // Both collections, no short-circuit — findMediaObservations enqueues from both.
459
+ const inObservations = new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
460
+ const inExitObservations = new _ObservationsHolder.default(this.programExitObservations).replaceMediaObservation(originalValue, newValue, conceptUUID);
461
+ return inObservations || inExitObservations;
459
462
  }
460
463
  replaceObservation(originalValue, newValue) {
461
464
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "openchs-models",
3
3
  "description": "OpenCHS data model to be used by front end clients",
4
- "version": "1.33.65",
4
+ "version": "1.33.66",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",