Affects versions: None
Fix versions: 2.0
This project will enhance reminder generation to:
- support multiple delivery methods per reminder
- improve error handling and resending
- improve performance
When sending reminders, customer contact preferences and rules determine how reminders are sent. The rules that determine how reminders are sent are inflexible, making customisation difficult.
This project will change the Reminder Type templates to allow:
- up to 5 rules to be specified to indicate how reminders should be processed. Rules will be evaluated in order, and the first rule that is satisfied determines how the reminder is processed.
- multiple reminders to be sent (e.g. send both an email and/or an SMS)
Each rule will contain the following options, one or more of which may be selected:
- Contact - use the customer's reminder contact(s). Can have multiple.
- Print - using the customer's preferred Location contact (or first location if no preferred), print the reminder for posting to the customer
- Email - using the customer's preferred Email contact (or first if no preferred), email the reminder to the customer
- SMS - using the customer's preferred Phone contact (or first if no preferred) with Allow SMS enabled, send the reminder via SMS
- List - the reminder will be listed on the Patient Reminders Report
- Export - the reminder will be included in the exported CSV file
- Send To - may be one of:
- All - send to all specified contacts.
If a customer doesn't have a contact, then the rule isn't satisfied.
E.g. if both Email and SMS is selected, the rule is only satisfied if the customer has both Email and SMS contacts. This is the default.
- First - send to the first matching contact.
E.g. if both Email and SMS is selected, the rule is satisfied if the customer has either contact.
The precedence is Email > SMS > Print
- Any - send to any matching contact. If a customer doesn't have a contact, then the rule isn't satisfied.
E.g. if both Email and SMS is selected, the rule is satisfied if the customer has either contact, and the reminder will be sent to each one
- All - send to all specified contacts.
If no rule is satisfied, then the Reminder will be processed as per List.
E.g. A Reminder Type might specify the following:
- Reminder Count = 0
- Rule 1: Contact, Send To = All
- Rule 2: Email,SMS, Send To = All
- Rule 3: Print, Send To = All
- Reminder Count = 1
- Rule 1: SMS, Print, Send To = Any
In the above, the first reminder will be sent:
- to all reminder contact(s) if there are any; else
- via SMS, if the customer has a phone contact with Allow SMS set AND by Email if the customer has an email contact; else
- via Print, if the customer has a location contact; else
- it will be Listed
The second reminder will be sent:
- via SMS, if the customer has a phone contact with Allow SMS set and/or via Print, if the customer has a location contact; else
- it will be Listed
Multiple rules may be selected. If Contact and Print is selected, and both correspond to to the same customer contact, a duplicate is not created.
Each delivery method will have a lead time, indicating how long before a reminder is due it should be sent.
It will also have a cancellation time, indicating the time after its lead time that it should no longer be sent.
- Print reminders may have a lead time of 2 weeks, and a cancellation time of 1 weeks
- SMS reminders may have a lead time of 3 days, and a cancellation time of 3 days
These times apply globally.
When reminders are processed, the longest lead time will be selected to determine which reminders to process.
At present, reminders may on be grouped by customer by setting a Group flag in the reminder type.
This will be changed so that the reminder type has a Group By setting, with the following options:
- None - do not perform grouping for this reminder type
- Customer - group reminders by customer
- Patient - group reminders by patient
At present, all reminders are processed interactively. This is time-consuming, and the options for handling failures are limited.
This will be changed so that reminder processing is split into 3 phases, two of which are automatic:
- Phase 1 queues reminders according to their delivery methods
- Phase 2 sends queued email and SMS reminders
- Phase 3 is a manual process for queued print, export and list reminders
Note that Phase 2 is optional. Email and SMS reminders can be sent interactively, if required.
The first phase is performed by a background job that will run and queue reminders for email, SMS, print, export and/or list. This job will process all reminders due <= now + the maximum lead time.
E.g. if print reminders have a lead time of two weeks, the job will process all reminders with a due date less than now + 2 weeks.
This will produce states for each reminder and delivery method, with a start time prior to their due date, based on the lead time for the delivery method.
For each reminder it will look at the rules for the reminder type and reminder count and determine which delivery methods will be used, based on the customer's contacts.
- Email, it will create an act.patientReminderItemEmail
- SMS, it will create an act.patientReminderItemSMS
- Print, it will create an an act.patientReminderItemPrint
- Export, it will create an act.patientReminderItemExport
- List, it will create an act.patientReminderItemList
Each act will have its:
- status set to PENDING
- startTime set to due date - lead time.
E.g. an SMS reminder due on 12/10 with a lead time of 3 days would be given a start time of 9/10.
If no reminder states are created for a reminder count, the reminder next due date is updated to the next due date.
If there is no next due date, the next due date is set to due date + cancellation interval. This allows the reminder to be displayed for the patient, until the cancellation due date has passed.
On completion of the job, it will send a notification to the job user of number of reminders states processed, and any errors encountered.
The second phase is optional. It is performed by a background job that sends reminders queued for email and SMS. This second job should be scheduled during business hours, to avoid sending messages at anti-social times.
This processes all reminders queued with a lead time less than or equal to today. Any reminder that is queued but has passed its cancel time will have its status set to ERROR.
If a reminder states is processed successfully and there are no other PENDING or ERROR states for the same reminder count, the reminder due date is updated to the next due date.
If there is no next due date, the reminder due date is set to the due date + cancellation interval.
The third phase is performed via Reporting - Reminders. Here, users will process queued reminders..
See Reporting - Reminders Workspace below.
Reminders are grouped by date, customer and patient.
Those reminders for a particular customer that fall on the same date are inspected to see if they have reminder types that have a Group By setting. Those that have Group By set to Patient, are processed first, per patient. The reminders that have Group By set to Customer, are processed next. The remaining reminders are processed individually.
At present, charging a product with a reminder sets the status of any any reminders with the same reminder type to COMPLETED.
This will need to be changed to update any states associated with the reminder with PENDING or ERROR status to COMPLETED, so they are no longer candidates for processing.
The existing Reminders workspace will be changed Include the following tabs:
- Send - sends queued reminders and provides the option to resend all types.
- Errors - displays reminder state acts with ERROR states
The Send tab allows Reminders that have been processed by the background job to be sent or resent.
It will provide:
- a Type dropdown to filter reminders by delivery method (i.e. act.patientReminderPrint, act.patientReminderSMS etc)
- a Status filter:
- Incomplete - alias for PENDING and ERROR
- Complete - reminders that have been processed previously.
- date/time range
The time range is required when re-processing prior states.
By default, the filter will display all Incomplete acts.
Acts will be displayed in a table containing:
- Run Date - this is for the purposes of filtering on startTime, and represents the date when the reminder state was queued for send.
- Due Date - the reminder due date
- Reminder Type - the reminder type
- Reminder type
- Reminders Sent - corresponds to the reminder count
- Last Sent - TODO - not sure if this should be from the reminder or the reminder state
- Error - the error message if the last attempt to print or send failed
It will provide a:
- Send button, to process the selected reminder state
- Send All button, to process all reminders selected by the date range and status filter, for a single state type.
I.e. it will not process both print and export states
This process reminders by customer, in order to support grouped reminders.
- Complete button - to mark the selected reminder state as COMPLETED, without performing any processing
- Complete All button - marks all reminder states matching the filter as COMPLETED without performing any processing.
- Label button, to print a mailing label for the selected Print reminder state. This only applies when the Status filter is set to Print
- Label All button, to print mailing labels for all Print reminder states
Both the Send and Send All buttons work as follows:
- Interactively print act.patientReminderItemPrint states
- Email act.patientReminderItemEmail states
- SMS act.patientReminderItemSMS states
- Generate and display a print dialog of act.patientReminderItemList states. This can be used to print, email or export listed reminders..
- Generate and download a CSV for act.patientReminderItemExport states
Once a reminder state is processed successfully:
- the reminder state status is set to to COMPLETED*
- any error is cleared.
- the reminder is linked to any communication log, if logging is enabled.
For grouped reminders, one log entry is created per reminder.
- and there are no other PENDING or ERROR states for the same reminder count, the reminder due date is updated to the next due date.
- If there is no next due date, the reminder due date is set to the due date + cancellation interval.
The Errors tab is essentially the same as the Send tab, but only displays reminder states with ERROR status.
It is provided as a convenient way to display all errors.
To support grouped reminder reporting, a function will be required that can process multiple reminders and list the:
- distinct patient names
- reminder type names
- replace text if it is too long for SMS
- reminder:names(listOfReminders, '& ') -> Fido & Spot
- reminder:types(listOfReminders, '& ') -> Vaccination & Check Up
- expr:replaceIf(reminder:names(listOfReminders, '& '), 50, 'Your pets') -> replaces the text produced by reminder:names() with 'Your pets' if the text is longer than 50 chars
This would allow a template to do produce text like "Fido & Spot are due for Vaccination & Check Up"
At present, reminders sent via emails are sent with an attachment containing the list of reminders. With the new HTML email support in 1.9, it is possible to include the reminders directly in the email body, without any attachment.
This should be possible for both single and grouped email reminders.
To suppress inclusion of the attachment, the Reminder Job will include a flag Email Reminders as Attachments to indicate if attachments are required. This is true by default to indicate the 1.9 behaviour. If false, the:
- Email Template associated with the reminder type template will be used to generate the email content, for single reminders
- Email Template associated with the grouped reminder template will be used to generate the email content, for grouped reminders
In 1.9 grouped SMS reminders are not supported. A single SMS will be sent to the customer, for one of the reminders.
The reporting functions above will allow the SMS template associated grouped reminder template to generate text including multiple patients and reminders.
The Resend Reminder dialog in Medical Records -> Reminders lists reminder counts and available customer contacts to send to.
If there is an existing state record for the reminder count, this will be updated when the reminder is sent, and the status set to COMPLETED. This handles reminders that have PENDING or ERROR status.
If the reminder state was PENDING or ERROR, and there are no other PENDING or ERROR states for the same reminder count, the reminder due date is updated to the next due date.
If there is no next due date, the reminder due date is set to the due date + cancellation interval.
If there is no state record for the reminder count, one will be created. This will only occur if customer contacts have changed.
If there is no rule for the selected contact, the reminder will be listed.
Communication log records will be linked to the reminder state, if communication logging is enabled.
Any report or document template that includes the startTime (i.e. creation date) of the reminder will need to be updated.
The existing reminder functions that return reminders based on startTime need to be changed to filter by createdTime. Until this is an indexed field, the reminders returned by these functions will need to be filtered in memory.
To support multiple delivery methods, the existing Reminder Type Template (a relationship between an entity.reminderType and entity.documentTemplate) will need to be replaced by a new archetype, entity.reminderCount. The entity.reminderType will change to include the following:
- reminderCounts - relationships to one or more entity.reminderCounts
- groupBy - one of NONE, CUSTOMER, PATIENT
The entity.reminderCount archetype includes the following:
- count - the reminder count
- rules - relationships to one or more entity.reminderRule
- template - optional template, required if one of the entity.reminderRules is SMS, Email, or Print
The entity.reminderRule archetype will contain flags indicating how the reminder should be processed:
- contact - use the customer's reminder contact or if none defined, use their preferred contact, or if none defined use the first available contact
- print - using the customer's Location contact, print the reminder for posting to the customer
- email - using the customer's Email contact, email the reminder to the customer
- sms - using the customer's Phone contact with Allow SMS enabled, send the reminder via SMS
- list - the reminder will be listed on the Patient Reminders Report
- export - the reminder will be included in the exported CSV file.
- sendTo - one of ALL, FIRST, or ANY. Only applies when one or more of contact, print, email or sms is selected
The following acts will be created to store delivery method state:
- act.patientReminderItemEmail - indicates reminder delivery via email
- act.patientReminderItemSMS - indicates reminder delivery via SMS
- act.patientReminderItemPrint - indicates reminder was printed for posting
- act.patientReminderItemExport - indicates that the reminder was exported
- act.patientReminderItemList - indicates that the reminder was listed for phone call
Each will have the following nodes:
- startTime - indicates when the act needs to be processed by.
- endTime - indicates the due date of the reminder for the reminder count
- reminderCount - the reminder count that the state is for
- status - the current status. One of
- PENDING - the reminder is yet to be processed
- COMPLETED - the reminder has been successfully processed
- ERROR - the reminder failed to process.
E.g. failed to be sent due to email server error etc. The error node will contain the reason
- error - the error message when status is ERROR
The act.patientReminder archetype will be updated to include:
- items - link to zero or more delivery methods (act.patientReminderItemEmail, act.patientReminderItemSMS, act.patientReminderItemPrint, act.patientReminderItemExport, act.patientReminderItemList)
The entity.reminderConfigurationType is an archetype linked via the practice, used to determine lead times for delivery methods.
It will contain the following nodes:
- emailInterval - lead time interval for emails. Defaults to 3
- emailUnits - lead time interval units for emails. Defaults to DAYS
- emailCancelInterval - time interval when emails should no longer be sent. Defaults to 1
- emailCancelUnits - time interval units when emails should no longer be sent. Defaults to DAYS
- smsInterval - lead time interval for SMS. Defaults to 3
- smsUnits - lead time interval units for SMS. Defaults to DAYS
- smsCancelInterval - time interval when SMS should no longer be sent. Defaults to 1
- smsCancelUnits - time interval units when SMS should no longer be sent. Defaults to DAYS
- printInterval - lead time interval for print. Defaults to 2
- printUnits - lead time interval units for print. Defaults to WEEKS
- printCancelInterval - time interval when print reminders should no longer be sent. Defaults to 5
- printCancelUnits - time interval units when print reminders should no longer be sent. Defaults to DAYS
- exportInterval - lead time interval for export. Defaults to 2
- exportUnits - lead time interval units for export. Defaults to WEEKS
- exportCancelInterval - time interval when export reminders should no longer be sent. Defaults to 5
- exportCancelUnits - time interval units when export reminders should no longer be sent. Defaults to DAYS.
- listInterval - lead time interval for export. Defaults to 3
- listUnits - lead time interval units for export. Defaults to DAYS
- listCancelInterval - time interval when list reminders should no longer be sent. Defaults to 1
- listCancelUnits - time interval units when list reminders should no longer be sent. Defaults to DAYS.
The entity.jobConfigurationReminderProcessor will be used to queue reminders for the first phase of reminder processing.
The entity.jobConfigurationReminderSender will be used to send email and SMS reminders for the second phase of reminder processing.
Reminder processing performance will be improved by storing the 'next due date' in the startTime of act.patientReminder.
This means that:
- the 'next due date' is not calculated as part of reminder processing. At present many reminders are loaded and then discarded as their due date is calculated to be in the future by virtue of the fact that they are on a reminderCount > 0.
- an appropriate database index can be used.
At present the endTime of the reminder is used to filter reminders, which is not indexed.
The creation date of the reminder, currently held in startTime, will need to be stored in a createdTime node.
- the existing startTime needs to be moved to a createdTime node
- reminders will need to have their 'next due date' calculated in SQL based on the current reminderCount and the reminder type.
- the existing entityRelationship.reminderTypeTemplate needs to be migrated to entity.reminderCount and entity.reminderRule instances
- the entity.reminderType group node needs to be migrated to groupBy
- the existing act.patientReminder error node will be removed
- existing reminder reports