Fix: Belegsumme blendet steuerliche Umbuchungen auf Konto 1800 aus
This commit is contained in:
parent
4eb622fa7d
commit
1e2c8cf498
2 changed files with 117 additions and 2 deletions
|
|
@ -19,7 +19,8 @@ class Beleg
|
||||||
OR s.name LIKE ?
|
OR s.name LIKE ?
|
||||||
OR b.bewirtungsgrund LIKE ? OR b.teilnehmerliste LIKE ?
|
OR b.bewirtungsgrund LIKE ? OR b.teilnehmerliste LIKE ?
|
||||||
OR (SELECT CAST(SUM(bk2s.betrag_brutto) AS CHAR) FROM bookings bk2s
|
OR (SELECT CAST(SUM(bk2s.betrag_brutto) AS CHAR) FROM bookings bk2s
|
||||||
WHERE bk2s.beleg_id = b.id AND bk2s.is_reversal = 0 AND bk2s.parent_booking_id IS NULL) LIKE ?)';
|
WHERE bk2s.beleg_id = b.id AND bk2s.is_reversal = 0 AND bk2s.parent_booking_id IS NULL
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM accounts az WHERE az.id = bk2s.zahlungskonto_id AND az.kontonummer = \'1800\')) LIKE ?)';
|
||||||
$s = '%' . $filter['search'] . '%';
|
$s = '%' . $filter['search'] . '%';
|
||||||
$sBrutto = '%' . str_replace(',', '.', $filter['search']) . '%';
|
$sBrutto = '%' . str_replace(',', '.', $filter['search']) . '%';
|
||||||
$params = array_merge($params, [$s, $s, $s, $s, $s, $s, $s, $s, $sBrutto]);
|
$params = array_merge($params, [$s, $s, $s, $s, $s, $s, $s, $s, $sBrutto]);
|
||||||
|
|
@ -48,6 +49,7 @@ class Beleg
|
||||||
$sql = 'SELECT b.*,
|
$sql = 'SELECT b.*,
|
||||||
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
||||||
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL
|
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM accounts az WHERE az.id = bk.zahlungskonto_id AND az.kontonummer = \'1800\')
|
||||||
) AS betrag_brutto,
|
) AS betrag_brutto,
|
||||||
fy.year as fiscal_year_nr,
|
fy.year as fiscal_year_nr,
|
||||||
s.name as supplier_name,
|
s.name as supplier_name,
|
||||||
|
|
@ -78,7 +80,8 @@ class Beleg
|
||||||
'SELECT b.*,
|
'SELECT b.*,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
||||||
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL),
|
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM accounts az WHERE az.id = bk.zahlungskonto_id AND az.kontonummer = \'1800\')),
|
||||||
b.betrag_brutto
|
b.betrag_brutto
|
||||||
) AS betrag_brutto,
|
) AS betrag_brutto,
|
||||||
fy.year as fiscal_year_nr,
|
fy.year as fiscal_year_nr,
|
||||||
|
|
@ -122,6 +125,7 @@ class Beleg
|
||||||
'SELECT b.*,
|
'SELECT b.*,
|
||||||
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
(SELECT SUM(bk.betrag_brutto) FROM bookings bk
|
||||||
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL
|
WHERE bk.beleg_id = b.id AND bk.is_reversal = 0 AND bk.parent_booking_id IS NULL AND bk.reversed_by IS NULL
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM accounts az WHERE az.id = bk.zahlungskonto_id AND az.kontonummer = \'1800\')
|
||||||
) AS betrag_brutto,
|
) AS betrag_brutto,
|
||||||
fy.year as fiscal_year_nr,
|
fy.year as fiscal_year_nr,
|
||||||
s.name as supplier_name,
|
s.name as supplier_name,
|
||||||
|
|
|
||||||
111
tests/40_BelegBruttoBereinigungTest.php
Normal file
111
tests/40_BelegBruttoBereinigungTest.php
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Steuerkram\Models\Beleg;
|
||||||
|
use Steuerkram\Models\Booking;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 40: Belegsumme ignoriert steuerliche Umbuchungen auf Konto 1800.
|
||||||
|
*
|
||||||
|
* Eine Buchung mit zahlungskonto_id = 1800 ist eine steuerliche Wirksamkeitsumbuchung
|
||||||
|
* (z.B. Vorsteuerkorrektur). Sie darf nicht in die angezeigte Belegsumme einfließen,
|
||||||
|
* weil sie keine Gegenbuchung erzeugt und den Betrag künstlich erhöht.
|
||||||
|
*/
|
||||||
|
class BelegBruttoBereinigungTest extends TestCase
|
||||||
|
{
|
||||||
|
protected string $testName = 'Test 40: Belegsumme – Umbuchungen auf Konto 1800 ausgeblendet';
|
||||||
|
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$bankId = $this->findAccountId('1200');
|
||||||
|
$umbuchungId = $this->findAccountId('1800');
|
||||||
|
$ausgabeId = $this->findAccountId('4920');
|
||||||
|
|
||||||
|
if (!$bankId || !$umbuchungId || !$ausgabeId) {
|
||||||
|
$this->assert(false, 'Benötigte Konten (1200, 1800, 4920) fehlen – SKR03-Seed vorhanden?');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$datum = date('Y-m-d');
|
||||||
|
$belegId = Beleg::create([
|
||||||
|
'beleg_nr' => 'TEST-1800-' . uniqid(),
|
||||||
|
'filename' => 'umbuchung-test.pdf',
|
||||||
|
'storage_path' => '',
|
||||||
|
'mime_type' => 'application/pdf',
|
||||||
|
'file_hash' => hash('sha256', 'umbuchung-test-' . uniqid()),
|
||||||
|
'beleg_datum' => $datum,
|
||||||
|
'belegtyp' => 'Eingangsrechnung',
|
||||||
|
]);
|
||||||
|
$this->assertGreaterThan(0, $belegId, 'Beleg angelegt');
|
||||||
|
|
||||||
|
// Normale Buchung: 100 € netto + 19 % = 119 € brutto
|
||||||
|
Booking::create([
|
||||||
|
'beleg_id' => $belegId,
|
||||||
|
'buchungs_datum' => $datum,
|
||||||
|
'buchungstyp' => 'Ausgabe',
|
||||||
|
'kategorie_konto_id' => $ausgabeId,
|
||||||
|
'zahlungskonto_id' => $bankId,
|
||||||
|
'betrag_netto' => 100.00,
|
||||||
|
'ust_satz' => 19.0,
|
||||||
|
'buchungstext' => 'Normale Buchung',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Steuerliche Umbuchung auf Konto 1800 (darf nicht in Belegsumme einfließen)
|
||||||
|
Booking::create([
|
||||||
|
'beleg_id' => $belegId,
|
||||||
|
'buchungs_datum' => $datum,
|
||||||
|
'buchungstyp' => 'Ausgabe',
|
||||||
|
'kategorie_konto_id' => $ausgabeId,
|
||||||
|
'zahlungskonto_id' => $umbuchungId,
|
||||||
|
'betrag_netto' => 50.00,
|
||||||
|
'ust_satz' => 0.0,
|
||||||
|
'buchungstext' => 'Steuerliche Umbuchung 1800',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Beleg::find() darf nur 119,00 liefern (nicht 169,00)
|
||||||
|
$beleg = Beleg::find($belegId);
|
||||||
|
$this->assertEquals(
|
||||||
|
119.00,
|
||||||
|
round((float)($beleg['betrag_brutto'] ?? 0), 2),
|
||||||
|
'Beleg::find() – betrag_brutto = 119,00 (ohne Konto-1800-Umbuchung)'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Beleg::all() – dieselbe Filterung in der Listenansicht
|
||||||
|
$result = Beleg::all([], 1, 9999);
|
||||||
|
$found = null;
|
||||||
|
foreach ($result['rows'] as $row) {
|
||||||
|
if ((int)$row['id'] === $belegId) {
|
||||||
|
$found = $row;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->assert($found !== null, 'Beleg erscheint in Beleg::all()');
|
||||||
|
$this->assertEquals(
|
||||||
|
119.00,
|
||||||
|
round((float)($found['betrag_brutto'] ?? 0), 2),
|
||||||
|
'Beleg::all() – betrag_brutto = 119,00 (ohne Konto-1800-Umbuchung)'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Brutto-Suche findet den Beleg über 119,00 – nicht über 169,00
|
||||||
|
$resHit = Beleg::all(['search' => '119.00'], 1, 9999);
|
||||||
|
$foundByBrutto = false;
|
||||||
|
foreach ($resHit['rows'] as $row) {
|
||||||
|
if ((int)$row['id'] === $belegId) {
|
||||||
|
$foundByBrutto = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->assert($foundByBrutto, 'Brutto-Suche nach 119.00 findet den Beleg');
|
||||||
|
|
||||||
|
$resMiss = Beleg::all(['search' => '169.00'], 1, 9999);
|
||||||
|
$foundByWrong = false;
|
||||||
|
foreach ($resMiss['rows'] as $row) {
|
||||||
|
if ((int)$row['id'] === $belegId) {
|
||||||
|
$foundByWrong = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->assert(!$foundByWrong, 'Brutto-Suche nach 169.00 findet den Beleg NICHT');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue