163 lines
5.8 KiB
PHP
163 lines
5.8 KiB
PHP
<?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;
|
|
}
|
|
}
|