mirror of
https://github.com/OCA/knowledge.git
synced 2025-07-13 15:34:49 -06:00
[ADD] document_print_control: restrict document printing based on tag configuration
This commit is contained in:
parent
62ebf2ba86
commit
32e5cbbce5
3
document_print_control/__init__.py
Normal file
3
document_print_control/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
# Copyright 2025 Juan Alberto Raja<juan.raja@sygel.es>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from . import models
|
22
document_print_control/__manifest__.py
Normal file
22
document_print_control/__manifest__.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright 2025 Juan Alberto Raja <juan.raja@sygel.es>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "Document Print Control",
|
||||
"summary": "Restricts document page printing based on assigned tags",
|
||||
"version": "16.0.1.0.0",
|
||||
"license": "AGPL-3",
|
||||
"author": "Sygel, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/knowledge",
|
||||
"category": "Knowledge",
|
||||
"depends": [
|
||||
"document_page",
|
||||
"document_page_tag",
|
||||
],
|
||||
"data": [
|
||||
"views/document_page_tag.xml",
|
||||
"views/document_page.xml",
|
||||
],
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"auto_install": False,
|
||||
}
|
46
document_print_control/i18n/ca_ES.po
Normal file
46
document_print_control/i18n/ca_ES.po
Normal file
@ -0,0 +1,46 @@
|
||||
# Translation of Odoo Server.
|
||||
# * document_print_control
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Language: ca\n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,field_description:document_print_control.field_document_page_tag__is_printable
|
||||
msgid "Is Printable"
|
||||
msgstr "És imprimible"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,help:document_print_control.field_document_page__is_printable
|
||||
msgid "Indicates if the document can be printed based on its tags"
|
||||
msgstr "Indica si el document es pot imprimir basant-se en les seves etiquetes"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,help:document_print_control.field_document_page_tag__is_printable
|
||||
msgid "If unchecked, pages with this tag cannot be printed"
|
||||
msgstr "Si està desmarcat, les pàgines amb aquesta etiqueta no es poden imprimir"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_form_inherit_print
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_tag_search_extended
|
||||
msgid "Printable Tags"
|
||||
msgstr "Etiquetes imprimibles"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_tag_search_extended
|
||||
msgid "Non-Printable Tags"
|
||||
msgstr "Etiquetes no imprimibles"
|
46
document_print_control/i18n/es.po
Normal file
46
document_print_control/i18n/es.po
Normal file
@ -0,0 +1,46 @@
|
||||
# Translation of Odoo Server.
|
||||
# * document_print_control
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Language: es\n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,field_description:document_print_control.field_document_page_tag__is_printable
|
||||
msgid "Is Printable"
|
||||
msgstr "Es imprimible"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,help:documents_print_control.field_document_page__is_printable
|
||||
msgid "Indicates if the document can be printed based on its tags"
|
||||
msgstr "Indica si el documento puede ser impreso basándose en sus etiquetas"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model:ir.model.fields,help:documents_print_control.field_document_page_tag__is_printable
|
||||
msgid "If unchecked, pages with this tag cannot be printed"
|
||||
msgstr "Si está desmarcado, las páginas con esta etiqueta no se pueden imprimir"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_form_inherit_print
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_tag_search_extended
|
||||
msgid "Printable Tags"
|
||||
msgstr "Etiquetas imprimibles"
|
||||
|
||||
#. module: document_print_control
|
||||
#: model_terms:ir.ui.view,arch_db:document_print_control.view_document_page_tag_search_extended
|
||||
msgid "Non-Printable Tags"
|
||||
msgstr "Etiquetas no imprimibles"
|
4
document_print_control/models/__init__.py
Normal file
4
document_print_control/models/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# Copyright 2025 Juan Alberto Raja<juan.raja@sygel.es>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from . import document_page_tag
|
||||
from . import document_page
|
25
document_print_control/models/document_page.py
Normal file
25
document_print_control/models/document_page.py
Normal file
@ -0,0 +1,25 @@
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class DocumentPage(models.Model):
|
||||
_inherit = "document.page"
|
||||
|
||||
is_printable = fields.Boolean(
|
||||
compute="_compute_is_printable",
|
||||
store=True,
|
||||
help="Indicates if the document can be printed based on its tags",
|
||||
)
|
||||
|
||||
@api.depends("tag_ids", "tag_ids.is_printable")
|
||||
def _compute_is_printable(self):
|
||||
for record in self:
|
||||
if not record.tag_ids:
|
||||
record.is_printable = True
|
||||
else:
|
||||
record.is_printable = all(tag.is_printable for tag in record.tag_ids)
|
||||
|
||||
def action_print_document_page(self):
|
||||
for record in self:
|
||||
if not record.is_printable:
|
||||
return None
|
||||
return self.env.ref("document_page.report_document_page").report_action(self)
|
18
document_print_control/models/document_page_tag.py
Normal file
18
document_print_control/models/document_page_tag.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright 2025 Juan Alberto Raja<juan.raja@sygel.es>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class DocumentPageTag(models.Model):
|
||||
_inherit = "document.page.tag"
|
||||
|
||||
is_printable = fields.Boolean(
|
||||
default=True,
|
||||
help="If unchecked, pages with this tag cannot be printed",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if "is_printable" not in vals:
|
||||
vals["is_printable"] = True
|
||||
return super().create(vals)
|
5
document_print_control/readme/CONTRIBUTORS.md
Normal file
5
document_print_control/readme/CONTRIBUTORS.md
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
> - [Sygel](https://www.sygel.es):
|
||||
>
|
||||
> > - Juan Alberto Raja Martinez\<<juan.raja@sygel.es>\>
|
||||
> > - Valentín Vinagre Urteaga\<<valentin.vinagre@sygel.es>\>
|
1
document_print_control/readme/DESCRIPTION.md
Normal file
1
document_print_control/readme/DESCRIPTION.md
Normal file
@ -0,0 +1 @@
|
||||
This module adds print control functionality to document pages based on tags. It allows users to control which document pages can be printed by configuring tags with a "printable" attribute. When a document page has tags marked as non-printable, the print button will be hidden and the printing functionality will be disabled for that document.
|
8
document_print_control/readme/USAGE.md
Normal file
8
document_print_control/readme/USAGE.md
Normal file
@ -0,0 +1,8 @@
|
||||
If you want to control the printing of document pages using tags:
|
||||
|
||||
1. Go to Document Management, then to Configuration, and open Tags.
|
||||
2. Create or edit existing tags and use the "Is Printable" checkbox to control printing permissions.
|
||||
3. Uncheck "Is Printable" for tags that should prevent document printing.
|
||||
4. Assign these tags to document pages - if any tag on a document page is marked as non-printable, the entire document becomes non-printable.
|
||||
5. The print button will automatically hide for non-printable documents, and printing functionality will be disabled.
|
||||
6. All tags are printable by default to maintain backward compatibility.
|
BIN
document_print_control/static/description/icon.png
Normal file
BIN
document_print_control/static/description/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
3
document_print_control/tests/__init__.py
Normal file
3
document_print_control/tests/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
# Copyright 2025 Juan Alberto Raja <juan.raja@sygel.es>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from . import test_document_print_control
|
90
document_print_control/tests/test_document_print_control.py
Normal file
90
document_print_control/tests/test_document_print_control.py
Normal file
@ -0,0 +1,90 @@
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestDocumentPrintControl(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.printable_tag = cls.env["document.page.tag"].create(
|
||||
{
|
||||
"name": "Printable Tag",
|
||||
"is_printable": True,
|
||||
}
|
||||
)
|
||||
|
||||
cls.non_printable_tag = cls.env["document.page.tag"].create(
|
||||
{
|
||||
"name": "Non-Printable Tag",
|
||||
"is_printable": False,
|
||||
}
|
||||
)
|
||||
|
||||
cls.doc_without_tags = cls.env["document.page"].create(
|
||||
{
|
||||
"name": "Document without tags",
|
||||
"content": "Test content without tags",
|
||||
}
|
||||
)
|
||||
|
||||
cls.doc_with_printable_tag = cls.env["document.page"].create(
|
||||
{
|
||||
"name": "Document with printable tag",
|
||||
"content": "Test content with printable tag",
|
||||
"tag_ids": [(4, cls.printable_tag.id)],
|
||||
}
|
||||
)
|
||||
|
||||
cls.doc_with_non_printable_tag = cls.env["document.page"].create(
|
||||
{
|
||||
"name": "Document with non-printable tag",
|
||||
"content": "Test content with non-printable tag",
|
||||
"tag_ids": [(4, cls.non_printable_tag.id)],
|
||||
}
|
||||
)
|
||||
|
||||
cls.doc_with_mixed_tags = cls.env["document.page"].create(
|
||||
{
|
||||
"name": "Document with mixed tags",
|
||||
"content": "Test content with mixed tags",
|
||||
"tag_ids": [(4, cls.printable_tag.id), (4, cls.non_printable_tag.id)],
|
||||
}
|
||||
)
|
||||
|
||||
def test_printable_without_tags(self):
|
||||
"""Documents without tags should be printable by default"""
|
||||
self.assertTrue(self.doc_without_tags.is_printable)
|
||||
|
||||
def test_printable_with_allowed_tags(self):
|
||||
"""Documents with only printable tags should be printable"""
|
||||
self.assertTrue(self.doc_with_printable_tag.is_printable)
|
||||
|
||||
def test_not_printable_with_restricted_tags(self):
|
||||
"""Documents with non-printable tags should not be printable"""
|
||||
self.assertFalse(self.doc_with_non_printable_tag.is_printable)
|
||||
|
||||
def test_not_printable_with_mixed_tags(self):
|
||||
"""Documents with mixed tags should not be printable"""
|
||||
self.assertFalse(self.doc_with_mixed_tags.is_printable)
|
||||
|
||||
def test_print_action_allowed_documents(self):
|
||||
"""Print action should return report for printable documents"""
|
||||
result = self.doc_with_printable_tag.action_print_document_page()
|
||||
self.assertIsNotNone(result)
|
||||
self.assertIn("context", result)
|
||||
self.assertIn("report_action", result["context"])
|
||||
self.assertIn("report_name", result["context"]["report_action"])
|
||||
|
||||
def test_print_action_restricted_documents(self):
|
||||
"""Print action should return None for non-printable documents"""
|
||||
result = self.doc_with_non_printable_tag.action_print_document_page()
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_tag_default_is_printable(self):
|
||||
"""Tags created without is_printable should default to True"""
|
||||
tag = self.env["document.page.tag"].create(
|
||||
{"name": "Test Tag Without is_printable"}
|
||||
)
|
||||
self.assertTrue(tag.is_printable)
|
33
document_print_control/views/document_page.xml
Normal file
33
document_print_control/views/document_page.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2025 Juan Alberto Raja <juan.raja@sygel.es>
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="document_page.report_document_page" model="ir.actions.report">
|
||||
<field name="binding_type">action</field>
|
||||
<field name="binding_view_types" eval="False" />
|
||||
</record>
|
||||
|
||||
<record id="view_document_page_form_inherit_print" model="ir.ui.view">
|
||||
<field name="name">document.page.form.inherit.print</field>
|
||||
<field name="model">document.page</field>
|
||||
<field name="inherit_id" ref="document_page.view_wiki_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form" position="inside">
|
||||
<field name="is_printable" invisible="0" />
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//sheet" position="before">
|
||||
<header>
|
||||
<button
|
||||
name="action_print_document_page"
|
||||
type="object"
|
||||
string="Print"
|
||||
icon="fa-print"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': [('is_printable', '=', False)]}"
|
||||
/>
|
||||
</header>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
53
document_print_control/views/document_page_tag.xml
Normal file
53
document_print_control/views/document_page_tag.xml
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2025 Juan Alberto Raja <juan.raja@sygel.es>
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="view_document_page_tag_form_extended" model="ir.ui.view">
|
||||
<field name="name">document.page.tag.form.extended</field>
|
||||
<field name="model">document.page.tag</field>
|
||||
<field name="inherit_id" ref="document_page_tag.view_document_page_tag_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="color" position="before">
|
||||
<field name="is_printable" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_document_page_tag_tree_extended" model="ir.ui.view">
|
||||
<field name="name">document.page.tag.tree.extended</field>
|
||||
<field name="model">document.page.tag</field>
|
||||
<field name="inherit_id" ref="document_page_tag.view_document_page_tag_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="color" position="after">
|
||||
<field name="is_printable" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_document_page_tag_search_extended" model="ir.ui.view">
|
||||
<field name="name">document.page.tag.search.extended</field>
|
||||
<field name="model">document.page.tag</field>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="document_page_tag.view_document_page_tag_search"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="is_printable" />
|
||||
</field>
|
||||
<xpath expr="//filter[@name='inactive']" position="after">
|
||||
<separator />
|
||||
<filter
|
||||
name="printable_tags"
|
||||
string="Printable Tags"
|
||||
domain="[('is_printable', '=', True)]"
|
||||
/>
|
||||
<filter
|
||||
name="non_printable_tags"
|
||||
string="Non-Printable Tags"
|
||||
domain="[('is_printable', '=', False)]"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
Loading…
Reference in New Issue
Block a user