From 0fea305e17d49fb33d16ba1167c3228b230fb32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Fri, 4 Sep 2026 10:20:31 +0200 Subject: [PATCH] [FIX] dms: Taking archived users into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Case Example: - Create an archived user (an employee’s user account that will be activated in the future) - Create a group that explicitly includes the user created earlier (this is done indirectly using `hr_dms_field`) - The `users` field does not contain this user TT64366 --- dms/README.rst | 122 ++++++++++---------- dms/__manifest__.py | 2 +- dms/migrations/19.0.1.1.0/post-migration.py | 26 +++++ dms/models/access_groups.py | 4 + dms/static/description/index.html | 4 +- 5 files changed, 94 insertions(+), 64 deletions(-) create mode 100644 dms/migrations/19.0.1.1.0/post-migration.py diff --git a/dms/README.rst b/dms/README.rst index 10af6f5b6..17321aba3 100644 --- a/dms/README.rst +++ b/dms/README.rst @@ -72,9 +72,9 @@ To configure this module, you need to: 2. Create a new document storage. You can choose between three options on ``Save Type``: - - ``Database``: Store the files on the database as a field - - ``Attachment``: Store the files as attachments - - ``File``: Store the files on the file system + - ``Database``: Store the files on the database as a field + - ``Attachment``: Store the files as attachments + - ``File``: Store the files on the file system 2. Create an access group ------------------------- @@ -82,13 +82,13 @@ To configure this module, you need to: 1. Next, create an administrative access group. Go to *Configuration -> Access Groups*. - - Create a new group, name it appropriately, and turn on all three - permissions (Create, Write and Unlink. Read is implied and always - enabled). - - Add any other top-level administrative users to the group if needed - (your user should already be there). - - You can create other groups in here later for fine-grained access - control. + - Create a new group, name it appropriately, and turn on all three + permissions (Create, Write and Unlink. Read is implied and always + enabled). + - Add any other top-level administrative users to the group if + needed (your user should already be there). + - You can create other groups in here later for fine-grained access + control. 3. Create a directory --------------------- @@ -98,18 +98,18 @@ To configure this module, you need to: 2. Create a new directory, mark it as root and select the previously created setting. - - Select the *Groups* tab and add your administrative group created - above. If your directory was already created before the group, you - can also add it in the access groups (*Configuration -> Access - Groups*). + - Select the *Groups* tab and add your administrative group created + above. If your directory was already created before the group, you + can also add it in the access groups (*Configuration -> Access + Groups*). 3. In the directory settings, you can also add other access groups (created above) that will be able to: - - read - - create - - write - - delete + - read + - create + - write + - delete Migration ========= @@ -155,28 +155,28 @@ access to that resource, no matter if logged or not. Known issues / Roadmap ====================== -- Files preview in portal -- Allow to download folder in portal and create zip file with all - content -- Save in cache own_root directories and update in every - create/write/unlink function -- Add a migration procedure for converting an storage to attachment one - for populating existing records with attachments as folders -- Add a link from attachment view in chatter to linked documents -- If Inherit permissions from related record (the - inherit_access_from_parent_record field from storage) is changed when - directories already exist, inconsistencies may occur because groups - defined in the directories and subdirectories will still exist, all - groups in these directories should be removed before changing. -- Since portal users can read ``dms.storage`` records, if your module - extends this model to another storage backend that needs using - secrets, remember to forbid access to the secrets fields by other - means. It would be nice to be able to remove that rule at some point. -- Searchpanel in files: Highlight items (shading) without records when - filtering something (by name for example). -- Accessing the clipboard (for example copy share link of - file/directory) is limited to secure connections. It also happens in - any part of Odoo. +- Files preview in portal +- Allow to download folder in portal and create zip file with all + content +- Save in cache own_root directories and update in every + create/write/unlink function +- Add a migration procedure for converting an storage to attachment one + for populating existing records with attachments as folders +- Add a link from attachment view in chatter to linked documents +- If Inherit permissions from related record (the + inherit_access_from_parent_record field from storage) is changed when + directories already exist, inconsistencies may occur because groups + defined in the directories and subdirectories will still exist, all + groups in these directories should be removed before changing. +- Since portal users can read ``dms.storage`` records, if your module + extends this model to another storage backend that needs using + secrets, remember to forbid access to the secrets fields by other + means. It would be nice to be able to remove that rule at some point. +- Searchpanel in files: Highlight items (shading) without records when + filtering something (by name for example). +- Accessing the clipboard (for example copy share link of + file/directory) is limited to secure connections. It also happens in + any part of Odoo. Bug Tracker =========== @@ -200,40 +200,40 @@ Authors Contributors ------------ -- Mathias Markl -- Enric Tobella -- Antoni Romera -- Gelu Boros -- `Tecnativa `__: +- Mathias Markl +- Enric Tobella +- Antoni Romera +- Gelu Boros +- `Tecnativa `__: - - Víctor Martínez - - Pedro M. Baeza - - Jairo Llopis + - Víctor Martínez + - Pedro M. Baeza + - Jairo Llopis -- `Elego `__: +- `Elego `__: - - Yu Weng - - Philip Witte - - Khanh Bui + - Yu Weng + - Philip Witte + - Khanh Bui -- `Subteno `__: +- `Subteno `__: - - Timothée Vannier + - Timothée Vannier -- `Kencove `__: +- `Kencove `__: - - Mohamed Alkobrosli + - Mohamed Alkobrosli Other credits ------------- Some pictures are based on or inspired by: -- `Roundicons `__ -- `Smashicons `__ -- `EmojiOne `__ : Portal DMS icon -- `GitHub Octicons `__ : The main - DMS icon +- `Roundicons `__ +- `Smashicons `__ +- `EmojiOne `__ : Portal DMS icon +- `GitHub Octicons `__ : The main + DMS icon Maintainers ----------- diff --git a/dms/__manifest__.py b/dms/__manifest__.py index 0f69a1936..01253cd9e 100644 --- a/dms/__manifest__.py +++ b/dms/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Document Management System", "summary": "Document Management System for Odoo", - "version": "19.0.1.0.0", + "version": "19.0.1.1.0", "category": "Document Management", "license": "LGPL-3", "website": "https://github.com/OCA/dms", diff --git a/dms/migrations/19.0.1.1.0/post-migration.py b/dms/migrations/19.0.1.1.0/post-migration.py new file mode 100644 index 000000000..54bd0ceff --- /dev/null +++ b/dms/migrations/19.0.1.1.0/post-migration.py @@ -0,0 +1,26 @@ +# Copyright 2026 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + """If there were archived users linked in `explicit_user_ids`, the relationship + did exist in the `dms_access_group_explicit_users_rel` table; therefore, those + users will now "appear" in `explicit_user_ids`, and it will be necessary to call + the `_compute_users()` method so that the `users` and `count_users` fields have + the correct values. + It is extremely important that the `users` field has the correct values; otherwise, + if we activate any of those users, they will not be able to view the linked records. + We set `active_test=False` in the search context to ensure that archived users are + taken into account, even though the `explicit_user_ids` field has that context + defined in the field itself. + """ + groups = ( + env["dms.access.group"] + .sudo() + .with_context(active_test=False) + .search([("explicit_user_ids.active", "=", False)]) + ) + if groups: + groups._compute_users() diff --git a/dms/models/access_groups.py b/dms/models/access_groups.py index 899c93026..e9c079aab 100644 --- a/dms/models/access_groups.py +++ b/dms/models/access_groups.py @@ -82,6 +82,7 @@ class DmsAccessGroups(models.Model): ) explicit_user_ids = fields.Many2many( comodel_name="res.users", + context={"active_test": False}, relation="dms_access_group_explicit_users_rel", column1="gid", column2="uid", @@ -89,6 +90,7 @@ class DmsAccessGroups(models.Model): ) users = fields.Many2many( comodel_name="res.users", + context={"active_test": False}, relation="dms_access_group_users_rel", column1="gid", column2="uid", @@ -143,8 +145,10 @@ def default_get(self, fields_list): @api.depends( "parent_group_id", "parent_group_id.users", + "parent_group_id.users.active", "group_ids", "group_ids.user_ids", + "group_ids.user_ids.active", "explicit_user_ids", ) def _compute_users(self): diff --git a/dms/static/description/index.html b/dms/static/description/index.html index 9e3711939..af4f3c622 100644 --- a/dms/static/description/index.html +++ b/dms/static/description/index.html @@ -449,8 +449,8 @@

2. Create an access group

Create a new group, name it appropriately, and turn on all three permissions (Create, Write and Unlink. Read is implied and always enabled). -
  • Add any other top-level administrative users to the group if needed -(your user should already be there).
  • +
  • Add any other top-level administrative users to the group if +needed (your user should already be there).
  • You can create other groups in here later for fine-grained access control.