diff --git a/Changes.md b/Changes.md index 1b0a900..804acc2 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,11 @@ --- +## 2026-05-14 – Feature: UStVA Kz 61 aus ust89 abgeleitet (ReverseCharge-Symmetrie) + +- `UstvaCalculator`: Kz 61 = ust89 (nicht mehr kontobasiert via Konto 1574) – fachlich korrekt, da VSt ig. Erwerb = USt ig. Erwerb +- `Booking::reverse()`: Hauptstornobuchung überträgt jetzt `steuerart` der Originalbuchung (fehlte bisher, wurde durch Kz-61-Kontoberechnung kaschiert) + ## 2026-05-14 – Feature: UStVA Kz 81/89 auf volle Euro abgerundet - `UstvaCalculator`: Kz 81 und 89 werden mit `floor()` auf volle Euro abgerundet; USt wird auf dem gerundeten Wert berechnet diff --git a/docs/berechnungslogik.md b/docs/berechnungslogik.md index a14acea..498dc25 100644 --- a/docs/berechnungslogik.md +++ b/docs/berechnungslogik.md @@ -50,7 +50,7 @@ Diese Berechnung wird ausschließlich für **monatliche** Voranmeldungen unterst | **81** | Steuerpflichtige Umsätze zum Steuersatz von 19 % | Konto | `floor(SUM(betrag_netto))` WHERE `ustva_kz='81'`, EU-Steuerarten ausgeschlossen – **auf volle Euro abgerundet (floor)** | | **89** | Steuerpfl. innergemeinschaftliche Erwerbe 19 % | Steuerart | `floor(SUM(betrag_netto))` WHERE `steuerart='ig_erwerb_19'` – **auf volle Euro abgerundet (floor)** | | **66** | Gesamte Vorsteuerbeträge | Konto | `SUM(betrag_netto)` WHERE `ustva_kz='66'` (Konten 1571, 1576) | -| **61** | Vorsteuerbeträge i.g. Erwerb | Konto | `SUM(betrag_netto)` WHERE `ustva_kz='61'` (Konto 1574) | +| **61** | Vorsteuerbeträge i.g. Erwerb | abgeleitet | `ust89` (= `round(Kz 89 × 0,19, 2)`) – ReverseCharge-Symmetrie: VSt ig. Erwerb = USt ig. Erwerb | | **83** | Vorauszahlung / Überschuss | abgeleitet | `(Summe ustva_kz='83') − Kz 66 − Kz 61` | Zusätzlich werden zwei **reine Anzeigefelder** berechnet (erscheinen im Bericht, aber **nicht** im XML): @@ -68,7 +68,7 @@ Zusätzlich werden zwei **reine Anzeigefelder** berechnet (erscheinen im Bericht EU-Steuerarten (`ig_lieferung`, `export`, `ig_erwerb_19`, `ig_erwerb_7`) werden aus der kontobasierten Abfrage ausgeschlossen, um Doppelzählung mit Quelle 2 zu vermeiden. **Quelle 2 – steuerartbasiert** (`bookings.steuerart = 'ig_erwerb_19'`) -Nur ig_erwerb_19 fließt als Bemessungsgrundlage in Kz 89 ein. Die zugehörigen Steuerkonten (1574, 1774) werden über Quelle 1 kontobasiert erfasst. +Nur ig_erwerb_19 fließt als Bemessungsgrundlage in Kz 89 ein. Kz 61 wird daraus rechnerisch abgeleitet (nicht mehr kontobasiert über 1574). ### Automatische Kindzeilen (Buchungslogik) diff --git a/src/Models/Booking.php b/src/Models/Booking.php index b4b6ddd..df95c97 100644 --- a/src/Models/Booking.php +++ b/src/Models/Booking.php @@ -244,8 +244,8 @@ class Booking Database::execute( 'INSERT INTO bookings (buchungs_nr, beleg_id, buchungs_datum, buchungstyp, kategorie_konto_id, zahlungskonto_id, - betrag_netto, ust_satz, betrag_ust, betrag_brutto, buchungstext, is_reversal, fiscal_year_id) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)', + betrag_netto, ust_satz, steuerart, betrag_ust, betrag_brutto, buchungstext, is_reversal, fiscal_year_id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)', [ $nr, $reversalData['beleg_id'], @@ -255,6 +255,7 @@ class Booking $reversalData['zahlungskonto_id'], -1 * (float)$orig['betrag_netto'], $orig['ust_satz'], + $orig['steuerart'], -1 * (float)$orig['betrag_ust'], -1 * (float)$orig['betrag_brutto'], $reversalData['buchungstext'], diff --git a/src/Services/UstvaCalculator.php b/src/Services/UstvaCalculator.php index d147df6..aba5d3e 100644 --- a/src/Services/UstvaCalculator.php +++ b/src/Services/UstvaCalculator.php @@ -12,18 +12,19 @@ use Steuerkram\Database; * Kontobasierte Kennzahlen (accounts.ustva_kz des Kategorie-Kontos): * ustva_kz = '81' → Kz 81 (betrag_netto, EU-Steuerarten ausgeschlossen) * ustva_kz = '66' → Kz 66 (betrag_netto, Konten 1571 + 1576) - * ustva_kz = '61' → Kz 61 (betrag_netto, Konto 1574) * ustva_kz = '83' → Summand für Kz 83 (Konten 1771 + 1774 + 1776) * * Steuerart-basiert: * steuerart = 'ig_erwerb_19' → Kz 89 (betrag_netto, Bemessungsgrundlage) * * Abgeleitete Kennzahlen: + * ust89 = round(Kz 89 × 0,19, 2) (abzuführende USt aus Kz 89) + * Kz 61 = ust89 (VSt ig. Erwerb = USt ig. Erwerb, ReverseCharge-Symmetrie) * Kz 83 = (Summe ustva_kz='83') − Kz 66 − Kz 61 (Vorauszahlung / Überschuss) * * Nur-Anzeige (kein XML-Export): - * ust81 = Kz 81 × 0,19 (abzuführende USt aus Kz 81) - * ust89 = Kz 89 × 0,19 (abzuführende USt aus Kz 89) + * ust81 = round(Kz 81 × 0,19, 2) (abzuführende USt aus Kz 81) + * ust89 = s.o. */ class UstvaCalculator { @@ -79,10 +80,11 @@ class UstvaCalculator $kz81 = floor($n('81')); $kz89 = floor($kz89); $kz66 = $n('66'); - $kz61 = $n('61'); - $kz83 = $n('83') - $kz66 - $kz61; $ust81 = round($kz81 * 0.19, 2); $ust89 = round($kz89 * 0.19, 2); + // Kz 61 (VSt ig. Erwerb) = ust89: ReverseCharge ist immer symmetrisch zur USt aus Kz 89 + $kz61 = $ust89; + $kz83 = $n('83') - $kz66 - $kz61; return [ '81' => ['name' => 'Steuerpflichtige Umsätze zum Steuersatz von 19 %', 'betrag' => $kz81, 'steuer' => null, 'xml' => true, 'ganze_euro' => true],