1000.00, 'zugaenge' => 0, 'abgaenge' => 0, 'nutzungsdauer' => 0, 'cent_im_ersten_jahr'=> false, 'anschaffungsdatum' => '2025-03-15', ]); $this->assertEquals(1, count($rows), 'Sofortabschreibung: genau 1 Zeile'); $this->assertEquals(2025, $rows[0]['jahr'], 'Sofortabschreibung: Startjahr korrekt'); $this->assertEquals(1000.00, $rows[0]['abschreibungsbetrag'], 'Sofortabschreibung: voller Betrag'); $this->assertEquals(0.00, $rows[0]['restwert'], 'Sofortabschreibung: Restwert 0'); // ── Gleichmäßige lineare AfA ohne Cent-Option ──────────── $rows = AssetDepreciation::calculate([ 'anschaffungskosten' => 3000.00, 'zugaenge' => 0, 'abgaenge' => 0, 'nutzungsdauer' => 3, 'cent_im_ersten_jahr'=> false, 'anschaffungsdatum' => '2023-01-01', ]); $this->assertEquals(3, count($rows), 'Lineare AfA 3 Jahre: 3 Zeilen'); $this->assertEquals(1000.00, $rows[0]['abschreibungsbetrag'], 'Jahr 1: 1000,00'); $this->assertEquals(2000.00, $rows[0]['restwert'], 'Jahr 1 Restwert: 2000,00'); $this->assertEquals(1000.00, $rows[2]['abschreibungsbetrag'], 'Jahr 3: 1000,00'); $this->assertEquals(0.00, $rows[2]['restwert'], 'Jahr 3 Restwert: 0,00'); // ── Cent-Option: Centbeträge im ersten Jahr ────────────── $rows = AssetDepreciation::calculate([ 'anschaffungskosten' => 1000.75, 'zugaenge' => 0, 'abgaenge' => 0, 'nutzungsdauer' => 3, 'cent_im_ersten_jahr'=> true, 'anschaffungsdatum' => '2024-01-01', ]); $this->assertEquals(3, count($rows), 'Cent-Option 3 Jahre: 3 Zeilen'); // Folgejahre: floor(1000.75/3) = 333 € $this->assertEquals(333.00, $rows[1]['abschreibungsbetrag'], 'Jahr 2 mit Cent-Option: 333,00'); $this->assertEquals(333.00, $rows[2]['abschreibungsbetrag'], 'Jahr 3 mit Cent-Option: 333,00'); // Erstes Jahr: 1000.75 - 333*2 = 334.75 $this->assertEquals(334.75, $rows[0]['abschreibungsbetrag'], 'Jahr 1 mit Cent-Option: 334,75'); // Restwert nach Jahr 1 auf volle Euro $restwertJ1 = $rows[0]['restwert']; $this->assert( $restwertJ1 == floor($restwertJ1), 'Restwert nach Jahr 1 ist volle Euro: ' . $restwertJ1 ); // Gesamtsumme muss Basis entsprechen $sumAfa = array_sum(array_column($rows, 'abschreibungsbetrag')); $this->assertEquals(1000.75, round($sumAfa, 2), 'Summe aller Abschreibungen = Basis'); // ── Basis mit Zugängen und Abgängen ───────────────────── $rows = AssetDepreciation::calculate([ 'anschaffungskosten' => 5000.00, 'zugaenge' => 500.00, 'abgaenge' => 200.00, 'nutzungsdauer' => 5, 'cent_im_ersten_jahr'=> false, 'anschaffungsdatum' => '2022-06-01', ]); $this->assertEquals(5, count($rows), 'AfA mit Zu-/Abgängen: 5 Zeilen'); $basis = 5000.00 + 500.00 - 200.00; $sumAfa = array_sum(array_column($rows, 'abschreibungsbetrag')); $this->assertEquals($basis, round($sumAfa, 2), 'Summe AfA = Basis mit Zu-/Abgängen'); // ── Leere Tabelle bei Basis <= 0 ───────────────────────── $rows = AssetDepreciation::calculate([ 'anschaffungskosten' => 0, 'zugaenge' => 0, 'abgaenge' => 0, 'nutzungsdauer' => 5, 'cent_im_ersten_jahr'=> false, 'anschaffungsdatum' => '2024-01-01', ]); $this->assertEquals(0, count($rows), 'Keine Zeilen bei Basis = 0'); // ── Persistenz: Speichern und Laden ────────────────────── // Erst ein Test-Asset anlegen (Rollback durch TestCase) \Steuerkram\Database::execute( "INSERT INTO assets (lfd_nr, anlage_nr, bezeichnung, anschaffungsdatum, anschaffungskosten) VALUES (9999, 'TEST-DEPR', 'Test Abschreibung', '2024-01-01', 2400.00)" ); $assetId = (int)\Steuerkram\Database::lastInsertId(); $testRows = [ ['jahr' => 2024, 'abschreibungsbetrag' => 800.00, 'restwert' => 1600.00, 'position' => 0], ['jahr' => 2025, 'abschreibungsbetrag' => 800.00, 'restwert' => 800.00, 'position' => 1], ['jahr' => 2026, 'abschreibungsbetrag' => 800.00, 'restwert' => 0.00, 'position' => 2], ]; AssetDepreciation::saveForAsset($assetId, $testRows); $loaded = AssetDepreciation::findByAsset($assetId); $this->assertEquals(3, count($loaded), 'Persistenz: 3 Zeilen gespeichert und geladen'); $this->assertEquals(2024, (int)$loaded[0]['jahr'], 'Persistenz: Jahr 2024 korrekt'); $this->assertEquals(800.00, (float)$loaded[0]['abschreibungsbetrag'], 'Persistenz: Betrag korrekt'); AssetDepreciation::deleteByAsset($assetId); $loaded = AssetDepreciation::findByAsset($assetId); $this->assertEquals(0, count($loaded), 'Persistenz: Nach deleteByAsset keine Zeilen mehr'); } }