add website_membership_associate
This commit is contained in:
parent
40d7cc8772
commit
31d53c428c
12 changed files with 837 additions and 0 deletions
293
website_membership_associate/controllers/main.py
Normal file
293
website_membership_associate/controllers/main.py
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
# Copyright 2026 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, http
|
||||
from odoo.http import request
|
||||
from odoo.tools.translate import _
|
||||
|
||||
from odoo.addons.website_membership.controllers.main import (
|
||||
WebsiteMembership as BaseWebsiteMembership,
|
||||
)
|
||||
|
||||
|
||||
class WebsiteMembership(BaseWebsiteMembership):
|
||||
@http.route()
|
||||
def members(
|
||||
self, membership_id=None, country_name=None, country_id=0, page=1, **post
|
||||
):
|
||||
request.env = request.env(
|
||||
context=dict(request.env.context, include_associate_members=True)
|
||||
)
|
||||
response = super().members(
|
||||
membership_id=membership_id,
|
||||
country_name=country_name,
|
||||
country_id=country_id,
|
||||
page=page,
|
||||
**post,
|
||||
)
|
||||
self._add_associate_members(response, membership_id, country_id, page, post)
|
||||
return response
|
||||
|
||||
def _add_associate_members(
|
||||
self, response, membership_id, country_id, page, post
|
||||
):
|
||||
values = response.qcontext
|
||||
memberships_partner_ids = values.get("memberships_partner_ids", {})
|
||||
if not memberships_partner_ids:
|
||||
return
|
||||
|
||||
post_name = post.get("search") or post.get("name", "")
|
||||
host_keys = {}
|
||||
for key, ids in memberships_partner_ids.items():
|
||||
for partner_id in ids:
|
||||
host_keys.setdefault(partner_id, []).append(key)
|
||||
host_ids = set(host_keys.keys())
|
||||
hosts = {
|
||||
pid: partner
|
||||
for pid, partner in values.get("partners", {}).items()
|
||||
if pid in host_ids
|
||||
}
|
||||
|
||||
associates = (
|
||||
request.env["membership.membership_line"]
|
||||
.sudo()
|
||||
._get_associate_partners(
|
||||
tuple(host_ids), country_id=country_id, post_name=post_name
|
||||
)
|
||||
)
|
||||
|
||||
new_memberships_partner_ids = self._filter_displayed_hosts(
|
||||
memberships_partner_ids, hosts, country_id, post_name
|
||||
)
|
||||
for associate in associates:
|
||||
keys = host_keys.get(associate.associate_member.id)
|
||||
if not keys:
|
||||
continue
|
||||
for key in keys:
|
||||
if associate.id not in new_memberships_partner_ids[key]:
|
||||
new_memberships_partner_ids[key].append(associate.id)
|
||||
values["memberships_partner_ids"] = {
|
||||
key: ids
|
||||
for key, ids in new_memberships_partner_ids.items()
|
||||
if ids
|
||||
}
|
||||
|
||||
displayed_ids = set(
|
||||
pid
|
||||
for ids in values["memberships_partner_ids"].values()
|
||||
for pid in ids
|
||||
)
|
||||
values["partners"] = {
|
||||
p.id: p
|
||||
for p in request.env["res.partner"]
|
||||
.sudo()
|
||||
.browse(list(displayed_ids))
|
||||
}
|
||||
|
||||
all_host_ids, all_free_host_ids, all_associates = (
|
||||
self._get_all_visible_ids(membership_id, country_id, post_name)
|
||||
)
|
||||
self._recompute_countries(
|
||||
values, all_host_ids, all_free_host_ids, all_associates, country_id
|
||||
)
|
||||
self._update_google_map(values, country_id, post_name)
|
||||
self._update_pager(
|
||||
values,
|
||||
membership_id,
|
||||
country_id,
|
||||
page,
|
||||
post,
|
||||
all_host_ids,
|
||||
all_free_host_ids,
|
||||
)
|
||||
|
||||
def _filter_displayed_hosts(
|
||||
self, memberships_partner_ids, hosts, country_id, post_name
|
||||
):
|
||||
return {
|
||||
key: [
|
||||
pid
|
||||
for pid in ids
|
||||
if pid not in hosts
|
||||
or self._partner_matches_filters(hosts[pid], country_id, post_name)
|
||||
]
|
||||
for key, ids in memberships_partner_ids.items()
|
||||
}
|
||||
|
||||
def _partner_matches_filters(self, partner, country_id, post_name):
|
||||
if country_id and partner.country_id.id != country_id:
|
||||
return False
|
||||
if post_name and not self._partner_matches_search(partner, post_name):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _partner_matches_search(self, partner, post_name):
|
||||
term = post_name.lower()
|
||||
if term in (partner.name or "").lower():
|
||||
return True
|
||||
if term in (partner.website_description or "").lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_all_visible_ids(self, membership_id, country_id, post_name):
|
||||
free_selected = membership_id in (None, "free")
|
||||
if membership_id == "free":
|
||||
all_host_ids = set()
|
||||
else:
|
||||
all_host_ids = self._get_all_host_ids(
|
||||
membership_id, country_id, post_name
|
||||
)
|
||||
all_free_host_ids = (
|
||||
self._get_all_free_host_ids(country_id, post_name)
|
||||
if free_selected
|
||||
else set()
|
||||
)
|
||||
all_associates = (
|
||||
request.env["membership.membership_line"]
|
||||
.sudo()
|
||||
._get_associate_partners(
|
||||
tuple(all_host_ids | all_free_host_ids),
|
||||
country_id=country_id,
|
||||
post_name=post_name,
|
||||
)
|
||||
)
|
||||
return all_host_ids, all_free_host_ids, all_associates
|
||||
|
||||
def _get_all_host_ids(self, membership_id, country_id, post_name):
|
||||
Product = request.env["product.product"]
|
||||
MembershipLine = request.env["membership.membership_line"]
|
||||
today = fields.Date.today()
|
||||
products = Product.sudo().search([("membership", "=", True)])
|
||||
domain = [
|
||||
("partner.website_published", "=", True),
|
||||
("state", "=", "paid"),
|
||||
("date_to", ">=", today),
|
||||
("date_from", "<=", today),
|
||||
("membership_id", "in", products.ids),
|
||||
]
|
||||
if membership_id and membership_id != "free":
|
||||
domain.append(("membership_id", "=", int(membership_id)))
|
||||
if post_name:
|
||||
domain += [
|
||||
"|",
|
||||
("partner.name", "ilike", post_name),
|
||||
("partner.website_description", "ilike", post_name),
|
||||
]
|
||||
if country_id:
|
||||
domain.append(("partner.country_id", "=", country_id))
|
||||
lines = MembershipLine.sudo().search(domain)
|
||||
return set(lines.partner.ids)
|
||||
|
||||
def _get_all_free_host_ids(self, country_id, post_name):
|
||||
domain = [
|
||||
("membership_state", "=", "free"),
|
||||
("website_published", "=", True),
|
||||
]
|
||||
if post_name:
|
||||
domain += [
|
||||
"|",
|
||||
("name", "ilike", post_name),
|
||||
("website_description", "ilike", post_name),
|
||||
]
|
||||
if country_id:
|
||||
domain.append(("country_id", "=", country_id))
|
||||
return set(request.env["res.partner"].sudo().search(domain).ids)
|
||||
|
||||
def _recompute_countries(
|
||||
self, values, all_host_ids, all_free_host_ids, all_associates, country_id
|
||||
):
|
||||
visible_ids = all_host_ids | all_free_host_ids | set(all_associates.ids)
|
||||
values["countries"] = self._build_countries(visible_ids, country_id)
|
||||
|
||||
def _build_countries(self, visible_ids, country_id):
|
||||
Partner = request.env["res.partner"]
|
||||
Country = request.env["res.country"]
|
||||
current_country = None
|
||||
countries = Partner.sudo().read_group(
|
||||
[("id", "in", list(visible_ids))],
|
||||
["__count"],
|
||||
groupby="country_id",
|
||||
)
|
||||
countries_total = sum(
|
||||
country_dict["country_id_count"] for country_dict in countries
|
||||
)
|
||||
if country_id:
|
||||
current_country = Country.browse(country_id).read(["id", "name"])[0]
|
||||
if not any(
|
||||
x["country_id"] and x["country_id"][0] == country_id
|
||||
for x in countries
|
||||
):
|
||||
countries.append(
|
||||
{
|
||||
"country_id_count": 0,
|
||||
"country_id": (country_id, current_country["name"]),
|
||||
}
|
||||
)
|
||||
countries = [d for d in countries if d["country_id"]]
|
||||
countries.sort(key=lambda d: d["country_id"][1])
|
||||
countries.insert(
|
||||
0,
|
||||
{
|
||||
"country_id_count": countries_total,
|
||||
"country_id": (0, _("All Countries")),
|
||||
},
|
||||
)
|
||||
return countries
|
||||
|
||||
def _update_google_map(self, values, country_id, post_name):
|
||||
map_ids_str = values.get("google_map_partner_ids", "")
|
||||
if not map_ids_str:
|
||||
return
|
||||
map_ids = [int(pid) for pid in map_ids_str.split(",") if pid]
|
||||
if not map_ids:
|
||||
return
|
||||
partners = request.env["res.partner"].sudo().browse(map_ids)
|
||||
if country_id:
|
||||
partners = partners.filtered(
|
||||
lambda p: p.country_id.id == country_id
|
||||
)
|
||||
if post_name:
|
||||
partners = partners.filtered(
|
||||
lambda p: self._partner_matches_search(p, post_name)
|
||||
)
|
||||
values["google_map_partner_ids"] = ",".join(
|
||||
str(pid) for pid in partners.ids
|
||||
)
|
||||
|
||||
def _update_pager(
|
||||
self,
|
||||
values,
|
||||
membership_id,
|
||||
country_id,
|
||||
page,
|
||||
post,
|
||||
all_host_ids,
|
||||
all_free_host_ids,
|
||||
):
|
||||
post_name = post.get("search") or post.get("name", "")
|
||||
if membership_id == "free":
|
||||
displayed_host_ids = set()
|
||||
else:
|
||||
host_records = request.env["res.partner"].sudo().browse(
|
||||
list(all_host_ids)
|
||||
)
|
||||
displayed_host_ids = {
|
||||
host.id
|
||||
for host in host_records
|
||||
if self._partner_matches_filters(host, country_id, post_name)
|
||||
}
|
||||
count_members = len(displayed_host_ids) + len(all_free_host_ids)
|
||||
limit = self._references_per_page
|
||||
base_url = "/members%s%s" % (
|
||||
"/association/%s" % membership_id if membership_id else "",
|
||||
"/country/%s" % country_id if country_id else "",
|
||||
)
|
||||
values["pager"] = request.website.pager(
|
||||
url=base_url,
|
||||
total=count_members,
|
||||
page=page,
|
||||
step=limit,
|
||||
scope=7,
|
||||
url_args=post,
|
||||
)
|
||||
values["search_count"] = count_members
|
||||
Loading…
Add table
Add a link
Reference in a new issue