Visits that spans across multiple days


I’m trying to understand what’s OpenMRS 3 status regarding allowing “multiple day visits”. Currently, by looking at the way the active visit is determined on esm-core, it seems that visits must start and end within the same day.

Is there currently any development being done or planned in order to support having an active visit span across multiple days?

Not sure who to tag here. @grace @ibacher any feedback on this will be appreciated. Thanks!

Thank you @icrc.psousa for kicking this off. Pulling in @dennis - can you help here with the frontend piece, and @dkayiwa can you help w/ the backend context?

My initial reaction was that O3 should handle multi-day visits exactly the same as any other OMRS platform since we’re all on the same backend.

But then I’m a bit surprised by the stopDatetime condition you discovered in esm-core. I suspect the only reason for this is because @vasharma05 needed a way to limit/daily refresh the patients showing up in the Active Visits list so that it didn’t become super long; or perhaps because @corneliouzbett found that trying to maintain this list caused ++ compute cost - because you see @icrc.psousa many sites do not use the “End Visit” feature, so many outpatient implementations have logic that auto-ends visits at midnight. Of course that doesn’t make sense for inpatient care.

I agree we should not be blocking folks from multi-day visits, and having that blocker in esm-core feels wrong to me - @dennis what do you think?

The backend allows you to have multiple day visits. Configuring Visits · GitBook

1 Like

A while ago we had > 6.4 million active visits list. The ActiveVisit app tried to load these records but it always crashed, so we limit the active visits list per location and “today’s” visits. I’d agree we should be supporting multiple-day visits. However, I’d recommend leveraging the backend paging in favor of data-table pagination.

1 Like


Auto-ending visits (just like deciding which visit a new encounter belongs) is an implementation-specific business rule. As such, we won’t be able to come up with one rule that meets everyone’s needs. Instead, the backend would ideally implement the most common approach using a strategy pattern so implementations can easily override the behavior with their custom business rules.

1 Like

@dkayiwa do you mean that if we don’t check the “Start auto close” option we should be able to create multi-day visits ? I check our configuration and it’s not checked

The backend supports multi-day visits, but the hook @icrc.psousa points to makes it so those visits are effectively “invisible” to the frontend.

Basically, to echo what @burke said, we probably need an API endpoint that can be called with a patient and return the active visit(s) for the patient, but allowing an implementation to supply whatever logic it wants to use to determine the “active” visit (the current “includeInactive” basically excludes visits where the stopDatetime is prior to the moment the query is run—which brings up another class of valid visits our current frontend would be unable to “see”, namely those that are active but with a scheduled end time).

PS This broader support for “the current visit for the current patient” is orthogonal to the “Active Visits” list. There is some additional frontend logic necessary, e.g., to support useVisit correctly returning the current visit, even if that’s a past visit (to support retrospective data entry).

To be clear, I did not mean to imply that implementations come up with their own definition of active visits (visits are still active until end date is set and in the past); rather, that implementation business logic be used to auto-end visits (i.e., optionally set the end date on visits either in a scheduled task and/or when active visits are requested).

We should still be able to rely on judging active visits by the start & end dates.

Well, I’m actually thinking there may be context-specific ways for implementations (who care about it) to determine the “active” visit for a patient based on implementation-specific logic. The way we ended up with this hook (AFAICT) is that AMPATH uses visits, but mostly without any end-dates. Consequently, most visits are (from the perspective of our default logic) “active”. However, since AMPATH services are generally outpatient settings, the only relevant visit is that from the current day, hence the logic currently embedded in the frontend. My suggestion is more for having a way to enable implementations to make these context-sensitive decisions without the current hard-coding we have. (See also Bett’s remark about having 6.4 million “active” visits).

@burke or @dkayiwa I need your help here - can you create a Platform ticket for this API work required, and estimate the lift? Then @frederic.deniger can review it; he’s interested in possibly assigning one of his developers to this.

So @icrc.psousa, do you want to explicitly or manually (by clicking End Visit) end the visits after the multiple days?

@dkayiwa Yes, for ICRC we would like the visit to only be ended when explicitly requested, either by the user on the UI or by some action triggered on our distro, for example, after filling in a certain form.

@icrc.psousa that should be available if you do not enable the Start auto close visits task

@dkayiwa correct, we’re using Start auto close visits task cfg as disabled. It’s working as expected for O2 but, on O3, at least, the frontend seems not to be prepared. e.g.: openmrs-esm-core/useVisit.ts at 8f1b7f54330e70f5b420fc2f6685b4e334bcfbb2 · openmrs/openmrs-esm-core · GitHub

I know implementations will have implementation-specific business rules governing when visits should remain active. My concern is trying to depend on and properly implement this custom business logic everywhere it is needed. Instead, it seems a lot more scalable to use that custom business logic to populate the visit’s end date and let every downstream process treat active visits as any without an end date.

For example, any reports, decision support rules, encounter filters in FHIR, etc. would have to implement the same business logic to infer active visits. And that logic would need to be designed not only to get active visits, but also to return inactive visits. Instead, if we focus the implementation-specific business logic to populating visit end date, these become simply date_stopped is null and date_stopped is not null.

Even with 6.4 million visits, once the code is in place to properly end visits prospectively, it’s not that hard to “fix” all the existing data with something like

UPDATE visit
SET date_stopped = DATE_ADD(date_started, INTERVAL 1 DAY)
WHERE date_started IS NOT NULL
      AND date_started < DATE_SUB(CURDATE(), INTERVAL 1 DAY);
1 Like

So, yeah, I agree that fixing the date stopped thing is pretty straight-forward. I think, though, that there are other circumstances in which having a straight-forward way to use a strategy pattern to determine the “active” visit would make sense, e.g., to handle the case where there are overlapping active visits or other business logic implementations might have (e.g., patients who come into the HIV Clinic should always have a visit with the type “HIV Consultation” regardless of if there is another active visit).