Topic: wftk -- Process definition example -- chair purchase

wftk home ] [ process definition ] [ discussion ]
This is an example definition of the process in the chair purchase scenario. Wish me luck.

<?xml version="1.0"?>

<workflow name="Purchase request" author="Michael:">
  <role name="Supervisor"></role>
  <role name="Purchasing"></role>
  <role name="Accounting"></role>
  <role name="Receiving"></role>

  <data name="Product requested" type="text"></data>
  <data name="Reason for request" type="text"></data>
  <data name="Requester's email" type="text"></data>

    <task label="Approval" role="Supervisor">
      <data name="Approval code" type="text"></data>
      <!-- You know, something like an HTML select box would be appropriate here. -->

    <if expr="${Approval code} == 'No'">
      <situation name="Request rejected"></situation>

    <task label="Order item" role="Purchasing">
      <data name="Purchasing record" type="text"></data>

    <alert type="email" to="${Requester's email}">
      Your request for the purchase of ${Product requested} has been approved and the
      order was placed.  The purchasing record is ${Purchasing record} if you need to
      contact Purchasing for inquiries.

    <alert type="role" to="Accounting">
      An order for ${Product requested} has been placed.

    <alert type="role" to="Receiving">
      An order for ${Product requested} has been placed.  Expect delivery.

        <task label="Receive ${Product requested}" role="Receiving"></task>
        <alert type="email" to="${Requester's email}">
          Your requested ${Product requested} has arrived.

      <task label="File invoice" role="Accounting">
        <data name="Invoice number" type="text"></data>

    <task label="Pay invoice" role="Accounting"></task>
    <alert type="role" to="Purchasing">
      The purchase has been paid.

  <handle situation="Request rejected">
    <alert type="email" to="${Requester's email}">
      Your request for ${Product requested} has been rejected by your supervisor.
So let's talk about this. I pretty much just sat down and hacked this out, making up syntax as I went. Let's talk about the parts I made up, and the parts that I already had planned.
  • Variable interpolation
    You'll notice the syntax I used for using variable values: ${variable name}. This is borrowed from Tcl and Perl; I found that without assuming accessibility to variable values I really couldn't even express this simple scenario. So regardless of what other scripty kinds of things we need to be able to do, we certainly need to be able to insert the values of variables into strings. I use this mostly in the text for alerts, but also for the "to" value for alerts which go back to the requester.
  • Role alert
    The alert type="role" is something which seemed natural. Messages to role queues should be handled, uh, well, not sure yet. If a purchasing clerk has already been assigned, then it's probably logical that that person would receive a role alert. This is another area where actual usage of the prototype system will help us make sense of things.
  • Use of situation to break sequence
    To my surprise, the situation tag just seemed completely intuitive in the case shown here. So maybe the situation concept is a good cover for exceptions. I guess a couple more example process definitions will shed light on that question.
  • Exclusion of supplier from system
    When I originally drew the diagram in the original chair scenario, it seemed logical to include the supplier in order to make the flow easier to see. But when writing this definition, it seemed illogical to include the supplier in the internal roles, as the supplier will obviously be another company (and that seemed to be the reaction of the group to the original diagram, too...) At any rate, I had to include another task for Accounting in order to make it all make sense. So this definition doesn't quite correspond to the diagram. Ah well. We pick up the pieces and get on with life, right?
  • Parallel block
    Note the use of a parallel block for the two tasks receiving something back from the supplier (the chair and the invoice). This parallelism reflects the fact that we don't know what we'll get first. So both tasks have to be active in order for them to be fulfillable. Since receipt of the chair is supposed to alert the requester, there's a sequence nested within that block. (If the alert simply followed the receipt task, then the alert would fire as soon as the chair was ordered. Which is not what we want.)
  • Implicit situation?
    It would seem that if a task is rejected, that an implicit situation is generated which breaks the chain of events. I guess by saying that I'm also buying into the idea of exception-as-situation. The question is, how should such a situation be named? How should a handler be written, given that a single handler would logically be written to handle rejection at any one of several steps? This question needs some more thought. But the problem with handling rejection as a situation is that we've got no way to get the process back on track should the rejection be cleared up. Messy.
Anyway, I found this a pretty intuitive way to represent what I perceived to be the original workflow. Of course, most people using this system won't compose the XML by hand, but if it's easy to represent a workflow with this setup, then tools will also be relatively easy to write. Onwards.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.