Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions base_archive_manager/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
===============
Archive Manager
===============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2346ac753b8e3940aa35c3ea94dbd53152c6d64b6cdb1f10d20d7af3edee9342
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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--ux-lightgray.png?logo=github
:target: https://github.com/OCA/server-ux/tree/18.0/base_archive_manager
:alt: OCA/server-ux
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-ux-18-0/server-ux-18-0-base_archive_manager
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-ux&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows administrators to control who can archive and
unarchive records in Odoo. By default, Odoo only provides a ``write``
permission, which implicitly allows any user with write access to
archive and unarchive records. This module introduces specific
``Archive Access`` and ``Unarchive Access`` permissions on the Access
Rights (``ir.model.access``) level.

**Table of contents**

.. contents::
:local:

Configuration
=============

To configure this module, you need to:

1. Go to *Settings > Technical > Security > Access Rights*.
2. Open any access right record.
3. You will see two new checkboxes: **Archive Access**
(``perm_archive``) and **Unarchive Access** (``perm_unarchive``).
4. Check or uncheck these boxes to grant or deny archive/unarchive
permissions for the corresponding group and model.

Usage
=====

Once configured, the module automatically controls the visibility of the
Archive and Unarchive actions across the system:

- In Form views, the ``Active`` stat button will be hidden if the user
lacks the required permission to toggle it (e.g., if a record is
active and the user lacks archive permission, the button is hidden).
- In List and Kanban views, the ``Archive`` and ``Unarchive`` action
menu items will be hidden depending on the user's permissions.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-ux/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-ux/issues/new?body=module:%20base_archive_manager%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
-------

* Solomon Prabu
* CIT Services

Contributors
------------

- `CIT-Services <cit-services.eu>`__

- Solomon Prabu s.prabu@cit-services.eu

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-ux <https://github.com/OCA/server-ux/tree/18.0/base_archive_manager>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions base_archive_manager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
23 changes: 23 additions & 0 deletions base_archive_manager/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright CIT Services 2026-27
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
"name": "Archive Manager",
"summary": "Manage model archive/unarchive accesses",
"category": "Personalization",
"version": "18.0.1.0.0",
"depends": ["web"],
"author": "Solomon Prabu, CIT Services, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-ux",
"assets": {
"web.assets_backend": [
"base_archive_manager/static/src/js/archiveAccess.esm.js",
"base_archive_manager/static/src/js/listController.esm.js",
"base_archive_manager/static/src/js/formController.esm.js",
"base_archive_manager/static/src/js/kanbanController.esm.js",
],
},
"data": ["views/ir_model_access.xml", "views/res_groups.xml"],
"license": "AGPL-3",
"installable": True,
}
1 change: 1 addition & 0 deletions base_archive_manager/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import base, ir_model_access
68 changes: 68 additions & 0 deletions base_archive_manager/models/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2026 CIT Services
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from lxml import etree

from odoo import api, models


class Base(models.AbstractModel):
_inherit = "base"

@api.model
def get_views(self, views, options=None):
"""Dynamically modify form view arch to hide the toggle_active button."""
res = super().get_views(views, options=options)

active_name = self._active_name
if not active_name:
return res

can_archive = self.env["ir.model.access"].check(
self._name, "archive", raise_exception=False
)
can_unarchive = self.env["ir.model.access"].check(
self._name, "unarchive", raise_exception=False
)

if can_archive and can_unarchive:
return res

if "views" in res:
for view_type in ["form", "list"]:
if view_type in res["views"]:
arch = res["views"][view_type].get("arch")
if arch:
doc = etree.fromstring(arch)
# Look for both the toggle_active button and
# the active field itself
elements = doc.xpath(
"//button[@name='toggle_active']"
) + doc.xpath(f"//field[@name='{active_name}']")
for elem in elements:
invisible_attr = ""
if not can_archive and not can_unarchive:
invisible_attr = "True"
elif can_archive and not can_unarchive:
# Can archive:
# hide if record is already archived (active=False)
invisible_attr = f"not {active_name}"
elif not can_archive and can_unarchive:
# Can unarchive:
# hide if record is already active (active=True)
invisible_attr = active_name

if invisible_attr:
existing = elem.get("invisible")
if existing:
elem.set(
"invisible",
f"({existing}) or ({invisible_attr})",
)
else:
elem.set("invisible", invisible_attr)

res["views"][view_type]["arch"] = etree.tostring(
doc, encoding="unicode"
)

return res
53 changes: 53 additions & 0 deletions base_archive_manager/models/ir_model_access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2026 CIT Services
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models, tools
from odoo.tools import SQL


class IrModelAccess(models.Model):
_inherit = "ir.model.access"

perm_archive = fields.Boolean("Archive Access", default=True)
perm_unarchive = fields.Boolean("Unarchive Access", default=True)

@api.model
@tools.ormcache("self.env.uid", "mode")
def _get_allowed_models(self, mode="read"):
"""Extend to support archive/unarchive access modes."""
if mode not in ("archive", "unarchive"):
return super()._get_allowed_models(mode)

group_ids = self.env.user._get_group_ids()

self.flush_model()
rows = self.env.execute_query(
SQL(
"""
SELECT m.model
FROM ir_model_access a
JOIN ir_model m ON (m.id = a.model_id)
WHERE a.perm_%s
AND a.active
AND (
a.group_id IS NULL OR
a.group_id IN %s
)
GROUP BY m.model
""",
SQL(mode),
tuple(group_ids) or (None,),
)
)
return frozenset(v[0] for v in rows)

@api.model
def get_archive_access(self, model):
"""Return archive/unarchive permission for the current user and model.
Called by the JS layer to decide whether to show Archive/Unarchive
action menu items.
"""
return {
"can_archive": self.check(model, "archive", raise_exception=False),
"can_unarchive": self.check(model, "unarchive", raise_exception=False),
}
3 changes: 3 additions & 0 deletions base_archive_manager/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
6 changes: 6 additions & 0 deletions base_archive_manager/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
To configure this module, you need to:

1. Go to *Settings > Technical > Security > Access Rights*.
2. Open any access right record.
3. You will see two new checkboxes: **Archive Access** (`perm_archive`) and **Unarchive Access** (`perm_unarchive`).
4. Check or uncheck these boxes to grant or deny archive/unarchive permissions for the corresponding group and model.
2 changes: 2 additions & 0 deletions base_archive_manager/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [CIT-Services](cit-services.eu)
- Solomon Prabu <s.prabu@cit-services.eu>
1 change: 1 addition & 0 deletions base_archive_manager/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module allows administrators to control who can archive and unarchive records in Odoo. By default, Odoo only provides a `write` permission, which implicitly allows any user with write access to archive and unarchive records. This module introduces specific `Archive Access` and `Unarchive Access` permissions on the Access Rights (`ir.model.access`) level.
4 changes: 4 additions & 0 deletions base_archive_manager/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Once configured, the module automatically controls the visibility of the Archive and Unarchive actions across the system:

* In Form views, the `Active` stat button will be hidden if the user lacks the required permission to toggle it (e.g., if a record is active and the user lacks archive permission, the button is hidden).
* In List and Kanban views, the `Archive` and `Unarchive` action menu items will be hidden depending on the user's permissions.
Loading