This is the documentation for Clover Club 12.0.
Documentation for the upcoming version Rampur 13.0 can be found here.

Message Templates

In this section you will find different template types designated for:

  • Different document workflow states

  • General cases and messaging functionality in Unity UI

The templates are organized by document/situation type and they contain styling (HTML code) with placeholders referring to:

  • Texts – e.g. $email_approveSuccess$ which translates to "You have approved the following $object$"
    For details see Template Texts and Localization below.

  • Repeating parts of styling –  $header()$, $body()$ and $footer()$
    Each of these placeholders has a corresponding file in the build. These files contain company logo and formatting which is shared across all of the various template types. There are no texts and so these files are not editable in the UI.

In this section:

Template Types

Workflow

There are several workflow email templates which inform users (approvers, watchers, owners) about various workflow states. The templates are:

  • For email body:

    • approvalRequired – Request for an approval to the approver.

    • approve_success – Confirmation to the approver.

    • deny_success – Confirmation to the approver.

    • stepApproved – Notification to others.

    • stepDenied – Notification to others.

    • watcherNotification – Triggered by having a watcher step in the workflow. 

    • workflowApproved – Triggered when the whole workflow is approved.

    • delegationFooter/Header – Delegation of approval authority to other user.

  • For email subject:

    • workflowSubjectSuffix – Adds document's details to the email subject. (The subject is hardcoded and contains one of the following: Pricefx - Approval Required, Pricefx - Watcher notification, Pricefx - Approved, Pricefx - Workflow Approved, Pricefx - Denied.)

    • delegationSubjectSuffix – Adds source and target users' names to the subject when workflow delegation is used.
       When editing these templates, you must put everything in one row (text line), even if you use a more complex template code. (If multiple rows were used, the subject suffix would be generated empty and the code you wrote would appear in the email body.)

Some of these notifications can be switched off. You can disable:

  • All notifications for specified events – for details see My Workflows (Configuration).

  • Individual message types. Use the Allow Sending option (next to the template name; see below) to control which message types will be sent.
    Note: Some messages are split into several items (e.g., email subject and body) – in this case only the main part (e.g., the email body) can be enabled/disabled. Disabling the main part disables the whole message.

All of these templates are available for all the approvable documents:

  • Data Change Request

  • Price Grid Item

  • Quote

  • Rebate Agreement

  • Agreement/Promotion

  • Price List

  • Rebate Record

  • Rebate Record Group

  • Compensation Plan

  • Compensation Record

  • Custom Form

  • Claim

Export and Send by Email

There are templates for emails which users can send manually from Quotes, Agreements/Promotions and Rebate Agreements with the related document as an attachment (available only in the Unity interface):

  • quote_externalEmailSubject

  • quote_externalEmailBody

  • contract_externalEmailSubject

  • contract_externalEmailBody

  • rebateagreement_externalEmailSubject

  • rebateagreement_externalEmailBody

Templates for Messaging in Documents

The following templates relate to the messaging functionality in Quotes, Agreements/Promotions, Rebate Agreements, Deal Plans and Custom Forms:

  • emailBody_requestInfo

  • emailSubject_requestInfo

In these templates you can work with the following variables:

  • $requester – Sender of the message. It is the user object for which which you can access fields such as firstname, lastname etc.

  • $recipient – Recipient of the message. It is the user object for which which you can access fields such as firstname, lastname etc.

  • $baseURL – URL of the Pricefx application. You can append to it a specific string pointing to e.g., Agreements/Promotions and create a link to this part of the application.

  • $type – Allows you to find out in which context you are: it is either Quote, Agreement/Promotion, Rebate Agreement, Deal Plan or Custom Form. 
    Instead of this variable you can also use one of the following five variables (isQuote, etc.) – their usage is similar.

  • $isQuote – Allows you to customize the template for Quotes only. It returns true if $entity is a Quote.

  • $isContract – Allows you to customize the template for Agreements/Promotions only. It returns true if $entity is a Agreement/Promotion.

  • $isRebateAgreement – Allows you to customize the template for Rebate Agreements only. It returns true if $entity is a Rebate Agreement.

  • $isDealPlan – Allows you to customize the template for Deal Plans only. It returns true if $entity is a Deal Plan.

  • $isCustomForm – Allows you to customize the template for Custom Forms only. It returns true if $entity is a Custom Form.

  • $entity – Contains the whole object of a Quote, Agreement/Promotion or Rebate Agreement (based on the context). See this Knowledge Base article to learn how to find out which fields are available for use for a specific object.

  • $message – Body of the message which you type in the Messages tab of e.g., a Quote.

  • $msgEntity – Object of the message. In a thread, there is msgEntity created for each message sent within the conversation. You can work with its fields such as sender, recipient, date of sending, message body etc.

  • $workflow.externalActionToken – A token allowing any user (workflow notification email recipient) to perform an action in the particular workflow step.

  • $directActionEmail – The user identity used for approval. The value is derived from user email on behalf of which the action will be done.

Other

There are also message templates for:

  • General failure

  • Workflow failure

  • E-signature system notifications

  • Password expiry notifications

  • Notifications about Action items.

Links in Templates

The email body will typically contain a link to the document for which the message has been sent.

To configure a working link, make sure that they follow the correct pattern and use the correct variables. As page token, you can use typed ID for all document types.

Document Type

Link Pattern

Document Type

Link Pattern

Quote

$baseURL$/app/modules/#/qc/go-to-quotes/$entity.typedId$/messages/$msgEntity.typedId$

Agreement/Promotion

$baseURL$/app/modules/#/pm/go-to-contracts/$entity.typedId$/messages/$msgEntity.typedId$

Price List

$baseURL$/app/modules/?partition=partitionName#/pb/pricelists/$pricelist.typedId$/detail

Live Price Grid

$baseURL$/app/modules/?partition=partitionName#/pb/lpgs/$pricegriditem.priceGrid.typedId$/detail

Rebate Agreement

$baseURL$/app/modules/#/rm/go-to-rebate-agreements/$entity.typedId$/messages/$msgEntity.typedId$

Rebate Calculation

$baseURL$/app/modules/?partition=partitionName#/rm/calculations/$rebatecalculation.typedId$/detail

Rebate Record

$baseURL$/app/modules/?partition=partitionName#/rm/rebate-records/$rebaterecord.typedId$/detail

Data Change Request

$baseURL$/app/modules/?partition=partitionName#/md/dcr/$dcr.typedId$/detail

Ship and Debit Claim

$baseURL$/app/modules/?partition=partitionName#/cm/claims/$claim.typedId$/detail

Deal Plan

$baseURL$/app/modules/?partition=partitionName#/lo/deal-plans/$dealplan.typedId$/detail

Action

$baseURL$/app/modules/#/user/actions/$actionItem.typedId$/detail

Note:

  • For Quotes, Agreements/Promotions and Rebate Agreements, use the above links that work both for the Ember and React UI versions.

  • With limitations, you can use other parameters as page tokens:

    • Document ID – You must, however, format it as integer for the link to work.
      For example: $baseURL$/app/modules/?partition=partitionName#/pb/pricelists/$pricelist.id;format="#"$/detail

    • uniqueName – This parameter will not work for revisions as the revision number is appended to the unique name.

Template Texts and Localization

To support easier text customizations and localization of the templates, their content and formatting are separated (since Bijou 7.0).

  • All textual elements in the templates are represented by placeholders. These placeholders and their values (texts) are shipped and maintained as part of the product. In your custom templates you can use them or replace them with "real" text.

  • The default templates contain only HTML and styling information and text placeholders.

To ensure that the previous system (templates containing both formatting and content) keeps working, the following rules apply:

  • Template names stay as they are.

  • First the server loads customized language specific templates (e.g., quote_approvalRequired_fr). 

  • If no customized template is found, the server will load the default template in a 3-step hierarchy:

    1. Full template name as specified (e.g., quote_approvalRequired_fr)

    2. Full template name without language suffix (e.g., quote_approvalRequired)

    3. Template name without language suffix and without type prefix (e.g., approvalRequired)

  • It will then add the language-specific translations into the templating engine (plus the usual placeholders) and render it.

By default, the templates are available in the same languages as the application UI. You can also add other languages in the Add Language dialog (if you have provided the Email.properties file for that language) and then simply switch between the template's language versions in the Language drop-down list. To determine, which language version will be used for a particular user, go to the User Admin section and select the appropriate language in 'Email Language'.

Customize Template

A default template is provided and can be changed by writing standard HTML code and using Pricefx fields. Make sure you keep the correct syntax. 

In the message you can access data from the object which triggered sending the email message. For example, the method withDataMap(Map dataMap) of the WorkflowDTO object allows you to access any workflow related data at the time of submitting. (If data from later phases of the workflow are needed, use Workflow Post Step Logic.) To access data stored with the method withDataMap(Map dataMap) in the message templates, you need to access the context variable workflowHistory.dataMap.

Example:

Workflow code
def map = [test: "This is a test"] workflow.withDataMap(map)
Message template code
$workflowHistory.dataMap.test$

The template engine used here by the Pricefx application is StringTemplate, version 3.

To learn more about this engine see: 

Examples

This will be replaced by the label of the Quote:

$quote.label$

This block will be rendered conditionally:

(It works only with true values; it is not possible to use if( a == 'a'). This true/null element has to be visible in the line item logic on the Quotes.)

Adding "&approve" or "&deny" to the document link approves/rejects the document immediately after clicking on the link, skipping the dialog where users can add a comment.

Replacing "approve" or "deny" in the document link with "form" displays a dialog with both Approve and Deny buttons.

 If the $partition$ variable is not present,  you can use $entity.partition$ where "entity" is to be replaced with the current object, e.g., $pricelist.partition$.

 When you check the JSON structure of the underlying item (using Chrome Developer tools), all attributes should be accessible through the $entity reference. In addition, there are variables like $entity.partition which are not visible in this JSON representation, but they are part of the object in the backend.

More advanced example: it iterates through line items and conditionally shows the line items with workflow with colors.

Enhanced email template

Note on Arrays

Sometimes you may have to do some work with arrays.

Typically, this type of work should not be done in the presentation layer, and so StringTemplate only has very limited support for this using the following functions: first(), last(), rest(), trunc(), strip() and  length(). These functions can be used in conjunction with each other for more specific needs.

An example showing how to obtain a property of a Quote's first line item:

Accessing an array like array[index] as you would expect is not possible.

There are however some workarounds, such as first(rest(array)), which would return the second item in the array.

As you can see, this can quickly get messy, so the true solution would be to take such logic out of the presentation layer altogether if possible.