import logging import base64 from odoo.addons.whatsapp.tools.whatsapp_api import WhatsAppApi _logger = logging.getLogger(__name__) # Guarda una referencia al método original original_get_whatsapp_document = WhatsAppApi._get_whatsapp_document def custom_get_whatsapp_document(self, document_id): _logger.info("Ejecutando versión modificada de _get_whatsapp_document") if self.wa_account_id.whatsapp_web_url: _logger.info( "Ejecutando versión modificada de _get_whatsapp_document con whatsapp web" ) try: result = base64.b64decode(document_id) except Exception: # Si falla la decodificación (ej. es un ID y no base64), devolvemos vacío o el ID raw # para evitar crash, aunque el archivo estará corrupto. # TODO: Implementar fetch real a WPPConnect _logger.warning( "No se pudo decodificar base64 en _get_whatsapp_document, retornando vacío" ) result = b"" else: result = original_get_whatsapp_document(self, document_id) # Aquí puedes modificar 'result' si es necesario antes de devolverlo return result # Sobrescribir el método en tiempo de ejecución WhatsAppApi._get_whatsapp_document = custom_get_whatsapp_document # Parche para el método _post_whatsapp_reaction para evitar errores de constraint try: from odoo.addons.whatsapp.models.mail_message import MailMessage # Guardar referencia al método original original_post_whatsapp_reaction = MailMessage._post_whatsapp_reaction def custom_post_whatsapp_reaction(self, reaction_content, partner_id): """Parche para evitar error de constraint cuando partner_id es None""" self.ensure_one() # Si no hay partner_id, no procesar la reacción if not partner_id: _logger.warning( "Reacción de WhatsApp recibida sin partner_id para mensaje %s - ignorando", self.id, ) return # Llamar al método original si hay partner_id return original_post_whatsapp_reaction(self, reaction_content, partner_id) # Aplicar el parche MailMessage._post_whatsapp_reaction = custom_post_whatsapp_reaction _logger.info("Parche aplicado exitosamente para _post_whatsapp_reaction") except ImportError as e: _logger.warning("No se pudo aplicar el parche para _post_whatsapp_reaction: %s", e) # Parche para el método wa_phone_format de phone_validation para evitar AttributeError try: from odoo.addons.whatsapp.tools import phone_validation # Guardar referencia al método original original_wa_phone_format = phone_validation.wa_phone_format def custom_wa_phone_format( record, fname=False, number=False, country=None, force_format="INTERNATIONAL", raise_exception=True, ): """Parche para evitar AttributeError: 'bool' object has no attribute 'italian_leading_zero'""" # Ejecutar lógica original, pero capturando errores try: # Reimplementar la parte final del método original que falla # Primero llamamos al método original, si funciona, perfecto return original_wa_phone_format( record, fname, number, country, force_format, raise_exception ) except AttributeError as e: if "italian_leading_zero" in str(e): _logger.warning( "Capturado AttributeError en wa_phone_format, intentando recuperación segura: %s", e, ) # Intentar replicar la lógica segura aquí si es necesario # Por ahora, simplemente devolvemos el número formateado si es posible obtenerlo # o relanzamos si no podemos manejarlo # Obtener el número base if not number and record and fname: record.ensure_one() number = record[fname] if not number: return False # Si llegamos aquí es porque falló el acceso a atributos de parsed # Devolvemos el número original o intentamos un formateo básico return number raise e # Una mejor aproximación: Monkey Patch directo a la función interna si es posible, # o redefinir completamente la función si el error está dentro de ella y no podemos envolverla fácilmente. # Dado que el error ocurre DENTRO de la función original al acceder a parsed.italian_leading_zero, # necesitamos redefinir la función completa para corregir el acceso al atributo. def safe_wa_phone_format( record, fname=False, number=False, country=None, force_format="INTERNATIONAL", raise_exception=True, ): """Versión segura de wa_phone_format que maneja correctamente los atributos de parsed""" # Importar dependencias necesarias from odoo.addons.phone_validation.tools import phone_validation as pv_tools if not number and record and fname: record.ensure_one() number = record[fname] if not number: return False if not country and record: country = record._phone_get_country().get(record.id) if not country: country = record.env.company.country_id try: formatted = pv_tools.phone_format( number, country.code, country.phone_code, force_format=force_format if force_format != "WHATSAPP" else "E164", raise_exception=True, ) except Exception: if raise_exception: raise formatted = False if formatted and force_format == "WHATSAPP": try: parsed = pv_tools.phone_parse(formatted, country.code) except Exception: if raise_exception: raise return False zeros = "" # USO SEGURO DE ATRIBUTOS (Corrección del bug original) if getattr(parsed, "italian_leading_zero", False): zeros = "0" if getattr(parsed, "number_of_leading_zeros", False): zeros = "0" * parsed.number_of_leading_zeros # Verificación adicional para country_code y national_number country_code = getattr(parsed, "country_code", "") national_number = getattr(parsed, "national_number", "") if not country_code or not national_number: # Si no se pueden obtener estos datos, intentar usar el formatted original o un fallback if formatted: return formatted return number return f"{country_code}" + zeros + f"{national_number}" return formatted # Aplicar el parche reemplazando la función en el módulo phone_validation.wa_phone_format = safe_wa_phone_format _logger.info("Parche aplicado exitosamente para phone_validation.wa_phone_format") except ImportError as e: _logger.warning("No se pudo aplicar el parche para phone_validation: %s", e) except Exception as e: _logger.warning("Error al aplicar parche para phone_validation: %s", e)