From 1b7c6b5d91048387df9a9f8a037b785e747cfb16 Mon Sep 17 00:00:00 2001 From: Yoshi Tashiro Date: Sat, 28 Aug 2021 15:54:11 +0800 Subject: [PATCH 01/24] [ADD] attachment_delete_restrict --- attachment_delete_restrict/README.rst | 87 ++++ attachment_delete_restrict/__init__.py | 1 + attachment_delete_restrict/__manifest__.py | 17 + attachment_delete_restrict/i18n/ja.po | 97 ++++ attachment_delete_restrict/models/__init__.py | 4 + .../models/ir_attachment.py | 40 ++ attachment_delete_restrict/models/ir_model.py | 26 ++ .../models/res_groups.py | 15 + .../models/res_users.py | 14 + .../readme/CONFIGURE.rst | 9 + .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 2 + .../static/description/index.html | 434 ++++++++++++++++++ attachment_delete_restrict/tests/__init__.py | 1 + .../tests/test_attachment_delete_restrict.py | 44 ++ .../views/ir_model_views.xml | 29 ++ .../views/res_groups_views.xml | 24 + .../views/res_users_views.xml | 24 + 18 files changed, 869 insertions(+) create mode 100644 attachment_delete_restrict/README.rst create mode 100644 attachment_delete_restrict/__init__.py create mode 100644 attachment_delete_restrict/__manifest__.py create mode 100644 attachment_delete_restrict/i18n/ja.po create mode 100644 attachment_delete_restrict/models/__init__.py create mode 100644 attachment_delete_restrict/models/ir_attachment.py create mode 100644 attachment_delete_restrict/models/ir_model.py create mode 100644 attachment_delete_restrict/models/res_groups.py create mode 100644 attachment_delete_restrict/models/res_users.py create mode 100644 attachment_delete_restrict/readme/CONFIGURE.rst create mode 100644 attachment_delete_restrict/readme/CONTRIBUTORS.rst create mode 100644 attachment_delete_restrict/readme/DESCRIPTION.rst create mode 100644 attachment_delete_restrict/static/description/index.html create mode 100644 attachment_delete_restrict/tests/__init__.py create mode 100644 attachment_delete_restrict/tests/test_attachment_delete_restrict.py create mode 100644 attachment_delete_restrict/views/ir_model_views.xml create mode 100644 attachment_delete_restrict/views/res_groups_views.xml create mode 100644 attachment_delete_restrict/views/res_users_views.xml diff --git a/attachment_delete_restrict/README.rst b/attachment_delete_restrict/README.rst new file mode 100644 index 00000000000..a8b8a5aa77f --- /dev/null +++ b/attachment_delete_restrict/README.rst @@ -0,0 +1,87 @@ +================================ +Restrict Deletion of Attachments +================================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/12.0/attachment_delete_restrict + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-attachment_delete_restrict + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/149/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides the ability to restrict the deletion of the attachments to certain +groups or users per related model. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +#. Go to *Settings > Techinical > Database Structure > Models*. +#. Open a model for which attachment deletion should be restricted. +#. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or + 'Attachment Deletion Users' as necessary (if no assignment, no one can delete the + attachments of this model). + +For assigning 'Attachment Deletion Groups'/'Attachment Deletion Users' to the model, +you can alternatively add the model in the 'Attachment Deletion Models' tab in the +respective group/user form. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Quartile Limited + +Contributors +~~~~~~~~~~~~ + +* Yoshi Tashiro + +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/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_delete_restrict/__init__.py b/attachment_delete_restrict/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/attachment_delete_restrict/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py new file mode 100644 index 00000000000..3121791076c --- /dev/null +++ b/attachment_delete_restrict/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Restrict Deletion of Attachments", + "version": "12.0.1.0.0", + "depends": ["base"], + "website": "https://github.com/OCA/server-tools", + "author": "Quartile Limited, Odoo Community Association (OCA)", + "category": "Tools", + "license": "AGPL-3", + "data": [ + "views/ir_model_views.xml", + "views/res_groups_views.xml", + "views/res_users_views.xml", + ], + "installable": True, +} diff --git a/attachment_delete_restrict/i18n/ja.po b/attachment_delete_restrict/i18n/ja.po new file mode 100644 index 00000000000..c5f194ef637 --- /dev/null +++ b/attachment_delete_restrict/i18n/ja.po @@ -0,0 +1,97 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_delete_restrict +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-08-29 14:47+0000\n" +"PO-Revision-Date: 2021-08-29 14:47+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_groups +msgid "Access Groups" +msgstr "アクセスグループ" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_attachment +msgid "Attachment" +msgstr "添付" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "Attachment Deletion Groups" +msgstr "添付削除グループ" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_groups_form +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_users_form +msgid "Attachment Deletion Models" +msgstr "添付削除モデル" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "Attachment Deletion Users" +msgstr "添付削除ユーザ" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_model +msgid "Models" +msgstr "モデル" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "Restrict Attachment Deletion" +msgstr "添付削除を制限" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +msgid "The user can delete the attachments related to the models assigned here." +msgstr "ユーザはここで割り当てられたモデルの添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "The users in the groups selected here can delete the attachments related to this model." +msgstr "ここで選択されたグループのユーザはこのモデルに関連する添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +msgid "The users of the group can delete the attachments related to the models assigned here." +msgstr "グループのユーザはここで割り当てられたモデルの添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "The users selected here can delete the attachments related to this model." +msgstr "ここで選択されたユーザはこのモデルに関連する添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_users +msgid "Users" +msgstr "ユーザ" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "When selected, the deletion of the attachments related to this model is restricted to certain users." +msgstr "選択された場合、このモデルに関連する添付の削除は許可されたユーザのみに制限されます。" + +#. module: attachment_delete_restrict +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:34 +#, python-format +msgid "You are not allowed to delete this attachment.\n" +"\n" +"Users with the delete permission:\n" +"%s" +msgstr "この添付の削除権限がありません。\n" +"\n" +"削除権限を持つユーザ:\n" +"%s" + diff --git a/attachment_delete_restrict/models/__init__.py b/attachment_delete_restrict/models/__init__.py new file mode 100644 index 00000000000..92c0bbcbe1e --- /dev/null +++ b/attachment_delete_restrict/models/__init__.py @@ -0,0 +1,4 @@ +from . import ir_attachment +from . import ir_model +from . import res_groups +from . import res_users diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py new file mode 100644 index 00000000000..f9587ac0714 --- /dev/null +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -0,0 +1,40 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, models +from odoo.exceptions import ValidationError + + +class IrAttachment(models.Model): + _inherit = "ir.attachment" + + @api.multi + def unlink(self): + for rec in self: + if not rec.res_model: + continue + model = self.env["ir.model"].search( + [ + ("model", "=", rec.res_model), + ("restrict_delete_attachment", "=", True), + ] + ) + if not model: + continue + groups = model.delete_attachment_group_ids + if groups and self.env.user in groups.mapped("users"): + continue + users = model.delete_attachment_user_ids + if users and self.env.user in users: + continue + user_names = "\n".join( + list(set(groups.mapped("users").mapped("name") + users.mapped("name"))) + ) + raise ValidationError( + _( + "You are not allowed to delete this attachment.\n\nUsers with " + "the delete permission:\n%s" + ) + % (user_names or "None") + ) + return super().unlink() diff --git a/attachment_delete_restrict/models/ir_model.py b/attachment_delete_restrict/models/ir_model.py new file mode 100644 index 00000000000..dedb19e4100 --- /dev/null +++ b/attachment_delete_restrict/models/ir_model.py @@ -0,0 +1,26 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class IrAttachment(models.Model): + _inherit = "ir.model" + + restrict_delete_attachment = fields.Boolean( + string="Restrict Attachment Deletion", + help="When selected, the deletion of the attachments related to this model is " + "restricted to certain users.", + ) + delete_attachment_group_ids = fields.Many2many( + "res.groups", + string="Attachment Deletion Groups", + help="The users in the groups selected here can delete the attachments related " + "to this model.", + ) + delete_attachment_user_ids = fields.Many2many( + "res.users", + string="Attachment Deletion Users", + help="The users selected here can delete the attachments related to this " + "model.", + ) diff --git a/attachment_delete_restrict/models/res_groups.py b/attachment_delete_restrict/models/res_groups.py new file mode 100644 index 00000000000..88d3987009f --- /dev/null +++ b/attachment_delete_restrict/models/res_groups.py @@ -0,0 +1,15 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResGroups(models.Model): + _inherit = "res.groups" + + delete_attachment_model_ids = fields.Many2many( + "ir.model", + string="Attachment Deletion Models", + help="The users of the group can delete the attachments related to the models " + "assigned here.", + ) diff --git a/attachment_delete_restrict/models/res_users.py b/attachment_delete_restrict/models/res_users.py new file mode 100644 index 00000000000..2d6c2cee4ac --- /dev/null +++ b/attachment_delete_restrict/models/res_users.py @@ -0,0 +1,14 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + delete_attachment_model_ids = fields.Many2many( + "ir.model", + string="Attachment Deletion Models", + help="The user can delete the attachments related to the models assigned here.", + ) diff --git a/attachment_delete_restrict/readme/CONFIGURE.rst b/attachment_delete_restrict/readme/CONFIGURE.rst new file mode 100644 index 00000000000..2227c6bbaf1 --- /dev/null +++ b/attachment_delete_restrict/readme/CONFIGURE.rst @@ -0,0 +1,9 @@ +#. Go to *Settings > Techinical > Database Structure > Models*. +#. Open a model for which attachment deletion should be restricted. +#. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or + 'Attachment Deletion Users' as necessary (if no assignment, no one can delete the + attachments of this model). + +For assigning 'Attachment Deletion Groups'/'Attachment Deletion Users' to the model, +you can alternatively add the model in the 'Attachment Deletion Models' tab in the +respective group/user form. diff --git a/attachment_delete_restrict/readme/CONTRIBUTORS.rst b/attachment_delete_restrict/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..599d1f834f3 --- /dev/null +++ b/attachment_delete_restrict/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Yoshi Tashiro diff --git a/attachment_delete_restrict/readme/DESCRIPTION.rst b/attachment_delete_restrict/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..792dd641fcd --- /dev/null +++ b/attachment_delete_restrict/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module provides the ability to restrict the deletion of the attachments to certain +groups or users per related model. diff --git a/attachment_delete_restrict/static/description/index.html b/attachment_delete_restrict/static/description/index.html new file mode 100644 index 00000000000..3b9827967dc --- /dev/null +++ b/attachment_delete_restrict/static/description/index.html @@ -0,0 +1,434 @@ + + + + + + +Restrict Deletion of Attachments + + + +
+

Restrict Deletion of Attachments

+ + +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module provides the ability to restrict the deletion of the attachments to certain +groups or users per related model.

+

Table of contents

+ +
+

Configuration

+
    +
  1. Go to Settings > Techinical > Database Structure > Models.
  2. +
  3. Open a model for which attachment deletion should be restricted.
  4. +
  5. Select ‘Restrict Attachment Deletion’, and assign ‘Attachment Deletion Groups’ and/or +‘Attachment Deletion Users’ as necessary (if no assignment, no one can delete the +attachments of this model).
  6. +
+

For assigning ‘Attachment Deletion Groups’/’Attachment Deletion Users’ to the model, +you can alternatively add the model in the ‘Attachment Deletion Models’ tab in the +respective group/user form.

+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Quartile Limited
  • +
+
+
+

Contributors

+ +
+
+

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/server-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/attachment_delete_restrict/tests/__init__.py b/attachment_delete_restrict/tests/__init__.py new file mode 100644 index 00000000000..c6f40a3f2fb --- /dev/null +++ b/attachment_delete_restrict/tests/__init__.py @@ -0,0 +1 @@ +from . import test_attachment_delete_restrict diff --git a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py new file mode 100644 index 00000000000..8d1e595c64e --- /dev/null +++ b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py @@ -0,0 +1,44 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.tests import SavepointCase, tagged + + +@tagged("post_install", "-at_install") +class TestAttachmentDeleteRestrict(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")]) + cls.test_group = cls.env["res.groups"].create({"name": "test group"}) + cls.test_user = cls.env["res.users"].create( + {"name": "test user", "login": "test@example.com"} + ) + cls.test_attachment = cls.env["ir.attachment"].create( + {"name": "test attachment", "type": "binary", "res_model": "res.partner"} + ) + + def test_01_delete_attachment_unrestricted(self): + self.test_attachment.sudo(self.test_user).unlink() + + def test_02_delete_attachment_restricted_user_permitted(self): + self.partner_model.write({"restrict_delete_attachment": True}) + with self.assertRaises(ValidationError): + self.test_attachment.sudo(self.test_user).unlink() + self.partner_model.write( + {"delete_attachment_user_ids": [(4, self.test_user.id)]} + ) + self.test_attachment.sudo(self.test_user).unlink() + + def test_03_delete_attachment_restricted_group_permitted(self): + self.partner_model.write({"restrict_delete_attachment": True}) + with self.assertRaises(ValidationError): + self.test_attachment.sudo(self.test_user).unlink() + self.partner_model.write( + {"delete_attachment_group_ids": [(4, self.test_group.id)]} + ) + with self.assertRaises(ValidationError): + self.test_attachment.sudo(self.test_user).unlink() + self.test_user.write({"groups_id": [(4, self.test_group.id)]}) + self.test_attachment.sudo(self.test_user).unlink() diff --git a/attachment_delete_restrict/views/ir_model_views.xml b/attachment_delete_restrict/views/ir_model_views.xml new file mode 100644 index 00000000000..6c17fd164fc --- /dev/null +++ b/attachment_delete_restrict/views/ir_model_views.xml @@ -0,0 +1,29 @@ + + + + ir.model form + ir.model + + + + + + + + + + + + + + + + diff --git a/attachment_delete_restrict/views/res_groups_views.xml b/attachment_delete_restrict/views/res_groups_views.xml new file mode 100644 index 00000000000..626860c40e7 --- /dev/null +++ b/attachment_delete_restrict/views/res_groups_views.xml @@ -0,0 +1,24 @@ + + + + res.groups.form + res.groups + + + + + + + + + + + + diff --git a/attachment_delete_restrict/views/res_users_views.xml b/attachment_delete_restrict/views/res_users_views.xml new file mode 100644 index 00000000000..8ed77fe28b9 --- /dev/null +++ b/attachment_delete_restrict/views/res_users_views.xml @@ -0,0 +1,24 @@ + + + + res.users.form + res.users + + + + + + + + + + + + From b3db51ce17a20c9e7439a70366d01a7b39494c4b Mon Sep 17 00:00:00 2001 From: Kev-Roche Date: Thu, 12 May 2022 19:59:34 +0200 Subject: [PATCH 02/24] [IMP] attachment_delete_restrict: black, isort, prettier --- attachment_delete_restrict/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py index 3121791076c..58485c0364f 100644 --- a/attachment_delete_restrict/__manifest__.py +++ b/attachment_delete_restrict/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Restrict Deletion of Attachments", - "version": "12.0.1.0.0", + "version": "14.0.1.0.0", "depends": ["base"], "website": "https://github.com/OCA/server-tools", "author": "Quartile Limited, Odoo Community Association (OCA)", From e34ffbe8ad8e43d9a8ce0ef67a7fa2ae6b492d99 Mon Sep 17 00:00:00 2001 From: Kev-Roche Date: Thu, 12 May 2022 22:58:41 +0200 Subject: [PATCH 03/24] [MIG] attachment_delete_restrict: Migration to 14.0 --- attachment_delete_restrict/__init__.py | 1 + attachment_delete_restrict/__manifest__.py | 10 +- attachment_delete_restrict/hooks.py | 23 ++ attachment_delete_restrict/i18n/fr.po | 199 ++++++++++++++++++ attachment_delete_restrict/models/__init__.py | 1 + .../models/ir_attachment.py | 80 ++++--- attachment_delete_restrict/models/ir_model.py | 20 +- .../models/res_config.py | 22 ++ .../models/res_groups.py | 3 +- .../models/res_users.py | 4 +- .../readme/CONFIGURE.rst | 15 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 3 +- .../tests/test_attachment_delete_restrict.py | 76 +++++-- .../views/ir_model_views.xml | 3 +- .../views/res_config_view.xml | 32 +++ .../views/res_groups_views.xml | 2 +- .../views/res_users_views.xml | 2 +- 18 files changed, 445 insertions(+), 52 deletions(-) create mode 100644 attachment_delete_restrict/hooks.py create mode 100644 attachment_delete_restrict/i18n/fr.po create mode 100644 attachment_delete_restrict/models/res_config.py create mode 100644 attachment_delete_restrict/views/res_config_view.xml diff --git a/attachment_delete_restrict/__init__.py b/attachment_delete_restrict/__init__.py index 0650744f6bc..cc6b6354ad8 100644 --- a/attachment_delete_restrict/__init__.py +++ b/attachment_delete_restrict/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py index 58485c0364f..cf1db289481 100644 --- a/attachment_delete_restrict/__manifest__.py +++ b/attachment_delete_restrict/__manifest__.py @@ -3,15 +3,21 @@ { "name": "Restrict Deletion of Attachments", "version": "14.0.1.0.0", - "depends": ["base"], + "depends": [ + "base", + "base_setup", + ], "website": "https://github.com/OCA/server-tools", - "author": "Quartile Limited, Odoo Community Association (OCA)", + "author": "Quartile Limited, Akretion, Odoo Community Association (OCA)", "category": "Tools", "license": "AGPL-3", + "maintainers": ["Kev-Roche", "yostashiro"], "data": [ "views/ir_model_views.xml", "views/res_groups_views.xml", "views/res_users_views.xml", + "views/res_config_view.xml", ], "installable": True, + "post_init_hook": "post_init_hook", } diff --git a/attachment_delete_restrict/hooks.py b/attachment_delete_restrict/hooks.py new file mode 100644 index 00000000000..ccc840c2d02 --- /dev/null +++ b/attachment_delete_restrict/hooks.py @@ -0,0 +1,23 @@ +# Copyright (C) 2022 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID, api + + +def post_init_hook(cr, registry): + # if previous configuration exist on delete_attachment_group_ids or + # delete_attachment_user_ids, change the default level of + # attachment deletion at 'custom' to keep it. + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + previous_group_or_user = False + for model in env["ir.model"].search([]): + if model.delete_attachment_group_ids or model.delete_attachment_user_ids: + model.is_restrict_delete_attachment = True + previous_group_or_user = True + + if previous_group_or_user: + env["ir.config_parameter"].sudo().set_param( + "restrict_delete_attachment", "custom" + ) diff --git a/attachment_delete_restrict/i18n/fr.po b/attachment_delete_restrict/i18n/fr.po new file mode 100644 index 00000000000..49ef4606e0c --- /dev/null +++ b/attachment_delete_restrict/i18n/fr.po @@ -0,0 +1,199 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_delete_restrict +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-05-12 20:36+0000\n" +"PO-Revision-Date: 2022-05-12 22:47+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 3.0.1\n" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_groups +msgid "Access Groups" +msgstr "Groupes d'accès" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_attachment +msgid "Attachment" +msgstr "Pièce jointe" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "Attachment Deletion Groups" +msgstr "Groupe avec droit de suppression de PJ" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_groups_form +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_users_form +msgid "Attachment Deletion Models" +msgstr "Modèle avec restrictions de suppression de PJ" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "Attachment Deletion Users" +msgstr "Utilisateurs avec droit de suppression de PJ" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_config_settings +msgid "Config Settings" +msgstr "Paramètres de config" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__custom +msgid "Custom: For each model, selected groups and users can delete them" +msgstr "" +"Personnalisé: Pour chaque modèle, sélectionner les groupes et/ou " +"utilisateurs ayant le droit" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__id +msgid "ID" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__is_restrict_delete_attachment +msgid "Model with Restrict Attachment Deletion" +msgstr "Modèle avec restrictions de suppression de PJ" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_model +msgid "Models" +msgstr "Modèles" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__none +msgid "No restriction: All users / groups can delete them" +msgstr "" +"Aucune restrictions: Tous les utilisateurs / groupes peuvent supprimer" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__restrict_delete_attachment +msgid "Restrict Delete Attachment" +msgstr "Restreindre la suppression de PJs" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Restrict Deletion on attachment" +msgstr "Restreindre la suppression de PJs" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Select level of delete restriction on attachments" +msgstr "Selectionner la restriction pour supprimer les PJs" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__strict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__strict +msgid "Strict: Only creator and admin can delete them" +msgstr "" +"Strict : Seuls le créateur et les administrateurs peuvent les supprimer" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +msgid "" +"The user can delete the attachments related to the models assigned here. In " +"general settings, 'Restrict Delete Attachment' must be set as 'custom' to " +"activate this setting." +msgstr "" +"L'utilisateur peut supprimer les pièces jointes reliées au modèle assigné " +"ici. Dans la configuration générale, \"Restreindre la suppression de PJs\" " +"doit être à \"Personnalisé\" pour que cela s'active." + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "" +"The users in the groups selected here can delete the attachments related to " +"this model." +msgstr "" +"Les utilisateurs de ces groupes peuvent supprimer les pièces jointes de ce " +"modèle." + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +msgid "" +"The users of the group can delete the attachments related to the models " +"assigned here. In general settings, 'Restrict Delete Attachment' must be " +"set as 'custom' to activate this setting." +msgstr "" +"Les utilisateurs de ce groupe peuvent supprimer les pièces jointes reliées " +"au modèle assigné ici. Dans la configuration générale, \"Restreindre la " +"suppression de PJs\" doit être à \"Personnalisé\" pour que cela s'active." + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "" +"The users selected here can delete the attachments related to this model." +msgstr "Ces utilisateurs peuvent supprimer les pièces jointes de ce modèle." + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_users +msgid "Users" +msgstr "Utilisateurs" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__is_restrict_delete_attachment +msgid "" +"When selected, the deletion of the attachments related to this model is " +"restricted to certain users." +msgstr "" + +#. module: attachment_delete_restrict +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 +#, python-format +msgid "" +"You are not allowed to delete this attachment.\n" +"\n" +"Users with the delete permission:\n" +"%s" +msgstr "" +"Vous n'êtes pas autorisé à supprimer cette pièce jointe.\n" +"\n" +"Utilisateurs ayant la permission:\n" +"%s" + +#. module: attachment_delete_restrict +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 +#, python-format +msgid "" +"You are not allowed to delete this attachment.\n" +"Only the owner and administrators can delete it." +msgstr "" +"Vous n'êtes pas autorisé à supprimer cette pièce jointe.\n" +"Seulement son créateur et les administrateurs ont le droit." diff --git a/attachment_delete_restrict/models/__init__.py b/attachment_delete_restrict/models/__init__.py index 92c0bbcbe1e..53b5a8681e4 100644 --- a/attachment_delete_restrict/models/__init__.py +++ b/attachment_delete_restrict/models/__init__.py @@ -2,3 +2,4 @@ from . import ir_model from . import res_groups from . import res_users +from . import res_config diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py index f9587ac0714..009bec1fcf4 100644 --- a/attachment_delete_restrict/models/ir_attachment.py +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -1,40 +1,62 @@ # Copyright 2021 Quartile Limited # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, models +from odoo import _, models from odoo.exceptions import ValidationError class IrAttachment(models.Model): _inherit = "ir.attachment" - @api.multi def unlink(self): - for rec in self: - if not rec.res_model: - continue - model = self.env["ir.model"].search( - [ - ("model", "=", rec.res_model), - ("restrict_delete_attachment", "=", True), - ] - ) - if not model: - continue - groups = model.delete_attachment_group_ids - if groups and self.env.user in groups.mapped("users"): - continue - users = model.delete_attachment_user_ids - if users and self.env.user in users: - continue - user_names = "\n".join( - list(set(groups.mapped("users").mapped("name") + users.mapped("name"))) - ) - raise ValidationError( - _( - "You are not allowed to delete this attachment.\n\nUsers with " - "the delete permission:\n%s" - ) - % (user_names or "None") - ) + restriction = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("restrict_delete_attachment") + ) + if restriction != "none": + for rec in self: + if restriction == "strict": + if rec.create_uid == self.env.user or self.user_has_groups( + "base.group_system" + ): + continue + raise ValidationError( + _( + "You are not allowed to delete this attachment.\n" + "Only the owner and administrators can delete it." + ) + ) + if restriction == "custom": + if not rec.res_model: + continue + model = self.env["ir.model"].search( + [ + ("model", "=", rec.res_model), + ("is_restrict_delete_attachment", "=", True), + ] + ) + if not model: + continue + groups = model.delete_attachment_group_ids + if groups and self.env.user in groups.mapped("users"): + continue + users = model.delete_attachment_user_ids + if users and self.env.user in users: + continue + user_names = "\n".join( + list( + set( + groups.mapped("users").mapped("name") + + users.mapped("name") + ) + ) + ) + raise ValidationError( + _( + "You are not allowed to delete this attachment.\n\nUsers with " + "the delete permission:\n%s" + ) + % (user_names or "None") + ) return super().unlink() diff --git a/attachment_delete_restrict/models/ir_model.py b/attachment_delete_restrict/models/ir_model.py index dedb19e4100..ec29ba98812 100644 --- a/attachment_delete_restrict/models/ir_model.py +++ b/attachment_delete_restrict/models/ir_model.py @@ -3,15 +3,31 @@ from odoo import fields, models +from .res_config import RESTRICT_DELETE_ATTACH + class IrAttachment(models.Model): _inherit = "ir.model" - restrict_delete_attachment = fields.Boolean( - string="Restrict Attachment Deletion", + restrict_delete_attachment = fields.Selection( + selection=RESTRICT_DELETE_ATTACH, + compute="_compute_restrict_delete_attachment", + readonly=True, + ) + + def _compute_restrict_delete_attachment(self): + return ( + self.env["ir.config_parameter"] + .sudo() + .get_param("restrict_delete_attachment") + ) + + is_restrict_delete_attachment = fields.Boolean( + string="Model with Restrict Attachment Deletion", help="When selected, the deletion of the attachments related to this model is " "restricted to certain users.", ) + delete_attachment_group_ids = fields.Many2many( "res.groups", string="Attachment Deletion Groups", diff --git a/attachment_delete_restrict/models/res_config.py b/attachment_delete_restrict/models/res_config.py new file mode 100644 index 00000000000..9b25df23acb --- /dev/null +++ b/attachment_delete_restrict/models/res_config.py @@ -0,0 +1,22 @@ +# Copyright (C) 2022 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +RESTRICT_DELETE_ATTACH = [ + ("strict", "Strict: Only creator and admin can delete them"), + ("custom", "Custom: For each model, selected groups and users can delete them"), + ("none", "No restriction: All users / groups can delete them"), +] + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + restrict_delete_attachment = fields.Selection( + selection=RESTRICT_DELETE_ATTACH, + readonly=False, + required=True, + default="strict", + ) diff --git a/attachment_delete_restrict/models/res_groups.py b/attachment_delete_restrict/models/res_groups.py index 88d3987009f..f3048a7557e 100644 --- a/attachment_delete_restrict/models/res_groups.py +++ b/attachment_delete_restrict/models/res_groups.py @@ -11,5 +11,6 @@ class ResGroups(models.Model): "ir.model", string="Attachment Deletion Models", help="The users of the group can delete the attachments related to the models " - "assigned here.", + "assigned here. In general settings, 'Restrict Delete " + "Attachment' must be set as 'custom' to activate this setting.", ) diff --git a/attachment_delete_restrict/models/res_users.py b/attachment_delete_restrict/models/res_users.py index 2d6c2cee4ac..837f1e21e66 100644 --- a/attachment_delete_restrict/models/res_users.py +++ b/attachment_delete_restrict/models/res_users.py @@ -10,5 +10,7 @@ class ResUsers(models.Model): delete_attachment_model_ids = fields.Many2many( "ir.model", string="Attachment Deletion Models", - help="The user can delete the attachments related to the models assigned here.", + help="The user can delete the attachments related to the " + "models assigned here. In general settings, 'Restrict Delete " + "Attachment' must be set as 'custom' to activate this setting.", ) diff --git a/attachment_delete_restrict/readme/CONFIGURE.rst b/attachment_delete_restrict/readme/CONFIGURE.rst index 2227c6bbaf1..103d10a51ff 100644 --- a/attachment_delete_restrict/readme/CONFIGURE.rst +++ b/attachment_delete_restrict/readme/CONFIGURE.rst @@ -1,3 +1,18 @@ +Select level: +============= +#. Go to *Settings > General Settings> Permission section*. +#. Choose the level of *Restrict Delete Attachment* (strict by default). + +Three levels: +============= +* Strict : Owner and admins only (by default) +* Custom : Certain groups or users per related model. +* None : all users can delete them + +Only Custom needs specific configuration. + +For Custom level: +================= #. Go to *Settings > Techinical > Database Structure > Models*. #. Open a model for which attachment deletion should be restricted. #. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or diff --git a/attachment_delete_restrict/readme/CONTRIBUTORS.rst b/attachment_delete_restrict/readme/CONTRIBUTORS.rst index 599d1f834f3..374eca48aed 100644 --- a/attachment_delete_restrict/readme/CONTRIBUTORS.rst +++ b/attachment_delete_restrict/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Yoshi Tashiro +* Kévin Roche diff --git a/attachment_delete_restrict/readme/DESCRIPTION.rst b/attachment_delete_restrict/readme/DESCRIPTION.rst index 792dd641fcd..83c443b24d9 100644 --- a/attachment_delete_restrict/readme/DESCRIPTION.rst +++ b/attachment_delete_restrict/readme/DESCRIPTION.rst @@ -1,2 +1 @@ -This module provides the ability to restrict the deletion of the attachments to certain -groups or users per related model. +This module provides the ability to restrict the deletion of the attachments at different levels. diff --git a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py index 8d1e595c64e..b0c054ffcd3 100644 --- a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py +++ b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py @@ -10,35 +10,87 @@ class TestAttachmentDeleteRestrict(SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() + cls.env["ir.config_parameter"].sudo().set_param( + "restrict_delete_attachment", "custom" + ) cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")]) cls.test_group = cls.env["res.groups"].create({"name": "test group"}) cls.test_user = cls.env["res.users"].create( - {"name": "test user", "login": "test@example.com"} + { + "name": "test user", + "login": "test@example.com", + "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], + } + ) + cls.test_user2 = cls.env["res.users"].create( + { + "name": "test user2", + "login": "test2@example.com", + "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], + } + ) + cls.test_admin = cls.env["res.users"].create( + { + "name": "User admin", + "login": "admin@example.com", + "groups_id": [(6, 0, cls.env.ref("base.group_system").ids)], + } ) cls.test_attachment = cls.env["ir.attachment"].create( {"name": "test attachment", "type": "binary", "res_model": "res.partner"} ) - def test_01_delete_attachment_unrestricted(self): - self.test_attachment.sudo(self.test_user).unlink() + def test_01_custom_delete_attachment_unrestricted(self): + self.test_attachment.with_user(self.test_user).unlink() - def test_02_delete_attachment_restricted_user_permitted(self): - self.partner_model.write({"restrict_delete_attachment": True}) + def test_02_custom_delete_attachment_restricted_user_permitted(self): + self.partner_model.write({"is_restrict_delete_attachment": True}) with self.assertRaises(ValidationError): - self.test_attachment.sudo(self.test_user).unlink() + self.test_attachment.with_user(self.test_user).unlink() self.partner_model.write( {"delete_attachment_user_ids": [(4, self.test_user.id)]} ) - self.test_attachment.sudo(self.test_user).unlink() + self.test_attachment.with_user(self.test_user).unlink() - def test_03_delete_attachment_restricted_group_permitted(self): - self.partner_model.write({"restrict_delete_attachment": True}) + def test_03_custom_delete_attachment_restricted_group_permitted(self): + self.partner_model.write({"is_restrict_delete_attachment": True}) with self.assertRaises(ValidationError): - self.test_attachment.sudo(self.test_user).unlink() + self.test_attachment.with_user(self.test_user).unlink() self.partner_model.write( {"delete_attachment_group_ids": [(4, self.test_group.id)]} ) with self.assertRaises(ValidationError): - self.test_attachment.sudo(self.test_user).unlink() + self.test_attachment.with_user(self.test_user).unlink() self.test_user.write({"groups_id": [(4, self.test_group.id)]}) - self.test_attachment.sudo(self.test_user).unlink() + self.test_attachment.with_user(self.test_user).unlink() + + def test_04_strict_owner_can_delete_attachment(self): + self.env["ir.config_parameter"].sudo().set_param( + "restrict_delete_attachment", "strict" + ) + test_attachment_2 = ( + self.env["ir.attachment"] + .with_user(self.test_user) + .create( + { + "name": "test attachment 2", + "type": "binary", + "res_model": "res.partner", + } + ) + ) + with self.assertRaises(ValidationError): + test_attachment_2.with_user(self.test_user2).unlink() + test_attachment_2.with_user(self.test_user).unlink() + + def test_05_strict_admin_can_delete_attachment(self): + self.env["ir.config_parameter"].sudo().set_param( + "restrict_delete_attachment", "strict" + ) + self.test_attachment.with_user(self.test_admin).unlink() + + def test_06_none_no_restriction(self): + self.env["ir.config_parameter"].sudo().set_param( + "restrict_delete_attachment", "none" + ) + self.test_attachment.with_user(self.test_user2).unlink() diff --git a/attachment_delete_restrict/views/ir_model_views.xml b/attachment_delete_restrict/views/ir_model_views.xml index 6c17fd164fc..00b23ba17ba 100644 --- a/attachment_delete_restrict/views/ir_model_views.xml +++ b/attachment_delete_restrict/views/ir_model_views.xml @@ -11,8 +11,9 @@ + + + + res.config.settings.attachment.delete.restrict + res.config.settings + + + +
+
+
+
+
+
+
+
diff --git a/attachment_delete_restrict/views/res_groups_views.xml b/attachment_delete_restrict/views/res_groups_views.xml index 626860c40e7..4e3d744bf48 100644 --- a/attachment_delete_restrict/views/res_groups_views.xml +++ b/attachment_delete_restrict/views/res_groups_views.xml @@ -13,7 +13,7 @@ diff --git a/attachment_delete_restrict/views/res_users_views.xml b/attachment_delete_restrict/views/res_users_views.xml index 8ed77fe28b9..a4034613e05 100644 --- a/attachment_delete_restrict/views/res_users_views.xml +++ b/attachment_delete_restrict/views/res_users_views.xml @@ -13,7 +13,7 @@ From 37b9cdd6729e0d2454969be8c457fc43e8db597b Mon Sep 17 00:00:00 2001 From: Kev-Roche Date: Thu, 19 May 2022 10:58:28 +0200 Subject: [PATCH 04/24] rework module attachment_delete_restrict (to squash after review) --- attachment_delete_restrict/__init__.py | 1 - attachment_delete_restrict/__manifest__.py | 3 +- attachment_delete_restrict/hooks.py | 23 --- attachment_delete_restrict/i18n/fr.po | 95 ++++++++++--- .../migrations/14.0.1.0.0/post-migrate.py | 23 +++ .../migrations/14.0.1.0.0/pre-migrate.py | 16 +++ .../models/ir_attachment.py | 133 +++++++++++------- attachment_delete_restrict/models/ir_model.py | 36 ++--- .../models/res_config.py | 84 +++++++++-- .../models/res_groups.py | 3 +- .../models/res_users.py | 4 +- .../readme/CONFIGURE.rst | 7 +- .../tests/test_attachment_delete_restrict.py | 132 ++++++++++++++--- .../views/ir_model_views.xml | 3 +- .../views/res_config_view.xml | 48 ++++++- .../views/res_groups_views.xml | 2 +- .../views/res_users_views.xml | 2 +- 17 files changed, 460 insertions(+), 155 deletions(-) delete mode 100644 attachment_delete_restrict/hooks.py create mode 100644 attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py create mode 100644 attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py diff --git a/attachment_delete_restrict/__init__.py b/attachment_delete_restrict/__init__.py index cc6b6354ad8..0650744f6bc 100644 --- a/attachment_delete_restrict/__init__.py +++ b/attachment_delete_restrict/__init__.py @@ -1,2 +1 @@ from . import models -from .hooks import post_init_hook diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py index cf1db289481..040eb39a47d 100644 --- a/attachment_delete_restrict/__manifest__.py +++ b/attachment_delete_restrict/__manifest__.py @@ -11,7 +11,7 @@ "author": "Quartile Limited, Akretion, Odoo Community Association (OCA)", "category": "Tools", "license": "AGPL-3", - "maintainers": ["Kev-Roche", "yostashiro"], + "maintainers": ["yostashiro", "Kev-Roche"], "data": [ "views/ir_model_views.xml", "views/res_groups_views.xml", @@ -19,5 +19,4 @@ "views/res_config_view.xml", ], "installable": True, - "post_init_hook": "post_init_hook", } diff --git a/attachment_delete_restrict/hooks.py b/attachment_delete_restrict/hooks.py deleted file mode 100644 index ccc840c2d02..00000000000 --- a/attachment_delete_restrict/hooks.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2022 Akretion (). -# @author Kévin Roche -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import SUPERUSER_ID, api - - -def post_init_hook(cr, registry): - # if previous configuration exist on delete_attachment_group_ids or - # delete_attachment_user_ids, change the default level of - # attachment deletion at 'custom' to keep it. - with api.Environment.manage(): - env = api.Environment(cr, SUPERUSER_ID, {}) - previous_group_or_user = False - for model in env["ir.model"].search([]): - if model.delete_attachment_group_ids or model.delete_attachment_user_ids: - model.is_restrict_delete_attachment = True - previous_group_or_user = True - - if previous_group_or_user: - env["ir.config_parameter"].sudo().set_param( - "restrict_delete_attachment", "custom" - ) diff --git a/attachment_delete_restrict/i18n/fr.po b/attachment_delete_restrict/i18n/fr.po index 49ef4606e0c..788669f25a4 100644 --- a/attachment_delete_restrict/i18n/fr.po +++ b/attachment_delete_restrict/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-05-12 20:36+0000\n" -"PO-Revision-Date: 2022-05-12 22:47+0200\n" +"POT-Creation-Date: 2022-05-19 07:58+0000\n" +"PO-Revision-Date: 2022-05-19 10:07+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -29,6 +29,8 @@ msgstr "Pièce jointe" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__global_delete_attachment_group_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "Attachment Deletion Groups" msgstr "Groupe avec droit de suppression de PJ" @@ -42,9 +44,21 @@ msgstr "Modèle avec restrictions de suppression de PJ" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__global_delete_attachment_user_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "Attachment Deletion Users" msgstr "Utilisateurs avec droit de suppression de PJ" +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Groups:" +msgstr "Groupes autorisés:" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Users:" +msgstr "Utilisateurs autorisés:" + #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_config_settings msgid "Config Settings" @@ -52,12 +66,17 @@ msgstr "Paramètres de config" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom msgid "Custom: For each model, selected groups and users can delete them" msgstr "" "Personnalisé: Pour chaque modèle, sélectionner les groupes et/ou " "utilisateurs ayant le droit" +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Define a default value for Attachments Deletion" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__display_name @@ -67,6 +86,16 @@ msgstr "" msgid "Display Name" msgstr "Nom affiché" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids_str +msgid "Global Delete Attachment Group Ids Str" +msgstr "Groupe avec droit de suppression de toutes les PJs" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids_str +msgid "Global Delete Attachment User Ids Str" +msgstr "Utilisateurs avec droit de suppression de toutes les PJs" + #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id @@ -85,11 +114,6 @@ msgstr "" msgid "Last Modified on" msgstr "Dernière modification le" -#. module: attachment_delete_restrict -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__is_restrict_delete_attachment -msgid "Model with Restrict Attachment Deletion" -msgstr "Modèle avec restrictions de suppression de PJ" - #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_ir_model msgid "Models" @@ -97,16 +121,30 @@ msgstr "Modèles" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__none +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none msgid "No restriction: All users / groups can delete them" msgstr "" "Aucune restrictions: Tous les utilisateurs / groupes peuvent supprimer" +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__restrict_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__restrict_custom +msgid "" +"Restrict + Custom: Creator and admin can delete them + for each model, " +"selected groups and users can delete them" +msgstr "" +"Limité + personnalisé : Le propriétaire, les administrateurs et les " +"utilisateurs de certains groupes peuvent supprimer" + #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__restrict_delete_attachment -msgid "Restrict Delete Attachment" -msgstr "Restreindre la suppression de PJs" +msgid "Restrict Attachment Deletion" +msgstr "Suppression de PJs Limitée" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Restrict Delete Attachments" +msgstr "Suppression de PJs Limitée" #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form @@ -114,16 +152,16 @@ msgid "Restrict Deletion on attachment" msgstr "Restreindre la suppression de PJs" #. module: attachment_delete_restrict -#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form -msgid "Select level of delete restriction on attachments" -msgstr "Selectionner la restriction pour supprimer les PJs" +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__restrict +msgid "Restrict: Only creator and admin can delete them" +msgstr "" +"Limité : Seuls le propriétaire et les administrateurs peuvent supprimer" #. module: attachment_delete_restrict -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__strict -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__restrict_delete_attachment__strict -msgid "Strict: Only creator and admin can delete them" -msgstr "" -"Strict : Seuls le créateur et les administrateurs peuvent les supprimer" +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Select default level of delete restriction on attachments" +msgstr "Sélectionner le niveau de restriction sur les pièces jointes" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids @@ -136,6 +174,13 @@ msgstr "" "ici. Dans la configuration générale, \"Restreindre la suppression de PJs\" " "doit être à \"Personnalisé\" pour que cela s'active." +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__global_delete_attachment_group_ids +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +msgid "The users in the groups selected here can delete all the attachments." +msgstr "" +"Les utilisateurs de ce groupe peuvent supprimer toutes les pièces jointes." + #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids msgid "" @@ -156,6 +201,12 @@ msgstr "" "au modèle assigné ici. Dans la configuration générale, \"Restreindre la " "suppression de PJs\" doit être à \"Personnalisé\" pour que cela s'active." +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__global_delete_attachment_user_ids +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +msgid "The users selected here can delete all the attachments" +msgstr "Ces utilisateurs peuvent supprimer toutes les pièces jointes" + #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids msgid "" @@ -168,11 +219,13 @@ msgid "Users" msgstr "Utilisateurs" #. module: attachment_delete_restrict -#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__is_restrict_delete_attachment +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment msgid "" "When selected, the deletion of the attachments related to this model is " "restricted to certain users." msgstr "" +"Une fois sélectionné, la suppression de pièces jointes de ce modèle est " +"restreinte à certains utilisateurs." #. module: attachment_delete_restrict #: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 diff --git a/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py b/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py new file mode 100644 index 00000000000..5fe21510d99 --- /dev/null +++ b/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py @@ -0,0 +1,23 @@ +# Copyright (C) 2022 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +from odoo.tools.sql import column_exists + + +@openupgrade.migrate() +def migrate(env, version): + if column_exists(env.cr, "ir_model", "migrated_restrict_delete_attachment"): + query = """ + SELECT id FROM ir_model WHERE migrated_restrict_delete_attachment = True + """ + env.cr.execute(query) + results = env.cr.fetchall() + models = env["ir.model"].search([("id", "in", results)]) + for model in models: + model.restrict_delete_attachment = "custom" + + query2 = "ALTER TABLE ir_model DROP COLUMN migrated_restrict_delete_attachment;" + env.cr.execute(query2) diff --git a/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py b/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py new file mode 100644 index 00000000000..61c6e2221bb --- /dev/null +++ b/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py @@ -0,0 +1,16 @@ +# Copyright (C) 2022 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo.tools.sql import column_exists, rename_column + + +def migrate(cr, version): + if column_exists(cr, "ir_model", "restrict_delete_attachment"): + rename_column( + cr, + "ir_model", + "restrict_delete_attachment", + "migrated_restrict_delete_attachment", + ) diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py index 009bec1fcf4..c59257e3dde 100644 --- a/attachment_delete_restrict/models/ir_attachment.py +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -1,6 +1,8 @@ # Copyright 2021 Quartile Limited # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from ast import literal_eval + from odoo import _, models from odoo.exceptions import ValidationError @@ -8,55 +10,86 @@ class IrAttachment(models.Model): _inherit = "ir.attachment" - def unlink(self): - restriction = ( - self.env["ir.config_parameter"] - .sudo() - .get_param("restrict_delete_attachment") + def _check_delete_attachment(self, model, restrict, mode): + if restrict == "restrict": + if self._check_restrict_delete_attachment(): + return + else: + self._raise_restrict_validation_error() + elif restrict == "custom": + self._check_custom_delete_attachment(model, mode) + elif restrict == "restrict_custom": + if self._check_restrict_delete_attachment(): + return + self._check_custom_delete_attachment(model, mode) + + def _check_restrict_delete_attachment(self): + if self.create_uid == self.env.user or self.user_has_groups( + "base.group_system" + ): + return True + else: + return False + + def _check_custom_delete_attachment(self, model, mode): + if not model and mode != "global": + return + groups = model.delete_attachment_group_ids + users = model.delete_attachment_user_ids + param = self.env["ir.config_parameter"].sudo() + groups_ids = param.get_param( + "attachment_delete_restrict.global_delete_attachment_group_ids" + ) + users_ids = param.get_param( + "attachment_delete_restrict.global_delete_attachment_user_ids" ) - if restriction != "none": - for rec in self: - if restriction == "strict": - if rec.create_uid == self.env.user or self.user_has_groups( - "base.group_system" - ): - continue - raise ValidationError( - _( - "You are not allowed to delete this attachment.\n" - "Only the owner and administrators can delete it." - ) - ) - if restriction == "custom": - if not rec.res_model: - continue - model = self.env["ir.model"].search( - [ - ("model", "=", rec.res_model), - ("is_restrict_delete_attachment", "=", True), - ] - ) - if not model: - continue - groups = model.delete_attachment_group_ids - if groups and self.env.user in groups.mapped("users"): - continue - users = model.delete_attachment_user_ids - if users and self.env.user in users: - continue - user_names = "\n".join( - list( - set( - groups.mapped("users").mapped("name") - + users.mapped("name") - ) - ) - ) - raise ValidationError( - _( - "You are not allowed to delete this attachment.\n\nUsers with " - "the delete permission:\n%s" - ) - % (user_names or "None") - ) + if mode == "global": + if groups_ids: + groups = self.env["res.groups"].search( + [("id", "in", literal_eval(groups_ids))] + ) + if users_ids: + users = self.env["res.users"].search( + [("id", "in", literal_eval(users_ids))] + ) + if groups and self.env.user in groups.mapped("users"): + return + if users and self.env.user in users: + return + list_group = "\n".join(list(set(groups.mapped("users").mapped("name")))) + list_user = "\n".join(list(set(users.mapped("name")))) + user_names = list_group + list_user + raise ValidationError( + _( + "You are not allowed to delete this attachment.\n\nUsers with " + "the delete permission:\n%s" + ) + % (user_names or "None") + ) + + def _raise_restrict_validation_error(self): + raise ValidationError( + _( + "You are not allowed to delete this attachment.\n" + "Only the owner and administrators can delete it." + ) + ) + + def unlink(self): + for rec in self: + if not rec.res_model: + continue + model = self.env["ir.model"].search([("model", "=", rec.res_model)]) + model_restrict = model.restrict_delete_attachment + global_restrict = ( + self.env["ir.config_parameter"] + .sudo() + .get_param( + "attachment_delete_restrict.global_restrict_delete_attachment" + ) + ) + if model_restrict == "default": + rec._check_delete_attachment(model, global_restrict, "global") + elif model_restrict not in ["default", "none"]: + rec._check_delete_attachment(model, model_restrict, "model") return super().unlink() diff --git a/attachment_delete_restrict/models/ir_model.py b/attachment_delete_restrict/models/ir_model.py index ec29ba98812..411d695bb14 100644 --- a/attachment_delete_restrict/models/ir_model.py +++ b/attachment_delete_restrict/models/ir_model.py @@ -3,40 +3,42 @@ from odoo import fields, models -from .res_config import RESTRICT_DELETE_ATTACH - - -class IrAttachment(models.Model): +RESTRICT_DELETE_ATTACH = [ + ("default", "Use global configuration"), + ("restrict", "Restrict: Only creator and admin can delete them"), + ("custom", "Custom: For each model, selected groups and users can " "delete them"), + ( + "restrict_custom", + "Restrict + Custom: Creator and admin can delete them + for " + "each model, selected groups and users can delete them", + ), + ("none", "No restriction: All users / groups can delete them"), +] + + +class IrModel(models.Model): _inherit = "ir.model" restrict_delete_attachment = fields.Selection( selection=RESTRICT_DELETE_ATTACH, - compute="_compute_restrict_delete_attachment", - readonly=True, - ) - - def _compute_restrict_delete_attachment(self): - return ( - self.env["ir.config_parameter"] - .sudo() - .get_param("restrict_delete_attachment") - ) - - is_restrict_delete_attachment = fields.Boolean( - string="Model with Restrict Attachment Deletion", + string="Restrict Attachment Deletion", help="When selected, the deletion of the attachments related to this model is " "restricted to certain users.", + default="default", ) delete_attachment_group_ids = fields.Many2many( "res.groups", string="Attachment Deletion Groups", + relation="delete_attachment_group_rel", help="The users in the groups selected here can delete the attachments related " "to this model.", ) + delete_attachment_user_ids = fields.Many2many( "res.users", string="Attachment Deletion Users", + relation="delete_attachment_user_rel", help="The users selected here can delete the attachments related to this " "model.", ) diff --git a/attachment_delete_restrict/models/res_config.py b/attachment_delete_restrict/models/res_config.py index 9b25df23acb..a471829d799 100644 --- a/attachment_delete_restrict/models/res_config.py +++ b/attachment_delete_restrict/models/res_config.py @@ -2,21 +2,89 @@ # @author Kévin Roche # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import api, fields, models -RESTRICT_DELETE_ATTACH = [ - ("strict", "Strict: Only creator and admin can delete them"), - ("custom", "Custom: For each model, selected groups and users can delete them"), - ("none", "No restriction: All users / groups can delete them"), -] +from .ir_model import RESTRICT_DELETE_ATTACH class ResConfigSettings(models.TransientModel): _inherit = "res.config.settings" - restrict_delete_attachment = fields.Selection( + global_restrict_delete_attachment = fields.Selection( selection=RESTRICT_DELETE_ATTACH, + config_parameter="attachment_delete_restrict.global_restrict_delete_attachment", readonly=False, required=True, - default="strict", + default="none", + string="Restrict Delete Attachments", + help="Define a default value for Attachments Deletion", ) + + global_delete_attachment_group_ids = fields.Many2many( + "res.groups", + string="Attachment Deletion Groups", + relation="global_delete_attachment_group_rel", + help="The users in the groups selected here can delete all the attachments.", + readonly=False, + compute="_compute_global_delete_attachment_group_ids", + inverse="_inverse_global_delete_attachment_group_ids", + ) + global_delete_attachment_group_ids_str = fields.Char( + string="", + config_parameter="attachment_delete_restrict.global_delete_attachment_group_ids", + ) + + global_delete_attachment_user_ids = fields.Many2many( + "res.users", + string="Attachment Deletion Users", + relation="global_delete_attachment_user_rel", + help="The users selected here can delete all the attachments", + readonly=False, + compute="_compute_global_delete_attachment_user_ids", + inverse="_inverse_global_delete_attachment_user_ids", + ) + + global_delete_attachment_user_ids_str = fields.Char( + string="", + config_parameter="attachment_delete_restrict.global_delete_attachment_user_ids", + ) + + @api.depends("global_delete_attachment_group_ids_str") + def _compute_global_delete_attachment_group_ids(self): + for setting in self: + if setting.global_delete_attachment_group_ids_str: + ids = setting.global_delete_attachment_group_ids_str.split(",") + setting.global_delete_attachment_group_ids = self.env[ + "res.groups" + ].search([("id", "in", ids)]) + else: + setting.global_delete_attachment_group_ids = None + + def _inverse_global_delete_attachment_group_ids(self): + for setting in self: + if setting.global_delete_attachment_group_ids: + setting.global_delete_attachment_group_ids_str = ",".join( + str(setting.global_delete_attachment_group_ids.mapped("id")) + ) + else: + setting.global_delete_attachment_group_ids_str = "" + + @api.depends("global_delete_attachment_user_ids_str") + def _compute_global_delete_attachment_user_ids(self): + for setting in self: + if setting.global_delete_attachment_user_ids_str: + ids = setting.global_delete_attachment_user_ids_str.split(",") + setting.global_delete_attachment_user_ids = self.env["res.user"].search( + [("id", "in", ids)] + ) + else: + setting.global_delete_attachment_user_ids = None + + def _inverse_global_delete_attachment_user_ids(self): + for setting in self: + if setting.global_delete_attachment_user_ids: + setting.global_delete_attachment_user_ids_str = ",".join( + str(setting.global_delete_attachment_user_ids.mapped("id")) + ) + else: + setting.global_delete_attachment_user_ids_str = "" diff --git a/attachment_delete_restrict/models/res_groups.py b/attachment_delete_restrict/models/res_groups.py index f3048a7557e..10d18585fef 100644 --- a/attachment_delete_restrict/models/res_groups.py +++ b/attachment_delete_restrict/models/res_groups.py @@ -10,7 +10,8 @@ class ResGroups(models.Model): delete_attachment_model_ids = fields.Many2many( "ir.model", string="Attachment Deletion Models", - help="The users of the group can delete the attachments related to the models " + help="The users of the group can delete the attachments related to " + "the models " "assigned here. In general settings, 'Restrict Delete " "Attachment' must be set as 'custom' to activate this setting.", ) diff --git a/attachment_delete_restrict/models/res_users.py b/attachment_delete_restrict/models/res_users.py index 837f1e21e66..c8f79dd2c75 100644 --- a/attachment_delete_restrict/models/res_users.py +++ b/attachment_delete_restrict/models/res_users.py @@ -10,7 +10,7 @@ class ResUsers(models.Model): delete_attachment_model_ids = fields.Many2many( "ir.model", string="Attachment Deletion Models", - help="The user can delete the attachments related to the " - "models assigned here. In general settings, 'Restrict Delete " + help="The user can delete the attachments related to the models " + "assigned here. In general settings, 'Restrict Delete " "Attachment' must be set as 'custom' to activate this setting.", ) diff --git a/attachment_delete_restrict/readme/CONFIGURE.rst b/attachment_delete_restrict/readme/CONFIGURE.rst index 103d10a51ff..332bb57d367 100644 --- a/attachment_delete_restrict/readme/CONFIGURE.rst +++ b/attachment_delete_restrict/readme/CONFIGURE.rst @@ -7,12 +7,13 @@ Three levels: ============= * Strict : Owner and admins only (by default) * Custom : Certain groups or users per related model. +* Custom + Strict : Owner, admins and Certain groups or users per related model. * None : all users can delete them -Only Custom needs specific configuration. +Only Custom and Custom + Strict need specific configuration. -For Custom level: -================= +For Custom and Custom + Strict levels: +====================================== #. Go to *Settings > Techinical > Database Structure > Models*. #. Open a model for which attachment deletion should be restricted. #. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or diff --git a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py index b0c054ffcd3..386a3a588e8 100644 --- a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py +++ b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py @@ -10,8 +10,9 @@ class TestAttachmentDeleteRestrict(SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.env["ir.config_parameter"].sudo().set_param( - "restrict_delete_attachment", "custom" + cls.param = cls.env["ir.config_parameter"].sudo() + cls.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", "none" ) cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")]) cls.test_group = cls.env["res.groups"].create({"name": "test group"}) @@ -33,18 +34,42 @@ def setUpClass(cls): { "name": "User admin", "login": "admin@example.com", - "groups_id": [(6, 0, cls.env.ref("base.group_system").ids)], + "groups_id": [ + ( + 6, + 0, + ( + cls.env.ref("base.group_system").id, + cls.env.ref("base.group_user").id, + ), + ) + ], } ) cls.test_attachment = cls.env["ir.attachment"].create( {"name": "test attachment", "type": "binary", "res_model": "res.partner"} ) + cls.test_attachment_2 = ( + cls.env["ir.attachment"] + .with_user(cls.test_user) + .create( + { + "name": "test attachment 2", + "type": "binary", + "res_model": "res.partner", + } + ) + ) - def test_01_custom_delete_attachment_unrestricted(self): + def test_01_delete_attachment_unrestricted(self): self.test_attachment.with_user(self.test_user).unlink() + def test_01_bis_delete_attachment_unrestricted(self): + self.partner_model.write({"restrict_delete_attachment": "none"}) + self.test_attachment.with_user(self.test_user2).unlink() + def test_02_custom_delete_attachment_restricted_user_permitted(self): - self.partner_model.write({"is_restrict_delete_attachment": True}) + self.partner_model.write({"restrict_delete_attachment": "custom"}) with self.assertRaises(ValidationError): self.test_attachment.with_user(self.test_user).unlink() self.partner_model.write( @@ -53,7 +78,7 @@ def test_02_custom_delete_attachment_restricted_user_permitted(self): self.test_attachment.with_user(self.test_user).unlink() def test_03_custom_delete_attachment_restricted_group_permitted(self): - self.partner_model.write({"is_restrict_delete_attachment": True}) + self.partner_model.write({"restrict_delete_attachment": "custom"}) with self.assertRaises(ValidationError): self.test_attachment.with_user(self.test_user).unlink() self.partner_model.write( @@ -64,10 +89,8 @@ def test_03_custom_delete_attachment_restricted_group_permitted(self): self.test_user.write({"groups_id": [(4, self.test_group.id)]}) self.test_attachment.with_user(self.test_user).unlink() - def test_04_strict_owner_can_delete_attachment(self): - self.env["ir.config_parameter"].sudo().set_param( - "restrict_delete_attachment", "strict" - ) + def test_04_restrict_owner_can_delete_attachment(self): + self.partner_model.write({"restrict_delete_attachment": "restrict"}) test_attachment_2 = ( self.env["ir.attachment"] .with_user(self.test_user) @@ -83,14 +106,89 @@ def test_04_strict_owner_can_delete_attachment(self): test_attachment_2.with_user(self.test_user2).unlink() test_attachment_2.with_user(self.test_user).unlink() - def test_05_strict_admin_can_delete_attachment(self): - self.env["ir.config_parameter"].sudo().set_param( - "restrict_delete_attachment", "strict" - ) + def test_05_restrict_admin_can_delete_attachment(self): + self.partner_model.write({"restrict_delete_attachment": "restrict"}) self.test_attachment.with_user(self.test_admin).unlink() - def test_06_none_no_restriction(self): - self.env["ir.config_parameter"].sudo().set_param( - "restrict_delete_attachment", "none" + def test_06_global_restrict_restriction(self): + self.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", "restrict" + ) + with self.assertRaises(ValidationError): + self.test_attachment_2.with_user(self.test_user2).unlink() + self.test_attachment_2.with_user(self.test_user).unlink() + + def test_07_global_custom_restriction_for_users(self): + self.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", "custom" ) + self.param.set_param( + "attachment_delete_restrict.global_delete_attachment_user_ids", + self.test_user2.ids, + ) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user).unlink() self.test_attachment.with_user(self.test_user2).unlink() + + def test_08_global_custom_restriction_for_groups(self): + self.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", "custom" + ) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user).unlink() + self.param.set_param( + "attachment_delete_restrict.global_delete_attachment_group_ids", + self.test_group.ids, + ) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user).unlink() + self.test_user.write({"groups_id": [(4, self.test_group.id)]}) + self.test_attachment.with_user(self.test_user).unlink() + + def test_09_global_none_restriction(self): + global_restrict = self.param.get_param( + "attachment_delete_restrict.global_restrict_delete_attachment" + ) + self.assertEqual(global_restrict, "none") + self.test_attachment.with_user(self.test_user).unlink() + + def test_10_restrict_and_custom_delete_user(self): + self.partner_model.write({"restrict_delete_attachment": "restrict_custom"}) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user2).unlink() + self.partner_model.write( + {"delete_attachment_user_ids": [(4, self.test_user2.id)]} + ) + self.test_attachment.with_user(self.test_user2).unlink() + + self.test_attachment_2.with_user(self.test_admin).unlink() + + def test_11_restrict_and_custom_delete_group(self): + self.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", + "restrict_custom", + ) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user).unlink() + self.test_user.write({"groups_id": [(4, self.test_group.id)]}) + self.param.set_param( + "attachment_delete_restrict.global_delete_attachment_group_ids", + self.test_group.ids, + ) + self.test_attachment.with_user(self.test_user).unlink() + self.test_attachment_2.with_user(self.test_admin).unlink() + + def test_12_default_model_restriction(self): + self.param.set_param( + "attachment_delete_restrict.global_restrict_delete_attachment", "custom" + ) + self.param.set_param( + "attachment_delete_restrict.global_delete_attachment_group_ids", + self.test_group.ids, + ) + self.partner_model.write({"restrict_delete_attachment": "default"}) + with self.assertRaises(ValidationError): + self.test_attachment.with_user(self.test_user).unlink() + + self.test_user.write({"groups_id": [(4, self.test_group.id)]}) + self.test_attachment.with_user(self.test_user).unlink() diff --git a/attachment_delete_restrict/views/ir_model_views.xml b/attachment_delete_restrict/views/ir_model_views.xml index 00b23ba17ba..7152e93a296 100644 --- a/attachment_delete_restrict/views/ir_model_views.xml +++ b/attachment_delete_restrict/views/ir_model_views.xml @@ -11,9 +11,8 @@
-
-
+
+
+ Authorized Groups: +
+
+ + + +
+
+ Authorized Users: +
+
+ + +
+ +
diff --git a/attachment_delete_restrict/views/res_groups_views.xml b/attachment_delete_restrict/views/res_groups_views.xml index 4e3d744bf48..9a52be721b0 100644 --- a/attachment_delete_restrict/views/res_groups_views.xml +++ b/attachment_delete_restrict/views/res_groups_views.xml @@ -13,7 +13,7 @@ diff --git a/attachment_delete_restrict/views/res_users_views.xml b/attachment_delete_restrict/views/res_users_views.xml index a4034613e05..7002905c28f 100644 --- a/attachment_delete_restrict/views/res_users_views.xml +++ b/attachment_delete_restrict/views/res_users_views.xml @@ -13,7 +13,7 @@ From 197aa2ff37c23441dbd0062416688eb1804ea9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Sun, 10 Jul 2022 18:34:38 +0200 Subject: [PATCH 05/24] attachment_delete_restrict: refactor test and improve restrict mode naming --- .../models/ir_attachment.py | 4 +- attachment_delete_restrict/models/ir_model.py | 6 +- .../models/res_config.py | 8 +- .../tests/test_attachment_delete_restrict.py | 216 ++++++++---------- .../views/res_config_view.xml | 2 +- 5 files changed, 98 insertions(+), 138 deletions(-) diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py index c59257e3dde..ecc06f5d5d0 100644 --- a/attachment_delete_restrict/models/ir_attachment.py +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -11,14 +11,14 @@ class IrAttachment(models.Model): _inherit = "ir.attachment" def _check_delete_attachment(self, model, restrict, mode): - if restrict == "restrict": + if restrict == "owner": if self._check_restrict_delete_attachment(): return else: self._raise_restrict_validation_error() elif restrict == "custom": self._check_custom_delete_attachment(model, mode) - elif restrict == "restrict_custom": + elif restrict == "owner_custom": if self._check_restrict_delete_attachment(): return self._check_custom_delete_attachment(model, mode) diff --git a/attachment_delete_restrict/models/ir_model.py b/attachment_delete_restrict/models/ir_model.py index 411d695bb14..19173f558c6 100644 --- a/attachment_delete_restrict/models/ir_model.py +++ b/attachment_delete_restrict/models/ir_model.py @@ -5,11 +5,11 @@ RESTRICT_DELETE_ATTACH = [ ("default", "Use global configuration"), - ("restrict", "Restrict: Only creator and admin can delete them"), + ("owner", "Owner: Only creator and admin can delete them"), ("custom", "Custom: For each model, selected groups and users can " "delete them"), ( - "restrict_custom", - "Restrict + Custom: Creator and admin can delete them + for " + "owner_custom", + "Owner + Custom: Creator and admin can delete them + for " "each model, selected groups and users can delete them", ), ("none", "No restriction: All users / groups can delete them"), diff --git a/attachment_delete_restrict/models/res_config.py b/attachment_delete_restrict/models/res_config.py index a471829d799..1fe814e3e78 100644 --- a/attachment_delete_restrict/models/res_config.py +++ b/attachment_delete_restrict/models/res_config.py @@ -11,7 +11,7 @@ class ResConfigSettings(models.TransientModel): _inherit = "res.config.settings" global_restrict_delete_attachment = fields.Selection( - selection=RESTRICT_DELETE_ATTACH, + selection=RESTRICT_DELETE_ATTACH[1:], config_parameter="attachment_delete_restrict.global_restrict_delete_attachment", readonly=False, required=True, @@ -23,21 +23,19 @@ class ResConfigSettings(models.TransientModel): global_delete_attachment_group_ids = fields.Many2many( "res.groups", string="Attachment Deletion Groups", - relation="global_delete_attachment_group_rel", help="The users in the groups selected here can delete all the attachments.", readonly=False, compute="_compute_global_delete_attachment_group_ids", inverse="_inverse_global_delete_attachment_group_ids", ) global_delete_attachment_group_ids_str = fields.Char( - string="", + string="Attachment Deletion Groups (Technical storage field)", config_parameter="attachment_delete_restrict.global_delete_attachment_group_ids", ) global_delete_attachment_user_ids = fields.Many2many( "res.users", string="Attachment Deletion Users", - relation="global_delete_attachment_user_rel", help="The users selected here can delete all the attachments", readonly=False, compute="_compute_global_delete_attachment_user_ids", @@ -45,7 +43,7 @@ class ResConfigSettings(models.TransientModel): ) global_delete_attachment_user_ids_str = fields.Char( - string="", + string="Attachment Deletion Users (Technical storage field)", config_parameter="attachment_delete_restrict.global_delete_attachment_user_ids", ) diff --git a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py index 386a3a588e8..330c9edb647 100644 --- a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py +++ b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py @@ -5,32 +5,89 @@ from odoo.tests import SavepointCase, tagged +class AbstractCase: + def test_restrict_none(self): + self._set_restrict_mode("none") + self.attachment.with_user(self.user).unlink() + + def test_restrict_custom_user(self): + self._set_restrict_mode("custom") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + self._allow_user() + self.attachment.with_user(self.user).unlink() + + def test_restrict_custom_group(self): + self._set_restrict_mode("custom") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + self._allow_group() + self.attachment.with_user(self.user).unlink() + + def test_restrict_owner(self): + self._set_restrict_mode("owner") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + self.attachment.with_user(self.user_owner).unlink() + + def test_restrict_owner_admin(self): + self._set_restrict_mode("owner") + self.attachment.with_user(self.user_admin).unlink() + + def test_restrict_owner_and_custom_user_forbiden(self): + self._set_restrict_mode("owner_custom") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + + def test_restrict_owner_and_custom_user_owner(self): + self._set_restrict_mode("owner_custom") + self.attachment.with_user(self.user_owner).unlink() + + def test_restrict_owner_and_custom_user_admin(self): + self._set_restrict_mode("owner_custom") + self.attachment.with_user(self.user_admin).unlink() + + def test_restrict_owner_and_custom_user(self): + self._set_restrict_mode("owner_custom") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + self._allow_user() + self.attachment.with_user(self.user).unlink() + + def test_restrict_owner_and_custom_user_group(self): + self._set_restrict_mode("owner_custom") + with self.assertRaises(ValidationError): + self.attachment.with_user(self.user).unlink() + self._allow_group() + self.attachment.with_user(self.user).unlink() + + @tagged("post_install", "-at_install") -class TestAttachmentDeleteRestrict(SavepointCase): +class TestAttachmentDeleteAbstract(SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.param = cls.env["ir.config_parameter"].sudo() + cls.param = cls.env["ir.config_parameter"] cls.param.set_param( "attachment_delete_restrict.global_restrict_delete_attachment", "none" ) cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")]) - cls.test_group = cls.env["res.groups"].create({"name": "test group"}) - cls.test_user = cls.env["res.users"].create( + cls.group = cls.env.ref("base.group_user") + cls.user_owner = cls.env["res.users"].create( { - "name": "test user", - "login": "test@example.com", + "name": "test owner user", + "login": "test-owner@example.com", "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], } ) - cls.test_user2 = cls.env["res.users"].create( + cls.user = cls.env["res.users"].create( { - "name": "test user2", + "name": "test user", "login": "test2@example.com", "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], } ) - cls.test_admin = cls.env["res.users"].create( + cls.user_admin = cls.env["res.users"].create( { "name": "User admin", "login": "admin@example.com", @@ -46,12 +103,9 @@ def setUpClass(cls): ], } ) - cls.test_attachment = cls.env["ir.attachment"].create( - {"name": "test attachment", "type": "binary", "res_model": "res.partner"} - ) - cls.test_attachment_2 = ( + cls.attachment = ( cls.env["ir.attachment"] - .with_user(cls.test_user) + .with_user(cls.user_owner) .create( { "name": "test attachment 2", @@ -61,134 +115,42 @@ def setUpClass(cls): ) ) - def test_01_delete_attachment_unrestricted(self): - self.test_attachment.with_user(self.test_user).unlink() + def _set_restrict_mode(self, restrict_mode): + raise NotImplementedError - def test_01_bis_delete_attachment_unrestricted(self): - self.partner_model.write({"restrict_delete_attachment": "none"}) - self.test_attachment.with_user(self.test_user2).unlink() + def _allow_user(self): + raise NotImplementedError - def test_02_custom_delete_attachment_restricted_user_permitted(self): - self.partner_model.write({"restrict_delete_attachment": "custom"}) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.partner_model.write( - {"delete_attachment_user_ids": [(4, self.test_user.id)]} - ) - self.test_attachment.with_user(self.test_user).unlink() - - def test_03_custom_delete_attachment_restricted_group_permitted(self): - self.partner_model.write({"restrict_delete_attachment": "custom"}) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.partner_model.write( - {"delete_attachment_group_ids": [(4, self.test_group.id)]} - ) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.test_user.write({"groups_id": [(4, self.test_group.id)]}) - self.test_attachment.with_user(self.test_user).unlink() - - def test_04_restrict_owner_can_delete_attachment(self): - self.partner_model.write({"restrict_delete_attachment": "restrict"}) - test_attachment_2 = ( - self.env["ir.attachment"] - .with_user(self.test_user) - .create( - { - "name": "test attachment 2", - "type": "binary", - "res_model": "res.partner", - } - ) - ) - with self.assertRaises(ValidationError): - test_attachment_2.with_user(self.test_user2).unlink() - test_attachment_2.with_user(self.test_user).unlink() + def _allow_group(self): + raise NotImplementedError - def test_05_restrict_admin_can_delete_attachment(self): - self.partner_model.write({"restrict_delete_attachment": "restrict"}) - self.test_attachment.with_user(self.test_admin).unlink() - def test_06_global_restrict_restriction(self): +class TestAttachmentDeleteGlobal(TestAttachmentDeleteAbstract, AbstractCase): + def _set_restrict_mode(self, restrict_mode): self.param.set_param( - "attachment_delete_restrict.global_restrict_delete_attachment", "restrict" + "attachment_delete_restrict.global_restrict_delete_attachment", + restrict_mode, ) - with self.assertRaises(ValidationError): - self.test_attachment_2.with_user(self.test_user2).unlink() - self.test_attachment_2.with_user(self.test_user).unlink() - def test_07_global_custom_restriction_for_users(self): - self.param.set_param( - "attachment_delete_restrict.global_restrict_delete_attachment", "custom" - ) + def _allow_user(self): self.param.set_param( "attachment_delete_restrict.global_delete_attachment_user_ids", - self.test_user2.ids, + self.user.ids, ) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.test_attachment.with_user(self.test_user2).unlink() - def test_08_global_custom_restriction_for_groups(self): - self.param.set_param( - "attachment_delete_restrict.global_restrict_delete_attachment", "custom" - ) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() + def _allow_group(self): self.param.set_param( "attachment_delete_restrict.global_delete_attachment_group_ids", - self.test_group.ids, + self.group.ids, ) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.test_user.write({"groups_id": [(4, self.test_group.id)]}) - self.test_attachment.with_user(self.test_user).unlink() - def test_09_global_none_restriction(self): - global_restrict = self.param.get_param( - "attachment_delete_restrict.global_restrict_delete_attachment" - ) - self.assertEqual(global_restrict, "none") - self.test_attachment.with_user(self.test_user).unlink() - def test_10_restrict_and_custom_delete_user(self): - self.partner_model.write({"restrict_delete_attachment": "restrict_custom"}) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user2).unlink() - self.partner_model.write( - {"delete_attachment_user_ids": [(4, self.test_user2.id)]} - ) - self.test_attachment.with_user(self.test_user2).unlink() +class TestAttachmentDeleteModel(TestAttachmentDeleteAbstract, AbstractCase): + def _set_restrict_mode(self, restrict_mode): + self.partner_model.write({"restrict_delete_attachment": restrict_mode}) - self.test_attachment_2.with_user(self.test_admin).unlink() - - def test_11_restrict_and_custom_delete_group(self): - self.param.set_param( - "attachment_delete_restrict.global_restrict_delete_attachment", - "restrict_custom", - ) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() - self.test_user.write({"groups_id": [(4, self.test_group.id)]}) - self.param.set_param( - "attachment_delete_restrict.global_delete_attachment_group_ids", - self.test_group.ids, - ) - self.test_attachment.with_user(self.test_user).unlink() - self.test_attachment_2.with_user(self.test_admin).unlink() - - def test_12_default_model_restriction(self): - self.param.set_param( - "attachment_delete_restrict.global_restrict_delete_attachment", "custom" - ) - self.param.set_param( - "attachment_delete_restrict.global_delete_attachment_group_ids", - self.test_group.ids, - ) - self.partner_model.write({"restrict_delete_attachment": "default"}) - with self.assertRaises(ValidationError): - self.test_attachment.with_user(self.test_user).unlink() + def _allow_user(self): + self.partner_model.write({"delete_attachment_user_ids": [(4, self.user.id)]}) - self.test_user.write({"groups_id": [(4, self.test_group.id)]}) - self.test_attachment.with_user(self.test_user).unlink() + def _allow_group(self): + self.partner_model.write({"delete_attachment_group_ids": [(4, self.group.id)]}) diff --git a/attachment_delete_restrict/views/res_config_view.xml b/attachment_delete_restrict/views/res_config_view.xml index 83467fae029..0c6112c739b 100644 --- a/attachment_delete_restrict/views/res_config_view.xml +++ b/attachment_delete_restrict/views/res_config_view.xml @@ -25,7 +25,7 @@
Authorized Groups: From 4d9cd2544f7efedf54d2e922517b5fff8097737b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Sun, 10 Jul 2022 22:18:22 +0200 Subject: [PATCH 06/24] attachment_delete_restrict: refactor code --- attachment_delete_restrict/i18n/fr.po | 62 ++++----- .../models/ir_attachment.py | 121 ++++++++---------- attachment_delete_restrict/models/ir_model.py | 2 +- .../models/res_config.py | 66 +++++----- .../readme/CONFIGURE.rst | 15 ++- .../readme/CONTRIBUTORS.rst | 1 + .../views/res_config_view.xml | 10 -- 7 files changed, 117 insertions(+), 160 deletions(-) diff --git a/attachment_delete_restrict/i18n/fr.po b/attachment_delete_restrict/i18n/fr.po index 788669f25a4..3f58aec759b 100644 --- a/attachment_delete_restrict/i18n/fr.po +++ b/attachment_delete_restrict/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-05-19 07:58+0000\n" -"PO-Revision-Date: 2022-05-19 10:07+0200\n" +"POT-Creation-Date: 2022-07-11 14:14+0000\n" +"PO-Revision-Date: 2022-07-11 16:16+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: \n" -"X-Generator: Poedit 3.0.1\n" +"X-Generator: Poedit 3.1.1\n" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_groups @@ -29,7 +29,6 @@ msgstr "Pièce jointe" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__global_delete_attachment_group_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "Attachment Deletion Groups" msgstr "Groupe avec droit de suppression de PJ" @@ -44,7 +43,6 @@ msgstr "Modèle avec restrictions de suppression de PJ" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__global_delete_attachment_user_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "Attachment Deletion Users" msgstr "Utilisateurs avec droit de suppression de PJ" @@ -75,7 +73,7 @@ msgstr "" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment msgid "Define a default value for Attachments Deletion" -msgstr "" +msgstr "Définir une valeur par défaut pour la suppression des pièces jointes" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name @@ -86,16 +84,6 @@ msgstr "" msgid "Display Name" msgstr "Nom affiché" -#. module: attachment_delete_restrict -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids_str -msgid "Global Delete Attachment Group Ids Str" -msgstr "Groupe avec droit de suppression de toutes les PJs" - -#. module: attachment_delete_restrict -#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids_str -msgid "Global Delete Attachment User Ids Str" -msgstr "Utilisateurs avec droit de suppression de toutes les PJs" - #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id @@ -127,14 +115,22 @@ msgstr "" "Aucune restrictions: Tous les utilisateurs / groupes peuvent supprimer" #. module: attachment_delete_restrict -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__restrict_custom -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__restrict_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner_custom msgid "" -"Restrict + Custom: Creator and admin can delete them + for each model, " +"Owner + Custom: Creator and admin can delete them + for each model, " "selected groups and users can delete them" msgstr "" -"Limité + personnalisé : Le propriétaire, les administrateurs et les " -"utilisateurs de certains groupes peuvent supprimer" +"Propriétaire + Personnalisé : Le créateur et l'administrateur peuvent les " +"supprimer + pour chaque modèle, les groupes et utilisateurs sélectionnés " +"peuvent les supprimer" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner +msgid "Owner: Only creator and admin can delete them" +msgstr "" +"Propriétaire : Seuls le créateur et l'administrateur peuvent les supprimer" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment @@ -151,13 +147,6 @@ msgstr "Suppression de PJs Limitée" msgid "Restrict Deletion on attachment" msgstr "Restreindre la suppression de PJs" -#. module: attachment_delete_restrict -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__restrict -#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__restrict -msgid "Restrict: Only creator and admin can delete them" -msgstr "" -"Limité : Seuls le propriétaire et les administrateurs peuvent supprimer" - #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form msgid "Select default level of delete restriction on attachments" @@ -175,7 +164,6 @@ msgstr "" "doit être à \"Personnalisé\" pour que cela s'active." #. module: attachment_delete_restrict -#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__global_delete_attachment_group_ids #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "The users in the groups selected here can delete all the attachments." msgstr "" @@ -202,7 +190,6 @@ msgstr "" "suppression de PJs\" doit être à \"Personnalisé\" pour que cela s'active." #. module: attachment_delete_restrict -#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__global_delete_attachment_user_ids #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "The users selected here can delete all the attachments" msgstr "Ces utilisateurs peuvent supprimer toutes les pièces jointes" @@ -213,6 +200,11 @@ msgid "" "The users selected here can delete the attachments related to this model." msgstr "Ces utilisateurs peuvent supprimer les pièces jointes de ce modèle." +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__default +msgid "Use global configuration" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_users msgid "Users" @@ -240,13 +232,3 @@ msgstr "" "\n" "Utilisateurs ayant la permission:\n" "%s" - -#. module: attachment_delete_restrict -#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 -#, python-format -msgid "" -"You are not allowed to delete this attachment.\n" -"Only the owner and administrators can delete it." -msgstr "" -"Vous n'êtes pas autorisé à supprimer cette pièce jointe.\n" -"Seulement son créateur et les administrateurs ont le droit." diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py index ecc06f5d5d0..a3a6d936441 100644 --- a/attachment_delete_restrict/models/ir_attachment.py +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -1,7 +1,6 @@ # Copyright 2021 Quartile Limited # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from ast import literal_eval from odoo import _, models from odoo.exceptions import ValidationError @@ -10,86 +9,70 @@ class IrAttachment(models.Model): _inherit = "ir.attachment" - def _check_delete_attachment(self, model, restrict, mode): + def _check_delete_attachment(self, model=None): + if model: + restrict = model.restrict_delete_attachment + else: + restrict = ( + self.env["ir.config_parameter"] + .sudo() + .get_param( + "attachment_delete_restrict.global_restrict_delete_attachment" + ) + ) if restrict == "owner": - if self._check_restrict_delete_attachment(): - return - else: - self._raise_restrict_validation_error() + self._check_owner_delete_attachment() elif restrict == "custom": - self._check_custom_delete_attachment(model, mode) + self._check_custom_delete_attachment(model) elif restrict == "owner_custom": - if self._check_restrict_delete_attachment(): - return - self._check_custom_delete_attachment(model, mode) + self._check_custom_delete_attachment(model, allow_owner_and_admin=True) - def _check_restrict_delete_attachment(self): - if self.create_uid == self.env.user or self.user_has_groups( - "base.group_system" - ): - return True - else: - return False - - def _check_custom_delete_attachment(self, model, mode): - if not model and mode != "global": - return - groups = model.delete_attachment_group_ids - users = model.delete_attachment_user_ids - param = self.env["ir.config_parameter"].sudo() - groups_ids = param.get_param( - "attachment_delete_restrict.global_delete_attachment_group_ids" - ) - users_ids = param.get_param( - "attachment_delete_restrict.global_delete_attachment_user_ids" - ) - if mode == "global": - if groups_ids: - groups = self.env["res.groups"].search( - [("id", "in", literal_eval(groups_ids))] - ) - if users_ids: - users = self.env["res.users"].search( - [("id", "in", literal_eval(users_ids))] - ) - if groups and self.env.user in groups.mapped("users"): - return - if users and self.env.user in users: - return - list_group = "\n".join(list(set(groups.mapped("users").mapped("name")))) - list_user = "\n".join(list(set(users.mapped("name")))) - user_names = list_group + list_user + def _raise_delete_attachment_error(self, allowed_users): raise ValidationError( _( "You are not allowed to delete this attachment.\n\nUsers with " "the delete permission:\n%s" ) - % (user_names or "None") + % ("\n".join(allowed_users.mapped("name")) or "None") ) - def _raise_restrict_validation_error(self): - raise ValidationError( - _( - "You are not allowed to delete this attachment.\n" - "Only the owner and administrators can delete it." + def _check_owner_delete_attachment(self): + if not ( + self.create_uid == self.env.user + or self.user_has_groups("base.group_system") + ): + return self._raise_delete_attachment_error( + self.create_uid + self.env.ref("base.group_system").users ) - ) + + def _check_custom_delete_attachment(self, model=None, allow_owner_and_admin=False): + if model: + groups = model.delete_attachment_group_ids + users = model.delete_attachment_user_ids + else: + groups = self.env[ + "res.config.settings" + ]._get_global_delete_attachment_groups() + users = self.env[ + "res.config.settings" + ]._get_global_delete_attachment_users() + if allow_owner_and_admin: + users += self.create_uid + groups += self.env.ref("base.group_system") + allowed_users = groups.users + users + if self.env.user not in allowed_users: + return self._raise_delete_attachment_error(allowed_users) def unlink(self): - for rec in self: - if not rec.res_model: - continue - model = self.env["ir.model"].search([("model", "=", rec.res_model)]) - model_restrict = model.restrict_delete_attachment - global_restrict = ( - self.env["ir.config_parameter"] - .sudo() - .get_param( - "attachment_delete_restrict.global_restrict_delete_attachment" - ) - ) - if model_restrict == "default": - rec._check_delete_attachment(model, global_restrict, "global") - elif model_restrict not in ["default", "none"]: - rec._check_delete_attachment(model, model_restrict, "model") + res_models = list(set(self.filtered("res_model").mapped("res_model"))) + if res_models: + models = self.env["ir.model"].search([("model", "in", res_models)]) + name2models = {m.model: m for m in models} + for rec in self: + if rec.res_model: + model = name2models[rec.res_model] + if model.restrict_delete_attachment == "default": + rec.sudo()._check_delete_attachment() + else: + rec.sudo()._check_delete_attachment(model) return super().unlink() diff --git a/attachment_delete_restrict/models/ir_model.py b/attachment_delete_restrict/models/ir_model.py index 19173f558c6..4006cc121e5 100644 --- a/attachment_delete_restrict/models/ir_model.py +++ b/attachment_delete_restrict/models/ir_model.py @@ -6,7 +6,7 @@ RESTRICT_DELETE_ATTACH = [ ("default", "Use global configuration"), ("owner", "Owner: Only creator and admin can delete them"), - ("custom", "Custom: For each model, selected groups and users can " "delete them"), + ("custom", "Custom: For each model, selected groups and users can delete them"), ( "owner_custom", "Owner + Custom: Creator and admin can delete them + for " diff --git a/attachment_delete_restrict/models/res_config.py b/attachment_delete_restrict/models/res_config.py index 1fe814e3e78..2ec98b30fbe 100644 --- a/attachment_delete_restrict/models/res_config.py +++ b/attachment_delete_restrict/models/res_config.py @@ -2,6 +2,8 @@ # @author Kévin Roche # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from ast import literal_eval + from odoo import api, fields, models from .ir_model import RESTRICT_DELETE_ATTACH @@ -25,64 +27,62 @@ class ResConfigSettings(models.TransientModel): string="Attachment Deletion Groups", help="The users in the groups selected here can delete all the attachments.", readonly=False, + compute_sudo=True, compute="_compute_global_delete_attachment_group_ids", inverse="_inverse_global_delete_attachment_group_ids", ) - global_delete_attachment_group_ids_str = fields.Char( - string="Attachment Deletion Groups (Technical storage field)", - config_parameter="attachment_delete_restrict.global_delete_attachment_group_ids", - ) - global_delete_attachment_user_ids = fields.Many2many( "res.users", string="Attachment Deletion Users", help="The users selected here can delete all the attachments", readonly=False, + compute_sudo=True, compute="_compute_global_delete_attachment_user_ids", inverse="_inverse_global_delete_attachment_user_ids", ) - global_delete_attachment_user_ids_str = fields.Char( - string="Attachment Deletion Users (Technical storage field)", - config_parameter="attachment_delete_restrict.global_delete_attachment_user_ids", - ) + def _get_global_delete_attachment_groups(self): + str_group_ids = self.env["ir.config_parameter"].get_param( + "attachment_delete_restrict.global_delete_attachment_group_ids" + ) + groups_ids = literal_eval(str_group_ids or "[]") + return self.env["res.groups"].search([("id", "in", groups_ids)]) - @api.depends("global_delete_attachment_group_ids_str") + @api.depends("global_restrict_delete_attachment") def _compute_global_delete_attachment_group_ids(self): + groups = self._get_global_delete_attachment_groups() for setting in self: - if setting.global_delete_attachment_group_ids_str: - ids = setting.global_delete_attachment_group_ids_str.split(",") - setting.global_delete_attachment_group_ids = self.env[ - "res.groups" - ].search([("id", "in", ids)]) + if "custom" in setting.global_restrict_delete_attachment: + setting.global_delete_attachment_group_ids = groups else: setting.global_delete_attachment_group_ids = None def _inverse_global_delete_attachment_group_ids(self): for setting in self: - if setting.global_delete_attachment_group_ids: - setting.global_delete_attachment_group_ids_str = ",".join( - str(setting.global_delete_attachment_group_ids.mapped("id")) - ) - else: - setting.global_delete_attachment_group_ids_str = "" + self.env["ir.config_parameter"].set_param( + "attachment_delete_restrict.global_delete_attachment_group_ids", + str(setting.global_delete_attachment_group_ids.ids), + ) + + def _get_global_delete_attachment_users(self): + str_user_ids = self.env["ir.config_parameter"].get_param( + "attachment_delete_restrict.global_delete_attachment_user_ids" + ) + user_ids = literal_eval(str_user_ids or "[]") + return self.env["res.users"].search([("id", "in", user_ids)]) - @api.depends("global_delete_attachment_user_ids_str") + @api.depends("global_restrict_delete_attachment") def _compute_global_delete_attachment_user_ids(self): + users = self._get_global_delete_attachment_users() for setting in self: - if setting.global_delete_attachment_user_ids_str: - ids = setting.global_delete_attachment_user_ids_str.split(",") - setting.global_delete_attachment_user_ids = self.env["res.user"].search( - [("id", "in", ids)] - ) + if "custom" in setting.global_restrict_delete_attachment: + setting.global_delete_attachment_user_ids = users else: setting.global_delete_attachment_user_ids = None def _inverse_global_delete_attachment_user_ids(self): for setting in self: - if setting.global_delete_attachment_user_ids: - setting.global_delete_attachment_user_ids_str = ",".join( - str(setting.global_delete_attachment_user_ids.mapped("id")) - ) - else: - setting.global_delete_attachment_user_ids_str = "" + self.env["ir.config_parameter"].set_param( + "attachment_delete_restrict.global_delete_attachment_user_ids", + str(setting.global_delete_attachment_user_ids.ids), + ) diff --git a/attachment_delete_restrict/readme/CONFIGURE.rst b/attachment_delete_restrict/readme/CONFIGURE.rst index 332bb57d367..cbf3f027dfa 100644 --- a/attachment_delete_restrict/readme/CONFIGURE.rst +++ b/attachment_delete_restrict/readme/CONFIGURE.rst @@ -1,20 +1,21 @@ Select level: ============= #. Go to *Settings > General Settings> Permission section*. -#. Choose the level of *Restrict Delete Attachment* (strict by default). +#. Choose the level of *Restrict Delete Attachment* for all models by default or for models with "default" restriction level. -Three levels: +Five levels: ============= -* Strict : Owner and admins only (by default) +* Default : Use global configuration +* Owner : Owner and admins only * Custom : Certain groups or users per related model. -* Custom + Strict : Owner, admins and Certain groups or users per related model. +* Owner + Strict : Owner, admins and Certain groups or users per related model. * None : all users can delete them -Only Custom and Custom + Strict need specific configuration. +Only Owner and Custom + Strict need specific configuration on models. -For Custom and Custom + Strict levels: +For Custom and Owner + Strict levels: ====================================== -#. Go to *Settings > Techinical > Database Structure > Models*. +#. Go to *Settings > Technical > Database Structure > Models*. #. Open a model for which attachment deletion should be restricted. #. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or 'Attachment Deletion Users' as necessary (if no assignment, no one can delete the diff --git a/attachment_delete_restrict/readme/CONTRIBUTORS.rst b/attachment_delete_restrict/readme/CONTRIBUTORS.rst index 374eca48aed..0da6714f3ef 100644 --- a/attachment_delete_restrict/readme/CONTRIBUTORS.rst +++ b/attachment_delete_restrict/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Yoshi Tashiro * Kévin Roche +* Sébastien BEAU diff --git a/attachment_delete_restrict/views/res_config_view.xml b/attachment_delete_restrict/views/res_config_view.xml index 0c6112c739b..2cf23695541 100644 --- a/attachment_delete_restrict/views/res_config_view.xml +++ b/attachment_delete_restrict/views/res_config_view.xml @@ -38,11 +38,6 @@ widget="many2many_tags" options="{'no_create': True}" /> - -
Authorized Users: @@ -54,12 +49,7 @@ widget="many2many_tags" options="{'no_create': True}" /> -
-
From 90229b45e11d22c021ac8c98018b79aa0e30c511 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 1 Sep 2022 07:54:51 +0000 Subject: [PATCH 07/24] [UPD] Update attachment_delete_restrict.pot --- .../i18n/attachment_delete_restrict.pot | 262 ++++++++++++++++++ attachment_delete_restrict/i18n/fr.po | 65 ++++- attachment_delete_restrict/i18n/ja.po | 219 ++++++++++++++- 3 files changed, 526 insertions(+), 20 deletions(-) create mode 100644 attachment_delete_restrict/i18n/attachment_delete_restrict.pot diff --git a/attachment_delete_restrict/i18n/attachment_delete_restrict.pot b/attachment_delete_restrict/i18n/attachment_delete_restrict.pot new file mode 100644 index 00000000000..4d93d4072e6 --- /dev/null +++ b/attachment_delete_restrict/i18n/attachment_delete_restrict.pot @@ -0,0 +1,262 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_delete_restrict +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +msgid "Attachment Deletion Groups" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_groups_form +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_users_form +msgid "Attachment Deletion Models" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +msgid "Attachment Deletion Users" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Groups:" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Users:" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_ids +msgid "Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom +msgid "Custom: For each model, selected groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Define a default value for Attachments Deletion" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__display_name +msgid "Display Name" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__id +msgid "ID" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users____last_update +msgid "Last Modified on" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_model +msgid "Models" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none +msgid "No restriction: All users / groups can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner_custom +msgid "" +"Owner + Custom: Creator and admin can delete them + for each model, selected" +" groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner +msgid "Owner: Only creator and admin can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "Restrict Attachment Deletion" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Restrict Delete Attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Restrict Deletion on attachment" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Select default level of delete restriction on attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__smart_search +msgid "Smart Search" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +msgid "" +"The user can delete the attachments related to the models assigned here. In " +"general settings, 'Restrict Delete Attachment' must be set as 'custom' to " +"activate this setting." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +msgid "The users in the groups selected here can delete all the attachments." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "" +"The users in the groups selected here can delete the attachments related to " +"this model." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +msgid "" +"The users of the group can delete the attachments related to the models " +"assigned here. In general settings, 'Restrict Delete Attachment' must be set" +" as 'custom' to activate this setting." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +msgid "The users selected here can delete all the attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "" +"The users selected here can delete the attachments related to this model." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__default +msgid "Use global configuration" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_users +msgid "Users" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "" +"When selected, the deletion of the attachments related to this model is " +"restricted to certain users." +msgstr "" + +#. module: attachment_delete_restrict +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 +#, python-format +msgid "" +"You are not allowed to delete this attachment.\n" +"\n" +"Users with the delete permission:\n" +"%s" +msgstr "" diff --git a/attachment_delete_restrict/i18n/fr.po b/attachment_delete_restrict/i18n/fr.po index 3f58aec759b..ccaf58a6442 100644 --- a/attachment_delete_restrict/i18n/fr.po +++ b/attachment_delete_restrict/i18n/fr.po @@ -57,11 +57,47 @@ msgstr "Groupes autorisés:" msgid "Authorized Users:" msgstr "Utilisateurs autorisés:" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_ids +msgid "Changesets" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_config_settings msgid "Config Settings" msgstr "Paramètres de config" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom @@ -111,15 +147,14 @@ msgstr "Modèles" #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none msgid "No restriction: All users / groups can delete them" -msgstr "" -"Aucune restrictions: Tous les utilisateurs / groupes peuvent supprimer" +msgstr "Aucune restrictions: Tous les utilisateurs / groupes peuvent supprimer" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner_custom msgid "" -"Owner + Custom: Creator and admin can delete them + for each model, " -"selected groups and users can delete them" +"Owner + Custom: Creator and admin can delete them + for each model, selected " +"groups and users can delete them" msgstr "" "Propriétaire + Personnalisé : Le créateur et l'administrateur peuvent les " "supprimer + pour chaque modèle, les groupes et utilisateurs sélectionnés " @@ -152,6 +187,15 @@ msgstr "Restreindre la suppression de PJs" msgid "Select default level of delete restriction on attachments" msgstr "Sélectionner le niveau de restriction sur les pièces jointes" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__smart_search +msgid "Smart Search" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids msgid "" @@ -182,8 +226,8 @@ msgstr "" #: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids msgid "" "The users of the group can delete the attachments related to the models " -"assigned here. In general settings, 'Restrict Delete Attachment' must be " -"set as 'custom' to activate this setting." +"assigned here. In general settings, 'Restrict Delete Attachment' must be set " +"as 'custom' to activate this setting." msgstr "" "Les utilisateurs de ce groupe peuvent supprimer les pièces jointes reliées " "au modèle assigné ici. Dans la configuration générale, \"Restreindre la " @@ -205,6 +249,15 @@ msgstr "Ces utilisateurs peuvent supprimer les pièces jointes de ce modèle." msgid "Use global configuration" msgstr "" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_users msgid "Users" diff --git a/attachment_delete_restrict/i18n/ja.po b/attachment_delete_restrict/i18n/ja.po index c5f194ef637..0dca63d19d8 100644 --- a/attachment_delete_restrict/i18n/ja.po +++ b/attachment_delete_restrict/i18n/ja.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * attachment_delete_restrict +# * attachment_delete_restrict # msgid "" msgstr "" @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2021-08-29 14:47+0000\n" "Last-Translator: <>\n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" @@ -27,6 +28,7 @@ msgstr "添付" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "Attachment Deletion Groups" msgstr "添付削除グループ" @@ -40,38 +42,218 @@ msgstr "添付削除モデル" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "Attachment Deletion Users" msgstr "添付削除ユーザ" +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Groups:" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Users:" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_ids +msgid "Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom +msgid "Custom: For each model, selected groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +#, fuzzy +msgid "Define a default value for Attachments Deletion" +msgstr "添付削除を制限" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__display_name +msgid "Display Name" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__id +msgid "ID" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users____last_update +msgid "Last Modified on" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_ir_model msgid "Models" msgstr "モデル" +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none +msgid "No restriction: All users / groups can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner_custom +msgid "" +"Owner + Custom: Creator and admin can delete them + for each model, selected " +"groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner +msgid "Owner: Only creator and admin can delete them" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment msgid "Restrict Attachment Deletion" msgstr "添付削除を制限" +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +#, fuzzy +msgid "Restrict Delete Attachments" +msgstr "添付削除を制限" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +#, fuzzy +msgid "Restrict Deletion on attachment" +msgstr "添付削除を制限" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Select default level of delete restriction on attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__smart_search +msgid "Smart Search" +msgstr "" + #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids -msgid "The user can delete the attachments related to the models assigned here." -msgstr "ユーザはここで割り当てられたモデルの添付を削除することができます。" +msgid "" +"The user can delete the attachments related to the models assigned here. In " +"general settings, 'Restrict Delete Attachment' must be set as 'custom' to " +"activate this setting." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +#, fuzzy +msgid "The users in the groups selected here can delete all the attachments." +msgstr "" +"ここで選択されたグループのユーザはこのモデルに関連する添付を削除することがで" +"きます。" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids -msgid "The users in the groups selected here can delete the attachments related to this model." -msgstr "ここで選択されたグループのユーザはこのモデルに関連する添付を削除することができます。" +msgid "" +"The users in the groups selected here can delete the attachments related to " +"this model." +msgstr "" +"ここで選択されたグループのユーザはこのモデルに関連する添付を削除することがで" +"きます。" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids -msgid "The users of the group can delete the attachments related to the models assigned here." -msgstr "グループのユーザはここで割り当てられたモデルの添付を削除することができます。" +#, fuzzy +msgid "" +"The users of the group can delete the attachments related to the models " +"assigned here. In general settings, 'Restrict Delete Attachment' must be set " +"as 'custom' to activate this setting." +msgstr "" +"グループのユーザはここで割り当てられたモデルの添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +#, fuzzy +msgid "The users selected here can delete all the attachments" +msgstr "" +"ここで選択されたユーザはこのモデルに関連する添付を削除することができます。" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids -msgid "The users selected here can delete the attachments related to this model." -msgstr "ここで選択されたユーザはこのモデルに関連する添付を削除することができます。" +msgid "" +"The users selected here can delete the attachments related to this model." +msgstr "" +"ここで選択されたユーザはこのモデルに関連する添付を削除することができます。" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__default +msgid "Use global configuration" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_users @@ -80,18 +262,27 @@ msgstr "ユーザ" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment -msgid "When selected, the deletion of the attachments related to this model is restricted to certain users." -msgstr "選択された場合、このモデルに関連する添付の削除は許可されたユーザのみに制限されます。" +msgid "" +"When selected, the deletion of the attachments related to this model is " +"restricted to certain users." +msgstr "" +"選択された場合、このモデルに関連する添付の削除は許可されたユーザのみに制限さ" +"れます。" #. module: attachment_delete_restrict -#: code:addons/attachment_delete_restrict/models/ir_attachment.py:34 +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 #, python-format -msgid "You are not allowed to delete this attachment.\n" +msgid "" +"You are not allowed to delete this attachment.\n" "\n" "Users with the delete permission:\n" "%s" -msgstr "この添付の削除権限がありません。\n" +msgstr "" +"この添付の削除権限がありません。\n" "\n" "削除権限を持つユーザ:\n" "%s" +#~ msgid "" +#~ "The user can delete the attachments related to the models assigned here." +#~ msgstr "ユーザはここで割り当てられたモデルの添付を削除することができます。" From 7d63001c0e9ca2c4cf4886b1e7532ef3d9563ba9 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 1 Sep 2022 08:02:28 +0000 Subject: [PATCH 08/24] [UPD] README.rst --- attachment_delete_restrict/README.rst | 46 +++++++++++--- .../static/description/index.html | 60 ++++++++++++++----- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/attachment_delete_restrict/README.rst b/attachment_delete_restrict/README.rst index a8b8a5aa77f..20476887e6e 100644 --- a/attachment_delete_restrict/README.rst +++ b/attachment_delete_restrict/README.rst @@ -14,19 +14,18 @@ Restrict Deletion of Attachments :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github - :target: https://github.com/OCA/server-tools/tree/12.0/attachment_delete_restrict + :target: https://github.com/OCA/server-tools/tree/14.0/attachment_delete_restrict :alt: OCA/server-tools .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-attachment_delete_restrict + :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-attachment_delete_restrict :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/149/12.0 + :target: https://runbot.odoo-community.org/runbot/149/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| -This module provides the ability to restrict the deletion of the attachments to certain -groups or users per related model. +This module provides the ability to restrict the deletion of the attachments at different levels. **Table of contents** @@ -36,7 +35,24 @@ groups or users per related model. Configuration ============= -#. Go to *Settings > Techinical > Database Structure > Models*. +Select level: +============= +#. Go to *Settings > General Settings> Permission section*. +#. Choose the level of *Restrict Delete Attachment* for all models by default or for models with "default" restriction level. + +Five levels: +============= +* Default : Use global configuration +* Owner : Owner and admins only +* Custom : Certain groups or users per related model. +* Owner + Strict : Owner, admins and Certain groups or users per related model. +* None : all users can delete them + +Only Owner and Custom + Strict need specific configuration on models. + +For Custom and Owner + Strict levels: +====================================== +#. Go to *Settings > Technical > Database Structure > Models*. #. Open a model for which attachment deletion should be restricted. #. Select 'Restrict Attachment Deletion', and assign 'Attachment Deletion Groups' and/or 'Attachment Deletion Users' as necessary (if no assignment, no one can delete the @@ -52,7 +68,7 @@ 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 smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -63,11 +79,14 @@ Authors ~~~~~~~ * Quartile Limited +* Akretion Contributors ~~~~~~~~~~~~ * Yoshi Tashiro +* Kévin Roche +* Sébastien BEAU Maintainers ~~~~~~~~~~~ @@ -82,6 +101,17 @@ 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/server-tools `_ project on GitHub. +.. |maintainer-yostashiro| image:: https://github.com/yostashiro.png?size=40px + :target: https://github.com/yostashiro + :alt: yostashiro +.. |maintainer-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px + :target: https://github.com/Kev-Roche + :alt: Kev-Roche + +Current `maintainers `__: + +|maintainer-yostashiro| |maintainer-Kev-Roche| + +This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_delete_restrict/static/description/index.html b/attachment_delete_restrict/static/description/index.html index 3b9827967dc..1b362e77af7 100644 --- a/attachment_delete_restrict/static/description/index.html +++ b/attachment_delete_restrict/static/description/index.html @@ -367,26 +367,49 @@

Restrict Deletion of Attachments

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

-

This module provides the ability to restrict the deletion of the attachments to certain -groups or users per related model.

+

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module provides the ability to restrict the deletion of the attachments at different levels.

Table of contents

+
+

Select level:

+
    +
  1. Go to Settings > General Settings> Permission section.
  2. +
  3. Choose the level of Restrict Delete Attachment for all models by default or for models with “default” restriction level.
  4. +
+
+
+

Five levels:

+
    +
  • Default : Use global configuration
  • +
  • Owner : Owner and admins only
  • +
  • Custom : Certain groups or users per related model.
  • +
  • Owner + Strict : Owner, admins and Certain groups or users per related model.
  • +
  • None : all users can delete them
  • +
+

Only Owner and Custom + Strict need specific configuration on models.

+
+
+

For Custom and Owner + Strict levels:

    -
  1. Go to Settings > Techinical > Database Structure > Models.
  2. +
  3. Go to Settings > Technical > Database Structure > Models.
  4. Open a model for which attachment deletion should be restricted.
  5. Select ‘Restrict Attachment Deletion’, and assign ‘Attachment Deletion Groups’ and/or ‘Attachment Deletion Users’ as necessary (if no assignment, no one can delete the @@ -397,35 +420,40 @@

    Configuration

    respective group/user form.

-

Bug Tracker

+

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 smashing it by providing a detailed and welcomed -feedback.

+feedback.

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Quartile Limited
  • +
  • Akretion
-

Maintainers

+

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/server-tools project on GitHub.

+

Current maintainers:

+

yostashiro Kev-Roche

+

This module is part of the OCA/server-tools project on GitHub.

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

From 5b3c742d1c5808718a3033f80f53c0a31ae17846 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 1 Sep 2022 08:02:29 +0000 Subject: [PATCH 09/24] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 attachment_delete_restrict/static/description/icon.png diff --git a/attachment_delete_restrict/static/description/icon.png b/attachment_delete_restrict/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From b8ba7f7cf4aeee21f97715e8e02870627e9225a6 Mon Sep 17 00:00:00 2001 From: Ignacio Buioli Date: Sun, 4 Sep 2022 03:26:16 +0000 Subject: [PATCH 10/24] Added translation using Weblate (Spanish (Argentina)) --- attachment_delete_restrict/i18n/es_AR.po | 263 +++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 attachment_delete_restrict/i18n/es_AR.po diff --git a/attachment_delete_restrict/i18n/es_AR.po b/attachment_delete_restrict/i18n/es_AR.po new file mode 100644 index 00000000000..3ca8dac423c --- /dev/null +++ b/attachment_delete_restrict/i18n/es_AR.po @@ -0,0 +1,263 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_delete_restrict +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es_AR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +msgid "Attachment Deletion Groups" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_groups_form +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_users_form +msgid "Attachment Deletion Models" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +msgid "Attachment Deletion Users" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Groups:" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Authorized Users:" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_change_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_ids +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_ids +msgid "Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changeset_changes +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changesets +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom +msgid "Custom: For each model, selected groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Define a default value for Attachments Deletion" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__display_name +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__display_name +msgid "Display Name" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__id +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__id +msgid "ID" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups____last_update +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users____last_update +msgid "Last Modified on" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_ir_model +msgid "Models" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none +msgid "No restriction: All users / groups can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner_custom +msgid "" +"Owner + Custom: Creator and admin can delete them + for each model, selected" +" groups and users can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner +msgid "Owner: Only creator and admin can delete them" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "Restrict Attachment Deletion" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment +msgid "Restrict Delete Attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Restrict Deletion on attachment" +msgstr "" + +#. module: attachment_delete_restrict +#: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form +msgid "Select default level of delete restriction on attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__smart_search +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__smart_search +msgid "Smart Search" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids +msgid "" +"The user can delete the attachments related to the models assigned here. In " +"general settings, 'Restrict Delete Attachment' must be set as 'custom' to " +"activate this setting." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids +msgid "The users in the groups selected here can delete all the attachments." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids +msgid "" +"The users in the groups selected here can delete the attachments related to " +"this model." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids +msgid "" +"The users of the group can delete the attachments related to the models " +"assigned here. In general settings, 'Restrict Delete Attachment' must be set" +" as 'custom' to activate this setting." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids +msgid "The users selected here can delete all the attachments" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids +msgid "" +"The users selected here can delete the attachments related to this model." +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__default +msgid "Use global configuration" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__user_can_see_changeset +#: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model,name:attachment_delete_restrict.model_res_users +msgid "Users" +msgstr "" + +#. module: attachment_delete_restrict +#: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment +msgid "" +"When selected, the deletion of the attachments related to this model is " +"restricted to certain users." +msgstr "" + +#. module: attachment_delete_restrict +#: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 +#, python-format +msgid "" +"You are not allowed to delete this attachment.\n" +"\n" +"Users with the delete permission:\n" +"%s" +msgstr "" From aa5c9d26b77427db6c68117aa02446b649e8e86e Mon Sep 17 00:00:00 2001 From: Ignacio Buioli Date: Sun, 4 Sep 2022 03:39:11 +0000 Subject: [PATCH 11/24] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (37 of 37 strings) Translation: server-tools-14.0/server-tools-14.0-attachment_delete_restrict Translate-URL: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-attachment_delete_restrict/es_AR/ --- attachment_delete_restrict/i18n/es_AR.po | 83 ++++++++++++++++-------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/attachment_delete_restrict/i18n/es_AR.po b/attachment_delete_restrict/i18n/es_AR.po index 3ca8dac423c..350126ff174 100644 --- a/attachment_delete_restrict/i18n/es_AR.po +++ b/attachment_delete_restrict/i18n/es_AR.po @@ -6,29 +6,31 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2022-09-04 06:07+0000\n" +"Last-Translator: Ignacio Buioli \n" "Language-Team: none\n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_groups msgid "Access Groups" -msgstr "" +msgstr "Grupos de Acceso" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_ir_attachment msgid "Attachment" -msgstr "" +msgstr "Adjunto" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "Attachment Deletion Groups" -msgstr "" +msgstr "Grupos de Eliminación de Adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids @@ -36,23 +38,23 @@ msgstr "" #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_groups_form #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.view_users_form msgid "Attachment Deletion Models" -msgstr "" +msgstr "Modelo de Eliminación de Adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "Attachment Deletion Users" -msgstr "" +msgstr "Usuarios de Eliminación de Adjuntos" #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form msgid "Authorized Groups:" -msgstr "" +msgstr "Grupos Autorizados:" #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form msgid "Authorized Users:" -msgstr "" +msgstr "Usuarios Autorizados:" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_change_ids @@ -61,7 +63,7 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_change_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_change_ids msgid "Changeset Changes" -msgstr "" +msgstr "Cambios del Conjunto de Cambios" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__changeset_ids @@ -70,12 +72,12 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__changeset_ids #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__changeset_ids msgid "Changesets" -msgstr "" +msgstr "Conjunto de Cambios" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_config_settings msgid "Config Settings" -msgstr "" +msgstr "Ajustes Configuración" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changeset_changes @@ -84,7 +86,7 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changeset_changes #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changeset_changes msgid "Count Pending Changeset Changes" -msgstr "" +msgstr "Cuenta de los Cambios Pendientes de los Conjuntos de Cambios" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__count_pending_changesets @@ -93,18 +95,20 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__count_pending_changesets #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__count_pending_changesets msgid "Count Pending Changesets" -msgstr "" +msgstr "Cuenta de los Conjuntos de Cambios Pendientes" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__custom #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__custom msgid "Custom: For each model, selected groups and users can delete them" msgstr "" +"Personalizado: Para cada modelo, los grupos y usuarios seleccionados pueden " +"eliminarlos" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment msgid "Define a default value for Attachments Deletion" -msgstr "" +msgstr "Define un valor preterminado para la Eliminación de Adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__display_name @@ -113,7 +117,7 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__display_name #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__display_name msgid "Display Name" -msgstr "" +msgstr "Mostrar Nombre" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__id @@ -122,7 +126,7 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__id #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__id msgid "ID" -msgstr "" +msgstr "ID" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment____last_update @@ -131,18 +135,18 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups____last_update #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users____last_update msgid "Last Modified on" -msgstr "" +msgstr "Última modificación en" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_ir_model msgid "Models" -msgstr "" +msgstr "Modelos" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__none #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__none msgid "No restriction: All users / groups can delete them" -msgstr "" +msgstr "No hay resitricción: Todos los usuarios / grupos pueden eliminarlos" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner_custom @@ -151,32 +155,36 @@ msgid "" "Owner + Custom: Creator and admin can delete them + for each model, selected" " groups and users can delete them" msgstr "" +"Propietario + Personalizado: El creador y administrador puede eliminarlos + " +"para cada modelo, los grupos y usuarios seleccionados pueden eliminarlos" #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__owner #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__res_config_settings__global_restrict_delete_attachment__owner msgid "Owner: Only creator and admin can delete them" -msgstr "" +msgstr "Propietario: Solo el creador y el administrador puede eliminarlos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_model__restrict_delete_attachment msgid "Restrict Attachment Deletion" -msgstr "" +msgstr "Restringir Eliminación de Adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_config_settings__global_restrict_delete_attachment msgid "Restrict Delete Attachments" -msgstr "" +msgstr "Restringir Eliminar Adjuntos" #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form msgid "Restrict Deletion on attachment" -msgstr "" +msgstr "Restringir la Eliminación en adjunto" #. module: attachment_delete_restrict #: model_terms:ir.ui.view,arch_db:attachment_delete_restrict.res_config_settings_view_form msgid "Select default level of delete restriction on attachments" msgstr "" +"Seleccione el nivel predeterminado de restricción de eliminación de archivos " +"adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__smart_search @@ -185,7 +193,7 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__smart_search #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__smart_search msgid "Smart Search" -msgstr "" +msgstr "Búsqueda Inteligente" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_users__delete_attachment_model_ids @@ -194,11 +202,16 @@ msgid "" "general settings, 'Restrict Delete Attachment' must be set as 'custom' to " "activate this setting." msgstr "" +"El usuario puede eliminar los archivos adjuntos relacionados con los modelos " +"asignados aquí. En la configuración general, 'Restringir eliminar adjunto' " +"debe configurarse como 'Personalizado' para activar esta configuración." #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_group_ids msgid "The users in the groups selected here can delete all the attachments." msgstr "" +"Los usuarios en los grupos seleccionados acá pueden eliminar todos los " +"adjuntos." #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_group_ids @@ -206,6 +219,8 @@ msgid "" "The users in the groups selected here can delete the attachments related to " "this model." msgstr "" +"Los usuarios en los grupos seleccionados acá pueden eliminar los adjuntos " +"relacionados a este modelo." #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_groups__delete_attachment_model_ids @@ -214,22 +229,28 @@ msgid "" "assigned here. In general settings, 'Restrict Delete Attachment' must be set" " as 'custom' to activate this setting." msgstr "" +"Los usuarios del grupo pueden eliminar los archivos adjuntos relacionados " +"con los modelos asignados acá. En la configuración general, 'Restringir " +"eliminar adjuntos' debe configurarse como 'Personalizado' para activar esta " +"configuración." #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_res_config_settings__global_delete_attachment_user_ids msgid "The users selected here can delete all the attachments" -msgstr "" +msgstr "Los usuarios seleccionados acá pueden eliminar todos los adjuntos" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__delete_attachment_user_ids msgid "" "The users selected here can delete the attachments related to this model." msgstr "" +"Los usuarios seleccionados acá pueden eliminar los adjuntos relacionados a " +"este modelo." #. module: attachment_delete_restrict #: model:ir.model.fields.selection,name:attachment_delete_restrict.selection__ir_model__restrict_delete_attachment__default msgid "Use global configuration" -msgstr "" +msgstr "Usar configuración global" #. module: attachment_delete_restrict #: model:ir.model.fields,field_description:attachment_delete_restrict.field_ir_attachment__user_can_see_changeset @@ -238,12 +259,12 @@ msgstr "" #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_groups__user_can_see_changeset #: model:ir.model.fields,field_description:attachment_delete_restrict.field_res_users__user_can_see_changeset msgid "User Can See Changeset" -msgstr "" +msgstr "El Usuario Puede ver Conjuntos de Cambios" #. module: attachment_delete_restrict #: model:ir.model,name:attachment_delete_restrict.model_res_users msgid "Users" -msgstr "" +msgstr "Usuarios" #. module: attachment_delete_restrict #: model:ir.model.fields,help:attachment_delete_restrict.field_ir_model__restrict_delete_attachment @@ -251,6 +272,8 @@ msgid "" "When selected, the deletion of the attachments related to this model is " "restricted to certain users." msgstr "" +"Cuando se selecciona, la eliminación de los archivos adjuntos relacionados " +"con este modelo está restringida a ciertos usuarios." #. module: attachment_delete_restrict #: code:addons/attachment_delete_restrict/models/ir_attachment.py:0 @@ -261,3 +284,7 @@ msgid "" "Users with the delete permission:\n" "%s" msgstr "" +"No tiene permitido eliminar este archivo adjunto\n" +"\n" +"Usuarios con permisos de eliminación:\n" +"%s" From 2ad9eeab06f20fc67a5b1afcd3e5b23aac669ff6 Mon Sep 17 00:00:00 2001 From: Jon Date: Mon, 13 Feb 2023 16:22:50 +0000 Subject: [PATCH 12/24] [FIX] attachment_delete_restrict: adapt to Odoo permission change --- .../tests/test_attachment_delete_restrict.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py index 330c9edb647..d8d0ad2233f 100644 --- a/attachment_delete_restrict/tests/test_attachment_delete_restrict.py +++ b/attachment_delete_restrict/tests/test_attachment_delete_restrict.py @@ -72,19 +72,38 @@ def setUpClass(cls): "attachment_delete_restrict.global_restrict_delete_attachment", "none" ) cls.partner_model = cls.env["ir.model"].search([("model", "=", "res.partner")]) + cls.partner_1 = cls.env["res.partner"].create({"name": "partner_1"}) cls.group = cls.env.ref("base.group_user") cls.user_owner = cls.env["res.users"].create( { "name": "test owner user", "login": "test-owner@example.com", - "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], + "groups_id": [ + ( + 6, + 0, + ( + cls.env.ref("base.group_user").id, + cls.env.ref("base.group_partner_manager").id, + ), + ) + ], } ) cls.user = cls.env["res.users"].create( { "name": "test user", "login": "test2@example.com", - "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], + "groups_id": [ + ( + 6, + 0, + ( + cls.env.ref("base.group_user").id, + cls.env.ref("base.group_partner_manager").id, + ), + ) + ], } ) cls.user_admin = cls.env["res.users"].create( @@ -98,6 +117,7 @@ def setUpClass(cls): ( cls.env.ref("base.group_system").id, cls.env.ref("base.group_user").id, + cls.env.ref("base.group_partner_manager").id, ), ) ], @@ -111,6 +131,7 @@ def setUpClass(cls): "name": "test attachment 2", "type": "binary", "res_model": "res.partner", + "res_id": cls.partner_1.id, } ) ) From 58cc53a4a2f13dc179473c04d986751e8b100bb9 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 14 Feb 2023 08:34:08 +0000 Subject: [PATCH 13/24] attachment_delete_restrict 14.0.1.0.1 --- attachment_delete_restrict/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py index 040eb39a47d..459a7f78125 100644 --- a/attachment_delete_restrict/__manifest__.py +++ b/attachment_delete_restrict/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Restrict Deletion of Attachments", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "depends": [ "base", "base_setup", From 781997b3b58150f3199582678a0ed8c3e03f2abd Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 7 Jul 2023 12:56:33 +0630 Subject: [PATCH 14/24] [MIG] attachment_delete_restrict: Migration to 16.0 --- attachment_delete_restrict/README.rst | 10 ++++---- attachment_delete_restrict/__manifest__.py | 4 ++-- .../migrations/14.0.1.0.0/post-migrate.py | 23 ------------------- .../migrations/14.0.1.0.0/pre-migrate.py | 16 ------------- .../models/ir_attachment.py | 2 +- .../static/description/index.html | 8 +++---- .../tests/test_attachment_delete_restrict.py | 4 ++-- ..._view.xml => res_config_setting_views.xml} | 0 8 files changed, 14 insertions(+), 53 deletions(-) delete mode 100644 attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py delete mode 100644 attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py rename attachment_delete_restrict/views/{res_config_view.xml => res_config_setting_views.xml} (100%) diff --git a/attachment_delete_restrict/README.rst b/attachment_delete_restrict/README.rst index 20476887e6e..ae91e99c5f1 100644 --- a/attachment_delete_restrict/README.rst +++ b/attachment_delete_restrict/README.rst @@ -14,13 +14,13 @@ Restrict Deletion of Attachments :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github - :target: https://github.com/OCA/server-tools/tree/14.0/attachment_delete_restrict + :target: https://github.com/OCA/server-tools/tree/16.0/attachment_delete_restrict :alt: OCA/server-tools .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-attachment_delete_restrict + :target: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-attachment_delete_restrict :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/149/14.0 + :target: https://runbot.odoo-community.org/runbot/149/16.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -68,7 +68,7 @@ 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 smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -112,6 +112,6 @@ Current `maintainers `__: |maintainer-yostashiro| |maintainer-Kev-Roche| -This module is part of the `OCA/server-tools `_ project on GitHub. +This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_delete_restrict/__manifest__.py b/attachment_delete_restrict/__manifest__.py index 459a7f78125..698610f4425 100644 --- a/attachment_delete_restrict/__manifest__.py +++ b/attachment_delete_restrict/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Restrict Deletion of Attachments", - "version": "14.0.1.0.1", + "version": "16.0.1.0.0", "depends": [ "base", "base_setup", @@ -16,7 +16,7 @@ "views/ir_model_views.xml", "views/res_groups_views.xml", "views/res_users_views.xml", - "views/res_config_view.xml", + "views/res_config_setting_views.xml", ], "installable": True, } diff --git a/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py b/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py deleted file mode 100644 index 5fe21510d99..00000000000 --- a/attachment_delete_restrict/migrations/14.0.1.0.0/post-migrate.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2022 Akretion (). -# @author Kévin Roche -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from openupgradelib import openupgrade - -from odoo.tools.sql import column_exists - - -@openupgrade.migrate() -def migrate(env, version): - if column_exists(env.cr, "ir_model", "migrated_restrict_delete_attachment"): - query = """ - SELECT id FROM ir_model WHERE migrated_restrict_delete_attachment = True - """ - env.cr.execute(query) - results = env.cr.fetchall() - models = env["ir.model"].search([("id", "in", results)]) - for model in models: - model.restrict_delete_attachment = "custom" - - query2 = "ALTER TABLE ir_model DROP COLUMN migrated_restrict_delete_attachment;" - env.cr.execute(query2) diff --git a/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py b/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py deleted file mode 100644 index 61c6e2221bb..00000000000 --- a/attachment_delete_restrict/migrations/14.0.1.0.0/pre-migrate.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2022 Akretion (). -# @author Kévin Roche -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - - -from odoo.tools.sql import column_exists, rename_column - - -def migrate(cr, version): - if column_exists(cr, "ir_model", "restrict_delete_attachment"): - rename_column( - cr, - "ir_model", - "restrict_delete_attachment", - "migrated_restrict_delete_attachment", - ) diff --git a/attachment_delete_restrict/models/ir_attachment.py b/attachment_delete_restrict/models/ir_attachment.py index a3a6d936441..8b8077afec7 100644 --- a/attachment_delete_restrict/models/ir_attachment.py +++ b/attachment_delete_restrict/models/ir_attachment.py @@ -66,7 +66,7 @@ def _check_custom_delete_attachment(self, model=None, allow_owner_and_admin=Fals def unlink(self): res_models = list(set(self.filtered("res_model").mapped("res_model"))) if res_models: - models = self.env["ir.model"].search([("model", "in", res_models)]) + models = self.env["ir.model"].sudo().search([("model", "in", res_models)]) name2models = {m.model: m for m in models} for rec in self: if rec.res_model: diff --git a/attachment_delete_restrict/static/description/index.html b/attachment_delete_restrict/static/description/index.html index 1b362e77af7..2962e9d7c1e 100644 --- a/attachment_delete_restrict/static/description/index.html +++ b/attachment_delete_restrict/static/description/index.html @@ -3,7 +3,7 @@ - + Restrict Deletion of Attachments