On Sat, Apr 17, 2010 at 5:48 AM, Eric <[email protected]> wrote:
>
> I am new to ruote and have a couple of questions about process
> administration.
>
> 1.) I have a process for an invoice approval workflow that looks like
> this:
>
> def invoice_workflow(invoice_id)
>  (...)
> end

Hello Eric,

allow me some rewrite and commenting : (http://gist.github.com/369195)

---8<---

def invoice_workflow (invoice_id)

  Ruote.process_definition(
    :name => 'test',
    :timeout => '7d',
    #:on_error => 'admin',
    :on_timeout => 'admin'
      #
      # when no on_error is specified process instances stop on error and
      # it's up to the admin to unstuck them, I think you're OK with this
      # behaviour
      #
      # note that on_error and on_timeout do cancel the process / segment of
      # process they are bound to before executing the subprocess/participant
      # referred to, maybe it's not what you want
  ) do

    # Note that variables stay in the engine, they are not visible [directly]
    # to the participant, while [workitem] fields are the payload of workitems
    # and participants set/read them

    set 'invoice_id' => invoice_id
      # as a preliminary step before the 'body' of the process

    cursor do

      set 'v:billing_clerk' => 'me'
        # note that this will 'route' the workitem for the
        # participant/subprocess 'billing_clerk' to the participant/subprocess
        # 'me'

      billing_clerk :message => '${r:some_value}'

      #set 'message' => '${r:some_value}'
      #set 'reason' => 'This is a great invoice'
      biller_reviewer :task => 'review the invoice ${r:some_value}'

      payer_reviewer

      jump :to => 'billing_clerk', :if => '${not_ok}'
        # if the payer_reviewer set the workitem field 'not_ok' to true,
        # the cursor/flow will jump to the 'billing_clerk' step

      participant :ref => '${someone_adhoc}', :if => '${someone_adhoc}'
        # if there is a field 'someone_adhoc', a workitem is handed to
        # the participant named in that field
    end
  end
end

--->8---

I like your process definition generation method, it's an excellent technique.


> My question is how do I manipulate the workflow once it is in process.

I have started to gather some documentation at

  http://ruote.rubyforge.org/process_administration.html

but haven't had the time to go on with it.

> Can I or the administrator rewind,jump,skip, or insert directly or
> does it have to be hardwired in the process definition?

The administrator can directly manipulate process instances.

In the case of a cursor, the most straightforward technique is for the
admin to take the workitem of a user and reply in its place.

It's possible to directly edit process instances, it's advanced /
surgical. Maybe better to leave that for "further questions". I
certainly have to document it.

> The problem
> comes up because the workflow may have adhoc components by any
> participant in the chain. They could each either approve, reject or
> forward a bill and I am not sure what the best way to express it is.

Maybe a repeat loop could be effective :

---8<---
sequence do

  # ...

  set 'target' => 'alfred'
  repeat do
    participant '${target}'
    stop :unless => '${target}'
  end

  # ...
end
--->8---

Participants can determine who is the next 'target' until one of them
'blanks' that 'target' field and the loop exits (flow resumes). A few
lines from here I explain another different technique for user
assignment.

> A couple of examples:
>
> a.) The administrator notices that the payer_reviewer is on vacation
> and wants to route the bill to someone else for approval.

I will answer after, along with 2)

> b.) The payer_review wants to forward the bill to someone  adhoc.
>
> c.) The_payer_review wants to route the bill back to the billing
> clerk.

The rewritten process above has an example for both b) and c). Of
course there are other techniques.

> 2.) Regarding participants ,I have hundreds of user who fall into
> different roles. What is the best practice for creating role based
> participants and how should they be represented  (user_id,email,etc).

There is no "best practice", it all depends. Ruote doesn't try to
force a technique on you.

What I use these days : workitems have a "user" field. The participant
name is a role name (or an action name in the case of a non-human
participant).

I let users re-assign workitems by changing the value of the workitem
'user' field.

For humans, there is / could be one catch-all participant and users
may access workitems based on their role (participant name) and their
user name, for example, a workitem may be for the "billing_reviewer"
participant and currently assigned to the user "Bill", when the user
field is not set, the workitem is considered "unassigned".

(catch all participant :
http://groups.google.com/group/openwferu-users/search?group=openwferu-users&q=catchall
)


> How do you change a workitem in process if I need to change people in
> those roles? ( they get hired,fired or transfered)

When someone leaves the organization, I'd write a script that takes
all the workitems and blanks their "user" field if it is currently set
to the username of the person who left.

There is one slight disadvantage to use the role/participant -
user/username, it's when leveraging participant timeouts :

  billing_reviewer :timeout => '3d'

Three days after the task showed up, the timeout will trigger, it's
not "three days after the task was assigned to user 'bill'".

If you use the "hot potato" repeat loop shown above, a timeout per
user / assignment is possible.

With a catchall participant (ie a store participant that catches
workitems for any unknown participant names), you could also use
conventions like "user_bill" or "role_ceo" or simply, directly, "bill"
and "ceo" and not use a "user" workitem field.

These days I tend to things like :

---8<---
sequence do
  team_a :task => 'batch reception'
  team_b :task => 'batch testing'
  coordinator :task => 'batch validation'
end
--->8---

Where participant names are mapped to teams or roles and a task
[description] is passed. Since it's a Rails application, I determine
which "form" (view) to use based on the task [description].

Many possibilities.


> 3.) The docs are a little confusing about using active record to
> persist the datastore. Is it still supported? if so is there a sample
> for this?

Sorry, there is currently no activerecord based storage for ruote 2.1 :

  http://ruote.rubyforge.org/configuration.html#storage

The DataMapper storage should coexist happily with any ActiveRecord install.


Questions / suggestions / critiques are welcome, best regards,

-- 
John Mettraux   -   http://jmettraux.wordpress.com

-- 
you received this message because you are subscribed to the "ruote users" group.
to post : send email to [email protected]
to unsubscribe : send email to [email protected]
more options : http://groups.google.com/group/openwferu-users?hl=en

Reply via email to