added new "Aggregate to summary email" workflow action, which will get all
requests and mail them all at once at 6 in the morning.
This commit is contained in:
parent
6777d0beff
commit
d5ef93eba2
|
@ -18,7 +18,7 @@ from formdata import FormData
|
|||
from roles import Role
|
||||
from users import User
|
||||
from categories import Category
|
||||
from workflows import Workflow
|
||||
from wcs.workflows import Workflow
|
||||
import fields
|
||||
|
||||
status_labels = {
|
||||
|
|
|
@ -10,6 +10,13 @@ except ImportError:
|
|||
|
||||
from qommon.publisher import get_publisher_class, set_publisher_class, QommonPublisher
|
||||
|
||||
# this is terribly ugly but import RootDirectory will import a bunch of things,
|
||||
# and some of them need a publisher to be set
|
||||
class StubWcsPublisher(QommonPublisher):
|
||||
pass
|
||||
set_publisher_class(StubWcsPublisher)
|
||||
|
||||
|
||||
from root import RootDirectory
|
||||
from backoffice import RootDirectory as BackofficeRootDirectory
|
||||
from admin import RootDirectory as AdminRootDirectory
|
||||
|
@ -29,7 +36,7 @@ class UnpicklerClass(pickle.Unpickler):
|
|||
return klass
|
||||
|
||||
|
||||
class WcsPublisher(QommonPublisher):
|
||||
class WcsPublisher(StubWcsPublisher):
|
||||
APP_NAME = 'wcs'
|
||||
APP_DIR = APP_DIR
|
||||
DATA_DIR = DATA_DIR
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
from qommon.publisher import get_publisher_class
|
||||
from qommon.storage import StorableObject
|
||||
from qommon.form import *
|
||||
from qommon.cron import CronJob
|
||||
from qommon import emails
|
||||
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class, \
|
||||
render_list_of_roles, get_role_translation
|
||||
|
||||
from wcs.roles import Role, logged_users_role, get_user_roles
|
||||
|
||||
class AggregationEmailWorkflowStatusItem(WorkflowStatusItem):
|
||||
description = N_('Aggregate to summary email')
|
||||
key = 'aggregationemail'
|
||||
|
||||
to = None
|
||||
|
||||
def render_as_line(self):
|
||||
if self.to:
|
||||
return _('Aggregate for summary email to %s') % render_list_of_roles(self.to)
|
||||
else:
|
||||
return _('Aggregate for summary email (not completed)')
|
||||
|
||||
def fill_admin_form(self, form):
|
||||
form.add(WidgetList, 'to', title = _('To'), element_type = SingleSelectWidget,
|
||||
value = self.to,
|
||||
add_element_label = _('Add Role'),
|
||||
element_kwargs = {'render_br': False,
|
||||
'options': [(None, '---'),
|
||||
('_submitter', _('Sender')),
|
||||
('_receiver', _('Receiver')), ] + get_user_roles()})
|
||||
|
||||
|
||||
def submit_admin_form(self, form):
|
||||
for f in ('to',):
|
||||
widget = form.get_widget(f)
|
||||
if widget:
|
||||
setattr(self, f, widget.parse())
|
||||
|
||||
def perform(self, formdata):
|
||||
if not self.to:
|
||||
return
|
||||
|
||||
for dest in self.to:
|
||||
dest = get_role_translation(formdata.formdef, dest)
|
||||
try:
|
||||
aggregate = AggregationEmail.get(dest)
|
||||
except KeyError:
|
||||
aggregate = AggregationEmail(id = dest)
|
||||
|
||||
aggregate.append({
|
||||
'formdef': formdata.formdef.id,
|
||||
'formdata': formdata.id,
|
||||
'formurl': formdata.get_url()})
|
||||
aggregate.store()
|
||||
|
||||
register_item_class(AggregationEmailWorkflowStatusItem)
|
||||
|
||||
|
||||
class AggregationEmail(StorableObject):
|
||||
_names = 'aggregation_emails'
|
||||
|
||||
items = None
|
||||
|
||||
def __init__(self, id = None):
|
||||
StorableObject.__init__(self, id = id)
|
||||
self.items = []
|
||||
|
||||
def append(self, dict):
|
||||
self.items.append(dict)
|
||||
|
||||
|
||||
def send_aggregation_emails(publisher):
|
||||
from wcs.formdef import FormDef
|
||||
from qommon.publisher import get_cfg
|
||||
|
||||
publisher.reload_cfg()
|
||||
site_name = publisher.cfg.get('misc', {}).get('sitename', None)
|
||||
|
||||
cache = {}
|
||||
for aggregate_id in AggregationEmail.keys():
|
||||
role = Role.get(aggregate_id)
|
||||
if not role.emails:
|
||||
continue
|
||||
|
||||
aggregate = AggregationEmail.get(aggregate_id)
|
||||
aggregate.remove_self()
|
||||
if not aggregate.items:
|
||||
continue
|
||||
|
||||
last_formdef = None
|
||||
body = []
|
||||
for item in sorted(aggregate.items):
|
||||
formdef_id = item.get('formdef')
|
||||
if formdef_id in cache:
|
||||
formdef, formdata, workflow = cache[formdef_id]
|
||||
else:
|
||||
formdef = FormDef.get(formdef_id)
|
||||
formdata = formdef.data_class()
|
||||
workflow = formdef.workflow
|
||||
cache[formdef_id] = (formdef, formdata, workflow)
|
||||
|
||||
data = formdata.get(item.get('formdata'))
|
||||
status = data.get_workflow_status()
|
||||
url = item.get('formurl')
|
||||
|
||||
if last_formdef != formdef:
|
||||
if last_formdef is not None:
|
||||
body.append('') # blank line
|
||||
last_formdef = formdef
|
||||
body.append(formdef.name)
|
||||
body.append('-' * len(formdef.name))
|
||||
body.append('')
|
||||
|
||||
body.append('- %sstatus (%s)' % (url, status.name))
|
||||
|
||||
body = '\n'.join(body)
|
||||
|
||||
mail_subject = _('New arrivals')
|
||||
if site_name:
|
||||
mail_subject += ' (%s)' % site_name
|
||||
|
||||
emails.email(mail_subject, body,
|
||||
email_rcpt = role.emails, bcc = role.emails[1:], exclude_current_user = False)
|
||||
|
||||
|
||||
# at 6:00 in the morning, every day but the week end
|
||||
get_publisher_class().register_cronjob(
|
||||
CronJob(send_aggregation_emails, minutes=[0], hours=[6], weekdays=range(5)))
|
||||
|
|
@ -10,6 +10,9 @@ from qommon import emails, get_cfg
|
|||
from wcs.roles import Role, logged_users_role, get_user_roles
|
||||
from wcs.formdata import Evolution
|
||||
|
||||
if not __name__.startswith('wcs.'):
|
||||
raise ImportError('Import of workflows module must be absolute (import wcs.workflows)')
|
||||
|
||||
def lax_int(s):
|
||||
try:
|
||||
return int(s)
|
||||
|
@ -122,8 +125,7 @@ class WorkflowStatus:
|
|||
break
|
||||
if role == '_submitter' and filled.user_id == user.id:
|
||||
break
|
||||
if role == '_receiver':
|
||||
role = filled.formdef.receiver_id
|
||||
role = get_role_translation(filled.formdef, role)
|
||||
if role in (user.roles or []):
|
||||
break
|
||||
else:
|
||||
|
@ -184,8 +186,7 @@ class WorkflowStatusItem:
|
|||
continue
|
||||
if role == '_submitter' and formdata.user_id == user.id:
|
||||
return True
|
||||
if role == '_receiver':
|
||||
role = formdata.formdef.receiver_id
|
||||
role = get_role_translation(formdata.formdef, role)
|
||||
if role in (user.roles or []):
|
||||
return True
|
||||
|
||||
|
@ -197,6 +198,15 @@ class WorkflowStatusItem:
|
|||
del odict['parent']
|
||||
return odict
|
||||
|
||||
|
||||
def get_role_translation(formdef, role_name):
|
||||
if role_name == '_receiver':
|
||||
return formdef.receiver_id
|
||||
elif role_name == '_submitter':
|
||||
raise Exception('_submitter is not a valid role')
|
||||
else:
|
||||
return role_name
|
||||
|
||||
def render_list_of_roles(roles):
|
||||
t = []
|
||||
for r in roles:
|
||||
|
@ -442,8 +452,7 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
|
||||
continue
|
||||
|
||||
if dest == '_receiver':
|
||||
dest = formdata.formdef.receiver_id
|
||||
dest = get_role_translation(formdef, dest)
|
||||
|
||||
try:
|
||||
role = Role.get(dest)
|
||||
|
@ -574,3 +583,5 @@ class EditableWorkflowStatusItem(WorkflowStatusItem):
|
|||
register_item_class(EditableWorkflowStatusItem)
|
||||
|
||||
|
||||
import wf.aggregation_email
|
||||
|
||||
|
|
Loading…
Reference in New Issue