Appointment

Introduction #

The Appointment model represents a single scheduled meeting from a patient, that may be in the future or past.

Basic usage #

To get an appointment by identifier, use the get method on the Appointment model manager:

from canvas_sdk.v1.data.appointment import Appointment

appointment = Appointment.objects.get(id="f53626e4-0683-43ac-a1b7-c52815639ce2")

If you have a patient object, the appointments for a patient can be accessed with the appointments attribute on a Patient object:

from canvas_sdk.v1.data.patient import Patient

patient = Patient.objects.get(id="1eed3ea2a8d546a1b681a2a45de1d790")
appointments = patient.appointments.all()

To get appointments part of a recurrence.

from canvas_sdk.v1.data.appointment import Appointment

appointment = Appointment.objects.get(id="f53626e4-0683-43ac-a1b7-c52815639ce2")

# parent appointment
parent_appointment = appointment.parent_appointment

# children appointments
children = parent_appointment.children.all()

Getting the reason for visit #

The reason for visit is recorded on the appointment’s note, not on the Appointment itself. Read the note’s ReasonForVisit records through its reasons_for_visit attribute. The Reason for Visit command has no commit step, so read the records directly rather than filtering for committed ones:

from canvas_sdk.v1.data.appointment import Appointment

appointment = Appointment.objects.get(id="b80b1cdc-2e6a-4aca-90cc-ebc02e683f35")
if appointment.note:
    reasons = appointment.note.reasons_for_visit.all()

Detecting rescheduled appointments #

What a reschedule looks like to a plugin depends on the operation used to move the appointment rather than on the surface the request came from. There are two shapes, and a plugin that needs to catch every reschedule has to handle both.

Cancel and create fires both APPOINTMENT_RESCHEDULED and APPOINTMENT_CREATED, each targeting the newly created appointment. The original appointment’s status is set to cancelled, and the new appointment’s appointment_rescheduled_from points back at it. This is what happens with:

  • The reschedule flow in the provider UI.
  • The reschedule flow in the patient portal.
  • The Appointment effect’s reschedule().

Listen for APPOINTMENT_RESCHEDULED rather than handling APPOINTMENT_CREATED and filtering on appointment_rescheduled_from. The purpose-built event already draws that distinction.

Update in place fires only APPOINTMENT_UPDATED. A single appointment record is modified, nothing is cancelled, no new appointment appears, and APPOINTMENT_RESCHEDULED does not fire even though the appointment moved to a different time. This is what happens with:

  • The Appointment effect’s update() carrying a new start_time.
  • A FHIR API appointment update, which changes the appointment’s attributes to comply with FHIR.

The SDK can produce either shape, so which one your plugin sees depends on what the calling code chose. A plugin that has to catch every move of an appointment needs to handle both APPOINTMENT_RESCHEDULED and APPOINTMENT_UPDATED.

Filtering #

Appointments can be filtered by any attribute that exists on the model.

Filtering for appointments is done with the filter method on the Appointment model manager.

By attribute #

Specify an attribute with filter to filter by that attribute:

from canvas_sdk.v1.data.appointment import Appointment, AppointmentProgressStatus

appointments = Appointment.objects.filter(status=AppointmentProgressStatus.CONFIRMED)

Filtering by External Identifiers #

To query Appointments by external identifiers, the external_identifiers relation can be used with double-underscores to identify values stored on the AppointmentExternalIdentifier model. For example:

from canvas_sdk.v1.data.appointment import Appointment

appointment = Appointment.objects.filter(
    external_identifiers__system="COMPANY_IDENTIFIER",
    external_identifiers__value="ejNoTa5vKzoT9oSjg87MVB").first()

Attributes #

Appointment #

Field NameType
idUUID
dbidInteger
createdDateTime
modifiedDateTime
entered_in_errorCanvasUser
patientPatient
appointment_rescheduled_fromAppointment
parent_appointmentAppointment
providerStaff
start_timeDateTime
duration_minutesInteger
commentString
note_idInteger
note_type_idInteger
statusString
meeting_linkURL
telehealth_instructions_sentBoolean
locationPracticeLocation
descriptionString
external_identifiersAppointmentExternalIdentifier[]
metadataAppointmentMetadata[]
childrenAppointment[]
appointment_rescheduled_toAppointment[]
labelsTaskLabel[]

AppointmentExternalIdentifier #

Field NameType
idUUID
dbidInteger
createdDateTime
modifiedDateTime
useString
identifier_typeString
systemString
valueString
issued_dateDate
expiration_dateDate
appointmentAppointment

AppointmentLabel #

The join between an appointment and a TaskLabel. Reach the labels on an appointment through its labels attribute rather than querying this model.

Field NameType
dbidInteger
appointmentAppointment
task_labelTaskLabel

AppointmentMetadata #

Field NameType
idUUID
dbidInteger
createdDateTime
modifiedDateTime
appointmentAppointment
keyString
valueString
from canvas_sdk.v1.data.appointment import Appointment
from logger import log

appointment_id = "f53626e4-0683-43ac-a1b7-c52815639ce2"
appointment = Appointment.objects.get(id=appointment_id)
appointment_metadata = appointment.metadata.all()

for metadata in appointment_metadata:
   log.info(f"Appointment metadata: {metadata.key}, {metadata.value}")