AnsweredAssumed Answered

How to add custom table to the reviewTask screen of workflow form?

Question asked by Aleksey Bykov on Mar 10, 2017
Latest reply on Mar 10, 2017 by Aleksey Bykov

Alfresco Community v5.2 includes some of preconfigured workflows that available on the page /share/page/start-workflow

 

Among others, there is one that is interested to me - is "Review and Approve (one or more reviewers) - Assign a review task to multiple reviewers".

 

This business process is well suited to the requirements of one of our customers.

 

The only difference is that is needed to see the table of all the performers on the ReviewTask screens.

 

I decided to start with this wonderful article by Muralidharan Deenathayalan: Alfresco community 5.1.x workflow form add input fields dynamically

 

For start, I would like to see the table on my screens.

 

But I faced with the problem - the table is not displayed (even the static header).

 

And when I try to approve or reject the document, an exception occurs:

 

org.activiti.engine.ActivitiException: 
Exception while invoking TaskListener: 02100034 Mandatory task properties have
not been provided! {http://www......com/model/workflow/1.0}userDetails

 

Some of the details below.

 

workflow-model.xml:

 

<?xml version="1.0" encoding="UTF-8"?>

<model name="mswf:workflowmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <imports>
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
      <import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm"/>
   </imports>

   <namespaces>
      <namespace uri="http://www.........../model/workflow/1.0" prefix="mswf" />
   </namespaces>

   <types>
      <type name="mswf:submitConcurrentReviewTask">
         <parent>bpm:startTask</parent>
         <properties>
            <property name="mswf:requiredApprovePercent">
                <type>d:int</type>
                <mandatory>true</mandatory>
                <default>50</default>
                <constraints>
                    <constraint type="MINMAX">
                        <parameter name="minValue"><value>1</value></parameter>
                        <parameter name="maxValue"><value>100</value></parameter>
                    </constraint>
                </constraints>
            </property>
         </properties>
      </type>

      <type name="mswf:submitParallelReviewTask">
         <parent>mswf:submitConcurrentReviewTask</parent>
         <mandatory-aspects>
            <aspect>bpm:assignees</aspect>
         </mandatory-aspects>
      </type>

        <type name="mswf:activitiReviewTask">
            <parent>bpm:activitiOutcomeTask</parent>
            <properties>
                <property name="mswf:reviewOutcome">
                    <type>d:text</type>
                    <default>Reject</default>
                    <constraints>
                        <constraint name="mswf:reviewOutcomeOptions" type="LIST">
                            <parameter name="allowedValues">
                                <list>
                                    <value>Approve|...</value>
                                    <value>Reject|...</value>
                                </list>
                            </parameter>
                        </constraint>
                    </constraints>
                </property>
                 <property name="mswf:userDetails">
                    <title> User Details</title>
                    <type>d:text</type>
                    <mandatory>true</mandatory>
                 </property>
            </properties>
            <overrides>
                <property name="bpm:packageItemActionGroup">
                    <default>edit_package_item_actions</default>
                </property>
                <property name="bpm:outcomePropertyName">
                    <default>{http://www......../model/workflow/1.0}reviewOutcome</default>
                </property>
            </overrides>
        </type>

      <type name="mswf:rejectedParallelTask">
         <parent>bpm:workflowTask</parent>
         <mandatory-aspects>
            <aspect>mswf:parallelReviewStats</aspect>
         </mandatory-aspects>
      </type>

      <type name="mswf:approvedParallelTask">
         <parent>bpm:workflowTask</parent>
         <mandatory-aspects>
            <aspect>mswf:parallelReviewStats</aspect>
         </mandatory-aspects>
      </type>
   </types>

   <aspects>
      <aspect name="mswf:parallelReviewStats">
         <properties>
            <property name="mswf:reviewerCount">
               <type>d:int</type>
            </property>
            <property name="mswf:requiredPercent">
               <type>d:int</type>
            </property>
            <property name="mswf:approveCount">
               <type>d:int</type>
            </property>
            <property name="mswf:actualPercent">
               <type>d:int</type>
            </property>
         </properties>
      </aspect>
   </aspects>
</model>

 

contractsApproval.bpmn:

 

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/....-10.0">
  <process id="contractsApproval" name="..... Approval " isExecutable="true">
    <extensionElements>
      <activiti:executionListener event="start" class="org.alfresco.repo.workflow.activiti.listener.ScriptExecutionListener">
        <activiti:field name="script">
          <activiti:string><![CDATA[execution.setVariable('mswf_approveCount', 0);
                        execution.setVariable('mswf_rejectCount', 0);

                        execution.setVariable('mswf_actualPercent', 0);
                        execution.setVariable('mswf_actualRejectPercent', 0);

                        execution.setVariable('mswf_reviewerCount', bpm_assignees.size());
                        execution.setVariable('mswf_requiredPercent', mswf_requiredApprovePercent);]]>
</activiti:string>
        </activiti:field>
      </activiti:executionListener>
    </extensionElements>
    <startEvent id="start" activiti:formKey="mswf:submitParallelReviewTask"></startEvent>
    <sequenceFlow id="flow1" sourceRef="start" targetRef="reviewTask"></sequenceFlow>
    <userTask id="reviewTask" name="Review Task" activiti:assignee="${reviewAssignee.properties.userName}" activiti:formKey="mswf:activitiReviewTask">
      <extensionElements>
        <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
          <activiti:field name="script">
            <activiti:string><![CDATA[if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
                        if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;]]>
</activiti:string>
          </activiti:field>
        </activiti:taskListener>
        <activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
          <activiti:field name="script">
            <activiti:string><![CDATA[if(task.getVariableLocal('mswf_reviewOutcome') == 'Approve') {
                            var newApprovedCount = mswf_approveCount + 1;
                             var newApprovedPercentage = (newApprovedCount / mswf_reviewerCount) * 100;

                             execution.setVariable('mswf_approveCount', newApprovedCount);
                             execution.setVariable('mswf_actualPercent', newApprovedPercentage);
                        } else {
                            var newRejectCount = mswf_rejectCount + 1;
                            var newRejectPercentage = (newRejectCount / mswf_reviewerCount) * 100;

                            execution.setVariable('mswf_rejectCount', newRejectCount);
                            execution.setVariable('mswf_actualRejectPercent', newRejectPercentage);
                        }]]>
</activiti:string>
          </activiti:field>
        </activiti:taskListener>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="bpm_assignees" activiti:elementVariable="reviewAssignee">
        <completionCondition>${mswf_actualPercent &gt;= mswf_requiredApprovePercent || mswf_requiredApprovePercent &gt; (100 - mswf_actualRejectPercent)}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>
    <sequenceFlow id="flow2" sourceRef="reviewTask" targetRef="reviewDecision"></sequenceFlow>
    <exclusiveGateway id="reviewDecision" name="Review Decision"></exclusiveGateway>
    <sequenceFlow id="flow3" sourceRef="reviewDecision" targetRef="approved">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${mswf_actualPercent >= mswf_requiredApprovePercent}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow4" sourceRef="reviewDecision" targetRef="rejected"></sequenceFlow>
    <userTask id="approved" name="Document Approved" activiti:assignee="${initiator.exists() ? initiator.properties.userName : 'admin'}" activiti:formKey="mswf:approvedParallelTask">
      <documentation>The document was reviewed and approved.</documentation>
      <extensionElements>
        <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
          <activiti:field name="script">
            <activiti:string><![CDATA[if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
                        if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;

                        // Set parallel review params on task, to be kept in history
                        task.setVariableLocal('mswf_reviewerCount', mswf_reviewerCount);
                        task.setVariableLocal('mswf_requiredPercent', mswf_requiredPercent);
                        task.setVariableLocal('mswf_actualPercent', mswf_actualPercent);
                        task.setVariableLocal('mswf_approveCount', mswf_approveCount);]]>
</activiti:string>
          </activiti:field>
        </activiti:taskListener>
      </extensionElements>
    </userTask>
    <userTask id="rejected" name="Document Rejected" activiti:assignee="${initiator.exists() ? initiator.properties.userName : 'admin'}" activiti:formKey="mswf:rejectedParallelTask">
      <documentation>The document was reviewed and rejected.</documentation>
      <extensionElements>
        <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
          <activiti:field name="script">
            <activiti:string><![CDATA[if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
                        if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;

                        // Set parallel review params on task, to be kept in history
                        task.setVariableLocal('mswf_reviewerCount', mswf_reviewerCount);
                        task.setVariableLocal('mswf_requiredPercent', mswf_requiredPercent);
                        task.setVariableLocal('mswf_actualPercent', mswf_actualPercent);
                        task.setVariableLocal('mswf_approveCount', mswf_approveCount);]]>
</activiti:string>
          </activiti:field>
        </activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow5" sourceRef="approved" targetRef="end"></sequenceFlow>
    <sequenceFlow id="flow6" sourceRef="rejected" targetRef="end"></sequenceFlow>
    <endEvent id="end"></endEvent>
  </process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_contractsApproval">
   ...
  </bpmndi:BPMNDiagram>
</definitions>

 

share-config-custom.xml (some fields are not specified):

 

<alfresco-config>
   <config evaluator="string-compare" condition="activiti$activitiReview">
      <forms>
         <form>
            <field-visibility>
               <show id="bpm:workflowDescription" />
               <show id="bpm:workflowDueDate" />
               <show id="bpm:workflowPriority" />
               <show id="bpm:assignee" />
               <show id="packageItems" />
               <show id="bpm:sendEMailNotifications" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.general" />
               <set id="info" appearance="" template="/org/alfresco/components/form/2-column-set.ftl" />
               <set id="assignee" appearance="title" label-id="workflow.set.assignee" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="other" appearance="title" label-id="workflow.set.other" />

               <field id="bpm:assignee" label-id="workflow.field.reviewer" set="assignee" />
                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>                  
            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="string-compare" condition="activiti$contractsApproval">
      <forms>
         <form>
            <field-visibility>
               <show id="bpm:workflowDescription" />
               <show id="bpm:workflowDueDate" />
               <show id="bpm:workflowPriority" />
               <show id="bpm:assignees" />
               <show id="mswf:requiredApprovePercent" />
               <show id="packageItems" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.general" />
               <set id="info" appearance="" template="/org/alfresco/components/form/2-column-set.ftl" />
               <set id="assignee" appearance="title" label-id="workflow.set.assignees" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="other" appearance="title" label-id="workflow.set.other" />

               <field id="bpm:assignees" label-id="workflow.field.reviewers" set="assignee" />
                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>
               <field id="packageItems" set="items" />
            </appearance>
         </form>
      </forms>
   </config>   
    <config evaluator="string-compare" condition="activiti$activitiLifecycleApproval">
      <forms>
         <form>
            <field-visibility>
               <show id="bpm:workflowDescription" />
               <show id="bpm:workflowDueDate" />
               <show id="bpm:workflowPriority" />
               <show id="bpm:assignee" />
               <show id="packageItems" />
               <show id="bpm:sendEMailNotifications" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.general" />
               <set id="info" appearance="" template="/org/alfresco/components/form/2-column-set.ftl" />
               <set id="assignee" appearance="title" label-id="workflow.set.assignee" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="other" appearance="title" label-id="workflow.set.other" />

                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>
            </appearance>
         </form>
      </forms>
   </config>           
   <config evaluator="task-type" condition="bpm:startTask">
      <forms>
         <form id="workflow-details">
            <field-visibility>
               <show id="bpm:sendEMailNotifications" />
               <show id="packageItems" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.workflow.more_info" />
               <set id="items" appearance="title" label-id="workflow.set.items" />

               <field id="packageItems" set="items" />
            </appearance>
         </form>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:workflowPriority" />
               <show id="bpm:workflowDueDate" />
               <show id="bpm:taskId" />
               <show id="bpm:status" />
               <show id="packageItems" />
               <show id="bpm:sendEMailNotifications" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="other" appearance="title" label-id="workflow.set.other" />

                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>

            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="task-type" condition="mswf:submitParallelReviewTask">
      <forms>
         <form id="workflow-details">
            <field-visibility>
               <show id="mswf:requiredApprovePercent" />
               <show id="bpm:sendEMailNotifications" />
               <show id="packageItems" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.workflow.more_info" />
               <set id="items" appearance="title" label-id="workflow.set.items" />

               <field id="packageItems" set="items" />
            </appearance>
         </form>   
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:workflowPriority" />
               <show id="bpm:workflowDueDate" />
               <show id="bpm:taskId" />
               <show id="mswf:requiredApprovePercent" />
               <show id="bpm:status" />
               <show id="packageItems" />
               <show id="bpm:sendEMailNotifications" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="other" appearance="title" label-id="workflow.set.other" />

                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>

            </appearance>
         </form>
      </forms>
   </config>      
   <config evaluator="task-type" condition="bpm:workflowTask">
      <forms>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:priority" />
               <show id="bpm:dueDate" />
               <show id="bpm:taskId" />
               <show id="bpm:status" />
               <show id="packageItems" />
               <show id="bpm:comment" />
               <show id="transitions" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="response" appearance="title" label-id="workflow.set.response" />

                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>
            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="task-type" condition="mswf:reviewTask">
      <forms>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:priority" />
               <show id="bpm:dueDate" />
               <show id="bpm:taskId" />
               <show id="packageItems" />
               <show id="bpm:comment" />
               <show id="transitions" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="response" appearance="title" label-id="workflow.set.response" />

                <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
                </field>

            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="task-type" condition="mswf:activitiReviewTask">
      <forms>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:priority" />
               <show id="bpm:dueDate" />
               <show id="bpm:taskId" />
               <show id="packageItems" />
               <show id="bpm:comment" />             
               <show id="mswf:reviewOutcome" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="response" appearance="title" label-id="workflow.set.response" />

               <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
               </field>
            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="task-type" condition="mswf:approvedParallelTask">
      <forms>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:priority" />
               <show id="bpm:dueDate" />
               <show id="bpm:taskId" />
               <show id="mswf:reviewerCount" />
               <show id="mswf:approveCount" />
               <show id="mswf:requiredPercent" />
               <show id="mswf:actualPercent" />
               <show id="packageItems" />
               <show id="bpm:comment" />
               <show id="transitions" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="outcome" appearance="title" label-id="workflow.set.outcome"
                    template="/org/alfresco/components/form/2-column-set.ftl" />

               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="response" appearance="title" label-id="workflow.set.response" />

               <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
               </field>
            </appearance>
         </form>
      </forms>
   </config>   
   <config evaluator="task-type" condition="mswf:rejectedParallelTask">
      <forms>
         <form>
            <field-visibility>
               <show id="message" />
               <show id="taskOwner" />
               <show id="bpm:priority" />
               <show id="bpm:dueDate" />
               <show id="bpm:taskId" />
               <show id="mswf:reviewerCount" />
               <show id="mswf:approveCount" />
               <show id="mswf:requiredPercent" />
               <show id="mswf:actualPercent" />
               <show id="packageItems" />
               <show id="bpm:comment" />
               <show id="transitions" />
            </field-visibility>
            <appearance>
               <set id="" appearance="title" label-id="workflow.set.task.info" />
               <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" />
               <set id="progress" appearance="title" label-id="workflow.set.task.progress" />
               <set id="outcome" appearance="title" label-id="workflow.set.outcome"
                    template="/org/alfresco/components/form/2-column-set.ftl" />

               <set id="items" appearance="title" label-id="workflow.set.items" />
               <set id="response" appearance="title" label-id="workflow.set.response" />

               <field id="mswf:userDetails" set="userDetails" label="User Details"  read-only="true">
                    <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
               </field>                  
            </appearance>
         </form>
      </forms>
   </config>
</alfresco-config>

 

Where I'm wrong?..

 

I suspect that the reason may be that there is no userDetails specified in <set> block.

 

I would be very grateful for the information. Thanks to all.

Outcomes