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;
|
||||
InvoiceStatus::INVOICE_STATUS_DENIED,
|
||||
InvoiceStatus::INVOICE_STATUS_DELETED,
|
||||
], true);
|
||||
}
|
||||
|
||||
public function sumupEstimatedByInvoiceType(CostUnit $costUnit, InvoiceType $invoiceType) : Amount {
|
||||
|
||||
Reference in New Issue
Block a user