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