# Accounts

- Tipo: Core/Extension Vtiger
- Criticidad: Critica
- Ubicacion: `admin/modules/Accounts/`
- Proposito: Cuentas/organizaciones; entidad central de clientes y base de GeoCuentas.
- Ultima actualizacion: 2026-06-26 14:38:00 CST

## Archivos clave

- `modules/Accounts/Accounts.php`
- `modules/Accounts/models/DetailView.php`
- `modules/Accounts/models/ListView.php`
- `modules/Accounts/models/Module.php`
- `modules/Accounts/models/Record.php`
- `modules/Accounts/models/MassEditRecordStructure.php`
- `modules/Accounts/views/Detail.php`
- `modules/Accounts/views/AccountHierarchy.php`
- `modules/Accounts/actions/TransferOwnership.php`

## Reglas

No modificar este modulo sin revisar `architecture.md`, `database.md`, `security.md`, `performance.md`, `known_issues.md` y `change_log.md`.

## Ver mapa

- Estado: Corregido.
- Health funcional: Operativo con modal interno de Vtiger.
- Flujo actual: `DetailViewHeaderTitle.tpl` construye la direccion con `bill_street`, `bill_city`, `bill_state`, `bill_code`, `bill_country` y entrega URLs codificadas a `Accounts_Detail_Js.showMap()`.
- URL embed: `https://www.google.com/maps?q=<direccion_codificada>&output=embed`.
- Link alternativo: `https://www.google.com/maps/search/?api=1&query=<direccion_codificada>`.
- API Key: No requerida.
- JavaScript: Solo se usa JS local de Accounts para abrir el modal; no se usa Google Maps JavaScript API ni MapAjax.
- Direccion usada: direccion fiscal de Accounts; los campos vacios se ignoran.

## Calcular distancia

- Estado: Implementado en pantalla sin guardar resultado en base de datos.
- UI: `layouts/v7/modules/Accounts/DetailViewHeaderTitle.tpl` agrega el boton `Calcular distancia` junto a `Ver mapa`.
- JavaScript: `layouts/v7/modules/Accounts/resources/Detail.js` abre un modal con selector de origen, destino fiscal y resultado.
- Backend: `modules/Accounts/actions/CalculateDistance.php` valida sesion/permisos de `DetailView`, construye destino con `bill_street`, `bill_city`, `bill_state`, `bill_code`, `bill_country`, llama a Google desde servidor y devuelve JSON.
- Configuracion servidor: `config.accounts_distance.php`. La API Key se lee desde `GRAVIMEX_GOOGLE_MAPS_API_KEY` o desde ese archivo PHP, nunca desde JavaScript/TPL.
- APIs usadas: Google Maps Distance Matrix API por HTTPS server-side y Google Maps Embed API para iframe de referencia.
- Origenes: `mina` y `patio` se leen desde `config.accounts_distance.php`.
- Resultado: origen usado, destino, distancia en km, tiempo estimado, fecha/hora del calculo, boton `Ver ruta en Google Maps` y mapa embebido de la ruta.
- Seguridad: la API Key no se coloca en JavaScript ni templates. Para el iframe de Google Maps Embed API, la key aparece en el `src` generado por backend porque Google lo requiere; debe restringirse por HTTP Referrer `gravimex.com` y solo para Maps Embed API.

## AI Enrichment

- Individual: `AI Buscar datos` en Detail View sugiere datos publicos y guarda solo campos aprobados por el usuario.
- Masivo: accion de lista `AI -> Enriquecer seleccionadas`, visible solo para administradores.
- Backend masivo: `StartAIEnrichmentBatch.php`, `ProcessAIEnrichmentBatch.php`, `CancelAIEnrichmentBatch.php`, `DownloadAIEnrichmentBatchReport.php`.
- UI masiva: `layouts/v7/modules/Accounts/resources/List.js`.
- Cola/progreso: job JSON server-side en `admin/cache/accounts_ai_batch_<job_id>.json`; reporte CSV via action autenticada.
- Control 180 dias: indice server-side `admin/cache/accounts_ai_enrichment_index.json`; evita nueva consulta si la cuenta fue enriquecida recientemente.
- Duplicados: reutiliza sugerencias dentro del mismo lote por clave de empresa basada en nombre, sitio web, ciudad y estado.
- Costo: una llamada AI por empresa no cacheada; estimacion UI de `$0.01 USD` por llamada y limite seleccionable de 10/25/50/100/todas.
- Recomendacion operativa: lotes de 25 cuentas para produccion; 10 para pruebas.

## Mapa de clientes

- Estado: Implementado como vista interna de Accounts.
- Acceso: menu lateral de Accounts, link `Mapa de clientes`.
- Vista: `modules/Accounts/views/ClientMap.php` renderiza `layouts/v7/modules/Accounts/ClientMap.tpl`.
- Datos: `modules/Accounts/actions/ClientMapData.php` devuelve JSON seguro con cuentas visibles para el usuario autenticado.
- Frontend: `layouts/v7/modules/Accounts/resources/ClientMap.js`.
- Mapa: Leaflet + OpenStreetMap, sin Google Maps JavaScript API y sin API Key para visualizacion masiva.
- Coordenadas: usa `account_geo_latitude` y `account_geo_longitude` desde `vtiger_accountscf`.
- Estado actual de datos: 1 cuenta con coordenadas y 137 cuentas sin coordenadas.
- Cuentas sin coordenadas: se muestran en la lista lateral como `Sin coordenadas`; no se geocodifican automaticamente.
- Campo de proceso comercial: no existe un campo dedicado en Accounts. Se usa `accounttype` como clasificacion provisional.
- Clasificacion provisional: `Customer` -> `Vendiendo`, `Partner/Reseller/Integrator/Investor` -> `En proceso`, `Competitor` -> `No interesado`, otros/vacios -> `Por contactar`.
- Pendiente recomendado: crear campo personalizado `Proceso comercial` con valores `Por contactar`, `En proceso`, `Vendiendo`, `No interesado` cuando se autorice escritura en base de datos.

## Geocodificar seleccionadas

- Estado: Implementado como accion masiva en List View de Accounts.
- Acceso: seleccionar cuentas en Accounts y ejecutar `Geocodificar seleccionadas`.
- Backend: `modules/Accounts/actions/GeocodeSelected.php`.
- UI: `layouts/v7/modules/Accounts/resources/List.js`.
- API usada: Google Geocoding API, llamada server-side con la API Key ya configurada en `config.accounts_distance.php`.
- Limite: maximo 25 cuentas por ejecucion.
- Seguridad: valida sesion, CSRF/write access y permiso `EditView`; no expone API Key al navegador.
- Sobrescritura: no reemplaza coordenadas existentes salvo que el usuario marque `Recalcular`.
- Direccion usada: `bill_street`, `bill_city`, `bill_state`, `bill_code`, `bill_country`.
- Guardado: `account_geo_latitude`, `account_geo_longitude`, `account_geo_normalized_address`, `account_geo_last_update`, `account_geo_status` en `vtiger_accountscf`.
- Prueba controlada: `record=2` actualizado con coordenadas y estado `Geolocalizado`.
