Uploaded image for project: 'OpenMRS Core'
  1. OpenMRS Core
  2. TRUNK-5015

Core data model should support Encounter Diagnoses



    • Medium
    • Encounter Diagnosis Sprint 4, Encounter Diagnosis Sprint 5, Encounter Diagnosis Sprint 6



      PIH first introduce "Diagnoses" in the emrapi module for their Mirebalais project (storing the actual data in an obs group). This has been included in the Reference Application and in Bahmni for years without any real changes being requested to the use case, so I'm pretty confident that we've got this right, and it's time to implement Encounter Diagnoses in openmrs-core, while aligning with recent developments in FHIR.


      It's important to design and implement Conditions and Encounter Diagnoses together, so this is intentionally a large ticket, with broad scope. Whoever picks this up should break down the work further. (For example, implement Diagnosis first, and Condition next.)


      • Introduce a new convenience class in the Java API:
        class CodedOrFreeText {
          Concept coded;
          ConceptName specificName;
          String nonCoded;
      • Introduce an Enum for what we've historically called "diagnosis certainty" and FHIR refers to as ConditionVerificationStatus (https://www.hl7.org/fhir/valueset-condition-ver-status.html). We will only support a subset of the FHIR statuses:
        enum ConditionVerificationStatus {
            PROVISIONAL, // was called "Presumed" in the original EMRAPI module implementation
      • Introduce an Enum for what we've historically called "condition status" and FHIR refers to as ConditionClinicalStatus (https://www.hl7.org/fhir/valueset-condition-clinical.html). We support a subset of the FHIR statuses, and we support one additional status not included in FHIR:
        enum ConditionClinicalStatus {
            HISTORY_OF // this maps most closely to the "remission" status in FHIR, but we want to be more clear about the common OpenMRS use case
      • Introduce new Condition domain object, backed by a new `condition` table:
        class Condition extends BaseOpenmrsData {
          CodedOrFreeText condition; // required
          ConditionClinicalStatus clinicalStatus; // required
          ConditionVerificationStatus verificationStatus; // optional
          Condition previousVersion; // optional
          String additionalDetail; // optional, a short comment, maps to https://www.hl7.org/fhir/condition-definitions.html#Condition.note
          Date onsetDate; // optional
      • Introduce a new Diagnosis domain object, backed by a new `encounter_diagnosis` table. Each encounter may have 0..n diagnoses.
        class Diagnosis extends BaseOpenmrsData {
          Encounter encounter; // required
          CodedOrFreeText diagnosis; // required
          ConditionVerificationStatus certainty; // required
          Integer rank; // required. must be a positive integer, and it's okay for two diagnoses in an encounter to have the same rank. (As compared to previous EMRAPI implementation, 1=PRIMARY, 2=SECONDARY)
          Condition condition; // optional. May refer to a new condition to be created as a result of this diagnosis, or an existing condition that this encounter is following up.
        class Encounter {
            // ...
           Set<Diagnosis> diagnoses 
      • Introduce new REST APIs for these domain objects (create associated tickets in the RESTWS project for this)
      • Refactor emrapi module's DiagnosisService and ConditionService to use this new functionality under the hood (e.g. either delegating to openmrs-core, or using the current emrapi approach, depending on the openmrs-core version)
      • Create a ticket for migrating existing data captured via the emrapi module and deprecating this functionality from emrapi.
      • Create a ticket for updating the UIs in the reference application to use these new tables.

      Dev Notes

      Note that whenever you introduce a domain object, you generally need to introduce:

      1. a Java class
      2. a Spring validator for that java class
      3. a hibernate mapping
      4. a liquibase changeset

      With the CodedOrFreeText class, the idea is that in the underlying database we'd have fields like condition.coded_condition, condition.non_coded_condition. We can use Hibernate "components/embedded objects" https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch05.html#mapping-declaration-component to implement this.

      Here are examples of domain object classes: https://github.com/openmrs/openmrs-core/tree/master/api/src/main/java/org/openmrs

      Here are examples of validators: https://github.com/openmrs/openmrs-core/tree/master/api/src/main/java/org/openmrs/validator

      Here are examples of hibernate mapping files: https://github.com/openmrs/openmrs-core/tree/master/api/src/main/resources/org/openmrs/api/db/hibernate

      Here are examples of liquibase changesets: https://github.com/openmrs/openmrs-core/blob/master/api/src/main/resources/liquibase-update-to-2.0.xml

      Gliffy Diagrams


          Issue Links

            There are no Sub-Tasks for this issue.



                dkayiwa Daniel Kayiwa
                darius Darius Jazayeri
                0 Vote for this issue
                8 Start watching this issue



                  Time Tracking

                    Original Estimate - 2 days Original Estimate - 2 days
                    Remaining Estimate - 0 minutes
                    Time Spent - 3 days