netgescon-day0/tests/Feature/BpmBankParserAndImporterTest.php

144 lines
7.0 KiB
PHP

<?php
use App\Models\DatiBancari;
use App\Models\Fornitore;
use App\Models\Stabile;
use App\Models\User;
use App\Modules\Contabilita\Models\MovimentoBanca;
use App\Services\Contabilita\BpmCsvParser;
use App\Services\Contabilita\MovimentiBancaImporter;
use Illuminate\Support\Facades\DB;
test('bpm csv parser extracts structured fields correctly', function () {
$csvContent = <<<CSV
"Ragione Sociale","Data contabile","Data valuta","Banca","Rapporto","Importo","Divisa","Descrizione","Categoria/sottocategoria","Hashtag"
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","23/12/2025","23/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-1416","EUR","VOSTRA DISPOSIZIONE - VS.DISP. RIF. MB0B92378843/90691538 FAVORE GAIA CONSORZIO - ADD.TOT - SALDO FT N. FEP 1056 DEL 18/12/2025","Servizi - Spese per manutenzione",""
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","11/12/2025","11/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","501","EUR","BONIF. VS. FAVORE - BON.DA LAI LISU - Condominio","Ricavi - Generico",""
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","16/12/2025","16/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-1351,68","EUR","PAG. UTENZE VARIE - BOLL.CBILL ACEA ATO 2 S.P.A. (PROFIL CBILL 301059900049257704","Utenze - Acqua, luce e gas",""
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","16/12/2025","16/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-995","EUR","I24 AGENZIA ENTRATE - PAG.TO TELEMATICO - DATA INCASSO 16/12/2025 2025-12-15-22.33.17.322634108123","Tasse - Imposte e contributi",""
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","23/12/2025","23/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-0,7","EUR","COMM.SU BONIFICI - NS RIF. MB0B92378843 SPESE E COMM.","Operazioni Finanziarie - Commissioni",""
"CONDOMINIO VIA OTTAVIANO 105. V.LE GIULIO CESARE 171 ROMA","31/12/2025","01/01/2026","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-32,01","EUR","INT. E COMP. - COMPETENZE","Operazioni Finanziarie - Interessi negativi",""
CSV;
$parser = new BpmCsvParser();
$parsed = $parser->parse($csvContent);
expect($parsed['rows'])->toHaveCount(6)
->and($parsed['meta']['skipped_rows'])->toBe(0);
// Row 0: Disposizione Gaia Consorzio
$r0 = $parsed['rows'][0];
expect($r0['data']->toDateString())->toBe('2025-12-23')
->and($r0['importo'])->toBe(-1416.00)
->and($r0['causale'])->toBe('BONIFICO')
->and($r0['descrizione'])->toContain('GAIA CONSORZIO')
->and((string) $r0['descrizione_estesa'])->not->toContain('CONDOMINIO VIA OTTAVIANO')
->and($r0['match_data']['tipo'])->toBe('disposizione_bonifico')
->and($r0['match_data']['beneficiario'])->toBe('GAIA CONSORZIO')
->and($r0['match_data']['rif_fattura'])->toBe('FEP 1056')
->and($r0['match_data']['data_fattura'])->toBe('18/12/2025')
->and($r0['match_data']['cod_abi'])->toBe('05034')
->and($r0['match_data']['cod_cab'])->toBe('03214');
// Row 1: Bonifico entrata LAI LISU
$r1 = $parsed['rows'][1];
expect($r1['data']->toDateString())->toBe('2025-12-11')
->and($r1['importo'])->toBe(501.00)
->and($r1['causale'])->toBe('BONIFICO')
->and($r1['match_data']['mittente'])->toBe('LAI LISU')
->and($r1['match_data']['dettaglio'])->toBe('Condominio');
// Row 2: CBILL ACEA ATO 2
$r2 = $parsed['rows'][2];
expect($r2['importo'])->toBe(-1351.68)
->and($r2['causale'])->toBe('CBILL')
->and($r2['match_data']['beneficiario'])->toBe('ACEA ATO 2 S.P.A.')
->and($r2['match_data']['codice_cbill'])->toBe('301059900049257704');
// Row 3: F24 Agenzia Entrate
$r3 = $parsed['rows'][3];
expect($r3['importo'])->toBe(-995.00)
->and($r3['causale'])->toBe('F24')
->and($r3['match_data']['beneficiario'])->toBe('AGENZIA DELLE ENTRATE')
->and($r3['match_data']['data_incasso'])->toBe('16/12/2025');
// Row 4: Commissioni
$r4 = $parsed['rows'][4];
expect($r4['importo'])->toBe(-0.70)
->and($r4['causale'])->toBe('COMMISSIONI')
->and($r4['match_data']['rif_disp'])->toBe('MB0B92378843');
// Row 5: Competenze
$r5 = $parsed['rows'][5];
expect($r5['importo'])->toBe(-32.01)
->and($r5['causale'])->toBe('COMPETENZE');
});
test('importer creates clean movements and links supplier', function () {
$user = User::first();
if (! $user) {
$user = User::factory()->create(['email' => 'admin.test@netgescon.it']);
}
$adminId = DB::table('amministratori')->insertGetId([
'user_id' => $user->id,
'nome' => 'Admin',
'cognome' => 'BpmTest',
'codice_amministratore' => 'ADMBPM01',
'created_at' => now(),
'updated_at' => now(),
]);
$stabile = Stabile::query()->firstOrCreate(
['codice_stabile' => 'TEST_BPM_0013'],
[
'denominazione' => 'Condominio BPM Test',
'codice_fiscale' => '99999999991',
'amministratore_id' => $adminId,
'indirizzo' => 'Via Test 105',
'cap' => '00192',
'citta' => 'Roma',
'provincia' => 'RM',
]
);
$fornitore = Fornitore::query()->firstOrCreate(
['ragione_sociale' => 'Gaia Consorzio'],
[
'amministratore_id' => $adminId,
'partita_iva' => '12345678901',
'codice_fiscale' => '12345678901',
]
);
$conto = DatiBancari::query()->firstOrCreate(
['stabile_id' => $stabile->id, 'iban' => 'IT88A0503403214000000000707'],
['denominazione_banca' => 'BANCO BPM', 'numero_conto' => '010300000707']
);
$csvContent = <<<CSV
"Ragione Sociale","Data contabile","Data valuta","Banca","Rapporto","Importo","Divisa","Descrizione","Categoria/sottocategoria","Hashtag"
"CONDOMINIO TEST","23/12/2025","23/12/2025","05034 - BANCO BPM S.P.A.","03214 - 010300000707","-1416","EUR","VOSTRA DISPOSIZIONE - VS.DISP. RIF. MB0B92378843/90691538 FAVORE GAIA CONSORZIO - ADD.TOT - SALDO FT N. FEP 1056 DEL 18/12/2025","Servizi - Spese per manutenzione",""
CSV;
$importer = app(MovimentiBancaImporter::class);
$result = $importer->importBpmCsvForConto($csvContent, (int) $stabile->id, (int) $conto->id, 'test_bpm.csv', null, true);
expect($result['imported'])->toBe(1);
$movement = MovimentoBanca::query()
->where('stabile_id', $stabile->id)
->where('conto_id', $conto->id)
->first();
expect($movement)->not->toBeNull()
->and((float) $movement->importo)->toBe(-1416.00)
->and($movement->causale)->toBe('BONIFICO')
->and((int) $movement->fornitore_id)->toBe((int) $fornitore->id)
->and((bool) $movement->da_confermare)->toBeFalse()
->and((string) $movement->beneficiario)->toContain('Gaia Consorzio')
->and((string) $movement->rif_documento)->toContain('FEP 1056')
->and((string) $movement->descrizione_estesa)->not->toContain('"CONDOMINIO TEST"')
->and((string) $movement->descrizione_estesa)->not->toContain('"-1416","EUR"');
});