netgescon-day0/app/Services/Arera/AreraFornitoreClassifier.php

166 lines
6.2 KiB
PHP
Executable File

<?php
namespace App\Services\Arera;
use App\Models\AreraOperatore;
use App\Models\Fornitore;
use App\Models\FornitoreStabileImpostazione;
use App\Models\RubricaUniversale;
use App\Models\VoceSpesa;
class AreraFornitoreClassifier
{
public function classifyFornitoreByVat(Fornitore $fornitore, ?string $vat = null): ?AreraOperatore
{
$piva = $this->normalizeVat($vat ?: (string) ($fornitore->partita_iva ?? ''));
if ($piva === '') {
return null;
}
$operatore = AreraOperatore::query()
->with('settori')
->where('partita_iva_normalizzata', $piva)
->first();
if (! $operatore instanceof AreraOperatore) {
return null;
}
$this->applyAreraToFornitore($fornitore, $operatore);
return $operatore;
}
public function applyDefaultStableMapping(Fornitore $fornitore, int $stabileId): void
{
if ($stabileId <= 0 || ! (bool) data_get($fornitore->operational_config_safe, 'service_supplier')) {
return;
}
$settori = array_map('mb_strtolower', (array) data_get($fornitore->operational_config_safe, 'arera_settori', []));
$isGas = collect($settori)->contains(fn(string $settore): bool => str_contains($settore, 'gas'));
if (! $isGas) {
return;
}
$voce = VoceSpesa::query()
->where('stabile_id', $stabileId)
->where('attiva', true)
->where(function ($query): void {
$query->where('tipo_gestione', 'riscaldamento')
->orWhere('tipo', 'riscaldamento');
})
->where(function ($query): void {
$query->where('descrizione', 'like', '%Combust%')
->orWhere('descrizione', 'like', '%Gas%')
->orWhere('descrizione', 'like', '%Metano%');
})
->orderByRaw("CASE WHEN descrizione LIKE '%Combust%' THEN 0 ELSE 1 END")
->orderBy('id')
->first();
if (! $voce instanceof VoceSpesa) {
return;
}
$row = FornitoreStabileImpostazione::query()->firstOrNew([
'stabile_id' => $stabileId,
'fornitore_id' => (int) $fornitore->id,
]);
$meta = is_array($row->meta ?? null) ? $row->meta : [];
$meta['service_supplier'] = true;
$meta['service_supplier_kind'] = 'gas';
$meta['service_type'] = 'riscaldamento';
$meta['arera_operatore_id'] = data_get($fornitore->operational_config_safe, 'arera_operatore_id');
$meta['arera_settori'] = data_get($fornitore->operational_config_safe, 'arera_settori', []);
$meta['voce_spesa_auto_reason'] = 'arera_gas_riscaldamento';
if (empty($row->voce_spesa_default_id)) {
$row->voce_spesa_default_id = (int) $voce->id;
}
$row->meta = $meta;
$row->save();
}
public function applyAreraToFornitore(Fornitore $fornitore, AreraOperatore $operatore): void
{
$config = is_array($fornitore->operational_config ?? null) ? $fornitore->operational_config : [];
$config['service_supplier'] = true;
$config['service_supplier_source'] = 'arera';
$config['arera_operatore_id'] = (int) $operatore->id;
$config['arera_id_soggetto'] = $operatore->id_soggetto;
$config['arera_settori'] = $operatore->settori->pluck('nome')->values()->all();
$config['skip_fe_rows_reason'] = 'fornitore_servizi_utenze_catalogo_arera';
$tags = $this->decodeTags($fornitore->tags ?? null);
$tags[] = 'arera';
$tags[] = 'servizi_utenze';
$fornitore->escludi_righe_fe = true;
$fornitore->operational_config = $config;
$fornitore->tags = json_encode(array_values(array_unique(array_filter($tags))), JSON_UNESCAPED_SLASHES);
if (empty($fornitore->sito_web) && ! empty($operatore->sito_internet)) {
$fornitore->sito_web = $operatore->sito_internet;
}
if (empty($fornitore->ragione_sociale) && ! empty($operatore->societa)) {
$fornitore->ragione_sociale = $operatore->societa;
}
foreach ([
'indirizzo' => 'sede_legale_indirizzo',
'cap' => 'sede_legale_cap',
'citta' => 'sede_legale_citta',
'provincia' => 'sede_legale_provincia',
] as $fornitoreField => $areraField) {
if (empty($fornitore->{$fornitoreField}) && ! empty($operatore->{$areraField})) {
$fornitore->{$fornitoreField} = $operatore->{$areraField};
}
}
$fornitore->save();
if ((int) ($fornitore->rubrica_id ?? 0) > 0) {
$rubrica = RubricaUniversale::query()->find((int) $fornitore->rubrica_id);
if ($rubrica instanceof RubricaUniversale) {
if (empty($rubrica->sito_web) && ! empty($operatore->sito_internet)) {
$rubrica->sito_web = $operatore->sito_internet;
}
if (empty($rubrica->ragione_sociale) && ! empty($operatore->societa)) {
$rubrica->ragione_sociale = $operatore->societa;
}
$rubrica->categoria = $rubrica->categoria ?: 'fornitore';
$rubrica->tipo_contatto = $rubrica->tipo_contatto ?: 'persona_giuridica';
$rubrica->stato = $rubrica->stato ?: 'attivo';
$rubrica->save();
}
}
}
private function normalizeVat(string $value): string
{
return preg_replace('/\D+/', '', $value) ?? '';
}
/** @return list<string> */
private function decodeTags(mixed $value): array
{
if (is_array($value)) {
return array_values(array_map('strval', $value));
}
if (! is_string($value) || trim($value) === '') {
return [];
}
$decoded = json_decode($value, true);
if (is_array($decoded)) {
return array_values(array_map('strval', $decoded));
}
return array_values(array_filter(array_map('trim', preg_split('/[,;]+/', $value) ?: [])));
}
}