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
49 changes: 49 additions & 0 deletions base_tier_validation/models/tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,36 @@ class TierValidation(models.AbstractModel):
)
next_review = fields.Char(compute="_compute_next_review")
hide_reviews = fields.Boolean(compute="_compute_hide_reviews")
tier_review_count = fields.Integer(
compute="_compute_tier_review_count",
string="Tier Reviews",
)

@api.depends("review_ids")
def _compute_tier_review_count(self):
for rec in self:
rec.tier_review_count = len(rec.review_ids)

def action_view_tier_reviews(self):
"""Open the tier.review list filtered to this document.

Used by the smart-button auto-injected on validated records and
callable from any bridge module that wants to surface the same
link manually.
"""
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id(
"base_tier_validation.action_tier_review"
)
action["domain"] = [
("model", "=", self._name),
("res_id", "=", self.id),
]
action["context"] = {
"default_model": self._name,
"default_res_id": self.id,
}
return action

@api.depends_context("uid")
@api.depends(
Expand Down Expand Up @@ -880,6 +910,13 @@ def _add_tier_validation_reviews(self, node, params):
new_node = etree.fromstring(str_element)
return new_node

def _add_tier_validation_smart_button(self, node, params):
str_element = self.env["ir.qweb"]._render(
"base_tier_validation.tier_validation_smart_button", params
)
new_node = etree.fromstring(str_element)
return new_node

def _get_tier_validation_readonly_domain(self):
return "validation_status not in ('no', False)"

Expand Down Expand Up @@ -914,6 +951,18 @@ def get_view(self, view_id=None, view_type="form", **options):
new_node = etree.fromstring(new_arch)
node.append(new_node)
_merge_view_fields(all_models, new_models)
for node in doc.xpath("//div[@name='button_box']"):
# _add_tier_validation_smart_button process: counter +
# link to the underlying tier.review records. Only injected
# when the form already has a button_box; we don't conjure
# one if the bridge model didn't choose to expose smart
# buttons.
new_node = self._add_tier_validation_smart_button(node, params)
new_arch, new_models = View.postprocess_and_fields(new_node, self._name)
new_node = etree.fromstring(new_arch)
for new_element in new_node:
node.append(new_element)
_merge_view_fields(all_models, new_models)
excepted_fields = self._get_all_validation_exceptions()
all_fields = self.fields_get(attributes=("readonly",))
for node in doc.xpath("//field[@name][not(ancestor::field)]"):
Expand Down
13 changes: 13 additions & 0 deletions base_tier_validation/templates/tier_validation_templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@
</div>
</div>
</template>
<template id="tier_validation_smart_button">
<div>
<button
type="object"
name="action_view_tier_reviews"
class="oe_stat_button"
icon="fa-thumbs-up"
invisible="not review_ids"
>
<field name="tier_review_count" widget="statinfo" string="Reviews" />
</button>
</div>
</template>
<template id="tier_validation_reviews">
<field
name="review_ids"
Expand Down
21 changes: 21 additions & 0 deletions base_tier_validation/tests/test_tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,27 @@ def test_16b_review_user_count_no_model_access(self):
result = self.test_user_2.with_user(self.test_user_2).review_user_count()
self.assertEqual(result, [])

def test_action_view_tier_reviews(self):
"""Smart-button helper returns an action filtered to the current
record's reviews."""
self.tier_def_obj.create(
{
"model_id": self.tester_model.id,
"review_type": "individual",
"reviewer_id": self.test_user_1.id,
"definition_domain": "[('test_field', '>', 1.0)]",
}
)
record = self.test_model.create({"test_field": 2.5})
# Before requesting validation: no reviews, counter is zero.
self.assertEqual(record.tier_review_count, 0)
record.with_user(self.test_user_2).request_validation()
self.assertGreater(record.tier_review_count, 0)
action = record.action_view_tier_reviews()
self.assertEqual(action["res_model"], "tier.review")
self.assertIn(("model", "=", record._name), action["domain"])
self.assertIn(("res_id", "=", record.id), action["domain"])

def test_17_search_records_no_validation(self):
"""Search for records that have no validation process started"""
records = self.env["tier.validation.tester"].search(
Expand Down
38 changes: 38 additions & 0 deletions base_tier_validation/views/tier_review_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,42 @@
</list>
</field>
</record>
<record id="tier_review_view_form" model="ir.ui.view">
<field name="name">tier.review.form</field>
<field name="model">tier.review</field>
<field name="arch" type="xml">
<form string="Tier Review" create="false" edit="false">
<sheet>
<group>
<group>
<field name="name" />
<field name="sequence" />
<field name="status" />
<field name="display_status" />
<field name="review_type" />
</group>
<group>
<field name="requested_by" widget="many2one_avatar_user" />
<field name="done_by" widget="many2one_avatar_user" />
<field name="reviewed_date" />
<field name="comment" />
</group>
</group>
<group string="Reviewers">
<field
name="reviewer_ids"
widget="many2many_avatar_user"
nolabel="1"
/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_tier_review" model="ir.actions.act_window">
<field name="name">Tier Reviews</field>
<field name="res_model">tier.review</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="tier_review_view_tree" />
</record>
</odoo>
Loading