diff --git a/base_tier_validation/models/tier_validation.py b/base_tier_validation/models/tier_validation.py index 29896f80..65158aa1 100644 --- a/base_tier_validation/models/tier_validation.py +++ b/base_tier_validation/models/tier_validation.py @@ -853,7 +853,18 @@ def restart_validation(self): def _update_counter(self, review_counter): self.review_ids._update_review_status() channel = "base.tier.validation/updated" - self.env.user.partner_id._bus_send(channel, review_counter) + # Notify the reviewers whose pending count actually changes, not the + # acting user. Sending the delta to ``self.env.user`` made unrelated + # users' systray counters drift (even negative) whenever someone acted + # on a tier-validated record without being one of its reviewers. When + # the reviews are already gone (deletions), fall back to the acting + # user. The client recomputes the absolute count on receipt, so the + # exact audience only affects how promptly a reviewer sees the update. + partners = self.review_ids.mapped("reviewer_ids.partner_id") + if not partners: + partners = self.env.user.partner_id + for partner in partners: + partner._bus_send(channel, review_counter) def unlink(self): self.mapped("review_ids").unlink() diff --git a/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.esm.js b/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.esm.js index 553796b8..1c7de6d0 100644 --- a/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.esm.js +++ b/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.esm.js @@ -16,8 +16,18 @@ export class TierReviewMenu extends Component { this.orm = useService("orm"); this.store = useState(useService("mail.store")); this.action = useService("action"); + this.busService = useService("bus_service"); this.dropdown = useDropdownState(); this.fetchSystrayReviewer(); + // Keep the badge live and correct: re-fetch the authoritative count + // whenever a tier review changes server-side, instead of nudging a + // running +/- delta. The absolute value is a len() and so can never go + // negative, which a delta could when an update reaches a user for whom + // the review was never part of their pending count. + this.busService.subscribe("base.tier.validation/updated", () => + this.fetchSystrayReviewer() + ); + this.busService.start(); } async fetchSystrayReviewer() { diff --git a/base_tier_validation/static/src/js/services/tier_review_service.esm.js b/base_tier_validation/static/src/js/services/tier_review_service.esm.js deleted file mode 100644 index bde257be..00000000 --- a/base_tier_validation/static/src/js/services/tier_review_service.esm.js +++ /dev/null @@ -1,33 +0,0 @@ -import {reactive} from "@odoo/owl"; -import {registry} from "@web/core/registry"; - -export class TierReviewService { - constructor(env, services) { - this.env = env; - this.store = services["mail.store"]; - this.busService = services.bus_service; - } - setup() { - this.busService.subscribe("base.tier.validation/updated", (payload) => { - if (payload.review_created) { - this.store.tierReviewCounter++; - } - if (payload.review_deleted) { - this.store.tierReviewCounter--; - } - }); - this.busService.start(); - } -} - -export const tierReviewService = { - dependencies: ["bus_service", "mail.store"], - - start(env, services) { - const tier_review_service = reactive(new TierReviewService(env, services)); - tier_review_service.setup(); - return tier_review_service; - }, -}; - -registry.category("services").add("tierReviewService", tierReviewService);