summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@openerp.com>2012-09-19 16:39:18 +0200
committerChristophe Matthieu <chm@openerp.com>2012-09-19 16:39:18 +0200
commit8e3aa494f183f6cc1354c822bc4e3c1c4429ea4b (patch)
tree4d7c34a774e6604a947cbcc62e5b832bf1e1e75a /addons
parent245002e48d9ce1ecbe0961071c0644b48f5a79bb (diff)
parentb0b4b4b25255e74c1a8c378e13fe8b541ec950e9 (diff)
[MERGE] from trunk
bzr revid: chm@openerp.com-20120919143918-r3sk2cl4ro19i3lm
Diffstat (limited to 'addons')
-rw-r--r--addons/auth_signup/auth_signup_data.xml2
-rw-r--r--addons/crm/__openerp__.py2
-rw-r--r--addons/portal/mail_mail.py2
-rw-r--r--addons/portal/portal.py190
-rw-r--r--addons/portal/portal_data.xml8
-rw-r--r--addons/portal/portal_demo.xml2
-rw-r--r--addons/portal/portal_view.xml74
-rw-r--r--addons/portal/security/ir.model.access.csv18
-rw-r--r--addons/portal/security/portal_security.xml31
-rw-r--r--addons/portal/tests/test_portal.py2
-rw-r--r--addons/portal/wizard/portal_wizard.py318
-rw-r--r--addons/portal/wizard/portal_wizard_view.xml57
-rw-r--r--addons/portal/wizard/share_wizard.py11
-rw-r--r--addons/portal/wizard/share_wizard_view.xml6
-rw-r--r--addons/portal_claim/security/ir.model.access.csv4
-rw-r--r--addons/portal_claim/security/portal_security.xml2
-rw-r--r--addons/portal_event/security/ir.model.access.csv4
-rw-r--r--addons/portal_event/security/portal_security.xml4
-rw-r--r--addons/portal_hr_employees/security/ir.model.access.csv10
-rw-r--r--addons/portal_project/security/ir.model.access.csv8
-rw-r--r--addons/portal_project/security/portal_security.xml2
-rw-r--r--addons/portal_project_issue/security/ir.model.access.csv4
-rw-r--r--addons/portal_project_issue/security/portal_security.xml2
-rw-r--r--addons/portal_sale/security/ir.model.access.csv64
-rw-r--r--addons/portal_sale/security/portal_security.xml12
-rw-r--r--addons/share/res_users_view.xml12
26 files changed, 299 insertions, 552 deletions
diff --git a/addons/auth_signup/auth_signup_data.xml b/addons/auth_signup/auth_signup_data.xml
index 4a6bf9ae4b9..39b62148494 100644
--- a/addons/auth_signup/auth_signup_data.xml
+++ b/addons/auth_signup/auth_signup_data.xml
@@ -13,7 +13,7 @@
<field name="groups_id" eval="[(5,)]"/>
</record>
- <record id="default_template_user" model="ir.config_parameter">
+ <record id="default_template_user_config" model="ir.config_parameter">
<field name="key">auth_signup.template_user_id</field>
<field name="value" ref="default_template_user"/>
</record>
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index a196f3d3f5f..135f4237f1c 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -25,7 +25,7 @@
'version': '1.0',
'category': 'Customer Relationship Management',
'sequence': 2,
- 'summary': 'Leads, Opportunities, Agenda',
+ 'summary': 'Leads, Opportunities, Phone Calls',
'description': """
The generic OpenERP Customer Relationship Management
=====================================================
diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py
index 72c8469c042..a41c28f15e2 100644
--- a/addons/portal/mail_mail.py
+++ b/addons/portal/mail_mail.py
@@ -43,7 +43,7 @@ class mail_mail_portal(osv.Model):
:param partner: browse_record of the specific recipient partner
"""
if partner:
- portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal')
+ portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal')
portal_id = portal_ref and portal_ref[1] or False
url = self._generate_signin_url(cr, uid, partner.id, portal_id, 1234, context=context)
body = tools.append_content_to_html(mail.body_html, url)
diff --git a/addons/portal/portal.py b/addons/portal/portal.py
index 3672d87cf30..13cde80f849 100644
--- a/addons/portal/portal.py
+++ b/addons/portal/portal.py
@@ -20,196 +20,14 @@
##############################################################################
from osv import osv, fields
-from tools.translate import _
-
class portal(osv.osv):
+ """ A portal is simply a group of users with the flag 'is_portal' set to True.
+ The flag 'is_portal' makes a user group usable as a portal.
"""
- A portal is a group of users with specific menu, widgets, and typically
- restricted access rights.
- """
- _name = 'res.portal'
- _description = 'Portal'
- _inherits = {'res.groups': 'group_id'}
-
- _columns = {
- 'group_id': fields.many2one('res.groups', required=True, ondelete='cascade',
- string='Group',
- help='The group corresponding to this portal'),
- 'url': fields.char('URL',
- help="The url where portal users can connect to the server"),
- 'home_action_id': fields.many2one('ir.actions.actions',
- string='Home Action',
- help="if set, replaces the standard home action (first screen after loggin) for the portal's users"),
- 'menu_action_id': fields.many2one('ir.actions.act_window', readonly=True,
- # ISSUE: 'ondelete' constraints do not seem effective on this field...
- string='Menu Action',
- help="If set, replaces the standard menu for the portal's users"),
- 'parent_menu_id': fields.many2one('ir.ui.menu', ondelete='restrict',
- string='Parent Menu',
- help='The menu action opens the submenus of this menu item'),
- 'widget_ids': fields.one2many('res.portal.widget', 'portal_id',
- string='Widgets',
- help='Widgets assigned to portal users'),
- }
-
- def copy(self, cr, uid, id, values, context=None):
- """ override copy(): menu_action_id must be different """
- values['menu_action_id'] = None
- return super(portal, self).copy(cr, uid, id, values, context)
-
- def create(self, cr, uid, values, context=None):
- """ extend create() to assign the portal menu to users """
- if context is None:
- context = {}
-
- # create portal (admin should not be included)
- context['noadmin'] = True
- portal_id = super(portal, self).create(cr, uid, values, context)
-
- # assign menu action and widgets to users
- if values.get('users') or values.get('menu_action_id'):
- self._assign_menu(cr, uid, [portal_id], context)
- if values.get('users') or values.get('widget_ids'):
- self._assign_widgets(cr, uid, [portal_id], context)
-
- return portal_id
-
- def write(self, cr, uid, ids, values, context=None):
- """ extend write() to reflect changes on users """
- # first apply portal changes
- super(portal, self).write(cr, uid, ids, values, context)
-
- # assign menu action and widgets to users
- if values.get('users') or values.get('menu_action_id'):
- self._assign_menu(cr, uid, ids, context)
- if values.get('users') or values.get('widget_ids'):
- self._assign_widgets(cr, uid, ids, context)
-
- # if parent_menu_id has changed, apply the change on menu_action_id
- if 'parent_menu_id' in values:
- act_window_obj = self.pool.get('ir.actions.act_window')
- portals = self.browse(cr, uid, ids, context)
- action_ids = [p.menu_action_id.id for p in portals if p.menu_action_id]
- if action_ids:
- action_values = {'domain': [('parent_id', '=', values['parent_menu_id'])]}
- act_window_obj.write(cr, uid, action_ids, action_values, context)
-
- return True
-
- def _assign_menu(self, cr, uid, ids, context=None):
- """ assign portal_menu_settings to users of portals (ids) """
- user_obj = self.pool.get('res.users')
- for p in self.browse(cr, uid, ids, context):
- # user menu action = portal menu action if set in portal
- if p.menu_action_id:
- user_ids = [u.id for u in p.users if u.id != 1]
- user_values = {'menu_id': p.menu_action_id.id}
- user_obj.write(cr, uid, user_ids, user_values, context)
-
- def _assign_widgets(self, cr, uid, ids, context=None):
- """ assign portal widgets to users of portals (ids) """
- widget_user_obj = self.pool.get('res.widget.user')
- for p in self.browse(cr, uid, ids, context):
- for w in p.widget_ids:
- values = {'sequence': w.sequence, 'widget_id': w.widget_id.id}
- for u in p.users:
- if u.id == 1: continue
- values['user_id'] = u.id
- widget_user_obj.create(cr, uid, values, context)
-
- def _res_xml_id(self, cr, uid, module, xml_id):
- """ return the resource id associated to the given xml_id """
- data_obj = self.pool.get('ir.model.data')
- data_id = data_obj._get_id(cr, uid, module, xml_id)
- return data_obj.browse(cr, uid, data_id).res_id
-
-portal()
-
-
-
-class portal_override_menu(osv.osv):
- """
- Extend res.portal with a boolean field 'Override Users Menu', that
- triggers the creation or removal of menu_action_id
- """
- _name = 'res.portal'
- _inherit = 'res.portal'
-
- def _get_override_menu(self, cr, uid, ids, field_name, arg, context=None):
- assert field_name == 'override_menu'
- result = {}
- for p in self.browse(cr, uid, ids, context):
- result[p.id] = bool(p.menu_action_id)
- return result
-
- def _set_override_menu(self, cr, uid, id, field_name, field_value, arg, context=None):
- assert field_name == 'override_menu'
- if field_value:
- self.create_menu_action(cr, uid, id, context)
- else:
- self.write(cr, uid, [id], {'menu_action_id': False}, context)
-
- def create_menu_action(self, cr, uid, id, context=None):
- """ create, if necessary, a menu action that opens the menu items below
- parent_menu_id """
- p = self.browse(cr, uid, id, context)
- if not p.menu_action_id:
- actions_obj = self.pool.get('ir.actions.act_window')
- parent_id = p.parent_menu_id.id if p.parent_menu_id else False
- action_values = {
- 'name': _('%s Menu') % p.name,
- 'type': 'ir.actions.act_window',
- 'usage': 'menu',
- 'res_model': 'ir.ui.menu',
- 'view_type': 'tree',
- 'view_id': self._res_xml_id(cr, uid, 'base', 'view_menu'),
- 'domain': [('parent_id', '=', parent_id)],
- }
- action_id = actions_obj.create(cr, uid, action_values, context)
- self.write(cr, uid, [id], {'menu_action_id': action_id}, context)
-
- _columns = {
- 'override_menu': fields.function(
- _get_override_menu, fnct_inv=_set_override_menu,
- type='boolean', string='Override Menu Action of Users',
- help='Enable this option to override the Menu Action of portal users'),
- }
-
-portal_override_menu()
-
-
-
-class portal_widget(osv.osv):
- """
- Similar to res.widget.user (res_widget.py), but with a portal instead.
- New users in a portal are assigned the portal's widgets.
- """
- _name='res.portal.widget'
- _description = 'Portal Widgets'
- _order = 'sequence'
+ _inherit = 'res.groups'
_columns = {
- 'sequence': fields.integer('Sequence'),
- 'portal_id': fields.many2one('res.portal', select=1, ondelete='cascade',
- string='Portal'),
- 'widget_id': fields.many2one('res.widget', required=True, ondelete='cascade',
- string='Widget'),
+ 'is_portal': fields.boolean('Portal', help="If checked, this group is usable as a portal."),
}
- def create(self, cr, uid, values, context=None):
- domain = [('portal_id', '=', values.get('portal_id')),
- ('widget_id', '=', values.get('widget_id'))]
- existing = self.search(cr, uid, domain, context=context)
- if existing:
- res = existing[0]
- else:
- res = super(portal_widget, self).create(cr, uid, values, context=context)
- return res
-
-portal_widget()
-
-
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/portal/portal_data.xml b/addons/portal/portal_data.xml
index eb06ca656d6..a980552a854 100644
--- a/addons/portal/portal_data.xml
+++ b/addons/portal/portal_data.xml
@@ -2,14 +2,6 @@
<openerp>
<data noupdate="1">
- <record id="portal" model="res.portal">
- <field name="name">Portal</field>
- <field name="group_id" ref="group_portal_member"/>
- <field name="override_menu" eval="False"/>
- <!-- Insert the template user from auth_signup in the portal members group -->
- <field name="users" eval="[(4,ref('auth_signup.default_template_user'))]"/>
- </record>
-
<!-- Mail group for the company's news -->
<record id="company_news_feed" model="mail.group">
<field name="name">Company's news</field>
diff --git a/addons/portal/portal_demo.xml b/addons/portal/portal_demo.xml
index 1ace02f3d7d..f4ba8fe2192 100644
--- a/addons/portal/portal_demo.xml
+++ b/addons/portal/portal_demo.xml
@@ -13,7 +13,7 @@
</record>
<!-- Add the demo user to the portal (and therefore to the portal member group) -->
- <record id="portal" model="res.portal">
+ <record id="group_portal" model="res.groups">
<field name="users" eval="[(4,ref('demo_user0'))]"/>
</record>
diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml
index fd15a842405..16e8a86b27e 100644
--- a/addons/portal/portal_view.xml
+++ b/addons/portal/portal_view.xml
@@ -5,7 +5,7 @@
<!-- Top menu item -->
<menuitem name="Portal"
id="portal_menu"
- groups="base.group_no_one,portal.group_portal_member,auth_anonymous.group_anonymous"
+ groups="base.group_no_one,portal.group_portal,auth_anonymous.group_anonymous"
sequence="20"/>
<menuitem name="Our company" id="portal_company" parent="portal_menu" sequence="10"/>
@@ -21,71 +21,31 @@
<menuitem name="Projects" id="portal_projects" parent="portal_menu" sequence="40"/>
<menuitem name="After Sale Services" id="portal_after_sales" parent="portal_menu" sequence="50"/>
- <!-- portal tree view -->
- <record id="portal_list_view" model="ir.ui.view">
- <field name="name">Portal List</field>
- <field name="model">res.portal</field>
+ <!-- extend res.groups search view -->
+ <record id="group_search_view" model="ir.ui.view">
+ <field name="name">Group Search</field>
+ <field name="model">res.groups</field>
+ <field name="inherit_id" ref="base.view_groups_search"/>
<field name="arch" type="xml">
- <tree string="Portals">
- <field name="name" string="Portal Name"/>
- </tree>
+ <field name="name" position="after">
+ <filter name="portal" string="Portal Groups" domain="[('is_portal','=',True)]"/>
+ <filter name="no_portal" string="Non-Portal Groups" domain="[('is_portal','=',False)]"/>
+ <separator orientation="vertical"/>
+ </field>
</field>
</record>
- <!-- portal form view -->
- <record id="portal_form_view" model="ir.ui.view">
+ <!-- extend res.groups form view -->
+ <record id="group_form_view" model="ir.ui.view">
<field name="name">Portal Form</field>
- <field name="model">res.portal</field>
+ <field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_form"/>
<field name="arch" type="xml">
- <page string="Users" position="before">
- <page string="Portal">
- <group>
- <group>
- <field name="url" widget="url" string="Portal URL"/>
- <field name="home_action_id"/>
- </group>
- <group>
- <field name="override_menu"/>
- <field name="parent_menu_id"
- context="{'ir.ui.menu.full_list': True}"/>
- <label for="partent_menu_id" colspan="1"/>
- </group>
- <separator string="Widgets Assigned to Users" colspan="2"/>
- <field name="widget_ids" nolabel="1" colspan="2">
- <tree string="Widgets" editable="bottom">
- <field name="sequence"/>
- <field name="widget_id"/>
- </tree>
- </field>
- </group>
- </page>
- </page>
+ <field name="name" position="after">
+ <field name="is_portal"/>
+ </field>
</field>
</record>
- <!-- action Administration/Portals/Portals -->
- <record id="portal_list_action" model="ir.actions.act_window">
- <field name="name">Portals</field>
- <field name="res_model">res.portal</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <!-- a context is necessary to get the right portal form view -->
- <field name="context">{'form_view_ref': 'portal.portal_form_view'}</field>
- <field name="help" type="html">
- <p class="oe_view_nocontent_create">
- Click to create a new portal.
- </p><p>
- A portal helps defining specific views and rules for a group of
- users (the portal group). A portal menu, widgets and specific
- groups may be assigned to the portal's users.
- </p>
- </field>
- </record>
-
- <!-- menu Administration/Portals/Portals -->
- <menuitem name="Portals Settings" id="portal_menu_settings" parent="base.menu_administration" groups="group_portal_manager"/>
- <menuitem name="Portals" id="portal_list_menu" parent="portal_menu_settings" action="portal_list_action"/>
-
</data>
</openerp>
diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv
index 56b3ae5f269..2d7a17e0016 100644
--- a/addons/portal/security/ir.model.access.csv
+++ b/addons/portal/security/ir.model.access.csv
@@ -1,12 +1,8 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_all,access.portal.all,model_res_portal,,1,0,0,0
-access_widget_all,access.portal.widget.all,model_res_portal_widget,,1,0,0,0
-access_manager,access.portal.manager,model_res_portal,group_portal_manager,1,1,1,1
-access_widget_manager,access.portal.widget.manager,model_res_portal_widget,group_portal_manager,1,1,1,1
-access_mail_message,mail.message,mail.model_mail_message,group_portal_member,1,0,1,1
-access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal_member,1,0,0,0
-access_mail_thread,mail.thread,mail.model_mail_thread,group_portal_member,1,0,0,0
-access_mail_followers,mail.followers,mail.model_mail_followers,group_portal_member,1,0,1,1
-access_mail_notification,mail.notification,mail.model_mail_notification,group_portal_member,1,0,1,0
-access_mail_group,mail.group,mail.model_mail_group,group_portal_member,1,0,0,0
-access_mail_alias,mail.alias,mail.model_mail_alias,group_portal_member,1,0,0,0
+access_mail_message,mail.message,mail.model_mail_message,group_portal,1,0,1,1
+access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal,1,0,0,0
+access_mail_thread,mail.thread,mail.model_mail_thread,group_portal,1,0,0,0
+access_mail_followers,mail.followers,mail.model_mail_followers,group_portal,1,0,1,1
+access_mail_notification,mail.notification,mail.model_mail_notification,group_portal,1,0,1,0
+access_mail_group,mail.group,mail.model_mail_group,group_portal,1,0,0,0
+access_mail_alias,mail.alias,mail.model_mail_alias,group_portal,1,0,0,0
diff --git a/addons/portal/security/portal_security.xml b/addons/portal/security/portal_security.xml
index 4a493204d67..ee0af785599 100644
--- a/addons/portal/security/portal_security.xml
+++ b/addons/portal/security/portal_security.xml
@@ -2,31 +2,14 @@
<openerp>
<data noupdate="1">
- <!-- Don't use any implied_ids here; this group's behavior is particular -->
- <record id="group_portal_member" model="res.groups">
- <field name="name">Portal Member</field>
- <field name="comment">Portal members can access information through the portal menu. Also, they are chrooted in this specific menu.</field>
- </record>
-
- <record id="module_category_portal" model="ir.module.category">
+ <!-- The portal group -->
+ <record id="group_portal" model="res.groups">
<field name="name">Portal</field>
- <field name="parent_id" ref="base.module_category_tools"/>
- <field name="sequence">25</field>
- </record>
-
- <!-- No implied ids with 'member' since this group is highly restrictive (chrooted menu) -->
- <record id="group_portal_officer" model="res.groups">
- <field name="name">Officer</field>
- <field name="comment">Portal officers can create new portal users with the portal wizard.</field>
- <field name="category_id" ref="module_category_portal"/>
- </record>
-
- <record id="group_portal_manager" model="res.groups">
- <field name="name">Manager</field>
- <field name="comment">Portal managers have access to the portal definitions, and can easily configure the users, access rights and menus of portal users.</field>
- <field name="category_id" ref="module_category_portal"/>
- <field name="implied_ids" eval="[(4, ref('group_portal_officer'))]"/>
- <field name="users" eval="[(4, ref('base.user_root'))]"/>
+ <field name="comment">Portal members have specific access rights (such as record rules and restricted menus).
+ They usually do not belong to the usual OpenERP groups.</field>
+ <field name="is_portal" eval="True"/>
+ <!-- Insert the template user from auth_signup in the portal members group -->
+ <field name="users" eval="[(4,ref('auth_signup.default_template_user'))]"/>
</record>
</data>
diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py
index 2c301228859..5e992fa06ea 100644
--- a/addons/portal/tests/test_portal.py
+++ b/addons/portal/tests/test_portal.py
@@ -42,7 +42,7 @@ class test_portal(test_mail.TestMailMockups):
user_admin = self.res_users.browse(cr, uid, uid)
self.mail_invite = self.registry('mail.wizard.invite')
base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='')
- portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal')
+ portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal')
portal_id = portal_ref and portal_ref[1] or False
# 0 - Admin
diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py
index 85f6566eba6..3cc706c2129 100644
--- a/addons/portal/wizard/portal_wizard.py
+++ b/addons/portal/wizard/portal_wizard.py
@@ -23,33 +23,43 @@ import logging
import random
from osv import osv, fields
-from tools.misc import email_re
from tools.translate import _
+from tools.misc import email_re
+from openerp import SUPERUSER_ID
from base.res.res_partner import _lang_get
_logger = logging.getLogger(__name__)
-
-# welcome email sent to new portal users (note that calling tools.translate._
-# has no effect except exporting those strings for translation)
+# welcome/goodbye email sent to portal users
+# (note that calling '_' has no effect except exporting those strings for translation)
WELCOME_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s")
WELCOME_EMAIL_BODY = _("""Dear %(name)s,
-You have been created an OpenERP account at %(url)s.
+You have been given access to %(portal)s at %(url)s.
Your login account data is:
Database: %(db)s
User: %(login)s
Password: %(password)s
-%(message)s
+%(welcome_message)s
--
OpenERP - Open Source Business Applications
http://www.openerp.com
""")
-ROOT_UID = 1
+GOODBYE_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s")
+GOODBYE_EMAIL_BODY = _("""Dear %(name)s,
+
+Your access to %(portal)s has been withdrawn.
+
+%(goodbye_message)s
+
+--
+OpenERP - Open Source Business Applications
+http://www.openerp.com
+""")
# character sets for passwords, excluding 0, O, o, 1, I, l
_PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ'
@@ -71,169 +81,173 @@ def extract_email(email):
class wizard(osv.osv_memory):
"""
- A wizard to create portal users from instances of 'res.partner'. The purpose
- is to provide an OpenERP database access to customers or suppliers.
+ A wizard to manage the creation/removal of portal users.
"""
- _name = 'res.portal.wizard'
- _description = 'Portal Wizard'
-
+ _name = 'portal.wizard'
+ _description = 'Portal Access Management'
+
_columns = {
- 'portal_id': fields.many2one('res.portal', required=True,
- string='Portal',
- help="The portal in which new users must be added"),
- 'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id',
- string='Users'),
- 'message': fields.text(string='Invitation message',
- help="This text is included in the welcome email sent to the users"),
+ 'portal_id': fields.many2one('res.groups', domain=[('is_portal', '=', True)], required=True,
+ string='Portal', help="The portal that users can be added in or removed from."),
+ 'user_ids': fields.one2many('portal.wizard.user', 'wizard_id', string='Users'),
+ 'welcome_message': fields.text(string='Invitation Message',
+ help="This text is included in the email sent to new users of the portal."),
+ 'goodbye_message': fields.text(string='Withdrawal Message',
+ help="This text is included in the email sent to users withdrawn from the portal."),
}
- def _default_user_ids(self, cr, uid, context):
- """ determine default user_ids from the active records """
- def create_user_from_address(address):
- if isinstance(address, int):
- res_partner_obj = self.pool.get('res.partner')
- address = res_partner_obj.browse(cr, uid, address, context=context)
- lang = address.id and address.lang or 'en_US'
- partner_id = address.id
-
- else:
- lang = address.parent_id and address.parent_id.lang or 'en_US'
- partner_id = address.parent_id and address.parent_id.id
-
- return{
- 'name': address.name,
- 'email': extract_email(address.email),
- 'lang': lang,
- 'partner_id': partner_id,
- }
-
- user_ids = []
- if context.get('active_model') == 'res.partner':
- partner_obj = self.pool.get('res.partner')
- partner_ids = context.get('active_ids', [])
- partners = partner_obj.browse(cr, uid, partner_ids, context)
- for p in partners:
- # add one user per contact, or one user if no contact
- if p.child_ids:
- user_ids.extend(map(create_user_from_address, p.child_ids))
- elif p.is_company == False and p.customer == True:
- user_ids.extend(map(create_user_from_address, [p.id]))
- else:
- user_ids.append({'lang': p.lang or 'en_US', 'parent_id': p.id})
-
- return user_ids
+ def _default_portal(self, cr, uid, context):
+ portal_ids = self.pool.get('res.groups').search(cr, uid, [('is_portal', '=', True)])
+ return portal_ids and portal_ids[0] or False
_defaults = {
- 'user_ids': _default_user_ids
+ 'portal_id': _default_portal,
}
- def action_create(self, cr, uid, ids, context=None):
- """ create new users in portal(s), and notify them by email """
- # we copy the context to change the language for translating emails
- context0 = context or {}
- context0['noshortcut'] = True # prevent shortcut creation
- context = context0.copy()
-
- user_obj = self.pool.get('res.users')
- user = user_obj.browse(cr, ROOT_UID, uid, context0)
- if not user.email:
- raise osv.except_osv(_('Email required'),
- _('You must have an email address in your User Preferences'
- ' to send emails.'))
-
- portal_obj = self.pool.get('res.portal')
- for wiz in self.browse(cr, uid, ids, context):
- # determine existing users
- login_cond = [('login', 'in', [u.email for u in wiz.user_ids])]
- existing_uids = user_obj.search(cr, ROOT_UID, login_cond)
- existing_users = user_obj.browse(cr, ROOT_UID, existing_uids)
- existing_logins = [u.login for u in existing_users]
-
- # create new users in portal (skip existing logins)
- new_users_data = [ {
- 'name': u.name,
- 'login': u.email,
- 'password': random_password(),
- 'email': u.email,
- 'lang': u.lang,
- 'share': True,
- 'action_id': wiz.portal_id.home_action_id and wiz.portal_id.home_action_id.id or False,
- 'partner_id': u.partner_id and u.partner_id.id,
- 'groups_id': [(6, 0, [])],
- } for u in wiz.user_ids if u.email not in existing_logins ]
- portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id],
- {'users': [(0, 0, data) for data in new_users_data]}, context0)
-
- # send email to all users (translated in their language)
- data = {
- 'company': user.company_id.name,
- 'message': wiz.message or "",
- 'url': wiz.portal_id.url or _("(missing url)"),
- 'db': cr.dbname,
- }
- mail_mail_obj = self.pool.get('mail.mail')
- dest_uids = user_obj.search(cr, ROOT_UID, login_cond)
- dest_users = user_obj.browse(cr, ROOT_UID, dest_uids)
- for dest_user in dest_users:
- context['lang'] = dest_user.lang
- data['login'] = dest_user.login
- data['password'] = dest_user.password
- data['name'] = dest_user.name
-
- email_from = user.email
- email_to = dest_user.email
- subject = _(WELCOME_EMAIL_SUBJECT) % data
- body = _(WELCOME_EMAIL_BODY) % data
- mail_id = mail_mail_obj.create(cr, uid, {
- 'email_from': email_from ,
- 'email_to': email_to,
- 'subject': subject,
- 'state': 'outgoing',
- 'body_html': '<pre>%s</pre>' % body}, context=context)
-
+ def onchange_portal_id(self, cr, uid, ids, portal_id, context=None):
+ # for each partner, determine corresponding portal.wizard.user records
+ res_partner = self.pool.get('res.partner')
+ partner_ids = context and context.get('active_ids') or []
+ contact_ids = set()
+ user_changes = []
+ for partner in res_partner.browse(cr, SUPERUSER_ID, partner_ids, context):
+ for contact in (partner.child_ids or [partner]):
+ # make sure that each contact appears at most once in the list
+ if contact.id not in contact_ids:
+ contact_ids.add(contact.id)
+ in_portal = False
+ if contact.user_ids:
+ in_portal = portal_id in [g.id for g in contact.user_ids[0].groups_id]
+ user_changes.append((0, 0, {
+ 'partner_id': contact.id,
+ 'email': contact.email,
+ 'in_portal': in_portal,
+ }))
+ return {'value': {'user_ids': user_changes}}
+
+ def action_apply(self, cr, uid, ids, context=None):
+ wizard = self.browse(cr, uid, ids[0], context)
+ portal_user_ids = [user.id for user in wizard.user_ids]
+ self.pool.get('portal.wizard.user').action_apply(cr, uid, portal_user_ids, context)
return {'type': 'ir.actions.act_window_close'}
-wizard()
-
-
-
class wizard_user(osv.osv_memory):
"""
A model to configure users in the portal wizard.
"""
- _name = 'res.portal.wizard.user'
+ _name = 'portal.wizard.user'
_description = 'Portal User Config'
_columns = {
- 'wizard_id': fields.many2one('res.portal.wizard', required=True,
- string='Wizard'),
- 'name': fields.char(size=64, required=True,
- string='User Name',
- help="The user's real name"),
- 'email': fields.char(size=64, required=True,
- string='Email',
- help="Will be used as user login. "
- "Also necessary to send the account information to new users"),
- 'lang': fields.selection(_lang_get, required=True,
- string='Language',
- help="The language for the user's user interface"),
- 'partner_id': fields.many2one('res.partner',
- string='Partner'),
+ 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True),
+ 'partner_id': fields.many2one('res.partner', string='Contact', required=True, readonly=True),
+ 'email': fields.char(size=240, string='Email'),
+ 'in_portal': fields.boolean('In Portal'),
}
- def _check_email(self, cr, uid, ids):
- """ check syntax of email address """
- for wuser in self.browse(cr, uid, ids):
- if not email_re.match(wuser.email): return False
- return True
-
- _constraints = [
- (_check_email, 'Invalid email address', ['email']),
- ]
-
-wizard_user()
-
-
-
+ def create(self, cr, uid, values, context=None):
+ """ overridden to update the partner's email (if necessary) """
+ id = super(wizard_user, self).create(cr, uid, values, context)
+ wuser = self.browse(cr, uid, id, context)
+ if wuser.partner_id.email != wuser.email:
+ wuser.partner_id.write({'email': wuser.email})
+ return id
+
+ def action_apply(self, cr, uid, ids, context=None):
+ res_users = self.pool.get('res.users')
+ for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context):
+ portal = wizard_user.wizard_id.portal_id
+ user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context)
+ if wizard_user.in_portal:
+ # create a user if necessary, and make sure it is in the portal group
+ if not user:
+ user = self._create_user(cr, SUPERUSER_ID, wizard_user, context)
+ if (not user.active) or (portal not in user.groups_id):
+ user.write({'active': True, 'groups_id': [(4, portal.id)]})
+ wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context)
+ self._send_email(cr, uid, wizard_user, context)
+ else:
+ # remove the user (if it exists) from the portal group
+ if user and (portal in user.groups_id):
+ # if user belongs to portal only, deactivate it
+ if len(user.groups_id) <= 1:
+ user.write({'groups_id': [(3, portal.id)], 'active': False})
+ else:
+ user.write({'groups_id': [(3, portal.id)]})
+ wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context)
+ self._send_email(cr, uid, wizard_user, context)
+
+ def _retrieve_user(self, cr, uid, wizard_user, context=None):
+ """ retrieve the (possibly inactive) user corresponding to wizard_user.partner_id
+ @param wizard_user: browse record of model portal.wizard.user
+ @return: browse record of model res.users
+ """
+ if wizard_user.partner_id.user_ids:
+ return wizard_user.partner_id.user_ids[0]
+ # the user may be inactive, search for it
+ res_users = self.pool.get('res.users')
+ domain = [('partner_id', '=', wizard_user.partner_id.id), ('active', '=', False)]
+ user_ids = res_users.search(cr, uid, domain)
+ return user_ids and res_users.browse(cr, uid, user_ids[0], context) or False
+
+ def _create_user(self, cr, uid, wizard_user, context=None):
+ """ create a new user for wizard_user.partner_id
+ @param wizard_user: browse record of model portal.wizard.user
+ @return: browse record of model res.users
+ """
+ res_users = self.pool.get('res.users')
+ create_context = dict(context or {}, noshortcut=True) # to prevent shortcut creation
+ values = {
+ 'login': extract_email(wizard_user.email),
+ 'password': random_password(),
+ 'partner_id': wizard_user.partner_id.id,
+ 'groups_id': [(6, 0, [])],
+ 'share': True,
+ }
+ user_id = res_users.create(cr, uid, values, context=create_context)
+ return res_users.browse(cr, uid, user_id, context)
+
+ def _send_email(self, cr, uid, wizard_user, context=None):
+ """ send notification email to a new/former portal user
+ @param wizard_user: browse record of model portal.wizard.user
+ @return: the id of the created mail.mail record
+ """
+ this_context = context
+ this_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context)
+ if not this_user.email:
+ raise osv.except_osv(_('Email required'),
+ _('You must have an email address in your User Preferences to send emails.'))
+
+ # determine subject and body in the portal user's language
+ url = self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'web.base.url', context=this_context)
+ user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context)
+ context = dict(this_context or {}, lang=user.lang)
+ data = {
+ 'company': this_user.company_id.name,
+ 'portal': wizard_user.wizard_id.portal_id.name,
+ 'welcome_message': wizard_user.wizard_id.welcome_message or "",
+ 'goodbye_message': wizard_user.wizard_id.goodbye_message or "",
+ 'url': url or _("(missing url)"),
+ 'db': cr.dbname,
+ 'login': user.login,
+ 'password': user.password,
+ 'name': user.name
+ }
+ if wizard_user.in_portal:
+ subject = _(WELCOME_EMAIL_SUBJECT) % data
+ body = _(WELCOME_EMAIL_BODY) % data
+ else:
+ subject = _(GOODBYE_EMAIL_SUBJECT) % data
+ body = _(GOODBYE_EMAIL_BODY) % data
+
+ mail_mail = self.pool.get('mail.mail')
+ mail_values = {
+ 'email_from': this_user.email,
+ 'email_to': user.email,
+ 'subject': subject,
+ 'body_html': '<pre>%s</pre>' % body,
+ 'state': 'outgoing',
+ }
+ return mail_mail.create(cr, uid, mail_values, context=this_context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/portal/wizard/portal_wizard_view.xml b/addons/portal/wizard/portal_wizard_view.xml
index f3cd5c98bb4..c8e3f30b128 100644
--- a/addons/portal/wizard/portal_wizard_view.xml
+++ b/addons/portal/wizard/portal_wizard_view.xml
@@ -3,28 +3,34 @@
<data>
<!-- wizard action on res.partner -->
<act_window id="partner_wizard_action"
- name="Add Portal Access"
+ name="Portal Access Management"
src_model="res.partner"
- res_model="res.portal.wizard"
+ res_model="portal.wizard"
view_type="form" view_mode="form"
key2="client_action_multi" target="new"
- groups="group_portal_officer"/>
+ groups="base.group_partner_manager"/>
<!-- wizard view -->
<record id="wizard_view" model="ir.ui.view">
- <field name="name">Add Portal Access</field>
- <field name="model">res.portal.wizard</field>
+ <field name="name">Portal Access Management</field>
+ <field name="model">portal.wizard</field>
<field name="arch" type="xml">
- <form string="Add Portal Access" version="7.0">
- <group col="4">
- <field name="portal_id" widget="selection"/>
+ <form string="Portal Access Management" version="7.0">
+ <group>
+ <field name="portal_id" widget="selection" on_change="onchange_portal_id(portal_id, context)"/>
</group>
+ <div>
+ Select which contacts should belong to the portal in the list below.
+ The email address of each selected contact must be valid and unique.
+ If necessary, you can fix any contact's email address directly in the list.
+ </div>
<field name="user_ids"/>
- <label string="The following text will be included in the welcome email sent to users."/>
- <field name="message"/>
+ <field name="welcome_message"
+ placeholder="This text is included in the email sent to new portal users."/>
+ <field name="goodbye_message"
+ placeholder="This text is included in the email sent to users withdrawn from the portal."/>
<footer>
- <button string="Send Invitations"
- name="action_create" type="object" class="oe_highlight" />
+ <button string="Apply" name="action_apply" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
@@ -35,32 +41,15 @@
<!-- wizard user list view -->
<record id="wizard_user_tree_view" model="ir.ui.view">
<field name="name">Portal Users</field>
- <field name="model">res.portal.wizard.user</field>
+ <field name="model">portal.wizard.user</field>
<field name="arch" type="xml">
- <!-- the attribute 'editable' is set below to make the elements
- editable in the web client 6.0 -->
- <tree string="Portal Users" editable="bottom">
- <field name="name"/>
- <field name="email"/>
+ <!-- the contact list is editable, but one cannot add or delete rows -->
+ <tree string="Contacts" editable="bottom" create="false" delete="false">
<field name="partner_id"/>
+ <field name="email"/>
+ <field name="in_portal"/>
</tree>
</field>
</record>
-
- <!-- wizard user form view -->
- <record id="wizard_user_form_view" model="ir.ui.view">
- <field name="name">Portal User</field>
- <field name="model">res.portal.wizard.user</field>
- <field name="arch" type="xml">
- <form string="Portal User" version="7.0">
- <group colspan="2" col="2">
- <field name="name"/>
- <field name="email"/>
- <field name="lang"/>
- <field name="partner_id"/>
- </group>
- </form>
- </field>
- </record>
</data>
</openerp>
diff --git a/addons/portal/wizard/share_wizard.py b/addons/portal/wizard/share_wizard.py
index ca950a61b08..b1b6e980dec 100644
--- a/addons/portal/wizard/share_wizard.py
+++ b/addons/portal/wizard/share_wizard.py
@@ -44,9 +44,6 @@ class share_wizard_portal(osv.TransientModel):
'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]),
}
- def is_portal_manager(self, cr, uid, context=None):
- return self.has_group(cr, uid, module='portal', group_xml_id='group_portal_manager', context=context)
-
def _check_preconditions(self, cr, uid, wizard_data, context=None):
if wizard_data.user_type == 'existing':
self._assert(wizard_data.user_ids,
@@ -122,16 +119,14 @@ class share_wizard_portal(osv.TransientModel):
# alter the rules of the groups so they can see the shared data
if wizard_data.group_ids:
# get the list of portals and the related groups to install their menus.
- Portals = self.pool.get('res.portal')
- all_portals = Portals.browse(cr, UID_ROOT, Portals.search(cr, UID_ROOT, [])) #no context!
- all_portal_group_ids = [p.group_id.id for p in all_portals]
+ res_groups = self.pool.get('res.groups')
+ all_portal_group_ids = res_groups.search(cr, UID_ROOT, [('is_portal', '=', True)])
# populate result lines with the users of each group and
# setup the menu for portal groups
for group in wizard_data.group_ids:
if group.id in all_portal_group_ids:
- portal = all_portals[all_portal_group_ids.index(group.id)]
- self._create_shared_data_menu(cr, uid, wizard_data, portal, context=context)
+ self._create_shared_data_menu(cr, uid, wizard_data, group.id, context=context)
for user in group.users:
new_line = {'user_id': user.id,
diff --git a/addons/portal/wizard/share_wizard_view.xml b/addons/portal/wizard/share_wizard_view.xml
index 72ae857eaaf..065a7aa317e 100644
--- a/addons/portal/wizard/share_wizard_view.xml
+++ b/addons/portal/wizard/share_wizard_view.xml
@@ -36,12 +36,12 @@
<field name="inherit_id" ref="share.share_step2_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='result_line_ids']//field[@name='login']" position="after">
- <field name="share_url" groups="portal.group_portal_manager"/>
+ <field name="share_url" groups="base.group_no_one"/>
</xpath>
<xpath expr="//field[@name='result_line_ids']" position="after">
<newline/>
- <group string="Details">
- <field name="share_root_url" groups="portal.group_portal_manager"/>
+ <group string="Details" groups="base.group_no_one">
+ <field name="share_root_url"/>
</group>
</xpath>
</field>
diff --git a/addons/portal_claim/security/ir.model.access.csv b/addons/portal_claim/security/ir.model.access.csv
index 554c66cc998..ab2a2f66770 100644
--- a/addons/portal_claim/security/ir.model.access.csv
+++ b/addons/portal_claim/security/ir.model.access.csv
@@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal_member,1,0,0,0
-access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal_member,1,0,0,0
+access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal,1,0,0,0
+access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal,1,0,0,0
diff --git a/addons/portal_claim/security/portal_security.xml b/addons/portal_claim/security/portal_security.xml
index e902bd043ad..9fc47c4cfb0 100644
--- a/addons/portal_claim/security/portal_security.xml
+++ b/addons/portal_claim/security/portal_security.xml
@@ -6,7 +6,7 @@
<field name="name">Portal Personal Claims</field>
<field ref="crm_claim.model_crm_claim" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
</data>
diff --git a/addons/portal_event/security/ir.model.access.csv b/addons/portal_event/security/ir.model.access.csv
index b418acbb9c4..7418b08bb4b 100644
--- a/addons/portal_event/security/ir.model.access.csv
+++ b/addons/portal_event/security/ir.model.access.csv
@@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_event,event,event.model_event_event,portal.group_portal_member,1,0,0,0
-access_registration,registration,event.model_event_registration,portal.group_portal_member,1,0,0,0
+access_event,event,event.model_event_event,portal.group_portal,1,0,0,0
+access_registration,registration,event.model_event_registration,portal.group_portal,1,0,0,0
diff --git a/addons/portal_event/security/portal_security.xml b/addons/portal_event/security/portal_security.xml
index 6a3ed0ac786..74b2372c147 100644
--- a/addons/portal_event/security/portal_security.xml
+++ b/addons/portal_event/security/portal_security.xml
@@ -6,14 +6,14 @@
<field name="name">Portal Visible Events</field>
<field ref="event.model_event_event" name="model_id"/>
<field name="domain_force">[('visibility', '=', 'public')]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_registration_rule" model="ir.rule">
<field name="name">Portal Personal Registrations</field>
<field ref="event.model_event_registration" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
</data>
diff --git a/addons/portal_hr_employees/security/ir.model.access.csv b/addons/portal_hr_employees/security/ir.model.access.csv
index 6131f49d749..d18aeb90e1c 100644
--- a/addons/portal_hr_employees/security/ir.model.access.csv
+++ b/addons/portal_hr_employees/security/ir.model.access.csv
@@ -1,6 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal_member,1,0,0,0
-access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0
-access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal_member,1,0,0,0
-access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0
-access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal_member,1,0,0,0
+access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal,1,0,0,0
+access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0
+access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal,1,0,0,0
+access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal,1,0,0,0
+access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal,1,0,0,0
diff --git a/addons/portal_project/security/ir.model.access.csv b/addons/portal_project/security/ir.model.access.csv
index dceca5ba8bb..85463868ee1 100644
--- a/addons/portal_project/security/ir.model.access.csv
+++ b/addons/portal_project/security/ir.model.access.csv
@@ -1,5 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_task,tasks,project.model_project_task,portal.group_portal_member,1,0,0,0
-access_task_type,task_type,project.model_project_task_type,portal.group_portal_member,1,0,0,0
-access_task_work,task_work,project.model_project_task_work,portal.group_portal_member,1,0,0,0
-access_project_category,project_category,project.model_project_category,portal.group_portal_member,1,0,0,0
+access_task,tasks,project.model_project_task,portal.group_portal,1,0,0,0
+access_task_type,task_type,project.model_project_task_type,portal.group_portal,1,0,0,0
+access_task_work,task_work,project.model_project_task_work,portal.group_portal,1,0,0,0
+access_project_category,project_category,project.model_project_category,portal.group_portal,1,0,0,0
diff --git a/addons/portal_project/security/portal_security.xml b/addons/portal_project/security/portal_security.xml
index b995c79bbbc..b9d37cec099 100644
--- a/addons/portal_project/security/portal_security.xml
+++ b/addons/portal_project/security/portal_security.xml
@@ -6,7 +6,7 @@
<field name="name">Portal Personal Task</field>
<field ref="project.model_project_task" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
</data>
diff --git a/addons/portal_project_issue/security/ir.model.access.csv b/addons/portal_project_issue/security/ir.model.access.csv
index 5257f9b6d02..80a38366b51 100644
--- a/addons/portal_project_issue/security/ir.model.access.csv
+++ b/addons/portal_project_issue/security/ir.model.access.csv
@@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_issues,project_issue,project_issue.model_project_issue,portal.group_portal_member,1,0,0,0
-access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal_member,1,0,0,0
+access_issues,project_issue,project_issue.model_project_issue,portal.group_portal,1,0,0,0
+access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal,1,0,0,0
diff --git a/addons/portal_project_issue/security/portal_security.xml b/addons/portal_project_issue/security/portal_security.xml
index 4ef8da5e4b6..358b5e6a0ad 100644
--- a/addons/portal_project_issue/security/portal_security.xml
+++ b/addons/portal_project_issue/security/portal_security.xml
@@ -6,7 +6,7 @@
<field name="name">Portal Personal Issues</field>
<field ref="project_issue.model_project_issue" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
</data>
diff --git a/addons/portal_sale/security/ir.model.access.csv b/addons/portal_sale/security/ir.model.access.csv
index 32266499af7..751c0b9baff 100644
--- a/addons/portal_sale/security/ir.model.access.csv
+++ b/addons/portal_sale/security/ir.model.access.csv
@@ -1,33 +1,33 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_sale_order,sale.order,sale.model_sale_order,portal.group_portal_member,1,0,0,0
-access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal_member,1,0,0,0
-access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal_member,1,0,0,0
-access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal_member,1,0,0,0
-access_stock_move,stock.move,stock.model_stock_move,portal.group_portal_member,1,0,0,0
-access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal_member,1,0,0,0
-access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal_member,1,0,0,0
-access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal_member,1,0,0,0
-access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal_member,1,0,0,0
-access_account_journal,account.journal,account.model_account_journal,portal.group_portal_member,1,0,0,0
-access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal_member,1,0,0,0
-access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal_member,1,0,0,0
-access_account_move,account.move,account.model_account_move,portal.group_portal_member,1,0,0,0
-access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal_member,1,0,0,0
-access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal_member,1,0,0,0
-access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal_member,1,0,0,0
-access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal_member,1,0,0,0
-access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal_member,1,0,0,0
-access_product,product.product,product.model_product_product,portal.group_portal_member,1,0,0,0
-access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0
-access_product_uom,product.uom,product.model_product_uom,portal.group_portal_member,1,0,0,0
-access_account_tax,account.tax,account.model_account_tax,portal.group_portal_member,1,0,0,0
-access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal_member,1,0,0,0
-access_product_template,product.template,product.model_product_template,portal.group_portal_member,1,0,0,0
-access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal_member,1,0,0,0
-access_stock_location,stock.location,stock.model_stock_location,portal.group_portal_member,1,0,0,0
-access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal_member,1,0,0,0
-access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0
-access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal_member,1,0,0,0
-access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal_member,1,0,0,0
-access_account_period,account.period,account.model_account_period,portal.group_portal_member,1,0,0,0
-access_account_account,account.account,account.model_account_account,portal.group_portal_member,1,0,0,0
+access_sale_order,sale.order,sale.model_sale_order,portal.group_portal,1,0,0,0
+access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal,1,0,0,0
+access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal,1,0,0,0
+access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal,1,0,0,0
+access_stock_move,stock.move,stock.model_stock_move,portal.group_portal,1,0,0,0
+access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal,1,0,0,0
+access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal,1,0,0,0
+access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal,1,0,0,0
+access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal,1,0,0,0
+access_account_journal,account.journal,account.model_account_journal,portal.group_portal,1,0,0,0
+access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal,1,0,0,0
+access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal,1,0,0,0
+access_account_move,account.move,account.model_account_move,portal.group_portal,1,0,0,0
+access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal,1,0,0,0
+access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal,1,0,0,0
+access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal,1,0,0,0
+access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal,1,0,0,0
+access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal,1,0,0,0
+access_product,product.product,product.model_product_product,portal.group_portal,1,0,0,0
+access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0
+access_product_uom,product.uom,product.model_product_uom,portal.group_portal,1,0,0,0
+access_account_tax,account.tax,account.model_account_tax,portal.group_portal,1,0,0,0
+access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal,1,0,0,0
+access_product_template,product.template,product.model_product_template,portal.group_portal,1,0,0,0
+access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal,1,0,0,0
+access_stock_location,stock.location,stock.model_stock_location,portal.group_portal,1,0,0,0
+access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal,1,0,0,0
+access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal,1,0,0,0
+access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal,1,0,0,0
+access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal,1,0,0,0
+access_account_period,account.period,account.model_account_period,portal.group_portal,1,0,0,0
+access_account_account,account.account,account.model_account_account,portal.group_portal,1,0,0,0
diff --git a/addons/portal_sale/security/portal_security.xml b/addons/portal_sale/security/portal_security.xml
index f69fd283db6..8028d5360c4 100644
--- a/addons/portal_sale/security/portal_security.xml
+++ b/addons/portal_sale/security/portal_security.xml
@@ -7,42 +7,42 @@
<field name="name">Portal Personal Quotations/Sales Orders</field>
<field ref="sale.model_sale_order" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_stock_picking_user_rule" model="ir.rule">
<field name="name">Portal Personal Delivery Orders</field>
<field ref="stock.model_stock_picking" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',[user.partner_id.id])]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_stock_picking_user_rule" model="ir.rule">
<field name="name">Portal Personal Delivery Orders Out</field>
<field ref="stock.model_stock_picking_out" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',[user.partner_id.id])]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_account_invoice_user_rule" model="ir.rule">
<field name="name">Portal Personal Account Invoices</field>
<field ref="account.model_account_invoice" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_personal_payment" model="ir.rule">
<field name="name">Portal Personal Payments</field>
<field ref="account_voucher.model_account_voucher" name="model_id"/>
<field name="domain_force">[('partner_id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
<record id="portal_personal_contact" model="ir.rule">
<field name="name">Portal Personal Contacts</field>
<field ref="base.model_res_partner" name="model_id"/>
<field name="domain_force">[('id','child_of',user.partner_id.id)]</field>
- <field name="groups" eval="[(4, ref('portal.group_portal_member'))]"/>
+ <field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
</record>
</data>
diff --git a/addons/share/res_users_view.xml b/addons/share/res_users_view.xml
index 9a657ffdbb6..cd9f7ad4f4c 100644
--- a/addons/share/res_users_view.xml
+++ b/addons/share/res_users_view.xml
@@ -25,13 +25,13 @@
<record model="ir.ui.view" id="res_groups_search_sharing">
<field name="name">res.groups.search.share</field>
<field name="model">res.groups</field>
- <field name="priority" eval="8"/>
+ <field name="inherit_id" ref="base.view_groups_search"/>
<field name="arch" type="xml">
- <search string="Groups">
- <field name="name" string="Group"/>
- <field name="share"/>
- <filter name="no_share" string="Regular groups only (no share groups)" icon="terp-partner" domain="[('share','=',False)]"/>
- </search>
+ <field name="name" position="after">
+ <filter name="share" string="Share Groups" domain="[('share','=',True)]"/>
+ <filter name="no_share" string="Non-Share Groups" domain="[('share','=',False)]"/>
+ <separator orientation="vertical"/>
+ </field>
</field>
</record>