Verbesserte EÜR-Abrechnung
This commit is contained in:
+33
-5
@@ -5,6 +5,7 @@ namespace App\Domains\Event\Actions\CreateIncomeSurplusStatement;
|
||||
use App\Enumerations\ParticipationType;
|
||||
use App\Models\CostUnit;
|
||||
use App\Models\Event;
|
||||
use App\Models\Invoice;
|
||||
use App\Providers\PdfGenerateAndDownloadProvider;
|
||||
use App\Repositories\CostUnitRepository;
|
||||
use App\ValueObjects\Amount;
|
||||
@@ -52,8 +53,9 @@ class CreateIncomeSurplusStatementCommand
|
||||
|
||||
$eventData = $this->event->toResource()->toArray(new Request());
|
||||
|
||||
$income = $this->buildIncome($eventData, $otherIncome);
|
||||
$expenses = $this->buildExpenses($costUnit);
|
||||
$donations = $this->buildExpenses($costUnit, donationsOnly: true);
|
||||
$income = $this->buildIncome($eventData, $otherIncome, $donations['total']);
|
||||
|
||||
$result = new Amount($income['total']->getAmount() - $expenses['total']->getAmount(), 'Euro');
|
||||
|
||||
@@ -62,6 +64,7 @@ class CreateIncomeSurplusStatementCommand
|
||||
'createdAt' => new \DateTime()->format('d.m.Y'),
|
||||
'income' => $income,
|
||||
'expenses' => $expenses,
|
||||
'donations' => $donations,
|
||||
'result' => $result,
|
||||
'money' => self::money(...),
|
||||
])->render();
|
||||
@@ -70,6 +73,7 @@ class CreateIncomeSurplusStatementCommand
|
||||
$response->filename = 'EUER-' . $this->event->identifier . '.pdf';
|
||||
$response->income = $income;
|
||||
$response->expenses = $expenses;
|
||||
$response->donations = $donations;
|
||||
$response->result = $result;
|
||||
$response->pdfContent = PdfGenerateAndDownloadProvider::fromHtml($html, 'portrait');
|
||||
|
||||
@@ -87,7 +91,7 @@ class CreateIncomeSurplusStatementCommand
|
||||
*
|
||||
* @return array{categories: array<int, array{name: string, total: Amount, entries: array<int, array{name: string, amount: Amount}>}>, total: Amount}
|
||||
*/
|
||||
private function buildIncome(array $eventData, float $otherIncome): array
|
||||
private function buildIncome(array $eventData, float $otherIncome, Amount $donations): array
|
||||
{
|
||||
// Beiträge aller Teilnahmearten in einer Zeile: Für die Mittelverwendung zählt, was an Beiträgen
|
||||
// hereingekommen ist, nicht von wem.
|
||||
@@ -118,6 +122,8 @@ class CreateIncomeSurplusStatementCommand
|
||||
'name' => 'Fördermittel (' . self::money($supportRate) . ' € p.P./Tag)',
|
||||
'amount' => new Amount($eventData['supportPerson']['amount']->getAmount(), 'Euro'),
|
||||
],
|
||||
// Gespendete Auslagen: als Ausgabe ihres Typs gebucht, hier die Gegenbuchung.
|
||||
['name' => 'Spenden', 'amount' => $donations],
|
||||
];
|
||||
|
||||
$categories = [
|
||||
@@ -134,14 +140,17 @@ class CreateIncomeSurplusStatementCommand
|
||||
/**
|
||||
* Die Ausgabenseite: eine Zeile je Ausgabentyp, dazu die Belege für die Anlage.
|
||||
*
|
||||
* Mit `$donationsOnly` nur die gespendeten Auslagen in derselben Gliederung -- für die Anlage „Spenden"
|
||||
* und die Summe unter den Förderungen.
|
||||
*
|
||||
* @return array{groups: array<int, array{name: string, sum: Amount, rows: array<int, array{number: string, date: string, purpose: string, amount: Amount}>}>, total: Amount}
|
||||
*/
|
||||
private function buildExpenses(CostUnit $costUnit): array
|
||||
private function buildExpenses(CostUnit $costUnit, bool $donationsOnly = false): array
|
||||
{
|
||||
$groups = [];
|
||||
$total = new Amount(0, 'Euro');
|
||||
|
||||
foreach ($this->costUnits->groupExpensesByType($costUnit) as $group) {
|
||||
foreach ($this->costUnits->groupExpensesByType($costUnit, $donationsOnly) as $group) {
|
||||
$rows = [];
|
||||
|
||||
foreach ($group['invoices'] as $invoice) {
|
||||
@@ -150,7 +159,7 @@ class CreateIncomeSurplusStatementCommand
|
||||
'date' => $invoice->created_at?->format('d.m.Y') ?? '',
|
||||
// Ohne die Anmerkung: dort steht, was die Kassenwart*in beim Korrigieren notiert hat,
|
||||
// und das gehört auf den Beleg, nicht in den Zweck.
|
||||
'purpose' => $invoice->purposeText(),
|
||||
'purpose' => self::purpose($invoice),
|
||||
'amount' => Amount::fromString($invoice->amount),
|
||||
];
|
||||
}
|
||||
@@ -167,6 +176,25 @@ class CreateIncomeSurplusStatementCommand
|
||||
return ['groups' => $groups, 'total' => $total];
|
||||
}
|
||||
|
||||
/**
|
||||
* Der Zweck eines Belegs für die Anlage.
|
||||
*
|
||||
* Erfasster oder abgeleiteter Zahlungsgrund wie in der Beleg-Übersicht. Nur wenn es keinen gibt --
|
||||
* ältere Abrechnungen ohne jede Zweckangabe --, steht dort ersatzweise, wem was erstattet wurde. Bewusst
|
||||
* hier und nicht in {@see Invoice::purposeText()}: Dort würde der Ersatztext als erfasster Zahlungsgrund
|
||||
* erscheinen und beim Korrigieren als Änderung protokolliert.
|
||||
*/
|
||||
private static function purpose(Invoice $invoice): string
|
||||
{
|
||||
$purpose = $invoice->purposeText();
|
||||
|
||||
if (trim($purpose) !== '') {
|
||||
return $purpose;
|
||||
}
|
||||
|
||||
return trim('Auslagenerstattung ' . $invoice->contact_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ein Betrag in deutscher Schreibweise: Punkt als Tausender-, Komma als Dezimaltrennzeichen.
|
||||
*
|
||||
|
||||
+7
@@ -29,5 +29,12 @@ class CreateIncomeSurplusStatementResponse
|
||||
*/
|
||||
public array $expenses = [];
|
||||
|
||||
/**
|
||||
* Die gespendeten Auslagen, gegliedert wie die Ausgaben -- die Gegenbuchung zur Zeile „Spenden".
|
||||
*
|
||||
* @var array{groups: array<int, array{name: string, sum: Amount, rows: array<int, array<string, mixed>>}>, total: Amount}|array{}
|
||||
*/
|
||||
public array $donations = [];
|
||||
|
||||
public ?Amount $result = null;
|
||||
}
|
||||
|
||||
@@ -172,9 +172,13 @@ class CostUnitRepository {
|
||||
* damit immer dieselbe Gliederung, und eine fehlende Zeile lässt sich nicht mit einer vergessenen
|
||||
* verwechseln.
|
||||
*
|
||||
* Gespendete Auslagen zählen hier mit: Für die Einnahmen-Überschuss-Rechnung ist die Spende eine Ausgabe
|
||||
* ihres Typs und zugleich eine Einnahme. Mit `$donationsOnly` liefert die Methode genau diesen Spendenanteil
|
||||
* in derselben Gliederung -- die Gegenbuchungen lassen sich so ihrer Ausgabenkategorie zuordnen.
|
||||
*
|
||||
* @return array<string, array{type: InvoiceType, invoices: array<int, Invoice>, sum: Amount}>
|
||||
*/
|
||||
public function groupExpensesByType(CostUnit $costUnit) : array {
|
||||
public function groupExpensesByType(CostUnit $costUnit, bool $donationsOnly = false) : array {
|
||||
$groups = [];
|
||||
|
||||
foreach (InvoiceType::countingAsExpense() as $invoiceType) {
|
||||
@@ -186,7 +190,11 @@ class CostUnitRepository {
|
||||
}
|
||||
|
||||
foreach ($costUnit->invoices()->orderBy('invoice_number')->get() as $invoice) {
|
||||
if (!self::countsAsExpense($invoice) || !isset($groups[$invoice->type])) {
|
||||
if (
|
||||
!self::isBooked($invoice) ||
|
||||
!isset($groups[$invoice->type]) ||
|
||||
($donationsOnly && !$invoice->donation)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -201,14 +209,22 @@ class CostUnitRepository {
|
||||
* Ob ein Beleg als Ausgabe zählt.
|
||||
*
|
||||
* Abgelehnt und gelöscht sind keine Ausgabe, weil kein Geld fließt. Dasselbe gilt für eine gespendete
|
||||
* Auslage: Auf die Auszahlung wurde verzichtet, die Kostenstelle gibt nichts aus.
|
||||
* Auslage: Auf die Auszahlung wurde verzichtet, die Kostenstelle gibt nichts aus. Die Einnahmen-Überschuss-
|
||||
* Rechnung sieht das anders und bucht die Spende als Ausgabe und Einnahme, siehe
|
||||
* {@see self::groupExpensesByType()}.
|
||||
*/
|
||||
private static function countsAsExpense(Invoice $invoice) : bool {
|
||||
return self::isBooked($invoice) && !$invoice->donation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ob ein Beleg überhaupt gebucht ist -- abgelehnt und gelöscht sind es nicht.
|
||||
*/
|
||||
private static function isBooked(Invoice $invoice) : bool {
|
||||
return !in_array($invoice->status, [
|
||||
InvoiceStatus::INVOICE_STATUS_DENIED,
|
||||
InvoiceStatus::INVOICE_STATUS_DELETED,
|
||||
], true)
|
||||
&& !$invoice->donation;
|
||||
], true);
|
||||
}
|
||||
|
||||
public function sumupEstimatedByInvoiceType(CostUnit $costUnit, InvoiceType $invoiceType) : Amount {
|
||||
|
||||
@@ -186,8 +186,8 @@
|
||||
|
||||
<div class="footnote">
|
||||
Berücksichtigt sind nur tatsächlich vereinnahmte Beiträge und erfasste Belege. Nicht enthalten sind
|
||||
offene Beiträge, Budget- und Schätzwerte, erstattete Beiträge sowie Auslagen, auf deren Auszahlung
|
||||
verzichtet wurde.
|
||||
offene Beiträge, Budget- und Schätzwerte sowie erstattete Beiträge. Gespendete Auslagen sind bei den
|
||||
Ausgaben enthalten und zugleich als Spenden unter den Förderungen ausgewiesen.
|
||||
@if($event->tax_liable)
|
||||
<br />Alle Beträge sind Bruttobeträge inklusive {{ $event->vat_rate }} % Umsatzsteuer.
|
||||
@endif
|
||||
@@ -203,33 +203,27 @@
|
||||
<h1>Anlage: Belege</h1>
|
||||
<div class="subline">{{ $event->name }} · Stand: {{ $createdAt }}</div>
|
||||
|
||||
@foreach($documentedGroups as $group)
|
||||
<h3>{{ $group['name'] }}</h3>
|
||||
<table class="receipts">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 22mm;">Beleg-Nr.</th>
|
||||
<th style="width: 18mm;">Datum</th>
|
||||
<th>Zweck</th>
|
||||
<th class="value">Betrag</th>
|
||||
@include('pdfs.partials.receipt-groups', ['groups' => $documentedGroups])
|
||||
@endif
|
||||
|
||||
@php
|
||||
$donatedGroups = array_filter($donations['groups'], fn ($group) => count($group['rows']) > 0);
|
||||
@endphp
|
||||
|
||||
@if(count($donatedGroups) > 0)
|
||||
<div class="page-break"></div>
|
||||
|
||||
<h1>Anlage: Spenden</h1>
|
||||
<div class="subline">{{ $event->name }} · Stand: {{ $createdAt }}</div>
|
||||
|
||||
@include('pdfs.partials.receipt-groups', ['groups' => $donatedGroups])
|
||||
|
||||
<table class="statement">
|
||||
<tr class="sum">
|
||||
<td>Summe Spenden</td>
|
||||
<td class="value">{{ $money($donations['total']) }} €</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($group['rows'] as $row)
|
||||
<tr>
|
||||
<td>{{ $row['number'] }}</td>
|
||||
<td>{{ $row['date'] }}</td>
|
||||
<td>{{ $row['purpose'] }}</td>
|
||||
<td class="value">{{ $money($row['amount']) }} €</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr class="group-sum">
|
||||
<td colspan="3">Zwischensumme {{ $group['name'] }}</td>
|
||||
<td class="value">{{ $money($group['sum']) }} €</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{{-- Belege je Ausgabentyp mit Zwischensumme; nur Gruppen mit Belegen übergeben. --}}
|
||||
@foreach($groups as $group)
|
||||
<h3>{{ $group['name'] }}</h3>
|
||||
<table class="receipts">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 22mm;">Beleg-Nr.</th>
|
||||
<th style="width: 18mm;">Datum</th>
|
||||
<th>Zweck</th>
|
||||
<th class="value">Betrag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($group['rows'] as $row)
|
||||
<tr>
|
||||
<td>{{ $row['number'] }}</td>
|
||||
<td>{{ $row['date'] }}</td>
|
||||
<td>{{ $row['purpose'] }}</td>
|
||||
<td class="value">{{ $money($row['amount']) }} €</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr class="group-sum">
|
||||
<td colspan="3">Zwischensumme {{ $group['name'] }}</td>
|
||||
<td class="value">{{ $money($group['sum']) }} €</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@endforeach
|
||||
@@ -202,11 +202,95 @@ class EventIncomeSurplusStatementTest extends TestCase
|
||||
// Kein Geldfluss, also keine Ausgabe:
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 999.0, InvoiceStatus::INVOICE_STATUS_DENIED);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 888.0, InvoiceStatus::INVOICE_STATUS_DELETED);
|
||||
|
||||
// Eine Spende ist Ausgabe ihres Typs (und zugleich Einnahme unter den Förderungen):
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 777.0, InvoiceStatus::INVOICE_STATUS_NEW, donation: true);
|
||||
|
||||
$this->assertEqualsWithDelta(150.0, $this->group('Programmkosten')['sum']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(927.0, $this->group('Programmkosten')['sum']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(30.0, $this->group('Verpflegungskosten')['sum']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(180.0, $this->statement()->expenses['total']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(957.0, $this->statement()->expenses['total']->getAmount(), 0.001);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Spenden
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function test_without_donations_the_donation_line_is_zero(): void
|
||||
{
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 100.0, InvoiceStatus::INVOICE_STATUS_NEW);
|
||||
|
||||
$this->assertEqualsWithDelta(0.0, $this->entry('Spenden')->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(0.0, $this->statement()->donations['total']->getAmount(), 0.001);
|
||||
}
|
||||
|
||||
public function test_a_donation_is_an_expense_of_its_type_and_funding_income(): void
|
||||
{
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 100.0, InvoiceStatus::INVOICE_STATUS_NEW);
|
||||
$resultWithoutDonation = $this->statement()->result->getAmount();
|
||||
|
||||
$donated = $this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 40.0, InvoiceStatus::INVOICE_STATUS_APPROVED, donation: true);
|
||||
|
||||
$statement = $this->statement();
|
||||
$program = $this->group('Programmkosten');
|
||||
|
||||
$this->assertEqualsWithDelta(140.0, $program['sum']->getAmount(), 0.001);
|
||||
$this->assertContains($donated->invoice_number, array_column($program['rows'], 'number'));
|
||||
|
||||
// Gegenbuchung unter den Förderungen (ohne Anmeldung keine Fördermittel, also nur die Spende).
|
||||
$this->assertSame('Förderungen', $statement->income['categories'][1]['name']);
|
||||
$this->assertEqualsWithDelta(40.0, $this->entry('Spenden')->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(40.0, $statement->income['categories'][1]['total']->getAmount(), 0.001);
|
||||
|
||||
// Ausgabe und Einnahme heben sich auf.
|
||||
$this->assertEqualsWithDelta($resultWithoutDonation, $statement->result->getAmount(), 0.001);
|
||||
}
|
||||
|
||||
public function test_donations_are_grouped_like_expenses(): void
|
||||
{
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 100.0, InvoiceStatus::INVOICE_STATUS_NEW);
|
||||
$programDonation = $this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 25.0, InvoiceStatus::INVOICE_STATUS_NEW, donation: true);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 15.0, InvoiceStatus::INVOICE_STATUS_EXPORTED, donation: true);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_CATERING, 60.0, InvoiceStatus::INVOICE_STATUS_APPROVED, donation: true);
|
||||
|
||||
$donations = $this->statement()->donations;
|
||||
|
||||
// Dieselbe Gliederung wie die Ausgaben, auch Typen ohne Spende stehen darin.
|
||||
$this->assertSame(
|
||||
array_column($this->statement()->expenses['groups'], 'name'),
|
||||
array_column($donations['groups'], 'name')
|
||||
);
|
||||
|
||||
$this->assertEqualsWithDelta(40.0, $this->donationGroup('Programmkosten')['sum']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(60.0, $this->donationGroup('Verpflegungskosten')['sum']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(100.0, $donations['total']->getAmount(), 0.001);
|
||||
$this->assertEqualsWithDelta(100.0, $this->entry('Spenden')->getAmount(), 0.001);
|
||||
|
||||
// Derselbe Beleg steht als Ausgabe und als Spende.
|
||||
$this->assertContains($programDonation->invoice_number, array_column($this->group('Programmkosten')['rows'], 'number'));
|
||||
$this->assertContains($programDonation->invoice_number, array_column($this->donationGroup('Programmkosten')['rows'], 'number'));
|
||||
|
||||
// Nicht gespendete Belege stehen nicht in der Spenden-Anlage.
|
||||
$this->assertCount(2, $this->donationGroup('Programmkosten')['rows']);
|
||||
}
|
||||
|
||||
public function test_donations_list_only_booked_donations(): void
|
||||
{
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 20.0, InvoiceStatus::INVOICE_STATUS_NEW, donation: true);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 999.0, InvoiceStatus::INVOICE_STATUS_DENIED, donation: true);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 888.0, InvoiceStatus::INVOICE_STATUS_DELETED, donation: true);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PARTICIPATION_REFUND, 220.0, InvoiceStatus::INVOICE_STATUS_EXPORTED, donation: true);
|
||||
|
||||
$donations = $this->statement()->donations;
|
||||
|
||||
$this->assertEqualsWithDelta(20.0, $donations['total']->getAmount(), 0.001);
|
||||
$this->assertCount(1, $this->donationGroup('Programmkosten')['rows']);
|
||||
$this->assertNotContains('Beitragserstattung', array_column($donations['groups'], 'name'));
|
||||
}
|
||||
|
||||
public function test_a_refund_is_no_expense(): void
|
||||
@@ -311,12 +395,34 @@ class EventIncomeSurplusStatementTest extends TestCase
|
||||
public function test_the_comment_is_no_longer_part_of_the_purpose(): void
|
||||
{
|
||||
// Die Anmerkung trägt, was die Kassenwart*in beim Korrigieren notiert hat -- sie steht auf dem
|
||||
// Beleg-PDF und hat im Zweck nichts zu suchen. Bestandsbelege ohne erfassten Zahlungsgrund haben
|
||||
// hier deshalb eine leere Zelle; nachtragen lässt er sich beim Korrigieren.
|
||||
// Beleg-PDF und hat im Zweck nichts zu suchen.
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 100.0, InvoiceStatus::INVOICE_STATUS_NEW);
|
||||
|
||||
$this->assertSame('', $this->group('Programmkosten')['rows'][0]['purpose']);
|
||||
$this->assertStringNotContainsString('Materialkauf', $this->group('Programmkosten')['rows'][0]['purpose']);
|
||||
}
|
||||
|
||||
public function test_an_empty_purpose_falls_back_to_the_refund_of_the_contact(): void
|
||||
{
|
||||
// Ältere Abrechnungen ohne jede Zweckangabe: ersatzweise, wem erstattet wurde -- als Ausgabe wie als Spende.
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 100.0, InvoiceStatus::INVOICE_STATUS_NEW);
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 30.0, InvoiceStatus::INVOICE_STATUS_NEW, donation: true);
|
||||
$this->makeInvoice(
|
||||
InvoiceType::INVOICE_TYPE_PROGRAM,
|
||||
50.0,
|
||||
InvoiceStatus::INVOICE_STATUS_NEW,
|
||||
purpose: 'Material für den Bastelnachmittag'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['Auslagenerstattung Mika Muster', 'Auslagenerstattung Mika Muster', 'Material für den Bastelnachmittag'],
|
||||
array_column($this->group('Programmkosten')['rows'], 'purpose')
|
||||
);
|
||||
$this->assertSame(
|
||||
['Auslagenerstattung Mika Muster'],
|
||||
array_column($this->donationGroup('Programmkosten')['rows'], 'purpose')
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -388,6 +494,20 @@ class EventIncomeSurplusStatementTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function test_a_donation_still_does_not_count_in_the_expense_overview(): void
|
||||
{
|
||||
// Die Bildschirm-Übersicht kennt keine Spenden-Einnahme -- dort bleibt die Spende außen vor.
|
||||
$this->makeEvent();
|
||||
$this->makeInvoice(InvoiceType::INVOICE_TYPE_PROGRAM, 777.0, InvoiceStatus::INVOICE_STATUS_NEW, donation: true);
|
||||
|
||||
$amount = new CostUnitRepository()->sumupByInvoiceType(
|
||||
$this->costUnit->fresh(),
|
||||
InvoiceType::where('slug', InvoiceType::INVOICE_TYPE_PROGRAM)->first()
|
||||
);
|
||||
|
||||
$this->assertEqualsWithDelta(0.0, $amount->getAmount(), 0.001);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Helfer
|
||||
@@ -435,6 +555,18 @@ class EventIncomeSurplusStatementTest extends TestCase
|
||||
$this->fail('Ausgaben-Gruppe "' . $name . '" fehlt.');
|
||||
}
|
||||
|
||||
/** @return array{name: string, sum: Amount, rows: array<int, array<string, mixed>>} */
|
||||
private function donationGroup(string $name): array
|
||||
{
|
||||
foreach ($this->statement()->donations['groups'] as $group) {
|
||||
if ($group['name'] === $name) {
|
||||
return $group;
|
||||
}
|
||||
}
|
||||
|
||||
$this->fail('Spenden-Gruppe "' . $name . '" fehlt.');
|
||||
}
|
||||
|
||||
private function makeEvent(): Event
|
||||
{
|
||||
$fee = EventParticipationFee::create([
|
||||
|
||||
Reference in New Issue
Block a user