summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/pfwbged/policy/locales/fr/LC_MESSAGES/pfwbged.policy.po8
-rw-r--r--src/pfwbged/policy/locales/fr/LC_MESSAGES/plone.po4
-rw-r--r--src/pfwbged/policy/locales/pfwbged.policy.pot8
-rw-r--r--src/pfwbged/policy/locales/plone.pot4
-rw-r--r--src/pfwbged/policy/menu.py28
-rw-r--r--src/pfwbged/policy/profiles/default/workflows/versionnote_workflow/definition.xml11
-rw-r--r--src/pfwbged/policy/subscribers/document.py49
7 files changed, 112 insertions, 0 deletions
diff --git a/src/pfwbged/policy/locales/fr/LC_MESSAGES/pfwbged.policy.po b/src/pfwbged/policy/locales/fr/LC_MESSAGES/pfwbged.policy.po
index 1abf0af..2161f9b 100644
--- a/src/pfwbged/policy/locales/fr/LC_MESSAGES/pfwbged.policy.po
+++ b/src/pfwbged/policy/locales/fr/LC_MESSAGES/pfwbged.policy.po
@@ -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
diff --git a/src/pfwbged/policy/locales/fr/LC_MESSAGES/plone.po b/src/pfwbged/policy/locales/fr/LC_MESSAGES/plone.po
index e54e683..84c33cb 100644
--- a/src/pfwbged/policy/locales/fr/LC_MESSAGES/plone.po
+++ b/src/pfwbged/policy/locales/fr/LC_MESSAGES/plone.po
@@ -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"
diff --git a/src/pfwbged/policy/locales/pfwbged.policy.pot b/src/pfwbged/policy/locales/pfwbged.policy.pot
index 8d7a1f4..1c896b0 100644
--- a/src/pfwbged/policy/locales/pfwbged.policy.pot
+++ b/src/pfwbged/policy/locales/pfwbged.policy.pot
@@ -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
diff --git a/src/pfwbged/policy/locales/plone.pot b/src/pfwbged/policy/locales/plone.pot
index 6d82c8e..45c2715 100644
--- a/src/pfwbged/policy/locales/plone.pot
+++ b/src/pfwbged/policy/locales/plone.pot
@@ -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 ""
diff --git a/src/pfwbged/policy/menu.py b/src/pfwbged/policy/menu.py
index ff8f94e..208b537 100644
--- a/src/pfwbged/policy/menu.py
+++ b/src/pfwbged/policy/menu.py
@@ -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):
diff --git a/src/pfwbged/policy/profiles/default/workflows/versionnote_workflow/definition.xml b/src/pfwbged/policy/profiles/default/workflows/versionnote_workflow/definition.xml
index 3dd09f4..5106c65 100644
--- a/src/pfwbged/policy/profiles/default/workflows/versionnote_workflow/definition.xml
+++ b/src/pfwbged/policy/profiles/default/workflows/versionnote_workflow/definition.xml
@@ -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">
diff --git a/src/pfwbged/policy/subscribers/document.py b/src/pfwbged/policy/subscribers/document.py
index a14edc3..e069519 100644
--- a/src/pfwbged/policy/subscribers/document.py
+++ b/src/pfwbged/policy/subscribers/document.py
@@ -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):