Skip to content
Open
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
6 changes: 1 addition & 5 deletions document_page_reference/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

=======================
Document Page Reference
=======================
Expand All @@ -17,7 +13,7 @@ Document Page Reference
.. |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/license-AGPL--3-blue.png
.. |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
Expand Down
2 changes: 1 addition & 1 deletion document_page_reference/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "Document Page Reference",
"summary": """
Include references on document pages""",
"version": "18.0.2.1.3",
"version": "18.0.2.1.4",
"license": "AGPL-3",
"author": "Creu Blanca,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/knowledge",
Expand Down
29 changes: 29 additions & 0 deletions document_page_reference/migrations/18.0.2.1.4/pre-migrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2026 GMI Fabrica
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openupgradelib import openupgrade


@openupgrade.migrate()
def migrate(env, version):
"""Clear duplicate references before adding the DB unique constraint.

The oldest record of each duplicated reference keeps its value; the rest
are left without a reference.
"""
openupgrade.logged_query(
env.cr,
"""
WITH duplicates AS (
SELECT id,
ROW_NUMBER() OVER (
PARTITION BY reference ORDER BY id
) AS rn
FROM document_page
WHERE reference IS NOT NULL
)
UPDATE document_page dp
SET reference = NULL
WHERE id IN (SELECT id FROM duplicates WHERE rn > 1)
""",
)
11 changes: 10 additions & 1 deletion document_page_reference/models/document_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,21 @@ class DocumentPage(models.Model):
_description = "Document Page"

reference = fields.Char(
help="Used to find the document, it can contain letters, numbers and _"
copy=False,
help="Used to find the document, it can contain letters, numbers and _",
)
content_parsed = fields.Html(
"Parsed Content", compute="_compute_content_parsed", sanitize=False, store=True
)

_sql_constraints = [
(
"document_page_reference_unique",
"UNIQUE(reference)",
"The reference must be unique.",
)
]

def get_formview_action(self, access_uid=None):
res = super().get_formview_action(access_uid)
view_id = self.env.ref("document_page.view_wiki_form").id
Expand Down
26 changes: 10 additions & 16 deletions document_page_reference/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Document Page Reference</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -360,21 +360,16 @@
</style>
</head>
<body>
<div class="document">
<div class="document" id="document-page-reference">
<h1 class="title">Document Page Reference</h1>


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="document-page-reference">
<h1>Document Page Reference</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:7ae4eea4b6e7501b923f3597e005c064c4b58658b2913d8c3bfd25b1a7f9494c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/knowledge/tree/18.0/document_page_reference"><img alt="OCA/knowledge" src="https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/knowledge-18-0/knowledge-18-0-document_page_reference"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/knowledge&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/knowledge/tree/18.0/document_page_reference"><img alt="OCA/knowledge" src="https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/knowledge-18-0/knowledge-18-0-document_page_reference"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/knowledge&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows to add a reference name on documents and simplifies
the link between document pages.</p>
<p><strong>Table of contents</strong></p>
Expand All @@ -391,35 +386,35 @@ <h1>Document Page Reference</h1>
</ul>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>When editing a document page add elements like {{XXX}} where XXX is the
reference of another page. Now, when viewing the document, it will link
directly to the page. Also, the name will be parsed as the display name.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/knowledge/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/knowledge/issues/new?body=module:%20document_page_reference%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>Creu Blanca</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand All @@ -434,6 +429,5 @@ <h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
</div>
</div>
</div>
</div>
</body>
</html>
26 changes: 20 additions & 6 deletions document_page_reference/tests/test_document_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
# Copyright 2025 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from markupsafe import Markup
from psycopg2 import IntegrityError

from odoo.exceptions import ValidationError
from odoo.tools import mute_logger

from odoo.addons.base.tests.common import BaseCommon

Expand All @@ -22,8 +24,12 @@ def setUpClass(cls):
)

def test_constraints_duplicate_reference(self):
"""Should raise if reference is not unique (same as another)."""
with self.assertRaises(ValidationError):
"""Should raise if reference is not unique (same as another).

Uniqueness is enforced by a SQL constraint, which fails on the
UPDATE itself with an IntegrityError.
"""
with self.assertRaises(IntegrityError), mute_logger("odoo.sql_db"):
self.page2.write({"reference": self.page1.reference})

def test_constraints_invalid_reference(self):
Expand All @@ -49,15 +55,23 @@ def test_auto_reference(self):
{"name": "Test Page with no reference", "content": "some content"}
)
self.assertEqual(new_page.reference, "test_page_with_no_reference")
with self.assertRaises(ValidationError):
new_page_duplicated_name = self.page_obj.create(
# The auto-generated reference collides with the existing page, and
# the SQL unique constraint rejects the insert with an IntegrityError.
with self.assertRaises(IntegrityError), mute_logger("odoo.sql_db"):
self.page_obj.create(
{
"name": "test page with no reference",
"content": "<p>this should have an empty reference "
"content": "<p>this should not be created "
"because reference must be unique</p>",
}
)
self.assertFalse(new_page_duplicated_name.reference)

def test_duplicate_page_clears_reference(self):
"""Duplicating a page must not reuse the original reference."""
new_page = self.page1.copy()
self.assertNotEqual(new_page.reference, self.page1.reference)
self.assertTrue(new_page.reference)
self.assertIn("copy", new_page.reference)

def test_get_formview_action(self):
res = self.page1.get_formview_action()
Expand Down
Loading