Skip to content

[19.0][ADD] tier_validation_digest#25

Open
bosd wants to merge 6 commits into
OCA:19.0from
bosd:19.0-add-tier_validation_digest
Open

[19.0][ADD] tier_validation_digest#25
bosd wants to merge 6 commits into
OCA:19.0from
bosd:19.0-add-tier_validation_digest

Conversation

@bosd
Copy link
Copy Markdown
Contributor

@bosd bosd commented May 12, 2026

What

Surface tier-validation counts in the periodic KPI digest email so each user 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 and you want to see what is coming).
  • How many reviews they validated during the digest period -- a satisfying "I cleared X reviews this week" signal, tied to whatever periodicity the user picked.
  • Manager view only: how many reviews are pending across the entire company.

Each tile in the email links to a filtered tier.review list so the recipient can act on the items in one click.

Why a glue module and not in base_tier_validation

Adding digest as a hard dependency to base_tier_validation is heavier than needed. OCA's convention is to ship a separate <feature>_digest glue module that auto-installs when both halves are present. This PR follows that convention.

Module shape

  • tier_validation_digest.digest extends digest.digest with four kpi_* boolean toggles and matching kpi_*_value Integer computes.
  • _compute_kpis_actions is overridden to map each KPI to a click-through action.
  • Two tier.review window actions are added:
    • action_my_tier_reviews -- domain [('reviewer_ids', 'in', uid)], default-filtered to pending and grouped by model. Click-through target for the three per-user KPIs.
    • action_team_pending_tier_reviews -- domain [('status', '=', 'pending')], gated to base.group_erp_manager. Click-through target for the team KPI.
  • A reusable search view on tier.review with status / "Reviewer is me" / "Validated by me" filters and group-by status / model.
  • The team-wide KPI's toggle and value field are both gated to base.group_erp_manager via the groups attribute -- ordinary users do not see the configuration toggle on their 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, 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 an approve_sequence flow, 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

  • The four KPIs are single counts over tier.review, not split per underlying business model. tier.review is 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 by model by default so the per-model breakdown is one click away.
  • base_tier_validation's tier.review ACL gives all internal users read access already, so the new actions do not need extra security rules.

CC @LoisRForgeFlow

@OCA-git-bot OCA-git-bot added series:19.0 mod:tier_validation_digest Module tier_validation_digest labels May 12, 2026
@bosd bosd changed the title [ADD] tier_validation_digest [19.0][ADD] tier_validation_digest May 12, 2026
bosd 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.
@bosd bosd force-pushed the 19.0-add-tier_validation_digest branch from 078d592 to 53c1013 Compare May 13, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:tier_validation_digest Module tier_validation_digest series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants