netgescon-day0/app/Console/Commands/GoogleSyncFornitoriRubricaCommand.php

163 lines
5.8 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use App\Models\Fornitore;
use App\Models\RubricaUniversale;
use App\Support\PhoneNumber;
use Illuminate\Console\Command;
class GoogleSyncFornitoriRubricaCommand extends Command
{
protected $signature = 'google:sync-fornitori-rubrica
{--fornitore-id=* : Limita sync a uno o piu fornitori}
{--dry-run : Mostra modifiche senza salvare}';
protected $description = 'Sincronizza i fornitori sulla Rubrica Universale e collega rubrica_id mancante.';
public function handle(): int
{
$dryRun = (bool) $this->option('dry-run');
$filterIds = collect((array) $this->option('fornitore-id'))
->map(fn($v) => (int) $v)
->filter(fn(int $v) => $v > 0)
->values()
->all();
$query = Fornitore::query();
if ($filterIds !== []) {
$query->whereIn('id', $filterIds);
}
$fornitori = $query->get();
if ($fornitori->isEmpty()) {
$this->warn('Nessun fornitore trovato per i filtri richiesti.');
return self::SUCCESS;
}
$created = 0;
$updated = 0;
$linked = 0;
$skipped = 0;
foreach ($fornitori as $fornitore) {
$target = null;
if ((int) ($fornitore->rubrica_id ?? 0) > 0) {
$target = RubricaUniversale::query()->find((int) $fornitore->rubrica_id);
}
if (! $target) {
$target = $this->findRubricaCandidate($fornitore);
}
$payload = [
'tipo_contatto' => 'persona_giuridica',
'ragione_sociale' => $fornitore->ragione_sociale ?: trim(($fornitore->nome ?: '') . ' ' . ($fornitore->cognome ?: '')),
'nome' => $fornitore->nome,
'cognome' => $fornitore->cognome,
'partita_iva' => $fornitore->partita_iva,
'codice_fiscale' => $fornitore->codice_fiscale,
'indirizzo' => $fornitore->indirizzo,
'civico' => $fornitore->civico,
'cap' => $fornitore->cap,
'citta' => $fornitore->citta,
'provincia' => $fornitore->provincia,
'nazione' => $fornitore->nazione,
'email' => $fornitore->email,
'pec' => $fornitore->pec,
'telefono_ufficio' => $this->normalizePhone($fornitore->telefono),
'telefono_cellulare' => $this->normalizePhone($fornitore->cellulare),
'sito_web' => $fornitore->sito_web,
'note' => $fornitore->note,
'categoria' => 'fornitore',
'stato' => 'attivo',
'data_ultima_modifica' => now()->toDateString(),
];
if (! $target) {
if ($dryRun) {
$this->line("[DRY] Crea rubrica per fornitore #{$fornitore->id}");
} else {
$target = RubricaUniversale::query()->create(array_merge($payload, [
'data_inserimento' => now()->toDateString(),
]));
$created++;
}
} else {
$dirty = $this->isDirtyPayload($target, $payload);
if (! $dirty) {
$skipped++;
} elseif ($dryRun) {
$this->line("[DRY] Aggiorna rubrica #{$target->id} da fornitore #{$fornitore->id}");
} else {
$target->fill($payload);
$target->save();
$updated++;
}
}
if (! $dryRun && $target && (int) ($fornitore->rubrica_id ?? 0) !== (int) $target->id) {
$fornitore->rubrica_id = (int) $target->id;
$fornitore->save();
$linked++;
}
}
$this->info("Sync fornitori completato: creati {$created}, aggiornati {$updated}, collegati {$linked}, invariati {$skipped}." . ($dryRun ? ' (dry-run)' : ''));
return self::SUCCESS;
}
private function findRubricaCandidate(Fornitore $fornitore): ?RubricaUniversale
{
$query = RubricaUniversale::query()->where('categoria', 'fornitore');
if (! empty($fornitore->partita_iva)) {
$match = (clone $query)->where('partita_iva', $fornitore->partita_iva)->first();
if ($match) {
return $match;
}
}
if (! empty($fornitore->codice_fiscale)) {
$match = (clone $query)->where('codice_fiscale', $fornitore->codice_fiscale)->first();
if ($match) {
return $match;
}
}
if (! empty($fornitore->email)) {
$match = (clone $query)->where('email', $fornitore->email)->first();
if ($match) {
return $match;
}
}
if (! empty($fornitore->ragione_sociale)) {
return (clone $query)->where('ragione_sociale', $fornitore->ragione_sociale)->first();
}
return null;
}
private function normalizePhone(?string $phone): ?string
{
if (! is_string($phone) || trim($phone) === '') {
return null;
}
return PhoneNumber::toE164Italy($phone);
}
private function isDirtyPayload(RubricaUniversale $rubrica, array $payload): bool
{
foreach ($payload as $key => $value) {
if ((string) ($rubrica->{$key} ?? '') !== (string) ($value ?? '')) {
return true;
}
}
return false;
}
}