Steuerkram/tests/26_AbschreibungstabelleTest.php

121 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
use Steuerkram\Models\AssetDepreciation;
class AbschreibungstabelleTest extends TestCase
{
protected string $testName = 'Test 26: Abschreibungstabelle (lineare AfA)';
public function run(): void
{
// ── Sofortabschreibung ───────────────────────────────────
$rows = AssetDepreciation::calculate([
'anschaffungskosten' => 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');
}
}