# Termin-Ausschluss: Intelligente Wochentags-Filterung

## 🎯 Problem

**Ausgangssituation:**
- Benutzer erstellt einen Kurs vom 22.12. - 28.12.
- Wählt alle Wochentage aus (Mo-So)
- Schließt aber 24.12., 25.12., 26.12. (Weihnachten) aus

**Altes Verhalten (FALSCH):**
- Alle 7 Wochentage wurden in `availability_day` gespeichert
- Die ausgeschlossenen Termine wurden nur in `excluded_dates` JSON gespeichert
- Buchungskalender zeigte trotzdem alle Tage an ❌

**Neues Verhalten (RICHTIG):**
- Nur die Wochentage, die **tatsächlich verfügbar** sind, werden in `availability_day` gespeichert
- Ausgeschlossene Termine werden NICHT als Wochentage gespeichert ✅

---

## 🔧 Implementierung

### Code-Location
**Datei:** `src/Controller/AppointmentController.php`  
**Methode:** `adminAvailability()` (Zeile 897-958)

### Logik-Ablauf

#### Schritt 1: Sammle ausgeschlossene Termine
```php
$excludedDates = [];
if (isset($data['excludedDates']) && is_array($data['excludedDates'])) {
    $excludedDates = $data['excludedDates'];
    $availability->setExcludedDates($excludedDates);
}
```

#### Schritt 2: Berechne tatsächlich verfügbare Wochentage
```php
$availableDaysOfWeek = $data['daysOfWeek'];

if (($data['type'] === 'limited_course' || $data['type'] === 'holiday_course') && !empty($excludedDates)) {
    $startDate = new \DateTime($data['startDate']);
    $endDate = new \DateTime($data['endDate']);
    $actualDates = [];
    
    $current = clone $startDate;
    while ($current <= $endDate) {
        $dayOfWeek = (int)$current->format('N'); // 1=Mo, 7=So
        
        if (in_array($dayOfWeek, $data['daysOfWeek'])) {
            $dateString = $current->format('Y-m-d');
            
            if (!in_array($dateString, $excludedDates)) {
                $actualDates[$dayOfWeek] = true;
            }
        }
        
        $current->modify('+1 day');
    }
    
    // Nur die Wochentage speichern, die tatsächlich vorkommen
    $availableDaysOfWeek = array_keys($actualDates);
}
```

#### Schritt 3: Speichere nur verfügbare Wochentage
```php
foreach ($availableDaysOfWeek as $dayOfWeek) {
    $day = new AvailabilityDay();
    $day->setDayOfWeek($dayOfWeek);
    // ... Zeiten setzen ...
    $availability->addDay($day);
}
```

---

## 📊 Beispiel

### Eingabe:
- **Zeitraum:** 22.12.2025 (Mo) - 28.12.2025 (So)
- **Wochentage:** Mo, Di, Mi, Do, Fr, Sa, So (alle)
- **Ausgeschlossene Termine:** 24.12., 25.12., 26.12.

### Berechnung:

| Datum | Wochentag | Ausgeschlossen? | Verfügbar? |
|-------|-----------|-----------------|------------|
| 22.12. | Montag (1) | Nein | ✅ Ja |
| 23.12. | Dienstag (2) | Nein | ✅ Ja |
| 24.12. | Mittwoch (3) | **Ja** | ❌ Nein |
| 25.12. | Donnerstag (4) | **Ja** | ❌ Nein |
| 26.12. | Freitag (5) | **Ja** | ❌ Nein |
| 27.12. | Samstag (6) | Nein | ✅ Ja |
| 28.12. | Sonntag (7) | Nein | ✅ Ja |

### Ergebnis in Datenbank:

**`availability` Tabelle:**
```json
{
  "id": 123,
  "name": "Weihnachtskurs",
  "type": "limited_course",
  "start_date": "2025-12-22",
  "end_date": "2025-12-28",
  "excluded_dates": ["2025-12-24", "2025-12-25", "2025-12-26"]
}
```

**`availability_day` Tabelle:**
```sql
INSERT INTO availability_day (availability_id, day_of_week) VALUES
(123, 1), -- Montag
(123, 2), -- Dienstag
(123, 6), -- Samstag
(123, 7); -- Sonntag

-- Mittwoch (3), Donnerstag (4), Freitag (5) NICHT gespeichert!
```

### Buchungskalender:
- ✅ Zeigt nur Mo, Di, Sa, So an
- ❌ Zeigt NICHT Mi, Do, Fr an

---

## ⚠️ Edge Cases

### Fall 1: Alle Termine ausgeschlossen
**Eingabe:**
- Zeitraum: 24.12. - 26.12.
- Wochentage: Mi, Do, Fr
- Ausgeschlossen: 24.12., 25.12., 26.12.

**Verhalten:**
```php
if (empty($availableDaysOfWeek)) {
    return $this->json([
        'success' => false, 
        'message' => 'Alle Termine wurden ausgeschlossen. Bitte wählen Sie mindestens einen verfügbaren Termin.'
    ]);
}
```

### Fall 2: Keine Termine ausgeschlossen
**Eingabe:**
- Zeitraum: 01.01. - 07.01.
- Wochentage: Mo, Mi, Fr
- Ausgeschlossen: (leer)

**Verhalten:**
```php
$availableDaysOfWeek = $data['daysOfWeek']; // Bleibt unverändert
```

### Fall 3: Nur ein Wochentag teilweise ausgeschlossen
**Eingabe:**
- Zeitraum: 01.12. - 31.12. (4 Montage)
- Wochentage: Mo
- Ausgeschlossen: 08.12. (nur 1 Montag)

**Verhalten:**
- Montag (1) bleibt in `availability_day`
- 3 Montage sind buchbar (01.12., 15.12., 22.12.)
- 1 Montag ist ausgeschlossen (08.12.) via `excluded_dates`

---

## 🔄 Zusammenspiel mit Buchungslogik

### Bei Termin-Buchung prüfen:

**AppointmentService.php** sollte prüfen:
1. Ist der Wochentag in `availability_day`? ✅
2. Ist das Datum in `excluded_dates`? ❌

```php
// Beispiel-Code (noch zu implementieren):
public function isDateAvailable(\DateTime $date, Availability $availability): bool
{
    $dayOfWeek = (int)$date->format('N');
    
    // Prüfe 1: Ist der Wochentag überhaupt verfügbar?
    $hasDayOfWeek = false;
    foreach ($availability->getDays() as $day) {
        if ($day->getDayOfWeek() === $dayOfWeek) {
            $hasDayOfWeek = true;
            break;
        }
    }
    
    if (!$hasDayOfWeek) {
        return false; // Wochentag nicht verfügbar
    }
    
    // Prüfe 2: Ist das spezifische Datum ausgeschlossen?
    if ($availability->isDateExcluded($date)) {
        return false; // Datum explizit ausgeschlossen
    }
    
    return true;
}
```

---

## ✅ Vorteile dieser Lösung

1. **Datenbank ist sauber**
   - Keine "toten" Wochentage in `availability_day`
   - Buchungskalender zeigt nur wirklich verfügbare Tage

2. **Performance**
   - Weniger Einträge in `availability_day`
   - Schnellere Abfragen

3. **Wartbarkeit**
   - Logik ist zentral an einer Stelle
   - `excluded_dates` dient als Dokumentation

4. **Benutzerfreundlich**
   - Admin sieht sofort welche Wochentage wirklich aktiv sind
   - Keine Verwirrung im Buchungskalender

---

## 🐛 Bekannte Einschränkungen

1. **Nur für zeitlich begrenzte Kurse**
   - Logic gilt nur für `limited_course` und `holiday_course`
   - Bei `recurring_course` werden alle Wochentage normal gespeichert

2. **Nachträgliche Änderungen**
   - Wenn später Termine ausgeschlossen werden, müssen Wochentage manuell aktualisiert werden

---

## 📝 Test-Checkliste

- [ ] Kurs mit ausgeschlossenen Terminen erstellen
- [ ] Prüfen: Richtige Wochentage in `availability_day`?
- [ ] Prüfen: Buchungskalender zeigt nur verfügbare Tage?
- [ ] Edge Case: Alle Termine ausschließen → Fehler?
- [ ] Edge Case: Keine Ausschlüsse → Alle Tage gespeichert?
- [ ] Edge Case: Wochentag komplett ausgeschlossen → Nicht in DB?
- [ ] Kurs bearbeiten: Ausschlüsse ändern → Wochentage aktualisiert?

---

## 🎉 Resultat

**Ihr Beispiel:**
- Zeitraum: 22.12. - 28.12.
- Ausgeschlossen: 24.12., 25.12., 26.12.

**Datenbank:**
- ✅ Nur Mo, Di, Sa, So in `availability_day`
- ❌ NICHT Mi, Do, Fr

**Buchungskalender:**
- ✅ Zeigt nur Mo, Di, Sa, So
- ✅ Kunde kann nur diese Tage buchen

