Online-Anmeldung

Veranstaltung

Leitungsmodus Noch nicht gespeichert

Veranstaltung bearbeiten Leitungsbereich

Die häufigsten Einstellungen stehen zuerst. Packliste, Bedingungen, Links und Technik können darunter aufgeklappt werden.

Einrichtung noch unvollständig
Bitte die hervorgehobenen Angaben ergänzen.
    1. Veranstaltung & Termine
    2. Beiträge & Zahlung
    Bankverbindung
    Kontoinhaber
    DPSG Stamm St. Hedwig
    IBAN
    DE80 4726 0121 8330 1481 00
    BIC
    DGPBDE3M
    Kreditinstitut
    VerbundVolksbank OWL
    3. Veranstalter & Zuschüsse
    Verantwortung / Veranstalter
    Art der Maßnahme für Zuschussformulare
    Angaben für den Stadt-Paderborn-Antrag

    Der Button oben öffnet wieder den von euch bereits vorbereiteten/gespeicherten Stadtantrag. Die aktuellen Veranstaltungswerte darunter kannst du zusätzlich einzeln kopieren und im Antrag aktualisieren.

    Bei Diözesanveranstaltungen: Der Stamm sammelt die internen Anmeldungen und meldet die Gruppe anschließend über das Pretix-System des Diözesanverbandes an.
    4. Teilnehmende & Abfragen
    Zugelassene Stufen / Rollen
    Module ein-/ausschalten

    Für Leitende/Mitarbeitende sind Gesundheits-, Kleingruppen-, Versorgungs- und Schwimmabfragen standardmäßig ausgeschaltet. Ihr könnt jede Zeile bei Bedarf getrennt aktivieren.

    ModulTeilnehmendeLeitende / Mitarbeitende
    Gesundheit
    Kleingruppen
    Versorgungsmaßnahmen (Wunddesinfektion, Insektenstiche/Sonnenbrand, Zecken)
    Schwimmen
    Verpflegung
    Hinweise / Packliste
    Foto/Video/Audio
    Zusatzabfragen / Zusatzinfos

    Auch Zusatzabfragen können getrennt für Teilnehmende und Leitende/Mitarbeitende geschaltet werden. Für Leitende sind sie zunächst aus.

    AbfrageTeilnehmendeLeitende / Mitarbeitende
    Deutschlandticket
    Eltern-PKW für An-/Abreise
    Kuchen / Salat / Beitrag
    Veranstaltungs-Notfallnummer anzeigen
    5. Texte, Briefkopf, Links & Packliste
    Briefkopf & Logos
    Vorschau Stammeslogo
    Kein Aktionslogo hinterlegt
    Weiterführende Links (optional)

    Links erscheinen nur, wenn Beschreibung und URL eingetragen sind.

    Packliste auswählen und bearbeiten
    Bedingungen und Hinweise bearbeiten

    Die jeweils akzeptierte Fassung wird bei der Anmeldung gespeichert.

    6. Sicherheit
    Kennwort für den Leitungsbereich ändern
    Veranstaltungskonfiguration sichern

    „Änderungen speichern“ speichert im Browser. Für die Weitergabe dieser Einstellungen bitte zusätzlich eine Konfigurationsdatei herunterladen.

    Listen & Auswertungen

    Die Filter gelten für Statistik, Vorschau und die anschließend geöffneten Listen.

    Kein Filter aktiv – die Listen enthalten alle Anmeldungen.

    Sortierung für Vorschau und PDF

    Treffer
    m / w / d
    vegetarisch / vegan
    DV-Kennzeichnung

    Gefilterte Personen

    Aufteilung nach Stufe

    Listen öffnen

    Veranstaltung

    Ort
    Zeitraum
    Verantwortlich
    Teilnahmebeitragkein Teilnahmebeitrag hinterlegt
    Anmeldeschluss
    Zahlung bis
    Hinweis zur Anmeldung beim Diözesanverband: Diese Anmeldung erfolgt zunächst beim DPSG Stamm St. Hedwig. Der Stamm meldet die Gruppe anschließend gesammelt über das Anmeldeportal des Diözesanverbandes an. Die dafür erforderlichen Angaben werden durch die zuständige Leitung übertragen. Eine Abmeldung von der Diözesanveranstaltung wird ebenfalls durch die anmeldende Leitung im Portal vorgenommen.
    Pflichtfelder: Felder mit * und roter Markierung müssen ausgefüllt werden. Die rote Markierung verschwindet, sobald die Angabe vollständig ist.

    Teilnehmende Person

    Ich gehöre zu

    Geschlecht i

    Kontakt und Erreichbarkeit

    Erziehungsberechtigte Person
    Weitere erziehungsberechtigte Person
    Weitere Erreichbarkeit / medizinischer Kontakt

    Veranstaltungsbezogene Zusatzfragen

    Gesundheit und Medikamente

    Allergien / Unverträglichkeiten / Krankheiten i
    Medikamente i

    Aufenthalt in Kleingruppen

    Darf sich die teilnehmende Person in einer Kleingruppe von mindestens drei Kindern/Jugendlichen ohne direkte Aufsicht, in einem vorher abgesprochenen Gebiet und nach Abmeldung bei der Gruppenleitung aufhalten?

    Medizinische Behandlung und kleine Versorgungsmaßnahmen

    Falls eine ärztliche Behandlung notwendig wird und die erziehungsberechtigten Personen nicht erreichbar sind, entscheidet medizinisches Fachpersonal über die erforderliche Behandlung. Das Leitungsteam versucht zuvor, die hinterlegten Kontaktpersonen zu erreichen.
    Oberflächliche Schürfwunden mit nicht jodhaltiger Wunddesinfektion (Octenisept®, Wirkstoff Octenidin)
    Kleine juckende Insektenstiche oder Sonnenbrand mit Fenistil® Gel (Wirkstoff Dimetindenmaleat 1 mg/g)
    Zeckenentfernung durch Leiter*innen und Reinigung der Bissstelle

    Schwimmen

    Schwimmerlaubnis

    Verpflegung

    Verpflegungsform i

    Organisatorische Hinweise und Packliste

    Einwilligung zu Bild-, Video- und Audioaufnahmen

    Bildrechte: noch nicht vollständig beantwortet Der Status wird automatisch aus den Antworten berechnet.

    Die Aufnahmen dienen der Informations- und Öffentlichkeitsarbeit im Zusammenhang mit der oben bezeichneten Veranstaltung. Die Einwilligung ist freiwillig und kann für die Zukunft widerrufen werden. Eine Nichtzustimmung hat keine Nachteile für die Teilnahme.

    Zuerst entscheidest du nur, ob überhaupt Aufnahmen gemacht werden dürfen. Nur bei „Ja“ werden anschließend die einzelnen Veröffentlichungswege angezeigt.
    Dürfen Bild-, Video- und Audioaufnahmen erstellt werden? i
    Datenschutz- und Widerrufshinweise zu Foto/Video/Audio

    Die Einwilligung kann jederzeit für die Zukunft widerrufen werden. Bis zum Widerruf erfolgte Nutzungen bleiben rechtmäßig. Bereits verteilte Druckerzeugnisse können nicht zurückgerufen werden; bei Online-Veröffentlichungen kann trotz Entfernung durch die verantwortliche DPSG-Stelle nicht ausgeschlossen werden, dass Dritte bereits Kopien gespeichert oder weiterverbreitet haben.

    Bei einer Veröffentlichung im Internet oder auf Social-Media-Plattformen kann eine Verarbeitung außerhalb der EU stattfinden; dort kann ein anderes Datenschutzniveau gelten.

    Aktuelle DPSG-Hinweise zu Foto-/Video-Einwilligungen

    Bedingungen und Hinweise

    Es gelten die Bedingungen und Hinweise des DPSG Stamm St. Hedwig in der hier angezeigten Fassung.

    Datenschutz der Anmeldung

    Für die Planung, Durchführung und Nachbereitung der Veranstaltung werden die in diesem Formular angegebenen personenbezogenen Daten verarbeitet. Gesundheitsdaten sollen nur den Personen zugänglich sein, die sie für die sichere Durchführung benötigen.

    Die bestehende Datenschutzerklärung der Stammeswebsite beschreibt dieses neue Veranstaltungs-Anmeldeformular noch nicht vollständig. Vor Livebetrieb muss sie um Zweck, Datenkategorien, Empfänger*innen, Rechtsgrundlagen, Speicherfristen und technische Verarbeitung dieses Formulars ergänzt werden.
    Abschließende Bestätigung

    Die freiwilligen Entscheidungen zu Bild-, Video- und Audioaufnahmen bleiben davon getrennt und werden ausschließlich im Abschnitt Bildrechte getroffen.

    Beteiligung und Unterschriften

    Die teilnehmende Person unterschreibt selbst. Bei Minderjährigen dient das ausdrücklich auch der Beteiligung des Kindes bzw. Jugendlichen an den Entscheidungen. Die Unterschrift des Kindes ersetzt nicht die erforderliche Erklärung einer erziehungsberechtigten Person.
    Mit Maus, Stift oder Finger unterschreiben.
    Mit Maus, Stift oder Finger unterschreiben.

    PDF-Kopie der Anmeldung

    Ihr könnt die PDF jederzeit vorab ansehen. Noch offene Pflichtangaben werden in der Vorschau deutlich markiert. Bereits geleistete Unterschriften, Bildrechte, Packliste, Bedingungen und Hinweise werden ebenfalls angezeigt.

    Datenschutz: Die PDF wird erst nach eurer Bestätigung auf diesem Gerät erstellt und zum Download angeboten.
    ${body} `; } let lastSubmission=null,lastSummaryBody=""; function openPrintableSummary(){ if(!lastSubmission)return;const w=window.open("","_blank");if(!w){alert("Bitte Pop-ups für diese Seite zulassen.");return;} w.document.open();w.document.write(fullPrintableHtml(lastSummaryBody));w.document.close(); } function parentPdfFilename(){ const first=(lastSubmission?.participantFirstName||"").trim(); const last=(lastSubmission?.participantLastName||"").trim(); const event=(cfg.eventName.value||"Veranstaltung").trim(); return `Anmeldung_${event}_${last}_${first}.pdf`.replace(/[^\wäöüÄÖÜß.-]+/g,"_"); } async function downloadParentPdf(){ if(!lastSubmission||!$("#confirmParentPdf").checked)return; if(typeof html2pdf==="undefined"){ $("#parentPdfDownloadStatus").textContent="Der direkte PDF-Download ist in diesem Browser nicht verfügbar. Die Druckansicht wurde geöffnet; dort bitte „Als PDF speichern“ wählen."; openPrintableSummary(); return; } $("#parentPdfDownloadStatus").textContent="PDF wird erstellt …"; const source=document.createElement("div"); source.className="parent-pdf-sheet"; source.innerHTML=lastSummaryBody; Object.assign(source.style,{width:"180mm",boxShadow:"none",position:"absolute",left:"0",top:"0",zIndex:"-1",background:"#fff"}); document.body.appendChild(source); try{ await new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve))); const worker=html2pdf().set({ margin:[10,10,10,10], image:{type:"jpeg",quality:.98}, html2canvas:{scale:2,useCORS:true,backgroundColor:"#ffffff"}, jsPDF:{unit:"mm",format:"a4",orientation:"portrait"}, pagebreak:{mode:["css","legacy"]} }).from(source).toPdf(); const pdf=await worker.get("pdf"); const blob=pdf.output("blob"); const url=URL.createObjectURL(blob),a=document.createElement("a"); a.href=url;a.download=parentPdfFilename();document.body.appendChild(a);a.click();a.remove(); setTimeout(()=>URL.revokeObjectURL(url),60000); $("#parentPdfDownloadStatus").textContent="PDF wurde erstellt."; }catch(err){ console.error("TN-PDF-Download fehlgeschlagen",err); $("#parentPdfDownloadStatus").textContent="Der direkte Download hat nicht funktioniert. Die Druckansicht wurde als Ausweichmöglichkeit geöffnet; dort bitte „Als PDF speichern“ wählen."; openPrintableSummary(); }finally{source.remove();} } const REPORT_DEMO = [ { first:"Mara",last:"Beispiel",stage:"Juffis",gender:"w",food:"vegetarian",dvPhoto:"yes",recordingAllowed:"yes",photoInfo:"yes",photoWeb:"yes",photoPress:"yes",photoDisplay:"yes",photoSocial:"no",photoMessenger:"yes",photoNameData:"yes",photoInfo:"yes",photoWeb:"yes",photoPress:"no",photoDisplay:"yes",photoSocial:"yes",photoMessenger:"yes",photoNameData:"yes", participantEmail:"mara@example.org",phone:"0170 1111111",guardian:"Alex Beispiel",guardianEmail:"alex@example.org",guardian2:"Chris Beispiel",guardian2Phone:"0170 1111122",guardian2Email:"chris@example.org",backup:"",street:"Musterweg 1",postal:"33100",city:"Paderborn",district:"", birthDate:"2013-05-11",occupation:"",healthHint:false,healthConditions:"",healthMeasures:"",medicationMode:"none",medicationNames:"",medicationSchedule:"",wound:"yes",fenistil:"yes",tick:"yes",swim:"allowed",dTicket:"yes", paymentAmount:250 }, { first:"Jonas",last:"Muster",stage:"Juffis",gender:"m",food:"vegan",dvPhoto:"no",recordingAllowed:"no",photoInfo:"no",photoWeb:"no",photoPress:"no",photoDisplay:"no",photoSocial:"no",photoMessenger:"no",photoNameData:"no", participantEmail:"jonas@example.org",phone:"0170 2222222",guardian:"Sam Muster",guardianEmail:"sam@example.org",guardian2:"",guardian2Phone:"",guardian2Email:"",backup:"0170 3333333",street:"Beispielstr. 2",postal:"33102",city:"Paderborn",district:"Schloß Neuhaus", birthDate:"2012-08-03",occupation:"",healthHint:true,healthConditions:"Nussallergie",healthMeasures:"Nüsse vermeiden; Notfallmedikament beachten",medicationMode:"asNeeded",medicationNames:"Antihistaminikum",medicationSchedule:"bei Bedarf nach hinterlegter Anweisung",wound:"no",fenistil:"no",tick:"yes",swim:"notAllowed",dTicket:"no", paymentAmount:230 }, { first:"Kim",last:"Test",stage:"Leitende",gender:"d",leaderQualification:"juleica",food:"vegetarian",dvPhoto:"yes",recordingAllowed:"yes", participantEmail:"kim@example.org",phone:"0170 4444444",guardian:"",guardianEmail:"",backup:"",street:"Pfad 3",postal:"33100",city:"Paderborn",district:"", birthDate:"2003-02-14",occupation:"Student*in",healthHint:false,healthConditions:"",healthMeasures:"",medicationMode:"none",medicationNames:"",medicationSchedule:"",wound:"yes",fenistil:"yes",tick:"yes",swim:"allowed",dTicket:"yes", paymentAmount:0 } , { first:"Robin",last:"Helfer",stage:"Mitarbeitende",gender:"m",food:"vegetarian",dvPhoto:"yes",recordingAllowed:"yes",photoInfo:"yes",photoWeb:"yes",photoPress:"yes",photoDisplay:"yes",photoSocial:"yes",photoMessenger:"yes",photoNameData:"yes", participantEmail:"robin@example.org",phone:"0170 5555555",guardian:"",guardianEmail:"",backup:"",street:"Helferweg 4",postal:"33100",city:"Paderborn",district:"", birthDate:"1998-05-01",occupation:"",healthHint:false,healthConditions:"",healthMeasures:"",medicationMode:"none",medicationNames:"",medicationSchedule:"",wound:"yes",fenistil:"yes",tick:"yes",swim:"allowed",dTicket:"yes", paymentAmount:250 } ]; let REPORT_DATA=REPORT_DEMO.map(r=>({...clone(r),registrationStatus:"angemeldet"})); function ageAtStart(birthDate){ if(!birthDate||!cfg.start.value)return ""; const dob=new Date(birthDate+"T12:00:00"),ref=new Date(cfg.start.value+"T12:00:00"); let a=ref.getFullYear()-dob.getFullYear(); const m=ref.getMonth()-dob.getMonth(); if(m<0||(m===0&&ref.getDate()r.registrationStatus!=="abgemeldet").filter(r=>(!s||r.stage===s)&&(!g||r.gender===g)&&(!f||r.food===f)&&(!d||r.dvPhoto===d)); const stageOrder={"Wölflinge":1,"Juffis":2,"Pfadis":3,"Rover":4,"Leitende":5,"Mitarbeitende":6}; const levels=[ [$("#reportSort1")?.value,$("#reportSort1Dir")?.value], [$("#reportSort2")?.value,$("#reportSort2Dir")?.value], [$("#reportSort3")?.value,$("#reportSort3Dir")?.value] ].filter(([key])=>key); const compare=(a,b,key,dir)=>{ const factor=dir==="desc"?-1:1; if(key==="stage")return ((stageOrder[a.stage]||99)-(stageOrder[b.stage]||99))*factor; const av=a[key]??"",bv=b[key]??""; return String(av).localeCompare(String(bv),"de",{sensitivity:"base",numeric:true})*factor; }; rows.sort((a,b)=>{ for(const [key,dir] of levels){ const c=compare(a,b,key,dir); if(c!==0)return c; } return String(a.last||"").localeCompare(String(b.last||""),"de",{sensitivity:"base"}) || String(a.first||"").localeCompare(String(b.first||""),"de",{sensitivity:"base"}); }); return rows; } function yesNo(v){return v==="yes"?"Ja":v==="no"?"Nein":(v||"");} function swimText(v){return v==="allowed"?"Ja":v==="notAllowed"?"Nein":v==="cannot"?"kann nicht schwimmen":(v||"");} function foodText(v){return v==="vegetarian"?"vegetarisch":v==="vegan"?"vegan":v==="omnivore"?"omnivor":(v||"");} function stageClass(stage){ return {"Wölflinge":"woelflinge","Juffis":"juffis","Pfadis":"pfadis","Rover":"rover","Leitende":"leitende","Mitarbeitende":"mitarbeitende"}[stage]||""; } function stageColor(stage){ return {"Wölflinge":"#ff6400","Juffis":"#2f53a7","Pfadis":"#00823c","Rover":"#cc1f2f","Leitende":"#8b9488","Mitarbeitende":"#555d63"}[stage]||"#777"; } function filterIsActive(){ return !!($("#reportFilterStage").value||$("#reportFilterGender").value||$("#reportFilterFood").value||$("#reportFilterDvPhoto").value); } function renderReportStats(){ const rows=filteredDemo(),c={m:0,w:0,d:0,vegetarian:0,vegan:0,dvNo:0}; rows.forEach(r=>{ c[r.gender]=(c[r.gender]||0)+1; c[r.food]=(c[r.food]||0)+1; if(r.dvPhoto==="no")c.dvNo++; }); const cards=$$("#reportStats .mini-stat strong"); if(cards[0])cards[0].textContent=rows.length; if(cards[1])cards[1].textContent=`${c.m}/${c.w}/${c.d}`; if(cards[2])cards[2].textContent=`${c.vegetarian}/${c.vegan}`; if(cards[3])cards[3].textContent=c.dvNo; const parts=[]; if($("#reportFilterStage").value)parts.push("Stufe: "+$("#reportFilterStage").value); if($("#reportFilterGender").value)parts.push("Geschlecht: "+$("#reportFilterGender").value); if($("#reportFilterFood").value)parts.push("Verpflegung: "+$("#reportFilterFood").selectedOptions[0].textContent); if($("#reportFilterDvPhoto").value)parts.push("DV-Bildrechte: "+$("#reportFilterDvPhoto").selectedOptions[0].textContent); const active=filterIsActive(); $("#reportFilterResult").className="filter-warning"+(active?"":" clear"); $("#reportFilterResult").textContent=active ? `FILTER AKTIV: ${parts.join(" · ")} – die Listen enthalten nur ${rows.length} von ${REPORT_DATA.filter(r=>r.registrationStatus!=="abgemeldet").length} Personen.` : `Kein Filter aktiv – die Listen enthalten alle ${REPORT_DATA.filter(r=>r.registrationStatus!=="abgemeldet").length} Personen.`; if(!rows.length){ $("#filteredParticipantsPreview").innerHTML="

    Keine Personen passen zu diesem Filter.

    "; $("#stageSummaryView").innerHTML=""; if(currentReportType)renderOpenedReport(currentReportType); return; } $("#filteredParticipantsPreview").innerHTML = ``+ rows.map(r=>``).join("")+ `
    NameStufem/w/dVerpflegung
    ${escapeHtml(r.last)}, ${escapeHtml(r.first)}${escapeHtml(r.stage)}${escapeHtml(r.gender)}${escapeHtml(foodText(r.food))}
    `; $$("[data-remove-participant]").forEach(btn=>btn.addEventListener("click",()=>{ const [last,first]=btn.dataset.removeParticipant.split("|"); const person=REPORT_DATA.find(r=>r.last===last&&r.first===first&&r.registrationStatus!=="abgemeldet"); if(!person)return; if(!confirm(`${first} ${last} wirklich als abgemeldet markieren? Die Person verschwindet aus allen aktiven Listen und Zuschusslisten.`))return; person.registrationStatus="abgemeldet"; person.cancelledAt=new Date().toISOString(); renderReportStats();syncCityCopyFields(); })); const selectedStage=$("#reportFilterStage").value; const stages=selectedStage?[selectedStage]:["Wölflinge","Juffis","Pfadis","Rover","Leitende","Mitarbeitende"].filter(stage=>rows.some(r=>r.stage===stage)); $("#stageSummaryView").innerHTML=stages.map(stage=>{ const sr=rows.filter(r=>r.stage===stage),g={m:0,w:0,d:0}; sr.forEach(r=>g[r.gender]=(g[r.gender]||0)+1); return `
    ${escapeHtml(stage)}: ${sr.length}m ${g.m} · w ${g.w} · d ${g.d}
    `; }).join(""); if(currentReportType)renderOpenedReport(currentReportType); } function buildPaymentCodeForRow(r){ const prefix=cfg.paymentPurpose.value.trim()||"Veranstaltung"; return `${prefix}, ${r.first} ${r.last}, ${r.stage}`; } function reportTitle(type){ return { participants:"Teilnehmendenliste", contacts:"Kontaktdaten", stats:"Statistik / Mengenplanung", photodetail:"Bildrechte – detaillierte Liste", photolist:"Namensliste Fotografie", photomarking:"Foto-Kennzeichnung / Bändchen", emergency:"Notfallkontakte", health:"Gesundheit / Medikamente", payments:"Zahlungskontrolle", kjp:"Zuschussliste KJP / Formular 2", kreis:"Zuschussliste Kreis Paderborn", rdp:"RDP Datenbogen / Wirksamkeitsdialog" }[type]||"Liste"; } function currentFilterText(){ return $("#reportFilterResult").textContent; } function csvEscape(v){ const s=String(v??""); return /[;"\n\r]/.test(s)?`"${s.replace(/"/g,'""')}"`:s; } function demoToSubmission(r){ return { participantFirstName:r.first,participantLastName:r.last,birthDate:r.birthDate, participantEmail:r.participantEmail||"",participantStreet:r.street,participantPostalCode:r.postal, participantCity:r.city,participantDistrict:r.district,stage:r.stage,gender:r.gender, guardian1Name:r.guardian||"",guardian1Phone:r.phone||"",guardian1Email:r.guardianEmail||"",guardian2Name:r.guardian2||"",guardian2Phone:r.guardian2Phone||"",guardian2Email:r.guardian2Email||"", backupContactPhone:r.backup||"",food:r.food,healthConditions:r.healthConditions||"",healthMeasures:r.healthMeasures||"",medicationMode:r.medicationMode||"",medicationNames:r.medicationNames||"",medicationSchedule:r.medicationSchedule||"",woundDisinfection:r.wound,fenistil:r.fenistil, tickRemoval:r.tick,swimPermission:r.swim,dTicket:r.dTicket,recordingAllowed:r.recordingAllowed, photoInfo:r.photoInfo,photoWeb:r.photoWeb,photoPress:r.photoPress,photoDisplay:r.photoDisplay, photoSocial:r.photoSocial,photoMessenger:r.photoMessenger,photoNameData:r.photoNameData, photoDvGlobal:r.dvPhoto,occupationStatus:r.occupation||"", payment:{amount:r.paymentAmount,paymentCode:buildPaymentCodeForRow(r)} }; } function flattenCsvObject(value,prefix="",out={}){ if(value===null||value===undefined)return out; if(Array.isArray(value)){out[prefix]=value.join(" | ");return out;} if(typeof value==="object"){ Object.entries(value).forEach(([k,v])=>flattenCsvObject(v,prefix?`${prefix}.${k}`:k,out)); return out; } out[prefix]=value; return out; } function csvHeaderLabel(key){ if(FIELD_LABELS[key])return FIELD_LABELS[key]; const leaf=key.split(".").pop(); if(FIELD_LABELS[leaf])return FIELD_LABELS[leaf]; const special={ "payment.amount":"Teilnahmebeitrag", "payment.paymentCode":"Verwendungszweck", "_meta.generatedAt":"Zeitpunkt Anmeldung" }; return special[key]||key; } function csvPretty(key,value){ if(value===undefined||value===null)return ""; if(key==="food")return foodText(value); return prettyValue(key,value); } function downloadCsv(){ const source=REPORT_DATA.map(r=>({...demoToSubmission(r),registrationStatus:r.registrationStatus||"angemeldet",cancelledAt:r.cancelledAt||""})); if(lastSubmission)source.push(lastSubmission); const flat=source.map(r=>flattenCsvObject(r)); const keys=[...new Set(flat.flatMap(r=>Object.keys(r)))] .filter(k=>flat.some(r=>String(r[k]??"").trim()!=="")); const data=[ keys.map(csvHeaderLabel), ...flat.map(r=>keys.map(k=>csvPretty(k,r[k]??""))) ].map(row=>row.map(csvEscape).join(";")).join("\r\n"); const blob=new Blob(["\ufeff"+data],{type:"text/csv;charset=utf-8"}); const url=URL.createObjectURL(blob),a=document.createElement("a"); a.href=url;a.download=(cfg.eventName.value||"veranstaltung").replace(/[^\wäöüÄÖÜß-]+/g,"_")+"_alle_ausgefüllten_felder.csv"; document.body.appendChild(a);a.click();a.remove();URL.revokeObjectURL(url); } $("#downloadCsvBtn").addEventListener("click",downloadCsv); function buildReportModel(type){ const rows=filteredDemo(); if(type==="participants")return { columns:["Nachname","Vorname","Stufe","m/w/d","Essen","Wunde","Fenistil","Zecke","Schwimmen","D-Ticket","Foto","DV"], rows:rows.map(r=>[r.last,r.first,r.stage,r.gender,foodText(r.food),yesNo(r.wound),yesNo(r.fenistil),yesNo(r.tick),swimText(r.swim),yesNo(r.dTicket),yesNo(r.recordingAllowed),r.dvPhoto==="no"?"Nein / Kennzeichnung":"Ja"]), stages:rows.map(r=>r.stage) }; if(type==="contacts")return { columns:["Nachname","Vorname","Stufe","Straße","PLZ","Ort","E-Mail TN","Erziehungsberechtigte Person","Telefon","E-Mail","Weitere erziehungsberechtigte Person","Telefon 2","E-Mail 2","Ersatzkontakt"], rows:rows.map(r=>[ r.last,r.first,r.stage,r.street,r.postal,r.city,r.participantEmail||"", r.guardian||"",r.phone||"",r.guardianEmail||"", r.guardian2||"",r.guardian2Phone||"",r.guardian2Email||"", r.backup||"" ]), stages:rows.map(r=>r.stage) }; if(type==="stats"){ const stages=["Wölflinge","Juffis","Pfadis","Rover","Leitende","Mitarbeitende"]; const stageRows=stages.filter(stage=>rows.some(r=>r.stage===stage)).map(stage=>{ const sr=rows.filter(r=>r.stage===stage); return [ stage, sr.length, sr.filter(r=>r.gender==="m").length, sr.filter(r=>r.gender==="w").length, sr.filter(r=>r.gender==="d").length ]; }); const foodRows=[ ["vegetarisch",rows.filter(r=>r.food==="vegetarian").length], ["vegan",rows.filter(r=>r.food==="vegan").length], ["omnivor",rows.filter(r=>r.food==="omnivore").length] ].filter(r=>r[1]>0); return { groups:[ {title:"Teilnehmende nach Stufe und Geschlecht",columns:["Stufe","Gesamt","m","w","d"],rows:stageRows,stages:stageRows.map(r=>r[0])}, {title:"Verpflegung",columns:["Verpflegung","Anzahl"],rows:foodRows,stages:[]} ] }; }; if(type==="rdp"){ const participantRows=rows.filter(r=>!["Leitende","Mitarbeitende"].includes(r.stage)); const volunteerRows=rows.filter(r=>["Leitende","Mitarbeitende"].includes(r.stage)); const pBands=[ ["unter 10",a=>a<10], ["10 bis unter 14",a=>a>=10&&a<14], ["14 bis unter 18",a=>a>=14&&a<18], ["18 bis unter 27",a=>a>=18&&a<27], ["27 und älter",a=>a>=27] ]; const vBands=[ ["unter 16",a=>a<16], ["16 bis unter 18",a=>a>=16&&a<18], ["18 bis unter 27",a=>a>=18&&a<27], ["27 bis unter 45",a=>a>=27&&a<45], ["45 und älter",a=>a>=45] ]; const count=(list,gender,pred)=>list.filter(r=>r.gender===gender&&pred(ageAtStart(r.birthDate))).length; const participantTable=["w","m","d"].map(g=>[ g==="w"?"weiblich":g==="m"?"männlich":"divers", ...pBands.map(([,pred])=>count(participantRows,g,pred)) ]); const volunteerTable=vBands.map(([label,pred])=>[ label, ...["w","m","d"].map(g=>count(volunteerRows,g,pred)) ]); return { warning:"Die Bereiche für haupt-/nebenberuflich pädagogisch tätige sowie sonstige tätige Personen werden nicht automatisch ausgefüllt und bleiben im Originalbogen frei.", groups:[ {title:"Teilnehmende nach Altersgruppe",columns:["Geschlecht",...pBands.map(x=>x[0])],rows:participantTable,stages:[]}, {title:"Ehrenamtliche nach Altersgruppe",columns:["Alter","weiblich","männlich","divers"],rows:volunteerTable,stages:[]} ] }; } if(type==="photodetail")return { columns:["Nachname","Vorname","Aufnahmen","Eulenpost / Info","Homepage Stamm","Presse / Der Dom / Flyer","Schaukästen / Aktionen","Social Media","Messenger / geschützter Bereich","Name/Funktion/Alter","DV"], rows:rows.map(r=>[r.last,r.first,yesNo(r.recordingAllowed),yesNo(r.photoInfo),yesNo(r.photoWeb),yesNo(r.photoPress),yesNo(r.photoDisplay),yesNo(r.photoSocial),yesNo(r.photoMessenger),yesNo(r.photoNameData),yesNo(r.dvPhoto)]), stages:rows.map(r=>r.stage) }; if(type==="photolist")return { groups:[ {title:"Dürfen fotografiert werden",columns:["Nachname","Vorname"],rows:rows.filter(r=>r.recordingAllowed==="yes").map(r=>[r.last,r.first]),stages:rows.filter(r=>r.recordingAllowed==="yes").map(r=>r.stage)}, {title:"Nicht fotografieren",columns:["Nachname","Vorname"],rows:rows.filter(r=>r.recordingAllowed!=="yes").map(r=>[r.last,r.first]),stages:rows.filter(r=>r.recordingAllowed!=="yes").map(r=>r.stage)} ] }; if(type==="photomarking"){ const marked=rows.filter(r=>r.recordingAllowed!=="yes" || (cfg.diocese.checked && r.dvPhoto==="no")); return { columns:["Nachname","Vorname","Stufe","Grund / Hinweis"], rows:marked.map(r=>[ r.last,r.first,r.stage, r.recordingAllowed!=="yes" ?"Stamm: nicht fotografieren / keine Aufnahme" :"Diözesanverband: Kennzeichnung; keine Veröffentlichung" ]), stages:marked.map(r=>r.stage) }; } if(type==="emergency")return { columns:["Nachname","Vorname","Kontaktperson","Telefon","Ersatzkontakt","Hinweis"], rows:rows.map(r=>[r.last,r.first,r.guardian||"",r.phone,r.backup,r.healthHint?"siehe Gesundheits-/Medikamentenliste":""]), stages:rows.map(r=>r.stage) }; if(type==="health"){ const healthRows=rows.filter(r=> r.healthHint || (r.healthConditions||"").trim() || (r.medicationNames||"").trim() || (r.medicationMode&&r.medicationMode!=="none") ); return { warning:"Diese Liste enthält sensible Gesundheitsdaten. Bitte sehr sorgsam verwenden und nur den Personen zugänglich machen, die diese Informationen für die sichere Durchführung der Veranstaltung tatsächlich benötigen.", columns:["Nachname","Vorname","Stufe","Allergien / Krankheiten","Maßnahmen / Einschränkungen","Medikamente","Einnahme / Zeitpunkt"], rows:healthRows.map(r=>[ r.last,r.first,r.stage, r.healthConditions||"—", r.healthMeasures||"—", r.medicationNames||((r.medicationMode&&r.medicationMode!=="none")?"Angabe vorhanden":"—"), r.medicationSchedule||"—" ]), stages:healthRows.map(r=>r.stage) }; }; if(type==="payments")return { columns:["Nachname","Vorname","Stufe","Sollbetrag","Verwendungszweck","Eingegangen am","Betrag eingegangen","Erledigt"], rows:rows.map(r=>[r.last,r.first,r.stage,formatEuro(r.paymentAmount),buildPaymentCodeForRow(r),"","","☐"]), stages:rows.map(r=>r.stage) }; if(type==="kjp")return { columns:["Lfd. Nr.","K/R/L","Name, Vorname","Anschrift: Straße, PLZ, Wohnort","w/m/d","Alter","*"], rows:rows.map((r,i)=>[i+1,grantCodeFromStage(r.stage),`${r.last}, ${r.first}`,`${r.street}, ${r.postal} ${r.city}${r.district?" ("+r.district+")":""}`,r.gender,ageAtStart(r.birthDate),""]) }; if(type==="kreis")return { columns:["Nr.","Name, Vorname","Geb.-Jahr","Beruf","Wohnort (auch Ortsteil)","Unterschrift"], rows:rows.map((r,i)=>[i+1,`${r.last}, ${r.first}`,(r.birthDate||"").slice(0,4),r.occupation||"",`${r.postal} ${r.city}${r.district?" / "+r.district:""}`,""]) }; return {columns:[],rows:[]}; } function modelToTsv(model){ if(model.groups){ return model.groups.map(g=>[ g.title.toUpperCase(), g.columns.join("\t"), ...g.rows.map(r=>r.join("\t")) ].join("\n")).join("\n\n"); } return [model.columns.join("\t"),...model.rows.map(r=>r.join("\t"))].join("\n"); } function isBooleanVisual(value){return value==="Ja"||value==="Nein"||value==="Nein / Kennzeichnung";} function visualCell(value){ if(value==="Ja")return ''; if(value==="Nein")return ''; if(value==="Nein / Kennzeichnung")return '
    Kennzeichnung'; return escapeHtml(value); } function tableHtml(columns,rows,stages=[]){ const head=`${columns.map(c=>`${escapeHtml(c)}`).join("")}`; const body=rows.length ? `${rows.map((r,i)=>`${r.map((v,j)=>`${visualCell(v)}`).join("")}`).join("")}` : `Keine Einträge im aktuellen Filter.`; return `${head}${body}
    `; } function modelToHtml(model){ if(model.groups){ return model.groups.map(g=>`
    ${escapeHtml(g.title)}
    ${tableHtml(g.columns,g.rows,g.stages||[])}`).join(""); } return tableHtml(model.columns,model.rows,model.stages||[]); } let currentReportType=null; let currentReportText=""; function renderOpenedReport(type){ currentReportType=type; $$(".export-row").forEach(b=>b.classList.toggle("active",b.dataset.report===type)); const model=buildReportModel(type); currentReportText=modelToTsv(model); $("#reportOutputTitle").textContent=reportTitle(type); $("#reportPdfBtn").textContent=(type==="kjp"||type==="kreis"||type==="rdp")?"Originalformular als PDF":"PDF-Ansicht"; $("#reportOutputMeta").textContent=`${cfg.eventName.value} · ${$("#eventDateView").textContent} · ${currentFilterText()} · erstellt ${new Date().toLocaleString("de-DE")}`; $("#reportOutputBody").innerHTML=(model.warning?`
    Hinweis: ${escapeHtml(model.warning)}
    `:"")+modelToHtml(model); $("#reportOutput").classList.remove("hidden"); } function b64ToUint8(b64){ const raw=atob(b64),out=new Uint8Array(raw.length); for(let i=0;i|]+/g,"-").replace(/\s+/g," ").trim()+".pdf"; } function drawWrapped(page,text,x,y,maxWidth,font,size,lineHeight=10,maxLines=2){ const words=String(text||"").split(/\s+/).filter(Boolean); let line="",lines=[]; for(const word of words){ const test=line?line+" "+word:word; if(font.widthOfTextAtSize(test,size)>maxWidth && line){ lines.push(line);line=word; if(lines.length>=maxLines-1)break; }else line=test; } if(line&&lines.lengthpage.drawText(ln,{x,y:y-i*lineHeight,size,font,color:PDFLib.rgb(0,0,0)})); } function filterStampText(){ return filterIsActive()?currentFilterText():""; } function fillFixedKjpRows(page,font,rows,startIndex,numberedSlots){ const baseY=360.4,step=20.35; for(let i=0;ipage.drawLine({start:{x,y:top},end:{x,y:bottom},thickness:.55,color:rgb(.1,.1,.1)})); page.drawLine({start:{x:xs[0],y:top},end:{x:xs[xs.length-1],y:top},thickness:.55,color:rgb(.1,.1,.1)}); page.drawLine({start:{x:xs[0],y:top-headerH},end:{x:xs[xs.length-1],y:top-headerH},thickness:.55,color:rgb(.1,.1,.1)}); for(let i=1;i<=effectiveSlots;i++){ const yy=top-headerH-i*rowH; page.drawLine({start:{x:xs[0],y:yy},end:{x:xs[xs.length-1],y:yy},thickness:.4,color:rgb(.22,.22,.22)}); } page.drawText("Lfd.",{x:40,y:501,size:8,font});page.drawText("Nr.",{x:41,y:491,size:8,font}); page.drawText("K/R/L",{x:72,y:496,size:8,font}); page.drawText("Name, Vorname",{x:188,y:495,size:8.4,font}); page.drawText("Anschrift: Straße, PLZ, Wohnort",{x:443,y:495,size:8.4,font}); page.drawText("w/m/d",{x:692,y:495,size:8,font}); page.drawText("Alter",{x:753,y:495,size:8,font}); page.drawText("*",{x:801,y:493,size:12,font}); for(let i=0;ipage.drawRectangle({x:x+.8,y:y+.8,width:size-1.6,height:size-1.6,color:rgb(1,1,1)})); const type=state.event.measureType||""; if(!type)return; // Formular 2 unterscheidet hier Freizeit / Bildung / Aus- und Fortbildung / // Qualitätssicherung / Großveranstaltung. Unsere normalen Jugendmaßnahmen // laufen als Freizeit; nur Leitenden-Aus-/Fortbildung wird separat markiert. const selected=type==="training"?2:0; const x=boxes[selected]; page.drawLine({start:{x:x+1.5,y:y+1.5},end:{x:x+6.9,y:y+6.9},thickness:1,color:rgb(0,0,0)}); page.drawLine({start:{x:x+6.9,y:y+1.5},end:{x:x+1.5,y:y+6.9},thickness:1,color:rgb(0,0,0)}); } function validateOfficialListData(kind){ const missing=[]; if(!cfg.eventName.value.trim())missing.push("Veranstaltungsname"); if(!cfg.start.value)missing.push("Beginn-Datum"); if(!cfg.end.value)missing.push("Ende-Datum"); if(!cfg.location.value.trim())missing.push("Ort"); if(!state.event.measureType)missing.push("Art der Maßnahme"); if(!cfg.eventPostal.value.trim())missing.push("PLZ Veranstaltungsort"); if(missing.length){ alert("Die Liste kann noch nicht sinnvoll erzeugt werden. Bitte zuerst ergänzen:\n\n- "+missing.join("\n- ")); return false; } return true; } function reservePdfWindow(title){ const w=window.open("about:blank","_blank"); if(!w){alert("Bitte Pop-ups für diese Seite zulassen.");return null;} w.document.open(); w.document.write(`${escapeHtml(title||"PDF wird erstellt")}

    PDF wird erstellt …

    `); w.document.close(); return w; } function showPdfInReservedWindow(w,bytes,title){ const blob=new Blob([bytes],{type:"application/pdf"}); const url=URL.createObjectURL(blob); try{w.location.replace(url);}catch(e){w.location.href=url;} setTimeout(()=>URL.revokeObjectURL(url),300000); } async function openOfficialKjpPdf(){ if(!validateOfficialListData("kjp"))return; if(typeof PDFLib==="undefined"){alert("PDF-Bibliothek konnte nicht geladen werden.");return;} const title=kjpDocumentTitle(); const pdfWindow=reservePdfWindow(title);if(!pdfWindow)return; try{ const {PDFDocument,StandardFonts,rgb}=PDFLib; const raw=b64ToUint8(KJP_TEMPLATE_B64); const doc=await PDFDocument.load(raw); const sourceDoc=await PDFDocument.load(raw); const font=await doc.embedFont(StandardFonts.Helvetica); const rows=filteredDemo(),p1=doc.getPage(0); // Die korrigierte Vorlage ist bereits das Originalformular mit 14 // Teilnehmerzeilen und vollständigem Bestätigungsbereich auf Seite 1. p1.drawRectangle({x:300,y:511.7,width:510,height:16.5,color:rgb(.84,.84,.84)}); p1.drawText("Stamm St. Hedwig Paderborn",{x:304,y:517,size:9.5,font}); if(cfg.start.value&&cfg.end.value){ p1.drawText(`${shortDate(cfg.start.value)} - ${shortDate(cfg.end.value)}`,{x:107,y:459,size:9.5,font}); } if(eventPostalCity()){ // Das Originalfeld ist bereits leer und grau hinterlegt. Nur Text eintragen, // damit die darunterliegende Zeile mit den Maßnahmen-Kästchen unangetastet bleibt. p1.drawText(eventPostalCity(),{x:386,y:455,size:9.2,font}); } markKjpMeasureOriginal(p1); const stamp=filterStampText(); if(stamp)p1.drawText(stamp,{x:32,y:579,size:7.3,font,color:rgb(.72,.08,.08)}); const capacity=14; const totalNumbered=rows.length+3; if(totalNumbered<=capacity){ fillFixedKjpRows(p1,font,rows,0,totalNumbered); }else{ // Auf Seite 1 werden 14 Positionen genutzt; der Original-Bestätigungsbereich // wird dort ausgeblendet, damit die Bestätigung am Ende der Liste steht. fillFixedKjpRows(p1,font,rows,0,capacity); p1.drawRectangle({x:24,y:0,width:797,height:91,color:rgb(1,1,1)}); p1.drawLine({start:{x:31.5,y:91},end:{x:816.8,y:91},thickness:.55,color:rgb(.12,.12,.12)}); let startIndex=capacity; let remainingNumbers=totalNumbered-capacity; while(remainingNumbers>0){ const isLast=remainingNumbers<=13; const slots=Math.min(isLast?remainingNumbers:18,remainingNumbers); const page=drawKjpContinuationPage(doc,font,rows,startIndex,slots,isLast); startIndex+=slots; remainingNumbers-=slots; if(isLast){ await embedFixedKjpConfirmation(doc,sourceDoc,page,18); } } } doc.setTitle(title,{showInWindowTitleBar:true}); doc.setSubject(title); doc.setAuthor("DPSG Stamm St. Hedwig Paderborn"); doc.setCreator("DPSG Stamm St. Hedwig Paderborn"); const bytes=await doc.save(); showPdfInReservedWindow(pdfWindow,bytes,title); }catch(err){ console.error("KJP-PDF konnte nicht erstellt werden",err); try{ pdfWindow.document.open(); pdfWindow.document.write(`

    KJP-PDF konnte nicht erstellt werden.
    ${escapeHtml(err?.message||err)}

    `); pdfWindow.document.close(); }catch(e){} alert("Das KJP-PDF konnte nicht erstellt werden: "+(err?.message||err)); } } function kreisFieldName(base,globalNo){ if(globalNo<=10)return `${base}Row${globalNo}`; const local=globalNo-10; return local<=10?`${base}Row${local}_2`:`${base}Row${local}`; } function kreisRoleSuffix(stage){ if(stage==="Leitende")return " (L)"; if(stage==="Mitarbeitende")return " (M)"; return ""; } function drawKreisContinuationPage(doc,font,startNo,slots,rows){ const {rgb}=PDFLib; const page=doc.addPage([842.04,595.32]); page.drawText("Teilnehmendenliste – Fortsetzung",{x:300,y:558,size:13,font}); page.drawText("Kreis Paderborn – Jugendamt",{x:30,y:536,size:9,font}); const stamp=filterStampText(); if(stamp)page.drawText(stamp,{x:30,y:579,size:7.4,font,color:rgb(.72,.08,.08)}); const xs=[13,50,306,383,519,796,829],top=510,headerH=25,rowH=25,bottom=top-headerH-slots*rowH; xs.forEach(x=>page.drawLine({start:{x,y:top},end:{x,y:bottom},thickness:.55,color:rgb(.18,.18,.18)})); page.drawLine({start:{x:13,y:top},end:{x:829,y:top},thickness:.55,color:rgb(.18,.18,.18)}); page.drawLine({start:{x:13,y:top-headerH},end:{x:829,y:top-headerH},thickness:.55,color:rgb(.18,.18,.18)}); for(let i=1;i<=slots;i++){ const y=top-headerH-i*rowH; page.drawLine({start:{x:13,y},end:{x:829,y},thickness:.45,color:rgb(.25,.25,.25)}); } [["Nr.",22],["Name, Vorname",128],["Geb.-Jahr",319],["Beruf",427],["Wohnort (auch Ortsteil)",604],["Unterschrift",750]] .forEach(([t,x])=>page.drawText(t,{x,y:492,size:7.8,font})); for(let i=0;i{ try{ const f=form.getTextField(name); if(multiline)f.enableMultiline(); f.setText(String(value??"")); f.setFontSize(size); f.setAlignment(TextAlignment.Left); }catch(e){} }; textField("am vom",shortDate(cfg.start.value),9.5); textField("bis",shortDate(cfg.end.value),9.5); textField("in","",7.2,true); textField("Teilnehmendenliste zum Antrag vom",cfg.cityGrantNumber.value.trim(),8.5); textField("Name","DPSG Stamm St. Hedwig\nJosef-Spiegel-Platz 7\n33100 Paderborn",9,true); // Exactly one measure type. ["Check Box2","Check Box3","Check Box4","Check Box5"].forEach(name=>{try{form.getCheckBox(name).uncheck();}catch(e){}}); const measureMap={overnight:"Check Box2",day:"Check Box3",international:"Check Box4",training:"Check Box5"}; if(state.event.measureType){try{form.getCheckBox(measureMap[state.event.measureType]).check();}catch(e){}} const baseCapacity=25; const baseNumbered=rows.length<=baseCapacity ? rows.length+Math.min(3,baseCapacity-rows.length) : baseCapacity; for(let no=1;no<=baseNumbered;no++){ textField(kreisFieldName("Nr",no),no,9.2); const r=rows[no-1]; if(!r)continue; textField(kreisFieldName("Name Vorname",no),`${r.last}, ${r.first}${kreisRoleSuffix(r.stage)}`,9.2); textField(kreisFieldName("GebJahr",no),(r.birthDate||"").slice(0,4),9.2); textField(kreisFieldName("Beruf",no),r.occupation||"",9.2); textField(kreisFieldName("Wohnort auch Ortsteil",no),`${r.postal} ${r.city}${r.district?" / "+r.district:""}`,9.2); } form.updateFieldAppearances(font); form.flatten(); const p1=doc.getPage(0),stamp=filterStampText(); // Das originale Feld „in“ ist nur ca. 23 pt hoch. Drei Zeilen werden deshalb // nach dem Flatten gezielt mit kleiner, einheitlicher Schrift in das Feld gesetzt. const placeLines=eventVenueLines().slice(0,3); if(placeLines.length){ const startY=placeLines.length===1?410.0:placeLines.length===2?414.0:417.0; placeLines.forEach((line,i)=>{ p1.drawText(line,{x:575.5,y:startY-i*8.0,size:7.2,font,color:rgb(0,0,0)}); }); } if(stamp)p1.drawText(stamp,{x:30,y:579,size:7.4,font,color:rgb(.72,.08,.08)}); let index=baseCapacity,remaining=Math.max(0,rows.length-baseCapacity),nextNo=baseCapacity+1; while(remaining>0){ const take=Math.min(15,remaining); const isLast=remaining<=15; const slots=take+(isLast?Math.min(3,15-take):0); drawKreisContinuationPage(doc,font,nextNo,slots,rows); index+=take;nextNo+=slots;remaining-=take; } doc.setTitle(title,{showInWindowTitleBar:true}); doc.setSubject(title); doc.setAuthor("DPSG Stamm St. Hedwig Paderborn"); const bytes=await doc.save(); showPdfInReservedWindow(pdfWindow,bytes,title); }catch(err){ try{pdfWindow.close();}catch(e){} console.error("Kreis-PDF konnte nicht erstellt werden",err); alert("Das Kreis-PDF konnte nicht erstellt werden: "+(err?.message||err)); } } function rdpIsVolunteer(r){ return r.stage==="Leitende"||r.stage==="Mitarbeitende"; } function rdpParticipantBand(age){ if(age<10)return 0; if(age<14)return 1; if(age<18)return 2; if(age<27)return 3; return 4; } function rdpVolunteerBand(age){ if(age<16)return 0; if(age<18)return 1; if(age<27)return 2; if(age<45)return 3; return 4; } function rdpCounts(rows){ const genders={w:0,m:1,d:2}; const participants=Array.from({length:3},()=>Array(5).fill(0)); const volunteers=Array.from({length:5},()=>Array(3).fill(0)); rows.forEach(r=>{ const gi=genders[r.gender]; if(gi===undefined)return; const age=ageAtStart(r.birthDate); if(age===""||age===null||Number.isNaN(Number(age)))return; if(rdpIsVolunteer(r)){ volunteers[rdpVolunteerBand(Number(age))][gi]++; }else{ participants[gi][rdpParticipantBand(Number(age))]++; } }); return {participants,volunteers}; } function drawPdfCentered(page,text,cx,y,font,size=9){ const s=String(text??""); const w=font.widthOfTextAtSize(s,size); page.drawText(s,{x:cx-w/2,y,size,font,color:PDFLib.rgb(0,0,0)}); } async function openOfficialRdpPdf(){ if(!validateOfficialListData("rdp"))return; if(typeof PDFLib==="undefined"){alert("PDF-Bibliothek konnte nicht geladen werden.");return;} const title=`RDP ${cfg.eventName.value.trim()} v. ${shortDateNoYear(cfg.start.value)} bis ${shortDate(cfg.end.value)}`; const pdfWindow=reservePdfWindow(title);if(!pdfWindow)return; try{ const {PDFDocument,StandardFonts,rgb}=PDFLib; const doc=await PDFDocument.load(b64ToUint8(RDP_TEMPLATE_B64)); const page=doc.getPage(0); const font=await doc.embedFont(StandardFonts.Helvetica); const rows=filteredDemo(); const counts=rdpCounts(rows); // Kopf page.drawText("DPSG Stamm St. Hedwig Paderborn",{x:208,y:715,size:9,font,color:rgb(0,0,0)}); const responsible=cfg.rdpResponsible.value.trim()||""; if(responsible)page.drawText(responsible,{x:281,y:695,size:9,font,color:rgb(0,0,0)}); page.drawText(shortDate(cfg.start.value),{x:137,y:675,size:8.5,font,color:rgb(0,0,0)}); page.drawText(shortDate(cfg.end.value),{x:282,y:675,size:8.5,font,color:rgb(0,0,0)}); const venue=(cfg.eventVenueName?.value||cfg.eventVenue?.value||cfg.location.value||"").trim(); if(venue)drawWrapped(page,venue,367,675,120,font,8.2,9,1); // Teilnehmende: weiblich / männlich / divers, je 5 Altersgruppen const participantX=[167,239,312,384,457]; const participantY=[584.5,514.5,444.5]; counts.participants.forEach((row,gi)=>{ row.forEach((value,bi)=>drawPdfCentered(page,value,participantX[bi],participantY[gi],font,9)); }); // Ehrenamtliche: 5 Altersgruppen x weiblich/männlich/divers const volunteerX=[167,239,312]; const volunteerY=[364.5,344.5,324.5,304.5,284.5]; counts.volunteers.forEach((row,ai)=>{ row.forEach((value,gi)=>drawPdfCentered(page,value,volunteerX[gi],volunteerY[ai],font,9)); }); // Haupt-/nebenberufliche und sonstige tätige Personen bleiben bewusst leer. const stamp=filterStampText(); if(stamp)page.drawText(stamp,{x:52,y:817,size:6.6,font,color:rgb(.72,.08,.08)}); doc.setTitle(title,{showInWindowTitleBar:true}); doc.setSubject("Beiblatt zur Teilnehmerinnen- und Teilnehmerliste – Wirksamkeitsdialog / Bundesstatistik"); doc.setAuthor("DPSG Stamm St. Hedwig Paderborn"); const bytes=await doc.save(); showPdfInReservedWindow(pdfWindow,bytes,title); }catch(err){ try{pdfWindow.close();}catch(e){} console.error("RDP-PDF konnte nicht erstellt werden",err); alert("Das RDP-PDF konnte nicht erstellt werden: "+(err?.message||err)); } } function openReportPdf(){ if(!currentReportType)return; if(currentReportType==="kjp"){openOfficialKjpPdf();return;} if(currentReportType==="kreis"){openOfficialKreisPdf();return;} if(currentReportType==="rdp"){openOfficialRdpPdf();return;} const model=buildReportModel(currentReportType); const stand=new Date().toLocaleString("de-DE"); const filterText=filterIsActive()?currentFilterText():""; const body=`

    ${escapeHtml(reportTitle(currentReportType))}

    Stand: ${escapeHtml(stand)}${filterText?`
    ${escapeHtml(filterText)}`:""}

    ${escapeHtml(cfg.eventName.value)} · ${escapeHtml($("#eventDateView").textContent)} · ${escapeHtml(cfg.location.value)}

    ${model.warning?`
    Hinweis: ${escapeHtml(model.warning)}
    `:""} ${modelToHtml(model)}`; const w=window.open("","_blank"); if(!w){alert("Bitte Pop-ups für diese Seite zulassen.");return;} w.document.write(`${escapeHtml(reportTitle(currentReportType))}
    ${body}`); w.document.close(); } $$("#adminReportsSection select").forEach(s=>s.addEventListener("change",renderReportStats)); $("#resetReportFiltersBtn").addEventListener("click",()=>{ $("#reportFilterStage").value=""; $("#reportFilterGender").value=""; $("#reportFilterFood").value=""; $("#reportFilterDvPhoto").value=""; $("#reportSort1").value="stage";$("#reportSort1Dir").value="asc"; $("#reportSort2").value="last";$("#reportSort2Dir").value="asc"; $("#reportSort3").value="first";$("#reportSort3Dir").value="asc"; renderReportStats(); }); $$(".export-row").forEach(btn=>btn.addEventListener("click",()=>{ renderOpenedReport(btn.dataset.report); $("#reportOutput").scrollIntoView({behavior:"smooth",block:"nearest"}); })); $("#copyReportBtn").addEventListener("click",async()=>{ if(!currentReportType)return; currentReportText=modelToTsv(buildReportModel(currentReportType)); try{ await navigator.clipboard.writeText(currentReportText); $("#copyReportBtn").textContent="Kopiert"; setTimeout(()=>$("#copyReportBtn").textContent="Liste kopieren",1200); }catch(e){alert(currentReportText);} }); $("#reportPdfBtn").addEventListener("click",openReportPdf); const ADMIN_MASTER_PASSWORD=""; function showAdminLogin(){ document.body.classList.add("admin-locked"); $("#adminLoginOverlay").classList.remove("hidden"); setTimeout(()=>$("#adminPasswordInput")?.focus(),50); } function unlockAdmin(){ document.body.classList.remove("admin-locked"); $("#adminLoginOverlay").classList.add("hidden"); try{sessionStorage.setItem("dpsgAdminUnlocked","1");}catch(e){} } function applyMode(){ const mode=new URLSearchParams(location.search).get("mode")||"admin"; const admin=mode!=="form"; $("#adminToolbar").classList.toggle("hidden",!admin); $("#testConfig").classList.toggle("hidden",!admin); $("#adminReportsSection").classList.toggle("hidden",!admin); if(!admin){ document.title=(cfg.eventName.value||"Veranstaltung")+" - Anmeldung"; document.body.classList.remove("admin-locked"); $("#adminLoginOverlay").classList.add("hidden"); return; } let unlocked=false; try{unlocked=sessionStorage.getItem("dpsgAdminUnlocked")==="1";}catch(e){} if(unlocked)unlockAdmin();else showAdminLogin(); } $("#adminLoginBtn").addEventListener("click",()=>{ if(false){ $("#adminLoginError").textContent=""; $("#adminPasswordInput").value=""; unlockAdmin(); }else{ $("#adminLoginError").textContent="Die Anmeldung erfolgt ausschließlich über Keycloak."; } }); $("#adminPasswordInput").addEventListener("keydown",e=>{ if(e.key==="Enter")$("#adminLoginBtn").click(); }); $("#adminLogoutBtn").addEventListener("click",()=>{ try{sessionStorage.removeItem("dpsgAdminUnlocked");}catch(e){} showAdminLogin(); }); function exportCurrentConfig(){ gatherAdmin(); const data=JSON.stringify(state,null,2); const blob=new Blob([data],{type:"application/json;charset=utf-8"}); const url=URL.createObjectURL(blob),a=document.createElement("a"); const base=(cfg.eventName.value||"Veranstaltung").replace(/[^\wäöüÄÖÜß-]+/g,"_"); a.href=url;a.download=`${base}_Konfiguration.json`;document.body.appendChild(a);a.click();a.remove(); URL.revokeObjectURL(url); } $("#exportConfigBtn").addEventListener("click",exportCurrentConfig); $("#importConfigBtn").addEventListener("click",()=>$("#importConfigFile").click()); $("#importConfigFile").addEventListener("change",e=>{ const file=e.target.files?.[0];if(!file)return; const reader=new FileReader(); reader.onload=()=>{ try{ const parsed=JSON.parse(reader.result); state=Object.assign(clone(DEFAULT_STATE),parsed,{ event:Object.assign(clone(DEFAULT_STATE.event),parsed.event||{}), stages:Object.assign(clone(DEFAULT_STATE.stages),parsed.stages||{}), modules:Object.assign(clone(DEFAULT_STATE.modules),parsed.modules||{}), extras:Object.assign(clone(DEFAULT_STATE.extras),parsed.extras||{}), emergency:Object.assign(clone(DEFAULT_STATE.emergency),parsed.emergency||{}), conditions:Object.assign(clone(DEFAULT_STATE.conditions),parsed.conditions||{}), packlists:Array.isArray(parsed.packlists)?parsed.packlists:clone(DEFAULT_PACKLISTS) }); safeStorageSet(JSON.stringify(state));populateAdmin(); $("#adminSaveStatus").textContent="Konfiguration importiert."; }catch(err){alert("Die Konfigurationsdatei konnte nicht gelesen werden.");} e.target.value=""; }; reader.readAsText(file,"utf-8"); }); $("#setAdminPasswordBtn").addEventListener("click",()=>{ const a=$("#cfgAdminPasswordNew").value,b=$("#cfgAdminPasswordConfirm").value; if(a.length<8){$("#adminPasswordStatus").textContent="Bitte mindestens 8 Zeichen verwenden.";return;} if(a!==b){$("#adminPasswordStatus").textContent="Die Kennwörter stimmen nicht überein.";return;} state.event.adminPassword=a; safeStorageSet(JSON.stringify(state)); $("#cfgAdminPasswordNew").value="";$("#cfgAdminPasswordConfirm").value=""; $("#adminPasswordStatus").textContent="Kennwort wurde für diesen Prototyp gespeichert."; }); $("#openDigiPortPrefillBtn").addEventListener("click",()=>{ const form=document.getElementById("digiPortPrefillForm"); if(!form){ alert("Der vorbereitete Stadtantrag konnte technisch nicht geladen werden."); return; } form.submit(); }); $("#saveAdminBtn").addEventListener("click",()=>persist(true)); $("#openFormBtn").addEventListener("click",()=>{ persist(true); const url=new URL(location.href);url.searchParams.set("mode","form");window.open(url.toString(),"_blank"); }); $("#resetAdminBtn").addEventListener("click",()=>{ if(!confirm("Alle lokalen Änderungen verwerfen und auf den Standard zurücksetzen?"))return; state=clone(DEFAULT_STATE);safeStorageSet(JSON.stringify(state));populateAdmin();$("#adminSaveStatus").textContent="Standard geladen."; }); $("#duplicatePackBtn").addEventListener("click",duplicatePack); $("#newPackBtn").addEventListener("click",newPack); $("#renamePackBtn").addEventListener("click",renamePack); $("#deletePackBtn").addEventListener("click",deletePack); cfg.packSelect.addEventListener("change",()=>{ savePackEditorsToState();state.event.selectedPacklistId=cfg.packSelect.value;loadPackEditors();persist(true); }); $("#testConfig").addEventListener("input",e=>{ if(e.target===cfg.intro)syncIntroEditorSize(); if(e.target.matches("[data-pack-key]")){savePackEditorsToState();renderPackList();} else if(e.target.matches("[data-condition-key]")){state.conditions[e.target.dataset.conditionKey]=e.target.value;renderConditions();} updateAdminSetupStatus();autosave(); }); $("#testConfig").addEventListener("change",e=>{autosave();syncAll();updateAdminSetupStatus();}); $("#registrationForm").addEventListener("input",e=>{ if(e.target.id==="birthDate"||e.target.name==="stage")updateAgeLogic(); if(e.target.name==="occupationStatus"||e.target.name==="stage")syncOccupation(); if(e.target.name==="stage"){syncPaymentForm();updateModules();syncExtraVisibility();} if(["participantFirstName","participantLastName","stage","participantPaymentAmount"].includes(e.target.name))updatePaymentCode(); if(e.target.type==="radio"||e.target.type==="checkbox")toggleConditional(); }); $("#registrationForm").addEventListener("change",e=>{ if(e.target.id==="birthDate"||e.target.name==="stage")updateAgeLogic(); if(e.target.name==="occupationStatus"||e.target.name==="stage")syncOccupation(); if(e.target.name==="stage"){syncPaymentForm();updateModules();syncExtraVisibility();} if(["participantFirstName","participantLastName","stage","participantPaymentAmount"].includes(e.target.name))updatePaymentCode(); if(e.target.type==="radio"||e.target.type==="checkbox")toggleConditional(); }); $("#copyPaymentCodeBtn").addEventListener("click",async()=>{ const value=$("#paymentCodeView").textContent; try{await navigator.clipboard.writeText(value);$("#copyPaymentCodeBtn").textContent="Kopiert";setTimeout(()=>$("#copyPaymentCodeBtn").textContent="Zahlungscode kopieren",1200);} catch(e){alert(value);} }); $("#registrationForm").addEventListener("change",e=>{ if(e.target.name==="stage"||e.target.name==="participantPaymentAmount"){ queueMicrotask(updatePaymentCode); requestAnimationFrame(updatePaymentCode); } }); $("#registrationForm").addEventListener("input",e=>{ if(e.target.name==="participantFirstName"||e.target.name==="participantLastName"){ queueMicrotask(updatePaymentCode); } }); $("#registrationForm").addEventListener("submit",e=>{ e.preventDefault();updateAgeLogic();toggleConditional(); const formOk=e.currentTarget.checkValidity(),sigOk=validateSignatures(); if(!formOk)e.currentTarget.reportValidity();if(!sigOk)alert("Bitte die erforderlichen Unterschriftsfelder ausfüllen.");if(!formOk||!sigOk)return; lastSubmission=serializeForm(e.currentTarget);lastSummaryBody=buildSummaryBody(lastSubmission); $("#parentPdfPreviewSheet").innerHTML=lastSummaryBody; $("#confirmParentPdf").checked=false; $("#downloadParentPdfBtn").disabled=true; $("#parentPdfDownloadStatus").textContent=""; $("#resultCard").classList.remove("hidden"); $("#resultCard").scrollIntoView({behavior:"smooth",block:"start"}); }); $("#previewParticipantPdfBtn").addEventListener("click",()=>{ const w=window.open("","_blank"); if(!w){alert("Bitte Pop-ups für diese Seite zulassen.");return;} w.document.open();w.document.write(fullPrintableHtml(buildParticipantPdfPreviewBody()));w.document.close(); }); $("#previewCurrentPdfBtn").addEventListener("click",openCurrentDraftPdfPreview); $("#closeDraftPreviewBtn").addEventListener("click",closeCurrentDraftPdfPreview); $("#draftPreviewModal").addEventListener("click",e=>{if(e.target===$("#draftPreviewModal"))closeCurrentDraftPdfPreview();}); $("#confirmParentPdf").addEventListener("change",()=>{ $("#downloadParentPdfBtn").disabled=!$("#confirmParentPdf").checked; }); $("#downloadParentPdfBtn").addEventListener("click",downloadParentPdf); $("#anotherChildBtn").addEventListener("click",()=>{ const keepNames=[ "participantStreet","participantPostalCode","participantCity","participantDistrict", "guardian1Name","guardian1Phone","guardian1Email", "guardian2Name","guardian2Phone","guardian2Email", "backupContactName","backupContactPhone","declarationPlace" ]; const family={}; keepNames.forEach(name=>{ const el=$(`[name="${name}"]`); if(el)family[name]=el.value; }); $("#registrationForm").reset(); keepNames.forEach(name=>{ const el=$(`[name="${name}"]`); if(el && family[name]!==undefined)el.value=family[name]; }); ["participantSignature","guardianSignature"].forEach(id=>{ const c=$("#"+id); c.getContext("2d").clearRect(0,0,c.width,c.height); sigState[id].dirty=false; c.classList.remove("invalid-sig"); }); lastSubmission=null; lastSummaryBody=""; $("#resultCard").classList.add("hidden"); $("#familyCarryNotice").classList.remove("hidden"); updateAgeLogic(); toggleConditional(); syncStageOptions(); syncExtraVisibility(); syncPaymentForm(); syncOccupation(); $("#registrationForm").scrollIntoView({behavior:"smooth",block:"start"}); }); $("#resetBtn").addEventListener("click",()=>{ $("#registrationForm").reset(); ["participantSignature","guardianSignature"].forEach(id=>{const c=$("#"+id);c.getContext("2d").clearRect(0,0,c.width,c.height);sigState[id].dirty=false;c.classList.remove("invalid-sig");}); $("#resultCard").classList.add("hidden");$("#familyCarryNotice").classList.add("hidden");lastSubmission=null;lastSummaryBody="";updateAgeLogic();toggleConditional();syncStageOptions();syncExtraVisibility();syncPaymentForm(); }); function syncAll(){ gatherAdmin(); syncPaymentAdmin(); updateModules(); syncExtraVisibility(); syncEvent(); updateAgeLogic(); toggleConditional(); renderPackList(); renderConditions(); renderContributionOptions(); syncPaymentForm();syncOccupation();updateAdminSetupStatus(); } populateAdmin();renderReportStats();syncOccupation();renumberFormSections();updateAdminSetupStatus(); updateDeadlineCountdown();setInterval(updateDeadlineCountdown,60000); const numberObserver=new MutationObserver(()=>renumberFormSections()); numberObserver.observe($("#registrationForm"),{subtree:true,attributes:true,attributeFilter:["class"]}); applyMode(); })();