[IMP] mail: added catchall and bounce aliases to config
[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
27 class res_users(osv.Model):
28     """ Update of res.users class
29         - add a preference about sending emails about notifications
30         - make a new user follow itself
31         - add a welcome message
32         - add suggestion preference
33     """
34     _name = 'res.users'
35     _inherit = ['res.users']
36     _inherits = {'mail.alias': 'alias_id'}
37
38     _columns = {
39         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
40             help="Email address internally associated with this user. Incoming "\
41                  "emails will appear in the user's notifications."),
42         'display_groups_suggestions': fields.boolean("Display Groups Suggestions"),
43     }
44
45     _defaults = {
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         return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init,
67             self._name, self._columns['alias_id'], 'login', alias_force_key='id', context=context)
68
69     def create(self, cr, uid, data, context=None):
70         if not data.get('login', False):
71             raise osv.except_osv(_('Invalid Action!'), _('You may not create a user. To create new users, you should use the "Settings > Users" menu.'))
72         if context is None:
73             context = {}
74
75         create_context = dict(context, alias_model_name=self._name, alias_parent_model_name=self._name)
76         user_id = super(res_users, self).create(cr, uid, data, context=create_context)
77         user = self.browse(cr, uid, user_id, context=context)
78         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)
79
80         # create a welcome message
81         self._create_welcome_message(cr, uid, user, context=context)
82         return user_id
83
84     def _create_welcome_message(self, cr, uid, user, context=None):
85         if not self.has_group(cr, uid, 'base.group_user'):
86             return False
87         company_name = user.company_id.name if user.company_id else ''
88         body = _('%s has joined the %s network.') % (user.name, company_name)
89         # TODO change SUPERUSER_ID into user.id but catch errors
90         return self.pool.get('res.partner').message_post(cr, SUPERUSER_ID, [user.partner_id.id],
91             body=body, context=context)
92
93     def unlink(self, cr, uid, ids, context=None):
94         # Cascade-delete mail aliases as well, as they should not exist without the user.
95         alias_pool = self.pool.get('mail.alias')
96         alias_ids = [user.alias_id.id for user in self.browse(cr, uid, ids, context=context) if user.alias_id]
97         res = super(res_users, self).unlink(cr, uid, ids, context=context)
98         alias_pool.unlink(cr, uid, alias_ids, context=context)
99         return res
100
101     def _message_post_get_pid(self, cr, uid, thread_id, context=None):
102         assert thread_id, "res.users does not support posting global messages"
103         if context and 'thread_model' in context:
104             context['thread_model'] = 'res.users'
105         if isinstance(thread_id, (list, tuple)):
106             thread_id = thread_id[0]
107         return self.browse(cr, SUPERUSER_ID, thread_id).partner_id.id
108
109     def message_post(self, cr, uid, thread_id, context=None, **kwargs):
110         """ Redirect the posting of message on res.users to the related partner.
111             This is done because when giving the context of Chatter on the
112             various mailboxes, we do not have access to the current partner_id. """
113         if isinstance(thread_id, (list, tuple)):
114             thread_id = thread_id[0]
115         partner_ids = kwargs.get('partner_ids', [])
116         partner_id = self._message_post_get_pid(cr, uid, thread_id, context=context)
117         if partner_id not in [command[1] for command in partner_ids]:
118             partner_ids.append(partner_id)
119         kwargs['partner_ids'] = partner_ids
120         return self.pool.get('mail.thread').message_post(cr, uid, False, **kwargs)
121
122     def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
123         return True
124
125     def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
126         return True
127
128     def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None):
129         return self.pool.get('mail.thread').message_get_partner_info_from_emails(cr, uid, emails, link_mail=link_mail, context=context)
130
131     def message_get_suggested_recipients(self, cr, uid, ids, context=None):
132         return dict.fromkeys(ids, list())
133
134     def stop_showing_groups_suggestions(self, cr, uid, user_id, context=None):
135         """Update display_groups_suggestions value to False"""
136         if context is None:
137             context = {}
138         self.write(cr, uid, user_id, {"display_groups_suggestions": False}, context)
139
140
141 class res_users_mail_group(osv.Model):
142     """ Update of res.users class
143         - if adding groups to an user, check mail.groups linked to this user
144           group, and the user. This is done by overriding the write method.
145     """
146     _name = 'res.users'
147     _inherit = ['res.users']
148
149     # FP Note: to improve, post processing may be better ?
150     def write(self, cr, uid, ids, vals, context=None):
151         write_res = super(res_users_mail_group, self).write(cr, uid, ids, vals, context=context)
152         if vals.get('groups_id'):
153             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
154             user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
155             user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
156             mail_group_obj = self.pool.get('mail.group')
157             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', user_group_ids)], context=context)
158             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, ids, context=context)
159         return write_res
160
161 class res_groups_mail_group(osv.Model):
162     """ Update of res.groups class
163         - if adding users from a group, check mail.groups linked to this user
164           group and subscribe them. This is done by overriding the write method.
165     """
166     _name = 'res.groups'
167     _inherit = 'res.groups'
168
169     # FP Note: to improve, post processeing, after the super may be better
170     def write(self, cr, uid, ids, vals, context=None):
171         write_res = super(res_groups_mail_group, self).write(cr, uid, ids, vals, context=context)
172         if vals.get('users'):
173             # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
174             user_ids = [command[1] for command in vals['users'] if command[0] == 4]
175             user_ids += [id for command in vals['users'] if command[0] == 6 for id in command[2]]
176             mail_group_obj = self.pool.get('mail.group')
177             mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', ids)], context=context)
178             mail_group_obj.message_subscribe_users(cr, uid, mail_group_ids, user_ids, context=context)
179         return write_res