netgescon-day0/tests/Feature/RiscaldamentoReconciliationTest.php

173 lines
5.7 KiB
PHP

<?php
use App\Models\Fornitore;
use App\Models\FornitoreStabileImpostazione;
use App\Models\Stabile;
use App\Models\StabileServizio;
use App\Models\User;
use App\Models\Amministratore;
use App\Models\VoceSpesa;
use App\Models\GestioneContabile;
use App\Models\DatiBancari;
use App\Filament\Pages\Condomini\RiscaldamentoStabileArchivio;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
uses(RefreshDatabase::class);
test('it auto-assigns default voce spesa from legacy and reconciles bank payments', function () {
// 1. Setup User and Stabile
$user = User::factory()->create();
$user->assignRole('super-admin');
$this->actingAs($user);
$amministratore = Amministratore::create([
'user_id' => $user->id,
'nome' => 'Admin',
'cognome' => 'Test',
'denominazione' => 'Amministrazione Test',
'codice_fiscale' => '12345678901',
]);
$stabile = Stabile::create([
'amministratore_id' => $amministratore->id,
'codice_stabile' => '9999',
'denominazione' => 'Condominio Test XML',
'codice_fiscale' => '12345678901',
'indirizzo' => 'Via Test 1',
'citta' => 'Roma',
'cap' => '00100',
'provincia' => 'RM',
'codice_destinatario_sdi' => '0000000',
]);
// Create a GestioneContabile record to satisfy foreign keys
$gestione = GestioneContabile::create([
'tenant_id' => 'default',
'stabile_id' => $stabile->id,
'anno_gestione' => 2026,
'tipo_gestione' => 'riscaldamento',
'denominazione' => 'Gestione Riscaldamento 2026',
'data_inizio' => '2026-01-01',
'data_fine' => '2026-12-31',
'stato' => 'attiva',
'protocollo_prefix' => 'R2026',
]);
// Create a DatiBancari record to satisfy foreign keys
$conto = DatiBancari::create([
'stabile_id' => $stabile->id,
'tipo_conto' => 'corrente',
'denominazione_banca' => 'Unicredit',
'numero_conto' => '123456',
'iban' => 'IT02X0000000000000000000',
'saldo_iniziale' => 10000.00,
'stato_conto' => 'attivo',
'is_nostro_conto' => true,
]);
// 2. Setup Fornitore and StabileServizio
$fornitore = Fornitore::create([
'amministratore_id' => $amministratore->id,
'ragione_sociale' => 'ENI PLENITUDE',
'codice_fiscale' => '00215478900',
'partita_iva' => '00215478900',
'old_id' => '1234', // legacy ID matching operations
]);
$service = StabileServizio::create([
'stabile_id' => $stabile->id,
'fornitore_id' => $fornitore->id,
'tipo' => 'riscaldamento',
'nome' => 'Riscaldamento Centrale',
'attivo' => true,
]);
// 3. Setup VoceSpesa
$voceSpesa = VoceSpesa::create([
'stabile_id' => $stabile->id,
'codice' => 'R1',
'descrizione' => 'Spese Riscaldamento Metano',
'categoria' => 'riscaldamento',
'tipo' => 'riscaldamento',
'attiva' => true,
]);
// 4. Setup staging database environment for MDB operations mapping
Schema::connection('gescon_import')->dropIfExists('operazioni');
Schema::connection('gescon_import')->create('operazioni', function ($table) {
$table->id();
$table->string('cod_stabile')->nullable();
$table->string('cod_for')->nullable();
$table->string('cod_spe')->nullable();
$table->decimal('importo_euro', 15, 2)->nullable();
});
DB::connection('gescon_import')->table('operazioni')->insert([
'cod_stabile' => '9999',
'cod_for' => '1234',
'cod_spe' => 'R1',
'importo_euro' => 1500.00,
]);
session(['netgescon.stabile_attivo_id' => $stabile->id]);
$page = new RiscaldamentoStabileArchivio();
// Call auto-link default mapping method
$page->mount();
// Verify FornitoreStabileImpostazione was created
$imp = FornitoreStabileImpostazione::where('stabile_id', $stabile->id)
->where('fornitore_id', $fornitore->id)
->first();
expect($imp)->not->toBeNull();
expect((int)$imp->voce_spesa_default_id)->toBe($voceSpesa->id);
// 5. Test bank reconciliation
DB::table('contabilita_fatture_fornitori')->insert([
'id' => 101,
'stabile_id' => $stabile->id,
'gestione_id' => $gestione->id,
'fornitore_id' => $fornitore->id,
'numero_documento' => '10045/A',
'totale' => 1250.00,
'netto_da_pagare' => 1250.00,
'stato' => 'da_pagare',
'data_documento' => now()->toDateString(),
'created_at' => now(),
'updated_at' => now(),
]);
// Create a mock bank movement entry
DB::table('contabilita_movimenti_banca')->insert([
'id' => 202,
'stabile_id' => $stabile->id,
'conto_id' => $conto->id,
'gestione_id' => $gestione->id,
'iban' => 'IT02X0000000000000000000',
'data' => now()->toDateString(),
'valuta' => now()->toDateString(),
'descrizione' => 'Pagam. Fatt. 10045/A ENI PLENITUDE',
'descrizione_estesa' => 'Pagam. Fatt. 10045/A ENI PLENITUDE',
'importo' => -1250.00, // payment is negative
'fornitore_id' => $fornitore->id,
'row_hash' => md5('test_movement_202'),
'created_at' => now(),
'updated_at' => now(),
]);
// Run reconciliation
$page->riconciliaAutomaticamentePagamenti();
$updatedInvoice = DB::table('contabilita_fatture_fornitori')->where('id', 101)->first();
expect($updatedInvoice->stato)->toBe('pagato');
expect($updatedInvoice->movimento_pagamento_id)->toBe(202);
// Cleanup staging tables
Schema::connection('gescon_import')->dropIfExists('operazioni');
});