[ruote:2183] Couple of questions regarding ruote.

20 views
Skip to first unread message

Eric

unread,
Apr 16, 2010, 4:48:06 PM4/16/10
to ruote
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)
Ruote.process_definition :name => 'test',:time_out => '7d' do
cursor do
set :v => "billing_clerk", :value => "me"
set :v => "invoice_id", :value => invoice_id
set :v => "message", :value => "$:r{some_value}"
billing_clerk
set :v => "message", :value => "$:r{some_value}"
set :f => "reason", :value => "This is a great invoice"
biller_reviewer
payer_reviewer
end
:on_error
sequence {admin }
:on_timeout
sequence {admin }
end




My question is how do I manipulate the workflow once it is in process.
Can I or the administrator rewind,jump,skip, or insert directly or
does it have to be hardwired in the process definition? 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.

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.

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.

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).
How do you change a workitem in process if I need to change people in
those roles? ( they get hired,fired or transfered)

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?

Thanks
Eric smith


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

John Mettraux

unread,
Apr 16, 2010, 11:00:46 PM4/16/10
to openwfe...@googlegroups.com
On Sat, Apr 17, 2010 at 5:48 AM, Eric <erics...@gmail.com> 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
Reply all
Reply to author
Forward
0 new messages