[FIX] website_crm_partner_assign: reseller localization

Issue Description:
The partner() function previously inferred the country using GeoIP
when no specific country (nor "all_countries") was specified.
However, if there were no partners from the inferred country,
the render function would lead to a broken screen.

Resolution:
Implemented a fallback mechanism to treat the situation
as if no country was specified. This ensures that all partners are displayed
in such cases, preventing the occurrence of a broken screen.

[Reproducing bug]
- odoo 16.4 with: website, contacts, crm_enterprise_partner_assign
- Simulate GeoIP on the backend, so it points to some COUNTRY_A:
    - this can be achived by adding `country= country_obj.search([('name', 'ilike', 'mex')])`
    [below this line](https://github.com/odoo/odoo/blob/57d43aca2b07d3469a937890b7d5e5c4f29fe250/addons/website_crm_partner_assign/controllers/main.py#L237)
    - note: it doesn't matter which country you set it to, AS LONG AS COUNTRY_A != COUNTRY_B
- in CRM/Contacts:
   - create partner (set Partner Level and country to COUNTRY_B of the record )
   - Publish partner by "Go to website" -> Published
- go to url: ODOO_WEBSITE/partners
- BUG: No Partners are displayed

opw-3598110

closes odoo/odoo#148822

X-original-commit: cfca987efe83e6a6ba27779246a2d5da6b86dc7f
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Signed-off-by: Andrzej Pietrusiak (pian) <pian@odoo.com>
This commit is contained in:
Andrzej(pian)
2024-01-12 09:53:57 +00:00
parent 83f63df06b
commit 7ad5f2efbf
2 changed files with 53 additions and 9 deletions
@@ -230,11 +230,26 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
if search:
base_partner_domain += ['|', ('name', 'ilike', search), ('website_description', 'ilike', search)]
# group by grade
grade_domain = list(base_partner_domain)
# Infer Country
if not country and not country_all:
if request.geoip.country_code:
country = country_obj.search([('code', '=', request.geoip.country_code)], limit=1)
# Group by country
country_domain = list(base_partner_domain)
if grade:
country_domain += [('grade_id', '=', grade.id)]
countries = partner_obj.sudo().read_group(
country_domain, ["id", "country_id"],
groupby="country_id", orderby="country_id")
# Fallback: Show all partners when country has no associates.
country_ids = [c['country_id'][0] for c in countries]
if country and country.id not in country_ids:
country = None
# Group by grade
grade_domain = list(base_partner_domain)
if country:
grade_domain += [('country_id', '=', country.id)]
grades = partner_obj.sudo().read_group(
@@ -250,13 +265,6 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
'active': bool(grade is None),
})
# group by country
country_domain = list(base_partner_domain)
if grade:
country_domain += [('grade_id', '=', grade.id)]
countries = partner_obj.sudo().read_group(
country_domain, ["id", "country_id"],
groupby="country_id", orderby="country_id")
countries_partners = partner_obj.sudo().search_count(country_domain)
# flag active country
for country_dict in countries:
@@ -7,6 +7,8 @@ from odoo.exceptions import AccessError
from odoo.tests.common import TransactionCase
from odoo.addons.crm.tests.common import TestCrmCommon
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.website.tools import MockRequest
from odoo.addons.website_crm_partner_assign.controllers.main import WebsiteCrmPartnerAssign
class TestPartnerAssign(TransactionCase):
@@ -218,3 +220,37 @@ class TestPartnerLeadPortal(TestCrmCommon):
record_action = self.lead_portal._get_access_action(access_uid=self.user_portal.id)
self.assertEqual(record_action['url'], '/my/opportunity/%s' % self.lead_portal.id)
self.assertEqual(record_action['type'], 'ir.actions.act_url')
@patch('odoo.http.GeoIP')
def test_03_crm_partner_assign_geolocalization(self, GeoIpMock):
"""
This test checks situation when "{OdooURL}/partners" is visited from foreign country without resellers.
It uses Mexico as an example.
Why patching of GeoIP is used?
Tested function (WebsiteCrmPartnerAssign.partners) uses GeoIp.country_code which is read_only, because
of the property decorator https://docs.python.org/3/library/functions.html#property
Patching is allowing to modify normally read_only value.
"""
# Patch GeoIp so it acts, as if Odoo client is located in Mexico
GeoIpMock.return_value.country_code = 'MX'
# Create a partner outside of Mexico
non_mexican_partner = self.env['res.partner'].create({
'name': 'Non_Mexican_Partner',
'is_company': True,
'grade_id': self.env['res.partner.grade'].search([], limit=1).id,
'website_published': True,
'country_id': self.env['res.country'].search([('code', '!=', 'mx')], limit=1).id
})
def render_function(_, values, *args, **kwargs):
""" Tests values at the end of WebsiteCrmPartnerAssign.partners method."""
self.assertIn("partners", values, "Partner key is not present in the values, can't perform subsequent checks.")
self.assertIn(non_mexican_partner, values['partners'], "Non-Mexican Partner is not present when rendering partners from Mexico; fallback protection (protecting from no results) didn't work.")
return 'rendered'
with MockRequest(self.env, website=self.env['website'].browse(1)) as mock_request:
mock_request.render = render_function
res = WebsiteCrmPartnerAssign().partners()
self.assertEqual([b'rendered'], res.response, "render_function wasn't called")