Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[15.0][FIX] product_assortment: Product black_list_domain invalidates whitelist_product_ids. New cache methods to performance #1343

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion product_assortment/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 ACSONE SA/NV
# Copyright 2023 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
Expand All @@ -11,6 +12,10 @@
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/product-attribute",
"depends": ["base", "product"],
"data": ["views/product_assortment.xml", "views/res_partner_view.xml"],
"data": [
"data/ir_cron.xml",
"views/product_assortment.xml",
"views/res_partner_view.xml",
],
"installable": True,
}
33 changes: 33 additions & 0 deletions product_assortment/data/ir_cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<!-- Force to recompute all partners to take into account changes in related partner fields models.
P.E.: Domain includes tag_ids.name contains "**" and user changes tag name from tags view -->
<record
id="action_product_assortment_recompute_all_partners"
model="ir.actions.server"
>
<field name="name">Product assortment recompute all partbers</field>
<field name="model_id" ref="model_ir_filters" />
<field name="binding_model_id" ref="model_ir_filters" />
<field name="state">code</field>
<field name="code">model.search([])._compute_all_partner_ids()</field>
</record>

<!-- Cron to recompute all partners. (Not active by default). -->
<record id="ir_cron_product_assortment_recompute_all_partners" model="ir.cron">
carlosdauden marked this conversation as resolved.
Show resolved Hide resolved
<field
name="ir_actions_server_id"
ref="action_product_assortment_recompute_all_partners"
/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False" />
<field name="active" eval="False" />
<field
name="nextcall"
eval="(DateTime.now().replace(hour=3, minute=0, second=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"
/>
</record>

</odoo>
13 changes: 10 additions & 3 deletions product_assortment/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-19 05:53+0000\n"
"PO-Revision-Date: 2022-07-19 07:55+0200\n"
"Last-Translator: Sergio Teruel <sergio.teruel@tecnativa.com>\n"
"POT-Creation-Date: 2023-03-06 11:12+0000\n"
"PO-Revision-Date: 2023-03-06 12:14+0100\n"
"Last-Translator: Carlos Dauden <carlos.dauden@tecnativa.com>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
Expand Down Expand Up @@ -109,6 +109,13 @@ msgstr "Surtido de producto"
msgid "Product assortment"
msgstr "Surtido de producto"

#. module: product_assortment
#: model:ir.actions.server,name:product_assortment.action_product_assortment_invalidate_cache
#: model:ir.cron,cron_name:product_assortment.ir_cron_product_assortment_invalidate_cache
#: model:ir.cron,name:product_assortment.ir_cron_product_assortment_invalidate_cache
msgid "Product assortment reset cache"
msgstr "Resetear cache de surtido de producto"

#. module: product_assortment
#: code:addons/product_assortment/models/ir_filters.py:0
#, python-format
Expand Down
7 changes: 7 additions & 0 deletions product_assortment/i18n/product_assortment.pot
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ msgstr ""
msgid "Product assortment"
msgstr ""

#. module: product_assortment
#: model:ir.actions.server,name:product_assortment.action_product_assortment_invalidate_cache
#: model:ir.cron,cron_name:product_assortment.ir_cron_product_assortment_invalidate_cache
#: model:ir.cron,name:product_assortment.ir_cron_product_assortment_invalidate_cache
msgid "Product assortment reset cache"
msgstr ""

#. module: product_assortment
#: code:addons/product_assortment/models/ir_filters.py:0
#, python-format
Expand Down
34 changes: 25 additions & 9 deletions product_assortment/models/ir_filters.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright 2021 ACSONE SA/NV
# Copyright 2023 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.osv import expression
from odoo.tools import ormcache
from odoo.tools.safe_eval import datetime, safe_eval


Expand Down Expand Up @@ -74,6 +76,17 @@
string="Restricted product domain", default="[]", required=True
)

@api.model
@ormcache()
def get_partner_domain_fields(self):
field_set = set()
for ir_filter in self.sudo().search([("is_assortment", "=", True)]):
domain = ir_filter._get_eval_partner_domain()

Check warning on line 84 in product_assortment/models/ir_filters.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/ir_filters.py#L84

Added line #L84 was not covered by tests
for item in domain:
if isinstance(item, (list, tuple)) and isinstance(item[0], str):
field_set.add(item[0].split(".")[0])

Check warning on line 87 in product_assortment/models/ir_filters.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/ir_filters.py#L87

Added line #L87 was not covered by tests
return field_set

@api.depends("partner_ids", "partner_domain")
def _compute_all_partner_ids(self):
"""Summarize selected partners and partners from partner domain field"""
Expand All @@ -90,15 +103,6 @@

def _get_eval_domain(self):
res = super()._get_eval_domain()

if self.whitelist_product_ids:
result_domain = [("id", "in", self.whitelist_product_ids.ids)]
res = expression.OR([result_domain, res])

if self.blacklist_product_ids:
result_domain = [("id", "not in", self.blacklist_product_ids.ids)]
res = expression.AND([result_domain, res])

if self.apply_black_list_product_domain:
black_list_domain = safe_eval(
self.black_list_product_domain,
Expand All @@ -107,6 +111,12 @@
res = expression.AND(
[expression.distribute_not(["!"] + black_list_domain), res]
)
if self.whitelist_product_ids:
result_domain = [("id", "in", self.whitelist_product_ids.ids)]
res = expression.OR([result_domain, res])
if self.blacklist_product_ids:
result_domain = [("id", "not in", self.blacklist_product_ids.ids)]
res = expression.AND([result_domain, res])
return res

def _get_eval_black_list_domain(self):
Expand Down Expand Up @@ -144,6 +154,12 @@

return domain

def write(self, vals):
res = super().write(vals)
if "partner_ids" in vals or "partner_domain" in vals:
self.clear_caches()

Check warning on line 160 in product_assortment/models/ir_filters.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/ir_filters.py#L160

Added line #L160 was not covered by tests
return res

def show_products(self):
self.ensure_one()
xmlid = "product.product_normal_action_sell"
Expand Down
37 changes: 36 additions & 1 deletion product_assortment/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# Copyright 2021 Tecnativa - Carlos Roca
# Copyright 2021 Tecnativa - Carlos Dauden
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
from odoo import models
from odoo import api, fields, models


class ResPartner(models.Model):
_inherit = "res.partner"

applied_assortment_ids = fields.Many2many(
comodel_name="ir.filters",
relation="ir_filter_all_partner_rel",
column1="partner_id",
column2="filter_id",
)

def action_define_product_assortment(self):
self.ensure_one()
xmlid = "product_assortment.actions_product_assortment_view"
Expand All @@ -24,3 +32,30 @@
)
action["context"] = ctx
return action

def _update_partner_assortments(self):
# Using sudo to contemplate evaluation of domains with restricted fields
self = self.sudo()
assortments = self.env["ir.filters"].search([("is_assortment", "=", True)])
for partner in self:
# Use ids instead of record to improve performance (Remove in next versions)
partner_assortment_ids = []

Check warning on line 42 in product_assortment/models/res_partner.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/res_partner.py#L42

Added line #L42 was not covered by tests
for assortment in assortments:
if partner in assortment.partner_ids or partner.filtered_domain(
assortment._get_eval_partner_domain()
):
partner_assortment_ids.append(assortment.id)
partner.applied_assortment_ids = assortments.browse(partner_assortment_ids)

Check warning on line 48 in product_assortment/models/res_partner.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/res_partner.py#L47-L48

Added lines #L47 - L48 were not covered by tests

@api.model_create_multi
def create(self, vals_list):
partners = super().create(vals_list)
self._update_partner_assortments()
return partners

def write(self, vals):
res = super().write(vals)
IrFilters = self.env["ir.filters"]
if IrFilters.get_partner_domain_fields() & set(vals.keys()):
self._update_partner_assortments()

Check warning on line 60 in product_assortment/models/res_partner.py

View check run for this annotation

Codecov / codecov/patch

product_assortment/models/res_partner.py#L60

Added line #L60 was not covered by tests
return res
Loading