Steuerkram/tests/07_UstvaAuslandTest.php

144 lines
6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* Test 7: UStVA-Kennzahlen für Auslandsumsätze und ig. Erwerb.
*
* Prüft, dass steuerart-Buchungen korrekt in die UStVA-Kennzahlen einfließen.
* Im neuen Schema: Kz 89 (ig. Erwerb Bmgl.), Kz 61 (VSt ig. Erwerb), Kz 83 (Vorauszahlung).
* Kz 41/44 (ig. Lieferung, Ausfuhr) werden nicht mehr separat ausgewiesen.
*/
class UstvaAuslandTest extends TestCase
{
protected string $testName = 'Test 7: UStVA Auslandsumsätze und ig. Erwerb';
public function run(): void
{
$year = (int)date('Y');
$month = (int)date('n');
$datum = date('Y-m-d');
$erloesId = $this->findKonto('Betriebseinnahme');
$ausgabeId = $this->findKonto('Betriebsausgabe');
$zahlungId = $this->findKonto('Zahlungskonto');
if (!$erloesId || !$ausgabeId || !$zahlungId) {
$this->assert(false, 'Benötigte Konten nicht gefunden – SKR03-Seed vorhanden?');
return;
}
$this->assert(true, 'Konten vorhanden');
$bankId = \Steuerkram\Database::fetchOne(
"SELECT id FROM accounts WHERE kontenart = 'Zahlungskonto' AND aktiv = 1 AND id != ? LIMIT 1",
[$zahlungId]
);
$bankId = $bankId ? (int)$bankId['id'] : $zahlungId;
$calc = new \Steuerkram\Services\UstvaCalculator();
$kzPre = $calc->calculate($year, $month);
// ── 1. Steuerfreie ig. Lieferung (steuerart=ig_lieferung) ─────────────
// Wird nicht in Kz 81 eingerechnet (EU-Steuerarten-Filter), kein eigenes Kz.
$belegIgL = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-IGL-' . uniqid(),
'filename' => 'test-igl.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-igl'),
'beleg_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung',
]);
\Steuerkram\Models\Booking::create([
'beleg_id' => $belegIgL,
'buchungs_datum' => $datum,
'buchungstyp' => 'Einnahme',
'steuerart' => 'ig_lieferung',
'kategorie_konto_id' => $erloesId,
'zahlungskonto_id' => $zahlungId,
'betrag_netto' => 1000.00,
'ust_satz' => 0.0,
'buchungstext' => 'Test ig. Lieferung EU',
]);
// ── 2. Steuerfreie Ausfuhr (steuerart=export) ─────────────────────────
$belegExp = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-EXP-' . uniqid(),
'filename' => 'test-exp.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-exp'),
'beleg_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung',
]);
\Steuerkram\Models\Booking::create([
'beleg_id' => $belegExp,
'buchungs_datum' => $datum,
'buchungstyp' => 'Einnahme',
'steuerart' => 'export',
'kategorie_konto_id' => $erloesId,
'zahlungskonto_id' => $zahlungId,
'betrag_netto' => 2000.00,
'ust_satz' => 0.0,
'buchungstext' => 'Test Ausfuhr Drittland',
]);
// ── 3. Ig. Erwerb 19 % → Kz 89 / Kz 61 / Kz 83 ──────────────────────
$belegIgE19 = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-IGE19-' . uniqid(),
'filename' => 'test-ige19.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'test-ige19'),
'beleg_datum' => $datum,
'belegtyp' => 'Eingangsrechnung',
]);
\Steuerkram\Models\Booking::create([
'beleg_id' => $belegIgE19,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'steuerart' => 'ig_erwerb_19',
'kategorie_konto_id' => $ausgabeId,
'zahlungskonto_id' => $bankId,
'betrag_netto' => 500.00,
'ust_satz' => 0.0,
'buchungstext' => 'Test ig. Erwerb 19%',
]);
// ── UStVA berechnen und Delta prüfen ──────────────────────────────────
$kz = $calc->calculate($year, $month);
// ig. Lieferung/Ausfuhr fließen nicht in Kz 81 ein (EU-Steuerarten-Filter)
$delta81 = round((float)$kz['81']['betrag'] - (float)$kzPre['81']['betrag'], 2);
$this->assertEquals(0.00, $delta81, 'ig. Lieferung/Ausfuhr gehen nicht in Kz 81 ein');
// Kz 89: ig. Erwerb 19% Bemessungsgrundlage +500 €
$this->assert(
round((float)$kz['89']['betrag'] - (float)$kzPre['89']['betrag'], 2) >= 500.00,
'Kz 89 (ig. Erwerb 19% Bmgl.): Delta ≥ 500 €'
);
// Kz 61: VSt ig. Erwerb (Konto 1574) +95 €
$this->assertEquals(
95.00,
round((float)$kz['61']['steuer'] - (float)$kzPre['61']['steuer'], 2),
'Kz 61 (VSt ig. Erwerb): Delta = 95,00 €'
);
// ReverseCharge ist zahllastneutral: USt auf 1774 (+95) wird durch Kz61-Abzug (-95) aufgehoben
$this->assertEquals(
0.00,
round((float)$kz['83']['steuer'] - (float)$kzPre['83']['steuer'], 2),
'Kz 83 (Vorauszahlung) durch ig. Erwerb nicht verändert'
);
}
private function findKonto(string $kontenart): ?int
{
$row = \Steuerkram\Database::fetchOne(
"SELECT id FROM accounts WHERE kontenart = ? AND aktiv = 1 LIMIT 1",
[$kontenart]
);
return $row ? (int)$row['id'] : null;
}
}