Phase 1-2: build_ticket_vals/scope/unread helpers (utils.py), fusion.helpdesk.ticket.seen read-tracking model, group_reporter_admin. 10 unit tests pass on local Community. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1
|
|
"""Per-user read-tracking for the embedded ticket inbox.
|
|
|
|
Stores ONLY metadata — which central ticket a user has seen and up to
|
|
which message id. No ticket content is replicated locally; this exists
|
|
purely so the systray unread badge can work without re-fetching the
|
|
whole inbox on every page load. Tickets themselves remain a live RPC
|
|
view of the central Odoo.
|
|
"""
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class FusionHelpdeskTicketSeen(models.Model):
|
|
_name = 'fusion.helpdesk.ticket.seen'
|
|
_description = 'Fusion Helpdesk — per-user read tracking (metadata only)'
|
|
|
|
user_id = fields.Many2one(
|
|
'res.users', required=True, index=True, ondelete='cascade',
|
|
default=lambda self: self.env.uid,
|
|
)
|
|
central_ticket_id = fields.Integer(
|
|
string='Central Ticket ID', required=True, index=True,
|
|
help='helpdesk.ticket id on the central Odoo.',
|
|
)
|
|
last_seen_message_id = fields.Integer(
|
|
string='Last Seen Message ID', default=0,
|
|
help='Highest central mail.message id this user has viewed for '
|
|
'the ticket. Drives the unread badge.',
|
|
)
|
|
|
|
_user_ticket_uniq = models.Constraint(
|
|
'UNIQUE(user_id, central_ticket_id)',
|
|
'One seen-row per user per ticket.',
|
|
)
|
|
|
|
@api.model
|
|
def _mark_seen(self, central_ticket_id, last_message_id):
|
|
"""Upsert the current user's last-seen marker for a ticket.
|
|
|
|
Monotonic — never moves the marker backwards (a stale client
|
|
reporting an older id can't resurrect an unread badge)."""
|
|
rec = self.search([
|
|
('user_id', '=', self.env.uid),
|
|
('central_ticket_id', '=', central_ticket_id),
|
|
], limit=1)
|
|
if rec:
|
|
if (last_message_id or 0) > rec.last_seen_message_id:
|
|
rec.last_seen_message_id = last_message_id
|
|
else:
|
|
self.create({
|
|
'central_ticket_id': central_ticket_id,
|
|
'last_seen_message_id': last_message_id or 0,
|
|
})
|
|
return True
|
|
|
|
@api.model
|
|
def _seen_map(self, central_ticket_ids):
|
|
"""Return {central_ticket_id: last_seen_message_id} for the
|
|
current user across the given ticket ids."""
|
|
rows = self.search([
|
|
('user_id', '=', self.env.uid),
|
|
('central_ticket_id', 'in', list(central_ticket_ids)),
|
|
])
|
|
return {r.central_ticket_id: r.last_seen_message_id for r in rows}
|