Allow cancelling of validation requests #22008
This commit is contained in:
parent
f4c986b43a
commit
6a8f4e89dc
|
@ -39,6 +39,10 @@ msgstr "Un document précédemment validé est revenu en attente de validation"
|
|||
msgid "A validation request has been refused"
|
||||
msgstr "Une demande de validation a été refusée."
|
||||
|
||||
#: ../subscribers/document.py:638
|
||||
msgid "A validation request previously sent to you has been deleted"
|
||||
msgstr "Une demande de validation qui vous était adressée a été supprimée"
|
||||
|
||||
#: ../browser/comments.py:98
|
||||
msgid "Accept refusal"
|
||||
msgstr "Accepter la désattribution"
|
||||
|
@ -106,6 +110,10 @@ msgstr "Annuler la validation et finalisation de la version ${version}"
|
|||
msgid "Cancel validation of ${version}"
|
||||
msgstr "Annuler la validation de la version ${version}"
|
||||
|
||||
#: ../menu.py:504
|
||||
msgid "Cancel validation request"
|
||||
msgstr "Annuler la demande de validation"
|
||||
|
||||
#: ../browser/refuse.py:33
|
||||
#: ../browser/send_by_email.py:35
|
||||
#: ../browser/to_process.py:25
|
||||
|
|
|
@ -57,6 +57,10 @@ msgstr "Retour à indicater"
|
|||
msgid "Back to to process"
|
||||
msgstr "Retour en à traiter"
|
||||
|
||||
#: ../profiles/default/workflows/versionnote_workflow/definition.xml
|
||||
msgid "Back to validated"
|
||||
msgstr "Retour à validé"
|
||||
|
||||
#: ../profiles/default/workflows/outgoingmail_workflow/definition.xml
|
||||
msgid "Back to writing"
|
||||
msgstr "Retour à la rédaction"
|
||||
|
|
|
@ -41,6 +41,10 @@ msgstr ""
|
|||
msgid "A validation request has been refused"
|
||||
msgstr ""
|
||||
|
||||
#: ../subscribers/document.py:638
|
||||
msgid "A validation request previously sent to you has been deleted"
|
||||
msgstr ""
|
||||
|
||||
#: ../browser/comments.py:98
|
||||
msgid "Accept refusal"
|
||||
msgstr ""
|
||||
|
@ -108,6 +112,10 @@ msgstr ""
|
|||
msgid "Cancel validation of ${version}"
|
||||
msgstr ""
|
||||
|
||||
#: ../menu.py:504
|
||||
msgid "Cancel validation request"
|
||||
msgstr ""
|
||||
|
||||
#: ../browser/refuse.py:33
|
||||
#: ../browser/send_by_email.py:35
|
||||
#: ../browser/to_process.py:25
|
||||
|
|
|
@ -58,6 +58,10 @@ msgstr ""
|
|||
msgid "Back to to process"
|
||||
msgstr ""
|
||||
|
||||
#: ../profiles/default/workflows/versionnote_workflow/definition.xml
|
||||
msgid "Back to validated"
|
||||
msgstr ""
|
||||
|
||||
#: ../profiles/default/workflows/outgoingmail_workflow/definition.xml
|
||||
msgid "Back to writing"
|
||||
msgstr ""
|
||||
|
|
|
@ -235,6 +235,13 @@ class CustomMenu(menu.WorkflowMenu):
|
|||
cssClass += ' version-action version-id-%s' % context.id
|
||||
cssClass += ' version-action-%s' % action['id']
|
||||
|
||||
# special case to allow cancellation of validation requests:
|
||||
# back_to_draft is available from state pending,
|
||||
# but it must not be done directly by users.
|
||||
if action['id'] == 'back_to_draft' and \
|
||||
api.content.get_state(context) == 'pending':
|
||||
continue
|
||||
|
||||
# limit cancelling actions to a version's rightful owner
|
||||
# guards are bypassed for Managers, so call them at least once
|
||||
action_guards = {
|
||||
|
@ -484,6 +491,27 @@ class CustomMenu(menu.WorkflowMenu):
|
|||
'submenu': None,
|
||||
})
|
||||
|
||||
catalog = api.portal.get_tool('portal_catalog')
|
||||
container_path = '/'.join(context.getPhysicalPath())
|
||||
brains = catalog.searchResults({
|
||||
'path': container_path,
|
||||
'portal_type': 'validation',
|
||||
'review_state': 'todo',
|
||||
'Creator': api.user.get_current().id,
|
||||
})
|
||||
if IDmsDocument.providedBy(context) and brains:
|
||||
results.append({
|
||||
'title': _(u'Cancel validation request'),
|
||||
'description': '',
|
||||
'action': context.absolute_url() + '/@@cancel_validation',
|
||||
'selected': False,
|
||||
'icon': None,
|
||||
'extra': {'id': 'plone-contentmenu-actions-cancel-validation',
|
||||
'separator': None,
|
||||
'class': 'no-icon overlay-form-reload link-overlay'},
|
||||
'submenu': None,
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
def getWorkflowActionsForType(self, context, request, portal_type):
|
||||
|
|
|
@ -85,6 +85,8 @@
|
|||
<exit-transition transition_id="refuse"/>
|
||||
<exit-transition transition_id="validate"/>
|
||||
<exit-transition transition_id="obsolete"/>
|
||||
<exit-transition transition_id="back_to_draft"/>
|
||||
<exit-transition transition_id="back_to_validated"/>
|
||||
<permission-map name="View" acquired="False">
|
||||
<permission-role>Editor</permission-role>
|
||||
<permission-role>Manager</permission-role>
|
||||
|
@ -143,6 +145,15 @@
|
|||
<guard>
|
||||
<guard-role>Manager</guard-role>
|
||||
<guard-role>Owner</guard-role>
|
||||
<guard-role>Reviewer</guard-role>
|
||||
</guard>
|
||||
</transition>
|
||||
<transition transition_id="back_to_validated" title="Back to validated" new_state="validated" trigger="USER" before_script="" after_script="" i18n:attributes="title">
|
||||
<action url="" category="hidden" icon="" i18n:translate="">Back to draft</action>
|
||||
<guard>
|
||||
<guard-role>Manager</guard-role>
|
||||
<guard-role>Owner</guard-role>
|
||||
<guard-role>Reviewer</guard-role>
|
||||
</guard>
|
||||
</transition>
|
||||
<transition transition_id="restore_from_trash" title="Restore" new_state="finished" trigger="USER" before_script="" after_script="" i18n:attributes="title">
|
||||
|
|
|
@ -604,6 +604,55 @@ def email_notification_of_canceled_information(context):
|
|||
log = logging.getLogger('pfwbged.policy')
|
||||
log.exception(e)
|
||||
|
||||
@grok.subscribe(IValidation, IObjectWillBeRemovedEvent)
|
||||
def email_notification_of_canceled_validation(context, event):
|
||||
document = None
|
||||
for obj in aq_chain(context):
|
||||
obj = aq_parent(obj)
|
||||
if IDmsDocument.providedBy(obj):
|
||||
document = obj
|
||||
break
|
||||
if not document:
|
||||
return
|
||||
absolute_url = document.absolute_url()
|
||||
|
||||
for enquirer in (context.enquirer or []):
|
||||
member = context.portal_membership.getMemberById(enquirer)
|
||||
if member:
|
||||
email_from = member.getProperty('email', None)
|
||||
if email_from:
|
||||
break
|
||||
else:
|
||||
email_from = api.user.get_current().email or api.portal.get().getProperty('email_from_address') or 'admin@localhost'
|
||||
|
||||
responsible = context.responsible[0]
|
||||
principal = api.user.get(responsible)
|
||||
if not principal:
|
||||
principal = api.group.get(responsible)
|
||||
recipient_email = principal.getProperty('email') if principal else None
|
||||
if not recipient_email:
|
||||
return
|
||||
|
||||
subject = '%s - %s' % (context.title, document.title)
|
||||
|
||||
body = translate(_('A validation request previously sent to you has been deleted'), context=context.REQUEST) + \
|
||||
'\n\n' + \
|
||||
translate(_('Title: %s'), context=context.REQUEST) % context.title + \
|
||||
'\n\n' + \
|
||||
translate(_('Document: %s'), context=context.REQUEST) % document.title + \
|
||||
'\n\n' + \
|
||||
translate(_('Document Address: %s'), context=context.REQUEST) % document.absolute_url() + \
|
||||
'\n\n\n\n-- \n' + \
|
||||
translate(_('Sent by GED'))
|
||||
body = body.encode('utf-8')
|
||||
|
||||
try:
|
||||
context.MailHost.send(body, recipient_email, email_from, subject, charset='utf-8')
|
||||
except Exception as e:
|
||||
# do not abort transaction in case of email error
|
||||
log = logging.getLogger('pfwbged.policy')
|
||||
log.exception(e)
|
||||
|
||||
|
||||
@grok.subscribe(IDmsDocument, IObjectModifiedEvent)
|
||||
def log_some_history(context, event):
|
||||
|
|
Reference in New Issue