diff --git a/document_page_tag_print_control/README.rst b/document_page_tag_print_control/README.rst new file mode 100644 index 00000000..56ea4ae2 --- /dev/null +++ b/document_page_tag_print_control/README.rst @@ -0,0 +1,108 @@ +=============================== +Document Page Tag Print Control +=============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c08c914a87dd77f1d5c07e7716f9f40c7341917cc62a95efe6c0035fce9a9eaf + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/16.0/document_page_tag_print_control + :alt: OCA/knowledge +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-document_page_tag_print_control + :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=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds print control functionality to document pages based on +tags. It allows users to control which document pages cannot be printed +by configuring tags with a "Not Printable" attribute. + +When a document page has one or more tags marked as not printable, +printing functionality will be disabled and a warning will be shown if +attempted. + +Users with the "Manager" role in the "Document Knowledge" section (under +Settings > Users > Access Rights > Other) are exempt from these +restrictions and can print any document page regardless of its tags. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To restrict the printing of document pages using tags: + +1. Go to Document Management > Configuration > Tags. +2. Create or edit existing tags and use the "Not Printable" checkbox to + prevent printing. +3. Check "Not Printable" for tags that should block printing. +4. Assign these tags to document pages. If any tag on a page is marked + as not printable, the entire page will be blocked from printing. +5. If you attempt to print such pages, the system will raise a warning + and prevent the action. +6. All tags allow printing by default for compatibility. + +Users with the **Manager** role in the "Document Knowledge" section +(Settings > Users > Access Rights > Other) are not affected by this +restriction. They can always print any document page. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Sygel + +Contributors +------------ + +- `Sygel `__ + + - Juan Alberto Raja + - Valentín Vinagre + +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. + +This module is part of the `OCA/knowledge `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/document_page_tag_print_control/__init__.py b/document_page_tag_print_control/__init__.py new file mode 100644 index 00000000..f13e006e --- /dev/null +++ b/document_page_tag_print_control/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/document_page_tag_print_control/__manifest__.py b/document_page_tag_print_control/__manifest__.py new file mode 100644 index 00000000..ad7c65e5 --- /dev/null +++ b/document_page_tag_print_control/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Document Page Tag 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_tag", + ], + "data": [ + "views/document_page_tag.xml", + ], + "installable": True, + "application": False, + "auto_install": False, +} diff --git a/document_page_tag_print_control/i18n/ca_ES.po b/document_page_tag_print_control/i18n/ca_ES.po new file mode 100644 index 00000000..2b5b3286 --- /dev/null +++ b/document_page_tag_print_control/i18n/ca_ES.po @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# * document_page_tag_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_page_tag_print_control +#: code:addons/document_page_tag_print_control/models/report_document_page.py:0 +#, python-format +msgid "None of the selected document pages can be printed due to their tags." +msgstr "Cap de les pàgines seleccionades es pot imprimir a causa de les seves etiquetes." + +#. module: document_page_tag_print_control +#: code:addons/document_page_tag_print_control/models/report_document_page.py:0 +#, python-format +msgid "Some pages cannot be printed due to their tags:\n" +msgstr "Algunes pàgines no es poden imprimir a causa de les seves etiquetes:\n" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,field_description:document_page_tag_print_control.field_document_page_tag__is_not_printable +msgid "Is Not Printable" +msgstr "No és imprimible" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,help:document_page_tag_print_control.field_document_page__is_not_printable +msgid "Indicates if the document cannot be printed based on its tags" +msgstr "Indica si el document no es pot imprimir basant-se en les seves etiquetes" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,help:document_page_tag_print_control.field_document_page_tag__is_not_printable +msgid "If checked, pages with this tag cannot be printed" +msgstr "Si està marcat, les pàgines amb aquesta etiqueta no es poden imprimir" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_form_inherit_print +msgid "Print" +msgstr "Imprimir" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_tag_search_extended +msgid "Printable Tags" +msgstr "Etiquetes imprimibles" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_tag_search_extended +msgid "Non-Printable Tags" +msgstr "Etiquetes no imprimibles" diff --git a/document_page_tag_print_control/i18n/es.po b/document_page_tag_print_control/i18n/es.po new file mode 100644 index 00000000..e08e15c2 --- /dev/null +++ b/document_page_tag_print_control/i18n/es.po @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# * document_page_tag_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_page_tag_print_control +#: code:addons/document_page_tag_print_control/models/report_document_page.py:0 +#, python-format +msgid "None of the selected document pages can be printed due to their tags." +msgstr "Ninguna de las páginas seleccionadas se puede imprimir debido a sus etiquetas." + +#. module: document_page_tag_print_control +#: code:addons/document_page_tag_print_control/models/report_document_page.py:0 +#, python-format +msgid "Some pages cannot be printed due to their tags:\n" +msgstr "Algunas páginas no se pueden imprimir debido a sus etiquetas:\n" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,field_description:document_page_tag_print_control.field_document_page_tag__is_not_printable +msgid "Is Not Printable" +msgstr "No es imprimible" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,help:document_page_tag_print_control.field_document_page__is_not_printable +msgid "Indicates if the document cannot be printed based on its tags" +msgstr "Indica si el documento no puede ser impreso basándose en sus etiquetas" + +#. module: document_page_tag_print_control +#: model:ir.model.fields,help:document_page_tag_print_control.field_document_page_tag__is_not_printable +msgid "If checked, pages with this tag cannot be printed" +msgstr "Si está marcado, las páginas con esta etiqueta no se pueden imprimir" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_form_inherit_print +msgid "Print" +msgstr "Imprimir" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_tag_search_extended +msgid "Printable Tags" +msgstr "Etiquetas imprimibles" + +#. module: document_page_tag_print_control +#: model_terms:ir.ui.view,arch_db:document_page_tag_print_control.view_document_page_tag_search_extended +msgid "Non-Printable Tags" +msgstr "Etiquetas no imprimibles" diff --git a/document_page_tag_print_control/models/__init__.py b/document_page_tag_print_control/models/__init__.py new file mode 100644 index 00000000..9da26f3c --- /dev/null +++ b/document_page_tag_print_control/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import document_page_tag +from . import document_page +from . import report_document_page diff --git a/document_page_tag_print_control/models/document_page.py b/document_page_tag_print_control/models/document_page.py new file mode 100644 index 00000000..23790926 --- /dev/null +++ b/document_page_tag_print_control/models/document_page.py @@ -0,0 +1,20 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import api, fields, models + + +class DocumentPage(models.Model): + _inherit = "document.page" + + is_not_printable = fields.Boolean( + compute="_compute_is_not_printable", + store=True, + help="Indicates if the document cannot be printed based on its tags", + ) + + @api.depends("tag_ids", "tag_ids.is_not_printable") + def _compute_is_not_printable(self): + for record in self: + record.is_not_printable = any( + tag.is_not_printable for tag in record.tag_ids + ) diff --git a/document_page_tag_print_control/models/document_page_tag.py b/document_page_tag_print_control/models/document_page_tag.py new file mode 100644 index 00000000..daa27c50 --- /dev/null +++ b/document_page_tag_print_control/models/document_page_tag.py @@ -0,0 +1,12 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class DocumentPageTag(models.Model): + _inherit = "document.page.tag" + + is_not_printable = fields.Boolean( + default=False, + help="If checked, pages with this tag cannot be printed", + ) diff --git a/document_page_tag_print_control/models/report_document_page.py b/document_page_tag_print_control/models/report_document_page.py new file mode 100644 index 00000000..204bd9af --- /dev/null +++ b/document_page_tag_print_control/models/report_document_page.py @@ -0,0 +1,37 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import _, api, models +from odoo.exceptions import UserError + + +class ReportDocumentPage(models.AbstractModel): + _name = "report.document_page.report_documentpage" + _description = "Document Page Report with Print Control" + + @api.model + def _get_report_values(self, docids, data=None): + docs = self.env["document.page"].browse(docids).exists() + printable_docs = docs + + if not self.env.user.has_group("document_page.group_document_manager"): + printable_docs = docs.filtered(lambda d: not d.is_not_printable) + + if not printable_docs: + raise UserError( + _("None of the selected pages can be printed due to their tags.") + ) + + if len(printable_docs) < len(docs): + non_printable = docs - printable_docs + raise UserError( + _("Some pages cannot be printed due to their tags:\n") + + "\n".join(f"- {doc.name}" for doc in non_printable) + ) + + report_values = { + "doc_ids": printable_docs.ids, + "doc_model": "document.page", + "docs": printable_docs, + } + + return report_values diff --git a/document_page_tag_print_control/readme/CONTRIBUTORS.md b/document_page_tag_print_control/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..0734b46f --- /dev/null +++ b/document_page_tag_print_control/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- [Sygel](https://www.sygel.es) + - Juan Alberto Raja + - Valentín Vinagre diff --git a/document_page_tag_print_control/readme/DESCRIPTION.md b/document_page_tag_print_control/readme/DESCRIPTION.md new file mode 100644 index 00000000..8954f836 --- /dev/null +++ b/document_page_tag_print_control/readme/DESCRIPTION.md @@ -0,0 +1,5 @@ +This module adds print control functionality to document pages based on tags. It allows users to control which document pages cannot be printed by configuring tags with a "Not Printable" attribute. + +When a document page has one or more tags marked as not printable, printing functionality will be disabled and a warning will be shown if attempted. + +Users with the "Manager" role in the "Document Knowledge" section (under Settings > Users > Access Rights > Other) are exempt from these restrictions and can print any document page regardless of its tags. diff --git a/document_page_tag_print_control/readme/USAGE.md b/document_page_tag_print_control/readme/USAGE.md new file mode 100644 index 00000000..da4c6854 --- /dev/null +++ b/document_page_tag_print_control/readme/USAGE.md @@ -0,0 +1,11 @@ +To restrict the printing of document pages using tags: + +1. Go to Document Management > Configuration > Tags. +2. Create or edit existing tags and use the "Not Printable" checkbox to prevent printing. +3. Check "Not Printable" for tags that should block printing. +4. Assign these tags to document pages. If any tag on a page is marked as not printable, the entire page will be blocked from printing. +5. If you attempt to print such pages, the system will raise a warning and prevent the action. +6. All tags allow printing by default for compatibility. + +Users with the **Manager** role in the "Document Knowledge" section (Settings > Users > Access Rights > Other) are not affected by this restriction. They can always print any document page. + diff --git a/document_page_tag_print_control/static/description/icon.png b/document_page_tag_print_control/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/document_page_tag_print_control/static/description/icon.png differ diff --git a/document_page_tag_print_control/static/description/index.html b/document_page_tag_print_control/static/description/index.html new file mode 100644 index 00000000..11702390 --- /dev/null +++ b/document_page_tag_print_control/static/description/index.html @@ -0,0 +1,454 @@ + + + + + +Document Page Tag Print Control + + + +
+

Document Page Tag Print Control

+ + +

Beta License: AGPL-3 OCA/knowledge Translate me on Weblate Try me on Runboat

+

This module adds print control functionality to document pages based on +tags. It allows users to control which document pages cannot be printed +by configuring tags with a “Not Printable” attribute.

+

When a document page has one or more tags marked as not printable, +printing functionality will be disabled and a warning will be shown if +attempted.

+

Users with the “Manager” role in the “Document Knowledge” section (under +Settings > Users > Access Rights > Other) are exempt from these +restrictions and can print any document page regardless of its tags.

+

Table of contents

+ +
+

Usage

+

To restrict the printing of document pages using tags:

+
    +
  1. Go to Document Management > Configuration > Tags.
  2. +
  3. Create or edit existing tags and use the “Not Printable” checkbox to +prevent printing.
  4. +
  5. Check “Not Printable” for tags that should block printing.
  6. +
  7. Assign these tags to document pages. If any tag on a page is marked +as not printable, the entire page will be blocked from printing.
  8. +
  9. If you attempt to print such pages, the system will raise a warning +and prevent the action.
  10. +
  11. All tags allow printing by default for compatibility.
  12. +
+

Users with the Manager role in the “Document Knowledge” section +(Settings > Users > Access Rights > Other) are not affected by this +restriction. They can always print any document page.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Sygel
  • +
+
+
+

Contributors

+
    +
  • Sygel
      +
    • Juan Alberto Raja
    • +
    • Valentín Vinagre
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

This module is part of the OCA/knowledge project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/document_page_tag_print_control/tests/__init__.py b/document_page_tag_print_control/tests/__init__.py new file mode 100644 index 00000000..8cf16005 --- /dev/null +++ b/document_page_tag_print_control/tests/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2025 Juan Alberto Raja +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import test_document_page_tag_print_control diff --git a/document_page_tag_print_control/tests/test_document_page_tag_print_control.py b/document_page_tag_print_control/tests/test_document_page_tag_print_control.py new file mode 100644 index 00000000..bf0c7819 --- /dev/null +++ b/document_page_tag_print_control/tests/test_document_page_tag_print_control.py @@ -0,0 +1,90 @@ +from odoo.exceptions import UserError +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", "is_not_printable": False} + ) + cls.non_printable_tag = cls.env["document.page.tag"].create( + {"name": "Non-Printable", "is_not_printable": True} + ) + cls.doc_without_tags = cls.env["document.page"].create( + {"name": "Document Without Tags", "content": "Content"} + ) + cls.doc_printable = cls.env["document.page"].create( + { + "name": "Printable Document", + "content": "Content", + "tag_ids": [(4, cls.printable_tag.id)], + } + ) + cls.doc_non_printable = cls.env["document.page"].create( + { + "name": "Non-Printable Document", + "content": "Content", + "tag_ids": [(4, cls.non_printable_tag.id)], + } + ) + cls.doc_mixed_tags = cls.env["document.page"].create( + { + "name": "Mixed Tags Document", + "content": "Content", + "tag_ids": [(4, cls.printable_tag.id), (4, cls.non_printable_tag.id)], + } + ) + + def test_document_without_tags_is_printable(self): + """Document without tags is printable.""" + self.assertFalse(self.doc_without_tags.is_not_printable) + + def test_document_with_printable_tag(self): + """Document with printable tag is printable.""" + self.assertFalse(self.doc_printable.is_not_printable) + + def test_document_with_non_printable_tag(self): + """Document with non-printable tag is not printable.""" + self.assertTrue(self.doc_non_printable.is_not_printable) + + def test_document_with_mixed_tags(self): + """Document with mixed tags is not printable.""" + self.assertTrue(self.doc_mixed_tags.is_not_printable) + + def test_report_non_printable_raises_error(self): + """Report fails if all documents are non-printable.""" + with self.assertRaises(UserError) as ctx: + self.env["report.document_page.report_documentpage"]._get_report_values( + [self.doc_non_printable.id] + ) + self.assertIn("None of the selected pages can be printed", str(ctx.exception)) + + def test_report_mixed_docs_raises_error(self): + """Report fails if some documents are non-printable.""" + with self.assertRaises(UserError) as ctx: + self.env["report.document_page.report_documentpage"]._get_report_values( + [self.doc_printable.id, self.doc_non_printable.id] + ) + self.assertIn("Some pages cannot be printed", str(ctx.exception)) + self.assertIn(self.doc_non_printable.name, str(ctx.exception)) + + def test_report_printable_docs(self): + """Report returns correct values for printable documents.""" + values = self.env[ + "report.document_page.report_documentpage" + ]._get_report_values([self.doc_printable.id]) + self.assertEqual(values["doc_ids"], [self.doc_printable.id]) + self.assertEqual(values["doc_model"], "document.page") + self.assertEqual(values["docs"].ids, [self.doc_printable.id]) + + def test_manager_bypasses_print_restrictions(self): + """Manager can print any document.""" + self.env.user.groups_id |= self.env.ref("document_page.group_document_manager") + values = self.env[ + "report.document_page.report_documentpage" + ]._get_report_values([self.doc_non_printable.id]) + self.assertEqual(values["doc_ids"], [self.doc_non_printable.id]) diff --git a/document_page_tag_print_control/views/document_page_tag.xml b/document_page_tag_print_control/views/document_page_tag.xml new file mode 100644 index 00000000..1d3bafcf --- /dev/null +++ b/document_page_tag_print_control/views/document_page_tag.xml @@ -0,0 +1,53 @@ + + + + + document.page.tag.form.extended + document.page.tag + + + + + + + + + + document.page.tag.tree.extended + document.page.tag + + + + + + + + + + document.page.tag.search.extended + document.page.tag + + + + + + + + + + + + + diff --git a/setup/document_page_tag_print_control/odoo/addons/document_page_tag_print_control b/setup/document_page_tag_print_control/odoo/addons/document_page_tag_print_control new file mode 120000 index 00000000..090c37a5 --- /dev/null +++ b/setup/document_page_tag_print_control/odoo/addons/document_page_tag_print_control @@ -0,0 +1 @@ +../../../../document_page_tag_print_control \ No newline at end of file diff --git a/setup/document_page_tag_print_control/setup.py b/setup/document_page_tag_print_control/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/document_page_tag_print_control/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)