mirror of
https://github.com/OCA/reporting-engine.git
synced 2025-02-16 16:30:38 +02:00
[IMP] sql_export_mail: black, isort, prettier
This commit is contained in:
committed by
Sylvain LE GAL
parent
1dedee2aae
commit
f7585a5b92
@@ -1,20 +1,19 @@
|
|||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
{
|
{
|
||||||
'name': 'SQL Export Mail',
|
"name": "SQL Export Mail",
|
||||||
'version': '12.0.1.0.0',
|
"version": "12.0.1.0.0",
|
||||||
'category': 'Generic Modules',
|
"category": "Generic Modules",
|
||||||
'summary': 'Send csv file generated by sql query by mail.',
|
"summary": "Send csv file generated by sql query by mail.",
|
||||||
'author':
|
"author": "Akretion, Odoo Community Association (OCA)",
|
||||||
"Akretion, Odoo Community Association (OCA)",
|
"website": "https://github.com/OCA/server-tools",
|
||||||
'website': 'https://github.com/OCA/server-tools',
|
"depends": [
|
||||||
'depends': [
|
"sql_export",
|
||||||
'sql_export',
|
"mail",
|
||||||
'mail',
|
|
||||||
],
|
],
|
||||||
'license': 'AGPL-3',
|
"license": "AGPL-3",
|
||||||
'data': [
|
"data": [
|
||||||
'views/sql_export_view.xml',
|
"views/sql_export_view.xml",
|
||||||
'mail_template.xml',
|
"mail_template.xml",
|
||||||
],
|
],
|
||||||
'installable': True,
|
"installable": True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
|
||||||
<odoo noupdate="1">
|
<odoo noupdate="1">
|
||||||
|
|
||||||
<!-- Error Email template -->
|
<!-- Error Email template -->
|
||||||
@@ -8,9 +7,11 @@
|
|||||||
<field name="email_from">admin@example.com</field>
|
<field name="email_from">admin@example.com</field>
|
||||||
<field name="email_to">${object.get_email_address_for_template()}</field>
|
<field name="email_to">${object.get_email_address_for_template()}</field>
|
||||||
<field name="subject">${object.name or ''}</field>
|
<field name="subject">${object.name or ''}</field>
|
||||||
<field name="model_id" ref="sql_export.model_sql_export"/>
|
<field name="model_id" ref="sql_export.model_sql_export" />
|
||||||
<field name="auto_delete" eval="True"/>
|
<field name="auto_delete" eval="True" />
|
||||||
<field name="body_html"><![CDATA[
|
<field
|
||||||
|
name="body_html"
|
||||||
|
><![CDATA[
|
||||||
<div style="font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
|
<div style="font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
|
||||||
|
|
||||||
<p>You will find the report ${object.name or ''} as an attachment of the mail.</p>
|
<p>You will find the report ${object.name or ''} as an attachment of the mail.</p>
|
||||||
|
|||||||
@@ -1,148 +1,148 @@
|
|||||||
# Copyright 2019 Akretion
|
# Copyright 2019 Akretion
|
||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
from odoo import models, fields, api, _
|
|
||||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
|
||||||
from odoo.exceptions import UserError
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from odoo import SUPERUSER_ID
|
|
||||||
|
from odoo import SUPERUSER_ID, _, api, fields, models
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
|
|
||||||
|
|
||||||
class SqlExport(models.Model):
|
class SqlExport(models.Model):
|
||||||
_inherit = 'sql.export'
|
_inherit = "sql.export"
|
||||||
|
|
||||||
mail_user_ids = fields.Many2many(
|
mail_user_ids = fields.Many2many(
|
||||||
'res.users',
|
"res.users",
|
||||||
'mail_user_sqlquery_rel',
|
"mail_user_sqlquery_rel",
|
||||||
'sql_id',
|
"sql_id",
|
||||||
'user_id',
|
"user_id",
|
||||||
'User to notify',
|
"User to notify",
|
||||||
help='Add the users who want to receive the report by e-mail. You '
|
help="Add the users who want to receive the report by e-mail. You "
|
||||||
'need to link the sql query with a cron to send mail automatically')
|
"need to link the sql query with a cron to send mail automatically",
|
||||||
|
)
|
||||||
cron_ids = fields.Many2many(
|
cron_ids = fields.Many2many(
|
||||||
'ir.cron',
|
"ir.cron", "cron_sqlquery_rel", "sql_id", "cron_id", "Crons"
|
||||||
'cron_sqlquery_rel',
|
)
|
||||||
'sql_id',
|
|
||||||
'cron_id',
|
|
||||||
'Crons')
|
|
||||||
# We could implement other conditions, that is why it is a selection field
|
# We could implement other conditions, that is why it is a selection field
|
||||||
mail_condition = fields.Selection(
|
mail_condition = fields.Selection(
|
||||||
[('not_empty', 'File Not Empty')], default='not_empty')
|
[("not_empty", "File Not Empty")], default="not_empty"
|
||||||
|
)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def create_cron(self):
|
def create_cron(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
nextcall = datetime.now() + timedelta(hours=2)
|
nextcall = datetime.now() + timedelta(hours=2)
|
||||||
cron_vals = {
|
cron_vals = {
|
||||||
'active': True,
|
"active": True,
|
||||||
'model_id': self.env.ref('sql_export.model_sql_export').id,
|
"model_id": self.env.ref("sql_export.model_sql_export").id,
|
||||||
'state': 'code',
|
"state": "code",
|
||||||
'code': 'model._run_all_sql_export_for_cron()',
|
"code": "model._run_all_sql_export_for_cron()",
|
||||||
'name': 'SQL Export : %s' % self.name,
|
"name": "SQL Export : %s" % self.name,
|
||||||
'nextcall': nextcall,
|
"nextcall": nextcall,
|
||||||
'doall': False,
|
"doall": False,
|
||||||
'numbercall': -1,
|
"numbercall": -1,
|
||||||
'user_id': SUPERUSER_ID,
|
"user_id": SUPERUSER_ID,
|
||||||
}
|
}
|
||||||
cron = self.env['ir.cron'].create(cron_vals)
|
cron = self.env["ir.cron"].create(cron_vals)
|
||||||
# We need to pass cron_id in the cron args because a cron is not
|
# We need to pass cron_id in the cron args because a cron is not
|
||||||
# aware of itself in the end method and we need it to find all
|
# aware of itself in the end method and we need it to find all
|
||||||
# linked sql exports
|
# linked sql exports
|
||||||
write_vals = {
|
write_vals = {"code": "model._run_all_sql_export_for_cron([%s])" % cron.id}
|
||||||
'code': 'model._run_all_sql_export_for_cron([%s])' % cron.id
|
|
||||||
}
|
|
||||||
cron.write(write_vals)
|
cron.write(write_vals)
|
||||||
self.write({'cron_ids': [(4, cron.id)]})
|
self.write({"cron_ids": [(4, cron.id)]})
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def send_mail(self, params=None):
|
def send_mail(self, params=None):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
mail_template = self.env.ref('sql_export_mail.sql_export_mailer')
|
mail_template = self.env.ref("sql_export_mail.sql_export_mailer")
|
||||||
now_time = datetime.strftime(datetime.now(),
|
now_time = datetime.strftime(datetime.now(), DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
attach_obj = self.env["ir.attachment"]
|
||||||
attach_obj = self.env['ir.attachment']
|
if self.mail_condition == "not_empty":
|
||||||
if self.mail_condition == 'not_empty':
|
res = self._execute_sql_request(params=params, mode="fetchone")
|
||||||
res = self._execute_sql_request(
|
|
||||||
params=params, mode='fetchone')
|
|
||||||
if not res:
|
if not res:
|
||||||
return
|
return
|
||||||
ctx = self.env.context.copy()
|
ctx = self.env.context.copy()
|
||||||
if params:
|
if params:
|
||||||
if 'user_id' in params:
|
if "user_id" in params:
|
||||||
ctx['force_user'] = params['user_id']
|
ctx["force_user"] = params["user_id"]
|
||||||
if 'company_id' in params:
|
if "company_id" in params:
|
||||||
ctx['force_company'] = params['company_id']
|
ctx["force_company"] = params["company_id"]
|
||||||
wizard = self.env['sql.file.wizard'].create({
|
wizard = self.env["sql.file.wizard"].create(
|
||||||
'sql_export_id': self.id,
|
{
|
||||||
})
|
"sql_export_id": self.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
wizard.with_context(ctx).export_sql()
|
wizard.with_context(ctx).export_sql()
|
||||||
binary = wizard.binary_file
|
binary = wizard.binary_file
|
||||||
filename = wizard.file_name
|
filename = wizard.file_name
|
||||||
msg_id = mail_template.send_mail(self.id, force_send=False)
|
msg_id = mail_template.send_mail(self.id, force_send=False)
|
||||||
mail = self.env['mail.mail'].browse(msg_id)
|
mail = self.env["mail.mail"].browse(msg_id)
|
||||||
attach_vals = {
|
attach_vals = {
|
||||||
'name': now_time + ' - ' + self.name,
|
"name": now_time + " - " + self.name,
|
||||||
'datas_fname': filename,
|
"datas_fname": filename,
|
||||||
'datas': binary,
|
"datas": binary,
|
||||||
'res_model': 'mail.mail',
|
"res_model": "mail.mail",
|
||||||
'res_id': mail.id,
|
"res_id": mail.id,
|
||||||
}
|
}
|
||||||
attachment = attach_obj.create(attach_vals)
|
attachment = attach_obj.create(attach_vals)
|
||||||
mail.write({'attachment_ids': [(4, attachment.id)]})
|
mail.write({"attachment_ids": [(4, attachment.id)]})
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _run_all_sql_export_for_cron(self, cron_ids):
|
def _run_all_sql_export_for_cron(self, cron_ids):
|
||||||
exports = self.search([('cron_ids', 'in', cron_ids)])
|
exports = self.search([("cron_ids", "in", cron_ids)])
|
||||||
for export in exports:
|
for export in exports:
|
||||||
if "%(company_id)s" in export.query and \
|
if "%(company_id)s" in export.query and "%(user_id)s" not in export.query:
|
||||||
"%(user_id)s" not in export.query:
|
|
||||||
variable_dict = {}
|
variable_dict = {}
|
||||||
companies = self.env['res.company'].search([])
|
companies = self.env["res.company"].search([])
|
||||||
for company in companies:
|
for company in companies:
|
||||||
users = export.mail_user_ids.filtered(
|
users = export.mail_user_ids.filtered(
|
||||||
lambda u: u.company_id == company)
|
lambda u: u.company_id == company
|
||||||
|
)
|
||||||
if users:
|
if users:
|
||||||
variable_dict['company_id'] = users[0].company_id.id
|
variable_dict["company_id"] = users[0].company_id.id
|
||||||
export.with_context(mail_to=users.ids).send_mail(
|
export.with_context(mail_to=users.ids).send_mail(
|
||||||
params=variable_dict)
|
params=variable_dict
|
||||||
|
)
|
||||||
elif "%(user_id)s" in export.query:
|
elif "%(user_id)s" in export.query:
|
||||||
variable_dict = {}
|
variable_dict = {}
|
||||||
for user in export.mail_user_ids:
|
for user in export.mail_user_ids:
|
||||||
variable_dict['user_id'] = user.id
|
variable_dict["user_id"] = user.id
|
||||||
if "%(company_id)s" in export.query:
|
if "%(company_id)s" in export.query:
|
||||||
variable_dict['company_id'] = user.company_id.id
|
variable_dict["company_id"] = user.company_id.id
|
||||||
export.with_context(mail_to=[user.id]).send_mail(
|
export.with_context(mail_to=[user.id]).send_mail(
|
||||||
params=variable_dict)
|
params=variable_dict
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
export.send_mail()
|
export.send_mail()
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.constrains('field_ids', 'mail_user_ids')
|
@api.constrains("field_ids", "mail_user_ids")
|
||||||
def check_no_parameter_if_sent_by_mail(self):
|
def check_no_parameter_if_sent_by_mail(self):
|
||||||
for export in self:
|
for export in self:
|
||||||
if export.field_ids and export.mail_user_ids:
|
if export.field_ids and export.mail_user_ids:
|
||||||
raise UserError(_(
|
raise UserError(
|
||||||
"It is not possible to execute and send a query "
|
_(
|
||||||
"automatically by mail if there are parameters to fill"))
|
"It is not possible to execute and send a query "
|
||||||
|
"automatically by mail if there are parameters to fill"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.constrains('mail_user_ids')
|
@api.constrains("mail_user_ids")
|
||||||
def check_mail_user(self):
|
def check_mail_user(self):
|
||||||
for export in self:
|
for export in self:
|
||||||
for user in export.mail_user_ids:
|
for user in export.mail_user_ids:
|
||||||
if not user.email:
|
if not user.email:
|
||||||
raise UserError(_(
|
raise UserError(_("The user does not have any e-mail address."))
|
||||||
"The user does not have any e-mail address."))
|
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def get_email_address_for_template(self):
|
def get_email_address_for_template(self):
|
||||||
"""
|
"""
|
||||||
Called from mail template
|
Called from mail template
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
if self.env.context.get('mail_to'):
|
if self.env.context.get("mail_to"):
|
||||||
mail_users = self.env['res.users'].browse(
|
mail_users = self.env["res.users"].browse(self.env.context.get("mail_to"))
|
||||||
self.env.context.get('mail_to'))
|
|
||||||
else:
|
else:
|
||||||
mail_users = self.mail_user_ids
|
mail_users = self.mail_user_ids
|
||||||
return ','.join([x.email for x in mail_users if x.email])
|
return ",".join([x.email for x in mail_users if x.email])
|
||||||
|
|||||||
@@ -2,28 +2,27 @@
|
|||||||
# @author: Florian da Costa
|
# @author: Florian da Costa
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
|
||||||
from odoo import SUPERUSER_ID
|
from odoo import SUPERUSER_ID
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
class TestExportSqlQueryMail(TransactionCase):
|
class TestExportSqlQueryMail(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestExportSqlQueryMail, self).setUp()
|
super(TestExportSqlQueryMail, self).setUp()
|
||||||
self.sql_report_demo = self.env.ref('sql_export.sql_export_partner')
|
self.sql_report_demo = self.env.ref("sql_export.sql_export_partner")
|
||||||
self.sql_report_demo.write({'mail_user_ids': [(4, SUPERUSER_ID)]})
|
self.sql_report_demo.write({"mail_user_ids": [(4, SUPERUSER_ID)]})
|
||||||
|
|
||||||
def test_sql_query_mail(self):
|
def test_sql_query_mail(self):
|
||||||
mail_obj = self.env['mail.mail']
|
mail_obj = self.env["mail.mail"]
|
||||||
mails = mail_obj.search(
|
mails = mail_obj.search(
|
||||||
[('model', '=', 'sql.export'),
|
[("model", "=", "sql.export"), ("res_id", "=", self.sql_report_demo.id)]
|
||||||
('res_id', '=', self.sql_report_demo.id)])
|
)
|
||||||
self.assertFalse(mails)
|
self.assertFalse(mails)
|
||||||
self.sql_report_demo.create_cron()
|
self.sql_report_demo.create_cron()
|
||||||
self.assertTrue(self.sql_report_demo.cron_ids)
|
self.assertTrue(self.sql_report_demo.cron_ids)
|
||||||
self.sql_report_demo.cron_ids.method_direct_trigger()
|
self.sql_report_demo.cron_ids.method_direct_trigger()
|
||||||
mails = mail_obj.search(
|
mails = mail_obj.search(
|
||||||
[('model', '=', 'sql.export'),
|
[("model", "=", "sql.export"), ("res_id", "=", self.sql_report_demo.id)]
|
||||||
('res_id', '=', self.sql_report_demo.id)])
|
)
|
||||||
self.assertTrue(mails)
|
self.assertTrue(mails)
|
||||||
self.assertTrue(mails.attachment_ids)
|
self.assertTrue(mails.attachment_ids)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
|
|
||||||
@@ -7,19 +7,32 @@
|
|||||||
<field name="inherit_id" ref="sql_export.sql_export_view_form" />
|
<field name="inherit_id" ref="sql_export.sql_export_view_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<button name="export_sql_query" position="after">
|
<button name="export_sql_query" position="after">
|
||||||
<button name="create_cron" string="Create Cron" type="object" groups="base.group_system"
|
<button
|
||||||
attrs="{'invisible': ['|', ('state', '=', 'draft'), ('mail_user_ids', '=', [(6, False, [])])]}"/>
|
name="create_cron"
|
||||||
|
string="Create Cron"
|
||||||
|
type="object"
|
||||||
|
groups="base.group_system"
|
||||||
|
attrs="{'invisible': ['|', ('state', '=', 'draft'), ('mail_user_ids', '=', [(6, False, [])])]}"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
<field name="copy_options" position="after">
|
<field name="copy_options" position="after">
|
||||||
<field name="mail_condition" attrs="{'invisible': [('cron_ids', '=', [(6, False, [])])]}"/>
|
<field
|
||||||
|
name="mail_condition"
|
||||||
|
attrs="{'invisible': [('cron_ids', '=', [(6, False, [])])]}"
|
||||||
|
/>
|
||||||
</field>
|
</field>
|
||||||
<group name="parameters" position="after">
|
<group name="parameters" position="after">
|
||||||
<group groups="sql_request_abstract.group_sql_request_user">
|
<group groups="sql_request_abstract.group_sql_request_user">
|
||||||
<group string="Users Notified by e-mail">
|
<group string="Users Notified by e-mail">
|
||||||
<field name="mail_user_ids" nolabel="1"/>
|
<field name="mail_user_ids" nolabel="1" />
|
||||||
</group>
|
</group>
|
||||||
<group string="Crons" groups="base.group_system">
|
<group string="Crons" groups="base.group_system">
|
||||||
<field name="cron_ids" nolabel="1" domain="[('function', '=', '_run_all_sql_export_for_cron')]" groups="base.group_system"/>
|
<field
|
||||||
|
name="cron_ids"
|
||||||
|
nolabel="1"
|
||||||
|
domain="[('function', '=', '_run_all_sql_export_for_cron')]"
|
||||||
|
groups="base.group_system"
|
||||||
|
/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
Reference in New Issue
Block a user