From b61f34f700f0383b67dd0b5ab701e4ddef1eaf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Sainl=C3=A9ger?= Date: Tue, 17 Mar 2026 17:29:42 +0100 Subject: [PATCH] [NEW] helpdesk_portal_ticket_list_defaults: create add-on this add-on comes from add-on helpdesk_portal_ticket_custom in v16.0 which has been refactorized. --- .../.gitignore | 2 + .../README.md | 64 +++++++ .../__init__.py | 3 + .../__manifest__.py | 20 +++ .../controllers/__init__.py | 3 + .../controllers/main.py | 165 ++++++++++++++++++ 6 files changed, 257 insertions(+) create mode 100644 helpdesk_portal_ticket_list_defaults/.gitignore create mode 100644 helpdesk_portal_ticket_list_defaults/README.md create mode 100644 helpdesk_portal_ticket_list_defaults/__init__.py create mode 100644 helpdesk_portal_ticket_list_defaults/__manifest__.py create mode 100644 helpdesk_portal_ticket_list_defaults/controllers/__init__.py create mode 100644 helpdesk_portal_ticket_list_defaults/controllers/main.py diff --git a/helpdesk_portal_ticket_list_defaults/.gitignore b/helpdesk_portal_ticket_list_defaults/.gitignore new file mode 100644 index 0000000..6da5887 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/.gitignore @@ -0,0 +1,2 @@ +*.*~ +*pyc diff --git a/helpdesk_portal_ticket_list_defaults/README.md b/helpdesk_portal_ticket_list_defaults/README.md new file mode 100644 index 0000000..07c50d0 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/README.md @@ -0,0 +1,64 @@ +==================================== +Helpdesk Portal Ticket List Defaults +==================================== + +Customize default filter, sort and groupby for the helpdesk portal ticket list. + +This module changes the default behavior of the ticket list in the portal: + +- **Default filter**: Shows only open tickets (instead of all tickets) +- **Default groupby**: Groups tickets by stage (instead of no grouping) +- **Default sort**: By date (unchanged, but now overridable) + +It also adds an "Open" filter option that wasn't available in the base module. + +# Extending + +Other modules can easily override the defaults by inheriting the controller +and overriding the dedicated methods: + +```python +from odoo.addons.helpdesk_portal_ticket_list_defaults.controllers.main import ( + CustomerPortalHelpdeskDefaults, +) + + +class MyCustomDefaults(CustomerPortalHelpdeskDefaults): + + def _ticket_get_default_filterby(self): + return "all" # Show all tickets by default + + def _ticket_get_default_groupby(self): + return "category" # Group by category instead of stage +``` + +# Installation + +Use Odoo normal module installation procedure to install +`helpdesk_portal_ticket_list_defaults`. + +# Known issues / Roadmap + +None yet. + +# Bug Tracker + +Bugs are tracked on `our issues website `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. + +# Credits + +## Contributors + +- Stéphan Sainléger + +## Funders + +The development of this module has been financially supported by: + +- Elabore (https://elabore.coop) + +## Maintainer + +This module is maintained by Elabore. diff --git a/helpdesk_portal_ticket_list_defaults/__init__.py b/helpdesk_portal_ticket_list_defaults/__init__.py new file mode 100644 index 0000000..bd07ce0 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import controllers diff --git a/helpdesk_portal_ticket_list_defaults/__manifest__.py b/helpdesk_portal_ticket_list_defaults/__manifest__.py new file mode 100644 index 0000000..f7a9047 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2024 Joris Scampucci (Elabore) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Helpdesk Portal Ticket List Defaults", + "version": "18.0.1.0.0", + "author": "Elabore", + "website": "https://elabore.coop", + "maintainer": "Joris Scampucci", + "license": "AGPL-3", + "category": "Helpdesk", + "summary": "Customize default filter, sort and groupby for portal ticket list.", + "depends": [ + "helpdesk_mgmt", + ], + "data": [], + "installable": True, + "auto_install": False, + "application": False, +} diff --git a/helpdesk_portal_ticket_list_defaults/controllers/__init__.py b/helpdesk_portal_ticket_list_defaults/controllers/__init__.py new file mode 100644 index 0000000..2a3e5d5 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/controllers/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import main diff --git a/helpdesk_portal_ticket_list_defaults/controllers/main.py b/helpdesk_portal_ticket_list_defaults/controllers/main.py new file mode 100644 index 0000000..7805747 --- /dev/null +++ b/helpdesk_portal_ticket_list_defaults/controllers/main.py @@ -0,0 +1,165 @@ +# Copyright 2024 Joris Scampucci (Elabore) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from collections import OrderedDict +from operator import itemgetter + +from odoo import _, http +from odoo.http import request +from odoo.osv.expression import AND +from odoo.tools import groupby as groupbyelem + +from odoo.addons.helpdesk_mgmt.controllers.myaccount import CustomerPortalHelpdesk +from odoo.addons.portal.controllers.portal import pager as portal_pager + + +class CustomerPortalHelpdeskDefaults(CustomerPortalHelpdesk): + """Customize default values for ticket list filters in portal.""" + + def _ticket_get_default_sortby(self): + """Return default sort field. Override to customize.""" + return "date" + + def _ticket_get_default_filterby(self): + """Return default filter key. Override to customize.""" + return "open" + + def _ticket_get_default_groupby(self): + """Return default groupby field. Override to customize.""" + return "stage" + + def _ticket_get_searchbar_filters(self): + """Return available filters for ticket list. + + Extends OCA filters with an 'open' filter. + Override to add more custom filters. + """ + filters = { + "all": {"label": _("All"), "domain": []}, + "open": {"label": _("Open"), "domain": [("closed", "=", False)]}, + } + # Add stage filters like OCA does + for stage in request.env["helpdesk.ticket.stage"].search([]): + filters[str(stage.id)] = { + "label": stage.name, + "domain": [("stage_id", "=", stage.id)], + } + return filters + + @http.route() + def portal_my_tickets( + self, + page=1, + date_begin=None, + date_end=None, + sortby=None, + filterby=None, + search=None, + search_in=None, + groupby=None, + **kw, + ): + HelpdeskTicket = request.env["helpdesk.ticket"] + if not HelpdeskTicket.has_access("read"): + return request.redirect("/my") + + values = self._prepare_portal_layout_values() + + searchbar_sortings = dict( + sorted( + self._ticket_get_searchbar_sortings().items(), + key=lambda item: item[1]["sequence"], + ) + ) + searchbar_filters = self._ticket_get_searchbar_filters() + searchbar_inputs = self._ticket_get_searchbar_inputs() + searchbar_groupby = self._ticket_get_searchbar_groupby() + + # Apply defaults + if not sortby: + sortby = self._ticket_get_default_sortby() + order = searchbar_sortings[sortby]["order"] + + if not filterby: + filterby = self._ticket_get_default_filterby() + domain = searchbar_filters.get(filterby, searchbar_filters.get("all"))["domain"] + + if not groupby: + groupby = self._ticket_get_default_groupby() + + if date_begin and date_end: + domain = domain + [ + ("create_date", ">", date_begin), + ("create_date", "<=", date_end), + ] + + if not search_in: + search_in = "all" + if search: + domain = domain + self._ticket_get_search_domain(search_in, search) + + domain = AND( + [ + domain, + request.env["ir.rule"]._compute_domain(HelpdeskTicket._name, "read"), + ] + ) + + ticket_count = HelpdeskTicket.search_count(domain) + pager = portal_pager( + url="/my/tickets", + url_args={ + "date_begin": date_begin, + "date_end": date_end, + "sortby": sortby, + "filterby": filterby, + "groupby": groupby, + "search": search, + "search_in": search_in, + }, + total=ticket_count, + page=page, + step=self._items_per_page, + ) + + order = self._ticket_get_order(order, groupby) + tickets = HelpdeskTicket.search( + domain, + order=order, + limit=self._items_per_page, + offset=pager["offset"], + ) + request.session["my_tickets_history"] = tickets.ids[:100] + + groupby_mapping = self._ticket_get_groupby_mapping() + group = groupby_mapping.get(groupby) + if group: + grouped_tickets = [ + request.env["helpdesk.ticket"].concat(*g) + for k, g in groupbyelem(tickets, itemgetter(group)) + ] + elif tickets: + grouped_tickets = [tickets] + else: + grouped_tickets = [] + + values.update( + { + "date": date_begin, + "date_end": date_end, + "grouped_tickets": grouped_tickets, + "page_name": "ticket", + "default_url": "/my/tickets", + "pager": pager, + "searchbar_sortings": searchbar_sortings, + "searchbar_groupby": searchbar_groupby, + "searchbar_inputs": searchbar_inputs, + "search_in": search_in, + "search": search, + "sortby": sortby, + "groupby": groupby, + "searchbar_filters": OrderedDict(sorted(searchbar_filters.items())), + "filterby": filterby, + } + ) + return request.render("helpdesk_mgmt.portal_my_tickets", values)