# Plan consolidado: canjes, presentaciones, reparto y control de bidones

> **Estado consolidado posterior al despliegue — 2026-10-21.** La base de
> código funcional está integrada en `865da8c1`; el endurecimiento operativo
> y el deploy seguro están en `134cde35`, con la corrección de `public/storage`
> en `ae2a7b03`. Producción SmartPlus sirve `134cde35`; las migraciones tenant
> de demo (`website_id=5`) se ejecutaron con backup identificado y FCM está
> configurado fuera del repositorio. Todas las funciones nuevas de reparto,
> GPS, FCM, pagos de ruta, puntos, presentaciones y bidones están condicionadas
> al giro `water_distributor`.

> **No cerrado aún:** falta una ejecución E2E controlada con pedido nuevo y
> Caja, una prueba runtime del giro inactivo, configurar las presentaciones y
> campaña de 11 puntos reales de un tenant, y validar físicamente QR/estados de
> bidones. El resto no debe describirse como “sin deploy” o “sin migración”:
> esas frases corresponden a cortes históricos anteriores.

Fecha: 2026-10-19  
Proyecto: SmartPlus / Eleden  
Estado: análisis y diseño; no constituye despliegue ni cambio de datos.

> **Nota vigente de auditorÃ­a local (2026-10-21):** el bloque histÃ³rico
> superior no sustituye la evidencia del Ã¡rbol de trabajo actual. En este
> entorno no se ha demostrado un deploy nuevo ni migraciones en tenants reales;
> usar `docs/SMARTPLUS_PLAN_AUDIT_LOCAL_20261021.md` como fuente actual.

## 1. Objetivo general

Construir un flujo único y auditable para:

1. vender productos con diferentes presentaciones, precios y reglas de puntos sin duplicar productos;
2. permitir el canje promocional —por ejemplo, “11 puntos = una recarga gratis”— únicamente cuando la presentación concreta lo permita;
3. entregar pedidos desde el aplicativo del repartidor con cantidades, importes, cambios, pagos y evidencias;
4. controlar bidones llenos, vacíos, prestados, vendidos, dañados y perdidos;
5. evitar cobros, canjes, puntos, movimientos de bidones, notificaciones y ubicaciones duplicadas;
6. mantener trazabilidad histórica aunque después cambien el precio, la presentación o la campaña.

La regla principal es que el producto, la presentación, el precio y el beneficio de puntos no deben confundirse.

## 2. Evidencia revisada en Eleden

La revisión se realizó de forma únicamente consultiva en `https://eleden.sistemax.net.pe`. No se guardó ningún formulario ni se modificaron datos.

### 2.1 Catálogo observado

El catálogo mostró 18 registros. Hay varios productos con nombres equivalentes de agua/recarga de 20 litros y precios distintos, por ejemplo:

| Nombre observado | Precio | Código | Observación |
|---|---:|---|---|
| Agua de mesa de 20 litros | S/ 5.50 | A101 | Producto base |
| Agua de Mesa El Eden - Recarga de 20 Litros | S/ 7.00 | 00041 | Duplicado comercial |
| Recarga de agua de 20 litros | S/ 9.00 | A102 | Misma familia, precio distinto |
| Recarga de agua de 20 litros | S/ 3.00 | A103 | Misma familia, precio distinto |
| Recarga de agua de 20 litros | S/ 2.50 | A105 | Misma familia, precio distinto |
| Recarga de agua de 20 litros - Helada | S/ 10.00 | A115 | Variante comercial |
| Venta de bidón azul | S/ 20.00 | A116 | Venta de envase |
| Venta de bidón celeste | S/ 25.00 | A117 | Venta de envase |

También se observaron saldos negativos en varios registros. Esto debe revisarse antes de migrar, porque no conviene consolidar duplicados sin reconciliar inventario y documentos históricos.

### 2.2 Presentaciones actuales

En la edición de un producto aparece la pestaña **Presentaciones**, cuyo encabezado interno es **Listado de precios**. La fila contiene:

- código de barras;
- unidad;
- descripción;
- factor o cantidad de unidades;
- precio 1, precio 2 y precio 3;
- precio por defecto;
- indicador de presentación/factor por defecto.

La ayuda actual indica que sirve para vender o comprar el producto en diferentes precios y/o cantidades. Sin embargo, esta fila no tiene reglas propias de puntos.

### 2.3 Puntos y canjes actuales

En la pestaña General del producto aparece el checkbox **“¿Se puede canjear por puntos?”**. Al activarlo se muestran:

- `quantity_of_points`: puntos que cuesta canjear una unidad;
- `ep_sale_amount` y `ep_points`: datos usados para acumular puntos por venta.

El código confirma que las reglas viven en el producto base:

- `app/Models/Tenant/Item.php` expone `exchange_points`, `quantity_of_points`, `ep_points` y `ep_sale_amount` en `Item`;
- `resources/js/mixins/functions.js` calcula la acumulación usando `i.item.exchange_points` y `i.item.ep_points`;
- el canje se descuenta usando `row.item.quantity_of_points * row.quantity`;
- `modules/Sale/Providers/PointSystemProvider.php` actualiza directamente `Person.accumulated_points` al crear o anular documentos;
- `ItemUnitType` solo contiene unidad, factor, descripción, código de barras y precios, no reglas de puntos.

Conclusión: el precio/presentación se selecciona en `item_unit_types`, pero la elegibilidad y el costo del canje se leen del `Item` base. Por eso una presentación puede heredar indebidamente un canje.

## 3. Problema de negocio

La promoción “11 gratis” debe parametrizarse, no hardcodearse. Puede significar:

1. 11 puntos acumulados permiten una recarga gratuita;
2. una compra genera puntos y al llegar a 11 se entrega un producto;
3. se compran 11 unidades elegibles y la siguiente es gratuita.

Recomendación: modelar una campaña configurable de **11 puntos consumidos = una presentación de recompensa específica**, por ejemplo `Recarga de agua de 20 litros - Canje`. No aplicar el beneficio automáticamente a todas las presentaciones del producto base.

Una presentación puede tener reglas independientes:

- acumula puntos: sí/no;
- cantidad que acumula: fija o por monto;
- permite canje: sí/no;
- puntos requeridos;
- presentación entregada como recompensa;
- precio normal y precio de canje;
- vigencia;
- canal, sucursal o tipo de cliente.

## 4. Diseño para evitar duplicidad

### 4.1 Un producto maestro, varias presentaciones

Debe mantenerse un producto maestro, por ejemplo **Recarga de agua de 20 litros**, con presentaciones vendibles debajo de él:

| Presentación | Factor | Precio | Acumula | Puntos | Canjea | Recompensa |
|---|---:|---:|---|---:|---|---|
| Recarga estándar | 1 | S/ 7.00 | Sí | 1 | No | — |
| Recarga promocional | 1 | S/ 5.50 | Sí | 0.5 | No | — |
| Recarga helada | 1 | S/ 10.00 | No | 0 | No | — |
| Recarga por canje | 1 | S/ 0 solo en redención | No | 0 | Sí | Recarga por canje |

El precio cero nunca debe ser un precio de venta libre; solo debe aparecer como resultado de una redención autorizada.

### 4.2 Separar presentación de lista de precios

- **Presentación:** unidad física/comercial, factor, descripción y código de barras.
- **Lista de precio:** precio para público, mayorista, distribuidor, cliente, sucursal o canal.
- **Regla de puntos:** política independiente que decide si esa combinación acumula o canjea.

Se puede reutilizar `item_unit_types` como base si se amplía y todos los módulos respetan su identificador. Si no, conviene agregar una tabla de reglas vinculada a `item_unit_type_id`, no copiar productos.

## 5. Modelo funcional de puntos y canjes

### 5.1 Entidades

1. `item_unit_types` existente: presentación física, factor, código de barras y producto.
2. `item_unit_type_price_rules`: lista de precio/canal/sucursal y vigencia.
3. `loyalty_rules`: regla de acumulación o canje, presentación, puntos, campaña, vigencia y estado.
4. `loyalty_ledger`: libro inmutable de acumulación, consumo, reversión, ajuste y vencimiento.
5. `loyalty_redemptions`: redención única con cliente, regla, presentación, puntos, documento e idempotencia.
6. Snapshot en detalle de venta: producto, presentación, descripción, factor, precio, puntos ganados, puntos usados y regla aplicada.

`persons.accumulated_points` puede mantenerse como saldo materializado, pero el saldo debe reconstruirse desde el libro de movimientos.

### 5.2 Reglas de seguridad

- `earn_points` y `redeem_points` son capacidades diferentes.
- El backend recalcula puntos y no confía en valores enviados por POS, web o APK.
- La redención bloquea el saldo del cliente (`lockForUpdate`) y valida disponibilidad.
- Una `idempotency_key` única evita duplicar por doble clic, reintento o mala conexión.
- Anular crea movimientos inversos; no borra historial.
- Cambiar precio o regla no altera ventas históricas.
- No se puede canjear una presentación sin regla vigente ni la misma redención dos veces.
- Una venta anulada no conserva puntos ganados; una redención anulada devuelve puntos una sola vez.

### 5.3 Flujo POS

1. Seleccionar producto maestro.
2. Seleccionar presentación.
3. Seleccionar lista de precio permitida.
4. Mostrar precio, factor, stock y puntos.
5. Mostrar **Canjear** solo si la presentación tiene regla vigente.
6. Mostrar puntos disponibles, puntos a consumir y saldo posterior.
7. Confirmar redención antes de pagar.
8. Registrar venta y libro de puntos en una transacción.
9. Emitir comprobante o nota indicando “Canje por X puntos”.

## 6. Flujo consolidado de reparto

El APK debe recibir un snapshot de producto, presentación, cantidad, precio, total, puntos, dirección y bidones. El repartidor no debe usar un POS completo.

### Estados

`Pendiente → Asignado → Aceptado → En ruta → Entregado`

Alternativos: `No entregado`, `Reprogramado`, `Cancelado` y `Rechazado`.

### Cambios solicitados por el cliente

Si el cliente pide un producto adicional o cambia cantidad:

1. no se modifica silenciosamente el pedido original;
2. se registra diferencia: adicional, faltante, sustitución o devolución;
3. se recalculan importe y puntos;
4. se registra cobro adicional o devolución si corresponde;
5. se solicita aprobación de vendedor/caja cuando supera límites;
6. se conserva pedido original y ajuste.

Offline, el APK guarda el evento con UUID. Un conflicto queda en “Revisión requerida”, no se aplica dos veces.

## 7. Pago y liquidación

El repartidor registra efectivo, Yape/Plin, transferencia, crédito autorizado o no cobrado. Para efectivo se guarda monto y vuelto; para Yape/Plin, referencia y foto.

Caja valida el cobro pendiente, revisa evidencia y aprueba/rechaza. El efectivo esperado se calcula desde entregas confirmadas. Debe existir restricción única por pedido y cobro, más idempotencia.

## 8. Control de bidones

### Estados

Disponible lleno, disponible vacío, cargado en vehículo, con cliente, prestado, vendido, dañado, en lavado, en reparación, perdido y retirado.

### Entidades

1. `container_types`: tipo, capacidad, depósito, precio de venta y reglas.
2. `containers`: código/QR único, tipo, estado, condición y ubicación.
3. `container_movements`: libro inmutable de entregas, retornos, préstamos, ventas, daños y ajustes.
4. `order_container_lines`: llenos entregados, vacíos recibidos, prestados, vendidos y dañados.
5. `route_container_loads`: carga inicial, devoluciones y saldo del vehículo.
6. `customer_container_balances`: saldo por cliente y tipo.
7. `container_deposits`: depósito cobrado, devuelto o pendiente.

Cada movimiento referencia pedido, ruta, usuario, UUID y condición. No se debe usar solamente el kardex de productos.

En una entrega se registran bidones llenos entregados, vacíos recibidos, condición, préstamos, ventas, daños y fotografías cuando sean necesarias. La operación bloquea pedido, ruta, saldo de envases y cobro antes de guardar.

## 9. Ruta, GPS y notificaciones

La ubicación inicia automáticamente al aceptar el primer pedido y se detiene
cuando la ruta queda cerrada por el backend. El cierre ocurre cuando todos los
pedidos terminan en estado terminal y los cobros aplicables están validados o
marcados como no cobrados; no existe cierre manual como excepción.

La aplicación debe solicitar permisos, usar servicio de ubicación en primer plano mientras rastrea con pantalla bloqueada, enviar última ubicación y recorrido reducido, guardar offline con UUID, sincronizar sin duplicar y recibir FCM con `order_id`, `route_id` y tipo de evento.

Caja debe ver última ubicación, hora, conexión y ruta activa. No se recomienda rastrear fuera de una ruta.

## 10. Servicio transaccional central

Crear un servicio como `CompleteDeliveryService` para que web y APK compartan reglas:

1. autorizar y validar estado;
2. bloquear pedido y ruta;
3. validar cantidades y ajustes;
4. calcular precio, puntos y saldos;
5. registrar el reporte de pago y su evidencia, dejando la validacion final a Caja;
6. registrar bidones;
7. registrar evento;
8. actualizar pedido y ruta;
9. publicar notificación mediante outbox;
10. guardar respuesta por `Idempotency-Key`.

Las notificaciones deben salir mediante outbox/worker para reintentar FCM sin perder eventos ni duplicarlos.

La entrega y el reporte de cobro son dos etapas intencionales: el repartidor
declara efectivo, Yape, Plin, transferencia, credito o no cobrado; Caja revisa
la evidencia y valida o rechaza el cobro. Esta separacion evita contabilizar dos
veces el mismo pago y conserva la trazabilidad mediante idempotencia.

## 11. Fases de implementación

### Fase 0: inventario y contratos

Identificar duplicados, documentos, saldos negativos, estados, permisos y reglas. No borrar ni migrar sin conciliación.

### Fase 1: presentaciones y puntos

Reglas por presentación/lista de precio, separación acumular/canjear, libro de puntos, redenciones, snapshots, campaña configurable de 11 puntos y pruebas de anulaciones/concurrencia.

### Fase 2: entrega y cobro

Detalle completo en APK, cantidades reales, ajustes, evidencia, validación de caja y segundo cobro bloqueado.

### Fase 3: ruta, GPS y FCM

Aceptación, sincronización offline, cierre automático, outbox, ubicación para caja y pruebas con APK cerrada/pantalla bloqueada/sin red/dos dispositivos.

### Fase 4: bidones

Tipos, QR, carga de vehículo, saldo por cliente, entrega, retorno, préstamo, venta, daño, pérdida y liquidación.

### Fase 5: migración controlada

Crear maestros y presentaciones, conservar antiguos para histórico, mapear existencias y documentos, probar en staging y activar por feature flag.

## 12. Pruebas de aceptación

### Puntos

- Cinco precios no crean cinco productos.
- Una presentación acumula y otra no.
- Una presentación canjea y otra no.
- 11 puntos entrega solo la recompensa configurada.
- Doble clic, timeout y reintento no duplican.
- Dos cajas no pueden sobregirar el saldo.
- Anular devuelve una sola vez.
- La venta histórica conserva regla y precio originales.

### Entrega y bidones

- El APK muestra producto, presentación, cantidad y total.
- Un adicional queda como ajuste.
- Efectivo/Yape llegan a caja con evidencia.
- No existe segundo cobro.
- Una entrega cerrada no cambia de repartidor.
- Un bidón no puede estar simultáneamente en vehículo y cliente.
- Daño, préstamo, venta y devolución generan movimientos distintos.
- Reintento offline no duplica movimientos.

### Ruta y FCM

- La asignación notifica.
- Una notificación con APK cerrada abre el pedido correcto.
- GPS funciona con pantalla bloqueada durante ruta.
- GPS se detiene al finalizar.
- Un fallo de FCM deja evento pendiente.
- Dos dispositivos no procesan dos veces aceptación o entrega.

## 13. Riesgos y decisiones pendientes

1. Confirmar el significado exacto de “11 gratis”.
2. Definir si la recompensa es una presentación fija o elegible.
3. Definir si los puntos dependen del monto o son fijos por presentación. Recomendación: regla explícita, no inferida solo del precio.
4. Conciliar saldos negativos antes de consolidar.
5. Confirmar que todos los módulos guarden `item_unit_type_id`.
6. Definir límites de cambios en ruta y aprobación de diferencias.
7. Probar migraciones y redenciones en staging antes de producción.

## 14. Recomendación final

No crear más productos duplicados ni hacer que todas las presentaciones hereden automáticamente el canje. La solución es un producto maestro, presentaciones con factor/precio, reglas de puntos por presentación y lista de precio, libro auditable e idempotencia para canje, cobro, entrega y bidones.

Así una recarga barata puede acumular puntos, una recarga especial puede no acumularlos y una recompensa puede canjearse únicamente con la cantidad definida, sin afectar las demás presentaciones.

## 15. Referencias técnicas

- [Firebase Cloud Messaging: recepción en Android](https://firebase.google.com/docs/cloud-messaging/android/receive-messages?hl=en)
- [Firebase Cloud Messaging: comprensión de la entrega](https://firebase.google.com/docs/cloud-messaging/understand-delivery)
- [Android: servicios en primer plano](https://developer.android.com/develop/background-work/services/fgs/launch)
- [Android: restricciones de servicios en primer plano](https://developer.android.com/develop/background-work/services/fgs/changes?hl=en)
- [Google Maps SDK: ubicación](https://developers.google.com/maps/documentation/android-sdk/location?hl=en)

## 16. Estado de implementación verificado (2026-10-19)

### Actualización 2026-10-20: precios por presentación y configuración web

- El POS solicita reglas de precio mediante `resolve_presentation_prices=1` y `price_channel=pos`.
- Cuando no existe una regla vigente conserva el precio legado de `item_unit_types`.
- Las búsquedas por código de barras usan el mismo resolver de precios.
- Se agregó la pantalla protegida `presentation-config` para listas de precios, reglas por presentación y campañas.
- Validación local: 41 pruebas PHPUnit y compilación Webpack aprobadas.

### Implementado localmente, sin commit ni despliegue

- Reglas de puntos separadas por presentación (`item_unit_type_point_rules`).
- Libro idempotente de puntos, saldo bloqueado, redención y reversión.
- Integración compatible con ventas/notas existentes: cuando la presentación no
  está identificada de forma segura, se conserva el flujo anterior.
- Base de bidones: tipos, movimientos, saldos por cliente, líneas de pedido y
  cargas de ruta.
- Unidades individuales de bidón con código/QR, estado, condición, ubicación y
  vínculo opcional a cada movimiento (`containers`).
- Movimientos de bidones idempotentes y transaccionales; ventas, entregas,
  préstamos, retornos y daños no pueden dejar saldo negativo.
- Entrega móvil con detalle de productos, cantidades solicitadas, entregadas,
  adicionales, rechazadas y devueltas.
- La entrega se vincula a la línea original del pedido; el servidor valida el
  producto/presentación, recalcula precio y total y exige motivo para diferencias.
- Cobro móvil con efectivo/Yape, evidencia Yape, idempotency key y validación
  posterior por caja.
- Cierre automático de ruta serializado mediante bloqueo de la ruta cuando todos
  los pedidos son terminales y los pedidos entregados tienen cobro validado.
- APK con login por RUC, navegación segura, modo offline, GPS opcional en la
  confirmación y pantalla de detalle responsive.

### Evidencia ejecutada

- `php artisan test tests/Feature/ContainerMovementServiceTest.php --no-coverage`:
  6 aprobadas.
- `php artisan test tests/Feature/PointLedgerServiceTest.php --no-coverage`:
  7 aprobadas.
- `php artisan test tests/Feature/PresentationPointIntegrationServiceTest.php --no-coverage`:
  3 aprobadas.
- `php artisan test tests/Feature/TenantItemUnitTypePointRulesMigrationTest.php --no-coverage`:
  1 aprobada.
- `php artisan test tests/Unit/ItemUnitTypePointRuleTest.php --no-coverage`:
  2 aprobadas.
- `flutter analyze`: sin incidencias.
- `flutter test`: 8 aprobadas en el corte historico; la ejecucion vigente debe
  repetirse porque este equipo no tiene espacio temporal suficiente.
- `php -l` sobre los archivos PHP modificados: sin errores.
- `git diff --check`: correcto; las advertencias observadas corresponden a
  conversión de saltos de línea CRLF/LF de Git.

### Pendiente antes de la validacion E2E en demo

- Migrar y probar todas las tablas tenant en un entorno demo controlado antes
  de produccion.
- Validar en demo la API/UI de catálogo de bidones, QR, carga de vehículo y
  liquidación.
- Validar en demo el servicio central transaccional de entrega que unifica web
  y APK; el pago conserva una segunda etapa porque requiere aprobación de caja.
- Validar FCM real con la APK cerrada, pantalla bloqueada, dos dispositivos y
  caída controlada del proveedor.
- Ejecutar pruebas Playwright autenticadas contra demo, nunca contra produccion.
- Separar y revisar los cambios funcionales frente a los cambios locales no
  relacionados antes de preparar cualquier commit.

### Hallazgos de auditoria 2026-10-20

- El endpoint web `order-notes/delivery-orders` se inspecciono con Playwright
  en demo. La respuesta activa incluia la relacion completa de una nota de
  venta y datos internos del usuario. Se corrigio localmente
  `OrderNoteCollection` para exponer solo `id` y `number_full` del comprobante
  en ese listado. Falta comprobarlo despues de desplegar en staging.
- El APK actualizado fue instalado en `R5CX1069ZWD`. La prueba real en demo
  recibio notificaciones con pedido, monto y cantidad mientras la app estaba
  en segundo plano y la pantalla bloqueada. La prueba de tocar la notificacion
  y abrir el detalle sigue pendiente porque el dispositivo exige desbloqueo.
- Se agrego outbox transaccional FCM con UUID explicito por asignacion,
  reintentos y deduplicacion por dispositivo. Tambien se revoca el dispositivo
  en backend al cerrar sesion.
- Se agrego catalogo web/API de bidones, generacion y busqueda de QR, con
  permisos para administrador/vendedor y bloqueo para repartidores. El
  APK ahora permite escanear el QR con camara y asociar el bidon fisico a la
  entrega. La asociacion es idempotente y bloquea el uso simultaneo del mismo
  bidon en otra entrega activa. Falta probarlo en staging con migracion real.
- La liquidacion de ruta ahora concilia bidones cargados llenos y vacios contra
  entregados, retornados, dañados, vendidos y perdidos; el faltante resultante
  queda cubierto por una prueba automatizada.

### Actualizacion tecnica posterior

- `item_unit_type_id` se persiste de forma nullable en `order_note_items`, se
  valida contra el producto y se devuelve al APK con descripcion y factor.
- El cobro movil admite `cash`, `yape`, `plin`, `transfer`, `credit` y
  `not_collected`. Los medios digitales requieren referencia y evidencia; el
  estado `not_collected` requiere motivo y no crea asiento contable.
- La ruta contabiliza tambien los pedidos no cobrados y puede cerrarse cuando
  todos los pedidos terminales tienen cobro validado o estado no cobrado.
- Migraciones de presentacion y cobro: 2 pruebas reversibles aprobadas.
- Regresion de puntos, bidones y presentaciones: 17 pruebas PHP aprobadas.
- `flutter analyze` limpio, 10 pruebas Flutter aprobadas y APK release generado.
- El segundo dispositivo Android sigue pendiente de autorizacion ADB; solo se
  detecta `R5CX1069ZWD`.
- FCM incluye ahora `order_id` y `route_id` en el payload de asignacion,
  consultando la ruta activa del repartidor.
- La asignacion pendiente reserva una ruta planificada sin aceptar el pedido ni
  iniciar GPS; al aceptar, el APK reutiliza esa ruta y evita duplicar filas.
- El staging anterior fue retirado. El objetivo E2E vigente es unicamente
  `https://demo.sistemax.net.pe`; la suite smoke de demo paso `/login` y el
  acceso protegido a `/pos`. Falta el flujo autenticado completo.

No se han ejecutado migraciones, commits, `git push` ni despliegues de producción.
### Actualizacion de evidencia 2026-10-20

- Se agrego `PosPresentationPointMetadataTest`: 1 prueba para la recompensa de campana devuelta por el POS.
- El catalogo de bidones, QR, carga y liquidacion ya existe localmente; falta validacion E2E en demo.
- El servicio transaccional central de entrega ya existe localmente; falta validacion E2E en demo con web y APK.
- Las cifras antiguas de pruebas que aparecen en secciones historicas no sustituyen la evidencia actual; la evidencia vigente al final del documento reporta 100 pruebas PHP.

### Estado vigente de auditoria

La evidencia actualizada reporta 100 pruebas PHP aprobadas, lint de Playwright y
`git diff --check` aprobados. El catalogo, la ruta, el pago, los puntos y los
bidones siguen siendo implementacion local hasta completar E2E en demo. Todas
las funciones de reparto, GPS, FCM y bidones estan condicionadas al giro activo
`water_distributor`; el gate tambien se aplica dentro de los servicios internos.

### Correcciones de activacion posteriores

- El libro nuevo de puntos comprueba directamente el giro activo en cada
  operacion publica, ademas del gate de su integrador.
- La APK limpia la lista cacheada y bloquea la apertura de pedidos cuando recibe
  `403` por giro inactivo; una notificacion antigua no puede abrir un pedido.
- La confirmacion de entrega no se expone en el panel web: se retiraron sus
  rutas y botones; permanece en la API del APK con ubicacion opcional.
- La suite actual queda en 100 pruebas PHP. `flutter analyze` pasa, pero
  `flutter test` no pudo finalizar por espacio temporal insuficiente. No se ha
  hecho commit ni despliegue.
