netgescon-day0/app/Http/Controllers/PublicAccess/WaterReadingRequestController.php

198 lines
8.4 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\PublicAccess;
use App\Http\Controllers\Controller;
use App\Models\StabileServizio;
use App\Models\StabileServizioLettura;
use App\Models\UnitaImmobiliare;
use App\Services\Support\TicketAttachmentUploadService;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
class WaterReadingRequestController extends Controller
{
public function show(Request $request): View
{
$servizioId = (int) $request->integer('servizio');
$unitaId = (int) $request->integer('unita');
$requestId = (int) $request->integer('request');
$servizio = StabileServizio::query()
->where('id', $servizioId)
->where('tipo', 'acqua')
->firstOrFail();
$unita = UnitaImmobiliare::query()
->with('stabile:id,denominazione,codice_stabile')
->where('id', $unitaId)
->where('stabile_id', (int) $servizio->stabile_id)
->firstOrFail();
$pendingRequest = $requestId > 0
? StabileServizioLettura::query()
->where('id', $requestId)
->where('stabile_servizio_id', $servizioId)
->where('unita_immobiliare_id', $unitaId)
->first()
: null;
$previous = StabileServizioLettura::query()
->where('stabile_servizio_id', $servizioId)
->where('unita_immobiliare_id', $unitaId)
->whereNotNull('lettura_fine')
->when($pendingRequest, fn($query) => $query->where('id', '!=', (int) $pendingRequest->id))
->orderByDesc('periodo_al')
->orderByDesc('id')
->first();
$submitUrl = URL::temporarySignedRoute('public.water-reading.store', now()->addDays(30), array_filter([
'servizio' => $servizioId,
'unita' => $unitaId,
'request' => $pendingRequest?->id,
]));
return view('public.water-reading.show', [
'servizio' => $servizio,
'unita' => $unita,
'pendingRequest' => $pendingRequest,
'previous' => $previous,
'submitUrl' => $submitUrl,
]);
}
public function store(Request $request): RedirectResponse
{
$servizioId = (int) $request->integer('servizio');
$unitaId = (int) $request->integer('unita');
$requestId = (int) $request->integer('request');
$servizio = StabileServizio::query()
->where('id', $servizioId)
->where('tipo', 'acqua')
->firstOrFail();
$unita = UnitaImmobiliare::query()
->where('id', $unitaId)
->where('stabile_id', (int) $servizio->stabile_id)
->firstOrFail();
$validated = $request->validate([
'lettura_attuale' => ['required', 'numeric', 'min:0'],
'data_lettura' => ['nullable', 'date'],
'rilevatore_nome' => ['required', 'string', 'max:255'],
'rilevatore_contatto' => ['nullable', 'string', 'max:255'],
'note' => ['nullable', 'string', 'max:2000'],
'foto_1' => ['nullable', 'image', 'max:8192'],
'foto_2' => ['nullable', 'image', 'max:8192'],
]);
$pendingRequest = $requestId > 0
? StabileServizioLettura::query()
->where('id', $requestId)
->where('stabile_servizio_id', $servizioId)
->where('unita_immobiliare_id', $unitaId)
->first()
: null;
$previous = StabileServizioLettura::query()
->where('stabile_servizio_id', $servizioId)
->where('unita_immobiliare_id', $unitaId)
->whereNotNull('lettura_fine')
->when($pendingRequest, fn($query) => $query->where('id', '!=', (int) $pendingRequest->id))
->orderByDesc('periodo_al')
->orderByDesc('id')
->first();
$letturaInizio = $previous?->lettura_fine !== null ? (float) $previous->lettura_fine : null;
$letturaFine = (float) $validated['lettura_attuale'];
$consumo = $letturaInizio !== null ? round($letturaFine - $letturaInizio, 3) : null;
if ($consumo !== null && $consumo < 0) {
return back()->withErrors([
'lettura_attuale' => 'La lettura attuale non puo essere inferiore a quella precedente.',
])->withInput();
}
$photoAssets = [];
foreach (['foto_1', 'foto_2'] as $photoField) {
if ($request->hasFile($photoField)) {
$file = $request->file($photoField);
if (! $file) {
continue;
}
$stored = app(TicketAttachmentUploadService::class)->store(
$file,
'letture-acqua-public/' . $servizio->id . '/' . $unita->id,
[
'stored_basename' => 'water-reading-' . $servizio->id . '-' . $unita->id . '-' . $photoField,
]
);
$photoAssets[] = [
'field' => $photoField,
'path' => $stored['path'],
'original_name' => $stored['original_name'] ?? null,
'source_original_name' => $stored['source_original_name'] ?? null,
'mime' => $stored['mime'] ?? null,
'size' => $stored['size'] ?? null,
'metadata' => is_array($stored['metadata'] ?? null) ? $stored['metadata'] : [],
];
}
}
$photoPaths = array_values(array_filter(array_map(
static fn(array $photo): ?string => is_string($photo['path'] ?? null) ? $photo['path'] : null,
$photoAssets
)));
$payload = [
'stabile_id' => (int) $servizio->stabile_id,
'stabile_servizio_id' => (int) $servizio->id,
'unita_immobiliare_id' => (int) $unita->id,
'fornitore_id' => $servizio->fornitore_id,
'periodo_dal' => $previous?->periodo_al,
'periodo_al' => isset($validated['data_lettura']) ? Carbon::parse((string) $validated['data_lettura'])->toDateString() : now()->toDateString(),
'tipologia_lettura' => 'autolettura_link_pubblico',
'canale_acquisizione' => 'portale_pubblico',
'workflow_stato' => 'ricevuta',
'riferimento_acquisizione' => $pendingRequest?->riferimento_acquisizione ?: ('PUBREAD:' . (int) $servizio->id . ':' . (int) $unita->id . ':' . now()->format('YmdHis')),
'rilevatore_tipo' => 'link_pubblico',
'rilevatore_nome' => trim((string) $validated['rilevatore_nome']),
'lettura_precedente_valore' => $letturaInizio,
'lettura_inizio' => $letturaInizio,
'lettura_fine' => $letturaFine,
'lettura_foto_path' => $photoPaths[0] ?? null,
'lettura_foto_original_name' => $photoAssets[0]['original_name'] ?? null,
'lettura_foto_metadata' => [
'photos' => $photoAssets,
'paths' => $photoPaths,
'contact' => trim((string) ($validated['rilevatore_contatto'] ?? '')),
'note' => trim((string) ($validated['note'] ?? '')),
],
'consumo_valore' => $consumo,
'consumo_unita' => 'mc',
'raw' => [
'source' => 'public_water_reading_link',
'contact' => trim((string) ($validated['rilevatore_contatto'] ?? '')),
'note' => trim((string) ($validated['note'] ?? '')),
'photo_assets' => $photoAssets,
'photo_paths' => $photoPaths,
'request_id' => $pendingRequest?->id,
],
];
if ($pendingRequest) {
$pendingRequest->fill($payload);
$pendingRequest->save();
} else {
StabileServizioLettura::query()->create($payload);
}
return redirect()->back()->with('success', 'Lettura acqua inviata correttamente.');
}
}