# INDEX_deps.md — Facades y Services
> Firmas y propósito de todas las dependencias usadas por `public.php` y `Plugin.php`

---

## src/Facade/

### AbstractMessageNotifierFacade (abstract) — L.1–537
`src/Facade/AbstractMessageNotifierFacade.php`
Base de todas las facades. Maneja lógica de notificación via Callbell/WhatsApp.

**Constantes:**
- `SUBJECT_OF_INSTALLER_CHANGE[]` — textos para notificar cambio/desasignación de técnico
- `ADDITIONAL_CHANGE_DATA[]` — datos adicionales del cambio de técnico

**Constructor:** `(Logger, MessageTextFactory, SmsNumberProvider)` + carga `$ucrmApi` desde config

**Métodos públicos:**
| Método | Descripción |
|---|---|
| `verifyPaymentActionToDo(NotificationData): void` | Itera teléfonos por tipo (whatsapp/whatsnotifica/whatsactualiza) y llama notify/update |
| `verifyClientActionToDo(NotificationData): void` | Solo `onlyUpdate()` para tipos whatsapp/whatsactualiza |
| `verifyServiceActionToDo(NotificationData): void` | `onlyUpdateService()` para tipos whatsapp/whatsactualiza |
| `verifyJobActionToDo($jsonData, $reprog, $changeInstaller): void` | Notifica instalador anterior, cliente y técnico nuevo; gestiona título del job |
| `verifyInvoiceActionToDo(NotificationData): void` | `onlyUpdate()` sin mostrar balance |
| `notify(NotificationData, $phone): void` | Envía notificación de pago vía Callbell (texto o plantilla) |
| `notifyAndUpdate(NotificationData, $phone): void` | Notifica + hace PATCH en Callbell |
| `notifyOverDue(NotificationData): void` | Notifica factura vencida/por vencer |
| `onlyUpdate(NotificationData, $phone): void` | Solo actualiza contacto en Callbell (sin enviar mensaje) |
| `onlyUpdateService(NotificationData, $phone): void` | Actualiza status de servicio en Callbell |

**Métodos protegidos:**
| Método | Descripción |
|---|---|
| `getVaultCredentialsByClientId($clientId): string` | Obtiene pass de antena desde UNMS vault; sincroniza en CRM. Usa `GET /nms/api/v2.1/devices?siteId=` y `GET /nms/api/v2.1/vault/{deviceId}/credentials` |
| `syncPasswordWithCrm(int $clientId, string $pass): void` | PATCH atributo `passwordAntenaCliente` en CRM si difiere |
| `generateStrongPassword(int $length=16): string` | Genera contraseña segura (lower+upper+digits+@#) |
| `patchClientCustomAttribute(int $clientId, int $attributeId, string $value): bool` | PATCH `clients/{id}` con atributo custom |
| `comparePasswords(?string $crm, ?string $vault): string` | Prioriza vault, luego crm, luego mensaje de advertencia |
| `validarNumeroTelefono($n): string` | Normaliza teléfono a formato internacional 521XXXXXXXXXX |

**Abstracto:** `sendWhatsApp(NotificationData, string $phone): void`

---

### PluginNotifierFacade extends AbstractStripeOperationsFacade
`src/Facade/PluginNotifierFacade.php` — L.1–152

**Herencia:** `PluginNotifierFacade → AbstractStripeOperationsFacade → AbstractOxxoOperationsFacade → AbstractMessageNotifierFacade`

**Constructor:** `(Logger, MessageTextFactory, SmsNumberProvider, OptionsManager)` — carga `$pluginData`

**Métodos propios:**
| Método | Descripción |
|---|---|
| `updatePasswordAntenaIfNeeded(int $clientId, array $jsonData): void` | Llama `getVaultCredentialsByClientId()` — sincroniza pass antena |
| `processClientPasswordAntenna(int $clientId, array $clientEntity): void` | Procesa tag "OBTENER PASSWORD ANTENA": incluye `scripts-uisp/audit_client_passwords.php`, llama `fixClientData()`, remueve tag |
| `sendWhatsApp(NotificationData, string $phone): void` | Implementación mock (solo log) |

**Métodos heredados de AbstractStripeOperationsFacade** (ver abajo):
- `createPaymentIntent()`, `registerPaymentFromWebhook()`, `registerPaymentFromIntent()`
- `ensureStripePaymentAttribute()`, `createStripeClient()`, `syncStripeCustomerData()`
- `createClabeForClient()`, `removeTagFromClient()`

---

### AbstractStripeOperationsFacade (abstract)
`src/Facade/AbstractStripeOperationsFacade.php` — ~45KB

Hereda de `AbstractOxxoOperationsFacade`. Maneja toda la integración con Stripe y registro de pagos en UCRM.

**Métodos clave** (firmas aproximadas):
| Método | Descripción |
|---|---|
| `createPaymentIntent(array $jsonData): void` | Crea PaymentIntent en Stripe desde webhook `customer_cash_balance_transaction.funded` |
| `registerPaymentFromWebhook(array $jsonData): void` | Registra pago en UCRM desde webhook `applied_to_payment` |
| `registerPaymentFromIntent(array $piData): void` | Registra pago en UCRM desde `payment_intent.succeeded` |
| `ensureStripePaymentAttribute(NotificationData $n): void` | Determina si el pago Stripe es OXXO, Transferencia o Tarjeta revisando metadata |
| `createStripeClient(NotificationData $n, string $tag, bool $createClabe): void` | Crea cliente en Stripe + opcionalmente genera CLABE |
| `syncStripeCustomerData(int $clientId, string $name, ?string $email): void` | Actualiza nombre/email del customer en Stripe |
| `removeTagFromClient(int $clientId, string $tagName): void` | Elimina tag del cliente en UCRM |

---

### AbstractOxxoOperationsFacade (abstract)
`src/Facade/AbstractOxxoOperationsFacade.php` — ~31KB

Maneja la integración OXXO Pay con Stripe y generación de vouchers.

**Métodos clave:**
| Método | Descripción |
|---|---|
| `createStripeReference(array $jsonData, ?float $amount): array` | Crea PaymentIntent OXXO en Stripe. Retorna `{hasError, data:{oxxo_reference, url, clientID, clientFullName, amount}}` |
| `createOxxoOrder(array $oxxoData): array` | Guarda orden OXXO en storage local. Retorna `{order_id, oxxo_reference, url, ...}` |
| `generateOxxoVoucher(array $responseOxxo, bool $background): void` | Llama a Puppeteer para generar imagen del voucher y subirla a MinIO |
| `getOxxoOrderStatus(string $orderId): array` | Retorna estado actual de la orden OXXO |
| `createOxxoPaymentIntent(array $clientData, float $amount, bool $notify): array` | Flujo completo: crea PI Stripe OXXO + orden + voucher |

---

### PluginOxxoNotifierFacade extends AbstractOxxoOperationsFacade
`src/Facade/PluginOxxoNotifierFacade.php` — pequeño

Solo implementa los métodos abstractos. No agrega lógica propia relevante.

---

### TwilioNotifierFacade extends AbstractMessageNotifierFacade
`src/Facade/TwilioNotifierFacade.php` — ~2KB

Implementa `sendWhatsApp()` usando Twilio (legacy, en desuso). Métodos notificación estándar delegados a la clase base.

---

### ClientCallBellAPI
`src/Facade/ClientCallBellAPI.php` — ~81KB

Cliente completo de la API de Callbell. Usado internamente por las facades vía `new ClientCallBellAPI($apitoken, $ipserver, $tokencallbell)`.

**Métodos clave relevantes para el plugin:**
| Método | Descripción |
|---|---|
| `sendPaymentNotificationWhatsApp($phone, NotificationData): bool` | Envía plantilla de pago con template de Callbell |
| `sendTextPaymentNotificationWhatsApp($phone, NotificationData): bool` | Envía texto plano de pago |
| `sendOverdueNotificationWhatsApp($phone, NotificationData): bool` | Notificación de factura vencida |
| `sendJobNotificationWhatsAppToClient($phone, array $data, $reprog, $changeInst): bool` | Notificación de job al cliente |
| `sendJobNotificationWhatsAppToInstaller($phone, array $data, $reprog, $changeInst): void` | Notificación de job al técnico |
| `getContactWhatsapp($phone): string` | GET contacto en Callbell por teléfono → JSON |
| `patchWhatsapp(array $contact, NotificationData): void` | PATCH datos del contacto en Callbell |
| `patchServiceStatusWhatsApp(array $contact, NotificationData): void` | PATCH status de servicio en Callbell |

---

## src/Service/

### PaymentIntentService
`src/Service/PaymentIntentService.php` — 282 líneas

Usado directamente en `public.php` (no via DI). Constructor: `($ucrmApi, $stripeApiKey, $logger=null)`

| Método | Descripción |
|---|---|
| `searchClients($query): array` | UCRM `GET clients?query=q&limit=5` — retorna array simplificado |
| `getClientDetails($clientId): array` | UCRM `GET clients/{id}` — retorna datos + stripeCustomerId + clabeInterbancaria |
| `createPaymentIntent($clientId, $amount, $stripeCustomerId, $adminId): array` | Crea PI Stripe tipo `customer_balance/bank_transfer/mx_bank_transfer` |
| `getLastPayments($stripeCustomerId, $limit=10): array` | Stripe `paymentIntents.all` filtrado a bank_transfer — últimos N |
| `getLastOxxoPayments($stripeCustomerId, $limit=5): array` | Stripe `paymentIntents.all` filtrado a OXXO — últimos N |
| `getCustomerCashBalance($stripeCustomerId): float` | Stripe `customers.retrieveCashBalance` → MXN |

---

### SmsNumberProvider
`src/Service/SmsNumberProvider.php` — 160 líneas

| Método | Descripción |
|---|---|
| `getUcrmClientNumber(NotificationData): ?string` | Primer contacto con tipo aplicable al evento |
| `getUcrmClientNumbers(NotificationData?, array?): array` | Retorna `['whatsapp'=>[phones], 'whatsnotifica'=>[phones], 'whatsactualiza'=>[phones]]` |
| `getAllUcrmClientNumbers(array): array` | Todos los teléfonos del cliente sin filtrar por tipo |

**Tipos de contacto reconocidos:**
- `whatsapp` — recibe notificación + actualización en Callbell
- `whatsnotifica` — solo recibe notificación (no actualiza Callbell)
- `whatsactualiza` — solo actualiza Callbell (no notifica)

---

### Logger (`src/Service/Logger.php`)
Wrapper de PSR-3. Métodos: `debug()`, `info()`, `warning()`, `error()`. Nivel controlado por config `logging_level` / `debugMode`.

### OptionsManager (`src/Service/OptionsManager.php`)
Carga config del plugin. Método: `load(): PluginData`

### PluginDataValidator (`src/Service/PluginDataValidator.php`)
Valida que la configuración esté completa. Método: `validate(): bool`

### MinioStorageService (`src/Service/MinioStorageService.php`)
Sube vouchers OXXO a MinIO. Usado por `AbstractOxxoOperationsFacade`.

### CurlExecutor (`src/Service/CurlExecutor.php`)
Wrapper de cURL para la `UcrmApi` interna del plugin.

---

## src/Data/

### PluginData (extends UcrmData)
`src/Data/PluginData.php` — Propiedades de configuración del plugin:

| Propiedad | Tipo | Descripción |
|---|---|---|
| `$ipserver` | string | IP/hostname del servidor UISP |
| `$apitoken` | string | Token API UCRM |
| `$unmsApiToken` | string | Token API UNMS/NMS |
| `$tokencallbell` | string | Token API Callbell |
| `$tokenstripe` | string | API Key Stripe |
| `$ipPuppeteer` | string | IP del microservicio Puppeteer |
| `$portPuppeteer` | string | Puerto del microservicio Puppeteer |
| `$idPaymentAdminCRM` | string | ID admin para registrar pagos |
| `$cashPaymentMethodId` | bool | Habilitar notif. efectivo |
| `$courtesyPaymentMethodId` | bool | Habilitar notif. cortesía |
| `$bankTransferPaymentMethodId` | bool | Habilitar notif. transferencia |
| `$oxxoPayPaymentMethodId` | bool | Habilitar notif. OXXO |
| `$creditCardStripePaymentMethodId` | bool | Habilitar notif. tarjeta Stripe |
| `$stripeSubscriptionCreditCardPaymentMethodId` | bool | Habilitar notif. suscripción Stripe |
| `$notificationTypeText` | bool | true=texto plano, false=plantilla Callbell |
| `$installersDataWhatsApp` | string | JSON de instaladores |
| `$debugMode` | bool | Activa logging DEBUG |
| `$logging_level` | bool | Nivel verbose de log |
| `$twilioAccountSid` | string\|null | Legacy Twilio |
| `$twilioAuthToken` | string\|null | Legacy Twilio |
| `$twilioSmsNumber` | string\|null | Legacy Twilio |

### NotificationData
`src/Data/NotificationData.php`
DTO con propiedades: `$uuid`, `$changeType`, `$entity`, `$entityId`, `$eventName`, `$clientId`, `$clientData[]`, `$paymentData[]`, `$invoiceData[]`

---

## src/Factory/

### NotificationDataFactory
`src/Factory/NotificationDataFactory.php` — 5.8KB
| Método | Descripción |
|---|---|
| `getObject(array $jsonData): NotificationData` | Construye `NotificationData` desde el payload del webhook UCRM, cargando datos adicionales de la API |

### MessageTextFactory
`src/Factory/MessageTextFactory.php` — 3.7KB
Genera textos de mensajes WhatsApp. Usado por las facades para construir el contenido de notificaciones.
