[MERGE] with trunk
[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 SUPERUSER_ID
24 from openerp.tools.translate import _
25
26 class res_users(osv.Model):
27     """ Update of res.users class
28         - add a preference about sending emails about notifications
29         - make a new user follow itself
30         - add a welcome message
31         - add suggestion preference
32     """
33     _name = 'res.users'
34     _inherit = ['res.users']
35     _inherits = {'mail.alias': 'alias_id'}
36
37     _columns = {
38         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
39             help="Email address internally associated with this user. Incoming "\
40                  "emails will appear in the user's notifications."),
41         'display_groups_suggestions': fields.boolean("Display Groups Suggestions"),
42     }
43
44     _defaults = {
45         'alias_domain': False,  # always hide alias during creation
46         'display_groups_suggestions': True,
47     }
48
49     def __init__(self, pool, cr):
50         """ Override of __init__ to add access rights on notification_email_send
51             and alias fields. Access rights are disabled by default, but allowed
52             on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
53         """
54         init_res = super(res_users, self).__init__(pool, cr)
55         # duplicate list to avoid modifying the original reference
56         self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
57         self.SELF_WRITEABLE_FIELDS.extend(['notification_email_send', 'display_groups_suggestions'])
58         # duplicate list to avoid modifying the original reference
59         self.SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS)
60         self.SELF_READABLE_FIELDS.extend(['notification_email_send', 'alias_domain', 'alias_name', 'display_groups_suggestions'])
61         return init_res
62
63     def _auto_init(self, cr, context=None):
64         """ Installation hook: aliases, partner following themselves """
65         # create aliases for all users and avoid constraint errors
66         res = self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init,
67             self._columns['alias_id'], 'login', alias_force_key='id', context=context)
68         return res
69
70     def create(self, cr, uid, data, context=None):
71         # create default alias same as the login
72         if not data.get('login', False):
73             raise osv.except_osv(_('Invalid Action!'), _('You may not create a user. To create new users, you should use the "Settings > Users" menu.'))
74
75         mail_alias = self.pool.get('mail.alias')
76         alias_id = mail_alias.create_unique_alias(cr, uid, {'alias_name': data['login']}, model_name=self._name, context=context)
77         data['alias_id'] = alias_id
78         data.pop('alias_name', None)  # prevent errors during copy()
79
80         # create user
81         user_id = super(res_users, self).create(cr, uid, data, context=context)
82         user = self.browse(cr, uid, user_id, context=context)
83         # alias
84         mail_alias.write(cr, SUPERUSER_ID, [alias_id], {"alias_force_thread_id": user_id}, context)
85         # create a welcome message
86         self._create_welcome_message(cr, uid, user, context=context)
87         return user_id
88
89     def _create_welcome_message(self, cr, uid, user, context=None):
90         if not self.has_group(cr, uid, 'base.group_user'):
91             return False
92         company_name = user.company_id.name if user.company_id else ''
93         body = _('%s has joined the %s network.') % (user.name, company_name)
94         # TODO change SUPERUSER_ID into user.id but catch errors
95         return self.pool.get('res.partner').message_post(cr, SUPERUSER_ID, [user.partner_id.id],
96             body=body, context=context)
97
98     def write(self, cr, uid, ids, vals, context=None):
99         # User alias is sync'ed with login
100         if vals.get('login'):
101             vals['alias_name'] = vals['login']
102         return super(res_users, self).write(cr, uid, ids, vals, context=context)
103
104     def unlink(self, cr, uid, ids, context=None):
105         # Cascade-delete mail aliases as well, as they should not exist without the user.
106         alias_pool = self.pool.get('mail.alias')
107         alias_ids = [user.alias_id.id for user in self.browse(cr, uid, ids, context=context) if user.alias_id]
108         res = super(res_users, self).unlink(cr, uid, ids, context=context)
109         alias_pool.unlink(cr, uid, alias_ids, context=context)
110         return res
111
112     def _message_post_get_pid(self, cr, uid, thread_id, context=None):
113         assert thread_id, "res.users does not support posting global messages"
114         if context and 'thread_model' in context:
115             context['thread_model'] = 'res.users'
116         if isinstance(thread_id, (list, tuple)):
117             thread_id = thread_id[0]
118         return self.browse(cr, SUPERUSER_ID, thread_id).partner_id.id
119
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         partner_ids = kwargs.get('partner_ids', [])
127         partner_id = self._message_post_get_pid(cr, uid, thread_id, context=context)
128         if partner_id not in [command[1] for command in partner_ids]:
129             partner_ids.append(partner_id)
130         kwargs['partner_ids'] = partner_ids
131         return self.pool.get('mail.thread').message_post(cr, uid, False, **kwargs)
132
133     def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
134         return True
135
136     def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
137         return True
138
139     def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None):
140         return self.pool.get('mail.thread').message_get_partner_info_from_emails(cr, uid, emails, link_mail=link_mail, context=context)
141
142     def message_get_suggested_recipients(self, cr, uid, ids, context=None):
143         return dict.fromkeys(ids, list())
144
145     def stop_showing_groups_suggestions(self, cr, uid, user_id, context=None):
146         """Update display_groups_suggestions value to False"""
147         if context is None:
148             context = {}
149         self.write(cr, uid, user_id, {"display_groups_suggestions": False}, context)
150
151
152 class res_users_mail_group(osv.Model):
153     """ Update of res.users class
154         - if adding groups to an user, check mail.groups linked to this user
155           group, and the user. This is done by overriding the write method.
156     """
157     _name = 'res.users'
158     _inherit = ['res.users']
159
160     # FP Note: to improve, post processing may be better ?
161     def write(self, cr, uid, ids, vals, context=None):
162         write_res = super(res_users_mail_group, self).write(cr, uid, ids, vals, context=context)
163         if vals.get('groups_id'):
164             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
165             user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
166             user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
167             mail_group_obj = self.pool.get('mail.group')
168             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', user_group_ids)], context=context)
169             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, ids, context=context)
170         return write_res
171
172 class res_groups_mail_group(osv.Model):
173     """ Update of res.groups class
174         - if adding users from a group, check mail.groups linked to this user
175           group and subscribe them. This is done by overriding the write method.
176     """
177     _name = 'res.groups'
178     _inherit = 'res.groups'
179
180     # FP Note: to improve, post processeing, after the super may be better
181     def write(self, cr, uid, ids, vals, context=None):
182         write_res = super(res_groups_mail_group, self).write(cr, uid, ids, vals, context=context)
183         if vals.get('users'):
184             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
185             user_ids = [command[1] for command in vals['users'] if command[0] == 4]
186             user_ids += [id for command in vals['users'] if command[0] == 6 for id in command[2]]
187             mail_group_obj = self.pool.get('mail.group')
188             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', ids)], context=context)
189             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, user_ids, context=context)
190         return write_res