# Refactoring : Filière rattachée à l'Agent — Plan Final

## Contexte

La filière réglementaire (coefficients, jours fériés, quotas) est actuellement portée par le **Service**. Le changement consiste à la porter directement par **l'Agent**, indépendamment de son service.

Chaîne actuelle : `Agent → HistoriqueService → Service.id_filiere → Filière`  
Cible : `Agent → HistoriqueFiliere → Filière` (pour la réglementation)  
Service conservé pour : motifs, horaires de nuit, délégation, organigramme.

---

## Décisions Validées

| Sujet | Décision |
|---|---|
| **Historique filière** | Option A : table `historique_filieres` (changement rare mais possible) |
| **Migration données** | Affecter à chaque agent la filière de son service actuel |
| **services.id_filiere** | Conservée — modifiable sur le profil agent et à sa création (pré-remplissage) |
| **Règle de délégation** | **Inchangée : délégué = même service** |
| **Regroupement impression/validation** | **Inchangé : regroupement par SERVICE** |
| **Catégories d'astreintes** | Filtrées par la filière de l'agent à la date saisie |
| **Calcul HS (OvertimeCalculator)** | La filière doit être lue via `HistoriqueFiliere` à la date de réalisation |

---

## Ce qui NE CHANGE PAS

- Structure de `HistoriqueService`
- Service : motifs, `heure_nuit_debut`, `heure_nuit_fin`, chefs de service
- Règle de délégation (même service)
- Regroupement et impression des feuilles de synthèse (par service)
- Coefficients, jours fériés, paramètres des filières

---

## Proposed Changes

### Phase 1 — Base de données

---

#### [NEW] Migration `create_historique_filieres_table`

```sql
CREATE TABLE historique_filieres (
  id_historique_filiere  INT AUTO_INCREMENT PRIMARY KEY,
  id_user                INT NOT NULL,
  id_filiere             INT NOT NULL,
  date_entree            DATE NOT NULL,
  FOREIGN KEY (id_user)    REFERENCES users(id),
  FOREIGN KEY (id_filiere) REFERENCES filieres(id_filiere)
);
```

#### [NEW] Migration `migrate_filiere_from_service_to_agents`

Peuple `historique_filieres` depuis l'état existant :
- Pour chaque agent, récupérer `id_filiere` du service de son historique le plus ancien.
- Insérer une ligne dans `historique_filieres` avec cette filière et `date_entree = date du premier historique de service` (ou `2000-01-01` par défaut).

---

### Phase 2 — Modèles

---

#### [NEW] `app/Models/HistoriqueFiliere.php`

Miroir de `HistoriqueService` :
```php
class HistoriqueFiliere extends Model {
    protected $table    = 'historique_filieres';
    protected $primaryKey = 'id_historique_filiere';
    public $timestamps  = false;
    protected $fillable = ['id_user', 'id_filiere', 'date_entree'];

    public function user()    { return $this->belongsTo(User::class, 'id_user'); }
    public function filiere() { return $this->belongsTo(Filiere::class, 'id_filiere'); }
}
```

#### [MODIFY] `app/Models/ProfileAgent.php`

Ajouter :
- `filiereActuelle()` → `hasOne(HistoriqueFiliere)->latestOfMany('date_entree')`
- `filiereAtDate($date)` → méthode de recherche historique (miroir de `serviceAtDate`)
- `isDelegationValid()` : **ne change pas** (même service)

#### [MODIFY] `app/Models/Filiere.php`

- Remplacer `services()` par → relation `agentsHistorique()` vers `historique_filieres`
- **Garder** `services()` pour l'UI d'affichage (association visuelle service↔filière)
- Modifier `destroy()` guard : bloquer si des agents sont rattachés via `historique_filieres`

---

### Phase 3 — Logique métier

---

#### [MODIFY] `app/Models/Parametre.php`

**`getFiliereStatus()`** : La détermination de la filière d'une ligne HS/Astreinte change de :
```php
// AVANT : service → filière
$hist = HistoriqueService::where('id_user', $userId)→where('date_entree', '<=', $date)→first();
return $hist?→service?→id_filiere == $idFiliere;
```
→
```php
// APRÈS : filière directe de l'agent
$histF = HistoriqueFiliere::where('id_user', $userId)→where('date_entree', '<=', $date)→orderBy('date_entree', 'desc')→first();
return $histF?→id_filiere == $idFiliere;
```

**`hasUnprintedFiliere()`** : Idem, récupérer les filières uniques via `historique_filieres`.

#### [MODIFY] `app/Services/OvertimeCalculator.php`

Dans `recalculateDeclaration()`, résolution de la filière :
```php
// AVANT
$service = $historique→service;
$filiere = $service→filiere;
```
→
```php
// APRÈS
$service = $historique→service;        // Conservé pour horaires de nuit
$filiereHist = $profile→filiereAtDate($line→date_realisation);
$filiere = $filiereHist?→filiere;      // Filière réglementaire de l'agent
```
> Le service reste utilisé pour `heure_nuit_debut` / `heure_nuit_fin`.

---

### Phase 4 — Contrôleurs

---

#### [MODIFY] `app/Http/Controllers/HeureSupController.php`

- `index()` : Résolution de `$linesByFiliere` → via `HistoriqueFiliere` (non plus `service→id_filiere`)
- `print()` : Filtrage des lignes HS/Astreintes par filière → via `HistoriqueFiliere`
- Le service reste utilisé pour les motifs et les horaires de nuit.
- **Le regroupement par service pour l'impression est CONSERVÉ tel quel.**

#### [MODIFY] `app/Http/Controllers/AstreinteAgentController.php`

- `index()` : `$fId` (identifiant de filière) vient de `HistoriqueFiliere` et non plus de `service→id_filiere`
- `getCategoriesForDate()` : `$filiereId` vient de `HistoriqueFiliere` à la date saisie — **c'est le changement principal pour les astreintes : on propose uniquement les catégories de la filière de l'agent**
- `store()` / `update()` : Même logique

#### [MODIFY] `app/Http/Controllers/Admin/AgentController.php`

- `store()` : Après création de l'agent et de son `HistoriqueService`, créer aussi une entrée dans `historique_filieres`
- `update()` : Si la filière change, ajouter une entrée dans `historique_filieres`
- `edit()` : Charger `$filieres` dans la vue pour le dropdown de sélection de filière
- La validation de la délégation (même service) **ne change pas**

#### [MODIFY] `app/Http/Controllers/Admin/FiliereController.php`

- `destroy()` : Guard → vérifier `historique_filieres` au lieu de `services`

#### [MODIFY] `app/Http/Controllers/Admin/PaieStatsController.php`

Filtre par filière :
- **Avant** : `filieres → services → agents` via `Service.id_filiere`
- **Après** : `filieres → agents` directement via `historique_filieres` **ET** `services → agents` via `historiqueService`
- Les deux filtres (filière ET service) peuvent s'appliquer indépendamment ou conjointement

#### [MODIFY] `app/Http/Controllers/Admin/ServiceController.php`

- `index()` / `create()` / `edit()` : `id_filiere` dans la vue service est conservé comme "filière indicative" — à utiliser pour pré-remplir lors de la création d'un agent dans ce service.
- Aucun impact sur le calcul.

---

### Phase 5 — Vues (Blade)

---

#### [MODIFY] `resources/views/admin/agents/create.blade.php` + `edit.blade.php`

- Ajouter un dropdown **"Filière de l'agent"** (sélection obligatoire).
- À la création : pré-remplir avec la filière du service sélectionné (via JS).
- À la modification : afficher la filière actuelle de l'agent.

#### Les vues de synthèse/impression NE CHANGENT PAS

- Le regroupement par service est conservé.
- La filière n'est utilisée que pour récupérer les bons coefficients (côté contrôleur).

#### [MODIFY] `resources/views/admin/services/index.blade.php` + `edit.blade.php`

- Le libellé du champ `id_filiere` peut être précisé : "Filière par défaut (pré-remplissage agents)".

---

## Ordre d'exécution

1. Migrations (DB schema + données)
2. Modèles (`HistoriqueFiliere`, `ProfileAgent`, `Filiere`)
3. `Parametre.php` (logique de verrouillage)
4. `OvertimeCalculator.php`
5. `AgentController.php` (Admin)
6. `HeureSupController.php`
7. `AstreinteAgentController.php`
8. `FiliereController.php`, `PaieStatsController.php`
9. Vues (`agents/create`, `agents/edit`)

---

## Plan de Vérification

1. Création d'agent → ligne créée dans `historique_filieres`
2. Modification de filière d'agent → nouvelle ligne dans `historique_filieres`, ancienne conservée
3. Calcul HS avec agent ayant changé de filière → bonne filière utilisée à chaque date
4. Astreintes → catégories proposées = uniquement celles de la filière de l'agent à la date
5. Verrouillage `isLocked()` / `getFiliereStatus()` → utilise `historique_filieres`
6. PaieStats → filtre filière fonctionne directement sur les agents
7. Suppression filière → bloquée si agents rattachés
8. Délégation → toujours même service (inchangée)
