Proposal for Adding Location and Provider Support to BillableService in OpenMRS Billing Module

Hi folks,

In the current implementation of the OpenMRS Billing (Cashier) module, when creating a BillableService via POST /rest/v1/billing/billableService

the payload does not support associating a service with a specific location or provider.

Example (current payload)

{
  "name": "Consultation by Doctor Doe",
  "shortName": "CDJ",
  "serviceType": "167410AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "servicePrices": [
    {
      "paymentMode": "ace025cb-504d-45f6-a868-9018cbb9704d",
      "name": "Cash",
      "price": 100
    }
  ],
  "serviceStatus": "DISABLED",
  "concept": "2f4e6a8b-1c3d-4e5f-9a7b-8c0d1e2f3a4b"
}

Problem Statement

The current billing implementation lacks flexibility for multi-site and provider-based workflows.

  • No linkage to location (facility or department) — Services are defined globally and not tied to where they’re provided. In the current implementation, a single “Consultation” service applies to all locations, even though pricing, reporting, or workflow may differ across departments (e.g., OPD vs IPD).
  • No linkage to provider — The system doesn’t track or differentiate which provider performs the service. This makes it impossible to uniquely represent or bill for “Consultation by Dr. John” vs “Consultation by Dr. Mary.”
  • Reporting and filtering are limited — Because services aren’t linked to location or provider, it’s difficult to filter per site, provider, or department.

cc @ibacher @dkayiwa @dkigen

I think this is a bit of a category confusion. A billable service is a service of some sort for which there is a price, so something like “Consultation” or maybe “Physician Consultation” are sensible billable services, but tying those to instance-specific details like where the service was provided and by whom needs to be a different object storing that. If it belongs anywhere, the closest thing in the billing module currently is a BillLineItem, which is a charge for a specific service provided.

That said, I’m not sure this is a good fit for BillLineItem either. So let’s focus on the higher level question, instead of focusing on where this goals, what are we trying to accomplish with this? You mention reporting, but what are we reporting and why? For most clinical services, it seems that the provision of that service shouldn’t be a billing concern at all, i.e, if we just wanted to know “How many consultations did Doctor Doe do last month?” more properly we probably need a consultation form that Doctor Doe is required to fill out (and it maybe that filling in that form creates a BillLineItem in a bill for that service or something, but that’s secondary).

That is to say, billable services link a name / concept and some metadata about a service to a price. Bill line items are a charge on a receipt (and maybe as an enhancement we should potentially allow a “Bill line item” to have a nice name like “Consultation with Doctor Doe” instead of just “Consultation”), but I this seems like an attempt to shovel data into the billing model that doesn’t really belong there.

A better solution might be to be able to link a BillLineItem to an encounter or something like that, if that’s what we decide is the place to store a consultation. But basically, let’s back up and focus on the high-level goal here: what are you trying to accomplish that isn’t possible in the system today?

1 Like

Basically A scenerio we had that exposed this issue was

"Dr. John (an authorized user) logs in to bill a patient and sees “Basic Consultation.” To make it easier to identify, he renames it to “John’s Standard Consult.” Because BillableService is globally shared, this change instantly propagates to every user.

Now Dr. Ben logs in on the other end of the hospital and suddenly sees “John’s Standard Consult” instead of “Basic Consultation.” There’s no trace of who changed it, and the naming inconsistency creates confusion across sites."

All in all We wanted to support richer traceability around who performed a service, where it was performed. To support filtering on our end by Location, without duplicating billing logic.

Reading your response makes sense @ibacher however my question would be what best appoach could be taken in such a scenerio?

I’m still kind of going back to: where do we need “John’s Standard Consult” to be? Why would Dr. John be authorized to change billable services rather than bills?

(The database will track in the changedBy field who changed it or you could install the auditlog module if the concern is just tracking who changes that).

But I don’t really see how locations and all the rest of it fits in?

So the problem you’ve described above doesn’t really seem like something we should be fixing by changing the BillableService model itself. The problem you have is, roughly, Dr. A wants the text of the service to read one thing and Dr. B wants it to read another.

The first thing here is to ask: why does either Dr. A or Dr. B have the privileges to change the name of a billable service? That seems off. But assuming Dr. A really needs a “Dr. A Consult”, then you can just create a new billable service with that name. If you need to restrict who can see that billable service in the drop-down, maybe data filter is the way to do it?

The problem is this seems to be proposing adding new fields to the BillableService object to implement some very clinic-specific business logic. I think maybe what we can do is modify BillableService to be attributable and then in your instance you’d be able to add attributes or something that would meet your need; you’d still likely need to build out some custom code to handle the business logic, but that’s mostly because I can’t see a general enough business rule we’d need at many different implementations here.

It’d be one thing if we were talking about adding, e.g., location because “Clinical Consult” is €10 in clinic A and €15 in clinic B.

1 Like