summaryrefslogtreecommitdiff
path: root/addons/mail
diff options
context:
space:
mode:
authorchm@openerp.com <>2014-04-23 17:48:52 +0200
committerchm@openerp.com <>2014-04-23 17:48:52 +0200
commitee7ff4bd07d8d84ed2ebb0e2e3f5eb437f158e5b (patch)
tree25577845139d390f9bf27e0237d18842aeace02b /addons/mail
parentb1bc68d8eb374f30173e03e8048d1c3588a00d4b (diff)
parent1657ffb8e7d95ef5f94e59121737abb068371b66 (diff)
[MERGE] from trunk
bzr revid: chm@openerp.com-20140423154852-gzegxqrzb2sj01zl
Diffstat (limited to 'addons/mail')
-rw-r--r--addons/mail/data/mail_data.xml2
-rw-r--r--addons/mail/data/mail_demo.xml48
-rw-r--r--addons/mail/i18n/ar.po4
-rw-r--r--addons/mail/i18n/bg.po4
-rw-r--r--addons/mail/i18n/bs.po4
-rw-r--r--addons/mail/i18n/ca.po4
-rw-r--r--addons/mail/i18n/cs.po4
-rw-r--r--addons/mail/i18n/da.po4
-rw-r--r--addons/mail/i18n/de.po4
-rw-r--r--addons/mail/i18n/es.po4
-rw-r--r--addons/mail/i18n/es_CR.po4
-rw-r--r--addons/mail/i18n/es_MX.po4
-rw-r--r--addons/mail/i18n/es_PY.po4
-rw-r--r--addons/mail/i18n/es_VE.po4
-rw-r--r--addons/mail/i18n/et.po4
-rw-r--r--addons/mail/i18n/fi.po4
-rw-r--r--addons/mail/i18n/fr.po6
-rw-r--r--addons/mail/i18n/gl.po4
-rw-r--r--addons/mail/i18n/he.po4
-rw-r--r--addons/mail/i18n/hr.po4
-rw-r--r--addons/mail/i18n/hu.po4
-rw-r--r--addons/mail/i18n/it.po4
-rw-r--r--addons/mail/i18n/ja.po4
-rw-r--r--addons/mail/i18n/ko.po4
-rw-r--r--addons/mail/i18n/lt.po4
-rw-r--r--addons/mail/i18n/lv.po4
-rw-r--r--addons/mail/i18n/mk.po4
-rw-r--r--addons/mail/i18n/mn.po4
-rw-r--r--addons/mail/i18n/nl.po4
-rw-r--r--addons/mail/i18n/pl.po4
-rw-r--r--addons/mail/i18n/pt.po4
-rw-r--r--addons/mail/i18n/pt_BR.po4
-rw-r--r--addons/mail/i18n/ro.po4
-rw-r--r--addons/mail/i18n/ru.po4
-rw-r--r--addons/mail/i18n/sl.po4
-rw-r--r--addons/mail/i18n/sr@latin.po4
-rw-r--r--addons/mail/i18n/sv.po4
-rw-r--r--addons/mail/i18n/th.po4
-rw-r--r--addons/mail/i18n/tr.po4
-rw-r--r--addons/mail/i18n/vi.po4
-rw-r--r--addons/mail/i18n/zh_CN.po4
-rw-r--r--addons/mail/i18n/zh_TW.po4
-rw-r--r--addons/mail/mail_followers.py13
-rw-r--r--addons/mail/mail_mail.py79
-rw-r--r--addons/mail/mail_mail_view.xml1
-rw-r--r--addons/mail/mail_message.py140
-rw-r--r--addons/mail/mail_thread.py49
-rw-r--r--addons/mail/res_partner.py17
-rw-r--r--addons/mail/res_partner_view.xml2
-rw-r--r--addons/mail/res_users.py4
-rw-r--r--addons/mail/res_users_view.xml4
-rw-r--r--addons/mail/static/src/js/mail.js5
-rw-r--r--addons/mail/static/src/js/many2many_tags_email.js2
-rw-r--r--addons/mail/static/src/xml/mail.xml11
-rw-r--r--addons/mail/tests/common.py4
-rw-r--r--addons/mail/tests/test_mail_features.py50
-rw-r--r--addons/mail/wizard/mail_compose_message.py247
-rw-r--r--addons/mail/wizard/mail_compose_message_view.xml37
58 files changed, 353 insertions, 524 deletions
diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml
index cdd7eb12c69..8e52f7e1f7d 100644
--- a/addons/mail/data/mail_data.xml
+++ b/addons/mail/data/mail_data.xml
@@ -53,7 +53,7 @@
<!-- Admin should not receivve emails at creation -->
<record id="base.partner_root" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<!-- Catchall Email Alias -->
diff --git a/addons/mail/data/mail_demo.xml b/addons/mail/data/mail_demo.xml
index dde8d1d9804..09415ba89e0 100644
--- a/addons/mail/data/mail_demo.xml
+++ b/addons/mail/data/mail_demo.xml
@@ -4,76 +4,76 @@
<!-- Update 'Demo user' and partners email preferences to avoid mail bombing -->
<record id="base.partner_demo" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_1" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_2" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_3" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_4" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_5" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_6" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_7" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_8" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_9" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_10" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_11" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_12" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_13" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_14" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_15" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_16" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_17" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_18" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_19" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_20" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_21" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_22" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<record id="base.res_partner_23" model="res.partner">
- <field name="notification_email_send">none</field>
+ <field name="notify_email">none</field>
</record>
<!-- Discussion: attachments and spec [DEMO: search on has_attachments -->
diff --git a/addons/mail/i18n/ar.po b/addons/mail/i18n/ar.po
index 660c6d30aa2..dff9a37498a 100644
--- a/addons/mail/i18n/ar.po
+++ b/addons/mail/i18n/ar.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/bg.po b/addons/mail/i18n/bg.po
index a907bb44a3c..983abf5d57a 100644
--- a/addons/mail/i18n/bg.po
+++ b/addons/mail/i18n/bg.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/bs.po b/addons/mail/i18n/bs.po
index 499d2bb03ad..eb76645da89 100644
--- a/addons/mail/i18n/bs.po
+++ b/addons/mail/i18n/bs.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/ca.po b/addons/mail/i18n/ca.po
index 1e774770274..412f16330e2 100644
--- a/addons/mail/i18n/ca.po
+++ b/addons/mail/i18n/ca.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/cs.po b/addons/mail/i18n/cs.po
index c2850c42237..ecfcc03e820 100644
--- a/addons/mail/i18n/cs.po
+++ b/addons/mail/i18n/cs.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/da.po b/addons/mail/i18n/da.po
index 122800b5aa6..259be11c1dc 100644
--- a/addons/mail/i18n/da.po
+++ b/addons/mail/i18n/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/de.po b/addons/mail/i18n/de.po
index c9d7ec0ec06..379d2f9d04a 100644
--- a/addons/mail/i18n/de.po
+++ b/addons/mail/i18n/de.po
@@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/es.po b/addons/mail/i18n/es.po
index 221c62a59cd..9010e1b7beb 100644
--- a/addons/mail/i18n/es.po
+++ b/addons/mail/i18n/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/es_CR.po b/addons/mail/i18n/es_CR.po
index 2234b60436e..68deb811c3b 100644
--- a/addons/mail/i18n/es_CR.po
+++ b/addons/mail/i18n/es_CR.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
"Language: es\n"
#. module: mail
diff --git a/addons/mail/i18n/es_MX.po b/addons/mail/i18n/es_MX.po
index 332f1a0751c..05cca870e25 100644
--- a/addons/mail/i18n/es_MX.po
+++ b/addons/mail/i18n/es_MX.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/es_PY.po b/addons/mail/i18n/es_PY.po
index fae6311e235..9889f3cc961 100644
--- a/addons/mail/i18n/es_PY.po
+++ b/addons/mail/i18n/es_PY.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/es_VE.po b/addons/mail/i18n/es_VE.po
index 70f0995cce4..bf28fe82dc3 100644
--- a/addons/mail/i18n/es_VE.po
+++ b/addons/mail/i18n/es_VE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/et.po b/addons/mail/i18n/et.po
index cfc6ddc4ad3..7c1cdb1caaa 100644
--- a/addons/mail/i18n/et.po
+++ b/addons/mail/i18n/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/fi.po b/addons/mail/i18n/fi.po
index 6ea227fe890..a5a13c3e112 100644
--- a/addons/mail/i18n/fi.po
+++ b/addons/mail/i18n/fi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/fr.po b/addons/mail/i18n/fr.po
index 4bc7a7cf5bf..da0536beae3 100644
--- a/addons/mail/i18n/fr.po
+++ b/addons/mail/i18n/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
@@ -1238,7 +1238,7 @@ msgstr "Favori"
#: code:addons/mail/static/src/xml/mail.xml:313
#, python-format
msgid "more messages"
-msgstr "plus de messages"
+msgstr "messages supplémentaires"
#. module: mail
#: code:addons/mail/update.py:93
diff --git a/addons/mail/i18n/gl.po b/addons/mail/i18n/gl.po
index 1ac16163418..9e00af100f4 100644
--- a/addons/mail/i18n/gl.po
+++ b/addons/mail/i18n/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/he.po b/addons/mail/i18n/he.po
index 07ac78a819b..c55a34fd29a 100644
--- a/addons/mail/i18n/he.po
+++ b/addons/mail/i18n/he.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/hr.po b/addons/mail/i18n/hr.po
index 7c5aa4d0c11..4cc04439627 100644
--- a/addons/mail/i18n/hr.po
+++ b/addons/mail/i18n/hr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/hu.po b/addons/mail/i18n/hu.po
index 0b0e10cf810..df72b962c4b 100644
--- a/addons/mail/i18n/hu.po
+++ b/addons/mail/i18n/hu.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/it.po b/addons/mail/i18n/it.po
index 228fd135aac..6860879c137 100644
--- a/addons/mail/i18n/it.po
+++ b/addons/mail/i18n/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/ja.po b/addons/mail/i18n/ja.po
index be6ef9c4426..649b0ddd794 100644
--- a/addons/mail/i18n/ja.po
+++ b/addons/mail/i18n/ja.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/ko.po b/addons/mail/i18n/ko.po
index e1cc4bc0608..9fe1610a6dd 100644
--- a/addons/mail/i18n/ko.po
+++ b/addons/mail/i18n/ko.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/lt.po b/addons/mail/i18n/lt.po
index 59acc32f0c3..f3bc8cb4262 100644
--- a/addons/mail/i18n/lt.po
+++ b/addons/mail/i18n/lt.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/lv.po b/addons/mail/i18n/lv.po
index 2c0b9ef39a8..4e2fb780288 100644
--- a/addons/mail/i18n/lv.po
+++ b/addons/mail/i18n/lv.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/mk.po b/addons/mail/i18n/mk.po
index 96c3a55d192..d8c8658cc3c 100644
--- a/addons/mail/i18n/mk.po
+++ b/addons/mail/i18n/mk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/mn.po b/addons/mail/i18n/mn.po
index 9fff5ef7d81..f607929b80a 100644
--- a/addons/mail/i18n/mn.po
+++ b/addons/mail/i18n/mn.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/nl.po b/addons/mail/i18n/nl.po
index cf8024bdd26..8213fbd11e7 100644
--- a/addons/mail/i18n/nl.po
+++ b/addons/mail/i18n/nl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:20+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:42+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/pl.po b/addons/mail/i18n/pl.po
index ef4568d5a33..5cacc26f18c 100644
--- a/addons/mail/i18n/pl.po
+++ b/addons/mail/i18n/pl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/pt.po b/addons/mail/i18n/pt.po
index f4e407562a0..a5eeb6db6eb 100644
--- a/addons/mail/i18n/pt.po
+++ b/addons/mail/i18n/pt.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/pt_BR.po b/addons/mail/i18n/pt_BR.po
index 1bd0a00f4a6..94c350a7781 100644
--- a/addons/mail/i18n/pt_BR.po
+++ b/addons/mail/i18n/pt_BR.po
@@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/ro.po b/addons/mail/i18n/ro.po
index 9bfb9331b80..2605e26660a 100644
--- a/addons/mail/i18n/ro.po
+++ b/addons/mail/i18n/ro.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/ru.po b/addons/mail/i18n/ru.po
index 70267a398db..819035082dd 100644
--- a/addons/mail/i18n/ru.po
+++ b/addons/mail/i18n/ru.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/sl.po b/addons/mail/i18n/sl.po
index 91145244cda..0674e2410bd 100644
--- a/addons/mail/i18n/sl.po
+++ b/addons/mail/i18n/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/sr@latin.po b/addons/mail/i18n/sr@latin.po
index 1bff0193658..d0694a48ccc 100644
--- a/addons/mail/i18n/sr@latin.po
+++ b/addons/mail/i18n/sr@latin.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/sv.po b/addons/mail/i18n/sv.po
index 5ed6764f98f..6565aaf3b2f 100644
--- a/addons/mail/i18n/sv.po
+++ b/addons/mail/i18n/sv.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/th.po b/addons/mail/i18n/th.po
index 54483c96055..bd2b2d7edd9 100644
--- a/addons/mail/i18n/th.po
+++ b/addons/mail/i18n/th.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/tr.po b/addons/mail/i18n/tr.po
index 02a88e33789..f3ef77a2241 100644
--- a/addons/mail/i18n/tr.po
+++ b/addons/mail/i18n/tr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/vi.po b/addons/mail/i18n/vi.po
index d234db7afc6..b64082ee258 100644
--- a/addons/mail/i18n/vi.po
+++ b/addons/mail/i18n/vi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:21+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/zh_CN.po b/addons/mail/i18n/zh_CN.po
index b1ae0e6ea58..a9829f57c1e 100644
--- a/addons/mail/i18n/zh_CN.po
+++ b/addons/mail/i18n/zh_CN.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/i18n/zh_TW.po b/addons/mail/i18n/zh_TW.po
index e66d773e10c..69cb75db37e 100644
--- a/addons/mail/i18n/zh_TW.po
+++ b/addons/mail/i18n/zh_TW.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-04-12 08:22+0000\n"
-"X-Generator: Launchpad (build 16976)\n"
+"X-Launchpad-Export-Date: 2014-04-22 07:43+0000\n"
+"X-Generator: Launchpad (build 16985)\n"
#. module: mail
#: view:mail.followers:0
diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py
index 0059df90530..33f5f1f8a83 100644
--- a/addons/mail/mail_followers.py
+++ b/addons/mail/mail_followers.py
@@ -96,13 +96,7 @@ class mail_notification(osv.Model):
if message.author_id and message.author_id.email == partner.email:
continue
# Partner does not want to receive any emails or is opt-out
- if partner.notification_email_send == 'none':
- continue
- # Partner wants to receive only emails and comments
- if partner.notification_email_send == 'comment' and message.type not in ('email', 'comment'):
- continue
- # Partner wants to receive only emails
- if partner.notification_email_send == 'email' and message.type != 'email':
+ if partner.notify_email == 'none':
continue
notify_pids.append(partner.id)
return notify_pids
@@ -115,8 +109,7 @@ class mail_notification(osv.Model):
Administrator
</p>
<div>
- <small>Sent by <a ...>Your Company</a> using <a ...>OpenERP</a>.</small> OR
- <small>Sent by Administrator using <a ...>OpenERP</a>.</small>
+ <small>Sent from <a ...>Your Company</a> using <a ...>OpenERP</a>.</small>
</div>
"""
footer = ""
@@ -138,7 +131,7 @@ class mail_notification(osv.Model):
company = "<a style='color:inherit' href='%s'>%s</a>" % (website_url, user.company_id.name)
else:
company = user.company_id.name
- sent_by = _('Sent by %(company)s using %(openerp)s.')
+ sent_by = _('Sent from %(company)s using %(openerp)s')
signature_company = '<small>%s</small>' % (sent_by % {
'company': company,
'openerp': "<a style='color:inherit' href='https://www.openerp.com/'>OpenERP</a>"
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index a33eaaea15d..ebce0988dd3 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -126,7 +126,7 @@ class mail_mail(osv.Model):
_logger.exception("Failed processing mail queue")
return res
- def _postprocess_sent_message(self, cr, uid, mail, context=None):
+ def _postprocess_sent_message(self, cr, uid, mail, context=None, mail_sent=True):
"""Perform any post-processing necessary after sending ``mail``
successfully, including deleting it completely along with its
attachment if the ``auto_delete`` flag of the mail was set.
@@ -145,9 +145,10 @@ class mail_mail(osv.Model):
#------------------------------------------------------
def _get_partner_access_link(self, cr, uid, mail, partner=None, context=None):
- """ Generate URLs for links in mails:
- - partner is an user and has read access to the document: direct link to document with model, res_id
- """
+ """Generate URLs for links in mails: partner has access (is user):
+ link to action_mail_redirect action that will redirect to doc or Inbox """
+ if context is None:
+ context = {}
if partner and partner.user_ids:
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
# the parameters to encode for the query and fragment part of url
@@ -162,16 +163,15 @@ class mail_mail(osv.Model):
fragment.update(model=mail.model, res_id=mail.res_id)
url = urljoin(base_url, "/web?%s#%s" % (urlencode(query), urlencode(fragment)))
- return _("""<span class='oe_mail_footer_access'><small>Access your messages and documents <a style='color:inherit' href="%s">in OpenERP</a></small></span>""") % url
+ return _("""<span class='oe_mail_footer_access'><small>about <a style='color:inherit' href="%s">%s %s</a></small></span>""") % (url, context.get('model_name', ''), mail.record_name)
else:
return None
def send_get_mail_subject(self, cr, uid, mail, force=False, partner=None, context=None):
- """ If subject is void and record_name defined: '<Author> posted on <Resource>'
+ """If subject is void, set the subject as 'Re: <Resource>' or
+ 'Re: <mail.parent_id.subject>'
:param boolean force: force the subject replacement
- :param browse_record mail: mail.mail browse_record
- :param browse_record partner: specific recipient partner
"""
if (force or not mail.subject) and mail.record_name:
return 'Re: %s' % (mail.record_name)
@@ -180,12 +180,8 @@ class mail_mail(osv.Model):
return mail.subject
def send_get_mail_body(self, cr, uid, mail, partner=None, context=None):
- """ Return a specific ir_email body. The main purpose of this method
- is to be inherited to add custom content depending on some module.
-
- :param browse_record mail: mail.mail browse_record
- :param browse_record partner: specific recipient partner
- """
+ """Return a specific ir_email body. The main purpose of this method
+ is to be inherited to add custom content depending on some module."""
body = mail.body_html
# generate footer
@@ -194,34 +190,34 @@ class mail_mail(osv.Model):
body = tools.append_content_to_html(body, link, plaintext=False, container_tag='div')
return body
- def send_get_email_dict(self, cr, uid, mail, partner=None, context=None):
- """ Return a dictionary for specific email values, depending on a
- partner, or generic to the whole recipients given by mail.email_to.
-
- :param browse_record mail: mail.mail browse_record
- :param browse_record partner: specific recipient partner
- """
- body = self.send_get_mail_body(cr, uid, mail, partner=partner, context=context)
- subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context)
- body_alternative = tools.html2plaintext(body)
-
- # generate email_to, heuristic:
- # 1. if 'partner' is specified and there is a related document: Followers of 'Doc' <email>
- # 2. if 'partner' is specified, but no related document: Partner Name <email>
- # 3; fallback on mail.email_to that we split to have an email addresses list
- if partner and mail.record_name:
+ def send_get_mail_to(self, cr, uid, mail, partner=None, context=None):
+ """Forge the email_to with the following heuristic:
+ - if 'partner' and mail is a notification on a document: followers (Followers of 'Doc' <email>)
+ - elif 'partner', no notificatoin or no doc: recipient specific (Partner Name <email>)
+ - else fallback on mail.email_to splitting """
+ if partner and mail.notification and mail.record_name:
sanitized_record_name = re.sub(r'[^\w+.]+', '-', mail.record_name)
email_to = [_('"Followers of %s" <%s>') % (sanitized_record_name, partner.email)]
elif partner:
email_to = ['%s <%s>' % (partner.name, partner.email)]
else:
email_to = tools.email_split(mail.email_to)
+ return email_to
+ def send_get_email_dict(self, cr, uid, mail, partner=None, context=None):
+ """Return a dictionary for specific email values, depending on a
+ partner, or generic to the whole recipients given by mail.email_to.
+
+ :param browse_record mail: mail.mail browse_record
+ :param browse_record partner: specific recipient partner
+ """
+ body = self.send_get_mail_body(cr, uid, mail, partner=partner, context=context)
+ body_alternative = tools.html2plaintext(body)
return {
'body': body,
'body_alternative': body_alternative,
- 'subject': subject,
- 'email_to': email_to,
+ 'subject': self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context),
+ 'email_to': self.send_get_mail_to(cr, uid, mail, partner=partner, context=context),
}
def send(self, cr, uid, ids, auto_commit=False, raise_exception=False, context=None):
@@ -239,10 +235,19 @@ class mail_mail(osv.Model):
email sending process has failed
:return: True
"""
+ if context is None:
+ context = {}
ir_mail_server = self.pool.get('ir.mail_server')
-
for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
try:
+ # TDE note: remove me when model_id field is present on mail.message - done here to avoid doing it multiple times in the sub method
+ if mail.model:
+ model_id = self.pool['ir.model'].search(cr, SUPERUSER_ID, [('model', '=', mail.model)], context=context)[0]
+ model = self.pool['ir.model'].browse(cr, SUPERUSER_ID, model_id, context=context)
+ else:
+ model = None
+ if model:
+ context['model_name'] = model.name
# handle attachments
attachments = []
for attach in mail.attachment_ids:
@@ -284,7 +289,7 @@ class mail_mail(osv.Model):
res = ir_mail_server.send_email(cr, uid, msg,
mail_server_id=mail.mail_server_id.id,
context=context)
-
+
if res:
mail.write({'state': 'sent', 'message_id': res})
mail_sent = True
@@ -294,11 +299,11 @@ class mail_mail(osv.Model):
# /!\ can't use mail.state here, as mail.refresh() will cause an error
# see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1
- if mail_sent:
- self._postprocess_sent_message(cr, uid, mail, context=context)
+ self._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=mail_sent)
except Exception as e:
_logger.exception('failed sending mail.mail %s', mail.id)
mail.write({'state': 'exception'})
+ self._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=False)
if raise_exception:
if isinstance(e, AssertionError):
# get the args of the original error, wrap into a value and throw a MailDeliveryException
@@ -307,6 +312,6 @@ class mail_mail(osv.Model):
raise MailDeliveryException(_("Mail Delivery Failed"), value)
raise
- if auto_commit == True:
+ if auto_commit is True:
cr.commit()
return True
diff --git a/addons/mail/mail_mail_view.xml b/addons/mail/mail_mail_view.xml
index cf3dd1e8233..e259d28a2b7 100644
--- a/addons/mail/mail_mail_view.xml
+++ b/addons/mail/mail_mail_view.xml
@@ -36,6 +36,7 @@
<div>
<group string="Status">
<field name="auto_delete"/>
+ <field name="notification"/>
<field name="type"/>
<field name="state"/>
<field name="mail_server_id"/>
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 4c05d7a6d1f..5b716a14ef2 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -81,22 +81,6 @@ class mail_message(osv.Model):
context = dict(context, default_type=None)
return super(mail_message, self).default_get(cr, uid, fields, context=context)
- def _shorten_name(self, name):
- if len(name) <= (self._message_record_name_length + 3):
- return name
- return name[:self._message_record_name_length] + '...'
-
- def _get_record_name(self, cr, uid, ids, name, arg, context=None):
- """ Return the related document name, using name_get. It is done using
- SUPERUSER_ID, to be sure to have the record name correctly stored. """
- # TDE note: regroup by model/ids, to have less queries to perform
- result = dict.fromkeys(ids, False)
- for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context):
- if not message.get('model') or not message.get('res_id') or message['model'] not in self.pool:
- continue
- result[message['id']] = self.pool[message['model']].name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1]
- return result
-
def _get_to_read(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, False) for id in ids)
@@ -135,16 +119,6 @@ class mail_message(osv.Model):
inversed because we search unread message on a read column. """
return ['&', ('notification_ids.partner_id.user_ids', 'in', [uid]), ('notification_ids.starred', '=', domain[0][2])]
- def name_get(self, cr, uid, ids, context=None):
- # name_get may receive int id instead of an id list
- if isinstance(ids, (int, long)):
- ids = [ids]
- res = []
- for message in self.browse(cr, uid, ids, context=context):
- name = '%s: %s' % (message.subject or '', strip_tags(message.body or '') or '')
- res.append((message.id, self._shorten_name(name.lstrip(' :'))))
- return res
-
_columns = {
'type': fields.selection([
('email', 'Email'),
@@ -172,9 +146,7 @@ class mail_message(osv.Model):
'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'),
'model': fields.char('Related Document Model', size=128, select=1),
'res_id': fields.integer('Related Document ID', select=1),
- 'record_name': fields.function(_get_record_name, type='char',
- store=True, string='Message Record Name',
- help="Name get of the related document."),
+ 'record_name': fields.char('Message Record Name', help="Name get of the related document."),
'notification_ids': fields.one2many('mail.notification', 'message_id',
string='Notifications', auto_join=True,
help='Technical field holding the message notifications. Use notified_partner_ids to access notified partners.'),
@@ -783,6 +755,13 @@ class mail_message(osv.Model):
_('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \
(self._description, operation))
+ def _get_record_name(self, cr, uid, values, context=None):
+ """ Return the related document name, using name_get. It is done using
+ SUPERUSER_ID, to be sure to have the record name correctly stored. """
+ if not values.get('model') or not values.get('res_id') or values['model'] not in self.pool:
+ return False
+ return self.pool[values['model']].name_get(cr, SUPERUSER_ID, [values['res_id']], context=context)[0][1]
+
def _get_reply_to(self, cr, uid, values, context=None):
""" Return a specific reply_to: alias of the document through message_get_reply_to
or take the email_from
@@ -841,8 +820,11 @@ class mail_message(osv.Model):
values['message_id'] = self._get_message_id(cr, uid, values, context=context)
if 'reply_to' not in values:
values['reply_to'] = self._get_reply_to(cr, uid, values, context=context)
+ if 'record_name' not in values and 'default_record_name' not in context:
+ values['record_name'] = self._get_record_name(cr, uid, values, context=context)
newid = super(mail_message, self).create(cr, uid, values, context)
+
self._notify(cr, uid, newid, context=context,
force_send=context.get('mail_notify_force_send', True),
user_signature=context.get('mail_notify_user_signature', True))
@@ -887,78 +869,6 @@ class mail_message(osv.Model):
# Messaging API
#------------------------------------------------------
- # TDE note: this code is not used currently, will be improved in a future merge, when quoted context
- # will be added to email send for notifications. Currently only WIP.
- MAIL_TEMPLATE = """<div>
- % if message:
- ${display_message(message)}
- % endif
- % for ctx_msg in context_messages:
- ${display_message(ctx_msg)}
- % endfor
- % if add_expandable:
- ${display_expandable()}
- % endif
- ${display_message(header_message)}
- </div>
-
- <%def name="display_message(message)">
- <div>
- Subject: ${message.subject}<br />
- Body: ${message.body}
- </div>
- </%def>
-
- <%def name="display_expandable()">
- <div>This is an expandable.</div>
- </%def>
- """
-
- def message_quote_context(self, cr, uid, id, context=None, limit=3, add_original=False):
- """
- 1. message.parent_id = False: new thread, no quote_context
- 2. get the lasts messages in the thread before message
- 3. get the message header
- 4. add an expandable between them
-
- :param dict quote_context: options for quoting
- :return string: html quote
- """
- add_expandable = False
-
- message = self.browse(cr, uid, id, context=context)
- if not message.parent_id:
- return ''
- context_ids = self.search(cr, uid, [
- ('parent_id', '=', message.parent_id.id),
- ('id', '<', message.id),
- ], limit=limit, context=context)
-
- if len(context_ids) >= limit:
- add_expandable = True
- context_ids = context_ids[0:-1]
-
- context_ids.append(message.parent_id.id)
- context_messages = self.browse(cr, uid, context_ids, context=context)
- header_message = context_messages.pop()
-
- try:
- if not add_original:
- message = False
- result = MakoTemplate(self.MAIL_TEMPLATE).render_unicode(message=message,
- context_messages=context_messages,
- header_message=header_message,
- add_expandable=add_expandable,
- # context kw would clash with mako internals
- ctx=context,
- format_exceptions=True)
- result = result.strip()
- return result
- except Exception:
- _logger.exception("failed to render mako template for quoting message")
- return ''
- return result
-
def _notify(self, cr, uid, newid, context=None, force_send=False, user_signature=True):
""" Add the related record followers to the destination partner_ids if is not a private message.
Call mail_notification.notify to manage the email sending
@@ -975,9 +885,11 @@ class mail_message(osv.Model):
cr, SUPERUSER_ID, [
('res_model', '=', message.model),
('res_id', '=', message.res_id),
- ('subtype_ids', 'in', message.subtype_id.id)
], context=context)
- partners_to_notify |= set(fo.partner_id.id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context))
+ partners_to_notify |= set(
+ fo.partner_id.id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)
+ if message.subtype_id.id in [st.id for st in fo.subtype_ids]
+ )
# remove me from notified partners, unless the message is written on my own wall
if message.subtype_id and message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id:
partners_to_notify |= set([message.author_id.id])
@@ -1006,25 +918,3 @@ class mail_message(osv.Model):
'partner_id': partner.id,
'read': True,
}, context=context)
-
- #------------------------------------------------------
- # Tools
- #------------------------------------------------------
-
- def check_partners_email(self, cr, uid, partner_ids, context=None):
- """ Verify that selected partner_ids have an email_address defined.
- Otherwise throw a warning. """
- partner_wo_email_lst = []
- for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
- if not partner.email:
- partner_wo_email_lst.append(partner)
- if not partner_wo_email_lst:
- return {}
- warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
- for partner in partner_wo_email_lst:
- warning_msg += '\n- %s' % (partner.name)
- return {'warning': {
- 'title': _('Partners email addresses not found'),
- 'message': warning_msg,
- }
- }
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 812ff91be90..112dff6bac6 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -97,6 +97,9 @@ class mail_thread(osv.AbstractModel):
# :param function lambda: returns whether the tracking should record using this subtype
_track = {}
+ # Mass mailing feature
+ _mail_mass_mailing = False
+
def get_empty_list_help(self, cr, uid, help, context=None):
""" Override of BaseModel.get_empty_list_help() to generate an help message
that adds alias information. """
@@ -585,23 +588,6 @@ class mail_thread(osv.AbstractModel):
model_obj.check_access_rights(cr, uid, check_operation)
model_obj.check_access_rule(cr, uid, mids, check_operation, context=context)
- def _get_formview_action(self, cr, uid, id, model=None, context=None):
- """ Return an action to open the document. This method is meant to be
- overridden in addons that want to give specific view ids for example.
-
- :param int id: id of the document to open
- :param string model: specific model that overrides self._name
- """
- return {
- 'type': 'ir.actions.act_window',
- 'res_model': model or self._name,
- 'view_type': 'form',
- 'view_mode': 'form',
- 'views': [(False, 'form')],
- 'target': 'current',
- 'res_id': id,
- }
-
def _get_inbox_action_xml_id(self, cr, uid, context=None):
""" When redirecting towards the Inbox, choose which action xml_id has
to be fetched. This method is meant to be inherited, at least in portal
@@ -644,10 +630,7 @@ class mail_thread(osv.AbstractModel):
if model_obj.check_access_rights(cr, uid, 'read', raise_exception=False):
try:
model_obj.check_access_rule(cr, uid, [res_id], 'read', context=context)
- if not hasattr(model_obj, '_get_formview_action'):
- action = self.pool.get('mail.thread')._get_formview_action(cr, uid, res_id, model=model, context=context)
- else:
- action = model_obj._get_formview_action(cr, uid, res_id, context=context)
+ action = model_obj.get_formview_action(cr, uid, res_id, context=context)
except (osv.except_osv, orm.except_orm):
pass
action.update({
@@ -662,15 +645,31 @@ class mail_thread(osv.AbstractModel):
# Email specific
#------------------------------------------------------
+ def message_get_default_recipients(self, cr, uid, ids, context=None):
+ if context and context.get('thread_model') and context['thread_model'] in self.pool and context['thread_model'] != self._name:
+ sub_ctx = dict(context)
+ sub_ctx.pop('thread_model')
+ return self.pool[context['thread_model']].message_get_default_recipients(cr, uid, ids, context=sub_ctx)
+ res = {}
+ for record in self.browse(cr, SUPERUSER_ID, ids, context=context):
+ recipient_ids, email_to, email_cc = set(), False, False
+ if 'partner_id' in self._all_columns and record.partner_id:
+ recipient_ids.add(record.partner_id.id)
+ elif 'email_from' in self._all_columns and record.email_from:
+ email_to = record.email_from
+ elif 'email' in self._all_columns:
+ email_to = record.email
+ res[record.id] = {'partner_ids': list(recipient_ids), 'email_to': email_to, 'email_cc': email_cc}
+ return res
+
def message_get_reply_to(self, cr, uid, ids, context=None):
""" Returns the preferred reply-to email address that is basically
the alias of the document, if it exists. """
if not self._inherits.get('mail.alias'):
return [False for id in ids]
- return ["%s@%s" % (record['alias_name'], record['alias_domain'])
- if record.get('alias_domain') and record.get('alias_name')
- else False
- for record in self.read(cr, SUPERUSER_ID, ids, ['alias_name', 'alias_domain'], context=context)]
+ return ["%s@%s" % (record.alias_name, record.alias_domain)
+ if record.alias_domain and record.alias_name else False
+ for record in self.browse(cr, SUPERUSER_ID, ids, context=context)]
#------------------------------------------------------
# Mail gateway
diff --git a/addons/mail/res_partner.py b/addons/mail/res_partner.py
index 8da2441f3bc..bf801511761 100644
--- a/addons/mail/res_partner.py
+++ b/addons/mail/res_partner.py
@@ -28,23 +28,21 @@ class res_partner_mail(osv.Model):
_name = "res.partner"
_inherit = ['res.partner', 'mail.thread']
_mail_flat_thread = False
+ _mail_mass_mailing = _('Customers')
_columns = {
- 'notification_email_send': fields.selection([
+ 'notify_email': fields.selection([
('none', 'Never'),
- ('email', 'Incoming Emails only'),
- ('comment', 'Incoming Emails and Discussions'),
- ('all', 'All Messages (discussions, emails, followed system notifications)'),
- ], 'Receive Messages by Email', required=True,
+ ('always', 'All Messages'),
+ ], 'Receive Inbox Notifications by Email', required=True,
+ oldname='notification_email_send',
help="Policy to receive emails for new messages pushed to your personal Inbox:\n"
"- Never: no emails are sent\n"
- "- Incoming Emails only: for messages received by the system via email\n"
- "- Incoming Emails and Discussions: for incoming emails along with internal discussions\n"
"- All Messages: for every notification you receive in your Inbox"),
}
_defaults = {
- 'notification_email_send': lambda *args: 'comment'
+ 'notify_email': lambda *args: 'always'
}
def message_get_suggested_recipients(self, cr, uid, ids, context=None):
@@ -53,4 +51,5 @@ class res_partner_mail(osv.Model):
self._message_add_suggested_recipient(cr, uid, recipients, partner, partner=partner, reason=_('Partner Profile'))
return recipients
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+ def message_get_default_recipients(self, cr, uid, ids, context=None):
+ return dict((id, {'partner_ids': [id], 'email_to': False, 'email_cc': False}) for id in ids)
diff --git a/addons/mail/res_partner_view.xml b/addons/mail/res_partner_view.xml
index 7df5d27c9d0..5066d85e682 100644
--- a/addons/mail/res_partner_view.xml
+++ b/addons/mail/res_partner_view.xml
@@ -8,7 +8,7 @@
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='active']" position="after">
- <field name='notification_email_send'/>
+ <field name='notify_email' widget="radio"/>
</xpath>
<xpath expr="//sheet" position="after">
<div class="oe_chatter">
diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py
index 42e739d8051..8fe1482b427 100644
--- a/addons/mail/res_users.py
+++ b/addons/mail/res_users.py
@@ -54,10 +54,10 @@ class res_users(osv.Model):
init_res = super(res_users, self).__init__(pool, cr)
# duplicate list to avoid modifying the original reference
self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
- self.SELF_WRITEABLE_FIELDS.extend(['notification_email_send', 'display_groups_suggestions'])
+ self.SELF_WRITEABLE_FIELDS.extend(['notify_email', 'display_groups_suggestions'])
# duplicate list to avoid modifying the original reference
self.SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS)
- self.SELF_READABLE_FIELDS.extend(['notification_email_send', 'alias_domain', 'alias_name', 'display_groups_suggestions'])
+ self.SELF_READABLE_FIELDS.extend(['notify_email', 'alias_domain', 'alias_name', 'display_groups_suggestions'])
return init_res
def _auto_init(self, cr, context=None):
diff --git a/addons/mail/res_users_view.xml b/addons/mail/res_users_view.xml
index 2bf54b4bafd..eef2924134f 100644
--- a/addons/mail/res_users_view.xml
+++ b/addons/mail/res_users_view.xml
@@ -10,7 +10,7 @@
<field name="arch" type="xml">
<data>
<field name="email" position="before">
- <field name="notification_email_send" readonly="0"/>
+ <field name="notify_email" widget="radio" readonly="0"/>
</field>
</data>
</field>
@@ -24,7 +24,7 @@
<field name="arch" type="xml">
<data>
<field name="signature" position="before">
- <field name="notification_email_send"/>
+ <field name="notify_email" widget="radio"/>
</field>
<field name="signature" position="before">
<label for="alias_id" string="Messaging Alias" class="oe_read_only"
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 17dd4b57cd0..99a7751e15e 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -507,18 +507,15 @@ openerp.mail = function (session) {
}
$.when(recipient_done).done(function (partner_ids) {
var context = {
- 'default_composition_mode': default_composition_mode,
'default_parent_id': self.id,
'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''),
'default_attachment_ids': _.map(self.attachment_ids, function (file) {return file.id;}),
'default_partner_ids': partner_ids,
+ 'default_is_log': self.is_log,
'mail_post_autofollow': true,
'mail_post_autofollow_partner_ids': partner_ids,
'is_private': self.is_private
};
- if (self.is_log) {
- _.extend(context, {'mail_compose_log': true});
- }
if (default_composition_mode != 'reply' && self.context.default_model && self.context.default_res_id) {
context.default_model = self.context.default_model;
context.default_res_id = self.context.default_res_id;
diff --git a/addons/mail/static/src/js/many2many_tags_email.js b/addons/mail/static/src/js/many2many_tags_email.js
index cc701e8a585..5d36262f5b9 100644
--- a/addons/mail/static/src/js/many2many_tags_email.js
+++ b/addons/mail/static/src/js/many2many_tags_email.js
@@ -44,7 +44,7 @@ instance.web.form.FieldMany2ManyTagsEmail = instance.web.form.FieldMany2ManyTags
new instance.web.Model('res.partner').call("search", [[
["id", "in", ids],
["email", "=", false],
- ["notification_email_send", "in", ['all', 'comment']] ]],
+ ["notify_email", "=", 'always'] ]],
{context: this.build_context()})
.then(function (record_ids) {
// valid partner
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 28cbbca1f2c..06af2303239 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -189,17 +189,6 @@
</td>
<td><div class="oe_view_manager_view_search" t-opentag="true"/></td>
</tr>
- <tr class="oe_header_row" t-if="widget.action.params.view_inbox and widget.action.params.show_compose_message" >
- <td colspan="2">
- <button type="button" class="oe_write_full oe_highlight">
- Compose a new message
- </button>
- <span class='oe_alternative'>
- or
- <a href='#' class='oe_write_onwall oe_bold' help='Your followers can read this message'>Write to my followers</a>
- </span>
- </td>
- </tr>
</tbody>
</table>
<div class="oe_mail-placeholder"></div>
diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py
index 68a329e043a..d53a8078c96 100644
--- a/addons/mail/tests/common.py
+++ b/addons/mail/tests/common.py
@@ -77,7 +77,7 @@ class TestMail(common.TransactionCase):
'alias_name': 'ernest',
'email': 'e.e@example.com',
'signature': '--\nErnest',
- 'notification_email_send': 'comment',
+ 'notify_email': 'always',
'groups_id': [(6, 0, [self.group_employee_id])]
}, {'no_reset_password': True})
self.user_noone_id = self.res_users.create(cr, uid, {
@@ -86,7 +86,7 @@ class TestMail(common.TransactionCase):
'alias_name': 'noemie',
'email': 'n.n@example.com',
'signature': '--\nNoemie',
- 'notification_email_send': 'comment',
+ 'notify_email': 'always',
'groups_id': [(6, 0, [])]
}, {'no_reset_password': True})
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index c7f1056c59a..0a481c78eca 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -210,24 +210,6 @@ class test_mail(TestMail):
self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs')
self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs')
- def test_10_message_quote_context(self):
- """ Tests designed for message_post. """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
-
- msg1_id = self.mail_message.create(cr, uid, {'body': 'Thread header about Zap Brannigan', 'subject': 'My subject'})
- msg2_id = self.mail_message.create(cr, uid, {'body': 'First answer, should not be displayed', 'subject': 'Re: My subject', 'parent_id': msg1_id})
- msg3_id = self.mail_message.create(cr, uid, {'body': 'Second answer', 'subject': 'Re: My subject', 'parent_id': msg1_id})
- msg4_id = self.mail_message.create(cr, uid, {'body': 'Third answer', 'subject': 'Re: My subject', 'parent_id': msg1_id})
- msg_new_id = self.mail_message.create(cr, uid, {'body': 'My answer I am propagating', 'subject': 'Re: My subject', 'parent_id': msg1_id})
-
- result = self.mail_message.message_quote_context(cr, uid, msg_new_id, limit=3)
- self.assertIn('Thread header about Zap Brannigan', result, 'Thread header content should be in quote.')
- self.assertIn('Second answer', result, 'Answer should be in quote.')
- self.assertIn('Third answer', result, 'Answer should be in quote.')
- self.assertIn('expandable', result, 'Expandable should be present.')
- self.assertNotIn('First answer, should not be displayed', result, 'Old answer should not be in quote.')
- self.assertNotIn('My answer I am propagating', result, 'Thread header content should be in quote.')
-
def test_11_notification_url(self):
""" Tests designed to test the URL added in notification emails. """
cr, uid, group_pigs = self.cr, self.uid, self.group_pigs
@@ -366,14 +348,14 @@ class test_mail(TestMail):
# Data creation
# --------------------------------------------------
# 0 - Update existing users-partners
- self.res_users.write(cr, uid, [uid], {'email': 'a@a', 'notification_email_send': 'comment'})
+ self.res_users.write(cr, uid, [uid], {'email': 'a@a', 'notify_email': 'always'})
self.res_users.write(cr, uid, [self.user_raoul_id], {'email': 'r@r'})
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
# 2 - Carine Poilvache, with email, should receive emails for emails
- p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
+ p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notify_email': 'none'})
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
- p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notification_email_send': 'all'})
+ p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notify_email': 'always'})
# 4 - Attachments
attach1_id = self.ir_attachment.create(cr, user_raoul.id, {
'name': 'Attach1', 'datas_fname': 'Attach1',
@@ -600,9 +582,9 @@ class test_mail(TestMail):
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
# 2 - Carine Poilvache, with email, should receive emails for emails
- p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
+ p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notify_email': 'always'})
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
- p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notification_email_send': 'all'})
+ p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notify_email': 'always'})
# 4 - Create a Bird mail.group, that will be used to test mass mailing
group_bird_id = self.mail_group.create(cr, uid,
{
@@ -674,7 +656,6 @@ class test_mail(TestMail):
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]
}, context={
'default_composition_mode': 'reply',
- 'default_model': 'mail.thread',
'default_res_id': self.group_pigs_id,
'default_parent_id': message.id
})
@@ -699,11 +680,10 @@ class test_mail(TestMail):
# --------------------------------------------------
# Do: Compose in mass_mail_mode on pigs and bird
- compose_id = mail_compose.create(cr, user_raoul.id,
- {
+ compose_id = mail_compose.create(
+ cr, user_raoul.id, {
'subject': _subject,
'body': '${object.description}',
- 'post': True,
'partner_ids': [(4, p_c_id), (4, p_d_id)],
}, context={
'default_composition_mode': 'mass_mail',
@@ -718,6 +698,13 @@ class test_mail(TestMail):
'default_res_id': -1,
'active_ids': [self.group_pigs_id, group_bird_id]
})
+ # check mail_mail
+ mail_mail_ids = self.mail_mail.search(cr, uid, [('subject', '=', _subject)])
+ for mail_mail in self.mail_mail.browse(cr, uid, mail_mail_ids):
+ self.assertEqual(set([p.id for p in mail_mail.recipient_ids]), set([p_c_id, p_d_id]),
+ 'compose wizard: mail_mail mass mailing: mail.mail in mass mail incorrect recipients')
+
+ # check logged messages
group_pigs.refresh()
group_bird.refresh()
message1 = group_pigs.message_ids[0]
@@ -733,14 +720,14 @@ class test_mail(TestMail):
'compose wizard: message_post: mail.message in mass mail subject incorrect')
self.assertEqual(message1.body, '<p>%s</p>' % group_pigs.description,
'compose wizard: message_post: mail.message in mass mail body incorrect')
- self.assertEqual(set([p.id for p in message1.notified_partner_ids]), set([p_c_id, p_d_id]),
- 'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
+ # self.assertEqual(set([p.id for p in message1.notified_partner_ids]), set([p_c_id, p_d_id]),
+ # 'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
self.assertEqual(message2.subject, _subject,
'compose wizard: message_post: mail.message in mass mail subject incorrect')
self.assertEqual(message2.body, '<p>%s</p>' % group_bird.description,
'compose wizard: message_post: mail.message in mass mail body incorrect')
- self.assertEqual(set([p.id for p in message2.notified_partner_ids]), set([p_c_id, p_d_id]),
- 'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
+ # self.assertEqual(set([p.id for p in message2.notified_partner_ids]), set([p_c_id, p_d_id]),
+ # 'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
# Test: mail.group followers: author not added as follower in mass mail mode
pigs_pids = [p.id for p in group_pigs.message_follower_ids]
@@ -757,7 +744,6 @@ class test_mail(TestMail):
{
'subject': _subject,
'body': '${object.description}',
- 'post': True,
'partner_ids': [(4, p_c_id), (4, p_d_id)],
}, context={
'default_composition_mode': 'mass_mail',
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index e5ff2b51fcd..e14a8f3dfe5 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -38,10 +38,7 @@ class mail_compose_message(osv.TransientModel):
at model and view levels to provide specific features.
The behavior of the wizard depends on the composition_mode field:
- - 'reply': reply to a previous message. The wizard is pre-populated
- via ``get_message_data``.
- - 'comment': new post on a record. The wizard is pre-populated via
- ``get_record_data``
+ - 'comment': post on a record. The wizard is pre-populated via ``get_record_data``
- 'mass_mail': wizard in mass mailing mode where the mail details can
contain template placeholders that will be merged with actual data
before being sent to each recipient.
@@ -50,6 +47,7 @@ class mail_compose_message(osv.TransientModel):
_inherit = 'mail.message'
_description = 'Email composition wizard'
_log_access = True
+ _batch_size = 500
def default_get(self, cr, uid, fields, context=None):
""" Handle composition mode. Some details about context keys:
@@ -68,28 +66,22 @@ class mail_compose_message(osv.TransientModel):
if context is None:
context = {}
result = super(mail_compose_message, self).default_get(cr, uid, fields, context=context)
- # get some important values from context
- composition_mode = context.get('default_composition_mode', context.get('mail.compose.message.mode'))
- model = context.get('default_model', context.get('active_model'))
- res_id = context.get('default_res_id', context.get('active_id'))
- message_id = context.get('default_parent_id', context.get('message_id', context.get('active_id')))
- active_ids = context.get('active_ids')
+
+ # v6.1 compatibility mode
+ result['composition_mode'] = result.get('composition_mode', context.get('mail.compose.message.mode'))
+ result['model'] = result.get('model', context.get('active_model'))
+ result['res_id'] = result.get('res_id', context.get('active_id'))
+ result['parent_id'] = result.get('parent_id', context.get('message_id'))
+
+ # default values according to composition mode - NOTE: reply is deprecated, fall back on comment
+ if result['composition_mode'] == 'reply':
+ result['composition_mode'] = 'comment'
+ vals = {}
if 'active_domain' in context: # not context.get() because we want to keep global [] domains
- result['use_active_domain'] = True
- result['active_domain'] = '%s' % context.get('active_domain')
- elif not result.get('active_domain'):
- result['active_domain'] = ''
- # get default values according to the composition mode
- if composition_mode == 'reply':
- vals = self.get_message_data(cr, uid, message_id, context=context)
- elif composition_mode == 'comment' and model and res_id:
- vals = self.get_record_data(cr, uid, model, res_id, context=context)
- elif composition_mode == 'mass_mail' and model and active_ids:
- vals = {'model': model, 'res_id': res_id}
- else:
- vals = {'model': model, 'res_id': res_id}
- if composition_mode:
- vals['composition_mode'] = composition_mode
+ vals['use_active_domain'] = True
+ vals['active_domain'] = '%s' % context.get('active_domain')
+ if result['composition_mode'] == 'comment':
+ vals.update(self.get_record_data(cr, uid, result, context=context))
for field in vals:
if field in fields:
@@ -102,13 +94,15 @@ class mail_compose_message(osv.TransientModel):
# but when creating the mail.message to create the mail.compose.message
# access rights issues may rise
# We therefore directly change the model and res_id
- if result.get('model') == 'res.users' and result.get('res_id') == uid:
+ if result['model'] == 'res.users' and result['res_id'] == uid:
result['model'] = 'res.partner'
result['res_id'] = self.pool.get('res.users').browse(cr, uid, uid).partner_id.id
return result
def _get_composition_mode_selection(self, cr, uid, context=None):
- return [('comment', 'Comment a document'), ('reply', 'Reply to a message'), ('mass_mail', 'Mass mailing')]
+ return [('comment', 'Post on a document'),
+ ('mass_mail', 'Email Mass Mailing'),
+ ('mass_post', 'Post on Multiple Documents')]
_columns = {
'composition_mode': fields.selection(
@@ -116,19 +110,19 @@ class mail_compose_message(osv.TransientModel):
string='Composition mode'),
'partner_ids': fields.many2many('res.partner',
'mail_compose_message_res_partner_rel',
- 'wizard_id', 'partner_id', 'Additional contacts'),
+ 'wizard_id', 'partner_id', 'Additional Contacts'),
'use_active_domain': fields.boolean('Use active domain'),
'active_domain': fields.char('Active domain', readonly=True),
- 'post': fields.boolean('Post a copy in the document',
- help='Post a copy of the message on the document communication history.'),
- 'notify': fields.boolean('Notify followers',
- help='Notify followers of the document'),
- 'same_thread': fields.boolean('Replies in the document',
- help='Replies to the messages will go into the selected document.'),
'attachment_ids': fields.many2many('ir.attachment',
'mail_compose_message_ir_attachments_rel',
'wizard_id', 'attachment_id', 'Attachments'),
- 'filter_id': fields.many2one('ir.filters', 'Filters'),
+ 'is_log': fields.boolean('Log an Internal Note',
+ help='Whether the message is an internal note (comment mode only)'),
+ # mass mode options
+ 'notify': fields.boolean('Notify followers',
+ help='Notify followers of the document (mass post only)'),
+ 'same_thread': fields.boolean('Replies in the document',
+ help='Replies to the messages will go into the selected document (mass mail only)'),
}
#TODO change same_thread to False in trunk (Require view update)
_defaults = {
@@ -136,8 +130,6 @@ class mail_compose_message(osv.TransientModel):
'body': lambda self, cr, uid, ctx={}: '',
'subject': lambda self, cr, uid, ctx={}: False,
'partner_ids': lambda self, cr, uid, ctx={}: [],
- 'post': False,
- 'notify': False,
'same_thread': True,
}
@@ -169,61 +161,36 @@ class mail_compose_message(osv.TransientModel):
not want that feature in the wizard. """
return
- def get_record_data(self, cr, uid, model, res_id, context=None):
- """ Returns a defaults-like dict with initial values for the composition
- wizard when sending an email related to the document record
- identified by ``model`` and ``res_id``.
-
- :param str model: model name of the document record this mail is
- related to.
- :param int res_id: id of the document record this mail is related to
- """
- doc_name_get = self.pool[model].name_get(cr, uid, [res_id], context=context)
- record_name = False
- if doc_name_get:
- record_name = doc_name_get[0][1]
- values = {
- 'model': model,
- 'res_id': res_id,
- 'record_name': record_name,
- }
- if record_name:
- values['subject'] = 'Re: %s' % record_name
- return values
-
- def get_message_data(self, cr, uid, message_id, context=None):
+ def get_record_data(self, cr, uid, values, context=None):
""" Returns a defaults-like dict with initial values for the composition
- wizard when replying to the given message (e.g. including the quote
- of the initial message, and the correct recipients).
-
- :param int message_id: id of the mail.message to which the user
- is replying.
- """
- if not message_id:
- return {}
+ wizard when sending an email related a previous email (parent_id) or
+ a document (model, res_id). This is based on previously computed default
+ values. """
if context is None:
context = {}
- message_data = self.pool.get('mail.message').browse(cr, uid, message_id, context=context)
+ result, subject = {}, False
+ if values.get('parent_id'):
+ parent = self.pool.get('mail.message').browse(cr, uid, values.get('parent_id'), context=context)
+ result['record_name'] = parent.record_name,
+ subject = tools.ustr(parent.subject or parent.record_name or '')
+ if not values.get('model'):
+ result['model'] = parent.model
+ if not values.get('res_id'):
+ result['res_id'] = parent.res_id
+ partner_ids = values.get('partner_ids', list()) + [partner.id for partner in parent.partner_ids]
+ if context.get('is_private') and parent.author_id: # check message is private then add author also in partner list.
+ partner_ids += [parent.author_id.id]
+ result['partner_ids'] = partner_ids
+ elif values.get('model') and values.get('res_id'):
+ doc_name_get = self.pool[values.get('model')].name_get(cr, uid, [values.get('res_id')], context=context)
+ result['record_name'] = doc_name_get and doc_name_get[0][1] or ''
+ subject = tools.ustr(result['record_name'])
- # create subject
re_prefix = _('Re:')
- reply_subject = tools.ustr(message_data.subject or message_data.record_name or '')
- if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)) and message_data.subject:
- reply_subject = "%s %s" % (re_prefix, reply_subject)
- # get partner_ids from original message
- partner_ids = [partner.id for partner in message_data.partner_ids] if message_data.partner_ids else []
- partner_ids += context.get('default_partner_ids', [])
- if context.get('is_private',False) and message_data.author_id : #check message is private then add author also in partner list.
- partner_ids += [message_data.author_id.id]
- # update the result
- result = {
- 'record_name': message_data.record_name,
- 'model': message_data.model,
- 'res_id': message_data.res_id,
- 'parent_id': message_data.id,
- 'subject': reply_subject,
- 'partner_ids': partner_ids,
- }
+ if subject and not (subject.startswith('Re:') or subject.startswith(re_prefix)):
+ subject = "%s %s" % (re_prefix, subject)
+ result['subject'] = subject
+
return result
#------------------------------------------------------
@@ -235,53 +202,42 @@ class mail_compose_message(osv.TransientModel):
email(s), rendering any template patterns on the fly if needed. """
if context is None:
context = {}
+
# clean the context (hint: mass mailing sets some default values that
# could be wrongly interpreted by mail_mail)
context.pop('default_email_to', None)
context.pop('default_partner_ids', None)
- active_ids = context.get('active_ids')
- is_log = context.get('mail_compose_log', False)
-
for wizard in self.browse(cr, uid, ids, context=context):
- mass_mail_mode = wizard.composition_mode == 'mass_mail'
+ mass_mode = wizard.composition_mode in ('mass_mail', 'mass_post')
active_model_pool = self.pool[wizard.model if wizard.model else 'mail.thread']
if not hasattr(active_model_pool, 'message_post'):
context['thread_model'] = wizard.model
active_model_pool = self.pool['mail.thread']
# wizard works in batch mode: [res_id] or active_ids or active_domain
- if mass_mail_mode and wizard.use_active_domain and wizard.model:
+ if mass_mode and wizard.use_active_domain and wizard.model:
res_ids = self.pool[wizard.model].search(cr, uid, eval(wizard.active_domain), context=context)
- elif mass_mail_mode and wizard.model and active_ids:
- res_ids = active_ids
+ elif mass_mode and wizard.model and context.get('active_ids'):
+ res_ids = context['active_ids']
else:
res_ids = [wizard.res_id]
- all_mail_values = self.get_mail_values(cr, uid, wizard, res_ids, context=context)
-
- for res_id, mail_values in all_mail_values.iteritems():
- if mass_mail_mode and not wizard.post:
- m2m_attachment_ids = self.pool['mail.thread']._message_preprocess_attachments(
- cr, uid, mail_values.pop('attachments', []),
- mail_values.pop('attachment_ids', []),
- 'mail.message', 0,
- context=context)
- mail_values['attachment_ids'] = m2m_attachment_ids
- if not mail_values.get('reply_to'):
- mail_values['reply_to'] = mail_values['email_from']
- self.pool.get('mail.mail').create(cr, uid, mail_values, context=context)
- else:
- subtype = 'mail.mt_comment'
- if is_log: # log a note: subtype is False
- subtype = False
- elif mass_mail_mode: # mass mail: is a log pushed to recipients unless specified, author not added
- if not wizard.notify:
+ sliced_res_ids = [res_ids[i:i + self._batch_size] for i in range(0, len(res_ids), self._batch_size)]
+ for res_ids in sliced_res_ids:
+ all_mail_values = self.get_mail_values(cr, uid, wizard, res_ids, context=context)
+ for res_id, mail_values in all_mail_values.iteritems():
+ if wizard.composition_mode == 'mass_mail':
+ self.pool['mail.mail'].create(cr, uid, mail_values, context=context)
+ else:
+ subtype = 'mail.mt_comment'
+ if context.get('mail_compose_log') or (wizard.composition_mode == 'mass_post' and not wizard.notify): # log a note: subtype is False
subtype = False
- context = dict(context,
- mail_notify_force_send=False, # do not send emails directly but use the queue instead
- mail_create_nosubscribe=True) # add context key to avoid subscribing the author
- active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **mail_values)
+ if wizard.composition_mode == 'mass_post':
+ context = dict(context,
+ mail_notify_force_send=False, # do not send emails directly but use the queue instead
+ mail_create_nosubscribe=True) # add context key to avoid subscribing the author
+ active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **mail_values)
return {'type': 'ir.actions.act_window_close'}
@@ -289,6 +245,7 @@ class mail_compose_message(osv.TransientModel):
"""Generate the values that will be used by send_mail to create mail_messages
or mail_mails. """
results = dict.fromkeys(res_ids, False)
+ rendered_values, default_recipients = {}, {}
mass_mail_mode = wizard.composition_mode == 'mass_mail'
# render all template-based value at once
@@ -303,40 +260,46 @@ class mail_compose_message(osv.TransientModel):
'parent_id': wizard.parent_id and wizard.parent_id.id,
'partner_ids': [partner.id for partner in wizard.partner_ids],
'attachment_ids': [attach.id for attach in wizard.attachment_ids],
+ 'author_id': wizard.author_id.id,
+ 'email_from': wizard.email_from,
+ 'record_name': wizard.record_name,
}
# mass mailing: rendering override wizard static values
if mass_mail_mode and wizard.model:
+ # always keep a copy, reset record name (avoid browsing records)
+ mail_values.update(notification=True, model=wizard.model, res_id=res_id, record_name=False)
+ # auto deletion of mail_mail
+ if 'mail_auto_delete' in context:
+ mail_values['auto_delete'] = context.get('mail_auto_delete')
+ # rendered values using template
email_dict = rendered_values[res_id]
mail_values['partner_ids'] += email_dict.pop('partner_ids', [])
+ mail_values.update(email_dict)
+ if wizard.same_thread:
+ mail_values.pop('reply_to')
+ elif not mail_values.get('reply_to'):
+ mail_values['reply_to'] = mail_values['email_from']
+ # mail_mail values: body -> body_html, partner_ids -> recipient_ids
+ mail_values['body_html'] = mail_values.get('body', '')
+ mail_values['recipient_ids'] = [(4, id) for id in mail_values.pop('partner_ids', [])]
+
# process attachments: should not be encoded before being processed by message_post / mail_mail create
- attachments = []
- if email_dict.get('attachments'):
- for name, enc_cont in email_dict.pop('attachments'):
- attachments.append((name, base64.b64decode(enc_cont)))
- mail_values['attachments'] = attachments
+ mail_values['attachments'] = [(name, base64.b64decode(enc_cont)) for name, enc_cont in email_dict.pop('attachments', list())]
attachment_ids = []
for attach_id in mail_values.pop('attachment_ids'):
new_attach_id = self.pool.get('ir.attachment').copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context)
attachment_ids.append(new_attach_id)
- mail_values['attachment_ids'] = attachment_ids
- # email_from: mass mailing only can specify another email_from
- if email_dict.get('email_from'):
- mail_values['email_from'] = email_dict.pop('email_from')
- # replies redirection: mass mailing only
- if wizard.same_thread and wizard.post:
- email_dict.pop('reply_to', None)
- else:
- mail_values['reply_to'] = email_dict.pop('reply_to', None)
- mail_values.update(email_dict)
- # mass mailing without post: mail_mail values
- if mass_mail_mode and not wizard.post:
- if 'mail_auto_delete' in context:
- mail_values['auto_delete'] = context.get('mail_auto_delete')
- mail_values['body_html'] = mail_values.get('body', '')
- mail_values['recipient_ids'] = [(4, id) for id in mail_values.pop('partner_ids', [])]
+ mail_values['attachment_ids'] = self.pool['mail.thread']._message_preprocess_attachments(
+ cr, uid, mail_values.pop('attachments', []),
+ attachment_ids, 'mail.message', 0, context=context)
+
results[res_id] = mail_values
return results
+ #------------------------------------------------------
+ # Template rendering
+ #------------------------------------------------------
+
def render_message_batch(self, cr, uid, wizard, res_ids, context=None):
"""Generate template-based values of wizard, for the document records given
by res_ids. This method is meant to be inherited by email_template that
@@ -346,6 +309,10 @@ class mail_compose_message(osv.TransientModel):
once, and render it multiple times. This is useful for mass mailing where
template rendering represent a significant part of the process.
+ Default recipients are also computed, based on mail_thread method
+ message_get_default_recipients. This allows to ensure a mass mailing has
+ always some recipients specified.
+
:param browse wizard: current mail.compose.message browse record
:param list res_ids: list of record ids
@@ -357,6 +324,9 @@ class mail_compose_message(osv.TransientModel):
emails_from = self.render_template_batch(cr, uid, wizard.email_from, wizard.model, res_ids, context=context)
replies_to = self.render_template_batch(cr, uid, wizard.reply_to, wizard.model, res_ids, context=context)
+ ctx = dict(context, thread_model=wizard.model)
+ default_recipients = self.pool['mail.thread'].message_get_default_recipients(cr, uid, res_ids, context=ctx)
+
results = dict.fromkeys(res_ids, False)
for res_id in res_ids:
results[res_id] = {
@@ -365,6 +335,7 @@ class mail_compose_message(osv.TransientModel):
'email_from': emails_from[res_id],
'reply_to': replies_to[res_id],
}
+ results[res_id].update(default_recipients.get(res_id, dict()))
return results
def render_template_batch(self, cr, uid, template, model, res_ids, context=None, post_process=False):
diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml
index 23931649402..5b6bfc50439 100644
--- a/addons/mail/wizard/mail_compose_message_view.xml
+++ b/addons/mail/wizard/mail_compose_message_view.xml
@@ -11,6 +11,7 @@
<field name="composition_mode" invisible="1"/>
<field name="model" invisible="1"/>
<field name="res_id" invisible="1"/>
+ <field name="is_log" invisible="1"/>
<field name="parent_id" invisible="1"/>
<field name="mail_server_id" invisible="1"/>
<!-- Various warnings -->
@@ -28,29 +29,27 @@
<field name="email_from"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
<field name="subject" placeholder="Subject..." required="True"/>
- <!-- classic message composer -->
- <label for="partner_ids" string="Recipients"
- attrs="{'invisible':[('composition_mode', '=', 'mass_mail')]}"/>
- <div groups="base.group_user"
- attrs="{'invisible':[('composition_mode', '=', 'mass_mail')]}">
- <span attrs="{'invisible':[('model', '=', False)]}">
- Followers of
- <field name="record_name" readonly="1" class="oe_inline oe_compose_recipients"/>
- and
+ <!-- recipients -->
+ <label for="partner_ids" string="Recipients" attrs="{'invisible': [('is_log', '=', True)]}" groups="base.group_user"/>
+ <div groups="base.group_user" attrs="{'invisible': [('is_log', '=', True)]}">
+ <span attrs="{'invisible': [('composition_mode', '!=', 'mass_mail')]}">
+ <strong>Email mass mailing</strong> on
+ <span attrs="{'invisible': [('use_active_domain', '=', True)]}">the selected records</span>
+ <span attrs="{'invisible': [('use_active_domain', '=', False)]}">the current search filter</span>.
</span>
+ <span attrs="{'invisible':[('composition_mode', '!=', 'comment')]}">Followers of the document and</span>
<field name="partner_ids" widget="many2many_tags_email" placeholder="Add contacts to notify..."
- context="{'force_email':True, 'show_email':True}"/>
+ context="{'force_email':True, 'show_email':True}"
+ attrs="{'invisible': [('composition_mode', '!=', 'comment')]}"/>
</div>
- <!-- mass post / mass mailing -->
- <field name="post"
- attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
+ <!-- mass post -->
<field name="notify"
- attrs="{'invisible':['|', ('post', '!=', True), ('composition_mode', '!=', 'mass_mail')]}"/>
- <field name="same_thread"
- attrs="{'invisible':['|', ('composition_mode', '!=', 'mass_mail'), ('post', '=', False)]}"/>
- <field name="reply_to" placeholder="Email address te redirect replies..."
- attrs="{'invisible':['|', '&amp;', ('same_thread', '=', True), ('post', '=', True), ('composition_mode', '!=', 'mass_mail')],
- 'required':['&amp;', '|', ('post', '=', False), ('same_thread', '=', False), ('composition_mode', '=', 'mass_mail')]}"/>
+ attrs="{'invisible':['|', ('composition_mode', '!=', 'mass_post')]}"/>
+ <!-- mass mailing -->
+ <field name="same_thread" attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
+ <field name="reply_to" placeholder="Email address to redirect replies..."
+ attrs="{'invisible':['|', ('same_thread', '=', True), ('composition_mode', '!=', 'mass_mail')],
+ 'required':[('same_thread', '!=', True), ('composition_mode', '=', 'mass_mail')]}"/>
</group>
<field name="body"/>
<field name="attachment_ids" widget="many2many_binary" string="Attach a file"/>