== The Leave workflow application == (not up to date) Follow instructions in the [https://opensvn.csie.org/goflow/trunk/INSTALL.TXT INSTALL.TXT] file included in the [https://opensvn.csie.org/goflow/trunk/goflow goflow distribution]. You can then play with the leave demo application (available [wiki:GoFlow:demo online] too). You will find here some details of the leave application implementation. === defining the workflow process === First, let's take a look at the process definition; the process is stored in the database, by using entities like Process, Activities, Transitions, Application (see workflow/models.py, and the [http://goflow.alwaysdata.net/images/workflow.png goflow data model] generated by modelviz/graphviz). In the leavedemo project, the process is dumped with the django dumpdata utility, and provided as a fixture. Typically, when you want to define a process, you will use the admin web console. So, the process is the following: http://goflow.alwaysdata.net/leavedemo/media/img/leaveactivities.png below, the process translated as django entities, with a python syntax (it is not a real code, it's just more readable by humans): {{{ Process(title='leave', begin='Begin', end='End') Activity(title='Begin', application='checkstatus', pushApplication='route_to_secretary', splitMode='xor', roles=('secretary',)) Activity(title='Approval', application='approvalform', pushApplication='route_to_supervisor', splitMode='xor', roles=('secretary',)) Activity(title='Refinement', application='refine', pushApplication='route_to_customer', joinMode='xor', splitMode='xor') Activity(title='UpdateHR', application='hrform', pushApplication='route_to_secretary', roles=('supervisor',)) Activity(title='End', application='finalinfo', pushApplication='route_to_customer', joinMode='xor', roles=('secretary',), autoFinish=False) Transition(name='send_to_approval', input = 'Begin', output='Approval', condition="instance.condition=='OK: Forward to supervisor'") Transition(name='send_to_refinement', input = 'Begin', output='Refinement', condition="instance.condition=='Denied: Back to requester'") Transition(name='request_approved', input = 'Approval', output='UpdateHR', condition="instance.condition=='OK: Forward to secretary'") Transition(name='not_approved', input = 'Approval', output='Refinement', condition="instance.condition=='Denied: Back to requester'") Transition(name='tell_employee', input = 'UpdateHR', output='End') Transition(name='cancel_request', input = 'Refinement', output='End', condition="instance.condition=='Withdraw request'") Transition(name='re_request', input = 'Refinement', output='Begin', condition="instance.condition=='Re-request'") }}} this [http://goflow.alwaysdata.net/images/leave.png diagram] is a graphviz dot representation. It has written by hand, but soon, it should be generated. '''Some definitions:''' [[BR]]A ''transition'' is a path from an ''Activity'' to another one. [[BR]]An ''Activity'' is a task that a person (or an automatic process) with a specific role must achieve: it is linked to an ''Application'' which is typically an URL declared in the ''urls.py'' file. [[BR]]A ''push application'' is a handler that return a user, given the context of process instance (in fact the parameter of the handler is a ''workitem'', we will see this later) === settings file === ''(a little obsolete since rev 14)'' ==== standard settings ==== First, tell Django you want to use the workflow engine: {{{ INSTALLED_APPS = ( .... 'leavedemo.leave', # the leave application 'goflow.workflow', # goflow workflow engine ) }}} If you use ''send_mail'' application, you should define these: {{{ DEFAULT_FROM_EMAIL = email sender EMAIL_HOST = smtp server }}} ==== specific settings ==== {{{ WF_APPS_PREFIX = 'leavedemo' }}} This is the url prefix for workflow application definition; for example, in the workflow definition the application ''app1'' is mapped on the url ''/leavedemo/app1'' {{{ WF_PUSH_APPS_PREFIX = 'leavedemo.leave.pushapplications' }}} this is the module containing the push applications functions; for example, the push application ''pushapp1'' is a function defined as following in the ''leavedemo/leave/pushapplications.py'' module: {{{ def pushapp1(workitem): ... return aUser }}} If you use ''send_mail'' application, you should define these: {{{ EMAIL_SUBJECT_PREFIX = '[Goflow notification]' }}} === urls.py file === ==== Starting a workflow instance ==== the ''start_application'' is a handler that display a form used to create an instance of the workflow process: usage: {{{ (r'^leave/start/(app)/(model)/$', 'goflow.workflow.applications.start_application'), }}} This above is the simplest way to start: the default process has the same name as app, and the default template used is "start_[model].html". other usage: {{{ (r'^leave/request/$', 'goflow.workflow.applications.start_application', {'process_name':'leave', 'form_class':RequestForm, 'template':'start_leave.html'}), }}} ''New:'' see ''workflow urls'' below: an instance can be started with just a model (see also leave demo) ==== Simple info application ==== the only parameter is a template; this application just shows an inf panel to a user. {{{ (r'^leave/finalinfo/$', 'goflow.workflow.applications.simple_application', {'template':'finalinfo.html'}), }}} ==== Form application ==== this application displays a form to the user: by clicking on a submit button, the activity is terminated with the instance condition set to the submit button value (label displayed) {{{ (r'^leave/checkstatus/$', 'goflow.workflow.applications.application_form', {'form_class':ApprovalForm, 'template':'checkstatus.html', 'submit_name':'approval'}), }}} ==== Custom applications ==== for more advanced usages, you may write your own applications: for this, take a look at the application form code (see above) and copy-paste the code in your project (in an applications.py file) and customize it; one advantage is that the urls.py file can be quite simpler (less parameters on the application url line). === workflow urls === Some urls are workflow standard tasks, managed by the engine itself; like CRUD urls managed by admin, the workflow standard tasks are available with the following line in the ''urls.py'' file: {{{ (r'^leave/', include('goflow.workflow.urls')), }}} So the workflow engine provides handlers and default templates below: {{{ (r'^mywork/$', 'goflow.workflow.views.mywork', {'template':'mywork.html'}), (r'^otherswork/$', 'goflow.workflow.views.otherswork', {'template':'otherswork.html'}), (r'^otherswork/instancehistory/$', 'goflow.workflow.views.instancehistory', {'template':'instancehistory.html'}), (r'^myrequests/$', 'goflow.workflow.views.myrequests', {'template':'myrequests.html'}), (r'^myrequests/instancehistory/$', 'goflow.workflow.views.instancehistory', {'template':'instancehistory.html'}), (r'^mywork/activate/$', 'goflow.workflow.views.activate', {'template':'activate.html'}), (r'^mywork/complete/$', 'goflow.workflow.views.complete', {'template':'complete.html'}), (r'^start/(?P.*)/(?P.*)/$', 'goflow.workflow.applications.start_application'), (r'^cron/$','django.contrib.workflow.views.cron'), }}} * ''mywork'': displays the tasks list of the current user * .... * ''start'': start a new instance given a model * ''cron'': cron simulation task for timeout management ''next soon'' === Application templates === You can (may) redefine the templates associated with standard workflow views. For each application, a specific template has to be built. The context available has following variales: * ''form'': form (newforms framework) * ''instance'': instance object * ''ob'': object (application-defined) linked to instance * ''instance_props'': properties of instance The application developper should insert submit input fields when he inserts forms; the ''application_form'' handler then will update ''instance.condition'' with the value of the submit button pressed.