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.

183 lines
7.4 KiB

  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Authors: Laetitia Gangloff
  5. # Copyright (c) 2015 Acsone SA/NV (http://www.acsone.eu)
  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. from openerp.osv import orm, fields
  22. from openerp.tools.translate import _
  23. from openerp.addons.web.controllers import main
  24. from openerp.tools.safe_eval import safe_eval
  25. import time
  26. from dateutil.relativedelta import relativedelta
  27. from datetime import datetime
  28. import base64
  29. class actions_server(orm.Model):
  30. _inherit = "ir.actions.server"
  31. def __init__(self, pool, cr):
  32. super(actions_server, self).__init__(pool, cr)
  33. # add state 'export_email'
  34. new_state = ('export_email', _('Export data by email'))
  35. if new_state not in self._columns['state'].selection:
  36. self._columns['state'].selection.append(new_state)
  37. return
  38. _columns = {
  39. 'model': fields.related('model_id', 'model',
  40. type="char", size=256, string='Model'),
  41. 'filter_id': fields.many2one(
  42. 'ir.filters', string='Filter', ondelete='restrict'),
  43. 'email_template_id': fields.many2one(
  44. 'email.template', string='Template', ondelete='restrict'),
  45. 'saved_export_id': fields.many2one(
  46. 'ir.exports', string='Saved export', ondelete='restrict'),
  47. 'fields_to_export': fields.text(
  48. 'Fields to export',
  49. help="The list of fields to export. \
  50. The format is ['name', 'seller_ids/product_name']"),
  51. 'export_format': fields.selection([('csv', 'CSV'),
  52. ('xls', 'Excel')],
  53. 'Export Formats'),
  54. }
  55. def _get_email_template(self, cr, uid, context=None):
  56. email_template_id = 0
  57. try:
  58. model_data_obj = self.pool['ir.model.data']
  59. email_template_id = model_data_obj.get_object_reference(
  60. cr, uid, 'base_export_email', 'export_data_email_template')[1]
  61. except ValueError:
  62. pass
  63. return email_template_id
  64. _defaults = {
  65. 'fields_to_export': '[]',
  66. 'export_format': 'csv',
  67. 'email_template_id': lambda self, cr, uid, c:
  68. self._get_email_template(cr, uid, context=c),
  69. }
  70. def onchange_model_id(self, cr, uid, ids, model_id, context=None):
  71. """
  72. Used to set correct domain on filter_id and saved_export_id
  73. """
  74. data = {'model': False,
  75. 'filter_id': False,
  76. 'saved_export_id': False}
  77. if model_id:
  78. model = self.pool['ir.model'].browse(cr, uid, model_id,
  79. context=context)
  80. data.update({'model': model.model})
  81. return {'value': data}
  82. def _search_data(self, cr, uid, action, context=None):
  83. obj_pool = self.pool[action.model]
  84. domain = action.filter_id and safe_eval(
  85. action.filter_id.domain, {'time': time,
  86. 'datetime': datetime,
  87. 'relativedelta': relativedelta,
  88. }) or []
  89. ctx = action.filter_id and safe_eval(
  90. action.filter_id.context) or context
  91. return obj_pool.search(cr, uid, domain,
  92. offset=0, limit=False, order=False,
  93. context=ctx)
  94. def _export_data(self, cr, uid, obj_ids, action, context=None):
  95. obj_pool = self.pool[action.model]
  96. export_fields = []
  97. if action.fields_to_export:
  98. export_fields = safe_eval(action.fields_to_export)
  99. if action.saved_export_id:
  100. # retrieve fields of the selected list
  101. export_fields.extend(
  102. [efl.name for efl in
  103. action.saved_export_id.export_fields])
  104. return export_fields, obj_pool.export_data(
  105. cr, uid, obj_ids, export_fields,
  106. context=context).get('datas', [])
  107. def _send_data_email(self, cr, uid, action, export_fields, export_data,
  108. context=None):
  109. """
  110. Prepare the exported data to send with the template
  111. of the configuration
  112. """
  113. if action.export_format == 'csv':
  114. export = main.CSVExport()
  115. else:
  116. export = main.ExcelExport()
  117. filename = export.filename(action.model)
  118. content = export.from_data(export_fields, export_data)
  119. return self._send_email(cr, uid, action, filename, content,
  120. context=context)
  121. def _send_email(self, cr, uid, action, filename, content,
  122. context=None):
  123. """
  124. Prepare a message with the exported data to send with the
  125. template of the configuration
  126. """
  127. mail_compose = self.pool['mail.compose.message']
  128. values = mail_compose.onchange_template_id(
  129. cr, uid, 0, action.email_template_id, 'comment',
  130. 'ir.actions.server', action.id, context=context)['value']
  131. values['partner_ids'] = [
  132. (4, partner_id) for partner_id in values.pop('partner_ids',
  133. [])
  134. ]
  135. if context and context.get('encoded_base_64'):
  136. data = content
  137. else:
  138. if isinstance(content, unicode):
  139. content = content.encode('utf-8')
  140. data = base64.b64encode(str(content))
  141. data_attach = {
  142. 'name': filename,
  143. 'datas': data,
  144. 'datas_fname': filename,
  145. 'description': filename,
  146. }
  147. values['attachment_ids'] = [(0, 0, data_attach)]
  148. compose_id = mail_compose.create(
  149. cr, uid, values, context=context)
  150. return mail_compose.send_mail(cr, uid, [compose_id], context=context)
  151. def run(self, cr, uid, ids, context=None):
  152. """
  153. If the state of an action is export_email,
  154. export data related to the configuration and send the result by email
  155. """
  156. for action in self.browse(cr, uid, ids, context):
  157. if action.state == 'export_email':
  158. # search data to export
  159. obj_ids = self._search_data(cr, uid, action, context=context)
  160. # export data
  161. export_fields, export_data = self._export_data(
  162. cr, uid, obj_ids, action, context=context)
  163. # Prepare a message with the exported data to send with the
  164. # template of the configuration
  165. self._send_data_email(
  166. cr, uid, action, export_fields, export_data,
  167. context=context)
  168. return super(actions_server, self).run(cr, uid, ids, context=context)