[FIX] website_membership: perf, pagination
This fixes : * pagination only on /members and sometimes with bad page count, * free members could not be searched (were always all displayed), * all elements are displayed even if there is a pagination, * for members without country, errors happened in some use case, * when too much locations were on a map (>2000) it failed, * numbers of members by countries was not displayed for guest. And also as performance improvemnts: * only query all partners when the map is enabled (customize > left world map), * limit partners put on the map to 2000 (even then it's a lot for google maps), * don't browse all membership_line to get res_partner but use a query. opw-634653
This commit is contained in:
parent
68599dcd43
commit
5804246e0f
|
@ -27,7 +27,7 @@ class WebsiteMembership(http.Controller):
|
||||||
'/members/association/<membership_id>/country/<country_name>-<int:country_id>/page/<int:page>',
|
'/members/association/<membership_id>/country/<country_name>-<int:country_id>/page/<int:page>',
|
||||||
'/members/association/<membership_id>/country/<int:country_id>/page/<int:page>',
|
'/members/association/<membership_id>/country/<int:country_id>/page/<int:page>',
|
||||||
], type='http', auth="public", website=True)
|
], type='http', auth="public", website=True)
|
||||||
def members(self, membership_id=None, country_name=None, country_id=0, page=0, **post):
|
def members(self, membership_id=None, country_name=None, country_id=0, page=1, **post):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
product_obj = request.registry['product.product']
|
product_obj = request.registry['product.product']
|
||||||
country_obj = request.registry['res.country']
|
country_obj = request.registry['res.country']
|
||||||
|
@ -56,7 +56,7 @@ class WebsiteMembership(http.Controller):
|
||||||
membership_line_ids = []
|
membership_line_ids = []
|
||||||
country_domain = ('free_member', '=', True)
|
country_domain = ('free_member', '=', True)
|
||||||
countries = partner_obj.read_group(
|
countries = partner_obj.read_group(
|
||||||
cr, uid, [country_domain, ("website_published", "=", True)], ["id", "country_id"],
|
cr, SUPERUSER_ID, [country_domain, ("website_published", "=", True)], ["id", "country_id"],
|
||||||
groupby="country_id", orderby="country_id", context=request.context)
|
groupby="country_id", orderby="country_id", context=request.context)
|
||||||
countries_total = sum(country_dict['country_id_count'] for country_dict in countries)
|
countries_total = sum(country_dict['country_id_count'] for country_dict in countries)
|
||||||
|
|
||||||
|
@ -64,11 +64,12 @@ class WebsiteMembership(http.Controller):
|
||||||
if country_id:
|
if country_id:
|
||||||
line_domain.append(('partner.country_id', '=', country_id))
|
line_domain.append(('partner.country_id', '=', country_id))
|
||||||
current_country = country_obj.read(cr, uid, country_id, ['id', 'name'], context)
|
current_country = country_obj.read(cr, uid, country_id, ['id', 'name'], context)
|
||||||
if not any(x['country_id'][0] == country_id for x in countries):
|
if not any(x['country_id'][0] == country_id for x in countries if x['country_id']):
|
||||||
countries.append({
|
countries.append({
|
||||||
'country_id_count': 0,
|
'country_id_count': 0,
|
||||||
'country_id': (country_id, current_country["name"])
|
'country_id': (country_id, current_country["name"])
|
||||||
})
|
})
|
||||||
|
countries = filter(lambda d:d['country_id'], countries)
|
||||||
countries.sort(key=lambda d: d['country_id'][1])
|
countries.sort(key=lambda d: d['country_id'][1])
|
||||||
|
|
||||||
countries.insert(0, {
|
countries.insert(0, {
|
||||||
|
@ -82,15 +83,32 @@ class WebsiteMembership(http.Controller):
|
||||||
# make sure we don't access to lines with unpublished membershipts
|
# make sure we don't access to lines with unpublished membershipts
|
||||||
line_domain.append(('membership_id', 'in', membership_ids))
|
line_domain.append(('membership_id', 'in', membership_ids))
|
||||||
|
|
||||||
# displayed membership lines
|
limit = self._references_per_page
|
||||||
|
offset = limit * (page - 1)
|
||||||
|
|
||||||
|
count_members = 0
|
||||||
|
membership_line_ids = []
|
||||||
|
# displayed non-free membership lines
|
||||||
if membership_id != 'free':
|
if membership_id != 'free':
|
||||||
membership_line_ids = membership_line_obj.search(cr, SUPERUSER_ID, line_domain, context=context)
|
count_members = membership_line_obj.search_count(cr, SUPERUSER_ID, line_domain, context=context)
|
||||||
|
if offset <= count_members:
|
||||||
|
membership_line_ids = tuple(membership_line_obj.search(cr, SUPERUSER_ID, line_domain, offset, limit, context=context))
|
||||||
membership_lines = membership_line_obj.browse(cr, uid, membership_line_ids, context=context)
|
membership_lines = membership_line_obj.browse(cr, uid, membership_line_ids, context=context)
|
||||||
# TODO: Following line can be deleted in master. Kept for retrocompatibility.
|
# TODO: Following line can be deleted in master. Kept for retrocompatibility.
|
||||||
membership_lines = sorted(membership_lines, key=lambda x: x.membership_id.website_sequence)
|
membership_lines = sorted(membership_lines, key=lambda x: x.membership_id.website_sequence)
|
||||||
partner_ids = [m.partner.id for m in membership_lines]
|
page_partner_ids = set(m.partner.id for m in membership_lines)
|
||||||
free_partner_ids = partner_obj.search(cr, SUPERUSER_ID, [('free_member', '=', True), ('website_published', '=', True)], context=context)
|
|
||||||
google_map_partner_ids = ",".join(map(str, partner_ids))
|
google_map_partner_ids = []
|
||||||
|
if request.env.ref('website_membership.opt_index_google_map').customize_show:
|
||||||
|
membership_lines_ids = membership_line_obj.search(cr, uid, line_domain, context=context)
|
||||||
|
google_map_partner_ids = membership_line_obj.get_published_companies(cr, uid, membership_line_ids, limit=2000, context=context)
|
||||||
|
|
||||||
|
search_domain = [('free_member', '=', True), ('website_published', '=', True)]
|
||||||
|
if post_name:
|
||||||
|
search_domain += ['|', ('name', 'ilike', post_name), ('website_description', 'ilike', post_name)]
|
||||||
|
if country_id:
|
||||||
|
search_domain += [('country_id', '=', country_id)]
|
||||||
|
free_partner_ids = partner_obj.search(cr, SUPERUSER_ID, search_domain, context=context)
|
||||||
memberships_data = []
|
memberships_data = []
|
||||||
for membership_record in memberships:
|
for membership_record in memberships:
|
||||||
memberships_data.append({'id': membership_record.id, 'name': membership_record.name})
|
memberships_data.append({'id': membership_record.id, 'name': membership_record.name})
|
||||||
|
@ -100,12 +118,23 @@ class WebsiteMembership(http.Controller):
|
||||||
if free_partner_ids:
|
if free_partner_ids:
|
||||||
memberships_data.append({'id': 'free', 'name': _('Free Members')})
|
memberships_data.append({'id': 'free', 'name': _('Free Members')})
|
||||||
if not membership_id or membership_id == 'free':
|
if not membership_id or membership_id == 'free':
|
||||||
memberships_partner_ids['free'] = free_partner_ids
|
if count_members < offset + limit:
|
||||||
|
free_start = max(offset - count_members, 0)
|
||||||
|
free_end = max(offset + limit - count_members, 0)
|
||||||
|
memberships_partner_ids['free'] = free_partner_ids[free_start:free_end]
|
||||||
|
page_partner_ids |= set(memberships_partner_ids['free'])
|
||||||
|
google_map_partner_ids += free_partner_ids[:2000-len(google_map_partner_ids)]
|
||||||
|
count_members += len(free_partner_ids)
|
||||||
|
|
||||||
partners = dict((p.id, p) for p in partner_obj.browse(request.cr, SUPERUSER_ID, list(set(partner_ids + free_partner_ids)), request.context))
|
google_map_partner_ids = ",".join(map(str, google_map_partner_ids))
|
||||||
|
|
||||||
|
partners = { p.id: p for p in partner_obj.browse(request.cr, SUPERUSER_ID, list(page_partner_ids), request.context)}
|
||||||
|
|
||||||
|
base_url = '/members%s%s' % ('/association/%s' % membership_id if membership_id else '',
|
||||||
|
'/country/%s' % country_id if country_id else '')
|
||||||
|
|
||||||
# request pager for lines
|
# request pager for lines
|
||||||
pager = request.website.pager(url="/members", total=len(membership_line_ids), page=page, step=self._references_per_page, scope=7, url_args=post)
|
pager = request.website.pager(url=base_url, total=count_members, page=page, step=limit, scope=7, url_args=post)
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
'partners': partners,
|
'partners': partners,
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
import product
|
import product
|
||||||
|
import membership
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
class membership_membership_line(osv.Model):
|
||||||
|
_inherit = 'membership.membership_line'
|
||||||
|
|
||||||
|
def get_published_companies(self, cr, uid, ids, limit=None, context=None):
|
||||||
|
if not ids:
|
||||||
|
return []
|
||||||
|
limit_clause = '' if limit is None else ' LIMIT %d' % limit
|
||||||
|
cr.execute('SELECT DISTINCT p.id \
|
||||||
|
FROM res_partner p INNER JOIN membership_membership_line m \
|
||||||
|
ON p.id = m.partner \
|
||||||
|
WHERE website_published AND is_company AND m.id IN %s ' + limit_clause, (tuple(ids),))
|
||||||
|
return [partner_id[0] for partner_id in cr.fetchall()]
|
Loading…
Reference in New Issue