| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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")
- result = base64.b64decode(document_id)
- 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)
|