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
14 changes: 14 additions & 0 deletions tier_validation_password_confirm/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
=====================================
Tier Validation Password Confirm
=====================================

This module adds a new field to the tier definition that allows to set a password confirmation,
so later in the tier validation the system will ask the user to confirm the password.

Credits
=======

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

- ForgeFlow S.L. <[email protected]>
2 changes: 2 additions & 0 deletions tier_validation_password_confirm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizards
19 changes: 19 additions & 0 deletions tier_validation_password_confirm/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com)
{
"name": "Tier Validation Password Confirm",
"version": "18.0.1.0.0",
"category": "Server UX",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/server-ux",
"depends": [
"base_tier_validation",
],
"data": [
"views/tier_definition_view.xml",
"wizards/tier_password_wizard_view.xml",
],
"installable": True,
"auto_install": False,
"application": False,
}
3 changes: 3 additions & 0 deletions tier_validation_password_confirm/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import tier_review
from . import tier_validation
from . import tier_definition
12 changes: 12 additions & 0 deletions tier_validation_password_confirm/models/tier_definition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2024 ForgeFlow S.L.

from odoo import fields, models


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

require_password = fields.Boolean(
help="If checked, the user will be asked to enter "
"the password to validate the tier.",
)
11 changes: 11 additions & 0 deletions tier_validation_password_confirm/models/tier_review.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2024 ForgeFlow S.L.
from odoo import fields, models


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

require_password = fields.Boolean(
related="definition_id.require_password", readonly=True
)
password_confirmed = fields.Boolean()
53 changes: 53 additions & 0 deletions tier_validation_password_confirm/models/tier_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2025 ForgeFlow S.L.

from odoo import _, fields, models
from odoo.exceptions import ValidationError


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

require_password = fields.Boolean(compute="_compute_require_password")

def _compute_require_password(self):
for rec in self:
require_password = rec.review_ids.filtered(
lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids)
).mapped("require_password")
rec.require_password = True in require_password

def validate_tier(self):
self.ensure_one()
sequences = self._get_sequences_to_approve(self.env.user)
reviews = self.review_ids.filtered(
lambda r: r.sequence in sequences or r.approve_sequence_bypass
)
if self.has_comment or self.require_password:
user_reviews = reviews.filtered(
lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids)
)
return self._add_comment("validate", user_reviews)
self._validate_tier(reviews)
self._update_counter({"review_deleted": True})

def _add_comment(self, validate_reject, reviews):
res = super()._add_comment(validate_reject, reviews)
res["context"]["comment"] = self.has_comment
res["context"]["require_password"] = self.require_password
return res

def _validate_tier(self, tiers=False):
self.ensure_one()
tier_reviews = tiers or self.review_ids
user_reviews = tier_reviews.filtered(
lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids)
)
for review in user_reviews:
if review.require_password and not review.password_confirmed:
raise ValidationError(
_(
"You need to request a validation, because "
"the reviewer requires a password to validate."
)
)
return super()._validate_tier(tiers)
3 changes: 3 additions & 0 deletions tier_validation_password_confirm/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
16 changes: 16 additions & 0 deletions tier_validation_password_confirm/views/tier_definition_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 ForgeFlow S.L. -->
<odoo>
<record id="complaint_tier_definition_form" model="ir.ui.view">
<field name="name">complaint.tier.definition.form</field>
<field name="model">tier.definition</field>
<field name="inherit_id" ref="base_tier_validation.tier_definition_view_form" />
<field name="arch" type="xml">
<xpath expr="//notebook/page[@name='options']" position="inside">
<group>
<field name="require_password" />
</group>
</xpath>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions tier_validation_password_confirm/wizards/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import tier_password_wizard
37 changes: 37 additions & 0 deletions tier_validation_password_confirm/wizards/tier_password_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from odoo import _, api, fields, models
from odoo.exceptions import AccessDenied, ValidationError


class CommentWizardInherit(models.TransientModel):
_inherit = "comment.wizard"

password = fields.Char()
has_comment = fields.Boolean()
require_password = fields.Boolean()
comment = fields.Char(required=False)

@api.model
def default_get(self, fields_list):
"""Set default values based on context."""
defaults = super().default_get(fields_list)
defaults["has_comment"] = self.env.context.get("comment", False)
defaults["require_password"] = self.env.context.get("require_password", False)

return defaults

def add_comment(self):
self.ensure_one()
if self.require_password:
user = self.env.user
try:
credentials = {
"login": user.login,
"password": self.password,
"type": "password",
}
user._check_credentials(credentials, {"interactive": True})
self.review_ids.write({"password_confirmed": True})
except AccessDenied as e:
raise ValidationError(_("Incorrect password. Please try again.")) from e

return super().add_comment()
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<odoo>
<record id="view_comment_wizard_inherit" model="ir.ui.view">
<field name="name">Comment Wizard Inherit</field>
<field name="model">comment.wizard</field>
<field name="inherit_id" ref="base_tier_validation.view_comment_wizard" />
<field name="arch" type="xml">
<xpath expr="//group" position="inside">
<field name="require_password" invisible="1" />
<field name="has_comment" invisible="1" />
</xpath>

<xpath expr="//group" position="after">
<group invisible="not require_password">
<field name="password" password="True" />
</group>
</xpath>

<field name="comment" position="attributes">
<attribute name="invisible">not has_comment</attribute>
<attribute name="requred">has_comment</attribute>
</field>

<field name="comment" position="before">
<label for="comment" string="Comment" invisible="not has_comment" />
</field>
</field>
</record>
</odoo>
Loading