-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG][16.0] project_task_id_in_display_name
- Loading branch information
Showing
15 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Project Task ID In Display Name | ||
=============================== | ||
This module displays the ID of a task in its displayed name. | ||
|
||
Searching a task by its ID | ||
-------------------------- | ||
When searching a task in kanban view, you may enter its ID instead of its name. | ||
The system will return the task if the entered expression matches its ID. | ||
|
||
Contributors | ||
------------ | ||
* Numigi (tm) and all its contributors (https://bit.ly/numigiens) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2022 Numigi (tm) and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import models, controllers | ||
from .init_hook import post_init_hook | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
|
||
{ | ||
"name": "Project Task ID In Display Name", | ||
"version": "16.0.1.0.0", | ||
"author": "Numigi", | ||
"maintainer": "Numigi", | ||
"website": "https://bit.ly/numigi-com", | ||
"license": "LGPL-3", | ||
"category": "Project", | ||
"summary": "Add the ID of a task to its displayed name.", | ||
"depends": ["project"], | ||
"data": [ | ||
"views/project_task_views.xml", | ||
], | ||
"installable": True, | ||
"post_init_hook": "post_init_hook", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import portal | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
import urllib.parse | ||
|
||
from odoo import http | ||
from odoo.addons.project.controllers.portal import CustomerPortal | ||
|
||
|
||
class ProjectPortalWithSearchTaskByID(CustomerPortal): | ||
""" | ||
Allow the portal user to find a task directly by the task id. | ||
If the task with the given id is found, | ||
the user is redirected to the task form. | ||
""" | ||
|
||
@http.route( | ||
["/my/tasks", "/my/tasks/page/<int:page>"], | ||
type="http", | ||
auth="user", | ||
website=True, | ||
) | ||
def portal_my_tasks(self, search=None, **kw): | ||
is_searching_by_task_id = isinstance(search, str) and search.strip().isdigit() | ||
|
||
if is_searching_by_task_id: | ||
task_id = search.strip() | ||
task = http.request.env["project.task"].search( | ||
[("id_string", "=", task_id)], limit=1 | ||
) | ||
if task: | ||
query = urllib.parse.urlencode(dict(kw)) | ||
redirect_url = "/my/task/{task_id}?{query}".format( | ||
task_id=task.id, query=query | ||
) | ||
return http.request.redirect(redirect_url) | ||
|
||
return super().portal_my_tasks(search=search, **kw) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
import logging | ||
|
||
from odoo import SUPERUSER_ID | ||
from odoo.api import Environment | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
def post_init_hook(cr, pool): | ||
setup_task_id_string(cr) | ||
|
||
|
||
def setup_task_id_string(cr): | ||
"""Setup the field id_string on all tasks.""" | ||
_logger.info("Setting field id_string on model project.task.") | ||
env = Environment(cr, SUPERUSER_ID, {}) | ||
for task in env["project.task"].with_context(active_test=False).search([]): | ||
task.id_string = str(task.id) |
8 changes: 8 additions & 0 deletions
8
project_task_id_in_display_name/migrations/11.0.1.1.0/post-migration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from odoo.addons.project_task_id_in_display_name.init_hook import setup_task_id_string | ||
|
||
|
||
def migrate(cr, version): | ||
setup_task_id_string(cr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import project_task | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from odoo import api, fields, models | ||
|
||
|
||
class ProjectTask(models.Model): | ||
""" | ||
Add a field to allow searching a task by its ID. | ||
Odoo does not allow to properly search an integer value from a search bar. | ||
This results in an exceptions because Odoo sends the searched value | ||
right to the database without checking if the given string only contains digits. | ||
This is why we copy the id value into a varchar column. | ||
""" | ||
|
||
_inherit = "project.task" | ||
|
||
id_string = fields.Char("ID (String)", readonly=True) | ||
|
||
def name_get(self): | ||
return [(t.id, t._get_complete_name()) for t in self] | ||
|
||
def _get_complete_name(self): | ||
"""Get the complete name of the task. | ||
:return: a string containing the id and the name of the task. | ||
""" | ||
return "[{id}] {name}".format(id=self.id, name=self.name) | ||
|
||
@api.model | ||
def name_search(self, name, args=None, operator="ilike", limit=100): | ||
args = args or [] | ||
tasks = self.browse() | ||
|
||
if name and name.isdigit(): | ||
tasks = self.search([("id", "=", int(name))] + args, limit=limit) | ||
|
||
if not tasks: | ||
tasks = self.search([("name", operator, name)] + args, limit=limit) | ||
|
||
return tasks.name_get() | ||
|
||
@api.model | ||
def create(self, vals): | ||
task = super().create(vals) | ||
task.id_string = str(task.id) | ||
return task |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
|
||
from . import test_project_task |
38 changes: 38 additions & 0 deletions
38
project_task_id_in_display_name/tests/test_project_task.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Copyright 2024-today Numigi and all its contributors (https://bit.ly/numigiens) | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from odoo.tests.common import TransactionCase | ||
|
||
|
||
class TestProjectTaskWithIdInDisplayName(TransactionCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
cls.task_a = cls.env["project.task"].create({"name": "Task A"}) | ||
cls.task_b = cls.env["project.task"].create({"name": "Task B"}) | ||
|
||
def _search_tasks_by_name(self, name): | ||
"""Search tasks given a string to search for. | ||
:param name: the name of the task to search for | ||
:return: a recordset of project.task | ||
""" | ||
ids = [t[0] for t in self.env["project.task"].name_search(name)] | ||
return self.env["project.task"].browse(ids) | ||
|
||
def test_task_search_by_name(self): | ||
tasks = self._search_tasks_by_name("Task A") | ||
self.assertIn(self.task_a, tasks) | ||
self.assertNotIn(self.task_b, tasks) | ||
|
||
def test_task_search_by_id(self): | ||
tasks = self._search_tasks_by_name(str(self.task_a.id)) | ||
self.assertIn(self.task_a, tasks) | ||
self.assertNotIn(self.task_b, tasks) | ||
|
||
def test_display_name(self): | ||
expected_name = "[{id}] {name}".format(id=self.task_a.id, name=self.task_a.name) | ||
self.assertEqual(self.task_a.display_name, expected_name) | ||
|
||
def test_compute_id_string(self): | ||
self.assertEqual(self.task_a.id_string, str(self.task_a.id)) |
77 changes: 77 additions & 0 deletions
77
project_task_id_in_display_name/views/project_task_views.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<odoo> | ||
|
||
<record id="view_task_form2" model="ir.ui.view"> | ||
<field name="name">Task Form With Display Name In Read Mode</field> | ||
<field name="model">project.task</field> | ||
<field name="inherit_id" ref="project.view_task_form2"/> | ||
<field name="arch" type="xml"> | ||
<field name="name" position="before"> | ||
<field name="display_name" class="oe_read_only"/> | ||
</field> | ||
<field name="name" position="attributes"> | ||
<attribute name="class">oe_edit_only</attribute> | ||
</field> | ||
</field> | ||
</record> | ||
|
||
<record id="view_task_kanban" model="ir.ui.view"> | ||
<field name="name">Task Kanban With Display Name Instead Of Name</field> | ||
<field name="model">project.task</field> | ||
<field name="inherit_id" ref="project.view_task_kanban"/> | ||
<field name="arch" type="xml"> | ||
<xpath expr="//strong[hasclass('o_kanban_record_title')]/s/field[@name='name']" position="before"> | ||
<field name="display_name"/> | ||
</xpath> | ||
<xpath expr="//strong[hasclass('o_kanban_record_title')]/s/field[@name='name']" position="attributes"> | ||
<attribute name="invisible">1</attribute> | ||
</xpath> | ||
<xpath expr="//strong[hasclass('o_kanban_record_title')]/t/field[@name='name']" position="before"> | ||
<field name="display_name"/> | ||
</xpath> | ||
<xpath expr="//strong[hasclass('o_kanban_record_title')]/t/field[@name='name']" position="attributes"> | ||
<attribute name="invisible">1</attribute> | ||
</xpath> | ||
</field> | ||
</record> | ||
|
||
<record id="view_task_tree2" model="ir.ui.view"> | ||
<field name="name">Task List: Display Name Instead Of Name</field> | ||
<field name="model">project.task</field> | ||
<field name="inherit_id" ref="project.view_task_tree2"/> | ||
<field name="arch" type="xml"> | ||
<field name="name" position="before"> | ||
<field name="display_name"/> | ||
</field> | ||
<field name="name" position="attributes"> | ||
<attribute name="invisible">1</attribute> | ||
</field> | ||
</field> | ||
</record> | ||
|
||
<record id="project_task_view_tree_activity" model="ir.ui.view"> | ||
<field name="name">Task Next Activities List: Display Name Instead Of Name</field> | ||
<field name="model">project.task</field> | ||
<field name="inherit_id" ref="project.project_task_view_tree_activity"/> | ||
<field name="arch" type="xml"> | ||
<field name="name" position="before"> | ||
<field name="display_name"/> | ||
</field> | ||
<field name="name" position="attributes"> | ||
<attribute name="invisible">1</attribute> | ||
</field> | ||
</field> | ||
</record> | ||
|
||
<record id="view_task_search_form" model="ir.ui.view"> | ||
<field name="name">Task Search With ID Searched In Name</field> | ||
<field name="model">project.task</field> | ||
<field name="inherit_id" ref="project.view_task_search_form"/> | ||
<field name="arch" type="xml"> | ||
<field name="name" position="attributes"> | ||
<attribute name="filter_domain">['|', ('id_string', '=', self), ('name', 'ilike', self)]</attribute> | ||
</field> | ||
</field> | ||
</record> | ||
|
||
</odoo> |