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
125 changes: 125 additions & 0 deletions base_tier_validation_review_history/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
===================================
Base Tier Validation Review History
===================================

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |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/16.0/base_tier_validation_review_history
: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-16-0/server-ux-16-0-base_tier_validation_review_history
: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=16.0
:alt: Try me on Runboat

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

This module extends *Base Tier Validation* to keep completed tier reviews as
history instead of deleting them once a validation cycle ends (e.g. on
rejection restart or when the record is reset/cancelled).

Without this module, reviews are removed when the validation cycle is reset, so
there is no trace of who approved or rejected a document in a previous cycle.
With this module, completed reviews (approved/rejected) can be archived and kept
as a *Reviews History*, viewable on the document and from a dedicated menu.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

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

Keeping tier review history is resolved from two configuration levels:

#. **Company** → *Settings > Tier Validation > Keep Tier Review History*
(boolean). Sets the default for all tier definitions of the company. In
multi-company, switch to the relevant company before changing it.
#. **Tier Definition** → *Keep Tier Review History* (selection: *Keep* / *Do
Not Keep* / empty), on the *More Options* tab of the tier definition
(*Settings > Technical > Tier Validations > Tier Definitions*). Leave empty
to inherit the company default. *Keep* or *Do Not Keep* overrides the company
default for this tier definition.

When keeping is effective for a tier definition, its completed
(approved/rejected) reviews are archived as history instead of being deleted
when the validation cycle ends. The archived reviews are shown in the *Reviews
History* section of the document and can be browsed from
*Settings > Technical > Tier Validations > Tier Reviews*.

The *Reviews History* section is injected automatically only into documents
whose tier validation view is built automatically
(``_tier_validation_manual_config = False``), which is the case of the usual
consumers (purchase, sale, account move). A model that configures its tier
validation view manually must add ``<field name="review_history_ids" />`` to
its form view to display the history.

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_tier_validation_review_history%0Aversion:%2016.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
~~~~~~~

* Quartile

Contributors
~~~~~~~~~~~~

* `Quartile <https://www.quartile.co>`__:

* Shinnosuke Morita <morita@quartile.co>

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.

.. |maintainer-smorita7749| image:: https://github.com/smorita7749.png?size=40px
:target: https://github.com/smorita7749
:alt: smorita7749

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-smorita7749|

This module is part of the `OCA/server-ux <https://github.com/OCA/server-ux/tree/16.0/base_tier_validation_review_history>`_ 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_tier_validation_review_history/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
21 changes: 21 additions & 0 deletions base_tier_validation_review_history/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Base Tier Validation Review History",
"summary": "Keep completed tier reviews as history instead of deleting them",
"version": "16.0.1.0.0",
"category": "Tools",
"website": "https://github.com/OCA/server-ux",
"author": "Quartile, Odoo Community Association (OCA)",
"license": "AGPL-3",
"depends": ["base_tier_validation"],
"data": [
"views/res_config_settings_views.xml",
"views/tier_definition_view.xml",
"views/tier_review_view.xml",
"templates/tier_validation_templates.xml",
],
"development_status": "Alpha",
"maintainers": ["smorita7749"],
"installable": True,
}
5 changes: 5 additions & 0 deletions base_tier_validation_review_history/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import res_company
from . import res_config_settings
from . import tier_definition
from . import tier_review
from . import tier_validation
12 changes: 12 additions & 0 deletions base_tier_validation_review_history/models/res_company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

tier_validation_keep_review_history = fields.Boolean(
string="Keep Tier Review History"
)
13 changes: 13 additions & 0 deletions base_tier_validation_review_history/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

tier_validation_keep_review_history = fields.Boolean(
related="company_id.tier_validation_keep_review_history",
readonly=False,
)
32 changes: 32 additions & 0 deletions base_tier_validation_review_history/models/tier_definition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class TierDefinition(models.Model):
_inherit = "tier.definition"

keep_review_history = fields.Selection(
selection=[
("keep", "Keep"),
("no_keep", "Do Not Keep"),
],
string="Keep Tier Review History",
help="Override the company default for keeping completed reviews as "
"history. Leave empty to inherit the company setting.",
)

def _keep_review_history_enabled(self):
"""Resolve whether completed reviews of this definition are kept as
history. The definition overrides the company default in either
direction; an empty value inherits the company setting."""
self.ensure_one()
if self.keep_review_history == "keep":
return True
if self.keep_review_history == "no_keep":
return False
# A definition without company applies to every company, so it falls back
# to the setting of the company the validation is running for.
company = self.company_id or self.env.company
return company.tier_validation_keep_review_history
30 changes: 30 additions & 0 deletions base_tier_validation_review_history/models/tier_review.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class TierReview(models.Model):
_inherit = "tier.review"

active = fields.Boolean(default=True)
record_reference = fields.Reference(
string="Document",
selection="_selection_record_reference",
compute="_compute_record_reference",
help="The document under validation, as a clickable link.",
)

@api.model
def _selection_record_reference(self):
model_names = self.env["tier.definition"]._get_tier_validation_model_names()
ir_models = self.env["ir.model"].sudo().search([("model", "in", model_names)])
return [(m.model, m.name) for m in ir_models]

@api.depends("model", "res_id")
def _compute_record_reference(self):
for record in self:
if record.model and record.res_id and record.model in self.env:
record.record_reference = "{},{}".format(record.model, record.res_id)
else:
record.record_reference = None
65 changes: 65 additions & 0 deletions base_tier_validation_review_history/models/tier_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2026 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from lxml import etree

from odoo import fields, models


class TierValidation(models.AbstractModel):
_inherit = "tier.validation"

review_history_ids = fields.One2many(
comodel_name="tier.review",
inverse_name="res_id",
string="Review History",
domain=lambda self: [("model", "=", self._name), ("active", "=", False)],
context={"active_test": False},
)

def _remove_reviews(self):
"""Archive completed reviews configured to keep history; delete the rest."""
to_archive = self.review_ids.filtered(
lambda r: r.status in ("approved", "rejected")
and r.definition_id
and r.definition_id._keep_review_history_enabled()
)
if to_archive:
to_archive.write({"active": False})
# Archiving changes no FK/status, so nothing invalidates the caches of
# review_ids / review_history_ids or of the fields derived from them.
# need_validation, has_comment, next_review and is_reevaluation_required
# are computed without @api.depends in base, so modified() cannot flag
# them either and they have to be invalidated explicitly.
self.invalidate_recordset(
[
"review_ids",
"review_history_ids",
"need_validation",
"has_comment",
"next_review",
"is_reevaluation_required",
]
)
self.modified(["review_ids"])
return super(
TierValidation, self.with_context(active_test=True)
)._remove_reviews()

def unlink(self):
# active_test=False so archived history reviews are deleted too, not orphaned.
self.with_context(active_test=False).mapped("review_ids").unlink()
return super().unlink()

def _add_tier_validation_reviews(self, node, params):
"""Render the base reviews block and append the review-history block,
wrapped in a single root element (the caller expects one node)."""
review_node = super()._add_tier_validation_reviews(node, params)
history_str = self.env["ir.qweb"]._render(
"base_tier_validation_review_history.tier_validation_review_history",
params,
)
wrapper = etree.Element("div")
wrapper.append(review_node)
wrapper.append(etree.fromstring(history_str))
return wrapper
23 changes: 23 additions & 0 deletions base_tier_validation_review_history/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Keeping tier review history is resolved from two configuration levels:

#. **Company** → *Settings > Tier Validation > Keep Tier Review History*
(boolean). Sets the default for all tier definitions of the company. In
multi-company, switch to the relevant company before changing it.
#. **Tier Definition** → *Keep Tier Review History* (selection: *Keep* / *Do
Not Keep* / empty), on the *More Options* tab of the tier definition
(*Settings > Technical > Tier Validations > Tier Definitions*). Leave empty
to inherit the company default. *Keep* or *Do Not Keep* overrides the company
default for this tier definition.

When keeping is effective for a tier definition, its completed
(approved/rejected) reviews are archived as history instead of being deleted
when the validation cycle ends. The archived reviews are shown in the *Reviews
History* section of the document and can be browsed from
*Settings > Technical > Tier Validations > Tier Reviews*.

The *Reviews History* section is injected automatically only into documents
whose tier validation view is built automatically
(``_tier_validation_manual_config = False``), which is the case of the usual
consumers (purchase, sale, account move). A model that configures its tier
validation view manually must add ``<field name="review_history_ids" />`` to
its form view to display the history.
3 changes: 3 additions & 0 deletions base_tier_validation_review_history/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Quartile <https://www.quartile.co>`__:

* Shinnosuke Morita <morita@quartile.co>
8 changes: 8 additions & 0 deletions base_tier_validation_review_history/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This module extends *Base Tier Validation* to keep completed tier reviews as
history instead of deleting them once a validation cycle ends (e.g. on
rejection restart or when the record is reset/cancelled).

Without this module, reviews are removed when the validation cycle is reset, so
there is no trace of who approved or rejected a document in a previous cycle.
With this module, completed reviews (approved/rejected) can be archived and kept
as a *Reviews History*, viewable on the document and from a dedicated menu.
Loading
Loading