diff --git a/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx b/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx index 7bf5ff9..9f38867 100644 --- a/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx +++ b/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx @@ -148,6 +148,56 @@ const ShiftPlanView: React.FC = () => { return date.getDay() === 0 ? 7 : date.getDay(); }; + const debugManagerAvailability = () => { + if (!shiftPlan || !employees.length || !availabilities.length) return; + + const manager = employees.find(emp => emp.role === 'admin'); + if (!manager) { + console.log('❌ Kein Manager (admin) gefunden'); + return; + } + + console.log('🔍 Manager-Analyse:', { + manager: manager.name, + managerId: manager.id, + totalAvailabilities: availabilities.length, + managerAvailabilities: availabilities.filter(a => a.employeeId === manager.id).length + }); + + // Prüfe speziell die leeren Manager-Schichten + const emptyManagerShifts = [ + 'a8ef4ce0-adfd-4ec3-8c58-efa0f7347f9f', + 'a496a8d6-f7a0-4d77-96de-c165379378c4', + 'ea2d73d1-8354-4833-8c87-40f318ce8be0', + '90eb5454-2ae2-4445-86b7-a6e0e2cf0b22' + ]; + + emptyManagerShifts.forEach(shiftId => { + const scheduledShift = shiftPlan.scheduledShifts?.find(s => s.id === shiftId); + if (scheduledShift) { + const dayOfWeek = getDayOfWeek(scheduledShift.date); + const shiftKey = `${dayOfWeek}-${scheduledShift.timeSlotId}`; + + const managerAvailability = availabilities.find(a => + a.employeeId === manager.id && + a.dayOfWeek === dayOfWeek && + a.timeSlotId === scheduledShift.timeSlotId + ); + + console.log(`📊 Schicht ${shiftId}:`, { + date: scheduledShift.date, + dayOfWeek, + timeSlotId: scheduledShift.timeSlotId, + shiftKey, + managerAvailability: managerAvailability ? managerAvailability.preferenceLevel : 'NICHT GEFUNDEN', + status: managerAvailability ? + (managerAvailability.preferenceLevel === 3 ? '❌ NICHT VERFÜGBAR' : '✅ VERFÜGBAR') : + '❌ KEINE VERFÜGBARKEITSDATEN' + }); + } + }); + }; + const handlePreviewAssignment = async () => { if (!shiftPlan) return; @@ -164,6 +214,26 @@ const ShiftPlanView: React.FC = () => { } ); + // DEBUG: Überprüfe die tatsächlichen Violations + console.log('🔍 VIOLATIONS ANALYSIS:', { + allViolations: result.violations, + criticalViolations: result.violations.filter(v => + v.includes('ERROR:') || v.includes('❌ KRITISCH:') + ), + warningViolations: result.violations.filter(v => + v.includes('WARNING:') || v.includes('⚠️') + ), + infoViolations: result.violations.filter(v => + v.includes('INFO:') + ), + criticalCount: result.violations.filter(v => + v.includes('ERROR:') || v.includes('❌ KRITISCH:') + ).length, + canPublish: result.violations.filter(v => + v.includes('ERROR:') || v.includes('❌ KRITISCH:') + ).length === 0 + }); + setAssignmentResult(result); setShowAssignmentPreview(true); @@ -173,48 +243,23 @@ const ShiftPlanView: React.FC = () => { result.resolutionReport.forEach(line => console.log(line)); } - // KORRIGIERT: Entscheidung basierend auf Reparatur-Bericht statt allProblemsResolved - const allCriticalResolved = result.resolutionReport && - result.resolutionReport.some(line => - line.includes('Alle kritischen Probleme behoben: ✅ JA') - ); + // Entscheidung basierend auf tatsächlichen kritischen Violations + const criticalCount = result.violations.filter(v => + v.includes('ERROR:') || v.includes('❌ KRITISCH:') + ).length; - if (allCriticalResolved) { + if (criticalCount === 0) { showNotification({ type: 'success', title: 'Erfolg', message: 'Alle kritischen Probleme wurden behoben! Der Schichtplan kann veröffentlicht werden.' }); } else { - // Zähle nur kritische Probleme (ERROR oder ❌ KRITISCH) - const criticalProblems = result.violations.filter(v => - v.includes('ERROR:') || v.includes('❌ KRITISCH:') - ); - - // Zähle Warnungen separat - const warnings = result.violations.filter(v => - v.includes('WARNING:') || v.includes('⚠️') - ); - - if (criticalProblems.length > 0) { - showNotification({ - type: 'error', - title: 'Kritische Probleme', - message: `${criticalProblems.length} kritische Probleme müssen behoben werden` - }); - } else if (warnings.length > 0) { - showNotification({ - type: 'warning', - title: 'Warnungen', - message: `${warnings.length} Warnungen - Plan kann trotzdem veröffentlicht werden` - }); - } else { - showNotification({ - type: 'success', - title: 'Erfolg', - message: 'Keine Probleme gefunden! Der Schichtplan kann veröffentlicht werden.' - }); - } + showNotification({ + type: 'error', + title: 'Kritische Probleme', + message: `${criticalCount} kritische Probleme müssen behoben werden` + }); } } catch (error) { @@ -312,14 +357,28 @@ const ShiftPlanView: React.FC = () => { try { setReverting(true); + // 1. Zuerst zurücksetzen const updatedPlan = await shiftPlanService.revertToDraft(id); - setShiftPlan(updatedPlan); + + // 2. Dann ALLE Daten neu laden + await loadShiftPlanData(); + + // 3. Assignment-Result zurücksetzen setAssignmentResult(null); + + // 4. Preview schließen falls geöffnet + setShowAssignmentPreview(false); showNotification({ type: 'success', title: 'Erfolg', - message: 'Schichtplan wurde erfolgreich zurück in den Entwurfsstatus gesetzt.' + message: 'Schichtplan wurde erfolgreich zurück in den Entwurfsstatus gesetzt. Alle Daten wurden neu geladen.' + }); + + console.log('Scheduled shifts after revert:', { + hasScheduledShifts: !!shiftPlan.scheduledShifts, + count: shiftPlan.scheduledShifts?.length || 0, + firstFew: shiftPlan.scheduledShifts?.slice(0, 3) }); } catch (error) { @@ -705,28 +764,56 @@ const ShiftPlanView: React.FC = () => { }}>

Wochenmuster-Zuordnung

- {/* Reparatur-Bericht anzeigen */} + {/* Detaillierter Reparatur-Bericht anzeigen */} {assignmentResult.resolutionReport && (
-

Reparatur-Bericht

-
- {assignmentResult.resolutionReport.map((line, index) => ( -
- {line} -
- ))} +

+ 📋 Detaillierter Reparatur-Bericht +

+
+ {assignmentResult.resolutionReport.map((line, index) => { + let color = '#2c3e50'; + let fontWeight = 'normal'; + + if (line.includes('✅') || line.includes('ALLES KRITISCHEN PROBLEME BEHOBEN')) { + color = '#2ecc71'; + fontWeight = 'bold'; + } else if (line.includes('❌') || line.includes('KRITISCHEN PROBLEME')) { + color = '#e74c3c'; + fontWeight = 'bold'; + } else if (line.includes('⚠️')) { + color = '#f39c12'; + } else if (line.includes('📊') || line.includes('🔧') || line.includes('📅') || line.includes('🚨') || line.includes('🛠️') || line.includes('💡') || line.includes('🎯')) { + color = '#3498db'; + fontWeight = 'bold'; + } else if (line.startsWith(' •') || line.startsWith(' -')) { + color = '#7f8c8d'; + } + + return ( +
+ {line} +
+ ); + })}
)} @@ -736,11 +823,10 @@ const ShiftPlanView: React.FC = () => {

Zusammenfassung:

- {/* Entscheidung basierend auf Reparatur-Bericht */} - {assignmentResult.resolutionReport && - assignmentResult.resolutionReport.some(line => - line.includes('Alle kritischen Probleme behoben: ✅ JA') - ) ? ( + {/* Entscheidung basierend auf tatsächlichen kritischen Problemen */} + {assignmentResult.violations.filter(v => + v.includes('ERROR:') || v.includes('❌ KRITISCH:') + ).length === 0 ? (
{