[IMP] remove alias_id field from view when catchall domain is not set.
[odoo/odoo.git] / addons / mail / mail_group.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2010-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 import datetime as DT
23 import io
24 import openerp
25 import openerp.tools as tools
26 from operator import itemgetter
27 from osv import osv
28 from osv import fields
29 from PIL import Image
30 import StringIO
31 import tools
32 from tools.translate import _
33
34 class mail_group(osv.osv):
35     """
36     A mail_group is a collection of users sharing messages in a discussion
37     group. Group users are users that follow the mail group, using the
38     subscription/follow mechanism of OpenSocial. A mail group has nothing
39     in common wih res.users.group.
40     Additional information on fields:
41         - ``member_ids``: user member of the groups are calculated with
42           ``message_get_subscribers`` method from mail.thread
43         - ``member_count``: calculated with member_ids
44         - ``is_subscriber``: calculated with member_ids
45         
46     """
47     
48     _description = 'Discussion group'
49     _name = 'mail.group'
50     _inherit = ['mail.thread']
51     _inherits = {'mail.alias': 'alias_id'}
52     def action_group_join(self, cr, uid, ids, context={}):
53         return self.message_subscribe(cr, uid, ids, context=context);
54     
55     def action_group_leave(self, cr, uid, ids, context={}):
56         return self.message_unsubscribe(cr, uid, ids, context=context);
57
58     def onchange_photo(self, cr, uid, ids, value, context=None):
59         if not value:
60             return {'value': {'avatar_big': value, 'avatar': value} }
61         return {'value': {'photo_big': value, 'photo': self._photo_resize(cr, uid, value) } }
62     
63     def _set_photo(self, cr, uid, id, name, value, args, context=None):
64         if value:
65             return self.write(cr, uid, [id], {'photo_big': value}, context=context)
66         else:
67             return self.write(cr, uid, [id], {'photo_big': value}, context=context)
68     
69     def _photo_resize(self, cr, uid, photo, width=128, height=128, context=None):
70         image_stream = io.BytesIO(photo.decode('base64'))
71         img = Image.open(image_stream)
72         img.thumbnail((width, height), Image.ANTIALIAS)
73         img_stream = StringIO.StringIO()
74         img.save(img_stream, "JPEG")
75         return img_stream.getvalue().encode('base64')
76         
77     def _get_photo(self, cr, uid, ids, name, args, context=None):
78         result = dict.fromkeys(ids, False)
79         for group in self.browse(cr, uid, ids, context=context):
80             if group.photo_big:
81                 result[group.id] = self._photo_resize(cr, uid, group.photo_big, context=context)
82         return result
83     
84     def get_member_ids(self, cr, uid, ids, field_names, args, context=None):
85         if context is None:
86             context = {}
87         result = dict.fromkeys(ids)
88         for id in ids:
89             result[id] = {}
90             result[id]['member_ids'] = self.message_get_subscribers_ids(cr, uid, [id], context=context)
91             result[id]['member_count'] = len(result[id]['member_ids'])
92             result[id]['is_subscriber'] = uid in result[id]['member_ids']
93         return result
94     
95     def search_member_ids(self, cr, uid, obj, name, args, context=None):
96         if context is None:
97             context = {}
98         sub_obj = self.pool.get('mail.subscription')
99         sub_ids = sub_obj.search(cr, uid, ['&', ('res_model', '=', obj._name), ('user_id', '=', args[0][2])], context=context)
100         subs = sub_obj.read(cr, uid, sub_ids, context=context)
101         return [('id', 'in', map(itemgetter('res_id'), subs))]
102     
103     def get_last_month_msg_nbr(self, cr, uid, ids, name, args, context=None):
104         result = {}
105         message_obj = self.pool.get('mail.message')
106         for id in ids:
107             lower_date = (DT.datetime.now() - DT.timedelta(days=30)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
108             result[id] = message_obj.search(cr, uid, ['&', '&', ('model', '=', self._name), ('res_id', 'in', ids), ('date', '>=', lower_date)], count=True, context=context)
109         return result
110     
111     def _get_default_photo(self, cr, uid, context=None):
112         avatar_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
113         return self._photo_resize(cr, uid, open(avatar_path, 'rb').read().encode('base64'), context=context)
114     
115     _columns = {
116         'name': fields.char('Name', size=64, required=True),
117         'description': fields.text('Description'),
118         'responsible_id': fields.many2one('res.users', string='Responsible',
119                             ondelete='set null', required=True, select=1,
120                             help="Responsible of the group that has all rights on the record."),
121         'public': fields.boolean('Public', help='This group is visible by non members. Invisible groups can add members through the invite button.'),
122         'photo_big': fields.binary('Full-size photo', help='Field holding the full-sized PIL-supported and base64 encoded version of the group image. The photo field is used as an interface for this field.'),
123         'photo': fields.function(_get_photo, fnct_inv=_set_photo, string='Photo', type="binary",
124             store = {
125                 'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['photo_big'], 10),
126             }, help='Field holding the automatically resized (128x128) PIL-supported and base64 encoded version of the group image.'),
127         'member_ids': fields.function(get_member_ids, fnct_search=search_member_ids, type='many2many',
128                         relation='res.users', string='Group members', multi='get_member_ids'),
129         'member_count': fields.function(get_member_ids, type='integer', string='Member count', multi='get_member_ids'),
130         'is_subscriber': fields.function(get_member_ids, type='boolean', string='Joined', multi='get_member_ids'),
131         'last_month_msg_nbr': fields.function(get_last_month_msg_nbr, type='integer', string='Messages count for last month'),
132         'alias_id': fields.many2one('mail.alias', 'Mail Alias', ondelete="cascade", required=True)
133     }
134
135     _defaults = {
136         'public': True,
137         'responsible_id': (lambda s, cr, uid, ctx: uid),
138         'photo': _get_default_photo,
139     }
140     
141     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
142         res = super(mail_group,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
143         if view_type == 'form':
144             domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "mail.catchall.domain", context=context)
145             if not domain:
146                 doc = etree.XML(res['arch'])
147                 alias_node = doc.xpath("//field[@name='alias_id']")[0]
148                 parent = alias_node.getparent()
149                 parent.remove(alias_node)
150                 res['arch'] = etree.tostring(doc)
151         return res
152     
153     def create(self, cr, uid, vals, context=None):
154         model_pool = self.pool.get('ir.model.data')
155         alias_pool = self.pool.get('mail.alias')
156         model, res_id = model_pool.get_object_reference( cr, uid, "mail", "model_mail_group")
157         vals.update({'alias_name': "mailing-group",
158                      'alias_model_id': res_id})
159         name = alias_pool.create_unique_alias(cr, uid, vals, context=context)
160         res = super( mail_group, self).create(cr, uid, vals, context)
161         record = self.read(cr, uid, res, context)
162         alias_pool.write(cr, uid, [record['alias_id']], {"alias_force_thread_id":record['id']}, context)
163         return res