diff --git a/public_category_product_count/README.rst b/public_category_product_count/README.rst new file mode 100644 index 00000000..b7f533ed --- /dev/null +++ b/public_category_product_count/README.rst @@ -0,0 +1,28 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=========================== +Contact Payment Mode Import +=========================== + +Displays the number of products per category in the eCommerce + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, +please check there if your issue has already been reported. If you spotted +it first, help us smash it by providing detailed and welcomed feedback. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Contributors +------------ + +* Eñaut Alberdi +* Ana Juaristi diff --git a/public_category_product_count/__init__.py b/public_category_product_count/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/public_category_product_count/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/public_category_product_count/__manifest__.py b/public_category_product_count/__manifest__.py new file mode 100644 index 00000000..619dc0d7 --- /dev/null +++ b/public_category_product_count/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2025 Eñaut Alberdi Korta - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + "name": "Public Category Product Count", + "version": "18.0.1.0.2", + "summary": """Displays the number of products + per public category in the eCommerce backend""", + "author": "AvanzOsc", + "website": "https://github.com/avanzosc/sale-addons", + "category": "Website/Website", + "depends": ["website_sale"], + "data": [ + "views/product_public_category_views.xml", + ], + "installable": True, + "application": False, + "license": "AGPL-3", +} diff --git a/public_category_product_count/i18n/es.po b/public_category_product_count/i18n/es.po new file mode 100644 index 00000000..afcf344e --- /dev/null +++ b/public_category_product_count/i18n/es.po @@ -0,0 +1,31 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * public_category_product_count +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-10-27 14:40+0000\n" +"PO-Revision-Date: 2025-10-27 14:40+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: public_category_product_count +#: model:ir.model.fields,field_description:public_category_product_count.field_product_public_category__product_count +msgid "Number of Products" +msgstr "Numero de productos" + +#. module: public_category_product_count +#: model_terms:ir.ui.view,arch_db:public_category_product_count.view_product_public_category_form_inherit_smartbutton +msgid "Products" +msgstr "Productos" + +#. module: public_category_product_count +#: model:ir.model,name:public_category_product_count.model_product_public_category +msgid "Website Product Category" +msgstr "Categoría de producto del sitio web" diff --git a/public_category_product_count/i18n/public_category_product_count.pot b/public_category_product_count/i18n/public_category_product_count.pot new file mode 100644 index 00000000..b5761839 --- /dev/null +++ b/public_category_product_count/i18n/public_category_product_count.pot @@ -0,0 +1,31 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * public_category_product_count +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-10-27 14:39+0000\n" +"PO-Revision-Date: 2025-10-27 14:39+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: public_category_product_count +#: model:ir.model.fields,field_description:public_category_product_count.field_product_public_category__product_count +msgid "Number of Products" +msgstr "" + +#. module: public_category_product_count +#: model_terms:ir.ui.view,arch_db:public_category_product_count.view_product_public_category_form_inherit_smartbutton +msgid "Products" +msgstr "" + +#. module: public_category_product_count +#: model:ir.model,name:public_category_product_count.model_product_public_category +msgid "Website Product Category" +msgstr "" diff --git a/public_category_product_count/models/__init__.py b/public_category_product_count/models/__init__.py new file mode 100644 index 00000000..0a91ef28 --- /dev/null +++ b/public_category_product_count/models/__init__.py @@ -0,0 +1 @@ +from . import product_public_category diff --git a/public_category_product_count/models/product_public_category.py b/public_category_product_count/models/product_public_category.py new file mode 100644 index 00000000..2567317e --- /dev/null +++ b/public_category_product_count/models/product_public_category.py @@ -0,0 +1,70 @@ +# Copyright 2025 Eñaut Alberdi Korta - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ProductPublicCategory(models.Model): + _inherit = "product.public.category" + + product_count = fields.Integer( + string="Number of Products", + compute="_compute_product_count", + store=False, + compute_sudo=True, + ) + + @api.depends_context("website_id") + def _compute_product_count(self): + Product = self.env["product.template"] + + if not self: + return + + category_ids = self.ids + + data = Product.read_group( + domain=[("public_categ_ids", "in", category_ids)], + fields=["public_categ_ids"], + groupby=["public_categ_ids"], + ) + + count_dict = { + entry["public_categ_ids"][0]: entry["public_categ_ids_count"] + for entry in data + if entry.get("public_categ_ids") + } + + for category in self: + category.product_count = count_dict.get(category.id, 0) + + def action_open_category_products(self): + self.ensure_one() + + product_action = self.env.ref( + "product.product_template_action", raise_if_not_found=False + ) + + action_vals = { + "type": "ir.actions.act_window", + "name": f"Products in {self.display_name}", + "res_model": "product.template", + "view_mode": "tree,form", + "target": "current", + "domain": [("public_categ_ids", "in", [self.id])], + "context": {"default_public_categ_ids": [self.id]}, + } + + if product_action: + base = product_action.read()[0] + action_vals.update( + {k: base[k] for k in base if k not in ["domain", "context"]} + ) + + action_vals["domain"] = [("public_categ_ids", "in", [self.id])] + return action_vals + + def action_recalculate_product_count(self): + for record in self: + record._compute_product_count() + return True diff --git a/public_category_product_count/pyproject.toml b/public_category_product_count/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/public_category_product_count/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/public_category_product_count/views/product_public_category_views.xml b/public_category_product_count/views/product_public_category_views.xml new file mode 100644 index 00000000..37344844 --- /dev/null +++ b/public_category_product_count/views/product_public_category_views.xml @@ -0,0 +1,49 @@ + + + + product.public.category.tree.inherit.count + product.public.category + + + + + + + + + + product.public.category.form.inherit.count + product.public.category + + + + + + + + + + product.public.category.form.smartbutton + product.public.category + + + +
+ +
+
+
+
+