= 2020; $y--) $years[] = $y; $view = new View(); $view->render('layout/base.php', [ 'pageTitle' => 'Umsatzsteuervoranmeldung', 'content' => $this->renderView('tax/ustva_index', [ 'submissions' => $submissions, 'years' => $years, ]), ]); } public function show(array $params): void { $year = (int)$params['year']; $month = (int)$params['month']; if ($month < 1 || $month > 12) { View::redirect('/tax/ustva', 'Ungültiger Monat.', 'error'); return; } $calc = new UstvaCalculator(); $kz = $calc->calculate($year, $month); // Load saved submission if exists $saved = Database::fetchOne( 'SELECT * FROM ustva_submissions WHERE year=? AND month=?', [$year, $month] ); $settings = Setting::get(); $months = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']; $view = new View(); $view->render('layout/base.php', [ 'pageTitle' => "UStVA {$months[$month-1]} {$year}", 'content' => $this->renderView('tax/ustva_show', [ 'year' => $year, 'month' => $month, 'kz' => $kz, 'saved' => $saved, 'settings' => $settings, 'months' => $months, ]), 'topbarActions' => 'ELSTER XML herunterladen', ]); } public function save(array $params): void { $year = (int)$params['year']; $month = (int)$params['month']; $calc = new UstvaCalculator(); $kz = $calc->calculate($year, $month); $xmlSvc = new ElsterXmlService(); $xml = $xmlSvc->generate($year, $month, $kz); // Upsert $existing = Database::fetchOne( 'SELECT id FROM ustva_submissions WHERE year=? AND month=?', [$year, $month] ); if ($existing) { Database::execute( 'UPDATE ustva_submissions SET xml_content=?, field_values=? WHERE year=? AND month=?', [$xml, json_encode($kz, JSON_UNESCAPED_UNICODE), $year, $month] ); } else { Database::execute( 'INSERT INTO ustva_submissions (year, month, xml_content, field_values) VALUES (?,?,?,?)', [$year, $month, $xml, json_encode($kz, JSON_UNESCAPED_UNICODE)] ); } View::redirect("/tax/ustva/{$year}/{$month}", 'UStVA gespeichert.'); } public function showKzBookings(array $params): void { $year = (int)$params['year']; $month = (int)$params['month']; $kz = $params['kz'] ?? ''; $validKz = ['81', '89', '66', '61', '83']; if (!in_array($kz, $validKz, true)) { View::redirect("/tax/ustva/{$year}/{$month}", 'Ungültige Kennzahl.', 'error'); return; } $calc = new UstvaCalculator(); $kzData = $calc->calculate($year, $month); $bookings = $calc->fetchBookingsForKz($year, $month, $kz); $months = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']; $view = new View(); $view->render('layout/base.php', [ 'pageTitle' => "Kz {$kz} – {$months[$month-1]} {$year}", 'content' => $this->renderView('tax/ustva_kz_bookings', [ 'year' => $year, 'month' => $month, 'kz' => $kz, 'kzName' => $kzData[$kz]['name'] ?? '', 'bookings' => $bookings, 'months' => $months, ]), ]); } public function downloadXml(array $params): void { $year = (int)$params['year']; $month = (int)$params['month']; // Recalculate fresh $calc = new UstvaCalculator(); $kz = $calc->calculate($year, $month); $xmlSvc = new ElsterXmlService(); $xml = $xmlSvc->generate($year, $month, $kz); $filename = sprintf('UStVA_%04d_%02d.xml', $year, $month); header('Content-Type: application/xml; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Content-Length: ' . strlen($xml)); echo $xml; } }