230 lines
6.8 KiB
PHP
Executable File
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');
|
|
}
|
|
}
|