} $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, ]; } }