Generate Reminders with optional escalation (to superiors)

Reminder Events uses the Messaging services to deliver its reminders. Your models can trigger reminders if it fulfills the following criteria.

  1. a Date or Datetime field, whose value is compared with the current time.
  2. a User field (to send reminders to). This can be left blank if you use Reminder Recipients to select at least one User instance. But this is required if you want to escalate to her superior.
  3. a status field which tells us that nothing has been done by User above after a specific period of days.

The Reminder is triggered based on a source Model instance which is still waiting for action by a User (specified in a field with a User foreign key). Waiting for action means a certain status value has not changed after a period of days from initiation. This can be a status code or balance unpaid amount.

You can optionally send reminders to the user’s superior by attaching an Application Hierarchy to the Reminder Event definition. The hierarchy will tell us who is the superior of the user in question.

Reminder Recipients are other users or external people you want to send the same reminder to. External people are not users of Maymyo and we can only send sms or email to them. You will need to use a Message Type that sends sms or email for this. External people could be found in another model that can be joined to your source model. For example, if your source model is the Billing Ledger (ie outstanding invoices) which has a Party field (ie the customer), then you can join to the Contact Persons of that Party to select one or more people to send sms or email to.

The sort of Models within Maymyo that can be used to generate reminders are like Workflow Document in-trays, Messages and Alerts, Business Rules awaiting authorisation, anything that involves a user and an action by that user.

When it does not involve users, then it may be an Invoice that has not been paid a number of days after (or before) its due date. We may want to send an email reminder to the Customer’s contact person. (However, our messaging service requires at least 1 user before it can send any external messages, so this person could be the Salesperson).

As part of the fixtures data, we have set up a daily scheduled job that generate reminders at 8pm every business day. You can either use this or disable it and add a generate reminders task to your own daily job.

How to configure a Reminder Event

It is best to illustrate this by using an example from Maymyo. We have a Workflow engine that it used for approval of Documents. A Document is mapped to a source model and it will track the approval stages that the document must go through. This Workflow Document will flow from the in-tray of each user it is assigned to throughout the workflow stages. If it sits for too long in somebody’s in-tray, then we want to generate a reminder to the assignee (and also her superior).

The first step is to decide on a Message Type to use for the reminder message. This will determine whether you send an alert or a normal message and in addition to that, send sms and/or email. You can reuse our standard Message Types.

The next step is to create a Message Template, which can use field values from your source document. The following shows our Message Template for Workflow Documents that is awaiting action by an assignee.

../_images/msg_tmpl.png

Maintain Message Templates

The Model Name should be your source model. In our case it is the Workflow Document model. The Message Text will be used for sending internal messages and sms. For emails, the Message Text will be used as the Subject while the External Message will be used for the email body.

You will notice the #self# and similar tokens. These will be replaced with actual values from the Workflow Document instance. #self# is a special field for the source model instance itself. It will be replaced with the unicode value as returned by the __unicode__ method of the model’s class. Other fields are like #workflow_type# or #submitted_by#. When a field is a foreign key field, then its unicode value is used. You can also use related fields, ie fields of the foreign key by using #fk.fk_field#, eg #workflow_type.workflow_description#.

In addition, you can call functions that returns a unicode value by using the syntax @pkg.mod.func(#field1#,#field2#,’literal1’)@. Just make sure that this function is importable from your PYTHONPATH. An example usage would be to format a date or numeric value.

Then create the Reminder Event.

../_images/rmdr_evt.png

Maintain Reminder Events

You must select a previously created Message Type and Template. Each Reminder must have an effective date from when to generate reminders (until its expiry date, which when blank means never expires). You can also temporarily suspend a Reminder by checking the Ignore Flag. Just remember to uncheck it later.

The Model Name must be the same as used in the Message Template. The Date or Datetime field is assigned_on which is the date and time when this document was assigned. If this is a Date field, then the time portion will be 12am midnight. The Reminder Days is the number of days since assignment (ie the value of assigned_on). This can be negative, in which case we will send a reminder before the assignment. But this will only make sense for forward dated fields, eg an Invoice’s Payment Due Date.

The User field tells us who to send the reminder to, in this case the Assignee. If you want to escalate the (same) reminder to her superior, then select an Application Hierarchy to use.

The Where Clause is a bit more complicated to define. We use the Where Clause to select instances whose status value has not changed. We use a JSON list (enclosed in []), which can be nested (ie list of lists). Each list must have 3 elements, the operator (as used by django’s QuerySet filter method), the field and the value operand. In our example, we have:

["exact", "document_status", "ACT"]

which will be translated to:

source_model.objects.filter(document_status__exact, 'ACT')

during execution. If you have nested lists, ie “[[...], [...]]”, then they will be ANDed together. Please look at django’s QuerySet documentation for the list of operators you can use. The value operand can support literals only, ie strings and numbers, so date(time) values are not supported. When your operator is in, then the value operand should be a list, eg [“A”, “B”, “C”].

JSON uses double quotes only (but single quotes will be converted automatically to double quotes).

You may also want to send the same reminder to other recipients.

../_images/rmdr_recp.png

Maintain Reminder Recipients

Each line in this maintenance allows the selection of one or more recipients. The recipients can be Maymyo Users (if the Recipient Field yields an auth.User instance) or external people, ie the Recipient Field yields either a mobile number or email address.

The Recipient(s) instance will come from another Model, which can be joined with the source Model (in this example, the Workflow Document) using the Join Clause. You can omit the Join Clause and use the Where Clause if these models are not related, eg you want to send reminders to certain Users in the IT Department.

The Email Mode is either To, ie the direct recipient, Cc or Bcc, ie the carbon-copied or blind carbon-copied recipient. This applies only when the Message Type sends emails.

The Join Clause is similar to the Where Clause described earlier with one exception. You can use field or function tokens from the Reminder Model for the operand value, ie fields from the Workflow Document. In the above example, we are joining to the auth.User model using the #superior_user.id# field. The second element of a list in the Join Clause must be a field of the Recipient’s Model (ie auth.User).

The Recipient Field is either a field or function token against the Recipient Model (ie auth.User). It must return a User instance, mobile number (for sending sms) or email address. If not, then no reminders can be sent.

What our example above does is to select the User instance of the Workflow Document’s superior_user. (Actually, this is redundant as we can escalate the same reminder to this superior by using the same Application Hierarchy as the Workflow Type. We setup this just to illustrate how to use Reminder Recipients).

The final step is to create a daily Scheduled Job to generate reminders. However, our fixtures data has already set this up to run every 8pm on business days. You can change the timing using “Maintain Scheduled Jobs” in the “Maintain Infrastructure Master Files” menu or “View your Scheduled Jobs” button in your Dashboard’s Toolbar.