Baustein 7: Berichtsheft mit Vorschlaegen, Pruefung, Abzeichnen und PDF
- Taegliche Stichworte, je Tag ein eigenes Formular - Wochenblatt mit Betrieb, Berufsschule und Sonstiges, je mit Stunden - Vorschlaege aus Tagesnotizen, Aufgaben, Checklisten und Handouts - Pruefung mitlaufend beim Tippen: fehlende Stunden, Floskeln, IP- und MAC-Adressen, E-Mail, Zugangsdaten, Kundennamen - Warnung, keine Sperre - Einreichen ist immer moeglich - Formulierungshilfe mit Taetigkeitsverben und Gegenueberstellungen - Einreichen, zurueckgeben mit Anmerkung, abzeichnen; danach gesperrt - Fehlende Wochen werden benannt und lassen sich nachtragen; die laufende Nummer richtet sich nach dem Zeitraum, nicht nach dem Anlegen - PDF im IHK-Layout, einzeln oder als ganzer Zeitraum Behoben: Im PDF-Kopffeld liefen die Spalten auseinander (dokument.y als Bezugspunkt in der Schleife). Das Abzeichnen-Formular hatte keine action - gefunden ueber die ESLint-Meldung zur ungenutzten Serveraktion. 55 neue Tests, insgesamt 241. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b9d6041f3b
commit
7c4a051347
@@ -0,0 +1,52 @@
|
||||
import { benutzerNachId } from '@/lib/repos/benutzer';
|
||||
import { ausbildungNachAzubi } from '@/lib/repos/ausbildung';
|
||||
import { alsWochenblatt } from '@/lib/repos/berichtsheft';
|
||||
import { berichtsheftPdf } from '@/lib/pdf/berichtsheft';
|
||||
import { alsDatumText, alsZeitpunktText } from '@/lib/zeit';
|
||||
import { ausbildungsjahr } from '@/lib/berichtsheft/jahr';
|
||||
import { blattZumLesen } from '../../aktionen';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
/** Ein einzelnes Wochenblatt als PDF. Rechteprüfung über `blattZumLesen`. */
|
||||
export async function GET(_anfrage: Request, kontext: { params: Promise<{ berichtId: string }> }) {
|
||||
const { berichtId } = await kontext.params;
|
||||
|
||||
const gelesen = await blattZumLesen(berichtId);
|
||||
if (!gelesen) return new Response('Nicht gefunden.', { status: 404 });
|
||||
|
||||
const { bericht } = gelesen;
|
||||
const azubi = benutzerNachId(bericht.benutzerId);
|
||||
const ausbildung = ausbildungNachAzubi(bericht.benutzerId);
|
||||
const ausbilder = ausbildung ? benutzerNachId(ausbildung.ausbilderId) : null;
|
||||
const abzeichner = bericht.abgezeichnetVon ? benutzerNachId(bericht.abgezeichnetVon) : null;
|
||||
|
||||
const pdf = await berichtsheftPdf([
|
||||
{
|
||||
nr: bericht.nr,
|
||||
von: alsDatumText(bericht.von),
|
||||
bis: alsDatumText(bericht.bis),
|
||||
azubi: azubi?.name ?? 'unbekannt',
|
||||
ausbilder: ausbilder?.name ?? '',
|
||||
beruf: ausbildung?.beruf ?? 'Fachinformatiker/-in für Systemintegration',
|
||||
ausbildungsjahr: ausbildung ? ausbildungsjahr(ausbildung.beginn, bericht.von) : null,
|
||||
status: bericht.status,
|
||||
anmerkung: bericht.anmerkung,
|
||||
abgezeichnetVon: abzeichner?.name ?? null,
|
||||
abgezeichnetAm: bericht.abgezeichnetAm ? alsZeitpunktText(bericht.abgezeichnetAm) : null,
|
||||
blatt: alsWochenblatt(bericht),
|
||||
},
|
||||
]);
|
||||
|
||||
const dateiname = `Ausbildungsnachweis_${String(bericht.nr).padStart(3, '0')}_${bericht.von}.pdf`;
|
||||
|
||||
return new Response(new Uint8Array(pdf), {
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Length': String(pdf.byteLength),
|
||||
'Content-Disposition': `inline; filename="${dateiname}"`,
|
||||
'Cache-Control': 'private, no-store',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user