Queue module as a basis for managing inpatients

The Queue module has recently been introduced into the reference application and O3 and is quickly becoming a means to manage and track patients throughout the course of their Visit. A typical usage would involve a Queue, which is a Service provided at a Location:

For example: Queue = Maternity Triage ( Location = Maternity, Service = Triage )

A Queue Entry would then provide a means to indicate that a Patient has a particular priority and status during a particular Visit on this Queue, during a particular time period.

The result is that we can track a Patient’s progression from Waiting for Triage to Attending Triage in the Maternity Triage queue, followed by their transition to Waiting for Admission, Admitted, and Waiting for Discharge on the Delivery Ward queue. We can track when and for how long they were in each of these states, and we can provide views that facilitate managing patients in each of these states.

As the above use case demonstrates, this is already providing much of the information that one might need to determine whether a Patient is an Inpatient on a particular ward at a given time. This would likely complement other information in the patient record, including potentially an In Patient Visit Type or one or more Admission encounters or disposition observations, but may actually be the most explicit indication that we have as to Admission status.

The first question I want to pose is - how does this resonate with people and their hopes and expectations for how Inpatient care would be represented and how admissions would be tracked?

The follow-up to this is that the logical extension is to enable associating a currentLocation to each Queue Entry, and then to use the Location domain in OpenMRS (with all of it’s support for Location types, tags, attributes, and hierarchy) to accomplish Bed Management.

Explicitly the thought is to:

  • Model beds as Locations in OpenMRS (child locations of a ward, with a particular type)
  • Bed numbers would be Location Attributes
  • Add a currentLocation property to QueueEntry to reflect where the patient is currently situated (primary use case is Bed Allocation, but could also indicate that a patient is in a particular Room or Ward, etc)

Thoughts or alternative suggestions welcome.

1 Like

For bed management, have you thought through this GitHub - openmrs/openmrs-module-bedmanagement: The Bed Management module brings in the data model, DAO entities, services and REST API layers for managing beds, admission locations and all other backend entities that relates to IPD Ward Management. as used by bahmni and i think UgandaEMR? cc @slubwama

1 Like

So a couple of points here:

  • I was hoping, at some point, that we’d be able to add a PatientVisitWorkflow (or something similarly scoped that ties a patient in a visit to some kind of status) for tracking where the patient is rather than strictly using queues to do so, though I get how they’ve been being shaped that way in the absence of a more “proper” workflow state tracking. Queues were intended to be a sort of logical “place” that a patient might be in the larger workflow.
  • Locations are tempting for beds, but it may not be the best representation. This is because in typical inpatient settings, beds functions more like data than metadata. Usually with bed management, you need to track not just physical beds and which physical beds are in use, but what we might call logical beds, i.e., physical beds that are available or unavailable based on available staffing or equipment. Usually inpatient staff will need to add or remove (or least deactivate) beds as part of normal operations. Similarly, even physical beds end up being moved between units or to different floors, etc. Granted, that all could be done with locations, but it is different enough that it may not entirely make sense to do so.

Sure @dkayiwa we have tried out this module of Bed management and the model seems fine. Just that api might need some rework. But by and large it support the use of wards as locations managing all beds in that locations. Would be happy to give a demo of what we have sofar

That’s the case with wards as well no?

Thanks for the responses so far! Addressing some of the comments:

Queues have definitely morphed into this. They link a patient in a visit to a status during a time period within the visit. I would imagine that any future designs to add more sophisticated workflows would be done as an evolution / enhancement of Queues, not as a replacement. Would you agree with that @ibacher ?

In any event, we don’t have such a thing in the short term, and to my knowledge the historical way that we indicate admission status is via the emrapi module, which has APIs with definitions roughly like:

  • Admitted: If visit has an emr.admissionEncounterType encounter without a subsequent emr.exitFromInpatientEncounterType encounter

  • Awaiting Admission: visit has a disposition obs of type ADMIT (as configured within dispositionConfig.json) that is not followed by an Admission Decision obs of of type Deny Admission, and has no emr.admissionEncounterType encounters

The Queue module seems to provide a more static means to record these statuses for a patient beyond these more dynamic computations.

The question I’m really posing here - before getting into bed management at all - is whether using Queues in this way - to indicate which patients are Inpatients and which are “Waiting for Admission”, or “Admitted” to particular wards, etc. makes sense as the generally accepted default approach to this moving forward, rather than the prior approach described above from emrapi.

(We could potentially link the emrapi and queue approaches by having the same emrapi rules set status queue statuses that reflect the computed admission states when they change)

Regarding the question of bed management, we might want to move that to another thread to discuss, but I bring it up here because I think adding Bed as something that is linked to a QueueEntry is a relatively low lift, and since the logic of “Admitted to a ward” and “In Bed X in ward” are so closely related and would ideally be maintained with the same association, if we do agree to uses QueueEntries to track admission status.

The bed management module used by Bahmni is definitely something we have considered, but if we were to use it, we would need to keep patient bed assignments and patient admission statuses at a particular location in sync with each other, and that has a lot of downsides, especially if adding what we need to Queues is low effort.

Yeah, I had the same thought initially. And another approach we are considering - but I left out of my initial post for brevity - was to expand on the recently added QueueRoom that is associated with a Queue, and to support a List<Bed> on QueueRoom and then add a bed property to QueueEntry rather than what I suggested above, which was to use a serviceLocation property.

I think both approaches have pros and cons. Both @chibongho1 and @cioan independently suggested maybe we use Locations for this when I originally suggested adding a Bed to QueueRoom. And the fact that FHIR represents beds as Locations gave me an indication that this might be the way to go.

The reason I balked originally was similar to what you indicate - that we currently manage all of our Locations in Initializer config, and if we were to use Locations then we’d be saying that a subset of Locations (Bed) would probably be something we’d want to manage via an Administrative UI, whereas other Locations we want to lock down via config. And also because the properties we need to manage for a Bed (eg. Bed Number) would need to be added via attributes.

That said, Locations have so much flexibility, and are already taggable, attributable, and able to be managed in parent/child relationships, that they are very tempting to use, especially since FHIR sees them that way.

They also have the benefit of being just one new additional property on QueueEntry that can be used outside of the Bed context. For example, adding this to QueueEntry could allow us to actually remove the QueueRoom domain entirely, as Queues could have any arbitrary hierarchy of service locations that are tagged as certain types associated with them. @aojwang FYI

Sorry for the long post :slight_smile:

It’s always easier to evolve from what we have, and I certainly wasn’t thinking of something divorced from the queueing system, just something that builds around it. Conceptually, I think the issue I have is that queues have an implicit sorting (by priority and time waited or some other mechanism) that doesn’t make a ton of sense once someone is actually admitted. (Although maybe there’s some kind of use case for a priority-sorted list of a ward’s patients?). Basically, I’m not sure queues are the right abstraction once someone is no longer waiting, but is in a state of some kind.

I definitely think coordinating this with the existing admissions stuff from emrapi is the right move.

Thanks @slubwama I’d love to learn more about your work in this space. How general purpose is the esm-ugandaemr-bed-management-app and is this something that non-UgandaEMR / refapp distributions could use directly or adapt?

Regarding the backend module, a few questions on my end - let me know how these dovetail with your thoughts, and I’m also eager to hear thoughts from Bahmni @angshuonline .

  • Bed, BedTag, and BedTagMap implement OpenmrsData, not OpenmrsMetadata. This doesn’t really pose a problem per se, but I’m wondering if this is intentional or reflects how these are meant to be used. If these are really intended to be metadata, it might be worthwhile trying to clean that up, though I recognize that the benefits to doing so are likely not worth the risk with backwards-compatibility.

  • BedPatientAssignment has a required Encounter property. At least in the original use cases we were envisioning, we were not thinking we’d need to create an Encounter to assign or reassign a patient to a bed, but would just make the association at the Visit level. There are definitely some potential benefits to having this linkage at the encounter rather than the Visit level, but I’m interested how others view this and whether this requirement to create Encounters for every bed assignment might be problematic.

  • The requirement on the atomfeed module is one that I think we would need to work with the Bahmni team to lessen, and to move this into more of an aware-of dependency like has been done elsewhere like appointments. Is this something that is possible @angshuonline ?

  • Similarly the requirement on the owa module I think should be straightforward to change to an aware-of dependency - can this be changed as well?


Sure @mseaton we carefully tried not to tie it around any dependency on ugandaemr. we could move this in OpenMRS repos as a starting point toward Bedmanagement and evolve it toward the desired designs as per the ongoing in with the inpatient. We could organize a demo at one of the community meetings. @jaba @mmwanje @akileng56

Thanks @ibacher. Based on this and the other feedback, my takeaway is that the preferred approach is to combine logic and constructs from emrapi, bedmanagment, and queue together, rather than to simply use an extended queue model for managing inpatient status.

So this kind of ties into my more recent post about higher-level APIs.

Looking at things concretely, we are initially planning to build an inpatient “Ward View” which needs to pull together the following:

Admission Requests

  • The EMR API approach is to define this as patients with an active visit, where the most recent “Disposition” observation indicates “Admit”, and where there are no subsequent Admission Encounters and no subsequent “Admission Decision” observations indicating “DENY”.

  • A Queue approach could defined this as patients who have a status of “Waiting” on a particular queue

The EMR API approach is more of a derived status. The Queue approach is more of a fixed status. There are pros and cons of each. One could lead to the other. A Disposition = Admit observation could trigger the creation of a queue entry, putting a patient in the “Waiting for Admission” state. An Admission Encounter could trigger the transition of a queue entry from Waiting for Admission to Admitted. An Admission Decision = Deny observation could trigger the removal of the patient from the queue by ending their queue entry. The drawbacks here are if these get out of sync as data is updated. The benefits are that Queue is much faster and straightforward to query, and patients can be added or removed from this state without requiring changes to their clinical data, if that is not appropriate.


  • The EMR API approach is to define this as patients with an active visit that contains an Admission Encounter with no subsequent “Discharge Encounter”.

  • The Bed Management approach would define this as patients who have an active bed assigned

  • The Queue approach would define this as patient who has a particular status (eg. “In Service”) on a particular queue

Main question here is where is the source of truth, if anywhere. Is it with EMR API? What if EMR API does not indicate an admission, but bed management has the patient assigned to a bed? What if they are “In Service” in a Queue on an Inpatient Ward? Should we attempt to take the super set of these representations or should one be the source of truth? How should they inter-relate?

Waiting for Discharge

Not currently defined anywhere. This is likely to be something we want to support with Queues, but could be derived in EMR API similarly to other approaches using encounters and observations.


  • EMR-API defines this as a visit with a “Discharge” encounter with no subsequent “Admission” encounter

There isn’t really a good equivalent here in the Queue of Bed Management modules, other than the completion of a bed or queue assignment.

It is likely that there is no one correct answer to any of these questions, and that no matter what we decide, we will want to design things out so different configurations can be supported. That said, we should implement a reasonable default for this that will have the broadest applicability. This is where EMR-API and it’s evolution may come in.

Very interested to hear thoughts on any of this.

1 Like