$bericht Rückgabe von Auswertung::bericht() */ public static function csv(array $bericht): string { $zeilen = match ($bericht['darstellung']) { 'buchungen' => self::buchungen($bericht), 'kontostaende' => self::kontostaende($bericht), 'budget' => self::budget($bericht), default => self::summen($bericht), }; $kopf = [ [$bericht['name'] ?? $bericht['typname']], [$bericht['beschriftung'] . ' (in Euro)'], [], ]; return CsvTabelle::schreibe(array_merge($kopf, $zeilen)); } /** Dateiname ohne Pfad, aus Berichtsname und Zeitraum. */ public static function dateiname(array $bericht): string { $roh = ($bericht['name'] ?? $bericht['typname']) . '-' . ($bericht['zeitraum']['von'] ?? ''); $sauber = preg_replace('/[^A-Za-z0-9_.-]+/', '-', self::umlaute($roh)) ?? 'bericht'; return trim($sauber, '-') . '.csv'; } /** * @param array $bericht * @return list> */ private static function summen(array $bericht): array { $spalten = array_column($bericht['spalten'], 'titel'); $extra = empty($bericht['vergleich']) ? [] : ['Differenz', 'Veränderung in %']; $zeilen = [array_merge(['Bezeichnung'], $spalten, $extra, ['Summe'])]; foreach ($bericht['abschnitte'] as $abschnitt) { $zeilen[] = [$abschnitt['name']]; foreach ($abschnitt['zeilen'] as $zeile) { $zeilen[] = self::wertzeile( // Die Einrückung des Baums als führende Leerzeichen: In einer // Tabellenkalkulation ist die Hierarchie sonst verloren. str_repeat(' ', (int)$zeile['ebene']) . $zeile['name'], $zeile, $bericht ); } $zeilen[] = self::wertzeile('Gesamt ' . $abschnitt['name'], $abschnitt, $bericht); $zeilen[] = []; } $zeilen[] = self::wertzeile($bericht['gesamt']['name'], $bericht['gesamt'], $bericht); return $zeilen; } /** * @param array $zeile * @param array $bericht * @return list */ private static function wertzeile(string $name, array $zeile, array $bericht): array { $werte = array_map(self::zahl(...), array_values($zeile['werte'])); if (!empty($bericht['vergleich'])) { $werte[] = self::zahl((float)($zeile['differenz'] ?? 0)); $werte[] = $zeile['prozent'] === null ? '' : self::zahl((float)$zeile['prozent'], 1); } $werte[] = self::zahl((float)$zeile['summe']); return array_merge([$name], $werte); } /** * @param array $bericht * @return list> */ private static function buchungen(array $bericht): array { $zeilen = [['Gruppe', 'Datum', 'Konto', 'Empfänger', 'Buchungstext', 'Kategorie', 'Klasse', 'Betrag']]; foreach ($bericht['gruppen'] as $gruppe) { foreach ($gruppe['buchungen'] as $buchung) { $zeilen[] = [ $gruppe['name'], View::datum($buchung['datum']), $buchung['konto'], $buchung['empfaenger'], $buchung['text'], $buchung['kategorie'], $buchung['klasse'], self::zahl($buchung['betrag']), ]; } $zeilen[] = ['Gesamt ' . $gruppe['name'], '', '', '', '', '', '', self::zahl($gruppe['summe'])]; } $zeilen[] = []; $zeilen[] = ['Gesamt', '', '', '', '', '', '', self::zahl($bericht['summe'])]; return $zeilen; } /** * @param array $bericht * @return list> */ private static function kontostaende(array $bericht): array { $zeilen = [array_merge(['Konto', 'Kontengruppe'], array_column($bericht['spalten'], 'titel'))]; foreach ($bericht['zeilen'] as $zeile) { $zeilen[] = array_merge( [$zeile['name'], $zeile['gruppe']], array_map(self::zahl(...), array_values($zeile['werte'])) ); } $zeilen[] = array_merge( [$bericht['gesamt']['name'], ''], array_map(self::zahl(...), array_values($bericht['gesamt']['werte'])) ); return $zeilen; } /** * @param array $bericht * @return list> */ private static function budget(array $bericht): array { $zeilen = [['Kategorie', 'Budget', 'Ist', 'Saldo']]; foreach ($bericht['zeilen'] as $zeile) { $zeilen[] = [ str_repeat(' ', (int)$zeile['ebene']) . $zeile['name'], self::zahl($zeile['budget']), self::zahl($zeile['ist']), self::zahl($zeile['saldo']), ]; } $gesamt = $bericht['gesamt']; $zeilen[] = [$gesamt['name'], self::zahl($gesamt['budget']), self::zahl($gesamt['ist']), self::zahl($gesamt['saldo'])]; return $zeilen; } private static function zahl(float $wert, int $stellen = 2): string { return CsvTabelle::zahl($wert, $stellen); } /** Umlaute im Dateinamen ausschreiben, statt sie zu Bindestrichen zu zermahlen. */ private static function umlaute(string $text): string { return strtr($text, [ 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'ß' => 'ss', ]); } }