[FIX] website, website_sale: correctly set company_id on address

During checkout, the user can create a new billing (only for public user as it
will create a 'normal' `res.partner`), a new shipping, edit its billing (that
will edit himself) or edit its shipping address.

All those cases will go through the exact same methods, public user and logged
in user included.

This previously led to multiple issues and multiple fixes to correctly set
`company_id` and `website_id` on the address (res.partner).

See 44372471ef that fixed the `website_id` part.

See 3a0f05f33 that fixed the multi-company behavior, but needed 2ba71140 to not
modify the company of an already created partner, but was still incomplete as
after that fix a logged in user would still have the admin (sudo) company
instead of the website one as supposed.

This commit will fix that bug and add some tests for all mentionned issues.

Related to #28853 as we want to backport the mentionned commit but needed to be
fix first.

closes odoo/odoo#34596

Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
Romain Derie
2019-07-04 13:58:23 +00:00
parent 1c57d5edcf
commit 789aa140b9
3 changed files with 106 additions and 17 deletions
+3
View File
@@ -47,6 +47,9 @@ class MockRequest(object):
},
'redirect': werkzeug.utils.redirect,
'session': {
'geoip': {
'country_code': kw.get('country_code'),
},
'sale_order_id': kw.get('sale_order_id'),
},
'website': kw.get('website'),
+1 -2
View File
@@ -609,8 +609,7 @@ class WebsiteSale(ProductConfiguratorController):
if request.website.specific_user_account:
new_values['website_id'] = request.website.id
if order.partner_id.id == request.website.user_id.sudo().partner_id.id:
# If the partner is public, we assign the company of the website
if mode[0] == 'new':
new_values['company_id'] = request.website.company_id.id
lang = request.lang if request.lang in request.website.mapped('language_ids.code') else None
+102 -15
View File
@@ -3,6 +3,7 @@
import odoo.tests
from odoo import api
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo.addons.website.tools import MockRequest
@@ -21,25 +22,111 @@ class TestUi(odoo.tests.HttpCase):
@odoo.tests.tagged('post_install', '-at_install')
class TestWebsiteSaleCheckoutAddress(odoo.tests.TransactionCase):
def test_01_edit_billing_address(self):
website = self.env['website'].browse(1)
p = self.env.user.partner_id
so = self.env['sale.order'].create({
'partner_id': p.id,
'website_id': website.id,
''' The goal of this method class is to test the address management on
the checkout (new/edit billing/shipping, company_id, website_id..).
'''
def setUp(self):
super(TestWebsiteSaleCheckoutAddress, self).setUp()
self.website = self.env['website'].browse(1)
self.country_id = self.env['res.country'].search([], limit=1).id
self.WebsiteSaleController = WebsiteSale()
self.default_address_values = {
'name': 'a res.partner address', 'email': 'email@email.email', 'street': 'ooo',
'city': 'ooo', 'country_id': self.country_id, 'submitted': 1,
}
def _create_so(self, partner_id=None):
return self.env['sale.order'].create({
'partner_id': partner_id,
'website_id': self.website.id,
'order_line': [(0, 0, {
'product_id': self.env['product.product'].create({'name': 'Product A', 'list_price': 100}).id,
'name': 'Product A',
})]
})
country_id = self.env['res.country'].search([], limit=1).id
WebsiteSaleController = WebsiteSale()
with MockRequest(self.env, website=website, sale_order_id=so.id):
WebsiteSaleController.address(name='website_sale test user', email='email@email.email', street='ooo', city='ooo', country_id=country_id, submitted=1, partner_id=p.id)
self.assertFalse(p.website_id, "Partner should not have a website set on him after editing billing.")
def _get_last_address(self, partner):
''' Useful to retrieve the last created shipping address '''
return partner.child_ids.sorted('id', reverse=True)[0]
website.specific_user_account = True
with MockRequest(self.env, website=website, sale_order_id=so.id):
WebsiteSaleController.address(name='website_sale test user', email='email@email.email', street='ooo', city='ooo', country_id=country_id, submitted=1, partner_id=p.id)
self.assertEqual(p.website_id, website, "Partner should have a website set on him after editing billing.")
# TEST WEBSITE
def test_01_create_shipping_address_specific_user_account(self):
''' Ensure `website_id` is correctly set (specific_user_account) '''
p = self.env.user.partner_id
so = self._create_so(p.id)
with MockRequest(self.env, website=self.website, sale_order_id=so.id):
self.WebsiteSaleController.address(**self.default_address_values)
self.assertFalse(self._get_last_address(p).website_id, "New shipping address should not have a website set on it (no specific_user_account).")
self.website.specific_user_account = True
self.WebsiteSaleController.address(**self.default_address_values)
self.assertEqual(self._get_last_address(p).website_id, self.website, "New shipping address should have a website set on it (specific_user_account).")
# TEST COMPANY
def _setUp_multicompany_env(self):
''' Have 2 companies A & B.
Have 1 website 1 which company is B
Have admin on company A
'''
self.company_a = self.env['res.company'].create({
'name': 'Company A',
})
self.company_b = self.env['res.company'].create({
'name': 'Company B',
})
self.company_c = self.env['res.company'].create({
'name': 'Company C',
})
self.website.company_id = self.company_b
self.env.user.company_id = self.company_a
self.demo_user = self.env.ref('base.user_demo')
self.demo_user.company_ids += self.company_c
self.demo_user.company_id = self.company_c
self.demo_partner = self.demo_user.partner_id
def test_02_demo_address_and_company(self):
''' This test ensure that the company_id of the address (partner) is
correctly set and also, is not wrongly changed.
eg: new shipping should use the company of the website and not the
one from the admin, and editing a billing should not change its
company.
'''
self._setUp_multicompany_env()
so = self._create_so(self.demo_partner.id)
env = api.Environment(self.env.cr, self.demo_user.id, {})
# change also website env for `sale_get_order` to not change order partner_id
with MockRequest(env, website=self.website.with_env(env), sale_order_id=so.id):
# 1. Logged in user, new shipping
self.WebsiteSaleController.address(**self.default_address_values)
new_shipping = self._get_last_address(self.demo_partner)
self.assertTrue(new_shipping.company_id != self.env.user.company_id, "Logged in user new shipping should not get the company of the sudo() neither the one from it's partner..")
self.assertEqual(new_shipping.company_id, self.website.company_id, ".. but the one from the website.")
# 2. Logged in user, edit billing
self.default_address_values['partner_id'] = self.demo_partner.id
self.WebsiteSaleController.address(**self.default_address_values)
self.assertEqual(self.demo_partner.company_id, self.company_c, "Logged in user edited billing (the partner itself) should not get its company modified.")
def test_03_public_user_address_and_company(self):
''' Same as test_02 but with public user '''
self._setUp_multicompany_env()
so = self._create_so(self.website.user_id.partner_id.id)
env = api.Environment(self.env.cr, self.website.user_id.id, {})
# change also website env for `sale_get_order` to not change order partner_id
with MockRequest(env, website=self.website.with_env(env), sale_order_id=so.id):
# 1. Public user, new billing
self.default_address_values['partner_id'] = -1
self.WebsiteSaleController.address(**self.default_address_values)
new_partner = so.partner_id
self.assertNotEqual(new_partner, self.website.user_id.partner_id, "New billing should have created a new partner and assign it on the SO")
self.assertEqual(new_partner.company_id, self.website.company_id, "The new partner should get the company of the website")
# 2. Public user, edit billing
self.default_address_values['partner_id'] = new_partner.id
self.WebsiteSaleController.address(**self.default_address_values)
self.assertEqual(new_partner.company_id, self.website.company_id, "Public user edited billing (the partner itself) should not get its company modified.")