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
