diff --git a/product_assortment/__manifest__.py b/product_assortment/__manifest__.py
index ffa756fc72b0..60e89fee6f29 100644
--- a/product_assortment/__manifest__.py
+++ b/product_assortment/__manifest__.py
@@ -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).
{
@@ -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,
}
diff --git a/product_assortment/data/ir_cron.xml b/product_assortment/data/ir_cron.xml
new file mode 100644
index 000000000000..1315b9a1fca2
--- /dev/null
+++ b/product_assortment/data/ir_cron.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ Product assortment recompute all partbers
+
+
+ code
+ model.search([])._compute_all_partner_ids()
+
+
+
+
+
+ 1
+ days
+ -1
+
+
+
+
+
+
diff --git a/product_assortment/i18n/es.po b/product_assortment/i18n/es.po
index 41b22e69837d..1709e8e1e8eb 100644
--- a/product_assortment/i18n/es.po
+++ b/product_assortment/i18n/es.po
@@ -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 \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 \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
@@ -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
diff --git a/product_assortment/i18n/product_assortment.pot b/product_assortment/i18n/product_assortment.pot
index d4aa4a16f460..a2b0a2c23315 100644
--- a/product_assortment/i18n/product_assortment.pot
+++ b/product_assortment/i18n/product_assortment.pot
@@ -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
diff --git a/product_assortment/models/ir_filters.py b/product_assortment/models/ir_filters.py
index 2deb6d7b12ec..1d015e35c65b 100644
--- a/product_assortment/models/ir_filters.py
+++ b/product_assortment/models/ir_filters.py
@@ -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
@@ -74,6 +76,17 @@ def create(self, vals_list):
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()
+ for item in domain:
+ if isinstance(item, (list, tuple)) and isinstance(item[0], str):
+ field_set.add(item[0].split(".")[0])
+ return field_set
+
@api.depends("partner_ids", "partner_domain")
def _compute_all_partner_ids(self):
"""Summarize selected partners and partners from partner domain field"""
@@ -90,15 +103,6 @@ def _compute_all_partner_ids(self):
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,
@@ -107,6 +111,12 @@ def _get_eval_domain(self):
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):
@@ -144,6 +154,12 @@ def _get_action_domain(self, action_id=None):
return domain
+ def write(self, vals):
+ res = super().write(vals)
+ if "partner_ids" in vals or "partner_domain" in vals:
+ self.clear_caches()
+ return res
+
def show_products(self):
self.ensure_one()
xmlid = "product.product_normal_action_sell"
diff --git a/product_assortment/models/res_partner.py b/product_assortment/models/res_partner.py
index d1da9ea5e643..dd6721400cd9 100644
--- a/product_assortment/models/res_partner.py
+++ b/product_assortment/models/res_partner.py
@@ -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"
@@ -24,3 +32,30 @@ def action_define_product_assortment(self):
)
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 = []
+ 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)
+
+ @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()
+ return res