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.

314 lines
13 KiB

9 years ago
9 years ago
9 years ago
  1. from lxml import etree
  2. from openerp import api, models, fields, SUPERUSER_ID
  3. from openerp.tools import email_split
  4. from openerp.tools.translate import _
  5. class wizard(models.TransientModel):
  6. _name = 'mail_move_message.wizard'
  7. def _model_selection(self):
  8. selection = []
  9. config_parameters = self.env['ir.config_parameter']
  10. model_names = config_parameters.get_param('mail_relocation_models')
  11. if model_names:
  12. model_names = model_names.split(',')
  13. selection = [(m.model, m.display_name) for m in self.env['ir.model'].search([('model', 'in', model_names)])]
  14. return selection
  15. @api.model
  16. def default_get(self, fields_list):
  17. res = super(wizard, self).default_get(fields_list)
  18. model_fields = self.fields_get()
  19. res['model'] = model_fields['model']['selection'] and model_fields['model']['selection'][0][0]
  20. res_id = self.env[res['model']].search([], order='id desc', limit=1)
  21. res['res_id'] = res_id and res_id[0].id
  22. if 'message_id' in res:
  23. email_from = self.env['mail.message'].browse(res['message_id']).email_from
  24. parts = email_split(email_from.replace(' ',','))
  25. if parts:
  26. email = parts[0]
  27. name = email_from[:email_from.index(email)].replace('"', '').replace('<', '').strip() or email_from
  28. else:
  29. name, email = email_from
  30. res['message_name_from'] = name
  31. res['message_email_from'] = email
  32. return res
  33. message_id = fields.Many2one('mail.message', string='Message')
  34. message_body = fields.Html(related='message_id.body', string='Message to move', readonly=True)
  35. message_moved_by_message_id = fields.Many2one('mail.message', related='message_id.moved_by_message_id', string='Moved with', readonly=True)
  36. message_moved_by_user_id = fields.Many2one('res.users', related='message_id.moved_by_user_id', string='Moved by', readonly=True)
  37. message_is_moved = fields.Boolean(string='Is Moved', related='message_id.is_moved', readonly=True)
  38. parent_id = fields.Many2one('mail.message', string='Search by name', )
  39. model = fields.Selection(_model_selection, string='Model', required=True)
  40. res_id = fields.Integer(string='Record ID', required=True)
  41. can_move = fields.Boolean('Can move', compute='get_can_move')
  42. move_back = fields.Boolean('Move to origin', help='Move message and submessages to original place')
  43. partner_id = fields.Many2one('res.partner', string='Author', related='message_id.author_id')
  44. filter_by_partner = fields.Boolean('Filter Records by partner')
  45. message_email_from = fields.Char()
  46. message_name_from = fields.Char()
  47. message_to_read = fields.Boolean(related='message_id.to_read')
  48. @api.depends('message_id')
  49. @api.one
  50. def get_can_move(self):
  51. # message was not moved before OR message is a top message of previous move
  52. self.can_move = not self.message_id.moved_by_message_id or self.message_id.moved_by_message_id.id == self.message_id.id
  53. @api.onchange('move_back')
  54. def on_change_move_back(self):
  55. if not self.move_back:
  56. return
  57. self.parent_id = self.message_id.moved_from_parent_id
  58. model = self.message_id.moved_from_model
  59. if model in [s[0] for s in self._model_selection()]:
  60. self.model = model
  61. self.res_id = self.message_id.moved_from_res_id
  62. @api.onchange('parent_id', 'res_id', 'model')
  63. def update_move_back(self):
  64. model = self.message_id.moved_from_model
  65. self.move_back = self.parent_id == self.message_id.moved_from_parent_id \
  66. and self.res_id == self.message_id.moved_from_res_id \
  67. and (self.model == model or (not self.model and not model))
  68. @api.onchange('parent_id')
  69. def on_change_parent_id(self):
  70. if self.parent_id and self.parent_id.model:
  71. self.model = self.parent_id.model
  72. self.res_id = self.parent_id.res_id
  73. else:
  74. self.model = None
  75. self.res_id = None
  76. @api.onchange('model', 'filter_by_partner', 'partner_id')
  77. def on_change_partner(self):
  78. domain = {'res_id': []}
  79. if self.model and self.filter_by_partner and self.partner_id:
  80. self.res_id = None
  81. fields = self.env[self.model].fields_get(False)
  82. contact_field = False
  83. for n, f in fields.iteritems():
  84. if f['type'] == 'many2one' and f['relation'] == 'res.partner':
  85. contact_field = n
  86. break
  87. if contact_field:
  88. domain['res_id'] = [(contact_field, '=', self.partner_id.id)]
  89. return {'domain': domain}
  90. @api.one
  91. def check_access(self):
  92. cr = self._cr
  93. uid = self.env.user.id
  94. operation = 'write'
  95. context = self._context
  96. if not ( self.model and self.res_id ):
  97. return True
  98. model_obj = self.pool[self.model]
  99. mids = model_obj.exists(cr, uid, [self.res_id])
  100. if hasattr(model_obj, 'check_mail_message_access'):
  101. model_obj.check_mail_message_access(cr, uid, mids, operation, context=context)
  102. else:
  103. self.pool['mail.thread'].check_mail_message_access(cr, uid, mids, operation, model_obj=model_obj, context=context)
  104. @api.multi
  105. def open_moved_by_message_id(self):
  106. message_id = None
  107. for r in self:
  108. message_id = r.message_moved_by_message_id.id
  109. return {
  110. 'type': 'ir.actions.act_window',
  111. 'res_model': 'mail_move_message.wizard',
  112. 'view_mode': 'form',
  113. 'view_type': 'form',
  114. 'views': [[False, 'form']],
  115. 'target': 'new',
  116. 'context': {'default_message_id': message_id},
  117. }
  118. @api.multi
  119. def move(self):
  120. for r in self:
  121. r.check_access()
  122. if r.parent_id:
  123. if not (r.parent_id.model == r.model and
  124. r.parent_id.res_id == r.res_id):
  125. r.parent_id = None
  126. r.message_id.move(r.parent_id.id, r.res_id, r.model, r.move_back)
  127. if not ( r.model and r.res_id ):
  128. obj = self.pool.get('ir.model.data').get_object_reference(self._cr, SUPERUSER_ID, 'mail', 'mail_archivesfeeds')[1]
  129. return {
  130. 'type' : 'ir.actions.client',
  131. 'name' : 'Archive',
  132. 'tag' : 'reload',
  133. 'params' : {'menu_id': obj},
  134. }
  135. return {
  136. 'name': _('Record'),
  137. 'view_type': 'form',
  138. 'view_mode': 'form',
  139. 'res_model': r.model,
  140. 'res_id': r.res_id,
  141. 'views': [(False, 'form')],
  142. 'type': 'ir.actions.act_window',
  143. }
  144. @api.one
  145. def delete(self):
  146. self.message_id.unlink()
  147. return {}
  148. @api.model
  149. def create_partner(self, message_id, relation, partner_id, message_name_from, message_email_from):
  150. model = self.env[relation]
  151. message = self.env['mail.message'].browse(message_id)
  152. if not partner_id and message_name_from:
  153. partner_id = self.env['res.partner'].create({
  154. 'name': message_name_from,
  155. 'email': message_email_from
  156. }).id
  157. message.write({'author_id': partner_id})
  158. context = {'partner_id': partner_id}
  159. if model._rec_name:
  160. context.update({'default_%s' % model._rec_name: message.subject})
  161. fields = model.fields_get()
  162. contact_field = False
  163. for n, f in fields.iteritems():
  164. if f['type'] == 'many2one' and f['relation'] == 'res.partner':
  165. contact_field = n
  166. break
  167. if contact_field:
  168. context.update({'default_%s' % contact_field: partner_id})
  169. return context
  170. @api.one
  171. def read_close(self):
  172. self.message_id.set_message_read(True)
  173. return {'type': 'ir.actions.act_window_close'}
  174. @api.model
  175. def fields_view_get(self, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
  176. res = super(wizard, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=False)
  177. doc = etree.XML(res['arch'])
  178. nodes = doc.xpath("//button[@name='delete']")
  179. for node in nodes:
  180. if self.env.uid != 1:
  181. node.set('invisible', "1")
  182. res['arch'] = etree.tostring(doc)
  183. return res
  184. class mail_message(models.Model):
  185. _inherit = 'mail.message'
  186. is_moved = fields.Boolean('Is moved')
  187. moved_from_res_id = fields.Integer('Related Document ID (Original)')
  188. moved_from_model = fields.Char('Related Document Model (Original)')
  189. moved_from_parent_id = fields.Many2one('mail.message', 'Parent Message (Original)', ondelete='set null')
  190. moved_by_message_id = fields.Many2one('mail.message', 'Moved by message', ondelete='set null', help='Top message, that initate moving this message')
  191. moved_by_user_id = fields.Many2one('res.users', 'Moved by user', ondelete='set null')
  192. all_child_ids = fields.One2many('mail.message', string='All childs', compute='_get_all_childs', help='all childs, including subchilds')
  193. @api.one
  194. def _get_all_childs(self, include_myself=True):
  195. ids = []
  196. if include_myself:
  197. ids.append(self.id)
  198. while True:
  199. new_ids = self.search([('parent_id', 'in', ids), ('id', 'not in', ids)]).ids
  200. if new_ids:
  201. ids = ids + new_ids
  202. continue
  203. break
  204. moved_childs = self.search([('moved_by_message_id', '=', self.id)]).ids
  205. self.all_child_ids = ids + moved_childs
  206. @api.one
  207. def move(self, parent_id, res_id, model, move_back):
  208. vals = {}
  209. if move_back:
  210. # clear variables if we move everything back
  211. vals['is_moved'] = False
  212. vals['moved_by_user_id'] = None
  213. vals['moved_by_message_id'] = None
  214. vals['moved_from_res_id'] = None
  215. vals['moved_from_model'] = None
  216. vals['moved_from_parent_id'] = None
  217. else:
  218. vals['parent_id'] = parent_id
  219. vals['res_id'] = res_id
  220. vals['model'] = model
  221. vals['is_moved'] = True
  222. vals['moved_by_user_id'] = self.env.user.id
  223. vals['moved_by_message_id'] = self.id
  224. for r in self.all_child_ids:
  225. r_vals = vals.copy()
  226. if not r.is_moved:
  227. # moved_from_* variables contain not last, but original
  228. # reference
  229. r_vals['moved_from_parent_id'] = r.parent_id.id
  230. r_vals['moved_from_res_id'] = r.res_id
  231. r_vals['moved_from_model'] = r.model
  232. elif move_back:
  233. r_vals['parent_id'] = r.moved_from_parent_id.id
  234. r_vals['res_id'] = r.moved_from_res_id
  235. r_vals['model'] = r.moved_from_model
  236. print 'update message', r, r_vals
  237. r.sudo().write(r_vals)
  238. def name_get(self, cr, uid, ids, context=None):
  239. if not (context or {}).get('extended_name'):
  240. return super(mail_message, self).name_get(cr, uid, ids, context=context)
  241. if isinstance(ids, (list, tuple)) and not len(ids):
  242. return []
  243. if isinstance(ids, (long, int)):
  244. ids = [ids]
  245. reads = self.read(cr, uid, ids, ['record_name','model', 'res_id'], context=context)
  246. res = []
  247. for record in reads:
  248. name = record['record_name'] or ''
  249. extended_name = ' [%s] ID %s' % (record.get('model', 'UNDEF'), record.get('res_id', 'UNDEF'))
  250. res.append((record['id'], name + extended_name))
  251. return res
  252. def _message_read_dict(self, cr, uid, message, parent_id=False, context=None):
  253. res = super(mail_message, self)._message_read_dict(cr, uid, message, parent_id, context)
  254. res['is_moved'] = message.is_moved
  255. return res
  256. class mail_move_message_configuration(models.TransientModel):
  257. _name = 'mail_move_message.config.settings'
  258. _inherit = 'res.config.settings'
  259. model_ids = fields.Many2many(comodel_name='ir.model', string='Models')
  260. @api.model
  261. def get_default_model_ids(self, fields):
  262. config_parameters = self.env['ir.config_parameter']
  263. model_obj = self.env['ir.model']
  264. model_names = config_parameters.get_param('mail_relocation_models')
  265. if not model_names:
  266. return {}
  267. model_names = model_names.split(',')
  268. model_ids = model_obj.search([('model', 'in', model_names)])
  269. return {'model_ids': [m.id for m in model_ids]}
  270. @api.multi
  271. def set_model_ids(self):
  272. config_parameters = self.env['ir.config_parameter']
  273. model_names = ''
  274. for record in self:
  275. model_names = ','.join([m.model for m in record.model_ids])
  276. config_parameters.set_param('mail_relocation_models', model_names)