Feature: UStVA Kz 61 = ust89 (ReverseCharge-Symmetrie); Fix: Storno überträgt steuerart

This commit is contained in:
fds2610-bot 2026-05-14 19:13:04 +02:00
parent 8bccd17d38
commit 6c4faec3bd
4 changed files with 17 additions and 9 deletions

View file

@ -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

View file

@ -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)

View file

@ -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'],

View file

@ -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],