Overview
The purpose of this tutorial is to:
...
Also, instead of creating Users and Work Groups ourselves, we will leave that task to the Identity Management system. In production, we can expect all Users to already be present in the system. Work Groups can be specific to workflows, so we can expect to request that these be created by the system administrators.
Development Steps
- Study the Business Process
- Gather the Required Details
- Create a Document Workflow Diagram
- Request Work Groups
- Create the Parent Document Type
- Create the Child Document Types
- Create the eDocLite Form
- Create the Definition
- Create the Stylesheet
- Create Rule Attributes
- Create the Rule Template
- Create Routing Rules
- Ingest XML Files
- Simulate the Business Process
- Create Validation Checklists
The Business Process
In using eDocLite to facilitate this process, we'll need a few things:
...
- This time there are four responsible parties: Requester, Desktop Services, Firewall Policy Group, and the Firewall Gatekeeper.
- The Requester submits the request as before, except s/he is now allowed to tell us whether if the request is URGENT. If it is, we expedite the process. If not, we go through the process as normal.
- The Desktop Services group will field all requests instead of the Firewall Policy Group. We want whoever receives the request to check if the firewall modification being requested is already in effect. If so, disapprove the request. The Requester will then get notification. Also if the request is URGENT, forward the request straight to the Firewall Gatekeeper to make the firewall modification. Otherwise, forward the request to the Firewall Policy Group.
- The Firewall Policy Group will review all normal requests and, upon approval, forward the request to the Firewall Gatekeeper. This group will review all URGENT requests after the Firewall Gatekeeper has fulfilled them.
- The Firewall Gatekeeper performs the actual modification of the firewall. As far as the process goes, all the gatekeeper will do is acknowledge the request and implement the modification to the firewall. Once the modification is complete, the gatekeeper will forward the request onward. We say "onward", because the gatekeeper is not routing the request to anyone per se. Behind the scenes, if the request is URGENT, then the request gets routed to the Firewall Policy Group. Otherwise the process is finished and the Requester gets a notification (and maybe all the other responsible parties too).
- To complicate things further, if the Firewall Gatekeeper modified the firewall based on an URGENT request, and the Firewall Policy Group decides to disapprove the request after the fact, then the request goes back to the gatekeeper to reverse the firewall modification.
- We documented the Review Non-Urgent Request and Review Urgent Request as subprocesses because there is the potential for the Firewall Policy Group to have continuous correspondence with the Requester. We'll address these in a future Way More Advanced tutorial.
The Request Details
As part of the process, the Firewall Policy Group requires that anyone who wants the firewall rules modified must provide the following details:
...
- The details we are asking from the Requester are almost the same as those in the Simple Workflow tutorial. This time we decided to split Source Specification and Destination Specification into two fields and allow for the Requester to tell us that this is an URGENT request.
- The details of the request don't stop there. As the process moves along, we want the other responsible parties to add detail to the form.
- Once Desktop Services fields the request, we want to capture whether the firewall modification being requested is already in effect or not. Depending on the answer, the workflow will route the form to the appropriate party.
- If the Firewall Policy Group decides to disapprove the request, we want to capture their reason for doing so.
- If the request is URGENT, and the Firewall Gatekeeper already modified the firewall rules, and the Firewall Policy Group disapproved the request afterward, we want our workflow to automatically check a box that prompts the Firewall Gatekeeper to revert the modification.
The Document Workflow Diagram
Here is a document workflow diagram based on our business process. It doesn't map exactly to our business process diagram, because we want to represent the state of the Request Firewall Change document as the responsible parties act upon it.
...
- The Request element is the first node (aka Start Node) in the workflow's route path. This is where the Request Firewall Change document is first created.
- Each violet element represents a subsequent node in the route path. Each node represents a point in the business process where a responsible party is viewing (and possibly editing) the Request Firewall Change docuement.
- Each lavender parallelogram represents a rule template that is applied to each node. Each rule template can be associated with a set of rules.
- The orange skittle represents a split in the workflow. If the request is URGENT, the workflow branches out one way. If not, it branches out the other way.
- The lime skittle represents a join in the workflow. No matter which way the workflow branched, it will end up at this point.
- The green Finish element means the workflow has ended with flying colors.
- The red Acknowledge and Finish elements mean that somewhere in the workflow there was a disapproval. Therefore the entire workflow stops. Out of the box, eDocLite routes the disapproved request back to the Requester for acknowledgment.
Request Work Groups
After going through the easy and expedient process of requesting Work Groups, the Kuali Rice administrator has notified us that the following groups are available for use in our workflow:
...
Node | Responsible Party | Action Requested |
Request | Initiator.Role.RuleAttribute (whoever creates the document) | SUBMIT |
Review Current Configuration | ucd.IET.DES.DevelopmentSupport.WorkGroup | APPROVE |
Review Request | ucd.IET.AppDev.FirewallPolicyGroup.Workgroup | APPROVE |
Fulfill Request | ucd.IET.DCCS.FirewallSysAdmin.Workgroup | ACKNOWLEDGE |
Fulfill Urgent Request | ucd.IET.DCCS.FirewallSysAdmin.Workgroup | ACKNOWLEDGE |
Review Urgent Request | ucd.IET.AppDev.FirewallPolicyGroup.Workgroup | APPROVE |
Acknowledge Configuration | Initiator.Role.RuleAttribute | ACKNOWLEDGE |
Create the Parent Document Type
Here we create a parent document type that defines the behavior of all Request Firewall Change documents. This particular parent document type defines everything short of routing paths. The idea is to allow for a hierarchy of child document types that inherit attributes of their parents.
...
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?> <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData"> <documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType"> <documentType> <name>RequestFirewallChange.eDoc.ParentDocType</name> <description>Request Firewall Change eDocLite Parent Document Type</description> <label>Request Firewall Change eDocLite Parent Document Type</label> <blanketApprovePolicy>NONE</blanketApprovePolicy> <docHandler>${workflow.url}/EDocLite</docHandler> <active>true</active> <routingVersion>2</routingVersion> </documentType> </documentTypes> </data> |
Create the Child Document Type
Here we create one child document type to support the behavior of our workflow. Besides identifying the name and parent of this document type, we define two other main things: routePaths and routeNodes. These define the behavior of the workflow.
...
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?> <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData"> <documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType"> <documentType> <name>RequestFirewallChange.eDoc.ChildDocType</name> <parent>RequestFirewallChange.eDoc.ParentDocType</parent> <description>Request Firewall Change eDocLite Child Document Type</description> <label>Request Firewall Change eDocLite Child Document Typee</label> <postProcessorName>edu.iu.uis.eden.edl.EDocLitePostProcessor</postProcessorName> <superUserWorkgroupName>ucd.IET.AppDev.KualiRice.SysAdmin.Workgroup</superUserWorkgroupName> <defaultExceptionWorkgroupName>ucd.IET.AppDev.KualiRice.SysAdmin.Workgroup</defaultExceptionWorkgroupName> <docHandler>${workflow.url}/EDocLite</docHandler> <active>true</active> <routingVersion>2</routingVersion> <routePaths> <routePath> <start name="RequestFirewallChange.eDoc.Request.Node" nextNode="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node" /> <requests name="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Split" /> <split name="RequestFirewallChange.eDoc.isUrgent.Split" nextNode="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node"> <branch name="RequestFirewallChange.eDoc.isUrgent.Branch"> <requests name="RequestFirewallChange.eDoc.FulfillUrgentRequest.Node" nextNode="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node" /> <requests name="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Join" /> </branch> <branch name="RequestFirewallChange.eDoc.isNotUrgent.Branch"> <requests name="RequestFirewallChange.eDoc.ReviewRequest.Node" nextNode="RequestFirewallChange.eDoc.FulfillRequest.Node" /> <requests name="RequestFirewallChange.eDoc.FulfillRequest.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Join" /> </branch> <join name="RequestFirewallChange.eDoc.isUrgent.Join" /> </split> <requests name="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node" /> </routePath> </routePaths> <routeNodes> <start name="RequestFirewallChange.eDoc.Request.Node"> <activationType>P</activationType> </start> <requests name="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node"> <activationType>P</activationType> <ruleTemplate>RequestFirewallChange.eDoc.ReviewCurrentConfiguration.RuleTemplate</ruleTemplate> </requests> <split name="RequestFirewallChange.eDoc.isUrgent.Split" /> <requests name="RequestFirewallChange.eDoc.FulfillUrgentRequest.Node"> <activationType>P</activationType> <ruleTemplate>RequestFirewallChange.eDoc.FulfillUrgentRequest.RuleTemplate</ruleTemplate> </requests> <requests name="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node"> <activationType>P</activationType> <ruleTemplate>RequestFirewallChange.eDoc.ReviewUrgentRequest.RuleTemplate</ruleTemplate> </requests> <requests name="RequestFirewallChange.eDoc.ReviewRequest.Node"> <activationType>P</activationType> <ruleTemplate>RequestFirewallChange.eDoc.ReviewRequest.RuleTemplate</ruleTemplate> </requests> <requests name="RequestFirewallChange.eDoc.FulfillRequest.Node"> <activationType>P</activationType> <ruleTemplate>RequestFirewallChange.eDoc.FulfillRequest.RuleTemplate</ruleTemplate> </requests> <join name="RequestFirewallChange.eDoc.isUrgent.Join" /> <requests name="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node"> <activationType>S</activationType> <ruleTemplate>RequestFirewallChange.eDoc.AcknowledgeConfiguration.RuleTemplate</ruleTemplate> <mandatoryRoute>false</mandatoryRoute> <finalApproval>false</finalApproval> </requests> </routeNodes> </documentType> </documentTypes> </data> |
Create the eDocLite Form
Based on the request details required by our process above (way above), we now build the form for the users to enter those details into.
...
- The eDocLite Form Skeleton
The Form Skeleton is the structure of the entire eDocLite form minus the Form Definition and Form Stylesheet. We separate this out so that you can use it as a base template for all of your eDocLite forms. This particular skeleton follows the scheme of the out-of-the-box Kuali Rice forms. The scheme uses the same look and feel and makes calls to the eDocLite widgets on the Kuali Rice server.Code Block title RequestFirewallChange.eDoc.Form.xml <?xml version="1.0" encoding="UTF-8"?> <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData"> <edoclite xmlns="ns:workflow/EDocLite" xsi:schemaLocation="ns:workflow/EDocLite resource:EDocLite"> <edl name="RequestFirewallChange.eDoc.Form" title="Request Firewall Change"> <security /> <createInstructions>** Fields with an asterisk are required.</createInstructions> <instructions>** Fields with an asterisk are required.</instructions> <validations /> <attributes /> ... ... </edl> <style name="RequestFirewallChange.eDoc.Style"> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my-class="xalan://edu.iu.uis.eden.edl.WorkflowFunctions" version="1.0"> <xsl:include href="widgets" /> <xsl:output indent="yes" method="html" omit-xml-declaration="yes" version="4.01" /> <xsl:variable name="actionable" select="/documentContent/documentState/actionable" /> <xsl:variable name="docHeaderId" select="/documentContent/documentState/docId" /> <xsl:variable name="editable" select="/documentContent/documentState/editable" /> <xsl:variable name="globalReadOnly" select="/documentContent/documentState/editable != 'true'" /> <xsl:variable name="docStatus" select="//documentState/workflowDocumentState/status" /> <xsl:variable name="isAtNodeInitiated" select="my-class:isAtNode($docHeaderId, 'Initiated')" /> <xsl:variable name="isPastInitiated" select="my-class:isNodeInPreviousNodeList('Initiated', $docHeaderId)" /> <xsl:variable name="isUserInitiator" select="my-class:isUserInitiator($docHeaderId)" /> <xsl:param name="overrideMain" select="'true'" /> <xsl:template name="mainForm"> <html xmlns=""> <head> <script language="javascript" /> <xsl:call-template name="htmlHead" /> </head> <body onload="onPageLoad()"> <xsl:call-template name="errors" /> <xsl:call-template name="header" /> <xsl:call-template name="instructions" /> <xsl:variable name="formTarget" select="'EDocLite'" /> <form action="{$formTarget}" enctype="multipart/form-data" id="edoclite" method="post" onsubmit="return validateOnSubmit(this)"> <xsl:call-template name="hidden-params" /> <xsl:call-template name="mainBody" /> <xsl:call-template name="notes" /> <br /> <xsl:call-template name="buttons" /> <br /> </form> <xsl:call-template name="footer" /> </body> </html> </xsl:template> <xsl:template name="mainBody"> ... ... </xsl:template> <xsl:template name="nbsp"> <xsl:text disable-output-escaping="yes">&nbsp;</xsl:text> </xsl:template> </xsl:stylesheet> </style> <association> <docType>RequestFirewallChange.eDoc.ChildDocType</docType> <definition>RequestFirewallChange.eDoc.Form</definition> <style>RequestFirewallChange.eDoc.Style</style> <active>true</active> </association> </edoclite> </data>
- Form Definition
The Form Definition defines the data entry fields on the form. Our definitions define field display characteristics and field validations. Place your form definition between the <edl> and </edl> tags in the Form Skeleton.Code Block title RequestFirewallChange.eDoc.Form.xml <fieldDef name="dateOfChange" title="Date and Time for Change"> <display> <type>text</type> </display> <validation required="true"> <regex>^[0-1]?[0-9](/|-)[0-3]?[0-9](/|-)[1-2][0-9][0-9][0-9]$</regex> <message>Enter a valid date in the format mm/dd/yyyy.</message> </validation> </fieldDef> <fieldDef name="descriptionOfChange" title="Description of the Port Change"> <display> <type>textarea</type> <meta> <name>rows</name> <value>5</value> </meta> <meta> <name>cols</name> <value>60</value> </meta> <meta> <name>wrap</name> <value>hard</value> </meta> </display> <validation required="true"> <message>Enter a description of the port change.</message> </validation> </fieldDef> <fieldDef attributeName="RequestFirewallChange.eDoc.isUrgent.RuleAttribute" name="isUrgent" title="URGENT"> <display> <type>select</type> <values title="NO">NO</values> <values title="YES">YES</values> </display> <validation required="true"> <message>Is this request URGENT?</message> </validation> </fieldDef> <fieldDef name="ingressEgressCharacteristic" title="Ingress/Egress Characteristic"> <display> <type>textarea</type> <meta> <name>rows</name> <value>5</value> </meta> <meta> <name>cols</name> <value>60</value> </meta> <meta> <name>wrap</name> <value>hard</value> </meta> </display> <validation required="true"> <message>Enter the ingress/egress characteristic.</message> </validation> </fieldDef> <fieldDef name="destinationSourceSpecification" title="Destination/Source Specification"> <display> <type>textarea</type> <meta> <name>rows</name> <value>5</value> </meta> <meta> <name>cols</name> <value>60</value> </meta> <meta> <name>wrap</name> <value>hard</value> </meta> </display> <validation required="true"> <message>Enter the destination/source specification.</message> </validation> </fieldDef> <fieldDef name="termOfRuleChange" title="Term of Rule Change (indefinite or otherwise)"> <display> <type>text</type> <meta> <name>size</name> <value>50</value> </meta> </display> <validation required="true"> <message>Enter term of the rule change.</message> </validation> </fieldDef> <fieldDef name="relatedProject" title="Project Related to Requested Rule(s) Change"> <display> <type>text</type> <meta> <name>size</name> <value>50</value> </meta> </display> <validation required="true"> <message>Enter a related project to the requested rule change.</message> </validation> </fieldDef>
- Form Stylesheet
The Form Stylesheet defines the layout of the form and renders the fields from our Form Definition onto the form. Our layout is an HTML table with a row for each field. In this case, we are customizing the mainBody piece of the stylesheet. In general, place your form stylesheet between the <style> and </style> tags in the Form Skeleton.Code Block title RequestFirewallChange.eDoc.Form.xml <xsl:template name="mainBody"> <table xmlns="" align="center" border="0" cellpadding="0" cellspacing="0" class="bord-r-t" width="80%"> <tr> <td align="left" border="3" class="thnormal" colspan="1"> <br /> <h3> University of California, Davis <br /> eDoclite Tutorial </h3> <br /> </td> <td align="center" border="3" class="thnormal" colspan="2"> <br /> <h2>Request Firewall Change Form</h2> </td> </tr> <tr> <td class="headercell5" colspan="100%"> <b>Request Details</b> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'dateOfChange'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'dateOfChange'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'descriptionOfChange'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'descriptionOfChange'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'isUrgent'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'isURgent'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'ingressEgressCharacteristic'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'ingressEgressCharacteristic'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'destinationSourceSpecification'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'destinationSourceSpecification'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'termOfRuleChange'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'termOfRuleChange'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> <tr> <td class="thnormal"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'relatedProject'" /> <xsl:with-param name="renderCmd" select="'title'" /> </xsl:call-template> <font color="#ff0000">*</font> </td> <td class="datacell"> <xsl:call-template name="widget_render"> <xsl:with-param name="fieldName" select="'relatedProject'" /> <xsl:with-param name="renderCmd" select="'input'" /> <xsl:with-param name="readOnly" select="$isPastInitiated" /> </xsl:call-template> </td> </tr> </table> <br xmlns="" /> <xsl:template>
Create Rule Attributes
Here we create a Rule Attribute that is associated with the isUrgent field in the form. Let's use <process name>.eDoc.<rule attribute name>.RuleAttribute to name our rule attributes and <process name>.eDoc.RuleAttributes to name the associated XML file defining our collection of rule attributes.
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?> <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData"> <ruleAttributes xmlns="ns:workflow/RuleAttribute" xsi:schemaLocation="ns:workflow/RuleAttribute resource:RuleAttribute"> <ruleAttribute> <name>RequestFirewallChange.eDoc.isUrgent.RuleAttribute</name> <className>edu.iu.uis.eden.routetemplate.xmlrouting.StandardGenericXMLRuleAttribute</className> <label>Request Firewall Change Is Urgent Rule Attribute</label> <description>Request Firewall Change Is Urgent Rule Attribute</description> <type>RuleXmlAttribute</type> <routingConfig> <fieldDef name="isUrgent" title="URGENT" workflowType="ALL"> <display> <type>select</type> <values title="NO">NO</values> <values title="YES">YES</values> </display> <validation required="true" /> <fieldEvaluation> <xpathexpression>//isUrgent = wf:ruledata('isUrgent')</xpathexpression> </fieldEvaluation> </fieldDef> <xmlDocumentContent> <isUrgent>%isUrgent%</isUrgent> </xmlDocumentContent> </routingConfig> </ruleAttribute> </ruleAttributes> </data> |
Create Rule Templates
Here we create several Rule Templates that are applied to each route node. Let's use <process name>.eDoc.<rule template name>.RuleTemplate to name our rule templates and <process name>.eDoc.RuleTemplates to name the associated XML file defining our collection of rule templates.
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?> <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData"> <ruleTemplates xmlns="ns:workflow/RuleTemplate" xsi:schemaLocation="ns:workflow/RuleTemplate resource:RuleTemplate"> <ruleTemplate> <name>RequestFirewallChange.eDoc.ReviewCurrentConfiguration.RuleTemplate</name> <description>ReviewCurrentConfiguration RuleTemplate</description> </ruleTemplate> <ruleTemplate> <name>RequestFirewallChange.eDoc.FulfillUrgentRequest.RuleTemplate</name> <description>FulfillUrgentRequest RuleTemplate</description> </ruleTemplate> <ruleTemplate> <name>RequestFirewallChange.eDoc.ReviewUrgentRequest.RuleTemplate</name> <description>ReviewUrgentRequest RuleTemplate</description> </ruleTemplate> <ruleTemplate> <name>RequestFirewallChange.eDoc.ReviewRequest.RuleTemplate</name> <description>ReviewRequest RuleTemplate</description> </ruleTemplate> <ruleTemplate> <name>RequestFirewallChange.eDoc.FulfillRequest.RuleTemplate</name> <description>FulfillRequest RuleTemplate</description> </ruleTemplate> <ruleTemplate> <name>RequestFirewallChange.eDoc.AcknowledgeConfiguration.RuleTemplate</name> <description>AcknowledgeConfiguration RuleTemplate</description> <attributes> <attribute> <name>Initiator.Role.RuleAttribute</name> <required>true</required> </attribute> </attributes> </ruleTemplate> </ruleTemplates> </data> |
Create Routing Rules
Finally, we create Routing Rules that is associated with RequestFirewallChange.eDoc.ChildDocType and its associated rule templates. Let's use <process name>.eDoc.RoutingRules to name the associated XML file defining our collection of routing rules.
...
Note: | actionRequested codes: A = APPROVE, K = ACKNOWLEDGE |
XML File Ingestion
- Open the URL to a Kuali Rice development server (e.g. http://ricedevhost.ucdavis.edu:8080/rice-0.9.3-server/)
- Click on Kuali Enterprise Workflow
- Log in as admin
- Under Administration, click on XML Ingester
- Upload the XML files we created in the following order:
Rule Attributes
RequestFirewallChange.eDoc.RuleAttributes.xml
Rule Templates
RequestFirewallChange.eDoc.RuleTemplates.xml
Parent Document Type
RequestFirewallChange.eDoc.ParentDocType.xml
Child Document Types
RequestFirewallChange.eDoc.ChildDocType.xml
EDL Form
RequestFirewallChange.eDoc.Form.xml
Routing Rules:
RequestFirewallChange.eDoc.RoutingRules.xml
Simulate the Business Process
First, let's simulate a Firewall Change Request that gets approved by someone in the Firewall Policy Group:
- Log in as requester1
- Click on EDocLites
- Click Search
- Find the eDocLite whose Definition Name is RequestFirewallChange.eDoc.Form
- Click on Create Document
- Here's the form we built:
- Fill out the form, set URGENT to NO and click route
- Log in as DES1
- Click on Action List
- Find and open the document initiated by requester1. Its status should be ENROUTE
- Click on the document and it should look like so:
- Click approve
- Log in as FPG1
- Click on Action List
- Find and open the document initiated by requester1 and approved by DES1. Its status should be ENROUTE
- Click approve
- Login as DCCS1
- Click on Action List
- Find and open the document initiated by requester1, approved by DES1, and approved by FPG1. Its status should be PROCESSED
- Click acknowledge
- Log in as requester1 again
- Click on Action List
- Find and open the document initiated by requester1, approved by DES1, approved by FPG1, and acknowledged by DCCS1. Its status should be PROCESSED
- Click acknowledge
- Click Document Search
- Find the document again
- Click on the Log icon
- The log should like like so:
Create Validation Checklists
Let's build a checklist that the QA team can use to validate the above simulation:
...
Requested Node | Action | Taken By |
RequestFirewallChange.eDoc.Request.Node | Fill out form, set URGENT to NO, click route | requester1 |
RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node | Click approve | DES1 |
RequestFirewallChange.eDoc.ReviewRequest.Node | Click disapprove | FPG1 |
RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node | Click acknowledge | requester1 |
Reference
https://test.kuali.org/confluence/display/KULRICE/EDocLite+Documentation+Guide
https://test.kuali.org/confluence/display/KULRICE/eDocLite+Example+1