netgescon-day0/app/Http/Controllers/Condomino/LetturaAcquaController.php

154 lines
6.0 KiB
PHP

<?php
namespace App\Http\Controllers\Condomino;
use App\Http\Controllers\Condomino\Concerns\ResolvesCondominoAccess;
use App\Http\Controllers\Controller;
use App\Models\StabileServizio;
use App\Models\StabileServizioLettura;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LetturaAcquaController extends Controller
{
use ResolvesCondominoAccess;
public function index(Request $request): View
{
/** @var User|null $user */
$user = Auth::user();
$unitaImmobiliari = $this->resolveUserUnita($user);
$unitaIds = $unitaImmobiliari->pluck('id')->filter()->map(fn($v) => (int) $v)->all();
$serviziAcqua = StabileServizio::query()
->where('tipo', 'acqua')
->whereIn('stabile_id', $unitaImmobiliari->pluck('stabile_id')->filter()->all())
->where('attivo', true)
->orderBy('stabile_id')
->orderBy('nome')
->get();
$serviziByUnita = [];
foreach ($unitaImmobiliari as $unita) {
$serviziByUnita[(int) $unita->id] = $serviziAcqua
->where('stabile_id', (int) $unita->stabile_id)
->values();
}
$query = StabileServizioLettura::query()
->with(['stabile', 'servizio', 'unitaImmobiliare'])
->whereIn('unita_immobiliare_id', $unitaIds)
->where('canale_acquisizione', 'portale_condomino')
->orderByDesc('periodo_al')
->orderByDesc('id');
if ($request->filled('unita_immobiliare_id')) {
$query->where('unita_immobiliare_id', (int) $request->input('unita_immobiliare_id'));
}
$letture = $query->paginate(20)->withQueryString();
return view('condomino.letture-acqua.index', [
'unitaImmobiliari' => $unitaImmobiliari,
'serviziByUnita' => $serviziByUnita,
'letture' => $letture,
]);
}
public function store(Request $request): RedirectResponse
{
/** @var User|null $user */
$user = Auth::user();
$validated = $request->validate([
'unita_immobiliare_id' => ['required', 'integer'],
'stabile_servizio_id' => ['required', 'integer'],
'totale_letto' => ['required', 'numeric', 'min:0'],
'data_lettura' => ['nullable', 'date'],
'foto' => ['nullable', 'image', 'max:8192'],
'note' => ['nullable', 'string', 'max:2000'],
]);
$unita = $this->resolveUserUnita($user)
->firstWhere('id', (int) $validated['unita_immobiliare_id']);
if (! $unita) {
return back()->withErrors([
'unita_immobiliare_id' => 'Unita immobiliare non accessibile per l\'utente autenticato.',
])->withInput();
}
$servizio = StabileServizio::query()
->where('id', (int) $validated['stabile_servizio_id'])
->where('stabile_id', (int) $unita->stabile_id)
->where('tipo', 'acqua')
->first();
if (! $servizio) {
return back()->withErrors([
'stabile_servizio_id' => 'Utenza acqua non valida per l\'unita selezionata.',
])->withInput();
}
$dataLettura = isset($validated['data_lettura'])
? Carbon::parse((string) $validated['data_lettura'])->toDateString()
: now()->toDateString();
$precedente = StabileServizioLettura::query()
->where('stabile_servizio_id', (int) $servizio->id)
->where('unita_immobiliare_id', (int) $unita->id)
->whereNotNull('lettura_fine')
->orderByDesc('periodo_al')
->orderByDesc('id')
->first();
$totaleLetto = (float) $validated['totale_letto'];
$letturaInizio = $precedente?->lettura_fine !== null ? (float) $precedente->lettura_fine : null;
$consumo = $letturaInizio !== null ? round($totaleLetto - $letturaInizio, 3) : null;
if ($consumo !== null && $consumo < 0) {
return back()->withErrors([
'totale_letto' => 'Il totale letto non puo essere inferiore alla lettura precedente (' . number_format($letturaInizio, 3, ',', '.') . ').',
])->withInput();
}
$fotoPath = null;
if ($request->hasFile('foto')) {
$fotoPath = $request->file('foto')?->store('letture-acqua', 'public');
}
$riferimento = 'autolettura-' . (int) ($user?->id ?? 0) . '-' . now()->format('YmdHis');
StabileServizioLettura::create([
'stabile_id' => (int) $unita->stabile_id,
'stabile_servizio_id' => (int) $servizio->id,
'unita_immobiliare_id' => (int) $unita->id,
'fornitore_id' => $servizio->fornitore_id,
'periodo_dal' => $precedente?->periodo_al,
'periodo_al' => $dataLettura,
'tipologia_lettura' => 'autolettura_utente',
'canale_acquisizione' => 'portale_condomino',
'riferimento_acquisizione' => $riferimento,
'lettura_inizio' => $letturaInizio,
'lettura_fine' => $totaleLetto,
'consumo_valore' => $consumo,
'consumo_unita' => 'mc',
'raw' => [
'foto_path' => $fotoPath,
'note' => trim((string) ($validated['note'] ?? '')),
'precedente_lettura_id' => $precedente?->id,
'precedente_totale' => $letturaInizio,
'delta_calcolato' => $consumo,
],
'created_by' => $user?->id,
]);
return redirect()->route('condomino.letture-acqua.index')
->with('success', 'Autolettura registrata correttamente.');
}
}