eedc04603f0b8d5cf6d59277a757217abdcb5407
[odoo/odoo.git] / addons / mail / res_users.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2009-Today OpenERP SA (<http://www.openerp.com>)
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
22 from openerp.osv import fields, osv
23 from openerp import api
24 from openerp import SUPERUSER_ID
25 from openerp.tools.translate import _
26 import openerp
27
28
29 class res_users(osv.Model):
30     """ Update of res.users class
31         - add a preference about sending emails about notifications
32         - make a new user follow itself
33         - add a welcome message
34         - add suggestion preference
35     """
36     _name = 'res.users'
37     _inherit = ['res.users']
38     _inherits = {'mail.alias': 'alias_id'}
39
40     _columns = {
41         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
42             help="Email address internally associated with this user. Incoming "\
43                  "emails will appear in the user's notifications.", copy=False, auto_join=True),
44         'display_groups_suggestions': fields.boolean("Display Groups Suggestions"),
45     }
46
47     _defaults = {
48         'display_groups_suggestions': True,
49     }
50
51     def __init__(self, pool, cr):
52         """ Override of __init__ to add access rights on notification_email_send
53             and alias fields. Access rights are disabled by default, but allowed
54             on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
55         """
56         init_res = super(res_users, self).__init__(pool, cr)
57         # duplicate list to avoid modifying the original reference
58         self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
59         self.SELF_WRITEABLE_FIELDS.extend(['notify_email', 'display_groups_suggestions'])
60         # duplicate list to avoid modifying the original reference
61         self.SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS)
62         self.SELF_READABLE_FIELDS.extend(['notify_email', 'alias_domain', 'alias_name', 'display_groups_suggestions'])
63         return init_res
64
65     def _auto_init(self, cr, context=None):
66         """ Installation hook: aliases, partner following themselves """
67         # create aliases for all users and avoid constraint errors
68         return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init,
69             self._name, self._columns['alias_id'], 'login', alias_force_key='id', context=context)
70
71     def create(self, cr, uid, data, context=None):
72         if not data.get('login', False):
73             model, action_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'action_res_users')
74             msg = _("You cannot create a new user from here.\n To create new user please go to configuration panel.")
75             raise openerp.exceptions.RedirectWarning(msg, action_id, _('Go to the configuration panel'))
76         if context is None:
77             context = {}
78
79         create_context = dict(context, alias_model_name=self._name, alias_parent_model_name=self._name)
80         user_id = super(res_users, self).create(cr, uid, data, context=create_context)
81         user = self.browse(cr, uid, user_id, context=context)
82         self.pool.get('mail.alias').write(cr, SUPERUSER_ID, [user.alias_id.id], {"alias_force_thread_id": user_id, "alias_parent_thread_id": user_id}, context)
83
84         # create a welcome message
85         self._create_welcome_message(cr, uid, user, context=context)
86         return user_id
87
88     def copy_data(self, *args, **kwargs):
89         data = super(res_users, self).copy_data(*args, **kwargs)
90         if data and data.get('alias_name'):
91             data['alias_name'] = data['login']
92         return data
93
94     def _create_welcome_message(self, cr, uid, user, context=None):
95         if not self.has_group(cr, uid, 'base.group_user'):
96             return False
97         company_name = user.company_id.name if user.company_id else ''
98         body = _('%s has joined the %s network.') % (user.name, company_name)
99         # TODO change SUPERUSER_ID into user.id but catch errors
100         return self.pool.get('res.partner').message_post(cr, SUPERUSER_ID, [user.partner_id.id],
101             body=body, context=context)
102
103     def unlink(self, cr, uid, ids, context=None):
104         # Cascade-delete mail aliases as well, as they should not exist without the user.
105         alias_pool = self.pool.get('mail.alias')
106         alias_ids = [user.alias_id.id for user in self.browse(cr, uid, ids, context=context) if user.alias_id]
107         res = super(res_users, self).unlink(cr, uid, ids, context=context)
108         alias_pool.unlink(cr, uid, alias_ids, context=context)
109         return res
110
111     def _message_post_get_pid(self, cr, uid, thread_id, context=None):
112         assert thread_id, "res.users does not support posting global messages"
113         if context and 'thread_model' in context:
114             context['thread_model'] = 'res.users'
115         if isinstance(thread_id, (list, tuple)):
116             thread_id = thread_id[0]
117         return self.browse(cr, SUPERUSER_ID, thread_id).partner_id.id
118
119     @api.cr_uid_ids_context
120     def message_post(self, cr, uid, thread_id, context=None, **kwargs):
121         """ Redirect the posting of message on res.users to the related partner.
122             This is done because when giving the context of Chatter on the
123             various mailboxes, we do not have access to the current partner_id. """
124         if isinstance(thread_id, (list, tuple)):
125             thread_id = thread_id[0]
126         current_pids = []
127         partner_ids = kwargs.get('partner_ids', [])
128         user_pid = self._message_post_get_pid(cr, uid, thread_id, context=context)
129         for partner_id in partner_ids:
130             if isinstance(partner_id, (list, tuple)) and partner_id[0] == 4 and len(partner_id) == 2:
131                 current_pids.append(partner_id[1])
132             elif isinstance(partner_id, (list, tuple)) and partner_id[0] == 6 and len(partner_id) == 3:
133                 current_pids.append(partner_id[2])
134             elif isinstance(partner_id, (int, long)):
135                 current_pids.append(partner_id)
136         if user_pid not in current_pids:
137             partner_ids.append(user_pid)
138         kwargs['partner_ids'] = partner_ids
139         return self.pool.get('mail.thread').message_post(cr, uid, False, **kwargs)
140
141     def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
142         return True
143
144     def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
145         return True
146
147     def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None):
148         return self.pool.get('mail.thread').message_get_partner_info_from_emails(cr, uid, emails, link_mail=link_mail, context=context)
149
150     def message_get_suggested_recipients(self, cr, uid, ids, context=None):
151         return dict.fromkeys(ids, list())
152
153     def stop_showing_groups_suggestions(self, cr, uid, user_id, context=None):
154         """Update display_groups_suggestions value to False"""
155         if context is None:
156             context = {}
157         self.write(cr, uid, user_id, {"display_groups_suggestions": False}, context)
158
159
160 class res_users_mail_group(osv.Model):
161     """ Update of res.users class
162         - if adding groups to an user, check mail.groups linked to this user
163           group, and the user. This is done by overriding the write method.
164     """
165     _name = 'res.users'
166     _inherit = ['res.users']
167
168     # FP Note: to improve, post processing may be better ?
169     def write(self, cr, uid, ids, vals, context=None):
170         write_res = super(res_users_mail_group, self).write(cr, uid, ids, vals, context=context)
171         if vals.get('groups_id'):
172             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
173             user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
174             user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
175             mail_group_obj = self.pool.get('mail.group')
176             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', user_group_ids)], context=context)
177             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, ids, context=context)
178         return write_res
179
180 class res_groups_mail_group(osv.Model):
181     """ Update of res.groups class
182         - if adding users from a group, check mail.groups linked to this user
183           group and subscribe them. This is done by overriding the write method.
184     """
185     _name = 'res.groups'
186     _inherit = 'res.groups'
187
188     # FP Note: to improve, post processeing, after the super may be better
189     def write(self, cr, uid, ids, vals, context=None):
190         write_res = super(res_groups_mail_group, self).write(cr, uid, ids, vals, context=context)
191         if vals.get('users'):
192             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
193             user_ids = [command[1] for command in vals['users'] if command[0] == 4]
194             user_ids += [id for command in vals['users'] if command[0] == 6 for id in command[2]]
195             mail_group_obj = self.pool.get('mail.group')
196             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', ids)], context=context)
197             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, user_ids, context=context)
198         return write_res