# Multi-tariffa per area di sosta

## Comportamento

VisPa consente ora di associare più tariffe attive alla stessa area.

- Con una sola tariffa valida, il flusso resta invariato e la tariffa viene selezionata automaticamente.
- Con più tariffe valide, sito e app mostrano le alternative con nome, descrizione e importo calcolato per il periodo richiesto.
- Preventivo e pagamento accettano `parking_tariff_id`.
- Il backend verifica nuovamente la tariffa al preventivo e al pagamento: deve appartenere all'area, essere attiva, valida per la data e compatibile con il tipo di veicolo.
- L'importo inviato dal client non viene mai considerato attendibile: il server ricalcola sempre il totale.
- L'app invia anche `quoted_amount` come sola guardia di consenso: se il totale ricalcolato è cambiato, il pagamento viene fermato e deve essere richiesto un nuovo preventivo.
- Le soste già create continuano a utilizzare il proprio `parking_tariff_id`; estensioni e interruzioni non passano a una tariffa diversa.

## Aggiornamento database

La migrazione `2026_07_18_000001_add_description_to_parking_tariffs_table.php` aggiunge il campo facoltativo `description` a `parking_tariffs`. Può essere usato, per esempio, per chiarire “Tariffa residenti” e “Tariffa ordinaria/non residenti”.

In produzione eseguire:

```bash
php artisan migrate --force
php artisan optimize:clear
```

I limiti condivisi di programmazione e durata possono essere configurati in `.env`:

```dotenv
VISPA_PARKING_MAX_ADVANCE_DAYS=7
VISPA_PARKING_MAX_DURATION_DAYS=7
```

## API mobile

Endpoint disponibili nel gruppo autenticato mobile:

- `GET /api/mobile/parking/options`
- `POST /api/mobile/parking/tariffs`
- `POST /api/mobile/parking/quote`
- `POST /api/mobile/parking/pay-wallet`

Dati principali per tariffe, preventivo e pagamento:

```json
{
  "municipality_id": 1,
  "parking_area_id": 4,
  "parking_tariff_id": 12,
  "vehicle_type_id": 2,
  "plate": "AB123CD",
  "start_at": "2026-07-18 10:00:00",
  "end_at": "2026-07-18 12:00:00",
  "quoted_amount": "3.15"
}
```

`parking_tariff_id` è facoltativo nelle aree con una sola tariffa. Quando le alternative sono più di una, il preventivo risponde con `selection_required: true` e con l'array `tariffs`, che contiene anche il totale calcolato per ogni alternativa.

Esempio sintetico:

```json
{
  "selection_required": true,
  "auto_selected_tariff_id": null,
  "parking_area_id": 4,
  "tariffs": [
    {
      "id": 12,
      "name": "Ordinaria",
      "description": "Tariffa per utenti non residenti",
      "parking_amount": "3.00",
      "service_fee_amount": "0.15",
      "amount": "3.15"
    },
    {
      "id": 13,
      "name": "Residenti",
      "description": "Tariffa riservata ai residenti",
      "parking_amount": "1.60",
      "service_fee_amount": "0.08",
      "amount": "1.68"
    }
  ]
}
```

## Ordine di rilascio consigliato

1. Eseguire un backup di database e configurazione.
2. Distribuire il backend aggiornato.
3. Eseguire `php artisan migrate --force`.
4. Eseguire `php artisan optimize:clear`.
5. Compilare e distribuire gli asset di produzione.
6. Distribuire la nuova versione dell'app Flutter.
7. Solo dopo, attivare più tariffe contemporaneamente sulle aree interessate.

La vecchia app continua a funzionare nelle aree con una sola tariffa, ma non conosce la schermata di scelta: per questo non va abilitato il multi-tariffa in produzione prima dell'aggiornamento dell'app.

## Verifiche previste

La suite `tests/Feature/Parking/MultiTariffQuoteTest.php` copre:

- selezione automatica con una sola tariffa;
- richiesta di scelta con più tariffe;
- ricalcolo della tariffa selezionata;
- rifiuto di una tariffa appartenente a un'altra area;
- compatibilità tra tariffa generica e tipo veicolo;
- esclusione di tariffe disattivate, scadute o non ancora valide.

Comandi di verifica:

```bash
php artisan test tests/Feature/Parking/MultiTariffQuoteTest.php
php artisan route:list --path=sosta
php artisan route:list --path=api/mobile/parking
npm run build
```

Per l'app:

```bash
flutter analyze
flutter test test/features/parking/parking_quote_result_test.dart
```

## Limite intenzionale di questa fase

Il sistema distingue le alternative tramite nome e descrizione, ma non certifica ancora requisiti personali come la residenza. Una tariffa “Residenti” è quindi selezionabile, non ancora autorizzata tramite una verifica anagrafica.

Le regole di idoneità e le nuove tipologie oraria, giornaliera, settimanale e mensile restano livelli successivi, costruibili sulla selezione introdotta qui.
