add support for workflow roles, convert '_receiver' as one
This commit is contained in:
parent
2a31aceabd
commit
9ecdc0beb3
|
@ -100,9 +100,6 @@ class FormDefUI:
|
|||
form.add(SingleSelectWidget, 'workflow_id', title = _('Workflow'),
|
||||
value = formdef.workflow_id,
|
||||
options = [(None, _('Default Workflow'))] + workflows)
|
||||
form.add(SingleSelectWidget, 'receiver_id', title = _('Recipient Role'), required = True,
|
||||
value = formdef.receiver_id,
|
||||
options = get_user_roles())
|
||||
form.add(WidgetList, 'roles', title = _('Sender Roles'), element_type = SingleSelectWidget,
|
||||
hint = _('Only show this form to the given roles.'),
|
||||
value = formdef.roles,
|
||||
|
@ -127,7 +124,7 @@ class FormDefUI:
|
|||
raise ValueError()
|
||||
|
||||
for f in ('name', 'confirmation', 'signing', 'acl_read',
|
||||
'only_allow_one', 'receiver_id', 'category_id', 'disabled',
|
||||
'only_allow_one', 'category_id', 'disabled',
|
||||
'allow_drafts', 'workflow_id', 'private_status_and_history',
|
||||
'disabled_redirection', 'always_advertise',
|
||||
'publication_date', 'expiration_date'):
|
||||
|
@ -197,10 +194,43 @@ class FieldsDirectory(FieldsDirectory):
|
|||
' <a href="../enable?back=fields">%s</a>' % _('Enable')
|
||||
'</p>'
|
||||
|
||||
|
||||
class WorkflowRoleDirectory(Directory):
|
||||
def __init__(self, formdef):
|
||||
self.formdef = formdef
|
||||
|
||||
def _q_lookup [html] (self, component):
|
||||
if not component in self.formdef.workflow.roles:
|
||||
raise errors.TraversalError()
|
||||
|
||||
role_id = self.formdef.workflow_roles.get(component)
|
||||
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(SingleSelectWidget, 'role_id',
|
||||
value=role_id,
|
||||
options = get_user_roles())
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('.')
|
||||
|
||||
if not form.is_submitted() or form.has_errors():
|
||||
get_response().breadcrumb.append( ('role/%s' % component, _('Workflow Role')) )
|
||||
html_top('forms', title=self.formdef.name)
|
||||
'<p>%s</p>' % self.formdef.workflow.roles.get(component)
|
||||
form.render()
|
||||
else:
|
||||
if not self.formdef.workflow_roles:
|
||||
self.formdef.workflow_roles = {}
|
||||
self.formdef.workflow_roles[component] = form.get_widget('role_id').parse()
|
||||
self.formdef.store()
|
||||
redirect('..')
|
||||
|
||||
|
||||
class FormDefPage(Directory):
|
||||
_q_exports = ['', 'fields', 'delete', 'duplicate', 'export',
|
||||
'archive', 'invite', 'enable', 'workflow', 'category',
|
||||
'recipient', ('workflow-options', 'workflow_options'),
|
||||
'role', ('workflow-options', 'workflow_options'),
|
||||
('workflow-status-remapping', 'workflow_status_remapping'),
|
||||
'roles', 'title', 'options', ('acl-read', 'acl_read')]
|
||||
|
||||
|
@ -212,6 +242,7 @@ class FormDefPage(Directory):
|
|||
self.formdefui = FormDefUI(self.formdef)
|
||||
get_response().breadcrumb.append((component + '/', self.formdef.name))
|
||||
self.fields = FieldsDirectory(self.formdef)
|
||||
self.role = WorkflowRoleDirectory(self.formdef)
|
||||
|
||||
def _q_index [html] (self):
|
||||
html_top('forms', title = self.formdef.name)
|
||||
|
@ -255,14 +286,21 @@ class FormDefPage(Directory):
|
|||
'(<a href="workflow" rel="popup">%s</a>)' % _('change')
|
||||
'</li>'
|
||||
|
||||
'<li>%s ' % _('Recipient Role:')
|
||||
if self.formdef.receiver:
|
||||
'<a href="../../roles/%s/">%s</a>' % (
|
||||
self.formdef.receiver.id, self.formdef.receiver.name)
|
||||
if self.formdef.workflow.roles:
|
||||
'<li>%s ' % _('Workflow Roles:')
|
||||
'<ul>'
|
||||
for (wf_role_id, wf_role_label) in self.formdef.workflow.roles.items():
|
||||
'<li>%s ' % _('%s:') % wf_role_label
|
||||
role_id = self.formdef.workflow_roles.get(wf_role_id)
|
||||
if role_id:
|
||||
role = Role.get(role_id)
|
||||
'<a href="../../roles/%s/">%s</a>' % (role.id, role.name)
|
||||
else:
|
||||
'-'
|
||||
' '
|
||||
'(<a href="recipient" rel="popup">%s</a>)' % _('change')
|
||||
'(<a href="role/%s" rel="popup">%s</a>)' % (wf_role_id, _('change'))
|
||||
'</li>'
|
||||
'</ul>'
|
||||
'</li>'
|
||||
|
||||
'<li>%s ' % _('Sender Roles:')
|
||||
|
@ -363,26 +401,6 @@ class FormDefPage(Directory):
|
|||
self.formdef.store()
|
||||
redirect('.')
|
||||
|
||||
def recipient [html] (self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(SingleSelectWidget, 'receiver_id',
|
||||
value=self.formdef.receiver_id,
|
||||
options = get_user_roles())
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('.')
|
||||
|
||||
if not form.is_submitted() or form.has_errors():
|
||||
get_response().breadcrumb.append( ('recipient', _('Recipient Role')) )
|
||||
html_top('forms', title=self.formdef.name)
|
||||
'<p>%s</p>' % _('Select the role that will handle those forms.')
|
||||
form.render()
|
||||
else:
|
||||
self.formdef.receiver_id = form.get_widget('receiver_id').parse()
|
||||
self.formdef.store()
|
||||
redirect('.')
|
||||
|
||||
def roles [html] (self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(WidgetList, 'roles', title=_('Sender Roles'), element_type=SingleSelectWidget,
|
||||
|
@ -399,7 +417,7 @@ class FormDefPage(Directory):
|
|||
return redirect('.')
|
||||
|
||||
if not form.is_submitted() or form.has_errors():
|
||||
get_response().breadcrumb.append( ('recipient', _('Recipient Role')) )
|
||||
get_response().breadcrumb.append( ('roles', _('Sender Roles')) )
|
||||
html_top('forms', title=self.formdef.name)
|
||||
'<p>%s</p>' % _('Select the roles that can access this form.')
|
||||
form.render()
|
||||
|
@ -1018,8 +1036,6 @@ class FormsDirectory(AccessControlled, Directory):
|
|||
'(<a href="%s">' % formdef.disabled_redirection
|
||||
_('redirection')
|
||||
'</a>) '
|
||||
if formdef.receiver:
|
||||
misc.ellipsize(formdef.receiver.name, 50)
|
||||
'</p>'
|
||||
'</li>'
|
||||
'</ul>'
|
||||
|
|
|
@ -114,22 +114,22 @@ class RolePage(Directory):
|
|||
'</div>'
|
||||
|
||||
# list forms in two columns,
|
||||
# - 1 forms where the recipient is this role
|
||||
# - 1 forms where this role is affected by the workflow
|
||||
# - 2 forms where the sender is this role
|
||||
formdefs = FormDef.select()
|
||||
formdefs.sort(lambda x,y: cmp(x.name, y.name))
|
||||
receiver_formdefs = [x for x in formdefs if x.receiver_id == self.role.id]
|
||||
workflow_formdefs = [x for x in formdefs if x.is_of_concern_for_role_id(self.role.id)]
|
||||
sender_formdefs = [x for x in formdefs if self.role.id in (x.roles or [])]
|
||||
|
||||
'<div class="splitcontent-left">'
|
||||
'<div class="bo-block">'
|
||||
'<h3>%s</h3>' % _('Forms handled by this role')
|
||||
'<ul>'
|
||||
for formdef in receiver_formdefs:
|
||||
for formdef in workflow_formdefs:
|
||||
'<li><a href="../../forms/%s">' % formdef.id
|
||||
formdef.name
|
||||
'</a></li>'
|
||||
if not receiver_formdefs:
|
||||
if not workflow_formdefs:
|
||||
'<li>%s</li>' % _('no form associated to this role')
|
||||
'</ul>'
|
||||
'</div>'
|
||||
|
|
|
@ -129,7 +129,7 @@ def graphviz(workflow, url_prefix='', select=None, svg=True,
|
|||
if getattr(item, 'label', None):
|
||||
label = item.label
|
||||
if getattr(item, 'by', None):
|
||||
roles = render_list_of_roles(item.by)
|
||||
roles = workflow.render_list_of_roles(item.by)
|
||||
label += ' %s %s' % (_('by'), roles)
|
||||
else:
|
||||
label = item.render_as_line()
|
||||
|
@ -614,6 +614,7 @@ class WorkflowPage(Directory):
|
|||
'%s</h2>'% self.workflow.name
|
||||
get_session().display_message()
|
||||
|
||||
'<div class="splitcontent-left">'
|
||||
|
||||
'<div class="bo-block">'
|
||||
'<h3>%s</h3>' % _('Possible Status')
|
||||
|
@ -634,6 +635,24 @@ class WorkflowPage(Directory):
|
|||
'</li>'
|
||||
'</ul>'
|
||||
'</div>'
|
||||
|
||||
'</div>' # .splitcontent-left
|
||||
|
||||
'<div class="splitcontent-right">'
|
||||
'<div class="bo-block">'
|
||||
'<h3>%s</h3>' % _('Workflow Roles')
|
||||
'<ul id="roles-list" class="biglist">'
|
||||
for key, label in (self.workflow.roles or {}).items():
|
||||
'<li class="bliglistitem">'
|
||||
'<a href="#roles/%s">%s</a>' % (key, label)
|
||||
'</li>'
|
||||
'</ul>'
|
||||
'</div>'
|
||||
'</div>' # .splitcontent-right
|
||||
|
||||
'<br style="clear:both;"/>'
|
||||
|
||||
if self.workflow.possible_status:
|
||||
'<div class="bo-block">'
|
||||
htmltext(graphviz(self.workflow, include=True))
|
||||
'</div>' # bo-block
|
||||
|
|
|
@ -103,7 +103,7 @@ class RootDirectory(BackofficeRootDirectory):
|
|||
for formdef in FormDef.select(order_by='name', ignore_errors=True):
|
||||
if formdef.disabled:
|
||||
continue
|
||||
if user.is_admin or formdef.receiver_id in (user.roles or []):
|
||||
if user.is_admin or formdef.is_of_concern_for(user):
|
||||
append_form_entry(formdef)
|
||||
|
||||
if forms_with_pending_stuff:
|
||||
|
@ -185,7 +185,7 @@ class FormPage(Directory):
|
|||
user.is_admin = True
|
||||
if not user:
|
||||
raise errors.AccessUnauthorizedError()
|
||||
if not user.is_admin and not self.formdef.receiver_id in (user.roles or []):
|
||||
if not user.is_admin and not self.formdef.is_of_concern_for(user):
|
||||
if session.user:
|
||||
raise errors.AccessForbiddenError()
|
||||
else:
|
||||
|
|
|
@ -234,6 +234,16 @@ class FormData(StorableObject):
|
|||
return None
|
||||
return wf_status
|
||||
|
||||
def get_handling_role(self):
|
||||
# TODO: look at current status and return the role(s) actually
|
||||
# concerned by the handling of the formdata
|
||||
from workflows import get_role_translation
|
||||
from roles import Role
|
||||
try:
|
||||
return Role.get(get_role_translation(self, '_receiver'))
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def get_field_value(self, field):
|
||||
try:
|
||||
x = [x for x in self.formdef.fields if x.label == field][0]
|
||||
|
|
|
@ -65,10 +65,10 @@ class FormDef(StorableObject):
|
|||
name = None
|
||||
url_name = None
|
||||
fields = None
|
||||
receiver_id = None
|
||||
category_id = None
|
||||
workflow_id = None
|
||||
workflow_options = None
|
||||
workflow_roles = None
|
||||
roles = None
|
||||
discussion = False
|
||||
confirmation = True
|
||||
|
@ -135,6 +135,14 @@ class FormDef(StorableObject):
|
|||
del self.__dict__['public']
|
||||
changed = True
|
||||
|
||||
if self.__dict__.has_key('receiver_id'):
|
||||
# migration from a simple receiver role to workflow roles
|
||||
if not self.workflow_roles:
|
||||
self.workflow_roles = {}
|
||||
self.workflow_roles['_receiver'] = self.__dict__['receiver_id']
|
||||
del self.__dict__['receiver_id']
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.store()
|
||||
|
||||
|
@ -169,23 +177,6 @@ class FormDef(StorableObject):
|
|||
self.url_name = new_url_name
|
||||
return StorableObject.store(self)
|
||||
|
||||
|
||||
def get_receiver(self):
|
||||
if self.receiver_id:
|
||||
try:
|
||||
return Role.get(self.receiver_id)
|
||||
except KeyError:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
def set_receiver(self, role):
|
||||
if role:
|
||||
self.receiver_id = role.id
|
||||
elif self.receiver_id:
|
||||
self.receiver_id = None
|
||||
receiver = property(get_receiver, set_receiver)
|
||||
|
||||
def get_category(self):
|
||||
if self.category_id:
|
||||
try:
|
||||
|
@ -538,6 +529,17 @@ class FormDef(StorableObject):
|
|||
details.append('\n%s\n' % evo.comment)
|
||||
return '\n\n----\n\n' + '\n'.join(details)
|
||||
|
||||
def is_of_concern_for_role_id(self, role_id):
|
||||
if not self.workflow_roles:
|
||||
return False
|
||||
return (role_id in self.workflow_roles.keys())
|
||||
|
||||
def is_of_concern_for_user(self, user):
|
||||
for role_id in self.workflow_roles.keys():
|
||||
if role_id in (user.roles or []):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_user_allowed_read(self, user, formdata=None):
|
||||
if self.acl_read == 'all':
|
||||
return True
|
||||
|
@ -554,14 +556,13 @@ class FormDef(StorableObject):
|
|||
|
||||
if self.acl_read == 'roles':
|
||||
form_roles = (self.roles or [])
|
||||
if self.receiver:
|
||||
form_roles.append(self.receiver.id)
|
||||
form_roles.append([x for x in self.workflow_roles.keys() if x])
|
||||
if user_roles.intersection(form_roles):
|
||||
return True
|
||||
elif self.acl_read == 'owner':
|
||||
if formdata and formdata.is_submitter(user):
|
||||
return True
|
||||
if self.receiver and self.receiver.id in user_roles:
|
||||
if self.is_of_concern_for_user(user):
|
||||
return True
|
||||
elif self.acl_read == 'none':
|
||||
# no special permission for anybody, but the form will be viewable
|
||||
|
@ -569,7 +570,6 @@ class FormDef(StorableObject):
|
|||
pass
|
||||
|
||||
if formdata:
|
||||
if self.workflow_id:
|
||||
# formdef has workflow, get roles allowed some actions relative to
|
||||
# current status
|
||||
wf_status = formdata.get_workflow_status()
|
||||
|
@ -582,24 +582,24 @@ class FormDef(StorableObject):
|
|||
# action for submitter
|
||||
if formdata and formdata.is_submitter(user):
|
||||
return True
|
||||
elif role == '_receiver':
|
||||
# action for receiver
|
||||
status_action_roles.append(self.receiver_id)
|
||||
elif not (type(role) is str and role.startswith('_')):
|
||||
# action for another group
|
||||
status_action_roles.append(role)
|
||||
else:
|
||||
status_action_roles.append(
|
||||
get_role_translation(formdata.formdef, role))
|
||||
if user_roles.intersection(status_action_roles or []):
|
||||
return True
|
||||
else:
|
||||
# in default workflow, access is allowed for formdef.receiver_id
|
||||
return self.receiver_id in user_roles
|
||||
|
||||
return False
|
||||
|
||||
def is_user_allowed_read_status_and_history(self, user, formdata=None):
|
||||
if user and user.is_admin:
|
||||
return True
|
||||
if user and self.private_status_and_history and not self.receiver_id in (user.roles or []):
|
||||
|
||||
if user and user.roles:
|
||||
user_roles = set(user.roles)
|
||||
else:
|
||||
user_roles = set([])
|
||||
form_roles = [x for x in self.workflow_roles.keys() if x]
|
||||
if user and self.private_status_and_history and not user_roles.intersection(form_roles):
|
||||
return False
|
||||
return self.is_user_allowed_read(user, formdata=formdata)
|
||||
|
||||
|
|
|
@ -96,16 +96,18 @@ class FormStatusPage(Directory):
|
|||
else:
|
||||
TextsDirectory.get_html_text('form-recorded',
|
||||
vars={'date': tm, 'number': self.filled.id})
|
||||
if self.formdef.receiver and mine:
|
||||
if self.formdef.receiver.details:
|
||||
if mine:
|
||||
handling_role = self.filled.get_handling_role()
|
||||
if handling_role and handling_role.details:
|
||||
endpoint_status = self.formdef.workflow.get_endpoint_status()
|
||||
'<p>'
|
||||
if self.filled.status != 'finished':
|
||||
if self.filled.status in endpoint_status:
|
||||
_('Your case is handled by:')
|
||||
else:
|
||||
_('Your case has been handled by:')
|
||||
'</p>'
|
||||
'<p id="receiver">'
|
||||
htmltext(self.formdef.receiver.details.replace(str('\n'), str('<br />')))
|
||||
htmltext(handling_role.details.replace(str('\n'), str('<br />')))
|
||||
'</p>'
|
||||
'</div>'
|
||||
|
||||
|
|
|
@ -167,10 +167,14 @@ class FormPage(Directory):
|
|||
raise errors.AccessUnauthorizedError()
|
||||
if logged_users_role().id not in self.formdef.roles and not (
|
||||
self.user and self.user.is_admin):
|
||||
for q in (self.user and self.user.roles) or []:
|
||||
if q in self.formdef.roles or q == self.formdef.receiver_id:
|
||||
break
|
||||
if self.user:
|
||||
user_roles = set(user.roles)
|
||||
else:
|
||||
user_roles = set([])
|
||||
other_roles = (self.formdef.roles or [])
|
||||
if self.formdef.workflow_roles:
|
||||
other_roles.extend(self.formdef.workflow_roles.keys())
|
||||
if not user_roles.intersect(other_roles):
|
||||
raise errors.AccessForbiddenError()
|
||||
|
||||
def step [html] (self, no, page_no = 0, log_detail = None, data = None, editing = None):
|
||||
|
@ -944,21 +948,25 @@ class FormPage(Directory):
|
|||
else:
|
||||
self.step(1)
|
||||
|
||||
t = None
|
||||
if self.formdef.workflow:
|
||||
htmltext(filled.display_workflow_message())
|
||||
t = filled.display_workflow_message()
|
||||
|
||||
if t:
|
||||
htmltext(t)
|
||||
else:
|
||||
# behaviour without workflow set
|
||||
# behaviour if workflow doesn't display any message
|
||||
tm = misc.localstrftime(filled.receipt_time)
|
||||
'<div id="receipt-intro">'
|
||||
TextsDirectory.get_html_text('form-recorded',
|
||||
vars={'date': tm, 'number': filled.id})
|
||||
if self.formdef.receiver:
|
||||
if self.formdef.receiver.details:
|
||||
handling_role = filled.get_handling_role()
|
||||
if handling_role and handling_role.details:
|
||||
'<p>'
|
||||
_('Your case will be handled by:')
|
||||
'</p>'
|
||||
'<p id="receiver">'
|
||||
htmltext(self.formdef.receiver.details.replace(str('\n'), str('<br />')))
|
||||
htmltext(handling_role.details.replace(str('\n'), str('<br />')))
|
||||
'</p>'
|
||||
'</div>'
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from qommon.cron import CronJob
|
|||
from qommon import emails
|
||||
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class, \
|
||||
render_list_of_roles, get_role_translation
|
||||
get_role_translation
|
||||
|
||||
from wcs.roles import Role, logged_users_role, get_user_roles
|
||||
|
||||
|
@ -33,7 +33,7 @@ class AggregationEmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
def render_as_line(self):
|
||||
if self.to:
|
||||
return _('Aggregate for summary email to %s') % render_list_of_roles(self.to)
|
||||
return _('Aggregate for summary email to %s') % self.render_list_of_roles(self.to)
|
||||
else:
|
||||
return _('Aggregate for summary email (not completed)')
|
||||
|
||||
|
@ -43,8 +43,8 @@ class AggregationEmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
value = self.to,
|
||||
add_element_label = _('Add Role'),
|
||||
element_kwargs = {'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_receiver', _('Receiver')), ] + get_user_roles()})
|
||||
'options': [(None, '---')] +
|
||||
self.get_list_of_roles(include_logged_in_users=False)})
|
||||
|
||||
def get_parameters(self):
|
||||
return ('to',)
|
||||
|
|
|
@ -26,8 +26,7 @@ from qommon import errors
|
|||
|
||||
from qommon import tokens
|
||||
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class, \
|
||||
render_list_of_roles, get_role_translation
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class
|
||||
|
||||
from wcs.roles import Role, logged_users_role, get_user_roles
|
||||
from wcs.forms.common import FormStatusPage
|
||||
|
|
|
@ -138,7 +138,7 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
def render_as_line(self):
|
||||
if self.by:
|
||||
return _('Allow Addition of an Attachment by %s') % render_list_of_roles(self.by)
|
||||
return _('Allow Addition of an Attachment by %s') % self.render_list_of_roles(self.by)
|
||||
else:
|
||||
return _('Allow Addition of an Attachment (not completed)')
|
||||
|
||||
|
@ -171,11 +171,7 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
|
|||
value = self.by,
|
||||
add_element_label = _('Add Role'),
|
||||
element_kwargs={'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')),
|
||||
(logged_users_role().id, logged_users_role().name),
|
||||
(None, '----')] + get_user_roles()})
|
||||
'options': [(None, '---')] + self.get_list_of_roles()})
|
||||
if 'required' in parameters:
|
||||
form.add(CheckboxWidget, '%srequired' % prefix, title = _('Required'), value = self.required)
|
||||
if 'title' in parameters:
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
from wcs.qommon.humantime import *
|
||||
|
||||
from wcs.workflows import Workflow, WorkflowStatusJumpItem, register_item_class, \
|
||||
render_list_of_roles, get_role_translation
|
||||
from wcs.workflows import Workflow, WorkflowStatusJumpItem, register_item_class
|
||||
|
||||
from wcs.formdata import Evolution
|
||||
from qommon.form import *
|
||||
|
|
123
wcs/workflows.py
123
wcs/workflows.py
|
@ -16,6 +16,7 @@
|
|||
|
||||
from qommon import ezt
|
||||
from cStringIO import StringIO
|
||||
import copy
|
||||
|
||||
try:
|
||||
import elementtree.ElementTree as ET
|
||||
|
@ -81,12 +82,23 @@ class Workflow(StorableObject):
|
|||
name = None
|
||||
details = None
|
||||
possible_status = None
|
||||
roles = None
|
||||
|
||||
def __init__(self, name = None):
|
||||
StorableObject.__init__(self)
|
||||
self.name = name
|
||||
self.possible_status = []
|
||||
|
||||
def migrate(self):
|
||||
changed = False
|
||||
|
||||
if not self.__dict__.has_key('roles') or self.roles is None:
|
||||
self.roles = {'_receiver': _('Recipient')}
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.store()
|
||||
|
||||
def get(cls, id, ignore_errors=False, ignore_migration=False):
|
||||
if id == '_default':
|
||||
return cls.get_default_workflow()
|
||||
|
@ -208,6 +220,26 @@ class Workflow(StorableObject):
|
|||
return workflow
|
||||
import_from_xml_tree = classmethod(import_from_xml_tree)
|
||||
|
||||
def get_list_of_roles(self, include_logged_in_users=True):
|
||||
t = []
|
||||
t.append(('_submitter', _('Sender')))
|
||||
for workflow_role in self.roles.items():
|
||||
t.append(workflow_role)
|
||||
if include_logged_in_users:
|
||||
t.append((logged_users_role().id, logged_users_role().name))
|
||||
if get_user_roles():
|
||||
t.append((None, '----'))
|
||||
t.extend(get_user_roles())
|
||||
return t
|
||||
|
||||
def render_list_of_roles(self, roles):
|
||||
t = []
|
||||
for r in roles:
|
||||
role_label = get_role_translation_label(self, r)
|
||||
if role_label:
|
||||
t.append(role_label)
|
||||
return ', '.join(t)
|
||||
|
||||
def get_unknown_workflow(cls):
|
||||
workflow = Workflow(name=_('Unknown'))
|
||||
workflow.id = '_unknown'
|
||||
|
@ -219,6 +251,7 @@ class Workflow(StorableObject):
|
|||
|
||||
workflow = Workflow(name=_('Default'))
|
||||
workflow.id = '_default'
|
||||
workflow.roles = {'_receiver': _('Recipient')}
|
||||
just_submitted_status = workflow.add_status(_('Just Submitted'), 'just_submitted')
|
||||
just_submitted_status.visibility = ['_receiver']
|
||||
new_status = workflow.add_status(_('New'), 'new')
|
||||
|
@ -269,23 +302,44 @@ class Workflow(StorableObject):
|
|||
notify_change_user_email = None
|
||||
|
||||
if notify_new_receiver_email:
|
||||
notify_new_receiver_email.parent = just_submitted_status
|
||||
just_submitted_status.items.append(notify_new_receiver_email)
|
||||
if notify_new_user_email:
|
||||
notify_new_user_email.parent = just_submitted_status
|
||||
just_submitted_status.items.append(notify_new_user_email)
|
||||
|
||||
just_submitted_status.items.append(jump_to_new)
|
||||
|
||||
if notify_change_receiver_email:
|
||||
accepted_status.items.append(notify_change_receiver_email)
|
||||
notify_change_receiver_email.parent = accepted_status
|
||||
notify_change_receiver_email = copy.copy(notify_change_receiver_email)
|
||||
|
||||
rejected_status.items.append(notify_change_receiver_email)
|
||||
notify_change_receiver_email.parent = rejected_status
|
||||
notify_change_receiver_email = copy.copy(notify_change_receiver_email)
|
||||
|
||||
finished_status.items.append(notify_change_receiver_email)
|
||||
notify_change_receiver_email.parent = finished_status
|
||||
|
||||
if notify_change_user_email:
|
||||
accepted_status.items.append(notify_change_user_email)
|
||||
notify_change_user_email.parent = accepted_status
|
||||
notify_change_user_email = copy.copy(notify_change_user_email)
|
||||
|
||||
rejected_status.items.append(notify_change_user_email)
|
||||
notify_change_user_email.parent = rejected_status
|
||||
notify_change_user_email = copy.copy(notify_change_user_email)
|
||||
|
||||
finished_status.items.append(notify_change_user_email)
|
||||
notify_change_user_email.parent = finished_status
|
||||
|
||||
new_status.items.append(commentable)
|
||||
commentable.parent = new_status
|
||||
|
||||
commentable = copy.copy(commentable)
|
||||
accepted_status.items.append(commentable)
|
||||
commentable.parent = accepted_status
|
||||
|
||||
accept = ChoiceWorkflowStatusItem()
|
||||
accept.id = '_accept'
|
||||
|
@ -458,8 +512,8 @@ class WorkflowStatus:
|
|||
user_roles = set([])
|
||||
|
||||
for role in self.visibility:
|
||||
if role == '_receiver':
|
||||
role = formdata.formdef.receiver_id
|
||||
if role != '_submitter':
|
||||
role = get_role_translation(formdata.formdef, role)
|
||||
if role in user_roles:
|
||||
return True
|
||||
return False
|
||||
|
@ -511,6 +565,12 @@ class WorkflowStatusItem:
|
|||
def render_as_line(self):
|
||||
return _(self.description)
|
||||
|
||||
def render_list_of_roles(self, roles):
|
||||
return self.parent.parent.render_list_of_roles(roles)
|
||||
|
||||
def get_list_of_roles(self, include_logged_in_users=True):
|
||||
return self.parent.parent.get_list_of_roles(include_logged_in_users=include_logged_in_users)
|
||||
|
||||
def perform(self, formdata):
|
||||
pass
|
||||
|
||||
|
@ -658,28 +718,26 @@ class WorkflowStatusJumpItem(WorkflowStatusItem):
|
|||
|
||||
|
||||
def get_role_translation(formdef, role_name):
|
||||
if role_name == '_receiver':
|
||||
return formdef.receiver_id
|
||||
elif role_name == '_submitter':
|
||||
if role_name == '_submitter':
|
||||
raise Exception('_submitter is not a valid role')
|
||||
elif str(role_name).startswith('_'):
|
||||
role_id = formdef.workflow_roles.get(role_name)
|
||||
return role_id
|
||||
else:
|
||||
return role_name
|
||||
|
||||
def render_list_of_roles(roles):
|
||||
t = []
|
||||
for r in roles:
|
||||
if r == logged_users_role().id:
|
||||
t.append(logged_users_role().name)
|
||||
elif r == '_submitter':
|
||||
t.append(_('sender'))
|
||||
elif r == '_receiver':
|
||||
t.append(_('receiver'))
|
||||
def get_role_translation_label(workflow, role_id):
|
||||
if role_id == logged_users_role().id:
|
||||
return logged_users_role().name
|
||||
if role_id == '_submitter':
|
||||
return _('sender')
|
||||
if str(role_id).startswith('_'):
|
||||
return workflow.roles.get(role_id)
|
||||
else:
|
||||
try:
|
||||
t.append(Role.get(r).name)
|
||||
return Role.get(role_id).name
|
||||
except KeyError:
|
||||
pass
|
||||
return ', '.join(t)
|
||||
return
|
||||
|
||||
item_classes = []
|
||||
|
||||
|
@ -702,7 +760,7 @@ class CommentableWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
def render_as_line(self):
|
||||
if self.by:
|
||||
return _('Allow Comment by %s') % render_list_of_roles(self.by)
|
||||
return _('Allow Comment by %s') % self.render_list_of_roles(self.by)
|
||||
else:
|
||||
return _('Allow Comment (not completed)')
|
||||
|
||||
|
@ -757,11 +815,7 @@ class CommentableWorkflowStatusItem(WorkflowStatusItem):
|
|||
value=self.by,
|
||||
add_element_label=_('Add Role'),
|
||||
element_kwargs={'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')),
|
||||
(logged_users_role().id, logged_users_role().name),
|
||||
(None, '----')] + get_user_roles()})
|
||||
'options': [(None, '---')] + self.get_list_of_roles()})
|
||||
|
||||
register_item_class(CommentableWorkflowStatusItem)
|
||||
|
||||
|
@ -780,7 +834,7 @@ class ChoiceWorkflowStatusItem(WorkflowStatusJumpItem):
|
|||
if self.by:
|
||||
return _('Change Status "%(label)s" by %(by)s') % \
|
||||
{ 'label' : self.label,
|
||||
'by' : render_list_of_roles(self.by) }
|
||||
'by' : self.render_list_of_roles(self.by) }
|
||||
else:
|
||||
return _('Change Status "%s"') % self.label
|
||||
else:
|
||||
|
@ -806,11 +860,7 @@ class ChoiceWorkflowStatusItem(WorkflowStatusJumpItem):
|
|||
value = self.by,
|
||||
add_element_label = _('Add Role'),
|
||||
element_kwargs={'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')),
|
||||
(logged_users_role().id, logged_users_role().name),
|
||||
(None, '----')] + get_user_roles()})
|
||||
'options': [(None, '---')] + self.get_list_of_roles()})
|
||||
|
||||
def get_parameters(self):
|
||||
return ('by', 'status', 'label')
|
||||
|
@ -855,7 +905,7 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
def render_as_line(self):
|
||||
if self.to:
|
||||
return _('Send mail to %s') % render_list_of_roles(self.to)
|
||||
return _('Send mail to %s') % self.render_list_of_roles(self.to)
|
||||
else:
|
||||
return _('Send mail (not completed)')
|
||||
|
||||
|
@ -872,9 +922,8 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
value=self.to,
|
||||
add_element_label=_('Add Role'),
|
||||
element_kwargs={'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')), ] + get_user_roles()})
|
||||
'options': [(None, '---')] +
|
||||
self.get_list_of_roles(include_logged_in_users=False)})
|
||||
if 'subject' in parameters:
|
||||
form.add(StringWidget, '%ssubject' % prefix, title=_('Subject'),
|
||||
value=self.subject, size=40)
|
||||
|
@ -1125,7 +1174,7 @@ class EditableWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
def render_as_line(self):
|
||||
if self.by:
|
||||
return _('Allow Edition by %s') % render_list_of_roles(self.by)
|
||||
return _('Allow Edition by %s') % self.render_list_of_roles(self.by)
|
||||
else:
|
||||
return _('Allow Edition (not completed)')
|
||||
|
||||
|
@ -1145,11 +1194,7 @@ class EditableWorkflowStatusItem(WorkflowStatusItem):
|
|||
value = self.by,
|
||||
add_element_label = _('Add Role'),
|
||||
element_kwargs={'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')),
|
||||
(logged_users_role().id, logged_users_role().name),
|
||||
(None, '----')] + get_user_roles()})
|
||||
'options': [(None, '---')] + self.get_list_of_roles()})
|
||||
if 'status' in parameters:
|
||||
# XXX: look into this one, as None is a perfectly valid value, and
|
||||
# it would put this question in the 'workflow options' part.
|
||||
|
|
Loading…
Reference in New Issue