Comment paramétrer le cycle de vie - Planifier des tâches avec les minuteurs (Timer)

Prérequis

Il faut avant toute chose avoir suivi et réalisé les étapes traitées dans ces guides :

Créer un minuteur - Anakeen CLI

À quoi sert un minuteur

Les minuteurs permettent de déclencher des tâches à des dates prédéfinies sur un Smart Element. Ces dates peuvent être statiques ou liées à des valeurs du Smart Element qui porte le minuteur [...]

Si vous n’êtes pas familier avec les Minuteurs et leur fonctionnement, il est fortement recommandé de lire la documentation associée disponible ici

Afin d’aborder cette notion de minuteurs permettant d’envoyer des mails ou de changer l’état d’un SmartElement, nous allons prendre nos trois cas suivants :

Transition En test -> À la carte :

  1. Créer un minuteur qui, 7 jours avant la date de fin de validité du plat, envoi un mail à la direction,
  2. Créer un minuteur qui, 2 jours avant la date de fin de validité du plat, envoi un mail aux cuisiniers,
  3. Créer un minuteur qui, le jour de la fin de date de validité du plat, change son état à Retiré.

Créons le minuteur avec la commande createSetting

npx @anakeen/anakeen-cli createSetting --type Timer --name PlatTimer --associatedSmartStructure PLAT

Informations

Si la SmartStructure, renseignée pour --associatedSmartStructure, existe, alors le minuteur est placé automatiquement dans le dossier <SmartStructureName>Settings

Voici le fichier que la commande génère 260-TimerPlatTimer.xml

<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:timer="https://platform.anakeen.com/4/schemas/timer/1.0">
    <timer:timer xmlns:timer="https://platform.anakeen.com/4/schemas/timer/1.0" name="PLATTIMER" label="PlatTimer" structure="PLAT" >
        <!--
        <timer:field-date-reference ref="field_date_creation"/>
        -->
        <timer:tasks>
            <!--
            <timer:task delta="0 days 0 hours">
                <timer:sendmail ref="MAILTEMPLATE_NAME"/>
            </timer:task>
            <timer:task delta="0 days 0 hours">
                <timer:process>
                    <timer:process-callable function="::Hello"/>
                </timer:process>
            </timer:task>
            -->
        </timer:tasks>
    </timer:timer>
</smart:config>

Il est possible de compléter la balise <timer:timer> afin d’y indiquer le modèle de workflow associée.

Rappel

Le modèle de workflow a été créé lors de la génération des fichiers de configuration d’un cycle de vie

Profitons-en donc pour le renseigner.

<timer:timer name="PLATTIMER" label="PlatTimer" structure="PLAT" workflow="WFAM_PLAT">...</timer:timer>

Nous pouvons aussi en profiter pour renseigner le SmartField servant de date de référence d’exécution des tâches, dans notre cas la date de validité du plat :

<timer:field-date-reference ref="plat_validity_date"/>

Sachant que l’on souhaite ici que nos minuteurs soient affectés à notre cycle de vie lorsque l’on effectue la transition En test -> À la carte, il faut lui faire référence dans le fichier de paramétrage de notre cycle de vie :src/vendor/<vendorName>/<moduleName>/SmartStructures/Plat/PlatWorkflows/WdocPlatWorkflow/510-WdocPlatWorkflowSettings.xml










 













<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:workflow="https://platform.anakeen.com/4/schemas/workflow/1.0">
    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
    <!--Timer and Mail templates workflow references-->
    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
    <workflow:config name="WDOC_PLAT" structure="PLAT" model="WFAM_PLAT">
        <workflow:steps>
            <workflow:step ref="plat_e2">
                <!-- Nom du minuteur que l’on souhaite attacher -->
                <workflow:timer ref="PLATTIMER"/>
                <workflow:view-control ref="CVDOC_PLAT_E2"/>
            </workflow:step>
        </workflow:steps>
        <workflow:transitions>
            <!-- Cibler la transition concernée ... -->
            <workflow:transition ref="t_plat_e1_e2">
                <!-- ... et lui lier le modèle de mail voulu -->
                <workflow:mailtemplate ref="MAIL_INFO_E1_TO_E2" />
            </workflow:transition>
        </workflow:transitions>
    </workflow:config>
</smart:config>

Envoyer un mail

Cette partie permet de lier le minuteur à un modèle de mail. Les cas nous intéressant ici sont les suivants :

  1. Créer un minuteur qui, 7 jours avant la date de fin de validité du plat, envoi un mail au directeur,
  2. Créer un minuteur qui, 2 jours avant la date de fin de validité du plat, envoi un mail aux cuisiniers,

Recommandation

Si vous n’êtes pas familier avec les Modèles de mail et leur fonctionnement, il est fortement recommandé de lire la documentation associée disponible ici.

De plus, il est nécessaire d’avoir vu comment créer un modèle de mail dépendant d’une SmartStructure

  • Créons tout d’abord les champs permettant de spécifier les destinataires de nos mails ainsi que leur valeur par défaut. Pour cela, rendons-nous dans le fichier de configuration du modèle de Workflow 100-WfamPlatStructure.xml











 
 







 
 




<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0">
    <smart:structure-configuration name="WFAM_PLAT">
        <smart:extends ref="WDOC" />
        <smart:icon file="wfam_plat.png" />
        <smart:class>Cogip\Restauratec\SmartStructures\Plat\PlatWorkflows\WfamPlatWorkflow\WfamPlatBehavior</smart:class>
        <smart:fields>
            <smart:field-set type="frame" name="wfl_f_destinataire" label="Destinataires pour les mail" access="ReadWrite">
                <!-- Destinataires transition e1 -> e2  -->
                <smart:field-account match="group" multiple="true" name="wfl_dest_validation_group" label="Destinataires(Groupe) pour validation" access="ReadWrite"></smart:field-account>
                <!-- Destinataires Timers -->
                <smart:field-account match="group" multiple="true" name="wfl_dest_warn_seven_days" label="Destinataires(Utilisateur) pour avertissement J-7 avant retrait du plat" access="ReadWrite"></smart:field-account>
                <smart:field-account match="group" multiple="true" name="wfl_dest_warn_two_days" label="Destinataires(Groupe) pour avertissement J-2 avant retrait du plat" access="ReadWrite"></smart:field-account>
            </smart:field-set>
        </smart:fields>
        <smart:hooks />
        <smart:defaults>
            <!-- Destinataire(s) par défaut lors de la transition e1 -> e2  -->
            <smart:default field="wfl_dest_validation_group">{GCUISINIER}</smart:default>
            <!-- Destinataires par défaut pour les timers -->
            <smart:default field="wfl_dest_warn_seven_days">{GCUISINIER}</smart:default>
            <smart:default field="wfl_dest_warn_two_days">{GDIRECTION}</smart:default>
        </smart:defaults>
    </smart:structure-configuration>
</smart:config>
  • Créons ensuite nos deux modèles de mails comme ceci :
npx @anakeen/anakeen-cli createSetting --type MailTemplate --name OneWeekBeforeValidityDate --associatedSmartStructure PLAT
npx @anakeen/anakeen-cli createSetting --type MailTemplate --name TwoDaysBeforeValidityDate --associatedSmartStructure PLAT
  • Et configurons-les de manière à référencer nos destinataires, le sujet et le corps du mail :
<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:mail="https://platform.anakeen.com/4/schemas/mailtemplate/1.0">
    <mail:mailtemplate name="MAIL_ONE_WEEK_BEFORE_VALIDITY_DATE" label="J-7 avant retrait du plat de la carte" structure="PLAT" workflow-model="WFAM_PLAT">
        <mail:from>
            <mail:address>admin@example.net</mail:address>
        </mail:from>
        <mail:recipients>
            <mail:recipient dest="to">
                <mail:workflow-account-field>wfl_dest_warn_seven_days</mail:workflow-account-field>
            </mail:recipient>
        </mail:recipients>
        <mail:subject>J-7 avant expiration du plat [V_CONSOMMABLE_TITLE]</mail:subject>
        <mail:use-html-anchor>true</mail:use-html-anchor>
        <mail:body content-type="html">
            <![CDATA[
            <p style="margin:0pt;">&nbsp;</p>
            <div>
                Le plat "<strong>[V_CONSOMMABLE_TITLE]</strong>" sera retiré de la carte dans 7 jours
            <p style="margin:0pt;">&nbsp;</p>
            ]]>
        </mail:body>
    </mail:mailtemplate>
</smart:config>
<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:mail="https://platform.anakeen.com/4/schemas/mailtemplate/1.0">
    <mail:mailtemplate name="MAIL_TWO_DAYS_BEFORE_VALIDITY_DATE" label="J-2 avant retrait du plat de la carte" structure="PLAT" workflow-model="WFAM_PLAT">
        <mail:from>
            <mail:address>admin@example.net</mail:address>
        </mail:from>
        <mail:recipients>
            <mail:recipient dest="to">
                <mail:workflow-account-field>wfl_dest_warn_two_days</mail:workflow-account-field>
            </mail:recipient>
        </mail:recipients>
        <mail:subject>J-2 avant expiration du plat [V_CONSOMMABLE_TITLE]</mail:subject>
        <mail:use-html-anchor>true</mail:use-html-anchor>
        <mail:body content-type="html">
            <![CDATA[
            <p style="margin:0pt;">&nbsp;</p>
            <div>
                Le plat "<strong>[V_CONSOMMABLE_TITLE]</strong>" sera retiré de la carte dans 2 jours
            <p style="margin:0pt;">&nbsp;</p>
            ]]>
        </mail:body>
    </mail:mailtemplate>
</smart:config>
  • Enfin, il ne reste plus qu’à indiquer dans le fichier de configuration de notre minuteur 260-TimerPlatTimer.xml :
    • quand effectuer l’action par rapport à la date de référence
    • l’action à effectuer





 
 
 
 
 
 
 
 




<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:timer="https://platform.anakeen.com/4/schemas/timer/1.0">
    <timer:timer name="PLATTIMER" label="PlatTimer" structure="PLAT" workflow="WFAM_PLAT">
        <timer:field-date-reference ref="plat_validity_date"/>
        <timer:tasks>
            <timer:task delta="-1 week">
                <!-- Envoi un mail en se basant sur le modèle référencé, une semaine avant la date de fin de validité du plat -->
                <timer:sendmail ref="MAIL_ONE_WEEK_BEFORE_VALIDITY_DATE"/>
            </timer:task>
            <timer:task delta="-2 days">
                <!-- Envoi un mail en se basant sur le modèle référencé, deux jours avant la date de fin de validité du plat -->
                <timer:sendmail ref="MAIL_TWO_DAYS_BEFORE_VALIDITY_DATE"/>
            </timer:task>
        </timer:tasks>
    </timer:timer>
</smart:config>

Changer l’état d’un SmartElement

Cette partie permet de lier le minuteur à un changement d’état. Le cas nous intéressant ici est le suivant :

  1. Créer un minuteur qui, le jour de la date de fin de validité du plat, change son état à Retiré.

Il suffit d’ajouter une tâche supplémentaire au fichier de configuration du minuteur :














 
 
 
 




<?xml version="1.0" encoding="UTF-8"?>
<smart:config xmlns:smart="https://platform.anakeen.com/4/schemas/smart/1.0" xmlns:timer="https://platform.anakeen.com/4/schemas/timer/1.0">
    <timer:timer name="PLATTIMER" label="PlatTimer" structure="PLAT" workflow="WFAM_PLAT">
        <timer:field-date-reference ref="plat_validity_date"/>
        <timer:tasks>
            <timer:task delta="-1 week">
                <!-- Envoi un mail en se basant sur le modèle référencé, une semaine avant la date de fin de validité du plat -->
                <timer:sendmail ref="MAIL_ONE_WEEK_BEFORE_VALIDITY_DATE"/>
            </timer:task>
            <timer:task delta="-2 days">
                <!-- Envoi un mail en se basant sur le modèle référencé, deux jours avant la date de fin de validité du plat -->
                <timer:sendmail ref="MAIL_TWO_DAYS_BEFORE_VALIDITY_DATE"/>
            </timer:task>
            <timer:task delta="0">
                <!-- Change l’état du plat à `Retiré` lorsque la date de fin de validité du plat est atteinte -->
                <timer:setstate state="plat_e3"/>
            </timer:task>
        </timer:tasks>
    </timer:timer>
</smart:config>

Informations

Droits par défaut

Et ensuite ?

Comment créer une collection dynamique