Sfoglia il codice sorgente

feat: agregar extensión de whatsapp_web con campos Many2one a ww.group

- Agregado modelo whatsapp_message.py que extiende whatsapp.message
- Agregado campo whatsapp_group_id Many2one a whatsapp.message
- Agregado modelo whatsapp_composer.py que extiende whatsapp.composer
- Agregado campo whatsapp_group_id Many2one a whatsapp.composer
- Agregadas vistas XML para extender vistas de whatsapp_web
- Funcionalidad completa de grupos ahora en whatsapp_web_groups
root 2 mesi fa
parent
commit
3ebe73cd3c

+ 1 - 0
.gitignore

@@ -50,3 +50,4 @@ htmlcov/
 *.bak
 *.orig
 
+

+ 2 - 0
__manifest__.py

@@ -21,6 +21,8 @@
         'views/ww_role_views.xml',
         'views/ww_group_contact_rel_views.xml',
         'views/marketing_activity_views.xml',
+        'views/whatsapp_message_views.xml',
+        'views/whatsapp_composer_views.xml',
         'data/ir_cron.xml',
     ],
     'installable': True,

+ 3 - 1
models/__init__.py

@@ -2,4 +2,6 @@ from . import ww_contact
 from . import ww_group
 from . import ww_role
 from . import ww_group_contact_rel
-from . import marketing_activity 
+from . import marketing_activity
+from . import whatsapp_message
+from . import whatsapp_composer 

+ 115 - 0
models/whatsapp_composer.py

@@ -0,0 +1,115 @@
+from odoo import models, fields, api
+from odoo.exceptions import ValidationError
+import logging
+
+_logger = logging.getLogger(__name__)
+
+class WhatsAppComposer(models.TransientModel):
+    _inherit = 'whatsapp.composer'
+
+    # Campo Many2one para grupos - solo disponible cuando whatsapp_web_groups está instalado
+    whatsapp_group_id = fields.Many2one('ww.group', string='WhatsApp Group', 
+                                        help="Select WhatsApp group to send message to",
+                                        ondelete='set null')
+
+    @api.onchange('whatsapp_group_id')
+    def _onchange_whatsapp_group_id(self):
+        """Actualizar campos cuando se selecciona un grupo"""
+        if self.whatsapp_group_id:
+            self.whatsapp_group_id_char = self.whatsapp_group_id.whatsapp_web_id
+            self.recipient_type = 'group'
+            self.phone = False
+
+    @api.onchange('recipient_type')
+    def _onchange_recipient_type(self):
+        """Limpiar campos al cambiar tipo de destinatario"""
+        super()._onchange_recipient_type()
+        if self.recipient_type != 'group':
+            self.whatsapp_group_id = False
+
+    @api.constrains('recipient_type', 'phone', 'whatsapp_group_id', 'whatsapp_group_id_char', 'wa_template_id', 'body')
+    def _check_recipient_configuration(self):
+        """Extender validación para incluir whatsapp_group_id"""
+        super()._check_recipient_configuration()
+        
+        for record in self:
+            if record.recipient_type == 'group':
+                if not record.whatsapp_group_id and not record.whatsapp_group_id_char:
+                    raise ValidationError("Please select a WhatsApp group or enter a Group ID when sending to groups")
+
+    def _send_whatsapp_web_message(self):
+        """Extender método para usar whatsapp_group_id si está disponible"""
+        records = self._get_active_records()
+        
+        for record in records:
+            # Determinar destinatario - priorizar whatsapp_group_id sobre whatsapp_group_id_char
+            if self.recipient_type == 'group':
+                if self.whatsapp_group_id:
+                    mobile_number = self.whatsapp_group_id.whatsapp_web_id
+                elif self.whatsapp_group_id_char:
+                    mobile_number = self.whatsapp_group_id_char
+                else:
+                    raise ValidationError("Please specify a group")
+            else:
+                mobile_number = self.phone
+                if not mobile_number:
+                    raise ValidationError("Please provide a phone number")
+            
+            # Crear mail.message con adjuntos si existen
+            post_values = {
+                'attachment_ids': [self.attachment_id.id] if self.attachment_id else [],
+                'body': self.body,
+                'message_type': 'whatsapp_message',
+                'partner_ids': hasattr(record, '_mail_get_partners') and record._mail_get_partners()[record.id].ids or record._whatsapp_get_responsible().partner_id.ids,
+            }
+            
+            if hasattr(records, '_message_log'):
+                message = record._message_log(**post_values)
+            else:
+                message = self.env['mail.message'].create(
+                    dict(post_values, res_id=record.id, model=self.res_model,
+                         subtype_id=self.env['ir.model.data']._xmlid_to_res_id("mail.mt_note"))
+                )
+            
+            # Crear mensaje WhatsApp
+            message_vals = {
+                'mail_message_id': message.id,
+                'mobile_number': mobile_number,
+                'mobile_number_formatted': mobile_number,
+                'recipient_type': self.recipient_type,
+                'wa_template_id': False,
+                'wa_account_id': self._get_whatsapp_web_account().id,
+                'state': 'outgoing',
+            }
+            
+            # Agregar whatsapp_group_id si está disponible
+            if self.whatsapp_group_id:
+                message_vals['whatsapp_group_id'] = self.whatsapp_group_id.id
+            
+            whatsapp_message = self.env['whatsapp.message'].create(message_vals)
+            
+            # Enviar mensaje
+            whatsapp_message._send_message()
+        
+        return {'type': 'ir.actions.act_window_close'}
+
+    def _prepare_whatsapp_message_values(self, record):
+        """Extender método para agregar información de grupo"""
+        values = super()._prepare_whatsapp_message_values(record)
+        
+        # Agregar información de grupo si está disponible
+        if (hasattr(self, 'recipient_type') and self.recipient_type == 'group'):
+            if self.whatsapp_group_id:
+                values.update({
+                    'whatsapp_group_id': self.whatsapp_group_id.id,
+                    'mobile_number': self.whatsapp_group_id.whatsapp_web_id,
+                    'mobile_number_formatted': self.whatsapp_group_id.whatsapp_web_id,
+                })
+            elif self.whatsapp_group_id_char:
+                values.update({
+                    'mobile_number': self.whatsapp_group_id_char,
+                    'mobile_number_formatted': self.whatsapp_group_id_char,
+                })
+        
+        return values
+

+ 64 - 0
models/whatsapp_message.py

@@ -0,0 +1,64 @@
+from odoo import models, fields, api
+from odoo.exceptions import ValidationError
+import logging
+
+_logger = logging.getLogger(__name__)
+
+class WhatsAppMessage(models.Model):
+    _inherit = 'whatsapp.message'
+
+    # Campo Many2one para grupos - solo disponible cuando whatsapp_web_groups está instalado
+    whatsapp_group_id = fields.Many2one('ww.group', string='WhatsApp Group', 
+                                        help="WhatsApp group to send message to (if recipient_type is group)",
+                                        ondelete='set null')
+
+    @api.depends('recipient_type', 'mobile_number', 'whatsapp_group_id')
+    def _compute_final_recipient(self):
+        """Compute the final recipient based on type - extiende la lógica base"""
+        # Primero ejecutar la lógica base de whatsapp_web
+        super()._compute_final_recipient()
+        
+        # Si hay grupo seleccionado, usar su ID (sobrescribe la lógica base)
+        for record in self:
+            if record.recipient_type == 'group' and record.whatsapp_group_id:
+                record.final_recipient = record.whatsapp_group_id.whatsapp_web_id
+
+    @api.onchange('whatsapp_group_id')
+    def _onchange_whatsapp_group_id(self):
+        """Actualizar mobile_number cuando se selecciona un grupo"""
+        if self.whatsapp_group_id:
+            self.mobile_number = self.whatsapp_group_id.whatsapp_web_id
+            self.recipient_type = 'group'
+
+    @api.constrains('recipient_type', 'mobile_number', 'whatsapp_group_id')
+    def _check_recipient_configuration(self):
+        """Extender validación para incluir whatsapp_group_id"""
+        super()._check_recipient_configuration()
+        
+        for record in self:
+            if record.recipient_type == 'group':
+                if not record.whatsapp_group_id and not (record.mobile_number and record.mobile_number.endswith('@g.us')):
+                    raise ValidationError("Para mensajes a grupos, debe seleccionar un grupo o proporcionar un ID de grupo válido (@g.us)")
+
+    def _get_final_destination(self):
+        """Método mejorado para obtener destino final - extiende la lógica base"""
+        self.ensure_one()
+        
+        # Si hay grupo seleccionado, usar su ID
+        if self.recipient_type == 'group' and self.whatsapp_group_id:
+            return self.whatsapp_group_id.whatsapp_web_id
+        
+        # De lo contrario, usar la lógica base (incluye verificación de mobile_number @g.us)
+        result = super()._get_final_destination()
+        if result:
+            return result
+        
+        # Fallback adicional si no hay resultado
+        return False
+
+    def _send_message(self, with_commit=False):
+        """Extender método _send_message para manejar whatsapp_group_id"""
+        # El método _get_final_destination ya maneja whatsapp_group_id,
+        # así que la lógica base funcionará correctamente
+        return super()._send_message(with_commit)
+

+ 22 - 0
views/whatsapp_composer_views.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+    <data>
+        <!-- Extender vista de formulario del composer de WhatsApp para agregar campo Many2one -->
+        <record id="whatsapp_composer_view_form_groups_m2o" model="ir.ui.view">
+            <field name="name">whatsapp.composer.view.form.groups.m2o</field>
+            <field name="model">whatsapp.composer</field>
+            <field name="inherit_id" ref="whatsapp_web.whatsapp_composer_view_form_groups"/>
+            <field name="arch" type="xml">
+                <!-- Agregar campo Many2one whatsapp_group_id antes de whatsapp_group_id_char -->
+                <xpath expr="//field[@name='whatsapp_group_id_char']" position="before">
+                    <field name="whatsapp_group_id" 
+                           invisible="recipient_type != 'group'"
+                           string="WhatsApp Group"
+                           placeholder="Select a WhatsApp group..."
+                           options="{'no_create': True}"/>
+                </xpath>
+            </field>
+        </record>
+    </data>
+</odoo>
+

+ 34 - 0
views/whatsapp_message_views.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+    <data>
+        <!-- Extender vista de formulario de WhatsApp Message para agregar campo Many2one -->
+        <record id="whatsapp_message_view_form_groups_m2o" model="ir.ui.view">
+            <field name="name">whatsapp.message.view.form.groups.m2o</field>
+            <field name="model">whatsapp.message</field>
+            <field name="inherit_id" ref="whatsapp_web.whatsapp_message_view_form_groups"/>
+            <field name="arch" type="xml">
+                <!-- Agregar campo Many2one whatsapp_group_id después de recipient_type -->
+                <xpath expr="//field[@name='recipient_type']" position="after">
+                    <field name="whatsapp_group_id" 
+                           invisible="recipient_type != 'group'"
+                           required="recipient_type == 'group'"
+                           options="{'no_create': True}"/>
+                </xpath>
+            </field>
+        </record>
+
+        <!-- Extender vista de lista de WhatsApp Message -->
+        <record id="whatsapp_message_view_tree_groups_m2o" model="ir.ui.view">
+            <field name="name">whatsapp.message.view.tree.groups.m2o</field>
+            <field name="model">whatsapp.message</field>
+            <field name="inherit_id" ref="whatsapp_web.whatsapp_message_view_tree_groups"/>
+            <field name="arch" type="xml">
+                <!-- Agregar columna whatsapp_group_id -->
+                <xpath expr="//field[@name='recipient_type']" position="after">
+                    <field name="whatsapp_group_id" optional="hide"/>
+                </xpath>
+            </field>
+        </record>
+    </data>
+</odoo>
+