You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
5.6 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. # Copyright 2019 Akretion
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  3. from odoo import models, fields, api, _
  4. from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
  5. from odoo.exceptions import UserError
  6. from datetime import datetime, timedelta
  7. from odoo import SUPERUSER_ID
  8. class SqlExport(models.Model):
  9. _inherit = 'sql.export'
  10. mail_user_ids = fields.Many2many(
  11. 'res.users',
  12. 'mail_user_sqlquery_rel',
  13. 'sql_id',
  14. 'user_id',
  15. 'User to notify',
  16. help='Add the users who want to receive the report by e-mail. You '
  17. 'need to link the sql query with a cron to send mail automatically')
  18. cron_ids = fields.Many2many(
  19. 'ir.cron',
  20. 'cron_sqlquery_rel',
  21. 'sql_id',
  22. 'cron_id',
  23. 'Crons')
  24. # We could implement other conditions, that is why it is a selection field
  25. mail_condition = fields.Selection(
  26. [('not_empty', 'File Not Empty')], default='not_empty')
  27. @api.multi
  28. def create_cron(self):
  29. self.ensure_one()
  30. nextcall = datetime.now() + timedelta(hours=2)
  31. cron_vals = {
  32. 'active': True,
  33. 'model_id': self.env.ref('sql_export.model_sql_export').id,
  34. 'state': 'code',
  35. 'code': 'model._run_all_sql_export_for_cron()',
  36. 'name': 'SQL Export : %s' % self.name,
  37. 'nextcall': nextcall,
  38. 'doall': False,
  39. 'numbercall': -1,
  40. 'user_id': SUPERUSER_ID,
  41. }
  42. cron = self.env['ir.cron'].create(cron_vals)
  43. # We need to pass cron_id in the cron args because a cron is not
  44. # aware of itself in the end method and we need it to find all
  45. # linked sql exports
  46. write_vals = {
  47. 'code': 'model._run_all_sql_export_for_cron([%s])' % cron.id
  48. }
  49. cron.write(write_vals)
  50. self.write({'cron_ids': [(4, cron.id)]})
  51. @api.multi
  52. def send_mail(self, params=None):
  53. self.ensure_one()
  54. mail_template = self.env.ref('sql_export_mail.sql_export_mailer')
  55. now_time = datetime.strftime(datetime.now(),
  56. DEFAULT_SERVER_DATETIME_FORMAT)
  57. attach_obj = self.env['ir.attachment']
  58. if self.mail_condition == 'not_empty':
  59. res = self._execute_sql_request(
  60. params=params, mode='fetchone')
  61. if not res:
  62. return
  63. ctx = self.env.context.copy()
  64. if params:
  65. if 'user_id' in params:
  66. ctx['force_user'] = params['user_id']
  67. if 'company_id' in params:
  68. ctx['force_company'] = params['company_id']
  69. wizard = self.env['sql.file.wizard'].create({
  70. 'sql_export_id': self.id,
  71. })
  72. wizard.with_context(ctx).export_sql()
  73. binary = wizard.binary_file
  74. filename = wizard.file_name
  75. msg_id = mail_template.send_mail(self.id, force_send=False)
  76. mail = self.env['mail.mail'].browse(msg_id)
  77. attach_vals = {
  78. 'name': now_time + ' - ' + self.name,
  79. 'datas_fname': filename,
  80. 'datas': binary,
  81. 'res_model': 'mail.mail',
  82. 'res_id': mail.id,
  83. }
  84. attachment = attach_obj.create(attach_vals)
  85. mail.write({'attachment_ids': [(4, attachment.id)]})
  86. @api.model
  87. def _run_all_sql_export_for_cron(self, cron_ids):
  88. exports = self.search([('cron_ids', 'in', cron_ids)])
  89. for export in exports:
  90. if "%(company_id)s" in export.query and \
  91. "%(user_id)s" not in export.query:
  92. variable_dict = {}
  93. companies = self.env['res.company'].search([])
  94. for company in companies:
  95. users = export.mail_user_ids.filtered(
  96. lambda u: u.company_id == company)
  97. if users:
  98. variable_dict['company_id'] = users[0].company_id.id
  99. export.with_context(mail_to=users.ids).send_mail(
  100. params=variable_dict)
  101. elif "%(user_id)s" in export.query:
  102. variable_dict = {}
  103. for user in export.mail_user_ids:
  104. variable_dict['user_id'] = user.id
  105. if "%(company_id)s" in export.query:
  106. variable_dict['company_id'] = user.company_id.id
  107. export.with_context(mail_to=[user.id]).send_mail(
  108. params=variable_dict)
  109. else:
  110. export.send_mail()
  111. @api.multi
  112. @api.constrains('field_ids', 'mail_user_ids')
  113. def check_no_parameter_if_sent_by_mail(self):
  114. for export in self:
  115. if export.field_ids and export.mail_user_ids:
  116. raise UserError(_(
  117. "It is not possible to execute and send a query "
  118. "automatically by mail if there are parameters to fill"))
  119. @api.multi
  120. @api.constrains('mail_user_ids')
  121. def check_mail_user(self):
  122. for export in self:
  123. for user in export.mail_user_ids:
  124. if not user.email:
  125. raise UserError(_(
  126. "The user does not have any e-mail address."))
  127. @api.multi
  128. def get_email_address_for_template(self):
  129. """
  130. Called from mail template
  131. """
  132. self.ensure_one()
  133. if self.env.context.get('mail_to'):
  134. mail_users = self.env['res.users'].browse(
  135. self.env.context.get('mail_to'))
  136. else:
  137. mail_users = self.mail_user_ids
  138. return ','.join([x.email for x in mail_users if x.email])