netgescon-day0/app/Modules/Contabilita/Models/MovimentoBanca.php

230 lines
6.8 KiB
PHP
Executable File

<?php
namespace App\Modules\Contabilita\Models;
use App\Models\GestioneContabile;
use App\Models\DatiBancari;
use Illuminate\Database\Eloquent\Model;
class MovimentoBanca extends Model
{
protected static ?array $cleaningConfigCache = null;
protected $table = 'contabilita_movimenti_banca';
protected $fillable = [
'stabile_id',
'conto_id',
'gestione_id',
'iban',
'data',
'valuta',
'descrizione',
'descrizione_estesa',
'importo',
'causale',
'source_file',
'raw_line',
'row_hash',
'da_confermare',
'match_data',
'rubrica_mittente_id',
'rubrica_beneficiario_id',
'fornitore_id',
'registrazione_id',
];
protected $casts = [
'data' => 'date',
'valuta' => 'date',
'importo' => 'decimal:2',
'da_confermare' => 'boolean',
'match_data' => 'array',
];
public function getDescrizioneEstesaPulitaAttribute(): ?string
{
$raw = $this->descrizione_estesa ?? $this->descrizione;
if (! is_string($raw)) {
return null;
}
$text = trim($raw);
if ($text === '') {
return null;
}
if (is_array($this->match_data ?? null) && ! empty($this->match_data['descrizione_base'])) {
$base = trim((string) $this->match_data['descrizione_base']);
if ($base !== '') {
$text = $base . ' ' . $text;
}
}
$text = $this->applyCleaningRules($text);
$text = preg_replace('/\s{2,}/', ' ', $text) ?? $text;
$text = trim($text, " \t\n\r\0\x0B|-");
return $text !== '' ? $text : null;
}
public function getDettaglioEstrattoAttribute(): array
{
$rawText = $this->descrizione_estesa ?? $this->descrizione ?? '';
$text = trim($rawText);
$commissioni = '';
$pos = -1;
foreach (['COMM', 'SPESE', 'TRN', 'COMMISSIONI', 'COMMISSIONE'] as $key) {
$p = stripos($text, $key);
if ($p !== false && ($pos === -1 || $p < $pos)) {
$pos = $p;
}
}
if ($pos !== -1) {
$commissioni = trim(substr($text, $pos));
$text = trim(substr($text, 0, $pos));
}
$bankPrefixes = [
'BONIFICO A VOSTRO FAVORE BONIFICO SEPA DA',
'BONIFICO A VOSTRO FAVORE BONIFICO SEPA',
'BONIFICO SEPA A VOSTRO FAVORE DA',
'BONIFICO SEPA A VOSTRO FAVORE',
'BONIFICO A VOSTRO FAVORE DA',
'BONIFICO A VOSTRO FAVORE',
'BONIFICO SEPA DA',
'BONIFICO SEPA',
'BONIFICO DA',
'BONIFICO ESEGUITO DA',
'ADDEBITO CORRISPETTIVI',
'GIROCONTO DA',
'GIROCONTO',
'DISPOSIZIONE DI PAGAMENTO DA',
'DISPOSIZIONE DI PAGAMENTO',
'PAGAMENTO CBILL',
'PAGAMENTO PAGOPA',
'VERSAMENTO DI CASSA',
'VERSAMENTO DA',
'VERSAMENTO',
'PRELEVAMENTO DA',
'PRELEVAMENTO',
'PAGAMENTO CON CARTA',
'PAGAMENTO POS',
'ADDEBITO DISPOSIZIONE SEPA',
'ADDEBITO SEPA',
];
$messaggioBanca = '';
$messaggioCliente = $text;
foreach ($bankPrefixes as $prefix) {
if (stripos($text, $prefix) === 0) {
$messaggioBanca = $prefix;
$messaggioCliente = trim(substr($text, strlen($prefix)));
break;
}
}
if (empty($messaggioBanca) && !empty($this->causale)) {
$messaggioBanca = $this->causale;
}
$cbillCode = null;
if (preg_match('/(?:CBILL|PAGOPA|IUV|AVVISO|CODICE\s*AVVISO)\s*:?\s*(\d{10,20})/i', $rawText, $cbillMatches)) {
$cbillCode = $cbillMatches[1];
}
$abi = null;
if (!empty($this->raw_line)) {
$parts = explode(';', $this->raw_line);
if (count($parts) >= 2) {
$last = trim(end($parts));
if (preg_match('/^[a-zA-Z0-9]{3,5}$/', $last)) {
$abi = $last;
}
}
}
if (!$abi && is_array($this->match_data) && !empty($this->match_data['cod_abi'])) {
$abi = $this->match_data['cod_abi'];
}
return [
'abi' => $abi,
'messaggio_banca' => $messaggioBanca ?: '—',
'messaggio_cliente' => $messaggioCliente ?: '—',
'commissioni_spese' => $commissioni ?: '—',
'cbill_code' => $cbillCode,
];
}
protected function applyCleaningRules(string $text): string
{
$patterns = [];
$config = self::loadCleaningConfig();
if (isset($config['base']['remove_patterns']) && is_array($config['base']['remove_patterns'])) {
$patterns = array_merge($patterns, $config['base']['remove_patterns']);
}
$codice = $this->resolveCodiceBreve();
if ($codice && isset($config['codici'][$codice]['remove_patterns']) && is_array($config['codici'][$codice]['remove_patterns'])) {
$patterns = array_merge($patterns, $config['codici'][$codice]['remove_patterns']);
}
foreach ($patterns as $pattern) {
if (! is_string($pattern) || $pattern === '') {
continue;
}
$text = preg_replace('/' . $pattern . '/i', '', $text) ?? $text;
}
return $text;
}
protected function resolveCodiceBreve(): ?string
{
$raw = strtoupper((string) ($this->descrizione ?? ''));
if (str_contains($raw, 'ACCREDITO_BEU_CON_CONTABILE')) {
return 'ACCBEUCONCON';
}
if (str_contains($raw, 'COMBONMYB')) {
return 'COMBONMYB';
}
return null;
}
protected static function loadCleaningConfig(): array
{
if (self::$cleaningConfigCache !== null) {
return self::$cleaningConfigCache;
}
$path = base_path('resources/bank-cleaning.json');
if (! is_file($path)) {
return self::$cleaningConfigCache = [];
}
$json = file_get_contents($path);
$data = is_string($json) ? json_decode($json, true) : null;
if (! is_array($data)) {
return self::$cleaningConfigCache = [];
}
return self::$cleaningConfigCache = $data;
}
public function registrazione()
{
return $this->belongsTo(Registrazione::class, 'registrazione_id');
}
public function conto()
{
return $this->belongsTo(DatiBancari::class, 'conto_id');
}
public function gestioneContabile()
{
return $this->belongsTo(GestioneContabile::class, 'gestione_id');
}
}