diff --git a/setup/shopinvader_search_engine_product_brand_tag/odoo/addons/shopinvader_search_engine_product_brand_tag b/setup/shopinvader_search_engine_product_brand_tag/odoo/addons/shopinvader_search_engine_product_brand_tag new file mode 120000 index 0000000000..995fa2fa2d --- /dev/null +++ b/setup/shopinvader_search_engine_product_brand_tag/odoo/addons/shopinvader_search_engine_product_brand_tag @@ -0,0 +1 @@ +../../../../shopinvader_search_engine_product_brand_tag \ No newline at end of file diff --git a/setup/shopinvader_search_engine_product_brand_tag/setup.py b/setup/shopinvader_search_engine_product_brand_tag/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/shopinvader_search_engine_product_brand_tag/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopinvader_search_engine/models/__init__.py b/shopinvader_search_engine/models/__init__.py index 3f9066f927..145fbeb211 100644 --- a/shopinvader_search_engine/models/__init__.py +++ b/shopinvader_search_engine/models/__init__.py @@ -3,3 +3,4 @@ from . import product_template from . import se_index from . import se_indexable_record +from . import se_product_update_mixin diff --git a/shopinvader_search_engine/models/product_product.py b/shopinvader_search_engine/models/product_product.py index ceed246879..a6e92267e6 100644 --- a/shopinvader_search_engine/models/product_product.py +++ b/shopinvader_search_engine/models/product_product.py @@ -17,3 +17,8 @@ def _get_shopinvader_product_variants(self, product_ids): @api.depends_context("index") def _compute_main_product(self): return super()._compute_main_product() + + def write(self, vals): + res = super(ProductProduct, self).write(vals) + self.shopinvader_mark_to_update() + return res diff --git a/shopinvader_search_engine/models/product_template.py b/shopinvader_search_engine/models/product_template.py index 71569264c4..285c29958e 100644 --- a/shopinvader_search_engine/models/product_template.py +++ b/shopinvader_search_engine/models/product_template.py @@ -23,3 +23,8 @@ def _get_parent_categories(self, categ_ids): @api.depends("categ_id", "categ_id.parent_id") def _compute_shopinvader_category(self): return super()._compute_shopinvader_category() + + def write(self, vals): + res = super(ProductTemplate, self).write(vals) + self.mapped("product_variant_ids").shopinvader_mark_to_update() + return res diff --git a/shopinvader_search_engine/models/se_indexable_record.py b/shopinvader_search_engine/models/se_indexable_record.py index 9d3a4a213d..7e3c9ee942 100644 --- a/shopinvader_search_engine/models/se_indexable_record.py +++ b/shopinvader_search_engine/models/se_indexable_record.py @@ -15,3 +15,6 @@ def _filter_by_index(self): lambda rec, index=index: index in rec.se_binding_ids.mapped("index_id") ) return records + + def shopinvader_mark_to_update(self): + self.sudo()._se_mark_to_update() diff --git a/shopinvader_search_engine/models/se_product_update_mixin.py b/shopinvader_search_engine/models/se_product_update_mixin.py new file mode 100644 index 0000000000..89d28b0bec --- /dev/null +++ b/shopinvader_search_engine/models/se_product_update_mixin.py @@ -0,0 +1,36 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import api, models + + +class SEProductUpdateMixin(models.AbstractModel): + _name = "se.product.update.mixin" + + @api.model + def create(self, values): + res = super(SEProductUpdateMixin, self).create(values) + res.get_products().shopinvader_mark_to_update() + return res + + def write(self, vals): + needs_update = self.needs_product_update(vals) + if needs_update: + products = self.get_products() + res = super(SEProductUpdateMixin, self).write(vals) + if needs_update: + (products | self.get_products()).shopinvader_mark_to_update() + return res + + def unlink(self): + products = self.get_products() + res = super(SEProductUpdateMixin, self).unlink() + products.shopinvader_mark_to_update() + return res + + def get_products(self): + raise NotImplementedError + + def needs_product_update(self, vals): + return True diff --git a/shopinvader_search_engine_image/models/__init__.py b/shopinvader_search_engine_image/models/__init__.py index 36858c277d..333ce012bd 100644 --- a/shopinvader_search_engine_image/models/__init__.py +++ b/shopinvader_search_engine_image/models/__init__.py @@ -1 +1,2 @@ +from . import fs_product_image from . import se_backend diff --git a/shopinvader_search_engine_image/models/fs_product_image.py b/shopinvader_search_engine_image/models/fs_product_image.py new file mode 100644 index 0000000000..c12bf4d8b4 --- /dev/null +++ b/shopinvader_search_engine_image/models/fs_product_image.py @@ -0,0 +1,26 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class FsProductImage(models.Model): + _name = "fs.product.image" + _inherit = ["fs.product.image", "se.product.update.mixin"] + + @api.model_create_multi + def create(self, vals_list): + res = super(FsProductImage, self).create(vals_list) + res.product_tmpl_id.shopinvader_mark_to_update() + return res + + def write(self, vals): + res = super(FsProductImage, self).write(vals) + self.mapped("product_tmpl_id").shopinvader_mark_to_update() + return res + + def unlink(self): + products = self.mapped("product_tmpl_id") + res = super(FsProductImage, self).unlink() + products.shopinvader_mark_to_update() + return res diff --git a/shopinvader_search_engine_product_brand/models/product_brand.py b/shopinvader_search_engine_product_brand/models/product_brand.py index 7ac0e4f7b4..ab82ad2aa9 100644 --- a/shopinvader_search_engine_product_brand/models/product_brand.py +++ b/shopinvader_search_engine_product_brand/models/product_brand.py @@ -7,3 +7,16 @@ class ProductBrand(models.Model): _name = "product.brand" _inherit = ["product.brand", "se.indexable.record"] + + def write(self, vals): + res = super(ProductBrand, self).write(vals) + self.shopinvader_mark_to_update() + return res + + def shopinvader_mark_to_update(self): + res = super(ProductBrand, self).shopinvader_mark_to_update() + self._shopinvader_mark_to_update_associated_products() + return res + + def _shopinvader_mark_to_update_associated_products(self): + self.product_ids.shopinvader_mark_to_update() diff --git a/shopinvader_search_engine_product_brand_image/__init__.py b/shopinvader_search_engine_product_brand_image/__init__.py index a51a83a6f8..106fc57265 100644 --- a/shopinvader_search_engine_product_brand_image/__init__.py +++ b/shopinvader_search_engine_product_brand_image/__init__.py @@ -1 +1,2 @@ +from . import models from . import schemas diff --git a/shopinvader_search_engine_product_brand_image/models/__init__.py b/shopinvader_search_engine_product_brand_image/models/__init__.py new file mode 100644 index 0000000000..d119b1d4b1 --- /dev/null +++ b/shopinvader_search_engine_product_brand_image/models/__init__.py @@ -0,0 +1 @@ +from . import fs_product_brand_image diff --git a/shopinvader_search_engine_product_brand_image/models/fs_product_brand_image.py b/shopinvader_search_engine_product_brand_image/models/fs_product_brand_image.py new file mode 100644 index 0000000000..e60194dab0 --- /dev/null +++ b/shopinvader_search_engine_product_brand_image/models/fs_product_brand_image.py @@ -0,0 +1,26 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class FsProductImage(models.Model): + _name = "fs.product.brand.image" + _inherit = ["fs.product.brand.image", "se.product.update.mixin"] + + @api.model_create_multi + def create(self, vals_list): + res = super(FsProductImage, self).create(vals_list) + res.product_tmpl_id.shopinvader_mark_to_update() + return res + + def write(self, vals): + res = super(FsProductImage, self).write(vals) + self.mapped("product_tmpl_id").shopinvader_mark_to_update() + return res + + def unlink(self): + products = self.mapped("product_tmpl_id") + res = super(FsProductImage, self).unlink() + products.shopinvader_mark_to_update() + return res diff --git a/shopinvader_search_engine_product_brand_tag/README.rst b/shopinvader_search_engine_product_brand_tag/README.rst new file mode 100644 index 0000000000..38929e8775 --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/README.rst @@ -0,0 +1,35 @@ +**This file is going to be generated by oca-gen-addon-readme.** + +*Manual changes will be overwritten.* + +Please provide content in the ``readme`` directory: + +* **DESCRIPTION.rst** (required) +* INSTALL.rst (optional) +* CONFIGURE.rst (optional) +* **USAGE.rst** (optional, highly recommended) +* DEVELOP.rst (optional) +* ROADMAP.rst (optional) +* HISTORY.rst (optional, recommended) +* **CONTRIBUTORS.rst** (optional, highly recommended) +* CREDITS.rst (optional) + +Content of this README will also be drawn from the addon manifest, +from keys such as name, authors, maintainers, development_status, +and license. + +A good, one sentence summary in the manifest is also highly recommended. + + +Automatic changelog generation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`HISTORY.rst` can be auto generated using `towncrier `_. + +Just put towncrier compatible changelog fragments into `readme/newsfragments` +and the changelog file will be automatically generated and updated when a new fragment is added. + +Please refer to `towncrier` documentation to know more. + +NOTE: the changelog will be automatically generated when using `/ocabot merge $option`. +If you need to run it manually, refer to `OCA/maintainer-tools README `_. diff --git a/shopinvader_search_engine_product_brand_tag/__init__.py b/shopinvader_search_engine_product_brand_tag/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/shopinvader_search_engine_product_brand_tag/__manifest__.py b/shopinvader_search_engine_product_brand_tag/__manifest__.py new file mode 100644 index 0000000000..381d017acb --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Shopinvader Seach Engine Product Brand Tag", + "summary": """ + Manage product brand tag info into search engines indexes""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV", + "website": "https://github.com/shopinvader/odoo-shopinvader", + "depends": [ + "shopinvader_search_engine_product_brand", + "shopinvader_product_brand_tag", + ], + "data": [], + "demo": [], +} diff --git a/shopinvader_search_engine_product_brand_tag/models/__init__.py b/shopinvader_search_engine_product_brand_tag/models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shopinvader_search_engine_product_brand_tag/models/product_brand_tag.py b/shopinvader_search_engine_product_brand_tag/models/product_brand_tag.py new file mode 100644 index 0000000000..2abee82db6 --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/models/product_brand_tag.py @@ -0,0 +1,14 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ProductBrandTag(models.Model): + _inherit = "product.brand.tag" + + def write(self, vals): + res = super(ProductBrandTag, self).write(vals) + if "name" in vals: + self.product_brand_ids.shopinvader_mark_to_update() + return res diff --git a/shopinvader_search_engine_product_brand_tag/readme/CONTEXT.md b/shopinvader_search_engine_product_brand_tag/readme/CONTEXT.md new file mode 100644 index 0000000000..7e73600f3d --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/readme/CONTEXT.md @@ -0,0 +1,7 @@ +When you manage tags on your products brand, you could want to export this information +with the information related to a product brand into search engine indexes. This +behavior could be achieved by using the module `shopinvader_product_brand_tag`. + +Nevertheless, when you update the tag name, the search engine index is not updated by +default. The purpose of this module is to update the impacted records into the search +engine indexes when a tag name is updated. diff --git a/shopinvader_search_engine_product_brand_tag/readme/CONTRIBUTORS.md b/shopinvader_search_engine_product_brand_tag/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..a15e3ef244 --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Laurent Mignon (https://www.acsone.eu) diff --git a/shopinvader_search_engine_product_brand_tag/readme/DESCRIPTION.md b/shopinvader_search_engine_product_brand_tag/readme/DESCRIPTION.md new file mode 100644 index 0000000000..d24c3b22bb --- /dev/null +++ b/shopinvader_search_engine_product_brand_tag/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module extends the functionality of `shopinvader_search_engine_product_brand` +module to ensure that when a tag name is updated, this change is applied into the search +engine indexes. diff --git a/shopinvader_search_engine_product_brand_tag/static/description/icon.png b/shopinvader_search_engine_product_brand_tag/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/shopinvader_search_engine_product_brand_tag/static/description/icon.png differ diff --git a/shopinvader_search_engine_product_media/models/__init__.py b/shopinvader_search_engine_product_media/models/__init__.py index 36858c277d..b9535158bb 100644 --- a/shopinvader_search_engine_product_media/models/__init__.py +++ b/shopinvader_search_engine_product_media/models/__init__.py @@ -1 +1,2 @@ +from . import fs_product_media from . import se_backend diff --git a/shopinvader_search_engine_product_media/models/fs_product_media.py b/shopinvader_search_engine_product_media/models/fs_product_media.py new file mode 100644 index 0000000000..78e25e1dd3 --- /dev/null +++ b/shopinvader_search_engine_product_media/models/fs_product_media.py @@ -0,0 +1,26 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class FsProductMedia(models.Model): + _name = "fs.product.media" + _inherit = ["fs.product.media", "se.product.update.mixin"] + + @api.model_create_multi + def create(self, vals_list): + res = super(FsProductMedia, self).create(vals_list) + res.product_tmpl_id.shopinvader_mark_to_update() + return res + + def write(self, vals): + res = super(FsProductMedia, self).write(vals) + self.mapped("product_tmpl_id").shopinvader_mark_to_update() + return res + + def unlink(self): + products = self.mapped("product_tmpl_id") + res = super(FsProductMedia, self).unlink() + products.shopinvader_mark_to_update() + return res