From 11911fe057f681bbf48f5ab17dc26323d2b4b231 Mon Sep 17 00:00:00 2001
From: Denis Ledoux <dle@odoo.com>
Date: Mon, 14 Dec 2015 18:35:30 +0100
Subject: [PATCH] [FIX] portal: portal access management for partners having
 users

When the partner already had a user,
checking `in_portal` of this partner and applying
the wizard raised the fact there was already a duplicated
user for this email, even if there wasn't.

This is because the system relied on the fact
the field `user_id` of the `portal.wizard.user`
was automatically filled with the partner user if
there was one, but it was not the case:
This `user_id` field is a simple many2one field,
not computed, and the assignation was done nowhere
when the partner already had a user.

The assignation should be done in the `onchange_portal_id` method
of the `portal.wizard` model, like the other fields
`partner_id`, `email` and `in_portal`,
but if we do it know, as the `user_id` field is not
in the view (not even in `invisible`), the
web client will ignore it even if returned by
this `onchange_portal_id` method. It was therefore pointless
to solve this issue by adding the correct `user_id`
in the `user_ids` returned by this onchange method.

We could add `user_id` in invisible in the view,
but existing databases with the current view
will not benefit of the bug fix without updating the according view.

This revision therefore replaces `wizard.user_id` by
`wizard.partner_ids.user_ids[0]` everywhere where it's needed to
know if the partner already has a user or not.

Besides, it takes care about the fact his user could
be disabled (`active` False).

opw-659339
---
 addons/portal/wizard/portal_wizard.py | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py
index a48d730ad030..670b563d99f9 100644
--- a/addons/portal/wizard/portal_wizard.py
+++ b/addons/portal/wizard/portal_wizard.py
@@ -94,8 +94,8 @@ class wizard_user(osv.osv_memory):
         error_emails = []
         error_user = []
         ctx = dict(context or {}, active_test=False)
-        for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context):
-            if wizard_user.in_portal and not wizard_user.user_id:
+        for wizard_user in self.browse(cr, SUPERUSER_ID, ids, ctx):
+            if wizard_user.in_portal and not wizard_user.partner_id.user_ids:
                 email = extract_email(wizard_user.email)
                 if not email:
                     error_empty.append(wizard_user.partner_id)
@@ -127,15 +127,19 @@ class wizard_user(osv.osv_memory):
         if error_msg:
             raise UserError( "\n\n".join(error_msg))
 
-        for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context):
+        for wizard_user in self.browse(cr, SUPERUSER_ID, ids, dict(context, active_test=False)):
             portal = wizard_user.wizard_id.portal_id
+            user = wizard_user.partner_id.user_ids and wizard_user.partner_id.user_ids[0] or False
             if wizard_user.partner_id.email != wizard_user.email:
                 wizard_user.partner_id.write({'email': wizard_user.email})
             if wizard_user.in_portal:
+                user_id = False
                 # create a user if necessary, and make sure it is in the portal group
-                if not wizard_user.user_id:
-                    user = self._create_user(cr, SUPERUSER_ID, wizard_user.id, context)
-                    wizard_user.write({'user_id': user})
+                if not user:
+                    user_id = self._create_user(cr, SUPERUSER_ID, wizard_user.id, context)
+                else:
+                    user_id = user.id
+                wizard_user.write({'user_id': user_id})
                 if (not wizard_user.user_id.active) or (portal not in wizard_user.user_id.groups_id):
                     wizard_user.user_id.write({'active': True, 'groups_id': [(4, portal.id)]})
                     # prepare for the signup process
@@ -144,12 +148,12 @@ class wizard_user(osv.osv_memory):
                 wizard_user.refresh()
             else:
                 # remove the user (if it exists) from the portal group
-                if wizard_user.user_id and (portal in wizard_user.user_id.groups_id):
+                if user and (portal in user.groups_id):
                     # if user belongs to portal only, deactivate it
-                    if len(wizard_user.user_id.groups_id) <= 1:
-                        wizard_user.user_id.write({'groups_id': [(3, portal.id)], 'active': False})
+                    if len(user.groups_id) <= 1:
+                        user.write({'groups_id': [(3, portal.id)], 'active': False})
                     else:
-                        wizard_user.user_id.write({'groups_id': [(3, portal.id)]})
+                        user.write({'groups_id': [(3, portal.id)]})
 
     def _create_user(self, cr, uid, ids, context=None):
         """ create a new user for wizard_user.partner_id
-- 
GitLab