Antrag und Mitteilung an die Klassen-/Stufenleitung.
${copies.map(renderCopy).join("")}
`;
}
function buildBeurlaubungText(data) {
return getBeurlaubungCopies(data)
.map((copy) => {
const rows = copy.rows.map(([label, value]) => `${label}: ${value}`).join("\n");
return `${copy.title}\n${rows}\n${copy.signature}: ____________________`;
})
.join("\n\n---\n\n");
}
function getBeurlaubungCopies(data) {
const timestampRow = outputTimestampRow();
const period = `${formatDate(data.beurlaubung_von)} bis ${formatDate(data.beurlaubung_bis)}`;
const returnDeadline = data.rueckmeldung_bis ? formatDate(data.rueckmeldung_bis) : "01.12. bzw. _____________ 20___";
const studentRows = [
["Name", value(data.name)],
["Vorname", value(data.vorname)],
["Schuljahr", value(data.schuljahr)],
["Klasse / Semester", classSemester(data)],
["Klassen-/Stufenleitung", value(data.klassenleitung)]
];
return [
{
title: "Antrag auf Beurlaubung - Abendgymnasium Köln",
rows: [
...studentRows,
["Antrag", `Hiermit beantrage ich gemäß APO-WBK § 9 Abs. 6 die Beurlaubung für ${period}.`],
["Rückmeldung", checkedText(data.rueckmeldung_informiert, `Schriftliche Rückmeldung erforderlich bis ${returnDeadline} (Posteingang); sonst verfällt das Anrecht auf einen Studienplatz am Abendgymnasium Köln WbK.`)],
["Schulbücher", checkedText(data.buecher_abgeben, "Leihweise erhaltene Schulbücher werden für die Zeit der Beurlaubung abgegeben.")],
["Köln, den", formatDate(data.antragsdatum)],
timestampRow
],
signature: "Unterschrift d. Studierenden / Unterschrift d. Schulleitung"
},
{
title: "Mitteilung an die Klassen-/Stufenleitung",
rows: [
["Name", value(data.name)],
["Vorname", value(data.vorname)],
["Semester", value(data.semester)],
["Beurlaubung", `hat sich am ${formatDate(data.antragsdatum)} bis zum ${formatDate(data.beurlaubung_bis)} beurlauben lassen.`],
["Hinweis", "Bitte informieren Sie die anderen Fachlehrer/innen und streichen Sie sie von den Kurslisten."],
["Version", "1"],
timestampRow
],
signature: "Kenntnisnahme Klassen-/Stufenleitung"
},
{
title: "Rechtsgrundlage",
rows: [
["APO-WBK § 9 Abs. 6", "Die Schulleiterin oder der Schulleiter kann eine Studierende oder einen Studierenden auf Antrag für längstens zwei Semester beurlauben (§ 43 Abs. 3 SchulG - jetzt: Absatz 4). Die Zeit der Beurlaubung wird auf die Höchstverweildauer nicht angerechnet."],
timestampRow
],
signature: "Zur Kenntnis genommen"
}
];
}
function classSemester(data) {
return uniqueValues([data.klasse, data.semester]).join(" / ") || "____________________";
}
function renderSchulbuchAusleiheOutput(data) {
return `
Druckausgabe
Kompakter Antrag auf Ausleihe aus dem Eigenanteil.
${renderCopy(getSchulbuchAusleiheCopy(data))}
`;
}
function buildSchulbuchAusleiheText(data) {
const copy = getSchulbuchAusleiheCopy(data);
const rows = copy.rows.map(([label, value]) => `${label}: ${value}`).join("\n");
return `${copy.title}\n${rows}\n${copy.signature}: ____________________`;
}
function getSchulbuchAusleiheCopy(data) {
return {
title: "Antrag auf Ausleihe von Schulbüchern aus dem Eigenanteil",
rows: [
["Name, Vorname", fullNameLastFirst(data)],
["Anschrift", value(data.anschrift)],
["Ich beziehe", `${value(data.leistungsbezug)} (Beleg bitte beifügen)`],
["Antrag", "Deshalb beantrage ich die Ausleihe des folgenden Schulbuches, das ich normalerweise aus dem Eigenanteil beschaffen müsste."],
["Schulbuch", value(data.buch)],
["Hinweis", checkedText(data.buchpflicht_bestaetigt, "Das Buch ist so zu behandeln, dass es nach der Nutzung weiter ausgeliehen werden kann; andernfalls sind die Kosten nachträglich zu übernehmen.")],
["Datum", formatDate(data.antragsdatum)],
outputTimestampRow()
],
signature: "Datum und Unterschrift"
};
}
function renderEinwilligungOutput(data) {
const rows = getEinwilligungRows(data);
const sections = getEinwilligungSections(data);
return `
Druckausgabe
Einwilligung mit Erklärungsteil und Datenschutz-Hinweisen.
Einwilligung in die Veröffentlichung von personenbezogenen Daten
einschließlich Fotos/Videos
${sections.map(renderPlainSection).join("")}
${rows.map(([label, value]) => `
${escapeHtml(label)}
${escapeHtml(value)}
`).join("")}
Unterschrift: ____________________
${renderA4Footer()}
`;
}
function buildEinwilligungText(data) {
const sections = getEinwilligungSections(data)
.map((section) => `${section.title}\n${section.body}`)
.join("\n\n");
const rows = getEinwilligungRows(data)
.map(([label, value]) => `${label}: ${value}`)
.join("\n");
return `Einwilligung in die Veröffentlichung von personenbezogenen Daten einschließlich Fotos/Videos\n\n${sections}\n\n${rows}\nUnterschrift: ____________________`;
}
function getEinwilligungRows(data) {
return [
["Name / Klasse", `${fullNameLastFirst(data)} / ${classSemester(data)}`],
["Ort, Datum", `Köln, den ${formatDate(data.antragsdatum)}`],
["Einwilligung", checkedText(data.einwilligung_erteilt, "Veröffentlichung personenbezogener Daten einschließlich Fotos/Videos im schulischen Kontext.")],
["Ausnahmen", getEinwilligungExceptions(data)],
outputTimestampRow()
];
}
function getEinwilligungSections(data) {
return [
{
title: "Erklärung",
body: "In geeigneten Fällen möchten wir Informationen über Ereignisse aus unserem Schulleben auch mit personenbezogenem Bezug einer größeren Öffentlichkeit zugänglich machen. Dies betrifft insbesondere Texte, Fotos oder Videos, die im Rahmen der pädagogischen Arbeit, von Schulveranstaltungen oder Projekten entstehen. Hierzu bitten wir um Ihre Einwilligung."
},
{
title: "Nutzungsrechte und Widerruf",
body: "Die Einräumung der Nutzungsrechte erfolgt unentgeltlich und umfasst auch das Recht zur Bearbeitung, sofern diese nicht entstellend ist. Die Einwilligung kann jederzeit schriftlich gegenüber der Schulleiterin oder dem Schulleiter widerrufen werden. Bei bereits erstellten, bestellten oder im Umlauf befindlichen Druckwerken ist ein Widerruf unter Umständen nicht mehr vollständig umsetzbar. Sofern die Einwilligung nicht widerrufen wird, gilt sie für den schulischen Kontext auch über das Ende der Schulzugehörigkeit hinaus, solange der Veröffentlichungszweck fortbesteht. Die Einwilligung erfolgt freiwillig; aus Nichterteilung oder Widerruf entstehen keine Nachteile."
},
{
title: "Zustimmung",
body: "Die Schule darf personenbezogene Daten einschließlich Fotos/Videos im Schulkontext digital, zum Beispiel Homepage, digitale oder soziale Medien wie YouTube und Instagram einschließlich vergleichbarer Plattformen, sowie analog nutzen und verbreiten. Die Zustimmung gilt für alle genannten Nutzungsarten, sofern diese nicht ausdrücklich ausgeschlossen werden."
},
{
title: "Veröffentlichungen im Internet / Datenschutz",
body: "Bei Veröffentlichungen im Internet können personenbezogene Daten einschließlich Fotos weltweit abgerufen und gespeichert werden. Sie können über Suchmaschinen aufgefunden, mit weiteren Daten verknüpft, verändert oder zu anderen Zwecken verwendet werden. Bei sozialen Netzwerken kann eine Verarbeitung in Staaten außerhalb der Europäischen Union nicht ausgeschlossen werden."
},
{
title: "Hinweise zu Fotos und Filmen bei erwachsenen Schüler*innen",
body: "Fotos/Videos mit anderen Personen sind nur mit deren Einwilligung oder ausschließlich im privaten Kreis zulässig. Ausnahmsweise ist eine Veröffentlichung ohne Einwilligung möglich, wenn abgebildete Personen lediglich Beiwerk sind. Bei Schulveranstaltungen kann Fotografieren zum Beispiel in ausgewiesenen Fotozonen möglich sein. Fotos/Videos im Unterricht sind nur mit vorheriger freiwilliger Einwilligung aller Betroffenen zulässig. Veröffentlichungen im Internet oder in sozialen Medien erfordern immer eine Einwilligung, sobald kein geschlossener Nutzerkreis besteht."
},
{
title: "Links",
body: "https://www.ldi.nrw.de/Bildaufnahmen-in-der-Schule\nhttps://www.schulministerium.nrw/fragen-und-antworten-zum-datenschutz"
}
];
}
function getEinwilligungExceptions(data) {
const exceptions = [];
if (data.ausnahme_fotoaushang) exceptions.push("Fotoaushang in der Schule");
if (data.ausnahme_homepage) exceptions.push("Homepage der Schule");
if (data.ausnahme_blog) exceptions.push("Blog der Schule");
if (data.ausnahme_social_media) exceptions.push("Social Media und vergleichbare Plattformen");
if (data.ausnahme_sonstiges?.trim()) exceptions.push(data.ausnahme_sonstiges.trim());
return exceptions.length ? exceptions.join("; ") : "Keine Ausnahmen angegeben.";
}
function renderPlainSection(section) {
return `
${escapeHtml(section.title)}
${section.body.split("\n").map((paragraph) => `
${escapeHtml(paragraph)}
`).join("")}
`;
}
function renderUnterrichtsversaeumnisseOutput(data) {
return `
`;
}
function renderAbsenceColumnHead(column) {
if (!column.date) {
return `Mo Di Mi Do Fr __ . __`;
}
return `${escapeHtml(weekdayShort(column.date))} ${escapeHtml(formatDate(column.date))}`;
}
function renderAbsenceCell(column, lesson) {
const entry = column.entries.find((item) => item.lesson === lesson);
if (!entry) {
return ``;
}
return `
${escapeHtml(entry.subject)}${escapeHtml(entry.teacher || "")}
`;
}
function buildAbsenceColumns(entries, minColumns) {
const dates = uniqueValues(entries.map((entry) => entry.date));
const columns = dates.map((date) => ({
date,
entries: entries.filter((entry) => entry.date === date)
}));
while (columns.length < minColumns) {
columns.push({ date: "", entries: [] });
}
return columns;
}
function parseAbsenceData(input) {
if (!input) return [];
if (Array.isArray(input)) return sortAbsences(input);
try {
return sortAbsences(JSON.parse(input));
} catch (error) {
return [];
}
}
function weekdayShort(input) {
const date = new Date(`${input}T00:00:00`);
return ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"][date.getDay()];
}
function renderAbsenceProcedure(data) {
const bafoegText = data.bafoeg
? "BAföG: Bitte spätestens zum Quartal und zum Semesterende eine Kopie dieses Blattes an die Stufenleitung geben und selbst eine Kopie/ein Foto als Beleg aufbewahren."
: "Kein BAföG: Bitte das Formular selbst aufbewahren; es kann bei Notenbesprechungen relevant werden.";
return `
Vorgehen
Tragen Sie versäumte Tage mit Datum und Fächern ein. Die betroffenen Lehrer*innen zeichnen nach Kenntnisnahme im kleinen Kästchen der jeweiligen Stunde ab. Von der Fachlehrerin/vom Fachlehrer unterschriebene Stunden gelten als entschuldigt.
${escapeHtml(bafoegText)}
Bitte verwenden Sie ausschließlich dieses Formular, um Unterrichtsversäumnisse zu entschuldigen. Bei mehr als einer Woche, vorhersehbaren oder regelmäßigen Fehlzeiten nehmen Sie bitte Kontakt mit Fachlehrer*innen und Stufenleitung auf.
Bei verpassten Klausuren bitte das Nachschreibformular unter formular.agkoeln.de nutzen; es gilt eine Frist von 3 Tagen.
`;
}
function buildAbwahlAdvice(data) {
const subject = getSubjectMeta(data.fach);
const abiSubjects = uniqueValues([data.lk1_fach, data.lk2_fach]);
const writtenSubjects = getWrittenSubjectsAfterAbwahl(data);
const writtenAreas = uniqueValues(writtenSubjects.map((name) => getSubjectMeta(name)?.bereich).filter(Boolean));
const requiredAreas = ["Sprache", "Gesellschaftswissenschaft", "Mathe/Naturwissenschaft"];
const missingAreas = requiredAreas.filter((area) => !writtenAreas.includes(area));
const coreAbiSubjects = uniqueValues(writtenSubjects.filter((name) => getSubjectMeta(name)?.kernfach));
const isAbiSubject = Boolean(data.fach) && abiSubjects.includes(data.fach);
const checks = [
{
ok: !isAbiSubject,
text: isAbiSubject
? `Das Fach ${data.fach} ist Leistungskurs/Abiturfach und darf nicht abgewählt werden.`
: "Das abzuwählende Fach ist kein LK-Abiturfach."
},
{
ok: coreAbiSubjects.length >= 2,
text: `${coreAbiSubjects.length} von 3 Kernfächern (Deutsch, Englisch, Mathematik) bleiben schriftlich belegt.`
},
{
ok: missingAreas.length === 0,
text: missingAreas.length === 0
? `Alle drei Bereiche bleiben schriftlich abgedeckt: ${writtenAreas.join(", ")}.`
: `Nicht schriftlich abgedeckt: ${missingAreas.join(", ")}.`
}
];
if (subject?.kernfach) {
checks.push({
ok: true,
text: "Kernfach-Hinweis: In H3/H4 kann bei zwei Klausuren nur die erste Klausur abgewählt werden; ab H5 muss keine Klausur mehr geschrieben werden."
});
} else if (subject) {
checks.push({
ok: true,
text: `Kein Kernfach. Bereich des Fachs: ${subject.bereich}.`
});
}
const blockers = checks.filter((check) => !check.ok);
return {
checks,
summary: blockers.length === 0 ? "Beratungsregeln erfüllt." : `Nicht erfüllt: ${blockers.map((check) => check.text).join(" ")}`
};
}
function getWrittenSubjectsAfterAbwahl(data) {
const courses = [
{ name: data.lk1_fach, written: true },
{ name: data.lk2_fach, written: true },
{ name: data.gk1_fach, written: data.gk1_status === "schriftlich" },
{ name: data.gk2_fach, written: data.gk2_status === "schriftlich" },
{ name: data.gk3_fach, written: data.gk3_status === "schriftlich" },
{ name: data.gk4_fach, written: data.gk4_status === "schriftlich" }
];
return uniqueValues(
courses
.filter((course) => course.name && course.written && course.name !== data.fach)
.map((course) => course.name)
);
}
function uniqueValues(values) {
return [...new Set(values.filter(Boolean))];
}
function renderAdvice(advice) {
return `