netgescon-day0/app/Services/Consumi/ConsumiRiscaldamentoIngestionService.php

155 lines
6.2 KiB
PHP

<?php
namespace App\Services\Consumi;
use App\Models\FatturaElettronica;
use App\Models\StabileServizio;
use App\Models\StabileServizioLettura;
use Illuminate\Support\Facades\Schema;
class ConsumiRiscaldamentoIngestionService
{
/**
* @param array{codici?: array{cliente?: string|null, contratto?: string|null, pdr?: string|null, pod?: string|null}, pagamento?: array{scadenza?: string|null}, consumi?: array<int, array{dal?: string|null, al?: string|null, valore?: float|null, unita?: string|null, tipologia_lettura?: string|null}>} $parsed
* @return array{status: string, servizio_id?: int, created_letture?: int, updated_letture?: int, tickets?: int, message?: string}
*/
public function ingest(
FatturaElettronica $fattura,
array $parsed,
?int $voceSpesaId,
int $userId,
bool $createTicketOnMismatch = true,
?int $forceServizioId = null,
): array {
if (! Schema::hasTable('stabile_servizi') || ! Schema::hasTable('stabile_servizio_letture')) {
return ['status' => 'skipped', 'message' => 'Tabelle servizi/letture non presenti'];
}
$stabileId = (int) ($fattura->stabile_id ?: 0);
if ($stabileId <= 0) {
return ['status' => 'error', 'message' => 'Stabile non disponibile'];
}
$codici = is_array($parsed['codici'] ?? null) ? $parsed['codici'] : [];
$consumi = is_array($parsed['consumi'] ?? null) ? $parsed['consumi'] : [];
$pagamento = is_array($parsed['pagamento'] ?? null) ? $parsed['pagamento'] : [];
$pdr = is_string($codici['pdr'] ?? null) ? trim((string) $codici['pdr']) : '';
$pod = is_string($codici['pod'] ?? null) ? trim((string) $codici['pod']) : '';
$cliente = is_string($codici['cliente'] ?? null) ? trim((string) $codici['cliente']) : '';
$contratto = is_string($codici['contratto'] ?? null) ? trim((string) $codici['contratto']) : '';
$tipoServizio = 'riscaldamento';
$unitaMisura = 'mc';
$identificativo = $pdr ?: $pod;
if ($pod !== '') {
$tipoServizio = 'riscaldamento'; // Rimaniamo su riscaldamento come contenitore per riscaldamento/utenze
$unitaMisura = 'kWh';
}
$servizio = null;
if ($forceServizioId) {
$servizio = StabileServizio::query()
->where('stabile_id', $stabileId)
->where('tipo', 'riscaldamento')
->whereKey($forceServizioId)
->first();
}
if (! $servizio) {
// Cerca per PDR/POD o codici
$servizio = StabileServizio::query()
->where('stabile_id', $stabileId)
->where('tipo', 'riscaldamento')
->where(function ($q) use ($pdr, $pod, $cliente, $contratto) {
if ($pdr !== '') $q->orWhere('codice_utenza', $pdr)->orWhere('contatore_matricola', $pdr);
if ($pod !== '') $q->orWhere('codice_utenza', $pod)->orWhere('contatore_matricola', $pod);
if ($cliente !== '') $q->orWhere('codice_cliente', $cliente);
if ($contratto !== '') $q->orWhere('codice_contratto', $contratto);
})
->first();
}
if (! $servizio) {
// Crea un nuovo servizio di riscaldamento
$name = 'Riscaldamento / Utenza';
if ($identificativo !== '') {
$name .= ' - ' . $identificativo;
}
$servizio = new StabileServizio([
'stabile_id' => $stabileId,
'tipo' => 'riscaldamento',
'nome' => $name,
'attivo' => true,
]);
}
if ((int) ($fattura->fornitore_id ?? 0) > 0 && ! $servizio->fornitore_id) {
$servizio->fornitore_id = (int) $fattura->fornitore_id;
}
if ($voceSpesaId && $voceSpesaId > 0) {
$servizio->voce_spesa_id = $voceSpesaId;
}
if ($pdr !== '' && empty($servizio->codice_utenza)) $servizio->codice_utenza = $pdr;
if ($pod !== '' && empty($servizio->codice_utenza)) $servizio->codice_utenza = $pod;
if ($cliente !== '' && empty($servizio->codice_cliente)) $servizio->codice_cliente = $cliente;
if ($contratto !== '' && empty($servizio->codice_contratto)) $servizio->codice_contratto = $contratto;
if ($identificativo !== '' && empty($servizio->contatore_matricola)) $servizio->contatore_matricola = $identificativo;
$servizio->save();
$created = 0;
$updated = 0;
foreach ($consumi as $c) {
$dal = $c['dal'] ?? null;
$al = $c['al'] ?? null;
$val = $c['valore'] ?? null;
$uni = $c['unita'] ?? $unitaMisura;
$lettura = StabileServizioLettura::query()->firstOrNew([
'stabile_id' => $stabileId,
'stabile_servizio_id' => (int) $servizio->id,
'fattura_elettronica_id' => (int) $fattura->id,
'periodo_dal' => $dal,
'periodo_al' => $al,
]);
$isNew = ! $lettura->exists;
$lettura->fill([
'fornitore_id' => (int) ($fattura->fornitore_id ?: 0) ?: null,
'voce_spesa_id' => $voceSpesaId ?: ($servizio->voce_spesa_id ?: null),
'tipologia_lettura' => $c['tipologia_lettura'] ?? 'rilevata',
'consumo_valore' => $val,
'consumo_unita' => $uni,
'importo_totale' => is_numeric($fattura->totale) ? (float) $fattura->totale : null,
'raw' => [
'source' => 'pdf_ocr_gas_luce',
'codici' => $codici,
'pagamento' => $pagamento,
'consumo' => $c,
],
'created_by' => $userId > 0 ? $userId : null,
]);
$lettura->save();
if ($isNew) {
$created++;
} else {
$updated++;
}
}
return [
'status' => 'ok',
'servizio_id' => (int) $servizio->id,
'created_letture' => $created,
'updated_letture' => $updated,
'tickets' => 0,
];
}
}