[19.0][ADD] tier_validation_digest#25
Open
bosd wants to merge 6 commits into
Open
Conversation
added 6 commits
May 13, 2026 17:57
New auto-installed module that surfaces tier-validation counts in the periodic KPI digest email so each recipient sees, at a glance: - how many tier reviews are pending their action right now, - how many reviews are queued behind a lower-sequence tier (useful when ``approve_sequence`` is enabled -- see what is coming), - how many reviews they validated during the digest period, and - (manager view) how many reviews are pending across the entire company. Each tile links to a filtered ``tier.review`` list so the recipient can act in one click. Auto-installs whenever both ``base_tier_validation`` and ``digest`` are present, so deployments already running both modules pick it up transparently. The four KPIs are single counts over ``tier.review`` -- not split per underlying business model -- because that is the digest convention (one number per tile) and because ``tier.review`` is the single source of truth across every tier-validated model. The action that opens from each tile groups by ``model`` by default, so the per-model breakdown is one click away. The team-wide KPI is gated to ``base.group_erp_manager`` so ordinary users do not see the configuration toggle on their own digest preferences. The framework already raises ``AccessError`` when a non-manager attempts to read the value, and the digest send loop catches that and skips the KPI for that user.
``ir.actions.act_window`` has no ``groups_id`` field in Odoo 19; the group restriction belongs on the calling ``ir.ui.menu``, not on the action itself. Setting it raised ``Invalid field 'groups_id' in 'ir.actions.act_window'`` at module install, breaking CI. Drop the field. Access gating is already handled where it matters: - The ``kpi_tier_validation_pending_team`` boolean is gated with ``groups="base.group_erp_manager"`` so only managers see the digest tile in their preferences. - The matching value field carries the same group, so non-managers reading it raise ``AccessError`` -- which the digest send loop already catches and skips. - If a non-manager direct-navigates to the action URL, they only ever see ``tier.review`` rows their existing ACL grants them (read access is granted to all internal users by ``base_tier_validation``).
Per-user KPIs need ``@api.depends_context('uid')`` so the ORM cache
is keyed by recipient. Without it, reading
``digest.with_user(A).kpi_value`` and then
``digest.with_user(B).kpi_value`` returns A's cached value on the
second read -- because the cache key ignores the user when no
context dependency is declared.
Same root cause for the period KPI: the digest send loop iterates
multiple ``previous_digest``/current ranges via
``with_context(start_datetime=..., end_datetime=...)``, so the
period field must declare those keys too.
Add:
- ``@api.depends_context('uid')`` on the pending / waiting / team-
pending computes.
- ``@api.depends_context('uid', 'start_datetime', 'end_datetime')``
on the period-scoped validated-by-me compute.
This is the same pattern Odoo's own digest module uses on its
per-user metrics.
Caught by CI: ``test_pending_kpi_counts_only_my_reviews``,
``test_waiting_kpi_counts_queued_reviews`` and
``test_validated_period_kpi_respects_digest_window`` all failed
asserting "second reader sees 0" when they got the first reader's
cached value of 1.
Caught in review of the previous commit: I claimed the fix covered the team-pending compute too, but only added the decorator to three of the four. env.company is user-scoped, so two managers in different allowed companies would otherwise see each other's cached count.
Two-part default so end users do not have to revisit the digest preferences after install: - ``default=True`` on ``kpi_tier_validation_pending`` so every digest *created after install* gets the tile turned on automatically. - A ``_post_init_hook`` that writes ``kpi_tier_validation_pending = True`` on every digest that *existed before install* -- so users with a pre-configured digest also start seeing the count on their next periodic email. Only the "pending for you" tile is defaulted: it is the one signal every reviewer wants. The other three (waiting, validated-this- period, team-pending) stay opt-in -- toggle them on if you want them. Tests: - ``test_default_pending_tile_enabled_on_new_digests`` -- the field default applies to freshly-created digests. - ``test_post_init_hook_enables_pending_on_existing_digests`` -- the hook flips a previously-False toggle to True on an existing digest and does not touch the other toggles.
078d592 to
53c1013
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Surface tier-validation counts in the periodic KPI digest email so each user sees, at a glance:
approve_sequenceis enabled and you want to see what is coming).Each tile in the email links to a filtered
tier.reviewlist so the recipient can act on the items in one click.Why a glue module and not in
base_tier_validationAdding
digestas a hard dependency tobase_tier_validationis heavier than needed. OCA's convention is to ship a separate<feature>_digestglue module that auto-installs when both halves are present. This PR follows that convention.Module shape
tier_validation_digest.digestextendsdigest.digestwith fourkpi_*boolean toggles and matchingkpi_*_valueInteger computes._compute_kpis_actionsis overridden to map each KPI to a click-through action.tier.reviewwindow actions are added:action_my_tier_reviews-- domain[('reviewer_ids', 'in', uid)], default-filtered topendingand grouped bymodel. Click-through target for the three per-user KPIs.action_team_pending_tier_reviews-- domain[('status', '=', 'pending')], gated tobase.group_erp_manager. Click-through target for the team KPI.tier.reviewwith status / "Reviewer is me" / "Validated by me" filters and group-by status / model.base.group_erp_managervia thegroupsattribute -- ordinary users do not see the configuration toggle on their digest preferences. The framework already raisesAccessErrorwhen a non-manager attempts to read the value, and the digest send loop catches that and skips the KPI for that user, so no extra defensive plumbing is needed.Tests
test_pending_kpi_counts_only_my_reviews-- the recipient user's pending count reflects exactly their pending reviews; another user sees 0.test_waiting_kpi_counts_queued_reviews-- in anapprove_sequenceflow, the next-in-line reviewer's waiting tier shows up in their queued count.test_validated_period_kpi_respects_digest_window-- approved reviews inside the digest period bracket are counted; outside-bracket approvals are not.test_team_pending_kpi_for_manager-- the manager view counts every pending review across the company; delta-based assertion to avoid coupling to the rest of the suite's state.test_kpis_actions_wired-- the four new KPIs are present in the action-mapping dict.Notes / questions for the reviewer
tier.review, not split per underlying business model.tier.reviewis the single source of truth across every tier-validated model and the digest convention is one number per tile. The matching click-through action groups bymodelby default so the per-model breakdown is one click away.base_tier_validation'stier.reviewACL gives all internal users read access already, so the new actions do not need extra security rules.CC @LoisRForgeFlow