176 lines
6.1 KiB
PHP
176 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\GestioneContabile;
|
|
use App\Models\User;
|
|
use App\Modules\Contabilita\Models\Registrazione;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class GesconSyncOperazioniPrimaNota extends Command
|
|
{
|
|
protected $signature = 'gescon:sync-operazioni-prima-nota
|
|
{--stabile-id= : ID stabile NetGescon}
|
|
{--year= : Anno (YYYY)}
|
|
{--tipo=all : all|ordinaria|straordinaria|riscaldamento}
|
|
{--dry : Simula senza scrivere}';
|
|
|
|
protected $description = 'Sincronizza operazioni legacy in contabilita_registrazioni (Prima Nota), con upsert idempotente per external_reference.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$stabileId = (int) ($this->option('stabile-id') ?? 0);
|
|
if ($stabileId <= 0) {
|
|
$this->error('Serve --stabile-id valido.');
|
|
return 1;
|
|
}
|
|
|
|
$yearOpt = $this->option('year');
|
|
$year = is_numeric($yearOpt) ? (int) $yearOpt : null;
|
|
|
|
$tipo = strtolower((string) ($this->option('tipo') ?? 'all'));
|
|
if (! in_array($tipo, ['all', 'ordinaria', 'straordinaria', 'riscaldamento'], true)) {
|
|
$this->error('Valore --tipo non valido. Usa all|ordinaria|straordinaria|riscaldamento');
|
|
return 1;
|
|
}
|
|
|
|
$dry = (bool) $this->option('dry');
|
|
|
|
$systemUserId = (int) (User::query()->orderBy('id')->value('id') ?? 0);
|
|
|
|
$query = DB::connection('gescon_import')->table('operazioni');
|
|
|
|
if ($year) {
|
|
$query->whereYear('dt_spe', $year);
|
|
}
|
|
|
|
if ($tipo !== 'all') {
|
|
$gestioneCode = match ($tipo) {
|
|
'ordinaria' => 'O',
|
|
'straordinaria' => 'S',
|
|
'riscaldamento' => 'R',
|
|
default => null,
|
|
};
|
|
if ($gestioneCode) {
|
|
$query->where('gestione', $gestioneCode);
|
|
}
|
|
}
|
|
|
|
$rows = $query
|
|
->orderBy('dt_spe')
|
|
->orderBy('id_operaz')
|
|
->get([
|
|
'id_operaz',
|
|
'dt_spe',
|
|
'benef',
|
|
'num_fat',
|
|
'gestione',
|
|
'n_stra',
|
|
]);
|
|
|
|
$created = 0;
|
|
$updated = 0;
|
|
$unchanged = 0;
|
|
|
|
foreach ($rows as $row) {
|
|
$legacyId = (int) ($row->id_operaz ?? 0);
|
|
if ($legacyId <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$dataReg = ! empty($row->dt_spe) ? (string) $row->dt_spe : now()->toDateString();
|
|
$anno = (int) substr($dataReg, 0, 4);
|
|
|
|
$tipoGestione = match (strtoupper((string) ($row->gestione ?? 'O'))) {
|
|
'S' => 'straordinaria',
|
|
'R' => 'riscaldamento',
|
|
default => 'ordinaria',
|
|
};
|
|
|
|
$gestioneQuery = GestioneContabile::query()
|
|
->where('stabile_id', $stabileId)
|
|
->where('anno_gestione', $anno)
|
|
->where('tipo_gestione', $tipoGestione);
|
|
|
|
if ($tipoGestione === 'straordinaria') {
|
|
$nStra = is_numeric($row->n_stra ?? null) ? (int) $row->n_stra : null;
|
|
if ($nStra && $nStra > 0) {
|
|
$gestioneQuery->where('numero_straordinaria', $nStra);
|
|
}
|
|
}
|
|
|
|
$gestione = $gestioneQuery
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
$resolvedGestioneId = $gestione
|
|
? Registrazione::resolveGestioneIdOrDefault((int) $gestione->id, $stabileId, $dataReg)
|
|
: Registrazione::resolveGestioneIdOrDefault(0, $stabileId, $dataReg);
|
|
|
|
$payload = [
|
|
'stabile_id' => $stabileId,
|
|
'gestione_id' => $resolvedGestioneId,
|
|
'data_registrazione' => $dataReg,
|
|
'entry_date' => $dataReg,
|
|
'description' => trim((string) ($row->benef ?? 'Operazione legacy #' . $legacyId)),
|
|
'document_type' => 'LEGACY_GESCON',
|
|
'document_number' => trim((string) ($row->num_fat ?? '')) !== ''
|
|
? trim((string) $row->num_fat)
|
|
: ('LEG-' . $legacyId),
|
|
'external_reference' => 'OPERAZIONE_LEGACY:' . $legacyId,
|
|
'status' => 'confirmed',
|
|
];
|
|
|
|
if (Schema::hasColumn('contabilita_registrazioni', 'user_id')) {
|
|
$payload['user_id'] = $systemUserId > 0 ? $systemUserId : null;
|
|
}
|
|
if (Schema::hasColumn('contabilita_registrazioni', 'created_by')) {
|
|
$payload['created_by'] = $systemUserId > 0 ? $systemUserId : null;
|
|
}
|
|
if (Schema::hasColumn('contabilita_registrazioni', 'updated_by')) {
|
|
$payload['updated_by'] = $systemUserId > 0 ? $systemUserId : null;
|
|
}
|
|
|
|
$existing = Registrazione::query()
|
|
->where('stabile_id', $stabileId)
|
|
->where('external_reference', $payload['external_reference'])
|
|
->first();
|
|
|
|
if (! $existing) {
|
|
if (! $dry) {
|
|
Registrazione::query()->create($payload);
|
|
}
|
|
$created++;
|
|
continue;
|
|
}
|
|
|
|
$dirty = false;
|
|
foreach ($payload as $field => $value) {
|
|
if ((string) ($existing->{$field} ?? '') !== (string) ($value ?? '')) {
|
|
$existing->{$field} = $value;
|
|
$dirty = true;
|
|
}
|
|
}
|
|
|
|
if (! $dry && $dirty) {
|
|
if (empty($existing->protocol) || empty($existing->protocollo_completo)) {
|
|
$existing->applyAutoProtocols();
|
|
}
|
|
$existing->save();
|
|
}
|
|
|
|
if ($dirty) {
|
|
$updated++;
|
|
} else {
|
|
$unchanged++;
|
|
}
|
|
}
|
|
|
|
$this->info('Sync completato: creati=' . $created . ' aggiornati=' . $updated . ' invariati=' . $unchanged . ($dry ? ' (DRY-RUN)' : ''));
|
|
|
|
return 0;
|
|
}
|
|
}
|