[IMP] better demo data
[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 osv import osv, fields
23 from openerp import SUPERUSER_ID
24 from 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     """
32     _name = 'res.users'
33     _inherit = ['res.users']
34     _inherits = {'mail.alias': 'alias_id'}
35
36     _columns = {
37         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True, 
38             help="Email address internally associated with this user. Incoming "\
39                  "emails will appear in the user's notifications."),
40     }
41     
42     _defaults = {
43         'alias_domain': False, # always hide alias during creation
44     }
45
46     def __init__(self, pool, cr):
47         """ Override of __init__ to add access rights on notification_email_send
48             field. Access rights are disabled by default, but allowed on
49             fields defined in self.SELF_WRITEABLE_FIELDS.
50         """
51         init_res = super(res_users, self).__init__(pool, cr)
52         # duplicate list to avoid modifying the original reference
53         self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
54         self.SELF_WRITEABLE_FIELDS.append('notification_email_send')
55         return init_res
56
57     def _auto_init(self, cr, context=None):
58         """ Installation hook: aliases, partner following themselves """
59         # create aliases for all users and avoid constraint errors
60         self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init,
61             self._columns['alias_id'], 'login', alias_force_key='id', context=context)
62         # make already existing users follow themselves, using SQL to avoid using the ORM during the auto_init
63         cr.execute("""  SELECT p.id FROM res_partner p
64                         LEFT JOIN mail_followers n
65                         ON (n.partner_id = p.id AND n.res_model = 'res.partner' AND n.res_id = p.id)
66                         WHERE n.id IS NULL
67                     """)
68         params = [(res[0], res[0]) for res in cr.fetchall()]
69         cr.executemany("""  INSERT INTO mail_followers (partner_id, res_model, res_id)
70                             VALUES (%s, 'res.partner', %s)
71                         """, params)
72
73     def create(self, cr, uid, data, context=None):
74         # create default alias same as the login
75         if not data.get('login', False):
76             raise osv.except_osv(_('Invalid Action!'), _('You may not create a user. To create new users, you should use the "Settings > Users" menu.'))
77
78         mail_alias = self.pool.get('mail.alias')
79         alias_id = mail_alias.create_unique_alias(cr, uid, {'alias_name': data['login']}, model_name=self._name, context=context)
80         data['alias_id'] = alias_id
81         data.pop('alias_name', None) # prevent errors during copy()
82
83         # create user that follows its related partner
84         user_id = super(res_users, self).create(cr, uid, data, context=context)
85         user = self.browse(cr, uid, user_id, context=context)
86         self.pool.get('res.partner').message_subscribe(cr, uid, [user.partner_id.id], [user.partner_id.id], context=context)
87         # alias
88         mail_alias.write(cr, SUPERUSER_ID, [alias_id], {"alias_force_thread_id": user_id}, context)
89         # create a welcome message
90         self._create_welcome_message(cr, uid, user, context=context)
91         return user_id
92
93     def _create_welcome_message(self, cr, uid, user, context=None):
94         if not self.has_group(cr, uid, 'base.group_user'):
95             return False
96         company_name = user.company_id.name if user.company_id else ''
97         body = _('%s has joined the %s network.') % (user.name, company_name)
98         # TODO change SUPERUSER_ID into user.id but catch errors
99         return self.pool.get('res.partner').message_post(cr, SUPERUSER_ID, [user.partner_id.id],
100             body=body, context=context)
101
102     def write(self, cr, uid, ids, vals, context=None):
103         # User alias is sync'ed with login
104         if vals.get('login'):
105             vals['alias_name'] = vals['login']
106         return super(res_users, self).write(cr, uid, ids, vals, context=context)
107
108     def unlink(self, cr, uid, ids, context=None):
109         # Cascade-delete mail aliases as well, as they should not exist without the user.
110         alias_pool = self.pool.get('mail.alias')
111         alias_ids = [user.alias_id.id for user in self.browse(cr, uid, ids, context=context) if user.alias_id]
112         res = super(res_users, self).unlink(cr, uid, ids, context=context)
113         alias_pool.unlink(cr, uid, alias_ids, context=context)
114         return res
115
116     def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False,
117                                 attachment_ids=None, context=None, content_subtype='plaintext', **kwargs):
118         """ Redirect the posting of message on res.users to the related partner.
119             This is done because when giving the context of Chatter on the
120             various mailboxes, we do not have access to the current partner_id.
121             We therefore post on the user and redirect on its partner. """
122         assert thread_id, "res.users does not support posting global messages"
123         if context and 'thread_model' in context:
124             context['thread_model'] = 'res.partner'
125         if isinstance(thread_id, (list, tuple)):
126             thread_id = thread_id[0]
127         partner_id = self.pool.get('res.users').read(cr, uid, thread_id, ['partner_id'], context=context)['partner_id'][0]
128         return self.pool.get('res.partner').message_post_user_api(cr, uid, partner_id, body=body, subject=subject,
129             parent_id=parent_id, attachment_ids=attachment_ids, context=context, content_subtype=content_subtype, **kwargs)
130
131     def message_post(self, cr, uid, thread_id, context=None, **kwargs):
132         """ Redirect the posting of message on res.users to the related partner.
133             This is done because when giving the context of Chatter on the
134             various mailboxes, we do not have access to the current partner_id.
135             We therefore post on the user and redirect on its partner. """
136         assert thread_id, "res.users does not support posting global messages"
137         if context and 'thread_model' in context:
138             context['thread_model'] = 'res.partner'
139         if isinstance(thread_id, (list, tuple)):
140             thread_id = thread_id[0]
141         partner_id = self.pool.get('res.users').read(cr, uid, thread_id, ['partner_id'], context=context)['partner_id'][0]
142         return self.pool.get('res.partner').message_post(cr, uid, partner_id, context=context, **kwargs)
143
144     def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
145         partner_id = self.pool.get('res.users').browse(cr, uid, ids)[0].partner_id.id
146         return self.pool.get('res.partner').message_update(cr, uid, [partner_id], msg_dict,
147             update_vals=update_vals, context=context)
148
149
150 class res_users_mail_group(osv.Model):
151     """ Update of res.users class
152         - if adding groups to an user, check mail.groups linked to this user
153           group, and the user. This is done by overriding the write method.
154     """
155     _name = 'res.users'
156     _inherit = ['res.users']
157
158     # FP Note: to improve, post processing may be better ?
159     def write(self, cr, uid, ids, vals, context=None):
160         write_res = super(res_users_mail_group, self).write(cr, uid, ids, vals, context=context)
161         if vals.get('groups_id'):
162             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
163             user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
164             user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
165             mail_group_obj = self.pool.get('mail.group')
166             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', user_group_ids)], context=context)
167             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, ids, context=context)
168         return write_res
169
170 class res_groups_mail_group(osv.Model):
171     """ Update of res.groups class
172         - if adding users from a group, check mail.groups linked to this user
173           group and subscribe them. This is done by overriding the write method.
174     """
175     _name = 'res.groups'
176     _inherit = 'res.groups'
177
178     # FP Note: to improve, post processeing, after the super may be better
179     def write(self, cr, uid, ids, vals, context=None):
180         write_res = super(res_groups_mail_group, self).write(cr, uid, ids, vals, context=context)
181         if vals.get('users'):
182             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
183             user_ids = [command[1] for command in vals['users'] if command[0] == 4]
184             user_ids += [id for command in vals['users'] if command[0] == 6 for id in command[2]]
185             mail_group_obj = self.pool.get('mail.group')
186             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', ids)], context=context)
187             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, user_ids, context=context)
188         return write_res