Steuerkram/tests/07_UstvaAuslandTest.php

165 lines
6.3 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
* 41, 44, 89, 91 und 67 einfließen.
*/
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');
// Konten aus SKR03
$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 → Kz 41 ──────────────────────────
$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 → Kz 44 ───────────────────────────────
$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/91/67 ─────────────────────────────
$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);
// Kz 41: ig. Lieferung 1000 €
$this->assert(
(float)$kz['41']['betrag'] >= 1000.00,
'Kz 41 (ig. Lieferung): Betrag ≥ 1.000 €'
);
// Kz 44: Ausfuhr 2000 €
$this->assert(
(float)$kz['44']['betrag'] >= 2000.00,
'Kz 44 (Ausfuhr): Betrag ≥ 2.000 €'
);
// 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 91: USt ig. Erwerb kontobasiert (1774) +95 €
$this->assertEquals(
95.00,
round((float)$kz['91']['steuer'] - (float)$kzPre['91']['steuer'], 2),
'Kz 91 (USt ig. Erwerb 19%): Delta = 95,00 €'
);
// Kz 67: VSt ig. Erwerb kontobasiert (1574) +95 €
$this->assertEquals(
95.00,
round((float)$kz['67']['steuer'] - (float)$kzPre['67']['steuer'], 2),
'Kz 67 (VSt ig. Erwerb): Delta = 95,00 €'
);
// ReverseCharge ist zahllastneutral: Kz 69 unverändert
$this->assertEquals(
0.00,
round((float)$kz['69']['steuer'] - (float)$kzPre['69']['steuer'], 2),
'Kz 69 (Zahllast) durch ig. Erwerb nicht verändert'
);
// ig. Erwerb darf nicht in Kz 35 landen
$this->assertEquals(
0.0,
(float)$kz['35']['betrag'],
'Kz 35 (steuerfreie Inlandsumsätze) = 0'
);
}
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;
}
}