+
+
\ No newline at end of file
diff --git a/imio/dms/mail/browser/templates/actions_panel_duplicate.pt b/imio/dms/mail/browser/templates/actions_panel_duplicate.pt
new file mode 100644
index 000000000..b78000a89
--- /dev/null
+++ b/imio/dms/mail/browser/templates/actions_panel_duplicate.pt
@@ -0,0 +1,10 @@
+
+
+
+
+
+ |
+
diff --git a/imio/dms/mail/browser/views.py b/imio/dms/mail/browser/views.py
index e95e0ee3c..9720a46c0 100644
--- a/imio/dms/mail/browser/views.py
+++ b/imio/dms/mail/browser/views.py
@@ -6,6 +6,8 @@
from imio.dms.mail import _
from imio.dms.mail import _tr
from imio.dms.mail import PMH_ENABLED
+from imio.dms.mail.browser.settings import IImioDmsMailConfig
+from imio.dms.mail.browser.settings import omail_duplicate_fields
from imio.dms.mail.browser.table import CKTemplatesTable
from imio.dms.mail.browser.table import PersonnelTable
from imio.dms.mail.dmsfile import IImioDmsFile
@@ -19,11 +21,16 @@
from imio.helpers.fancytree.views import BaseRenderFancyTree
from imio.helpers.workflow import do_transitions
from imio.helpers.xhtml import object_link
+from imio.pyutils.utils import safe_encode
from plone import api
from Products.CMFPlone.utils import safe_unicode
from Products.Five import BrowserView
from Products.PageTemplates.Expressions import SecureModuleImporter
from unidecode import unidecode # unidecode_expect_nonascii not yet available in used version
+from z3c.form import button
+from z3c.form.field import Fields
+from z3c.form.form import Form
+from zope import schema
from zope.annotation import IAnnotations
from zope.component import getMultiAdapter
from zope.i18n import translate
@@ -70,6 +77,65 @@ def redirect_url(self, uid):
return "{}/persistent-document-generation?{}".format(url, "&".join(params))
+class OMDuplicateForm(Form):
+
+ """Duplicate an outgoing mail."""
+ label = _(u"Duplicate mail")
+ ignoreContext = True
+
+ def update(self):
+ """Handle fields."""
+ om_fields = api.portal.get_registry_record("omail_fields", IImioDmsMailConfig, [])
+ om_fields = [dic["field_name"] for dic in om_fields]
+ matching = {u"category": "IClassificationFolder.classification_categories",
+ u"folder": "IClassificationFolder.classification_folders",
+ u"reply_to": "reply_to",
+ u"link_to_duplicated": "reply_to"}
+ to_show = api.portal.get_registry_record("omail_duplicate_display_fields", IImioDmsMailConfig, [])
+ to_true = api.portal.get_registry_record("omail_duplicate_true_default_values", IImioDmsMailConfig, [])
+ for term in omail_duplicate_fields:
+ if ((term.value in matching and matching[term.value] not in om_fields) or
+ (term.value not in to_show and term.value not in to_true)):
+ continue
+ self.fields += Fields(
+ schema.Bool(
+ __name__=safe_encode(term.value),
+ title=term.title,
+ default=term.value in to_true,
+ ))
+ super(OMDuplicateForm, self).update()
+
+ def updateWidgets(self, prefix=None):
+ super(OMDuplicateForm, self).updateWidgets()
+
+ # we hide fields not to show
+ to_show = api.portal.get_registry_record("omail_duplicate_display_fields", IImioDmsMailConfig, [])
+ for term in omail_duplicate_fields:
+ if term.value not in to_show:
+ self.widgets[term.value].mode = "hidden"
+
+ @button.buttonAndHandler(_('Duplicate'), name='duplicate')
+ def handleApply(self, action):
+ data, errors = self.extractData()
+
+ if errors:
+ self.status = self.formErrorsMessage
+ return
+
+ # Duplicate the mail
+ odm_utils = getMultiAdapter((self.context, self.request), name="odm-utils")
+ duplicated_mail = odm_utils.duplicate(
+ keep_category=data.get('category', False),
+ keep_folder=data.get('folder', False),
+ keep_reply_to=data.get('reply_to', False),
+ keep_dms_files=data.get('dms_files', False),
+ keep_annexes=data.get('annexes', False),
+ link_to_duplicated=data.get('link_to_duplicated', False),
+ )
+
+ self.request.response.redirect(duplicated_mail.absolute_url()+"/edit")
+
+
def parse_query(text):
"""Copied from plone.app.vocabularies.catalog.parse_query but cleaned."""
for char in "?-+*()":
diff --git a/imio/dms/mail/skins/imio_dms_mail/imiodmsmail.css.dtml b/imio/dms/mail/skins/imio_dms_mail/imiodmsmail.css.dtml
index fe4c3b6bb..c8e515049 100644
--- a/imio/dms/mail/skins/imio_dms_mail/imiodmsmail.css.dtml
+++ b/imio/dms/mail/skins/imio_dms_mail/imiodmsmail.css.dtml
@@ -471,6 +471,10 @@ dl.portletWidgetCollection div.portlet_add_icons a {
background-image: url('&dtml-portal_url;/++resource++imio.dms.mail/models_icon.png');
}
+.apButtonAction_duplicate {
+ background-image: url('&dtml-portal_url;/++resource++imio.dms.mail/copy.svg');
+}
+
.apButtonAction_sendemail {
background-image: url('&dtml-portal_url;/++resource++imio.dms.mail/send_email.svg');
background-size: 18px 18px;
diff --git a/imio/dms/mail/subscribers.py b/imio/dms/mail/subscribers.py
index 2390c21ff..d7eca2495 100644
--- a/imio/dms/mail/subscribers.py
+++ b/imio/dms/mail/subscribers.py
@@ -72,6 +72,7 @@
# from zope.component.interfaces import ComponentLookupError
from zope.annotation import IAnnotations
from zope.component import getAdapter
+from zope.component import getMultiAdapter
from zope.component import getSiteManager
from zope.component import getUtility
from zope.component import queryUtility
@@ -384,6 +385,16 @@ def dmsoutgoingmail_transition(mail, event):
mail.portal_catalog.reindexObject(mail, idxs=("in_out_date",), update_metadata=0)
+def dmsoutgoingmail_modified(mail, event):
+ annot = IAnnotations(mail).get('imio.dms.mail', {})
+ copy_dms_files_from = annot.get('copy_dms_files_from')
+ if copy_dms_files_from:
+ del annot['copy_dms_files_from']
+ original_mail = uuidToObject(copy_dms_files_from, unrestricted=True)
+ odm_utils = getMultiAdapter((mail, mail.REQUEST), name="odm-utils")
+ odm_utils.copy_dms_files(original_mail)
+
+
def dv_handle_file_creation(obj, event):
"""Intermediate function to avoid converting some files in documentviewer"""
if obj.portal_type in DV_AVOIDED_TYPES:
diff --git a/imio/dms/mail/subscribers.zcml b/imio/dms/mail/subscribers.zcml
index 7e357c39f..bde5b4cb2 100644
--- a/imio/dms/mail/subscribers.zcml
+++ b/imio/dms/mail/subscribers.zcml
@@ -98,6 +98,12 @@
handler=".subscribers.dmsoutgoingmail_transition"
/>
+
+
1
+ if requires_mailing and not annot.get('need_mailing'):
+ continue
+
+ # Generate a new document from the same template
+ template_uid = annot.get('template_uid')
+ generation_view = getMultiAdapter((self.context, self.request), name="persistent-document-generation")
+ pod_template = generation_view.get_pod_template(template_uid)
+ # Skip if it's a mailing loop template
+ if IMailingLoopTemplate.providedBy(pod_template):
+ continue
+ generation_view.pod_template = pod_template
+ generation_view.output_format = 'odt'
+ generation_view.generate_persistent_doc(pod_template, 'odt')
+ used_template_uids.add(template_uid)
+
class Dummy(object):
"""dummy class that allows setting attributes"""
|