function drawRoomPDFPage(doc, room, isFirstPage, includeRewards = false) { if (!isFirstPage) { doc.addPage(); } const pct = getRoomProgress(room); doc.setFontSize(18); doc.setTextColor(30, 41, 59); doc.text(`Mainpark Mühlheim – Datenblatt`, 14, 20); doc.setFontSize(14); doc.setTextColor(79, 70, 229); doc.text(`${room.room_number} (${room.floor})`, 14, 28); doc.setDrawColor(226, 232, 240); doc.setFillColor(248, 250, 252); doc.roundedRect(14, 33, 182, 22, 2, 2, 'FD'); doc.setFontSize(9); doc.setTextColor(100, 116, 139); doc.text(`Gesamtstatus:`, 18, 41); doc.text(`Material-Status:`, 75, 41); doc.text(`Fortschritt:`, 135, 41); doc.setFontSize(10); doc.setTextColor(15, 23, 42); doc.text(`${room.status}`, 18, 48); doc.text(`${room.material_status || 'Offen'}`, 75, 48); doc.text(`${pct}%`, 135, 48); let currentY = 62; if (room.notes) { doc.setFontSize(10); doc.setTextColor(30, 41, 59); doc.text("Notizen & Kommentare:", 14, currentY); currentY += 5; doc.setFontSize(9); doc.setTextColor(71, 85, 105); const splitNotes = doc.splitTextToSize(room.notes, 180); doc.text(splitNotes, 14, currentY); currentY += (splitNotes.length * 4) + 6; } doc.setFontSize(10); doc.setTextColor(30, 41, 59); doc.text("Anstehende Arbeiten & Aufgaben:", 14, currentY); currentY += 4; const taskHeaders = includeRewards ? ['Status', 'Aufgabe', 'Zugewiesen an', 'Vergütung'] : ['Status', 'Aufgabe', 'Zugewiesen an']; const taskRows = []; if (room.tasks && room.tasks.length > 0) { room.tasks.forEach(t => { let assignedName = "👥 Alle (Team)"; if (t.assigned_to) { const prof = allProfiles.find(p => p.id === t.assigned_to); if (prof && prof.alias) assignedName = `👤 ${prof.alias}`; } const row = [ t.is_completed ? '[ X ] Erledigt' : '[ ] Offen', t.task_name, assignedName ]; if (includeRewards) { const reward = parseFloat(t.reward_amount || 0); row.push(reward > 0 ? `${reward.toFixed(2)} €` : '0,00 €'); } taskRows.push(row); }); } else { taskRows.push(includeRewards ? ['-', 'Keine Aufgaben eingetragen', '-', '-'] : ['-', 'Keine Aufgaben eingetragen', '-'] ); } doc.autoTable({ startY: currentY, head: [taskHeaders], body: taskRows, headStyles: { fillColor: [30, 41, 59], textColor: [255, 255, 255], fontStyle: 'bold' }, alternateRowStyles: { fillColor: [248, 250, 252] }, styles: { fontSize: 8.5, cellPadding: 2.5 } }); } function exportSingleRoomPDF(roomId) { const room = allRoomsData.find(r => r.id === roomId); if (!room) return; const includeRewards = confirm("Möchtest du die Aufgaben-Vergütungen im PDF-Export anzeigen?"); const { jsPDF } = window.jspdf; const doc = new jsPDF(); drawRoomPDFPage(doc, room, true, includeRewards); const safeName = room.room_number.replace(/[^a-zA-Z0-9]/g, '_'); doc.save(`Mainpark_${safeName}_DataSheet.pdf`); logActivity(room, `hat PDF-Datenblatt heruntergeladen (Vergütung: ${includeRewards ? 'Ja' : 'Nein'})`); } function exportSelectedRoomsPDF() { if (selectedRoomIds.size === 0) { alert('Bitte wähle zuerst mindestens ein Zimmer aus!'); return; } const includeRewards = confirm("Möchtest du die Aufgaben-Vergütungen in den exportierten PDFs anzeigen?"); const { jsPDF } = window.jspdf; const doc = new jsPDF(); const selectedRooms = allRoomsData.filter(r => selectedRoomIds.has(r.id)); selectedRooms.forEach((room, index) => { drawRoomPDFPage(doc, room, index === 0, includeRewards); }); doc.save(`Mainpark_Auswahl_Renovierung (${selectedRooms.length}_Zimmer).pdf`); logActivity(null, `hat PDF-Export für ${selectedRooms.length} Zimmer heruntergeladen (Vergütung: ${includeRewards ? 'Ja' : 'Nein'})`); } function handleExport(format) { const select = document.getElementById('export-select'); if (format === 'csv') { exportRoomsToCSV(); } else if (format === 'pdf') { exportRoomsToPDF(); } select.selectedIndex = 0; } function exportRoomsToCSV() { let csv = 'ID;Zimmername;Etage;Status;Material-Status;Fortschritt (%)\n'; allRoomsData.forEach(r => { const pct = getRoomProgress(r); csv += `${r.id};"${r.room_number}";"${r.floor}";"${r.status}";"${r.material_status || 'Offen'}";${pct}\n`; }); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement("a"); const url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", `Mainpark_Renovierung_Report.csv`); document.body.appendChild(link); link.click(); document.body.removeChild(link); logActivity(null, 'hat Gesamt-CSV Export (Excel) heruntergeladen'); } function exportRoomsToPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(18); doc.setTextColor(30, 41, 59); doc.text("Mainpark Mühlheim - Renovierungs-Status", 14, 20); doc.setFontSize(10); doc.setTextColor(100, 116, 139); const dateStr = new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); doc.text(`Erstellt von ${currentUserAlias} am: ${dateStr}`, 14, 27); const tableRows = []; allRoomsData.forEach(r => { const pct = getRoomProgress(r); tableRows.push([ r.room_number, r.floor, r.status, r.material_status || 'Offen', `${pct}%` ]); }); doc.autoTable({ startY: 33, head: [['Zimmer', 'Etage', 'Status', 'Material', 'Fortschritt']], body: tableRows, headStyles: { fillColor: [30, 41, 59], textColor: [255, 255, 255], fontStyle: 'bold' }, alternateRowStyles: { fillColor: [248, 250, 252] }, styles: { fontSize: 9, cellPadding: 3 } }); doc.save(`Mainpark_Renovierung_Report.pdf`); logActivity(null, 'hat Gesamt-PDF Übersicht heruntergeladen'); }