Recurring Appointments in Appointment Module

Hello, The approach for

Recurring appointments:

  • Have a “registerGenerator(AppointmentNumberGenerator)” method - this will allow others to wire up such an implementation from their modules.

  • Modify appointments creation api and add additional params- recurring type, number of occurrences and recurring days (for weekly only)

Same appointment number will be given for all recurring appointments

@pramidat @angshuonline @swathivarkala @binduak

for … "same appoint number will be given … ", try to provide an extensible way for that as well.

Generating an appointment number, may have other logics, and we should not assume that the same number will be valid. For example, if someone provides a generator which generates unique numbers but only for the day, then reassigning the same number may not work.

Maybe something like below?

public interface AppointmentNumberGenerator {
   String create(Appointment apptTobeCreated, Optional<String> prevApptNumber);

}

Hi @angshuonline ,

The idea is to make a single API call which would create all the recurring appointments. We will need to have a common appointment number for all recurring appointments so that we can implement future functionalities like edit or cancel of that recurring appointment in entirety. A common appointment number is the logical link to group together all the recurring appointments. So, the extensibility will be provided to generate a custom appointment number, which will be common across all recurring appointments.

Ok. I understand that you are trying to use the “Appointment number” to tie all the appointments together. My point

  • is that generation of appointment number for a new one or reassign (group appointments) should be left to implementation. Therefore think of an injectable interface instance, which can customize both.
  • Lets not assume that same “Appointment Number” will be applicable.

Question:

  • the effected appointments (group) will be “voided”? or will you just edit the existing ones?
  • if you are not voiding and just editing the existing records, please add an entry in the appointment audit table “patient_appointment_audit” appropriately.
  • How have you thought of the web endpoint? for creation of series and also change for a series? For example, are you thinking of a different Web endpoint to accept list of “appointments”? Or will you modify the existing API to accept more information? What would you do for editing effected appointments?

For generation of appointment number, assuming, AppointmentsServiceImpl have a “AppointmentNumberGenerator” reference.

  • AppointmentsService Interface should have a “register(AppointmentNumberGenerator)”
  • AppointmentsServiceImpl should probably invoke “appointmentNumberGenerator.create(newappointment)” - e.x from here

(obviously this would be effected how you devise the interactions to the Web endpoint)

Hi @angshuonline,

As already mentioned we will make the appointment number generation logic pluggable, but it would be same for one give set of recurring appointments.

Answers:

  • the effected appointments (group) will be “voided”? or will you just edit the existing ones? --> It would behave in the same manner as the existing appointments with an additional option of cancelling one or all in that group of recurring appointments

  • if you are not voiding and just editing the existing records, please add an entry in the appointment audit table “patient_appointment_audit” appropriately. --> does this happen for appointments today?

  • How have you thought of the web endpoint? for creation of series and also change for a series? For example, are you thinking of a different Web endpoint to accept list of “appointments”? Or will you modify the existing API to accept more information? What would you do for editing effected appointments? --> We are thinking of reusing the existing endpoint and have few additional params (recurring type, number of occurrences and recurring days (for weekly only))

Hi,

In PAT call on 24th April (Bahmni PAT call 24th April 2019), the following approaches were spoken about:

  1. Adding a new column called ‘parent_appointment_id’ to ‘patient_appointment’ table. With this approach, we can get all past occurrences of an appointment, even when its recurrence pattern has been changed. It also becomes easier to cancel a set of appointments.

  2. Appointment Number: A unique appointment number for a specific set of ‘recurring appointments’. With this approach, we are not making the model clear enough for a developer to understand the logic out of the box, as we are overloading the appointment number with a responsibility it is not responsible for.

We would like to suggest the 1st approach, as it is independent and does not club with the logic of Appointment number generation. Giving the liberty to the system to use Appointment Number for just identifying an appointment.

@angshuonline @ramses @binduak @sowmika

1 Like

Hi - sorry to jump in late - does Bahmni use the OpenMRS Appt Module in your backend? At AMPATH (and I believe PIH too) we’re interested in the ability to create recurring appointment blocks that essentially match the very nice mockups you’ve presented.

I suspect canceling/editing a repeating appt would be similar to typical Calendar App - with ability to cancel or edit only that occurrence, or all future ones

cc: @mogoodrich @darius @jecihjoy @jdick

Bahmni uses it’s own module for appointments.

Hi, Attaching the document describing the way we are planning to functionally implement the edit functionality for recurring appointments. Two thumb rules are:

  • Edit this appointment
  • Edit this and following appointments

Also at any point of time we will not edit past appointments.

FUNCTIONALITY DETAILS - RECURRING APPOINTMENTS.pdf (90.6 KB)

@snehabagri @binduak @angshuonline @ramses @gschmidt @sravya @megkmcguire @abhinavpc @vmalini @mohitd

Seems good.

  • would like to see some mockups to visualize.
  • can you please specify what would be the API and model change for that
  • any change in appointment, hopefully you will be writing to the audit logs as well.
  • caution about editing: change of metadata (like speciality, type etc) - constitute cancellation and re-creation of appointments - are we respecting that.
  • keep in mind of future tractability as well. e.g. Notification - how would I notify someone that their previous appointment is now rescheduled?

Let me know if you want to discuss over slack or zoom

Hi,

Attaching the documents with model changes and how data gets modified on editing appointments.

Technical Details - Recurring Appointments.pdf (407.0 KB)

As per discussion with Angshu, we are fine with the functional approach for edit.

We need to finalize the database model and the API structure.

The data model should be designed keeping in mind that the Notifications can be implemented easily in future.

The API should follow FHIR model, but looks like FHIR does not provide it out of box and we need to extend it. Talk thread here - http://community.fhir.org/t/recurring-appointments/1321.

There is no recurring appointment concept in FHIR (but you can always use an extension to main contract, as suggested by FHIR guys).

Not to say, that I am suggesting that you stick to FHIR format, but you can take ideas from there.

You could just add another object as part of the “appointment-create-request” POST

Check: http://hl7.org/fhir/datatypes.html#timing

This should cover all aspects of your multiple occurances. You may not use the entire definition, but this should meet your needs

Sure, if we need to extend it can we do it like below just for the recurrence part of it:

    {
   
    "frequency" : "<positiveInt>",// no. of occurances
    "period" : "<decimal>", // repetition interval 
    "daysOfWeek" : ["<code>"],  // week days
    "endDate" :"", // date for the appointment to end
    "type":"" // DAY, MONTH or WEEK
 
}

As per the discussion with Angshu on the model and api, we have come to the following agreements:

1. The current technical model is good, with the following changes:

  • Rename ‘appointment_recurrence_map’ table to ‘patient_appointment_occurrence’.
  • Rename ‘appointment_recurrence_pattern’ table to ‘patient_appointment_timings’ ', hence the primary key will be now called ‘patient_appointment_timings_id’
  • Pass the type of recurrence as enum values (eg. 1 for DAY, 3 for MONTH & 2 for WEEK), handled in code. No need of an additional table called ‘appointment_recurring_type’.
  • If we have needs to encode date in data (e.g MONDAY) etc - use String (MONDAY, TUESDAY) instead of using 1, 2 etc.

2. Have API to return just one instance of that recurring appointment and another API to return the series of all recurring appointment.

3. The above API request body looks good. The final request body would look like below eg:

{
  "appointmentDetail": {
    "patientUuid": "f0d06506-8071-4ec4-a528-31cad0dff9dd",
    "serviceUuid": "7b200662-e21a-488c-8274-4eff81117608",
    "startDateTime": "2019-05-14T05:30:00.000Z",
    "endDateTime": "2019-05-14T06:30:00.000Z",
    "locationUuid": "8d6c993e-c2cc-11de-8d13-0010c6dffd0f",
    "appointmentKind": "Recurring"
  },
  "recurringPattern": {
    "frequency": "5",
    "period": "1",
    "daysOfWeek": [],
    "endDate": "",
    "type": "DAY"
  }
}

@angshuonline @vmalini @shivarachakonda @vvinay @sowmika @binduak @sravya @ramses @abhinavpc @megkmcguire @mohitd @jinal

1 Like

Hey,

Here is the updated technical documentation of the recurring appointments data model. This is the final model and we are going to develop the same…

Updated Technical Details - Recurring Appointments.pdf (323.1 KB)

We would call the ‘patient_appointment_timings’ table as ‘patient_appointment_recurring_time’, as per the discussion on community slack channel.

Based on the past conversations, we have shared the mock-ups for developing this functionality: https://docs.google.com/presentation/d/1smSa9qH7DNFNN7w94umdetAXffsBu0lJouB5kqnCABM/edit#slide=id.g5ad73faae4_0_0

It covers the following:

  1. Context and use case for recurring appointments
  2. Assumptions we are making when creating recurrences, especially in case of weekly recurring appts (we have gotten these assumptions validated by many implementations)
  3. User flow for editing an appointment and managing conflicts for a recurring appointment, which follows the current logic of allowing a user to double-book a patient or let him/her book an appt when service is unavailable but alerts the user for the same

Do let us know if there are any further questions

CC: @snehabagri @vmalini @sowmika @bhiravabhatla @shivarachakonda @grssvinay

@angshuonline @rajashri @sravya

Looking at the mocks, I feel users (and dev teams) are going to struggle for real estate (especially on Bahmni’s min display requirement of 9"). In another thread, there is mention of relooking at the UI design for the appointment create/edit display. I feel we need to think through the design and layout and not just make the “repeat” patterns follow on in a single column layout.

As part of edit of recurring appointments we are planning to create a new PUT API as below: <HOST>/openmrs/ws/rest/v1/appointment?applyForAll=true/false

In the above API,

  • applyForAll = true means that the change should be applied to all the pending occurrences of recurring appointment.
  • applyForAll = false means that the change should be applied to that particular appointment.

Below is the sample request and response:

Request: (same as existing AppointmentRequest)
{
 "uuid": "5eebc88b-3ad5-4fd8-8a6b-ac1601a4c3d3",
  "patientUuid": "7023ee46-e2ec-40c4-8f55-15673209dbf0",
  "serviceUuid": "2b87edcf-39ac-4dec-94c9-713b932e847c",
  "serviceTypeUuid": "e7912578-bb5b-4617-ba45-28dd178b46de",
  "startDateTime": "2019-06-12T04:30:00.000Z",
  "endDateTime": "2019-06-12T05:00:00.000Z",
  "providers": [
    {
      "uuid": "8e482ebc-20e0-11e7-a53f-000c29e530d2",
      "response": "ACCEPTED",
      "comments": null
    }
  ],
  "locationUuid": "8de35e75-20e0-11e7-a53f-000c29e530d2",
  "appointmentKind": "Scheduled",
  "recurringPattern": {
    "frequency": 10,
    "period": 2,
    "type": "Day"
  }
}

Response: (edited appointments)
[
  {
    "uuid": "5eebc88b-3ad5-4fd8-8a6b-ac1601a4c3d3",
    "appointmentNumber": "0000",
    "patient": {
      "identifier": "IQ1230",
      "name": "CFE4BD7C CFE4BD80",
      "uuid": "7023ee46-e2ec-40c4-8f55-15673209dbf0"
    },
    "service": {
      "appointmentServiceId": 1,
      "name": "Physiotherapy OPD",
      "description": null,
      "speciality": {},
      "startTime": "",
      "endTime": "",
      "maxAppointmentsLimit": null,
      "durationMins": null,
      "location": {
        "name": "Physiotherapy",
        "uuid": "8de35e75-20e0-11e7-a53f-000c29e530d2"
      },
      "uuid": "2b87edcf-39ac-4dec-94c9-713b932e847c",
      "color": "#00CED1",
      "creatorName": null
    },
    "serviceType": {
      "duration": 30,
      "name": "1x session",
      "uuid": "e7912578-bb5b-4617-ba45-28dd178b46de"
    },
    "provider": null,
    "location": {
      "name": "Physiotherapy",
      "uuid": "8de35e75-20e0-11e7-a53f-000c29e530d2"
    },
    "startDateTime": 1560313800000,
    "endDateTime": 1560315600000,
    "appointmentKind": "Scheduled",
    "status": "Scheduled",
    "comments": null,
    "additionalInfo": null,
    "providers": [
      {
        "uuid": "8e482ebc-20e0-11e7-a53f-000c29e530d2",
        "comments": null,
        "response": "ACCEPTED",
        "name": "Ahmad Alrosan"
      }
    ]
  },
  {...................................
  }]```