# ANÁLISIS Y PLAN DE ADAPTACIÓN: GEOCERCA CONTROL

## 📋 RESUMEN EJECUTIVO

**Vista Original:** `sistemagps/procesos/dib_poli2.php`  
**Vista Nueva:** `gpsphonnex/src/operaciones/geocerca-control.php`  
**Tipo de Mapa:** Google Maps API  
**Propósito:** Crear, editar, visualizar y gestionar geocercas de control (polígonos) para vehículos

---

## 🔍 ANÁLISIS DETALLADO DE LA VISTA ORIGINAL

### 1. ESTRUCTURA Y DISTRIBUCIÓN

#### Layout HTML
- **Tabla principal** con dos columnas:
  - **Columna izquierda:** Formulario de controles (Empresa, Flota, Vehículo, Dirección, Radio, Botones)
  - **Columna derecha:** Mapa de Google Maps (800x650px)
- **Tabla scrollable** (`tablescroll`) debajo del formulario para mostrar geocercas existentes
- **Formulario** con campos:
  - Selector de Empresa (solo admin/distribuidor)
  - Selector de Flota (dependiente de empresa)
  - Selector de Vehículo (dependiente de flota)
  - Campo de Dirección con botón "Buscar"
  - Radio buttons: "Personalizado" / "Automático"
  - Campo numérico "Radio" (en metros, se divide entre 1000)
  - Botones: "Borrar" y "Grabar"

#### Permisos por Tipo de Usuario
- **Admin (us_tipo='1'):** Ve empresa y flota
- **Distribuidor (us_tipo='2'):** Ve empresas de su distribuidor
- **Usuario Normal (us_tipo='0'):** Solo ve flotas asignadas (usuario_flota)

### 2. FUNCIONALIDADES DEL MAPA

#### Modos de Dibujo
1. **Modo Personalizado (`GetLocation2`):**
   - Geocodifica dirección
   - Inicializa mapa en coordenadas encontradas
   - Permite dibujar polígono haciendo clic en el mapa
   - Cada clic agrega un punto al polígono

2. **Modo Automático (`GetLocation` + `carga_poli`):**
   - Geocodifica dirección
   - Crea polígono circular automático basado en radio
   - Genera 4 puntos formando un cuadrado alrededor del centro
   - Marcador arrastrable que recalcula polígono al mover

#### Funciones de Inicialización
- `initialize()`: Mapa por defecto (Lima: -12.1277, -77.01818, zoom 13)
- `initialize2()`: Si viene `ti_vehiculo` en GET, carga geocercas del vehículo
- `initialize3(lat, lng)`: Inicializa en coordenadas específicas (zoom 16)

#### Gestión de Polígonos
- **Array global `miArray`:** Almacena puntos del polígono
- **Función `addLatLng(event)`:** Agrega punto al hacer clic
- **Función `borrar()`:** Limpia mapa y arrays
- **Función `removeOverlays()`:** Elimina marcadores y polígonos del mapa

### 3. APIS Y ENDPOINTS

#### APIs Utilizadas (Archivos PHP)

1. **`phpsqlajax_genxml11.php`**
   - **Propósito:** Obtener flotas y vehículos en formato XML
   - **Parámetros:**
     - `ti_empresa`: ID de empresa (para obtener flotas)
     - `ti_flota`: ID de flota (para obtener vehículos)
     - `id_identi_user`: ID de usuario (para filtrar vehículos)
     - `us_tipo`: Tipo de usuario (para permisos)
   - **Respuesta:** XML con `<markers>` conteniendo `<marker>` con atributos
   - **Uso:** Llenar dropdowns de flota y vehículo

2. **`muestra_geocercas2.php`**
   - **Propósito:** Mostrar tabla HTML con geocercas existentes
   - **Parámetros:**
     - `ti_vehiculo`: Placa del vehículo
   - **Respuesta:** HTML de tabla con:
     - Nombre de geocerca (editable)
     - Checkboxes: In, Out, Email, Monitor, Taller, General (id_emp), Estado
     - Botones: Ver (lupa), Borrar, Grabar
   - **Lógica:**
     - Busca geocercas donde `tipo_cerca=1` y (`id_vehi` o `id_emp`)
     - Agrupa por `id_cerca_total`
     - Muestra opciones desde tabla `opciones_geocerca`

3. **`grabar_geocercas2.php`**
   - **Propósito:** Guardar nueva geocerca
   - **Parámetros:**
     - `id_vehi`: Placa del vehículo (se busca `id_vehi` real)
     - `array`: Array de puntos en formato `(lat,lng)(lat,lng)...`
   - **Lógica:**
     - Obtiene `max(id_cerca_total) + 1` para nuevo ID
     - Parsea array de puntos: `explode('(', $array)`
     - Inserta cada punto en tabla `geocerca` con:
       - `co_coordx`, `co_coordy`
       - `id_vehi`, `id_cerca_total`
       - `tipo_cerca=1` (control)
       - `estado=1` (activo)
       - `id_emp` del vehículo
     - Inserta registro en `opciones_geocerca` con `estado_control='out'`
     - Inserta en `sms_block` con `id_alarma=1`
     - Devuelve HTML de tabla actualizada

4. **`phpsqlajax_genxml8.php`**
   - **Propósito:** Obtener puntos de una geocerca específica
   - **Parámetros:**
     - `ti_vehiculo`: Placa del vehículo
     - `max`: `id_cerca_total`
   - **Respuesta:** XML con puntos `(lat, lng)`
   - **Uso:** Función `muestrageocerca()` para visualizar geocerca en mapa

5. **`borrar_puntos2.php`**
   - **Propósito:** Eliminar geocerca
   - **Parámetros:**
     - `max`: `id_cerca_total`
     - `id_vehi`: Placa del vehículo
   - **Lógica:**
     - DELETE de `geocerca` donde `id_cerca_total`
     - DELETE de `opciones_geocerca` donde `id_cerca_total`
     - UPDATE `vehiculo` set `geocerca='out'`, `id_cerca_total='0'`, `tipo_geo_ciudad=''`
     - Devuelve HTML de tabla actualizada

6. **`actualizar_geocercas.php`**
   - **Propósito:** Actualizar opciones de geocerca
   - **Método:** POST
   - **Parámetros GET:**
     - `max`: `id_cerca_total`
     - `var1`: Índice del array de formulario
   - **Parámetros POST:**
     - `nombre_geocerca[$var1]`
     - `int[$var1]` (entrada)
     - `out[$var1]` (salida)
     - `email[$var1]`
     - `monitor[$var1]`
     - `taller[$var1]`
     - `id_emp[$var1]` (general)
     - `estado[$var1]`
   - **Lógica:**
     - Si `id_emp[$var1]=='1'`, obtiene `id_emp` del vehículo, sino `id_emp=0`
     - UPDATE `geocerca` set `nombre_geocerca`, `estado`, `id_emp`
     - UPDATE `opciones_geocerca` set todas las opciones
     - Redirige a `dib_poli2.php?ti_vehiculo=$placa`

### 4. ESTRUCTURA DE BASE DE DATOS

#### Tabla `geocerca`
- `id_cerca`: Auto-increment
- `id_cerca_total`: ID agrupador de la geocerca
- `co_coordx`: Latitud
- `co_coordy`: Longitud
- `id_vehi`: ID del vehículo
- `tipo_cerca`: 1 = Control, 0 = Otro
- `estado`: 1 = Activo, 0 = Inactivo
- `id_emp`: ID de empresa (0 = específica del vehículo, >0 = general de empresa)
- `nombre_geocerca`: Nombre de la geocerca

#### Tabla `opciones_geocerca`
- `id_cerca_total`: FK a geocerca
- `entrada`: 1/0 (alerta entrada)
- `salida`: 1/0 (alerta salida)
- `sms`: 1/0 (no usado en esta vista)
- `email`: 1/0
- `monitor`: 1/0
- `apagar`: 1/0 (no usado en esta vista)
- `taller`: 1/0
- `estado_control`: 'in' o 'out'

#### Tabla `sms_block`
- `id_vehi`: ID del vehículo
- `id_alarma`: Tipo de alarma (1 = geocerca)
- `id_cerca_total`: FK a geocerca

#### Tabla `vehiculo`
- Campos relevantes:
  - `geocerca`: 'in' o 'out'
  - `id_cerca_total`: ID de geocerca actual
  - `tipo_geo_ciudad`: Tipo de geocerca ciudad

### 5. FLUJOS DE TRABAJO

#### Flujo 1: Crear Geocerca Nueva
1. Usuario selecciona Empresa → Flota → Vehículo
2. Usuario ingresa dirección y hace clic en "Buscar"
3. Usuario elige modo:
   - **Automático:** Ingresa radio, se crea polígono circular
   - **Personalizado:** Hace clic en mapa para dibujar polígono
4. Usuario hace clic en "Grabar"
5. Se envía `miArray` a `grabar_geocercas2.php`
6. Se guardan puntos en BD
7. Se actualiza tabla de geocercas

#### Flujo 2: Ver Geocerca Existente
1. Usuario selecciona vehículo
2. Se llama `enviargeocerca()` → `muestra_geocercas2.php`
3. Se muestra tabla con geocercas
4. Usuario hace clic en botón "Ver" (lupa)
5. Se llama `muestrageocerca(id_cerca, lat, lng)`
6. Se carga XML con puntos desde `phpsqlajax_genxml8.php`
7. Se dibuja polígono en mapa con marcadores rojos

#### Flujo 3: Editar Opciones de Geocerca
1. Usuario modifica checkboxes o nombre en tabla
2. Usuario hace clic en "Grabar" (ícono)
3. Se llama `grabaropciones1(id_cerca, indice)`
4. Se envía formulario POST a `actualizar_geocercas.php`
5. Se actualizan tablas `geocerca` y `opciones_geocerca`
6. Se redirige a vista con vehículo seleccionado

#### Flujo 4: Eliminar Geocerca
1. Usuario hace clic en "Borrar" (ícono)
2. Se llama `borrargeocerca(id_cerca)`
3. Se envía GET a `borrar_puntos2.php`
4. Se eliminan registros de BD
5. Se actualiza tabla de geocercas

### 6. PUNTOS DELICADOS Y CRÍTICOS

#### ⚠️ PUNTOS CRÍTICOS

1. **Parsing del Array de Puntos:**
   - Formato: `(lat,lng)(lat,lng)(lat,lng)...`
   - Se usa `explode('(', $array)` y luego `explode(',', $coord)`
   - **CRÍTICO:** El formato debe ser exacto, cualquier variación rompe el parsing

2. **Gestión de `id_cerca_total`:**
   - Se obtiene `MAX(id_cerca_total) + 1` para nuevas geocercas
   - **CRÍTICO:** Si hay concurrencia, puede haber colisiones
   - **SOLUCIÓN:** Usar transacciones o locks

3. **Relación Vehículo-Empresa:**
   - Geocercas pueden ser específicas del vehículo (`id_emp=0`) o generales (`id_emp>0`)
   - **CRÍTICO:** La consulta usa `OR` entre `id_vehi` e `id_emp`, puede mostrar geocercas no esperadas

4. **Estado del Vehículo:**
   - Al eliminar geocerca, se actualiza `vehiculo.geocerca='out'`
   - **CRÍTICO:** Si el vehículo está dentro de otra geocerca, este campo puede quedar desactualizado

5. **Permisos de Usuario:**
   - Usuarios normales solo ven vehículos de `usuario_vehiculo`
   - **CRÍTICO:** La validación debe hacerse en cada API, no solo en frontend

6. **Formato de Coordenadas:**
   - Google Maps usa `LatLng(lat, lng)`
   - BD almacena `co_coordx` (lat) y `co_coordy` (lng)
   - **CRÍTICO:** No confundir orden (x=lat, y=lng)

7. **Inicialización Condicional:**
   - Si viene `ti_vehiculo` en GET, se llama `initialize2()` que carga geocercas
   - **CRÍTICO:** Debe ejecutarse después de que el mapa esté listo

8. **Geocodificación:**
   - Usa Google Geocoder API
   - **CRÍTICO:** Si falla, no hay manejo de error robusto

9. **Modo Automático vs Personalizado:**
   - Modo automático crea polígono cuadrado de 4 puntos
   - Modo personalizado permite puntos ilimitados
   - **CRÍTICO:** El marcador arrastrable solo funciona en modo automático

10. **Actualización de Tabla:**
    - Después de grabar/borrar, se reemplaza `innerHTML` de `tablescroll`
    - **CRÍTICO:** Se pierden event listeners si no se re-bindean

---

## 🎯 PLAN DE ADAPTACIÓN QUIRÚRGICO

### FASE 1: ESTRUCTURA BASE Y LAYOUT

#### 1.1 Archivo Principal (`geocerca-control.php`)
- [ ] Usar `base.php` layout
- [ ] Integrar sesión y permisos del nuevo sistema
- [ ] Crear estructura HTML con Bootstrap:
  - Columna izquierda: Formulario de controles
  - Columna derecha: Contenedor del mapa (responsive)
  - Tabla scrollable debajo del formulario
- [ ] Incluir Google Maps API (usar variable de entorno para API key)
- [ ] Incluir CSS y JS separados

#### 1.2 CSS (`operaciones/css/geocerca-control.css`)
- [ ] Estilos para layout de dos columnas
- [ ] Estilos para tabla de geocercas
- [ ] Estilos para checkboxes y botones
- [ ] Estilos para tema oscuro (`[data-theme="dark"]`)
- [ ] Estilos responsive (mobile)

#### 1.3 JavaScript (`operaciones/js/geocerca-control.js`)
- [ ] Clase principal `GeocercaControl`
- [ ] Inicialización del mapa
- [ ] Gestión de arrays y polígonos
- [ ] Event listeners

### FASE 2: APIS RESTFUL

#### 2.1 API: Obtener Flotas (`api/operaciones/get-flotas.php`)
- [ ] Validar sesión
- [ ] Recibir `id_emp` (GET)
- [ ] Consultar flotas según permisos:
  - Admin: Todas las flotas de la empresa
  - Distribuidor: Flotas de empresas del distribuidor
  - Usuario: Flotas asignadas en `usuario_flota`
- [ ] Retornar JSON: `{success: true, data: {flotas: [...]}}`
- [ ] Logging a `APIlogs.txt`

#### 2.2 API: Obtener Vehículos (`api/operaciones/get-vehiculos.php`)
- [ ] Validar sesión
- [ ] Recibir `id_flota` (GET)
- [ ] Consultar vehículos según permisos:
  - Admin/Distribuidor: Todos los vehículos de la flota
  - Usuario: Solo vehículos en `usuario_vehiculo`
- [ ] Retornar JSON: `{success: true, data: {vehiculos: [...]}}`
- [ ] Logging a `APIlogs.txt`

#### 2.3 API: Obtener Geocercas (`api/operaciones/get-geocercas.php`)
- [ ] Validar sesión
- [ ] Recibir `placa` o `id_vehi` (GET)
- [ ] Obtener `id_vehi` e `id_emp` del vehículo
- [ ] Consultar geocercas: `WHERE (id_vehi=? AND tipo_cerca=1) OR (id_emp=? AND tipo_cerca=1) GROUP BY id_cerca_total`
- [ ] Para cada geocerca, obtener opciones desde `opciones_geocerca`
- [ ] Retornar JSON con estructura completa
- [ ] Logging a `APIlogs.txt`

#### 2.4 API: Obtener Puntos de Geocerca (`api/operaciones/get-puntos-geocerca.php`)
- [ ] Validar sesión
- [ ] Recibir `id_cerca_total` (GET)
- [ ] Consultar puntos: `SELECT co_coordx, co_coordy FROM geocerca WHERE id_cerca_total=? ORDER BY id_cerca`
- [ ] Retornar JSON: `{success: true, data: {puntos: [{lat, lng}, ...]}}`
- [ ] Logging a `APIlogs.txt`

#### 2.5 API: Crear Geocerca (`api/operaciones/crear-geocerca.php`)
- [ ] Validar sesión
- [ ] Recibir POST:
  - `placa`: Placa del vehículo
  - `puntos`: Array JSON de `[{lat, lng}, ...]`
- [ ] Obtener `id_vehi` e `id_emp` del vehículo
- [ ] Obtener `MAX(id_cerca_total) + 1` (usar transacción)
- [ ] Insertar cada punto en `geocerca`
- [ ] Insertar registro en `opciones_geocerca` (valores por defecto)
- [ ] Insertar en `sms_block`
- [ ] Retornar JSON: `{success: true, data: {id_cerca_total: ...}}`
- [ ] Logging a `APIlogs.txt`

#### 2.6 API: Actualizar Geocerca (`api/operaciones/actualizar-geocerca.php`)
- [ ] Validar sesión
- [ ] Recibir POST:
  - `id_cerca_total`
  - `nombre_geocerca`
  - `entrada` (1/0)
  - `salida` (1/0)
  - `email` (1/0)
  - `monitor` (1/0)
  - `taller` (1/0)
  - `general` (1/0) → si 1, usar `id_emp` del vehículo, sino 0
  - `estado` (1/0)
- [ ] Actualizar `geocerca` y `opciones_geocerca`
- [ ] Retornar JSON: `{success: true, message: "..."}`
- [ ] Logging a `APIlogs.txt`

#### 2.7 API: Eliminar Geocerca (`api/operaciones/eliminar-geocerca.php`)
- [ ] Validar sesión
- [ ] Recibir POST:
  - `id_cerca_total`
  - `placa` (para obtener `id_vehi`)
- [ ] Usar transacción:
  - DELETE de `geocerca` WHERE `id_cerca_total`
  - DELETE de `opciones_geocerca` WHERE `id_cerca_total`
  - DELETE de `sms_block` WHERE `id_cerca_total`
  - UPDATE `vehiculo` SET `geocerca='out'`, `id_cerca_total='0'`, `tipo_geo_ciudad=''` WHERE `id_cerca_total=?`
- [ ] Retornar JSON: `{success: true, message: "..."}`
- [ ] Logging a `APIlogs.txt`

### FASE 3: FUNCIONALIDADES DEL MAPA

#### 3.1 Inicialización
- [ ] Función `initializeMap()`:
  - Verificar si viene `ti_vehiculo` en URL
  - Si viene, cargar geocercas del vehículo
  - Si no, inicializar en Lima por defecto
- [ ] Función `initializeMapAt(lat, lng, zoom)`:
  - Inicializar mapa en coordenadas específicas

#### 3.2 Modo Personalizado
- [ ] Función `enableDrawingMode()`:
  - Agregar event listener `map.addListener('click', addPoint)`
  - Mostrar instrucciones al usuario
- [ ] Función `addPoint(event)`:
  - Agregar punto a `miArray`
  - Crear marcador en el punto
  - Actualizar polígono si hay 3+ puntos
- [ ] Función `updatePolygon()`:
  - Crear/actualizar `google.maps.Polygon` con puntos de `miArray`

#### 3.3 Modo Automático
- [ ] Función `createCircularGeofence(center, radiusMeters)`:
  - Calcular 4 puntos formando cuadrado alrededor del centro
  - Crear polígono con estos puntos
  - Crear marcador arrastrable en el centro
  - Event listener `dragend` para recalcular polígono

#### 3.4 Geocodificación
- [ ] Función `geocodeAddress(address, callback)`:
  - Usar Google Geocoder API
  - Manejar errores (mostrar popup moderno)
  - Ejecutar callback con `{lat, lng}`

#### 3.5 Visualización de Geocercas
- [ ] Función `loadGeocercaOnMap(id_cerca_total)`:
  - Llamar API `get-puntos-geocerca.php`
  - Crear polígono rojo en el mapa
  - Crear marcadores rojos en cada punto
  - Centrar mapa en el polígono

#### 3.6 Limpieza
- [ ] Función `clearMap()`:
  - Eliminar todos los polígonos
  - Eliminar todos los marcadores
  - Limpiar `miArray`
  - Reinicializar mapa

### FASE 4: GESTIÓN DE TABLA DE GEOCERCAS

#### 4.1 Renderizado
- [ ] Función `renderGeocercasTable(geocercas)`:
  - Crear tabla HTML con Bootstrap
  - Columnas: Nombre, Ver, In, Out, Email, Monitor, Taller, General, Estado, Acciones
  - Agregar event listeners a checkboxes y botones

#### 4.2 Event Handlers
- [ ] Botón "Ver":
  - Llamar `loadGeocercaOnMap(id_cerca_total)`
- [ ] Botón "Grabar":
  - Recolectar valores de checkboxes
  - Llamar API `actualizar-geocerca.php`
  - Mostrar popup de éxito/error
  - Recargar tabla
- [ ] Botón "Borrar":
  - Mostrar popup de confirmación moderno
  - Si confirma, llamar API `eliminar-geocerca.php`
  - Mostrar popup de éxito/error
  - Recargar tabla

### FASE 5: INTEGRACIÓN Y VALIDACIONES

#### 5.1 Validaciones
- [ ] Validar que se seleccione vehículo antes de grabar
- [ ] Validar que `miArray` tenga al menos 3 puntos
- [ ] Validar que radio sea > 0 en modo automático
- [ ] Validar permisos en cada API call

#### 5.2 Manejo de Errores
- [ ] Popups modernos para errores (Bootstrap Modal)
- [ ] Logging de errores a `APIlogs.txt`
- [ ] Mensajes de error descriptivos

#### 5.3 Optimizaciones
- [ ] Debounce en geocodificación
- [ ] Cache de geocercas cargadas
- [ ] Lazy loading de tabla de geocercas

### FASE 6: TESTING Y AJUSTES

#### 6.1 Casos de Prueba
- [ ] Crear geocerca en modo automático
- [ ] Crear geocerca en modo personalizado
- [ ] Ver geocerca existente
- [ ] Editar opciones de geocerca
- [ ] Eliminar geocerca
- [ ] Cambiar entre vehículos
- [ ] Probar con diferentes tipos de usuario

#### 6.2 Ajustes Finales
- [ ] Ajustar estilos para tema oscuro
- [ ] Ajustar responsive design
- [ ] Optimizar rendimiento del mapa
- [ ] Verificar compatibilidad con navegadores

---

## 📝 NOTAS IMPORTANTES

1. **Formato de Puntos:**
   - En el nuevo sistema, usar JSON: `[{lat: -12.1277, lng: -77.01818}, ...]`
   - No usar el formato `(lat,lng)(lat,lng)` del sistema antiguo

2. **Transacciones:**
   - Usar transacciones MySQLi para operaciones críticas (crear, eliminar)

3. **Seguridad:**
   - Validar permisos en cada API
   - Sanitizar todos los inputs
   - Usar prepared statements

4. **Logging:**
   - Registrar todas las operaciones importantes
   - Incluir contexto (usuario, vehículo, geocerca)

5. **UX:**
   - Usar popups modernos en lugar de `alert()`
   - Mostrar loading states
   - Feedback visual inmediato

---

## ✅ CHECKLIST FINAL

- [ ] Vista principal creada y funcional
- [ ] Todas las APIs creadas y probadas
- [ ] Mapa funcional (modo automático y personalizado)
- [ ] Tabla de geocercas funcional
- [ ] CRUD completo funcionando
- [ ] Permisos validados
- [ ] Tema oscuro implementado
- [ ] Responsive design
- [ ] Logging implementado
- [ ] Manejo de errores robusto
- [ ] Testing completo

---

**Fecha de Análisis:** 2025-12-16  
**Versión del Plan:** 1.0

