Document History Event

Introduction #

The DocumentHistoryEvent model records the review history of a Lab, Imaging, Consult/Referral, or Uncategorized document. Canvas adds an entry each time staff reassign the document, add a comment, send it for signature, sign it, remove a signature, record the review, or enter the review in error. Together the entries form the timeline that the document’s history view shows.

Each entry stores who acted (actor), who received the document, any comment, and, for signed and recorded entries, whose signatures the document carried.

Basic usage #

To get a history entry by identifier, use the get method on the DocumentHistoryEvent model manager:

from canvas_sdk.v1.data import DocumentHistoryEvent

event = DocumentHistoryEvent.objects.get(id="0f6b3c2e-8a51-4d7e-9c14-5b2e7a9d3f60")

Getting a document’s timeline #

History entries link to their document through content_type and object_id, which is the document’s dbid. Resolve the ContentType at runtime from its stable app_label and model, rather than hardcoding its dbid:

from canvas_sdk.v1.data import ContentType, DocumentHistoryEvent, ImagingReport

report = ImagingReport.objects.get(id="3a5d8e21-6b4f-4c9a-8e27-1d9f0b6c4a73")
report_ct = ContentType.objects.get(app_label="api", model="imagingreport")

timeline = DocumentHistoryEvent.objects.filter(
    content_type=report_ct, object_id=report.dbid
).order_by("created")

The model values for the four reviewable document types are labreport, imagingreport, referralreport, and uncategorizedclinicaldocument, all with the app_label api.

To go the other way, from a history entry to its document, read the entry’s document property. It returns the entry’s LabReport, ImagingReport, ReferralReport, or UncategorizedClinicalDocument. On a recorded or entered_in_error entry, the review property returns the document’s review command:

from canvas_sdk.v1.data import DocumentHistoryEvent, DocumentHistoryEventType

recorded = DocumentHistoryEvent.objects.filter(event_type=DocumentHistoryEventType.RECORDED)
for entry in recorded:
    document = entry.document
    review = entry.review
    if document is not None:
        patient = document.patient

Filtering #

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

By event type #

from canvas_sdk.v1.data import DocumentHistoryEvent, DocumentHistoryEventType

comments = DocumentHistoryEvent.objects.filter(event_type=DocumentHistoryEventType.COMMENTED)

Signers of recorded documents #

from canvas_sdk.v1.data import DocumentHistoryEvent, DocumentHistoryEventType

recorded = DocumentHistoryEvent.objects.filter(event_type=DocumentHistoryEventType.RECORDED)
for event in recorded:
    signer_names = [staff.full_name for staff in event.signers.all()]

Entry types #

Event typeWritten whenPopulated fields
reassignedStaff reassign the document, including reviewer or team changes from the card’s dropdowns.recipient_staff and recipient_team hold the new assignment; comment holds any comment. actor is empty when the change came from an API client or a plugin.
commentedStaff add a comment without changing who holds the document.comment
sent_for_signatureStaff send a prepared form to a provider to sign. The document keeps its team.recipient_staff holds the provider and recipient_team the document’s team; comment holds any comment. A DocumentReviewDelegation records the same request.
signedThe provider holding the document signs it with SIGN FORM. When Canvas returns the signed form to its sender, or to the document’s creator, a reassigned entry follows.actor and signers hold the provider.
signature_removedStaff remove a signature from a signed form so they can edit it again. Canvas restores the version from just before signing.actor
recordedThe document’s review command is recorded. Recording again adds a new entry.signers, review_content_type, and review_object_id
entered_in_errorThe document’s review command is entered in error.review_content_type and review_object_id

When a review is entered in error, its recorded entry stays in the timeline, but its comment is hidden: deleted_at is set and comment_hidden returns True.

Attributes #

DocumentHistoryEvent #

Field NameType
idUUID
dbidInteger
createdDateTime
modifiedDateTime
content_typeContentType (the document’s type)
object_idInteger (the document’s dbid)
event_typeDocumentHistoryEventType
actorStaff (who acted, or empty for an API client or plugin)
recipient_staffStaff (who received the document)
recipient_teamTeam (the team that received the document)
commentString
review_content_typeContentType (the review command’s type)
review_object_idInteger (the review command’s dbid)
signersStaff[] (whose signatures the signed or recorded document carried)
deleted_atDateTime (when the comment was hidden)
comment_hiddenBoolean (computed; True when deleted_at is set)
documentLabReport, ImagingReport, ReferralReport, or UncategorizedClinicalDocument (computed; the entry’s document, or None)
reviewLabReview, ImagingReview, ReferralReview, or UncategorizedClinicalDocumentReview (computed; the review command of a recorded or entered_in_error entry, or None)

Enumeration types #

DocumentHistoryEventType #

ValueLabel
REASSIGNEDReassigned
COMMENTEDCommented
SENT_FOR_SIGNATURESent for signature
SIGNEDSigned
SIGNATURE_REMOVEDSignature removed
RECORDEDRecorded
ENTERED_IN_ERROREntered in error