205 lines
7.8 KiB
PHP
205 lines
7.8 KiB
PHP
<?php
|
|
|
|
use App\Filament\Pages\Gescon\Ordinarie;
|
|
use App\Filament\Pages\UnitaImmobiliarePage;
|
|
use App\Models\Stabile;
|
|
use App\Models\UnitaImmobiliare;
|
|
use App\Models\User;
|
|
use App\Services\Contabilita\GermanicoBancaReconciliationService;
|
|
use App\Services\Gescon\GesconEstrattoContoService;
|
|
use App\Support\StabileContext;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Livewire\Livewire;
|
|
|
|
beforeEach(function () {
|
|
DB::table('amministratori')->insertOrIgnore([
|
|
'id' => 1,
|
|
'nome' => 'Admin',
|
|
'cognome' => 'Test',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
$this->user = User::factory()->create();
|
|
if (method_exists($this->user, 'assignRole')) {
|
|
\Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']);
|
|
$this->user->assignRole('admin');
|
|
}
|
|
|
|
DB::table('stabili')->insertOrIgnore([
|
|
'id' => 19,
|
|
'amministratore_id' => 1,
|
|
'codice_stabile' => '0016',
|
|
'denominazione' => 'CONDOMINIO VIA GERMANICO 96',
|
|
'indirizzo' => 'Via Germanico 96',
|
|
'citta' => 'Roma',
|
|
'cap' => '00192',
|
|
'provincia' => 'RM',
|
|
'attivo' => 1,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$this->stabile = Stabile::find(19);
|
|
|
|
DB::table('unita_immobiliari')->insertOrIgnore([
|
|
'id' => 321,
|
|
'stabile_id' => 19,
|
|
'scala' => 'B',
|
|
'interno' => '4',
|
|
'codice_unita' => '0016-B-4',
|
|
'denominazione' => 'Barone Michele',
|
|
'legacy_cond_id' => '47',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$this->unita = UnitaImmobiliare::find(321);
|
|
|
|
DB::table('unita_immobiliare_nominativi')->insertOrIgnore([
|
|
[
|
|
'unita_immobiliare_id' => 321,
|
|
'nominativo' => 'Barone Michele',
|
|
'ruolo' => 'P',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
[
|
|
'unita_immobiliare_id' => 321,
|
|
'nominativo' => 'Francioni Claudia',
|
|
'ruolo' => 'CP',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
]);
|
|
|
|
StabileContext::setActiveStabileId($this->user, 19);
|
|
});
|
|
|
|
test('unit 321 owner picker includes barone michele and francioni claudia', function () {
|
|
$component = Livewire::actingAs($this->user)
|
|
->withQueryParams(['unita_id' => 321])
|
|
->test(UnitaImmobiliarePage::class, ['unita_id' => 321]);
|
|
|
|
$unitaOptions = $component->instance()->getUnitaOptions();
|
|
|
|
expect($unitaOptions)->toBeArray()
|
|
->and(isset($unitaOptions[321]))->toBeTrue();
|
|
|
|
$label321 = $unitaOptions[321];
|
|
expect($label321)->toContain('Barone Michele')
|
|
->and($label321)->toContain('Scala B')
|
|
->and($label321)->toContain('Int. 4');
|
|
});
|
|
|
|
test('bank reconciliation service reconciles over 85 percent of germanico bank transactions', function () {
|
|
$service = app(GermanicoBancaReconciliationService::class);
|
|
$result = $service->syncAndReconcileAll();
|
|
|
|
expect($result)->toBeArray()
|
|
->and($result['total_movimenti'])->toBeGreaterThanOrEqual(1900)
|
|
->and($result['totale_riconciliati'])->toBeGreaterThanOrEqual(1600)
|
|
->and($result['percentuale'])->toBeGreaterThanOrEqual(85.0);
|
|
|
|
// Verifica che l'unita 321 abbia transazioni riconciliate
|
|
$unitaMovs = $service->getMovimentiForUnita(321);
|
|
expect($unitaMovs->count())->toBeGreaterThanOrEqual(7);
|
|
|
|
// Verifica bonifico del 23/12/2025 di 960,79 euro
|
|
$bonifico960 = $unitaMovs->first(fn($m) => abs((float)$m->importo - 960.79) < 0.01);
|
|
expect($bonifico960)->not->toBeNull()
|
|
->and($bonifico960->stato_riconciliazione)->toBe('riconciliato');
|
|
|
|
$matchData = is_string($bonifico960->match_data) ? json_decode($bonifico960->match_data, true) : (array) $bonifico960->match_data;
|
|
expect($matchData['pdf_ricevuta'])->toBe('Inc_EC_20260310_184901.pdf');
|
|
});
|
|
|
|
test('gescon estratto conto service computes exact benchmark 885.00 for germanico unit 321', function () {
|
|
// Esegue sync/reconcile per popolare i movimenti bancari
|
|
$bankService = app(GermanicoBancaReconciliationService::class);
|
|
$bankService->syncAndReconcileAll();
|
|
|
|
$unita = UnitaImmobiliare::find(321);
|
|
expect($unita)->not->toBeNull();
|
|
|
|
$service = app(GesconEstrattoContoService::class);
|
|
$ec = $service->getEstrattoConto($unita, 'C', true);
|
|
|
|
expect($ec)->toBeArray()
|
|
->and($ec['codice_stabile'])->toBe('0016')
|
|
->and($ec['totali']['totale_dovuto'])->toBe(885.00)
|
|
->and($ec['totali']['totale_ordinaria_corrente_residuo'])->toBe(885.00)
|
|
->and($ec['totali']['totale_ordinarie_pregresse_residuo'])->toBe(0.0)
|
|
->and($ec['totali']['totale_straordinarie_residuo'])->toBe(0.0);
|
|
|
|
// Verifica ordinaria corrente 2025/26: 6 rate da 177.00 di cui rata 1 saldata
|
|
$ord = $ec['gestione_ordinaria_corrente'];
|
|
expect($ord['totale_dovuto'])->toBe(1062.00)
|
|
->and($ord['totale_pagato'])->toBe(177.00)
|
|
->and($ord['residuo'])->toBe(885.00)
|
|
->and(count($ord['rate']))->toBe(6);
|
|
|
|
$rata1 = $ord['rate'][0];
|
|
expect($rata1['stato'])->toBe('Saldata')
|
|
->and($rata1['pagato'])->toBe(177.00)
|
|
->and($rata1['residuo'])->toBe(0.0)
|
|
->and($rata1['data_pagamento'])->toBe('23/12/2025')
|
|
->and($rata1['movimento_bancario'])->not->toBeNull()
|
|
->and($rata1['movimento_bancario']['importo'])->toBe(960.79)
|
|
->and($rata1['ricevuta_pdf'])->toBe('Inc_EC_20260310_184901.pdf');
|
|
|
|
// Verifica movimenti bancari riconciliati allegati all'unita
|
|
expect($ec['movimenti_bancari'])->toBeArray()
|
|
->and(count($ec['movimenti_bancari']))->toBeGreaterThanOrEqual(7);
|
|
|
|
$mov960 = collect($ec['movimenti_bancari'])->first(fn($m) => abs($m['importo'] - 960.79) < 0.01);
|
|
expect($mov960)->not->toBeNull()
|
|
->and($mov960['stato'])->toBe('riconciliato')
|
|
->and($mov960['pdf_ricevuta'])->toBe('Inc_EC_20260310_184901.pdf');
|
|
});
|
|
|
|
test('ordinarie page renders banca tab and matches incassi from singolo_anno mdb', function () {
|
|
$bankService = app(GermanicoBancaReconciliationService::class);
|
|
$bankService->syncAndReconcileAll();
|
|
|
|
auth()->login($this->user);
|
|
|
|
$page = new Ordinarie();
|
|
$page->mount();
|
|
|
|
// Test KPI banca
|
|
$kpi = $page->bancaKpi;
|
|
expect($kpi)->toBeArray()
|
|
->and($kpi['total'])->toBeGreaterThanOrEqual(1900)
|
|
->and($kpi['riconciliati'])->toBeGreaterThanOrEqual(1600)
|
|
->and($kpi['iban'])->toBe(GermanicoBancaReconciliationService::IBAN_GERMANICO);
|
|
|
|
// Test ricerca movimento Barone Michele
|
|
$page->bancaSearch = 'Barone Michele';
|
|
$movimenti = $page->movimentiBanca;
|
|
expect($movimenti->total())->toBeGreaterThanOrEqual(7);
|
|
|
|
$firstMov = $movimenti->first();
|
|
expect($firstMov->estratto_conto_url)->toContain('unita-immobiliare?unita_id=321')
|
|
->and($firstMov->match_pdf)->toContain('.pdf');
|
|
|
|
// Test incassi da MDB con arricchimento bancario
|
|
$page->search = null;
|
|
$incassi = $page->incassi;
|
|
expect($incassi)->not->toBeNull()
|
|
->and($incassi->total())->toBeGreaterThan(0);
|
|
|
|
// Verifica che gli incassi abbiano il matching bancario se presente
|
|
$matched = collect($incassi->items())->filter(fn($i) => !empty($i->movimento_banca));
|
|
expect($matched->count())->toBeGreaterThan(0);
|
|
});
|
|
|
|
test('receipt pdf route streams valid pdf document for inc_ec', function () {
|
|
$response = $this->actingAs($this->user)
|
|
->get(route('admin.gescon.inc_ec.pdf', [
|
|
'stabile' => '0016',
|
|
'file' => 'Inc_EC_20260310_184901.pdf',
|
|
]));
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertHeader('content-type', 'application/pdf');
|
|
});
|