Conditions List for Bahmni

We are introducing conditions list in Bahmni and we are using the conditions list module that was already available in OpenMRS (Wiki Page).

However, there are a few changes that we had to do for our requirements. These are summarised below:

Summary of Changes done for supporting Conditions Lists in Bahmni thus far

  • Modified org.openmrs.Condition to have the following statuses ‘ACTIVE’, ‘IN_ACTIVE’, ‘HISTORY_OF’
  • On status change, a new condition shall be created with a link to the previous condition with the modified status. The previous condition before status change shall be voided.
  • Introduced new org.openmrs.module.emrapi.web.controller.ConditionController for handling the following requests:
  • GET “/rest/emrapi/conditionhistory?patientUuid=” used for getting all the ConditionHistories of the given patient.
  • POST “/rest/emrapi/condition” BODY: used for creating or updating a Condition.
  • For supporting follow up diagnosis, a complex obs called “Follow up” shall be created for that encounter which shall have condition marked as diagnosis as its coded value.
  • While creating a condition, the concept_id in Condition table shall be mapped to the concept linked to diagnosis which has been added as a diagnosis.
  • For free text condition, the condition shall contain concept_id mapped to “Non-coded Condition” and the field “condition_non_coded” shall contain the free text value.
  • New models and mappers:
  • org.openmrs.api.contract.Condition
  • org.openmrs.api.contract.ConditionHistory
  • org.openmrs.api.contract.ConditionMapper
  • org.openmrs.api.contract.ConditionHistoryMapper
  • Files Changed/Modified:
  • New org.openmrs.api.contract.Condition
  • New org.openmrs.api.contract.ConditionHistory
  • New org.openmrs.api.contract.ConditionMapper
  • New org.openmrs.api.contract.ConditionHistoryMapper
  • New org.openmrs.module.emrapi.web.controller.ConditionController
1 Like

Isn’t this already supported ?

We don’t have support for conditions list as of now.

We do have a similar setup to for non-coded diagnosis though.

This handles the validations for non coded conditions as well…

Presumably ‘INACTIVE’ rather than ‘IN_ACTIVE’, yes?

If only the status is changing but it is still the same condition concept, the previous condition should not go away for a few reasons, such as (1) the proper condition start date would be the original one, (2) there could be encounters or diagnosis observations that are tied to that condition which should be preserved to make the proper history chain.

We are switching this from PRESUMED, CONFIRMED, HISTORY_OF => ACTIVE, INACTIVE, HISTORY_OF. I agree, and this is a good change in general; it’s not specific to our requirements. Further, since we have never exposed a UI or REST API for the functionality that’s in the emrapi module now, we can just change this and not worry about migrating legacy data. (And +1 to Jonathan’s point that it should be INACTIVE, not IN_ACTIVE.)

I agree that we need to define precisely how this is going to work. I would expect that when you modify a condition’s properties, the old one is not voided but just “closed” in some way, because it was true data up until the modification date.

One approach is to use Condition.endDate for this. Another is to split the status into two different fields: one for CURRENT vs HISTORY OF, the other for ACTIVE vs INACTIVE.

I was expecting a (non-complex) Coded observation. E.g. if the patient has {conditionId:1, concept: “Diabetes Type 1”} and the encounter is a followup for this condition, then we store an obs with {concept:“Followup for”, valueCoded: “Diabetes Type 1”}. I.e. it’s pointing to the concept of the condition, not to the condition itself.

I assume that these are specific to the emrapi module, and they’re needed to work with the Encounter Transaction REST web service. In that case the java package name is wrong: they should be org.openmrs.module.emrapi.(something).

I’d suggest that the condition isn’t closed or replaced at all but simply modified, just as you don’t close (or void) an old patient when you change his or her marital status.

The live list display only needs to show the current conditions with their current status (and their original start date). If you really want to see when the status was changed you would query the audit trail, same as you would with the patient’s marital status.

@darius We shall follow this approach.[quote=“jteich, post:5, topic:10112”] Presumably ‘INACTIVE’ rather than ‘IN_ACTIVE’, yes? [/quote]

@jteich Yes. It will be INACTIVE.

@darius That was a typographical error. It is indeed a non-complex observation.

Thanks for the inputs. We will make these changes.

From the ‘audit trail’ perspective, when should we clone the condition and make a new entry in database. At what changes we keep an audit trail?

  1. Only when status changes
  2. Some other fields along with status changes
  3. All the fields


Calling this clinicalStatus and using values active, remission, and resolved would better align with FHIR Condition’s clinicalStatus and leave room for verificationStatus (presumed vs. confirmed), which is needed when conditions are used in as an EncounterDiagnosis.

I’m not a fan of the term “HISTORY_OF” for clinical status, because:

  • Whether of not something is historic does not always correlate with it being clinically active. For example, a History of Stroke condition may be historic, yet its clinical status is active, because a history of stroke is relevant to clinical decision being made today. On the other hand, a condition of [Halitosis] ( may be an ongoing condition, but have a clinical status of inactive, because it has no relevance to medical decision making.
  • “History of” is often pre-coordinated into concepts.

I’d favor not void & insert for every property change (e.g., changing the onset date, adding an end date, editing details). If someone is explicitly updating the concept for a condition (presumably refining it), then setting the end date on the old entry should suffice. I agree with @darius that voiding would mean we are invalidating the previous condition (which isn’t the case).

At the API level, we intend to support all of these:

  1. Add condition to condition list independent of encounter diagnoses.
  2. Add encounter diagnoses (condition) without adding the condition to the condition list.
  3. Add condition from condition list to encounter diagnoses.
  4. Add encounter diagnosis to condition list.

For #3 or #4, I would prefer that we record an explicit link in the encounter diagnosis to the related condition (rather than relying on someone inferring the relationship by comparing concepts).

Support for free text conditions aligns with our plans for use of Condition in EncounterDiagnoses. I assume for most CIEL-based implementations the “Non-coded condition” you are referring to would be Diagnosis or problem, non-coded.

The status “History-Of” depicts the importance of an inactive condition. A condition that is clinically inactive but can have an impact on the clinical decision making. The patient is not actually suffering from that condition anymore but the doctor has to know that the patient suffered from this condition some time ago.

Building pre-coordinated concepts will make it difficult to use. For Example: The doctor will have to inactivate Stroke and then add a new “History of Stroke” to the conditions list as compared to just marking Stroke as “History of” which requires only a single click to achieve.

Verification status can still be implemented. As for our implementation, we are only allowing “Confirmed” diagnoses to be added to the conditions list. We want to put this restriction because if a diagnosis is “Presumed”, it might turn out to be not the correct diagnosis after investigation results are made available to the doctor and generally, whatever is on the conditions list, is assumed to be true. But we will not put this restriction in the design. So other implementations of OpenMRS will not have to live with this restriction.

I believe you’re confusing clinical status (relevance to clinical decision making) with physiologic status (the state of a condition whether or not it is clinically relevant). We need the former to manage conditions. Accurate & timely collection of the latter is theoretical and not realistic in real life.

And it’s not a matter of deciding whether or not to create pre-coordinated concepts for physiologic status. CIEL dictionary is already full of them.

We (@jteich, @akhilmalhotra, and I) looked at FHIR’s clinicalStatus and decided that it’s not what we want for our settings and constraints. (Also, @burke, I’ve been inspired by your repeated comments over the years that the single most important thing about the condition list is that the clinician must be able to remove an entry with a single click and no followup questions.)

In the OpenMRS settings I have seen, nobody would ever take the time in a point-of-care UI to distinguish whether a problem was “resolved” or went into “remission”. (Is remission relevant outside of cancer?) Further, I find this argument by Akhil pretty convincing (about single click vs click + add new + search + confirm):

To automate this with precoordinated concepts we would need Bahmni/OpenMRS to automatically know which concept is the pre-coordinated history-of concept for any given symptom/diagnosis. In this particular case, CIEL does say that

Stroke (111103) is Same As SNOMED-CT 230690007 Personal History of Stroke (152512) has Associated Finding SNOMED-NP 230690007

…however (a) this is not done consistently for all symptoms and diagnoses, and (b) the client for whom we are building this feature is not using the CIEL dictionary, so this approach would require us to rework their entire dictionary, which they don’t have the resources to do.

Here’s what I think we do here:

  1. The Bahmni UI for this should be written to support a high-level action “Mark {condition X} as History Of”
  2. In the API (this is in the emrapi module, as an incremental improvement to this code) we support the statuses Akhil proposed: Active, Inactive, and History Of
  3. In the short run we implement “Mark {condition X} as History Of” by just changing the status
  4. In the future someone is welcome to write a more sophisticated implementation that uses concept mappings to find a pre-coordinated concept. (Thus if someone writes this code, and maps their dictionary correctly, they will never see the HISTORY_OF status being used.)

Actually the original request was to do something like this, but @jteich and I pushed to simplify as much as possible, because in practice knowing the date + concept is sufficient (and even if you theoretically get more granular data than that, it’s unlikely to be reliably captured). Also, to do this we’d need to store a complex obs that points to a condition, and this would be tougher to code against, especially in SQL reports.

@akhilmalhotra (+/- @jteich) can you follow up on this?

FYI - To track the status of this feature please refer to this Trello Card on Bahmni wall:

We should clone for every change we make. However, for status change, we should not void the previous condition (as discussed above). If we make any changes other than the status change (which will mainly include change of start date or attach a note), we can void the previous condition.

Just to be precise, can we look at the specific cases?

My uneducated guess is:

  1. Change from Active Stroke to History Of Stroke => new row in the condition table:
  • (1) status=active, concept=Stroke, onsetDate=stroke-date, endDate=today
  • (2) status=history-of, concept=Stroke, onsetDate=stroke-date?, previousCondition=(1)
  1. Change onsetDate, additionalDetails, endDate, endReason => edit these in-place, no clone or audit trail
  2. Change concept or conditionNonCoded => new row in the condition table
  • (1) status=active, concept=Myocardial Infarction, onsetDate=stroke-date, endDate=today
  • (2) status=active, concept=Coronary Artery Disease, onsetDate=today?, previousCondition=(1)

@darius I suggest we keep audit trail for everything and keep the logic simple. An audit trail also comes handy in certain circumstances like medico-legal cases, erroneous diagnosis and (potentially) settling false insurance claims.

I was referring to EncounterDiagnosis, which could have a foreign key to the condition list entry when the relationship was explicit. The reason being that someone could single click add a condition from the condition list and we’d explicitly capture the relationship rather than infer it. When someone manually added an encounter diagnosis that matches an active condition list entry, we could ask them if this is the same condition or not and make the explicit link if they say yes. This would allow for encounter diagnoses for repeated or concurrent occurrences to be recorded and not be implicitly linked as referring to the same thing. If we are going to enforce that active conditions in the condition list and conditions in encounter diagnoses cannot contain duplicates, then we can survive without an explicit link… but make implicit links may still come back and bite us for episodic non-related conditions (tb, pregnancy, etc.)

There is a ticket for this in openmrs-core, but it hasn’t been done yet (it’s not even ready-for-dev), and it’s not in our current workplan.

I think we’ll go ahead an implement this feature in the simpler way, knowing that it’s less than ideal. As long as there aren’t two active conditions with the same concept at the same time, then there’s no data loss. (And we may have to deal with a data migration task when condition and encounter_diagnosis actually make it into openmrs-core.)

(@akhilmalhotra let’s make sure to include in the story that we shouldn’t allow you to add another active condition with the same concept or non-coded-text as an existing one.)

@darius, @burke It is already included.