openchs-models 1.14.0 → 1.16.1

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.
@@ -186,6 +186,10 @@ class AbstractEncounter extends _BaseEntity.default {
186
186
  return (0, _Media.findMediaObservations)(_ObservationsHolder.default.clone(this.observations), _ObservationsHolder.default.clone(this.cancelObservations));
187
187
  }
188
188
 
189
+ replaceMediaObservation(originalValue, newValue, conceptUUID) {
190
+ new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
191
+ }
192
+
189
193
  replaceObservation(originalValue, newValue) {
190
194
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
191
195
  new _ObservationsHolder.default(this.cancelObservations).updateObservationBasedOnValue(originalValue, newValue);
@@ -199,6 +203,10 @@ class AbstractEncounter extends _BaseEntity.default {
199
203
  return this.latestEntityApprovalStatus && this.latestEntityApprovalStatus.isRejected;
200
204
  }
201
205
 
206
+ getEncounterLabel(identifier) {
207
+ return identifier === 'Encounter date' ? _General.default.toDisplayDate(encounter.encounterDateTime) : this.getObservationReadableValue(identifier);
208
+ }
209
+
202
210
  get subjectType() {
203
211
  return _lodash.default.get(this, this.getName() === "Encounter" ? "individual.subjectType" : "programEnrolment.individual.subjectType");
204
212
  }
package/dist/Concept.js CHANGED
@@ -189,7 +189,7 @@ class Concept {
189
189
  }
190
190
 
191
191
  getValueWrapperFor(obsValue) {
192
- if (this.isCodedConcept() || this.isSubjectConcept()) {
192
+ if (this.isSelectConcept()) {
193
193
  return _lodash.default.isArray(obsValue) ? new _MultipleCodedValues.default(obsValue) : new _SingleCodedValue.default(obsValue);
194
194
  }
195
195
 
@@ -224,6 +224,18 @@ class Concept {
224
224
  return this.isType(Concept.dataType.Subject);
225
225
  }
226
226
 
227
+ isEncounterConcept() {
228
+ return this.isType(Concept.dataType.Encounter);
229
+ }
230
+
231
+ isMediaConcept() {
232
+ return _lodash.default.includes([Concept.dataType.Image, Concept.dataType.Video, Concept.dataType.File], this.datatype);
233
+ }
234
+
235
+ isSelectConcept() {
236
+ return this.isCodedConcept() || this.isSubjectConcept() || this.isEncounterConcept() || this.isMediaConcept();
237
+ }
238
+
227
239
  isDurationConcept() {
228
240
  return this.isType(Concept.dataType.Duration);
229
241
  }
@@ -241,7 +253,7 @@ class Concept {
241
253
  }
242
254
 
243
255
  isPrimitive() {
244
- return [Concept.dataType.Text, Concept.dataType.Time, Concept.dataType.Numeric, Concept.dataType.Video, Concept.dataType.Image, Concept.dataType.Audio, Concept.dataType.Date, Concept.dataType.DateTime, Concept.dataType.Location, Concept.dataType.File].includes(this.datatype);
256
+ return [Concept.dataType.Text, Concept.dataType.Time, Concept.dataType.Numeric, Concept.dataType.Audio, Concept.dataType.Date, Concept.dataType.DateTime, Concept.dataType.Location].includes(this.datatype);
245
257
  }
246
258
 
247
259
  getAnswers() {
@@ -351,6 +363,7 @@ _defineProperty(Concept, "dataType", {
351
363
  GroupAffiliation: "GroupAffiliation",
352
364
  QuestionGroup: "QuestionGroup",
353
365
  File: "File",
366
+ Encounter: "Encounter",
354
367
 
355
368
  get Media() {
356
369
  return [this.Image, this.Video, this.Audio, this.File];
@@ -362,7 +375,14 @@ _defineProperty(Concept, "keys", {
362
375
  isWithinCatchment: 'isWithinCatchment',
363
376
  lowestAddressLevelTypeUUIDs: 'lowestAddressLevelTypeUUIDs',
364
377
  highestAddressLevelTypeUUID: 'highestAddressLevelTypeUUID',
365
- subjectTypeUUID: 'subjectTypeUUID'
378
+ subjectTypeUUID: 'subjectTypeUUID',
379
+ encounterTypeUUID: 'encounterTypeUUID',
380
+ encounterScope: 'encounterScope',
381
+ encounterIdentifier: 'encounterIdentifier'
382
+ });
383
+
384
+ _defineProperty(Concept, "encounterScopes", {
385
+ withinSubject: 'Within Subject'
366
386
  });
367
387
 
368
388
  _defineProperty(Concept, "childAssociations", () => new Map([[ConceptAnswer, "answers"]]));
@@ -617,6 +617,10 @@ class Individual extends _BaseEntity.default {
617
617
  return (0, _Media.findMediaObservations)(this.observations);
618
618
  }
619
619
 
620
+ replaceMediaObservation(originalValue, newValue, conceptUUID) {
621
+ new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
622
+ }
623
+
620
624
  replaceObservation(originalValue, newValue) {
621
625
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
622
626
  } //TODO use polymorphism to avoid if checks based on this
@@ -12,7 +12,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
12
12
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
13
 
14
14
  class MediaQueue {
15
- static create(entityUUID, entityName, fileName, type, entityTargetField, uuid = _General.default.randomUUID()) {
15
+ static create(entityUUID, entityName, fileName, type, entityTargetField, conceptUUID, uuid = _General.default.randomUUID()) {
16
16
  var mediaQueue = new MediaQueue();
17
17
  mediaQueue.entityUUID = entityUUID;
18
18
  mediaQueue.uuid = uuid;
@@ -20,6 +20,7 @@ class MediaQueue {
20
20
  mediaQueue.entityTargetField = entityTargetField;
21
21
  mediaQueue.fileName = fileName;
22
22
  mediaQueue.type = type;
23
+ mediaQueue.conceptUUID = conceptUUID;
23
24
  return mediaQueue;
24
25
  }
25
26
 
@@ -31,6 +32,7 @@ class MediaQueue {
31
32
  mediaQueueItem.entityTargetField = this.entityTargetField;
32
33
  mediaQueueItem.fileName = this.fileName;
33
34
  mediaQueueItem.type = this.type;
35
+ mediaQueueItem.conceptUUID = this.conceptUUID;
34
36
  return mediaQueueItem;
35
37
  }
36
38
 
@@ -45,7 +47,11 @@ _defineProperty(MediaQueue, "schema", {
45
47
  entityName: "string",
46
48
  entityTargetField: "string",
47
49
  fileName: "string",
48
- type: "string"
50
+ type: "string",
51
+ conceptUUID: {
52
+ type: "string",
53
+ optional: true
54
+ }
49
55
  }
50
56
  });
51
57
 
@@ -45,7 +45,8 @@ class Observation {
45
45
  conceptService,
46
46
  subjectService,
47
47
  addressLevelService,
48
- i18n
48
+ i18n,
49
+ encounterService
49
50
  }) {
50
51
  const valueWrapper = observation.getValueWrapper();
51
52
 
@@ -57,6 +58,12 @@ class Observation {
57
58
  if (observation.concept.datatype === _Concept.default.dataType.Subject) {
58
59
  const subject = subjectService.findByUUID(valueWrapper.getValue());
59
60
  return [new _Displayable.default(subject.nameStringWithUniqueAttribute, subject)];
61
+ } else if (observation.concept.datatype === _Concept.default.dataType.Encounter) {
62
+ const encounter = encounterService.findByUUID(valueWrapper.getValue());
63
+ const identifier = observation.concept.recordValueByKey(_Concept.default.keys.encounterIdentifier);
64
+ return [new _Displayable.default(encounter.getEncounterLabel(identifier), encounter)];
65
+ } else if (_Concept.default.dataType.Media.includes(observation.concept.datatype)) {
66
+ return new _Displayable.default(valueWrapper.getValue(), null);
60
67
  } else {
61
68
  return new _Displayable.default(i18n.t(conceptService.getConceptByUUID(valueWrapper.getConceptUUID()).name), null);
62
69
  }
@@ -66,6 +73,14 @@ class Observation {
66
73
  const subject = subjectService.findByUUID(uuid);
67
74
  return new _Displayable.default(subject.nameStringWithUniqueAttribute, subject);
68
75
  });
76
+ } else if (observation.concept.datatype === _Concept.default.dataType.Encounter) {
77
+ return valueWrapper.getValue().map(uuid => {
78
+ const encounter = encounterService.findByUUID(uuid);
79
+ const identifier = observation.concept.recordValueByKey(_Concept.default.keys.encounterIdentifier);
80
+ return new _Displayable.default(encounter.getEncounterLabel(identifier), encounter);
81
+ });
82
+ } else if (_Concept.default.dataType.Media.includes(observation.concept.datatype)) {
83
+ return new _Displayable.default(valueWrapper.getValue(), null);
69
84
  } else {
70
85
  return new _Displayable.default(_lodash.default.join(valueWrapper.getValue().map(value => {
71
86
  return i18n.t(conceptService.getConceptByUUID(value).name);
@@ -25,6 +25,8 @@ var _Identifier = _interopRequireDefault(require("./Identifier"));
25
25
 
26
26
  var _QuestionGroup = _interopRequireDefault(require("./observation/QuestionGroup"));
27
27
 
28
+ var _General = _interopRequireDefault(require("./utility/General"));
29
+
28
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
31
 
30
32
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -334,6 +336,50 @@ class ObservationsHolder {
334
336
  }
335
337
  }
336
338
 
339
+ replaceMediaObservation(oldValue, newValue, conceptUUID) {
340
+ if (_lodash.default.isNil(conceptUUID)) {
341
+ return this.updateObservationBasedOnValue(oldValue, newValue);
342
+ }
343
+
344
+ const observation = _lodash.default.find(this.observations, observation => observation.concept.uuid === conceptUUID);
345
+
346
+ if (observation) {
347
+ const valueWrapper = observation.getValueWrapper();
348
+
349
+ if (valueWrapper.isMultipleCoded) {
350
+ const answers = valueWrapper.getValue();
351
+
352
+ const oldValueIndex = _lodash.default.indexOf(answers, oldValue);
353
+
354
+ const newAnswers = _lodash.default.reject(answers, answer => answer === oldValue);
355
+
356
+ newAnswers.splice(oldValueIndex, 0, newValue);
357
+ observation.valueJSON = new _MultipleCodedValues.default(newAnswers);
358
+ } else {
359
+ observation.valueJSON = new _SingleCodedValue.default(newValue);
360
+ }
361
+ }
362
+ }
363
+
364
+ migrateMultiSelectMediaObservations(form) {
365
+ _lodash.default.forEach(form.nonVoidedFormElementGroups(), feg => {
366
+ _lodash.default.forEach(feg.getFormElements(), fe => {
367
+ const concept = fe.concept;
368
+ const observation = this.getObservation(concept);
369
+
370
+ if (_lodash.default.includes(_Concept.default.dataType.Media, fe.getType()) && observation && fe.isMultiSelect()) {
371
+ const valueWrapper = observation.getValueWrapper();
372
+
373
+ if (!_lodash.default.isArray(valueWrapper.getValue())) {
374
+ _General.default.logDebug("ObservationHolder", `Found string value ${valueWrapper.getValue()} for multi select media element, doing migration`);
375
+
376
+ observation.valueJSON = new _MultipleCodedValues.default([valueWrapper.getValue()]);
377
+ }
378
+ }
379
+ });
380
+ });
381
+ }
382
+
337
383
  toString(I18n) {
338
384
  let display = "";
339
385
  this.observations.forEach(obs => {
@@ -453,6 +453,10 @@ class ProgramEnrolment extends _BaseEntity.default {
453
453
  return (0, _Media.findMediaObservations)(_ObservationsHolder.default.clone(this.observations), _ObservationsHolder.default.clone(this.programExitObservations));
454
454
  }
455
455
 
456
+ replaceMediaObservation(originalValue, newValue, conceptUUID) {
457
+ new _ObservationsHolder.default(this.observations).replaceMediaObservation(originalValue, newValue, conceptUUID);
458
+ }
459
+
456
460
  replaceObservation(originalValue, newValue) {
457
461
  new _ObservationsHolder.default(this.observations).updateObservationBasedOnValue(originalValue, newValue);
458
462
  new _ObservationsHolder.default(this.programExitObservations).updateObservationBasedOnValue(originalValue, newValue);
package/dist/Schema.js CHANGED
@@ -168,7 +168,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
168
168
  var _default = {
169
169
  //order is important, should be arranged according to the dependency
170
170
  schema: [_LocaleMapping.default, _Settings.default, _Concept.ConceptAnswer, _Concept.default, _EncounterType.default, _Gender.default, _UserDefinedIndividualProperty.default, _AddressLevel.LocationMapping, _AddressLevel.default, _KeyValue.default, _Form.default, _FormMapping.default, _FormElementGroup.default, _FormElement.default, _SubjectType.default, _Individual.default, _ProgramOutcome.default, _Program.default, _ProgramEnrolment.default, _Observation.default, _ProgramEncounter.default, _Encounter.default, _EntitySyncStatus.default, _EntityQueue.default, _ConfigFile.default, _Checklist.default, _ChecklistItem.default, _Format.default, _UserInfo.default, _StringKeyNumericValue.default, _VisitScheduleInterval.default, _VisitScheduleConfig.default, _ProgramConfig.default, _Family.default, _IndividualRelation.default, _IndividualRelationGenderMapping.default, _IndividualRelationshipType.default, _IndividualRelationship.default, _RuleDependency.default, _Rule.default, _ChecklistItemStatus.default, _ChecklistDetail.default, _ChecklistItemDetail.default, _VideoTelemetric.default, _Video.default, _MediaQueue.default, _Point.default, _SyncTelemetry.default, _IdentifierSource.default, _IdentifierAssignment.default, _RuleFailureTelemetry.default, _BeneficiaryModePin.default, _OrganisationConfig.default, _PlatformTranslation.default, _Translation.default, _Groups.default, _MyGroups.default, _GroupPrivileges.default, _Privilege.default, _GroupRole.default, _GroupSubject.default, _DashboardCache.default, _LocationHierarchy.default, _ReportCard.default, _Dashboard.default, _DashboardSectionCardMapping.default, _DraftSubject.default, _StandardReportCardType.default, _ApprovalStatus.default, _EntityApprovalStatus.default, _GroupDashboard.default, _DashboardSection.default, _News.default, _Comment.default, _CommentThread.default, _Extension.default, _SubjectMigration.default],
171
- schemaVersion: 151,
171
+ schemaVersion: 153,
172
172
  migration: function (oldDB, newDB) {
173
173
  if (oldDB.schemaVersion < 10) {
174
174
  var oldObjects = oldDB.objects("DecisionConfig");
@@ -613,7 +613,7 @@ var _default = {
613
613
  });
614
614
  }
615
615
 
616
- if (oldDB.schemaVersion < 151) {
616
+ if (oldDB.schemaVersion < 152) {
617
617
  _lodash.default.forEach(newDB.objects(_MediaQueue.default.schema.name), mediaQueueItem => {
618
618
  mediaQueueItem.entityTargetField = "observations";
619
619
  });
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.14.0",
4
+ "version": "1.16.1",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",