Merge lp:~therp-nl/server-env-tools/7.0-add_email_template_conditional_attachment into lp:~server-env-tools-core-editors/server-env-tools/7.0

Proposed by Stefan Rijnhart (Opener)
Status: Work in progress
Proposed branch: lp:~therp-nl/server-env-tools/7.0-add_email_template_conditional_attachment
Merge into: lp:~server-env-tools-core-editors/server-env-tools/7.0
Diff against target: 409 lines (+345/-0)
11 files modified
email_template_conditional_attachment/__init__.py (+1/-0)
email_template_conditional_attachment/__openerp__.py (+58/-0)
email_template_conditional_attachment/i18n/email_template_conditional_attachment.pot (+52/-0)
email_template_conditional_attachment/i18n/nl.po (+64/-0)
email_template_conditional_attachment/model/__init__.py (+3/-0)
email_template_conditional_attachment/model/email_template.py (+51/-0)
email_template_conditional_attachment/model/email_template_conditional_attachment.py (+35/-0)
email_template_conditional_attachment/model/ir_attachment.py (+30/-0)
email_template_conditional_attachment/security/ir.model.access.csv (+3/-0)
email_template_conditional_attachment/view/email_template.xml (+22/-0)
email_template_conditional_attachment/view/ir_attachment.xml (+26/-0)
To merge this branch: bzr merge lp:~therp-nl/server-env-tools/7.0-add_email_template_conditional_attachment
Reviewer Review Type Date Requested Status
Holger Brunn (Therp) code review Needs Fixing
Nicolas Bessi - Camptocamp (community) no test, code review Needs Fixing
Graeme Gellatly code review, no test Abstain
Review via email: mp+202740@code.launchpad.net

Description of the change

See the description in __openerp__.py

To post a comment you must log in.
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

I suppose that you mean 'object' instead of 'invoice' in the module description in the part "...as a regular domain expression against the invoice model."

Regards.

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Pedro, thanks for having a look! This part of the text is a real world example on invoices, so I do mean 'invoice model' here. Of course the functionality is generic so the expression is always against the model of the template.

Revision history for this message
Graeme Gellatly (gdgellatly) wrote :

Hi I reviewed code only

All looks good and useful. Only comments for improvement are

Line 215, I know it is extremely unlikely/impossible in current modules but for futureproofing consider

if res_id and res:

rather than just if res_id.

From a usability standpoint it would be useful to have the reverse view. i.e. If you have an attachment you wish to attach to multiple templates being able to specify in the attachment rather than going in to each email template. I think of the use case of say a new product launch or an important change which needs to go with many emails. But that is new feature rather than complaint.

review: Abstain (code review, no test)
63. By Stefan Rijnhart (Opener)

[ADD] Allow configuration from the attachment itself
 Thanks to Graeme Gellatly for this suggestion

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Graeme,

thank you for the review!

I checked generate_email() in email_template/email_template.py and like you say, it is impossible not to have a return value that is not an email dictionary so I prefer to leave it like this to reflect that. If this changes in the future we can adapt then.

As for your usability suggestion, I just committed this as I think this is a very welcome improvement. Thank you for bringing this up!

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

And the above should say: *impossible to have a return value that is not an email dictionary*

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Some neat picks:
PEP8 in __openerp__.py
Some trailing white space here and there.

Here I'm not sure of this expression:

                domain = (
                    ['&', ('id', '=', res_id)] +
                    literal_eval(attachment.domain)

Why do you use ast.literal_eval instead of openerp safe_eval ?

review: Needs Fixing (no test, code review)
64. By Stefan Rijnhart (Opener)

[FIX] Pep8

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Nicolas, thanks for the review! I fixed up __openerp__.py.

Using ast.literal_eval here because its functionality is a subset of safe_eval and it is standard python functionality. So it should be safer than safe_eval in this case. Can you live with that?

Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

I'd also prefer OpenERP's API, so +1 for safe_eval.

But more picking on this line: The '&' makes your code crash for an empty attachment domain ('[]') and adds no benefit I can see. Do I overlook some benefit?

Generally, I think it's safer to use osv.expression.normalize and osv.expression.combine where applicable.

Further: What purpose does conditional_attachment_ids on ir.attachment serve?

review: Needs Fixing (code review)
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

In this case I prefere safe eval it is the standard way to do it and should be more portable.

Regards

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Any news about safe eval ?

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Thanks for the comments. Setting to work in progress as I'm currently thinking about whether or not to reset the m2m relationship when attachments are copied as this currently leads to duplicate attachments on the template (which is useful when you are configuring multiple attachments on the same template but rather disturbing when you are not.

Unmerged revisions

64. By Stefan Rijnhart (Opener)

[FIX] Pep8

63. By Stefan Rijnhart (Opener)

[ADD] Allow configuration from the attachment itself
 Thanks to Graeme Gellatly for this suggestion

62. By Stefan Rijnhart (Opener)

[IMP] Module description

61. By Stefan Rijnhart (Opener)

[IMP] Manifest

60. By Stefan Rijnhart (Opener)

[FIX] XML indentation
[ADD] Model access rules
[IMP] Translation
[IMP] Docstring

59. By Stefan Rijnhart (Opener)

[IMP] Module description

58. By Stefan Rijnhart (Opener)

[IMP] Module description

57. By Stefan Rijnhart (Opener)

[ADD] Module for conditional attachments on email templates

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'email_template_conditional_attachment'
=== added file 'email_template_conditional_attachment/__init__.py'
--- email_template_conditional_attachment/__init__.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/__init__.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,1 @@
1from . import model
02
=== added file 'email_template_conditional_attachment/__openerp__.py'
--- email_template_conditional_attachment/__openerp__.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/__openerp__.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,58 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21{
22 'name': 'Conditional attachments on email templates',
23 'version': '0.1',
24 'author': 'Therp BV',
25 'category': 'Email',
26 'website': 'http://therp.nl',
27 'depends': [
28 'email_template',
29 ],
30 'data': [
31 'view/email_template.xml',
32 'view/ir_attachment.xml',
33 'security/ir.model.access.csv',
34 ],
35 'description': """
36This module allows you to configure a set of static attachments on an email
37template that appear on generated emails conditionally. Conditions are
38specified in the technical *domain* notation that is widely used in OpenERP.
39
40For instance, if you want
41a specific attachment to only be sent out with invoices to Dutch speaking
42customers of a specific company, you can encode this on the template for
43outgoing invoices as a regular domain expression against the invoice model:
44
45 [('company_id', '=', 1), ('partner_id.lang', '=', 'nl_NL')]
46
47Generated emails will then only contain the attachment if the associated
48invoice meets these requirements.
49
50You can configure the conditional attachments on the *Advanced* tab of the
51email template form view.
52
53Again, only static attachments (so no dynamically generated reports) are
54currently supported. An example of usage is attaching a document containing
55general terms and conditions in various languages which can vary per company
56or customer region.
57""",
58}
059
=== added directory 'email_template_conditional_attachment/i18n'
=== added file 'email_template_conditional_attachment/i18n/email_template_conditional_attachment.pot'
--- email_template_conditional_attachment/i18n/email_template_conditional_attachment.pot 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/i18n/email_template_conditional_attachment.pot 2014-01-27 10:03:19 +0000
@@ -0,0 +1,52 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * email_template_conditional_attachment
4#
5msgid ""
6msgstr ""
7
8#. module: email_template_conditional_attachment
9#: field:ir.attachment,conditional_attachment_ids:0
10msgid "Conditionally attach to email templates"
11msgstr ""
12
13#. module: email_template_conditional_attachment
14#: field:email.template.conditional.attachment,domain:0
15msgid "Domain"
16msgstr ""
17
18#. module: email_template_conditional_attachment
19#: field:email.template.conditional.attachment,template_id:0
20msgid "Email template"
21msgstr ""
22
23#. module: email_template_conditional_attachment
24#: model:ir.model,name:email_template_conditional_attachment.model_email_template
25msgid "Email Templates"
26msgstr ""
27
28#. module: email_template_conditional_attachment
29#: model:ir.model,name:email_template_conditional_attachment.model_email_template_conditional_attachment
30msgid "email.template.conditional.attachment"
31msgstr ""
32
33#. module: email_template_conditional_attachment
34#: model:ir.model,name:email_template_conditional_attachment.model_ir_attachment
35msgid "ir.attachment"
36msgstr ""
37
38#. module: email_template_conditional_attachment
39#: field:email.template.conditional.attachment,attachment_id:0
40msgid "Attachment"
41msgstr ""
42
43#. module: email_template_conditional_attachment
44#: view:email.template:0 field:email.template,conditional_attachment_ids:0
45#: view:ir.attachment:0
46msgid "Conditional attachments"
47msgstr ""
48
49#. module: email_template_conditional_attachment
50#: view:ir.attachment:0
51msgid "Email templates to conditionally attach to"
52msgstr ""
053
=== added file 'email_template_conditional_attachment/i18n/nl.po'
--- email_template_conditional_attachment/i18n/nl.po 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/i18n/nl.po 2014-01-27 10:03:19 +0000
@@ -0,0 +1,64 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * email_template_conditional_attachment
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2014-01-24 14:04+0000\n"
10"PO-Revision-Date: 2014-01-24 14:04+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: email_template_conditional_attachment
19#: field:ir.attachment,conditional_attachment_ids:0
20msgid "Conditionally attach to email templates"
21msgstr "Voorwaardelijke bijlage bij emailsjabloon"
22
23#. module: email_template_conditional_attachment
24#: field:email.template.conditional.attachment,domain:0
25msgid "Domain"
26msgstr "Domein"
27
28#. module: email_template_conditional_attachment
29#: field:email.template.conditional.attachment,template_id:0
30msgid "Email template"
31msgstr "Emailsjabloon"
32
33#. module: email_template_conditional_attachment
34#: model:ir.model,name:email_template_conditional_attachment.model_email_template
35msgid "Email Templates"
36msgstr "Email-sjablonen"
37
38#. module: email_template_conditional_attachment
39#: model:ir.model,name:email_template_conditional_attachment.model_email_template_conditional_attachment
40msgid "email.template.conditional.attachment"
41msgstr "email.template.conditional.attachment"
42
43#. module: email_template_conditional_attachment
44#: model:ir.model,name:email_template_conditional_attachment.model_ir_attachment
45msgid "ir.attachment"
46msgstr "ir.attachment"
47
48#. module: email_template_conditional_attachment
49#: field:email.template.conditional.attachment,attachment_id:0
50msgid "Attachment"
51msgstr "Bijlage"
52
53#. module: email_template_conditional_attachment
54#: view:email.template:0
55#: field:email.template,conditional_attachment_ids:0
56#: view:ir.attachment:0
57msgid "Conditional attachments"
58msgstr "Conditionele bijlagen"
59
60#. module: email_template_conditional_attachment
61#: view:ir.attachment:0
62msgid "Email templates to conditionally attach to"
63msgstr "Voorwaardelijke bijlage bij emailsjablonen"
64
065
=== added directory 'email_template_conditional_attachment/model'
=== added file 'email_template_conditional_attachment/model/__init__.py'
--- email_template_conditional_attachment/model/__init__.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/model/__init__.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,3 @@
1from . import email_template_conditional_attachment
2from . import email_template
3from . import ir_attachment
04
=== added file 'email_template_conditional_attachment/model/email_template.py'
--- email_template_conditional_attachment/model/email_template.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/model/email_template.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,51 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from ast import literal_eval
22from openerp.osv import orm, fields
23
24
25class EmailTemplate(orm.Model):
26 _inherit = 'email.template'
27 _columns = {
28 'conditional_attachment_ids': fields.one2many(
29 'email.template.conditional.attachment',
30 'template_id', 'Conditional attachments'),
31 }
32
33 def generate_email(self, cr, uid, template_id, res_id, context=None):
34 """
35 Go through the conditional attachments and select those
36 of which the domain matches the resource.
37 """
38 res = super(EmailTemplate, self).generate_email(
39 cr, uid, template_id, res_id, context=context)
40 if res_id:
41 template = self.browse(cr, uid, template_id, context=context)
42 for attachment in template.conditional_attachment_ids:
43 domain = (
44 ['&', ('id', '=', res_id)] +
45 literal_eval(attachment.domain))
46 if self.pool.get(template.model).search(
47 cr, uid, domain, context=context):
48 res['attachment_ids'].append(
49 attachment.attachment_id.id)
50 return res
51
052
=== added file 'email_template_conditional_attachment/model/email_template_conditional_attachment.py'
--- email_template_conditional_attachment/model/email_template_conditional_attachment.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/model/email_template_conditional_attachment.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,35 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm, fields
22
23
24class EmailTemplateConditionalAttachment(orm.Model):
25 _name = 'email.template.conditional.attachment'
26
27 _columns = {
28 'template_id': fields.many2one(
29 'email.template', 'Email template', required=True,
30 ondelete='CASCADE'),
31 'attachment_id': fields.many2one(
32 'ir.attachment', 'Attachment', required=True),
33 'domain': fields.char(
34 size=256, string='Domain', required=True),
35 }
036
=== added file 'email_template_conditional_attachment/model/ir_attachment.py'
--- email_template_conditional_attachment/model/ir_attachment.py 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/model/ir_attachment.py 2014-01-27 10:03:19 +0000
@@ -0,0 +1,30 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm, fields
22
23
24class IrAttachment(orm.Model):
25 _inherit = 'ir.attachment'
26 _columns = {
27 'conditional_attachment_ids': fields.one2many(
28 'email.template.conditional.attachment',
29 'attachment_id', 'Conditionally attach to email templates'),
30 }
031
=== added directory 'email_template_conditional_attachment/security'
=== added file 'email_template_conditional_attachment/security/ir.model.access.csv'
--- email_template_conditional_attachment/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/security/ir.model.access.csv 2014-01-27 10:03:19 +0000
@@ -0,0 +1,3 @@
1id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2access_email_template_conditional_attachment,email.template,model_email_template_conditional_attachment,,1,1,1,0
3access_email_template_conditional_attachment_system,email.template system,model_email_template_conditional_attachment,base.group_system,1,1,1,1
04
=== added directory 'email_template_conditional_attachment/static'
=== added directory 'email_template_conditional_attachment/static/src'
=== added directory 'email_template_conditional_attachment/static/src/img'
=== added file 'email_template_conditional_attachment/static/src/img/icon.png'
1Binary files email_template_conditional_attachment/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and email_template_conditional_attachment/static/src/img/icon.png 2014-01-27 10:03:19 +0000 differ5Binary files email_template_conditional_attachment/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and email_template_conditional_attachment/static/src/img/icon.png 2014-01-27 10:03:19 +0000 differ
=== added directory 'email_template_conditional_attachment/view'
=== added file 'email_template_conditional_attachment/view/email_template.xml'
--- email_template_conditional_attachment/view/email_template.xml 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/view/email_template.xml 2014-01-27 10:03:19 +0000
@@ -0,0 +1,22 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record model="ir.ui.view" id="email_template_form">
6 <field name="name">Add list of conditional attachments to email template form</field>
7 <field name="model">email.template</field>
8 <field name="inherit_id" ref="email_template.email_template_form" />
9 <field name="arch" type="xml">
10 <field name="attachment_ids" position="after">
11 <field name="conditional_attachment_ids" colspan="4">
12 <tree string="Conditional attachments" editable="bottom">
13 <field name="attachment_id" />
14 <field name="domain" />
15 </tree>
16 </field>
17 </field>
18 </field>
19 </record>
20
21 </data>
22</openerp>
023
=== added file 'email_template_conditional_attachment/view/ir_attachment.xml'
--- email_template_conditional_attachment/view/ir_attachment.xml 1970-01-01 00:00:00 +0000
+++ email_template_conditional_attachment/view/ir_attachment.xml 2014-01-27 10:03:19 +0000
@@ -0,0 +1,26 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="view_attachment_form" model="ir.ui.view">
6 <field name="name">Conditional attachment onto email template</field>
7 <field name="model">ir.attachment</field>
8 <field name="inherit_id" ref="base.view_attachment_form" />
9 <field name="arch" type="xml">
10 <group name="description_group" position="after">
11 <group name="conditionally_attach"
12 string ="Email templates to conditionally attach to"
13 />
14 <field name="conditional_attachment_ids"
15 nolabel="1" colspan="4">
16 <tree string="Conditional attachments" editable="bottom">
17 <field name="template_id" />
18 <field name="domain" />
19 </tree>
20 </field>
21 </group>
22 </field>
23 </record>
24
25 </data>
26</openerp>