netgescon-day0/app/Models/ContoBancario.php

192 lines
5.0 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* MODEL: ContoBancario
*
* Gestisce i conti bancari del condominio
* Source: Anagr_casse da Gescon + estensioni Laravel
*/
class ContoBancario extends Model
{
use HasFactory;
protected $table = 'conti_bancari';
protected $fillable = [
'tenant_id',
'id_cassa_gescon',
'codice',
'descrizione',
'saldo_iniziale',
'tipo_conto',
'banca',
'numero_conto',
'iban',
'swift',
'saldo_corrente',
'ultima_riconciliazione',
'attivo',
'formato_file',
'configurazione_import',
'metadati_gescon'
];
protected $casts = [
'saldo_iniziale' => 'decimal:4',
'saldo_corrente' => 'decimal:4',
'ultima_riconciliazione' => 'date',
'attivo' => 'boolean',
'configurazione_import' => 'array',
'metadati_gescon' => 'array'
];
/**
* Incassi associati a questo conto
*/
public function incassi(): HasMany
{
return $this->hasMany(Incasso::class, 'conto_bancario_id');
}
/**
* Movimenti bancari di questo conto
*/
public function movimentiBancari(): HasMany
{
return $this->hasMany(MovimentoBancario::class, 'conto_bancario_id');
}
/**
* Operazioni contabili associate
*/
public function operazioni(): HasMany
{
return $this->hasMany(OperazioneContabile::class, 'conto_bancario_id');
}
/**
* Scope per tenant
*/
public function scopeForTenant($query, string $tenantId)
{
return $query->where('tenant_id', $tenantId);
}
/**
* Scope per conti attivi
*/
public function scopeAttivi($query)
{
return $query->where('attivo', true);
}
/**
* Scope per tipo conto
*/
public function scopeTipo($query, string $tipo)
{
return $query->where('tipo_conto', $tipo);
}
/**
* Calcola saldo corrente dai movimenti
*/
public function calcolaSaldoCorrente(): float
{
$entrate = $this->movimentiBancari()
->where('tipo_movimento', 'entrata')
->sum('importo');
$uscite = $this->movimentiBancari()
->where('tipo_movimento', 'uscita')
->sum('importo');
return $this->saldo_iniziale + $entrate - $uscite;
}
/**
* Verifica se supporta import automatico
*/
public function supportaImportAutomatico(): bool
{
return !empty($this->formato_file) && !empty($this->configurazione_import);
}
/**
* Statistiche riconciliazione
*/
public function statisticheRiconciliazione(): array
{
$movimenti = $this->movimentiBancari();
return [
'totale_movimenti' => $movimenti->count(),
'riconciliati_automatici' => $movimenti->where('stato_riconciliazione', 'automatica')->count(),
'riconciliati_manuali' => $movimenti->where('stato_riconciliazione', 'manuale')->count(),
'sospesi' => $movimenti->where('stato_riconciliazione', 'sospesa')->count(),
'anomali' => $movimenti->where('stato_riconciliazione', 'anomala')->count(),
'percentuale_riconciliazione' => $movimenti->count() > 0
? round(($movimenti->whereIn('stato_riconciliazione', ['automatica', 'manuale'])->count() / $movimenti->count()) * 100, 2)
: 0
];
}
/**
* Estrae configurazione per import file
*/
public function getConfigurazioneImport(): array
{
$default = [
'formato' => $this->formato_file,
'encoding' => 'UTF-8',
'separatore' => ';',
'pattern_data' => 'd/m/Y',
'skip_lines' => 0
];
return array_merge($default, $this->configurazione_import ?? []);
}
/**
* Aggiorna ultima riconciliazione
*/
public function aggiornaUltimaRiconciliazione(): void
{
$this->update(['ultima_riconciliazione' => today()]);
}
/**
* Formatta saldo per display
*/
public function getSaldoFormattato(): string
{
return '€ ' . number_format($this->saldo_corrente, 2, ',', '.');
}
/**
* Info conto per dashboard
*/
public function getInfoConto(): array
{
return [
'codice' => $this->codice,
'descrizione' => $this->descrizione,
'banca' => $this->banca,
'numero_conto' => $this->numero_conto,
'saldo_corrente' => $this->saldo_corrente,
'saldo_formattato' => $this->getSaldoFormattato(),
'tipo_conto' => $this->tipo_conto,
'attivo' => $this->attivo,
'ultima_riconciliazione' => $this->ultima_riconciliazione?->format('d/m/Y'),
'statistiche' => $this->statisticheRiconciliazione()
];
}
}