Files
public/tier_communications/models/tier_mailbox.py

99 lines
3.5 KiB
Python

import re
from odoo import api, fields, models
class TierMailbox(models.Model):
_name = 'tier.mailbox'
_description = 'Tier Mailbox'
_rec_name = 'name'
name = fields.Char(string='Name', required=True)
code = fields.Char(string='Code', required=True)
description = fields.Text(string='Description')
user_ids = fields.Many2many(
'res.users',
string='Allowed Users',
help='Users who have access to this mailbox. If empty, all users can access it.',
)
is_lead_inbox = fields.Boolean(string='Lead Inbox', default=False)
is_ticket_inbox = fields.Boolean(string='Ticket Inbox', default=False)
_sql_constraints = [
('code_unique', 'UNIQUE(code)', 'The mailbox code must be unique.'),
]
@api.model
def get_accessible_mailboxes(self):
"""Return mailboxes accessible to the current user.
A mailbox is accessible if the current user is in user_ids,
or if user_ids is empty (open to all).
"""
uid = self.env.uid
domain = [
'|',
('user_ids', '=', False),
('user_ids', 'in', [uid]),
]
mailboxes = self.search(domain)
return mailboxes.read(['id', 'name', 'code', 'is_lead_inbox', 'is_ticket_inbox'])
@api.model
def get_mailbox_conversations(self, mailbox_id, limit=50):
"""Return messages in a mailbox grouped by author (partner).
Returns a list of conversations:
[{
'partner_id': int,
'partner_name': str,
'partner_avatar_url': str,
'last_message_preview': str, # first 80 chars of body text
'last_message_date': str,
'channel_code': str|None, # email, matrix, or None
'message_count': int,
}]
"""
mailbox_tags = self.env['tier.mailbox.tag'].search([
('mailbox_id', '=', mailbox_id),
], order='message_id desc', limit=500)
if not mailbox_tags:
return []
message_ids = mailbox_tags.mapped('message_id')
# Group by author — show last message in conversation (ours or theirs)
conversations_by_partner = {}
for message in message_ids.sorted(key=lambda m: m.id, reverse=True):
author = message.author_id
partner_id = author.id if author else 0
if partner_id not in conversations_by_partner:
# Strip HTML for preview
body_text = re.sub(r'<[^>]+>', '', message.body or '')
preview = body_text[:80].strip() if body_text else (message.subject or '')
# If preview is still empty, use subject
if not preview and message.subject:
preview = message.subject[:80]
# Get channel code
channel_code = None
if message.channel_tag_ids:
channel_code = message.channel_tag_ids[0].code
conversations_by_partner[partner_id] = {
'partner_id': partner_id,
'partner_name': author.name if author else (message.email_from or 'Неизвестный'),
'last_message_preview': preview or 'Нет текста',
'last_message_date': str(message.date or message.create_date or ''),
'channel_code': channel_code,
'message_count': 0,
}
conversations_by_partner[partner_id]['message_count'] += 1
result = list(conversations_by_partner.values())[:limit]
return result