Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 262 additions & 0 deletions document_page_project_task/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
==========================
Document Page Project Task
==========================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:792f27beb9e30e02336420e9ffafb95a1a3027dc4b2ff368b4d350c683de3b01
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github
:target: https://github.com/OCA/knowledge/tree/18.0/document_page_project_task
:alt: OCA/knowledge
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/knowledge-18-0/knowledge-18-0-document_page_project_task
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/knowledge&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module extends the document page (wiki) functionality by allowing
you to link them directly to project tasks.

Main Features
-------------

- **Link Wiki Pages to Multiple Tasks**: Allows associating document
pages to one or more project tasks via a Many2many relationship
- **Automatic Project Filling**: When all linked tasks share the same
project, it is automatically filled on the document
- **Consistency Validation**: If a project is defined on the wiki page,
all linked tasks must belong to that project
- **Smart Filtering**: When a project is selected, only tasks from that
project are displayed for selection
- **Page Counter**: Displays the number of wiki pages linked to each
task directly in the task view

Benefits
--------

- Organize project documentation hierarchically (Project → Tasks → Wiki)
- A single wiki page can document multiple related tasks (e.g., a spec
shared by several tasks)
- A task can reference multiple wiki pages for different aspects of its
work
- Keep documentation close to the work context (tasks)
- Quickly access all documentation related to a specific task

Dependencies
------------

This module requires:

- ``document_page_project``: Module that links document pages to
projects
- ``project``: Odoo's project management module

**Table of contents**

.. contents::
:local:

Configuration
=============

This module does not require additional configuration after
installation. It works automatically once installed.

Installation
------------

1. Go to the **Apps** menu
2. Remove the "Apps" filter if necessary
3. Search for "Document Page Project Task"
4. Click **Install**

Prerequisites
-------------

Make sure the following modules are installed:

- **Project** (base project module)
- **Document Page Project** (links wiki pages to projects)

The system will automatically install the necessary dependencies during
installation.

Permissions
-----------

The module uses the same access permissions as the base modules:

- Users with access to **Projects** can view and create wiki pages
linked to tasks
- Users with access to **Documents/Knowledge** can manage wiki page
content

No additional permission configuration is required.

Usage
=====

This guide explains how to use the Document Page Project Task module to
link wiki pages to project tasks.

Create a Wiki Page from a Task
------------------------------

**Method 1: From the Task**

1. Go to the **Projects** module
2. Open the desired project and select a task
3. In the task view, locate the **Wiki Pages** button (book icon)
4. Click the button to see linked pages or create a new one
5. Click **Create** to add a new wiki page
6. The task and project will be automatically filled

**Method 2: From the Wiki Page**

1. Go to the **Knowledge** or **Documents** module
2. Create a new wiki page or edit an existing one
3. In the page form, you will see the fields:

- **Project**: Select the project
- **Tasks**: Select one or more tasks (when a project is selected,
only tasks from that project are shown)

4. Save the page

Automatic Behaviors
-------------------

**Automatic Project Filling**

When you add tasks and no project is yet selected:

- If all linked tasks belong to the same project, the **Project** field
is automatically filled

**Task Filtering**

When a project is selected:

- Only tasks from that project appear in the task selection list
- Tasks from other projects are automatically removed from the list

**Consistency Validation**

The system validates that:

- If a project is defined on the wiki page, all linked tasks must belong
to that project
- Attempting to link a task from a different project will be prevented

**No Project Restriction**

If no project is selected on the wiki page, tasks from any project can
be linked freely — useful for cross-project reference documents.

Link a Page to Multiple Tasks
-----------------------------

A wiki page can be linked to several tasks at the same time:

1. Open or create a wiki page
2. In the **Tasks** field (shown as tags), add all relevant tasks
3. The page will appear in the **Wiki Pages** counter on each of those
tasks

View Wiki Pages of a Task
-------------------------

1. Access a project task
2. At the top of the form, you will see the **Wiki Pages** button with a
counter
3. The number indicates how many wiki pages are linked to the task
4. Click the button to see all linked pages

Usage Examples
--------------

**Example 1: Shared Requirements Document**

1. Create a wiki page "Functional Requirements"
2. Link it to tasks "Backend Implementation", "Frontend Implementation",
and "QA Testing"
3. All three tasks will reference the same documentation

**Example 2: Technical Specification**

1. Create a task "Develop Module X"
2. From the task, create multiple wiki pages: "Technical Spec", "API
Design", "Database Schema"
3. Each page is linked to the task and accessible via the Wiki Pages
button

**Example 3: Cross-Task Reference**

1. Create a wiki page without a project
2. Link tasks from different projects that share a common dependency or
context
3. The page acts as a cross-project reference document

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/knowledge/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/knowledge/issues/new?body=module:%20document_page_project_task%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Escodoo

Contributors
------------

- `ESCODOO <https://escodoo.com.br>`__:

- Marcel Savegnago <marcel.savegnago@escodoo.com.br>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-marcelsavegnago| image:: https://github.com/marcelsavegnago.png?size=40px
:target: https://github.com/marcelsavegnago
:alt: marcelsavegnago

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-marcelsavegnago|

This module is part of the `OCA/knowledge <https://github.com/OCA/knowledge/tree/18.0/document_page_project_task>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions document_page_project_task/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
16 changes: 16 additions & 0 deletions document_page_project_task/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2025 Escodoo <https://escodoo.com.br>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Document Page Project Task",
"summary": "This module links document pages to project tasks",
"version": "18.0.2.0.0",
"category": "Project",
"author": "Escodoo, Odoo Community Association (OCA)",
"maintainers": ["marcelsavegnago"],
"website": "https://github.com/OCA/knowledge",
"license": "AGPL-3",
"depends": ["document_page_project"],
"data": ["views/document_page_views.xml", "views/project_task_views.xml"],
"installable": True,
}
2 changes: 2 additions & 0 deletions document_page_project_task/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import document_page
from . import project_task
67 changes: 67 additions & 0 deletions document_page_project_task/models/document_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright 2025 Marcel Savegnago - Escodoo <https://escodoo.com.br>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class DocumentPage(models.Model):
_inherit = "document.page"

task_ids = fields.Many2many(
string="Tasks",
comodel_name="project.task",
relation="document_page_project_task_rel",
column1="document_page_id",
column2="task_id",
)

@api.onchange("task_ids")
def _onchange_task_ids(self):
"""If no project is set and all tasks share the same project, fill it."""
if self.task_ids and not self.project_id:
projects = self.task_ids.mapped("project_id")
if len(projects) == 1:
self.project_id = projects

@api.onchange("project_id")
def _onchange_project_id(self):
"""Remove tasks that don't belong to the newly selected project."""
if self.project_id and self.task_ids:
self.task_ids = self.task_ids.filtered(
lambda t: t.project_id == self.project_id
)

@api.constrains("task_ids", "project_id")
def _check_task_project_consistency(self):
"""Ensure all linked tasks belong to the document's project."""
for record in self:
if record.project_id and record.task_ids:
invalid_tasks = record.task_ids.filtered(
lambda t, r=record: t.project_id != r.project_id
)
if invalid_tasks:
raise ValidationError(
_(
"All linked tasks must belong to the document's project "
"'%(project)s'. The following tasks belong to a different "
"project: %(tasks)s.",
project=record.project_id.name,
tasks=", ".join(invalid_tasks.mapped("name")),
)
)

@api.model
def default_get(self, fields_list):
"""Fill task_ids and project_id when created with default_task_id in context."""
res = super().default_get(fields_list)
if "default_task_id" in self.env.context:
task = self.env["project.task"].browse(
self.env.context.get("default_task_id")
)
if task.exists():
if "task_ids" in fields_list:
res["task_ids"] = [(4, task.id)]
if "project_id" in fields_list and task.project_id:
res["project_id"] = task.project_id.id
return res
22 changes: 22 additions & 0 deletions document_page_project_task/models/project_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 Marcel Savegnago - Escodoo <https://escodoo.com.br>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models


class ProjectTask(models.Model):
_inherit = "project.task"

document_page_ids = fields.Many2many(
string="Wiki Pages",
comodel_name="document.page",
relation="document_page_project_task_rel",
column1="task_id",
column2="document_page_id",
)
document_page_count = fields.Integer(compute="_compute_document_page_count")

@api.depends("document_page_ids")
def _compute_document_page_count(self):
for rec in self:
rec.document_page_count = len(rec.document_page_ids)
3 changes: 3 additions & 0 deletions document_page_project_task/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
Loading
Loading