99 lines
3.5 KiB
Python
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
|