[IMP] display the proper mail.group when clicking on the 'News' menu item
[odoo/odoo.git] / addons / portal / wizard / share_wizard.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2011 OpenERP S.A (<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 tools.translate import _
24
25 UID_ROOT = 1
26 SHARED_DOCS_MENU = "Documents"
27 SHARED_DOCS_CHILD_MENU = "Shared Documents"
28
29 class share_wizard_portal(osv.osv_memory):
30     """Inherited share wizard to automatically create appropriate
31        menus in the selected portal upon sharing with a portal group."""
32     _inherit = "share.wizard"
33
34     def _user_type_selection(self, cr, uid, context=None):
35         selection = super(share_wizard_portal, self)._user_type_selection(cr, uid, context=context)
36         selection.extend([('existing','Users you already shared with'),
37                           ('groups','Existing Groups (e.g Portal Groups)')])
38         return selection
39
40     _columns = {
41         'user_ids': fields.many2many('res.users', 'share_wizard_res_user_rel', 'share_id', 'user_id', 'Existing users', domain=[('share', '=', True)]),
42         'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]),
43     }
44
45     def is_portal_manager(self, cr, uid, context=None):
46         return self.has_group(cr, uid, module='portal', group_xml_id='group_portal_manager', context=context)
47
48     def _check_preconditions(self, cr, uid, wizard_data, context=None):
49         if wizard_data.user_type == 'existing':
50             self._assert(wizard_data.user_ids,
51                      _('Please select at least one user to share with'),
52                      context=context)
53         elif wizard_data.user_type == 'groups':
54             self._assert(wizard_data.group_ids,
55                      _('Please select at least one group to share with'),
56                      context=context)
57         return super(share_wizard_portal, self)._check_preconditions(cr, uid, wizard_data, context=context)
58
59     def _create_or_get_submenu_named(self, cr, uid, parent_menu_id, menu_name, context=None):
60         if not parent_menu_id:
61             return
62         Menus = self.pool.get('ir.ui.menu')
63         parent_menu = Menus.browse(cr, uid, parent_menu_id) # No context
64         menu_id = None
65         max_seq = 10
66         for child_menu in parent_menu.child_id:
67             max_seq = max(max_seq, child_menu.sequence)
68             if child_menu.name == menu_name:
69                 menu_id = child_menu.id
70                 break
71         if not menu_id:
72             # not found, create it
73             menu_id = Menus.create(cr, UID_ROOT,
74                                     {'name': menu_name,
75                                      'parent_id': parent_menu.id,
76                                      'sequence': max_seq + 10, # at the bottom
77                                     })
78         return menu_id
79
80     def _sharing_root_menu_id(self, cr, uid, portal, context=None):
81         """Create or retrieve root ID of sharing menu in portal menu
82
83            :param portal: browse_record of portal, constructed with a context WITHOUT language
84         """
85         parent_menu_id = self._create_or_get_submenu_named(cr, uid, portal.parent_menu_id.id, SHARED_DOCS_MENU, context=context)
86         if parent_menu_id:
87             child_menu_id = self._create_or_get_submenu_named(cr, uid, parent_menu_id, SHARED_DOCS_CHILD_MENU, context=context)
88             return child_menu_id
89
90     def _create_shared_data_menu(self, cr, uid, wizard_data, portal, context=None):
91         """Create sharing menus in portal menu according to share wizard options.
92
93            :param wizard_data: browse_record of share.wizard
94            :param portal: browse_record of portal, constructed with a context WITHOUT language
95         """
96         root_menu_id = self._sharing_root_menu_id(cr, uid, portal, context=context)
97         if not root_menu_id:
98             # no specific parent menu, cannot create the sharing menu at all.
99             return
100         # Create the shared action and menu
101         action_def = self._shared_action_def(cr, uid, wizard_data, context=None)
102         action_id = self.pool.get('ir.actions.act_window').create(cr, UID_ROOT, action_def)
103         menu_data = {'name': action_def['name'],
104                      'sequence': 10,
105                      'action': 'ir.actions.act_window,'+str(action_id),
106                      'parent_id': root_menu_id,
107                      'icon': 'STOCK_JUSTIFY_FILL'}
108         menu_id =  self.pool.get('ir.ui.menu').create(cr, UID_ROOT, menu_data)
109         return menu_id
110
111     def _create_share_users_group(self, cr, uid, wizard_data, context=None):
112         # Override of super() to handle the possibly selected "existing users"
113         # and "existing groups".
114         # In both cases, we call super() to create the share group, but when
115         # sharing with existing groups, we will later delete it, and copy its
116         # access rights and rules to the selected groups.
117         group_id = super(share_wizard_portal,self)._create_share_users_group(cr, uid, wizard_data, context=context)
118
119         # For sharing with existing groups, we don't create a share group, instead we'll
120         # alter the rules of the groups so they can see the shared data
121         if wizard_data.group_ids:
122             # get the list of portals and the related groups to install their menus.
123             Portals = self.pool.get('res.portal')
124             all_portals = Portals.browse(cr, UID_ROOT, Portals.search(cr, UID_ROOT, [])) #no context!
125             all_portal_group_ids = [p.group_id.id for p in all_portals]
126
127             # populate result lines with the users of each group and
128             # setup the menu for portal groups
129             for group in wizard_data.group_ids:
130                 if group.id in all_portal_group_ids:
131                     portal = all_portals[all_portal_group_ids.index(group.id)]
132                     self._create_shared_data_menu(cr, uid, wizard_data, portal, context=context)
133
134                 for user in group.users:
135                     new_line = {'user_id': user.id,
136                                 'newly_created': False}
137                     wizard_data.write({'result_line_ids': [(0,0,new_line)]})
138
139         elif wizard_data.user_ids:
140             # must take care of existing users, by adding them to the new group, which is group_ids[0],
141             # and adding the shortcut
142             selected_user_ids = [x.id for x in wizard_data.user_ids]
143             self.pool.get('res.users').write(cr, UID_ROOT, selected_user_ids, {'groups_id': [(4,group_id)]})
144             self._setup_action_and_shortcut(cr, uid, wizard_data, selected_user_ids, make_home=False, context=context)
145             # populate the result lines for existing users too
146             for user in wizard_data.user_ids:
147                 new_line = { 'user_id': user.id,
148                              'newly_created': False}
149                 wizard_data.write({'result_line_ids': [(0,0,new_line)]})
150
151         return group_id
152
153     def copy_share_group_access_and_delete(self, cr, wizard_data, share_group_id, context=None):
154         # In the case of sharing with existing groups, the strategy is to copy
155         # access rights and rules from the share group, so that we can
156         if not wizard_data.group_ids: return
157         Groups = self.pool.get('res.groups')
158         Rules = self.pool.get('ir.rule')
159         Rights = self.pool.get('ir.model.access')
160         share_group = Groups.browse(cr, UID_ROOT, share_group_id)
161         share_rule_ids = [r.id for r in share_group.rule_groups]
162         for target_group in wizard_data.group_ids:
163             # Link the rules to the group. This is appropriate because as of
164             # v6.1, the algorithm for combining them will OR the rules, hence
165             # extending the visible data.
166             Rules.write(cr, UID_ROOT, share_rule_ids, {'groups': [(4,target_group.id)]})
167             self._logger.debug("Linked sharing rules from temporary sharing group to group %s", target_group)
168
169             # Copy the access rights. This is appropriate too because
170             # groups have the UNION of all permissions granted by their
171             # access right lines.
172             for access_line in share_group.model_access:
173                 Rights.copy(cr, UID_ROOT, access_line.id, default={'group_id': target_group.id})
174             self._logger.debug("Copied access rights from temporary sharing group to group %s", target_group)
175
176         # finally, delete it after removing its users
177         Groups.write(cr, UID_ROOT, [share_group_id], {'users': [(6,0,[])]})
178         Groups.unlink(cr, UID_ROOT, [share_group_id])
179         self._logger.debug("Deleted temporary sharing group %s", share_group_id)
180
181     def _finish_result_lines(self, cr, uid, wizard_data, share_group_id, context=None):
182         super(share_wizard_portal,self)._finish_result_lines(cr, uid, wizard_data, share_group_id, context=context)
183         self.copy_share_group_access_and_delete(cr, wizard_data, share_group_id, context=context)
184
185 share_wizard_portal()
186
187
188 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: