Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make attachments of other models in poweremail.template #177

Open
wants to merge 9 commits into
base: v5_backport
Choose a base branch
from
18 changes: 18 additions & 0 deletions migrations/5.0.25.5.0/post-0001_add_new_column.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from tools import config
import pooler


def up(cursor, installed_version):
if not installed_version or config.updating_all:
return

pool = pooler.get_pool(cursor.dbname)

pool.get("poweremail.templates")._auto_init(cursor, context={'module': 'poweremail'})


def down(cursor, installed_version):
pass


migrate = up
34 changes: 33 additions & 1 deletion poweremail_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ def _get_model_data_name_search(
'report_template':fields.many2one(
'ir.actions.report.xml',
'Report to send'),
'report_template_object_reference': fields.char('Reference of the report', size=300, required=False),
#'report_template':fields.reference('Report to send',[('ir.actions.report.xml','Reports')],size=128),
'allowed_groups':fields.many2many(
'res.groups',
Expand Down Expand Up @@ -907,6 +908,30 @@ def create_report(self, cursor, user, template, record_ids, context=None):
(result, format) = service.create(cursor, user, record_ids, data, context=context)
return (result, format)

def get_report_template_object_reference_ids(self, cursor, uid, record_id, value, context=None):
"""
Evaluate the value of the field report_template_object_reference.
For example: ('giscedata.facturacio.factura', [('invoice_id', '=', record_id)]) from account.invoice template

:param cursor: DB cursor
:param uid: User ID
:param record_id: ID of the record to do the condition
:param value: Value of the field report_template_object_reference
:param context: Context

:return: rerturn the id from the condition in dmn
"""
if context is None:
context = {}

value = eval(value)
Copy link
Preview

Copilot AI Mar 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using eval() can be unsafe if the input is not strictly controlled. Consider replacing it with ast.literal_eval to safely evaluate literal structures.

Suggested change
value = eval(value)
import ast
value = ast.literal_eval(value)

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correcte és insegur utilitzar eval(), per això vam pensar d'usar el tools.safe_eval, però no era capaç d'interpretar el domain correctament.

@Ruben1700

dmn = value[1]
ref = value[0]
ref_obj = self.pool.get(ref)
res = ref_obj.search(cursor, uid, dmn, context=context)

return res

def _generate_attach_reports(self, cursor, user, template, record_ids, mail, context=None):
"""
Generate report to be attached and attach it
Expand All @@ -927,6 +952,7 @@ def _generate_attach_reports(self, cursor, user, template, record_ids, mail, con
attachment_obj = self.pool.get('ir.attachment')
mailbox_obj = self.pool.get('poweremail.mailbox')
lang = get_value(cursor, user, record_ids[0], template.lang, template, context=context)
record_reference_ids = record_ids
ctx = context.copy()
if lang:
ctx['lang'] = lang
Expand All @@ -935,7 +961,13 @@ def _generate_attach_reports(self, cursor, user, template, record_ids, mail, con
ctx['lang'] = tools.config.get('lang', 'en_US')
attachment_id = []
if template.report_template:
report_vals = self.create_report(cursor, user, template, record_ids, context=context)
if template.report_template_object_reference:
record_reference_ids = []
for record_id in record_ids:
reference_ids = self.get_report_template_object_reference_ids(cursor, user, record_id, template.report_template_object_reference, context=context)
record_reference_ids += reference_ids

report_vals = self.create_report(cursor, user, template, record_reference_ids, context=context)
result = report_vals[0]
format = report_vals[1]

Expand Down
6 changes: 4 additions & 2 deletions poweremail_template_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-->
<openerp>
<data>
<record model="ir.ui.view" id="poweremail_template_attachment_form">
<record model="ir.ui.view" id="poweremail_template_attachment_form">
<field name="name">poweremail.template.attachment.form</field>
<field name="model">poweremail.template.attachment</field>
<field name="type">form</field>
Expand Down Expand Up @@ -72,7 +72,7 @@
<!--
I dont advice using the html widget
because tinymce is interfering too
much with the html generated
much with the html generated

Sunday,30 May 2010:Enabling HTML as
community votes for it
Expand Down Expand Up @@ -136,6 +136,8 @@
<field name="save_to_drafts" colspan="4"/>
<field name="inline" colspan="4"/>
</group>
<separator string="Attachments (Report to attach)" colspan="4" />
<field name="report_template_object_reference" colspan="2"/>
<group>
<separator colspan="4" string="Allowed User Groups" />
<field name="allowed_groups" string="Allowed User Groups" nolabel="1" colspan="4"/>
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .test_poweremail_mailbox import *
from .test_poweremail_templates import *
from .test_attach_other_models import *
159 changes: 159 additions & 0 deletions tests/test_attach_other_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# coding=utf-8

from destral.transaction import Transaction
from destral import testing
from mock import patch
from base64 import b64decode

class TestAttachOtherModels(testing.OOTestCase):
"""
Test the attachment of other models to the email
"""

def setUp(self):
self.openerp.install_module('giscedata_facturacio')

def _create_account(self, cursor, uid, extra_vals=None):
acc_obj = self.openerp.pool.get('poweremail.core_accounts')

vals = {
'name': 'Test account',
'user': uid,
'email_id': '[email protected]',
'smtpserver': 'smtp.example.com',
'smtpport': 587,
'smtpuname': 'test',
'smtppass': 'test',
'company': 'yes'
}
if extra_vals:
vals.update(extra_vals)

acc_id = acc_obj.create(cursor, uid, vals)
return acc_id

def _create_template(self, cursor, uid, extra_vals=None):
if extra_vals is None:
extra_vals = {}

model = extra_vals['model'] if 'model' in extra_vals else None
conditions = extra_vals['conditions'] if 'conditions' in extra_vals else None

if model and conditions:
report_template_object_reference_value = "('{model}', {conditions})".format(
model=model,
conditions=conditions)
else:
report_template_object_reference_value = None


imd_obj = self.openerp.pool.get('ir.model.data')
tmpl_obj = self.openerp.pool.get('poweremail.templates')
acc_id = False
if 'enforce_from_account' not in extra_vals:
acc_id = self.create_account(cursor, uid)

model_partner = imd_obj.get_object_reference(
cursor, uid, 'base', 'model_res_partner'
)[1] # Retunr ir.model id of res.partner

# Agafem un report de demo
report_id = imd_obj.get_object_reference(
cursor, uid, 'base', 'report_test'
)[1]

vals = {
'name': 'Test template',
'object_name': model_partner,
'enforce_from_account': acc_id,
'template_language': 'mako',
'def_to': 'Test to',
'inline': True,
'def_subject': 'Test subject',
'def_cc': 'Test cc',
'def_bcc': 'Test bcc',
'def_body_text': 'Test body text',
'def_priority': '2',
'report_template': report_id,
'report_template_object_reference': report_template_object_reference_value
}

if extra_vals:
vals.update(extra_vals)

tmpl_id = tmpl_obj.create(cursor, uid, vals)
return tmpl_id

@patch('poweremail.poweremail_template.poweremail_templates.create_report', return_value=("content_from_report_template_object_reference", "provapdf"))
def test_generate_attachments_with_report_template_object_reference(self, extra_vals=None):
"""
Test the generation of attachments with a report template object reference

NOTE: In this case only will generate one attachment, because the conditions are too restrictive to return anything
"""
with Transaction().start(self.database) as txn:
uid = txn.user
cursor = txn.cursor
mailbox_obj = self.openerp.pool.get('poweremail.mailbox')
pm_tmp_obj = self.openerp.pool.get('poweremail.templates')

acc1_id = self._create_account(cursor, uid, extra_vals={'name': 'acc1', 'email_id': '[email protected]'})
tmpl_id = self._create_template(cursor, uid, extra_vals={'enforce_from_account': acc1_id,
'name': 'Test template 1',
'model': 'giscedata.facturacio.factura',
'conditions': [('invoice_id', '=', 1)]})

mailbox_id = pm_tmp_obj.generate_mail(cursor, uid, tmpl_id, [1], context={'raise_exception': True})
mail = mailbox_obj.simple_browse(cursor, uid, mailbox_id)
for att in mail.pem_attachments_ids:
self.assertEqual(b64decode(att.datas), 'content_from_report_template_object_reference') # datas is get from the 1r tuple value from create_report method, that in this case is mocked to avoid the real report generation

@patch('poweremail.poweremail_template.poweremail_templates.create_report', return_value=("content_from_report_template_object_reference", "provapdf"))
def test_generate_attachments_without_report_template_object_reference(self, mock_create_report , extra_vals=None):
"""
Test the generation of attachments without a report template object reference
"""
with Transaction().start(self.database) as txn:
uid = txn.user
cursor = txn.cursor
pm_tmp_obj = self.openerp.pool.get('poweremail.templates')
mailbox_obj = self.openerp.pool.get('poweremail.mailbox')

acc1_id = self._create_account(cursor, uid, extra_vals={'name': 'acc1', 'email_id': '[email protected]'})
tmpl_id = self._create_template(cursor, uid, extra_vals={'enforce_from_account': acc1_id,
'name': 'Test template 1',
'model': None,
'conditions': None}) # Without report_template_object_reference

with patch.object(pm_tmp_obj, '_generate_attach_reports') as mock_generate_attach_reports:
mock_generate_attach_reports.return_value = None
with patch.object(pm_tmp_obj._generate_attach_reports, 'get_value') as mock_get_value_from_generate_attach_reports: # Mock the get_value from the _generate_attach_reports method
mailbox_id = pm_tmp_obj.generate_mail(cursor, uid, tmpl_id, [1], context={'raise_exception': True})
mock_get_value_from_generate_attach_reports.assert_not_called()

mail = mailbox_obj.simple_browse(cursor, uid, mailbox_id)
for att in mail.pem_attachments_ids:
self.assertEqual(b64decode(att.datas), 'content_from_report_template_object_reference')

@patch('poweremail.poweremail_template.poweremail_templates.create_report', return_value=("content_from_report_template_object_reference", "provapdf"))
def test_generate_attachments_with_user(self, mock_create_report, extra_vals=None):
"""
Test the generation of attachments with a user and invoice
"""
with Transaction().start(self.database) as txn:
uid = txn.user
cursor = txn.cursor
mailbox_obj = self.openerp.pool.get('poweremail.mailbox')
pm_tmp_obj = self.openerp.pool.get('poweremail.templates')

acc1_id = self._create_account(cursor, uid, extra_vals={'name': 'acc1', 'email_id': '[email protected]'})
tmpl_id = self._create_template(cursor, uid, extra_vals={'enforce_from_account': acc1_id,
'name': 'Test template 1',
'model': 'account.invoice',
'conditions': [('partner_id', '=', 1)]}) # Tiny partner

mailbox_id = pm_tmp_obj.generate_mail(cursor, uid, tmpl_id, [1], context={'raise_exception': True})
mail = mailbox_obj.simple_browse(cursor, uid, mailbox_id)

for att in mail.pem_attachments_ids:
self.assertEqual(b64decode(att.datas), 'content_from_report_template_object_reference')
2 changes: 1 addition & 1 deletion wizard/wizard_poweremail_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def action_send_static_mail(self, cursor, uid, ids, context=None):
if not template:
raise Exception("The requested template could not be loaded")

mailbox_id = template_obj.generate_mail(cursor, uid, template_id, model_id, context=context)
mailbox_id = template_obj.generate_mail_sync(cursor, uid, template_id, model_id, context=context)

if wizard.save_to_drafts_prev:
mailbox_obj.write(cursor, uid, mailbox_id, {'folder': 'drafts'}, context=context)
Expand Down