# Geocodificacion de Pickups (Google Maps + Cache)

Este documento describe la implementacion vigente de geocodificacion para pickups:

- geocodificacion sincronica en create/update de pickup (**solo direccion de recogida**)
- disponibilidad controlada por Extra Plan **Map-Based Routing** (`extraplan` + `extraplancompany.active`)
- sin proceso de autocuracion en listados
- control de cuota con cache de exitos y fallos

## 1) Configuracion (env + defaults en PHP)

**Variables de entorno** (valores reales por entorno):

- `GOOGLE_MAPS_GEOCODING_ENABLED`
- `GOOGLE_MAPS_GEOCODING_TIMEOUT`
- `GOOGLE_MAPS_GEOCODING_FAILED_TTL`
- `GOOGLE_MAPS_GEOCODING_CONNECT_TIMEOUT`
- `GOOGLE_MAPS_GEOCODING_API_KEY`

En `config/services.yaml` las variables se leen con `%env(default:*_default:VAR)%` (cadena vacia si no estan definidas). Los valores numericos/booleanos reales se resuelven en PHP (`GeocodingServiceFactory`, `GoogleGeocodingHttpClientFactory`).

**Defaults** (solo si la variable no existe o viene vacia), definidos en `GeocodingService`:

- `DEFAULT_GEOCODING_ENABLED = false`
- `DEFAULT_FAILED_TTL_SECONDS = 86400`
- `DEFAULT_HTTP_TIMEOUT_SECONDS = 5.0`
- `DEFAULT_HTTP_CONNECT_TIMEOUT_SECONDS = 15.0`

`GeocodingServiceFactory` y `GoogleGeocodingHttpClientFactory` aplican esos defaults al construir los servicios.

## 2) Flujo funcional

En `PickupService` (create/update):

- si la compania **no** tiene Extra Plan activo, no se llama a Google
- si la compania tiene Extra Plan activo, se construye y normaliza la direccion de pickup
- si la direccion cambio o faltan coordenadas pickup, se intenta geocodificar
- si Google responde coordenadas validas, se guardan en DB
- si Google falla con Extra Plan activo, el guardado se bloquea con `ValidationException`

### Regla bloqueante por Extra Plan

La funcionalidad solo esta disponible cuando:

- existe un registro en `extraplan` con categoria/nombre **Map-Based Routing**
- la compania tiene un `extraplancompany` activo apuntando a ese plan

Cuando el plan esta activo:

- si existe direccion de pickup y no hay coordenadas validas -> error `pickup_geocoding_required_pickup_failed`

**Delivery:** no se geocodifica en esta version.

En `search` y `get` de pickup:

- no se encolan procesos
- no hay worker de geocoding para listados
- solo se devuelve la informacion existente en DB

## 3) Cache y control de cuota

`GeocodingService` usa dos llaves por hash de direccion normalizada:

- `geo_success_<hash>`: evita llamadas duplicadas para direcciones ya resueltas
- `geo_failed_<hash>`: evita reintentar direcciones que ya fallaron durante el TTL configurado

## 4) Normalizacion de direccion

Antes de invocar Google:

- trim por segmento
- colapso de espacios internos
- concatenacion con `, `
- omision de segmentos vacios

Segmentos pickup: `addressPickup`, `addressPickup2`, `cityPickup`, `statePickup`, `countryPickup`, `zipPickup`.

## 5) Endpoint fijo de Google

`GoogleGeocodingClient` usa:

- `private const GEOCODE_ENDPOINT = 'https://maps.googleapis.com/maps/api/geocode/json';`

La clave (`GOOGLE_MAPS_GEOCODING_API_KEY`) debe venir de entorno.

## 6) Variables de entorno sugeridas

```dotenv
GOOGLE_MAPS_GEOCODING_ENABLED=1
GOOGLE_MAPS_GEOCODING_API_KEY=your_api_key_here
GOOGLE_MAPS_GEOCODING_TIMEOUT=5
GOOGLE_MAPS_GEOCODING_FAILED_TTL=86400
GOOGLE_MAPS_GEOCODING_CONNECT_TIMEOUT=15
```

Si omitis alguna (excepto la API key en prod), se usan los `DEFAULT_*` de `GeocodingService`.

## 7) Migraciones

Las tablas `extraplan` y `extraplancompany` se crean via Doctrine migration.
El plan **Map-Based Routing** se inserta como catalogo en la migracion.
La asignacion por compania (`extraplancompany`) se gestiona por negocio/ops.

## 8) Exposicion al frontend (`GET /api/company/config`)

Tras el login, el front debe leer la config de compania (no el profile de usuario):

```json
{
  "extraPlans": {
    "mapBasedRouting": true,
    "ocrTech": false
  },
  "maps": {
    "geocodingEnabled": true
  }
}
```

- `extraPlans.mapBasedRouting`: `extraplancompany` activo con categoria **Map-Based Routing**.
- `extraPlans.ocrTech`: plan OCR TECH activo para la compania.
- `maps.geocodingEnabled`: flag global del servidor (`GOOGLE_MAPS_GEOCODING_ENABLED`).

Para habilitar geocoding en UI/backend de pickup, el front puede exigir `maps.geocodingEnabled && extraPlans.mapBasedRouting`.

## 9) Resultado esperado

- pickups nuevos/editados con Extra Plan activo intentan persistir coordenadas pickup en el mismo request
- sin Extra Plan activo, no hay geocoding automatico
- listados no disparan procesos de geocoding
- menor complejidad operativa (sin worker para esta funcionalidad)
