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 newstart_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 Name | Type |
|---|---|
| id | UUID |
| dbid | Integer |
| created | DateTime |
| modified | DateTime |
| entered_in_error | CanvasUser |
| patient | Patient |
| appointment_rescheduled_from | Appointment |
| parent_appointment | Appointment |
| provider | Staff |
| start_time | DateTime |
| duration_minutes | Integer |
| comment | String |
| note_id | Integer |
| note_type_id | Integer |
| status | String |
| meeting_link | URL |
| telehealth_instructions_sent | Boolean |
| location | PracticeLocation |
| description | String |
| external_identifiers | AppointmentExternalIdentifier[] |
| metadata | AppointmentMetadata[] |
| children | Appointment[] |
| appointment_rescheduled_to | Appointment[] |
| labels | TaskLabel[] |
AppointmentExternalIdentifier #
| Field Name | Type |
|---|---|
| id | UUID |
| dbid | Integer |
| created | DateTime |
| modified | DateTime |
| use | String |
| identifier_type | String |
| system | String |
| value | String |
| issued_date | Date |
| expiration_date | Date |
| appointment | Appointment |
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 Name | Type |
|---|---|
| dbid | Integer |
| appointment | Appointment |
| task_label | TaskLabel |
AppointmentMetadata #
| Field Name | Type |
|---|---|
| id | UUID |
| dbid | Integer |
| created | DateTime |
| modified | DateTime |
| appointment | Appointment |
| key | String |
| value | String |
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}")