# Système des Relances Automatiques - ELAN EuropFacilities v2.1

## Architecture globale

```
app/Classes/relances_auto/
├── RelanceDevisPrestataires.php    ← Relances devis prestataires (J+5,10,15)
├── RelanceFacturesBI.php           ← Relances factures/BIs prestataires (J+5,10,15)
└── RelanceFacturesClients.php      ← Relances factures clients impayées (J+N)

app/Http/Controllers/
├── TasksController.php             ← Orchestrateur (route HTTP cron)
└── ActionsRelancesController.php   ← Relances manuelles (UI)

app/Mail/
└── Mail_ElanStandard.php           ← Envoi mail universel (cherche template par tex_code)

app/Functions/
└── mailing.php                     ← envoyerMail() + routage vers les classes mail

routes/web.php                      ← Routes HTTP pour cron et actions relances
```

### Déclenchement

Les relances auto sont déclenchées par un **cron HTTP externe** (cPanel, EasyCron...) :

```
GET http://domaine.com/tasks/general_tasks   ← orchestre TOUTES les relances
```

Routes individuelles (débogage ou usage séparé) :
```
GET /tasks/relance_auto_devis_prestataires
GET /tasks/relance_auto_factures_prestataires
GET /tasks/relance_auto_factures_clients
```

`TasksController::general_tasks()` vérifie l'activation de chaque relance (`par_value='oui'`) avant de l'exécuter.

> **Note :** `app/Console/Kernel.php` est vide — pas de commandes Artisan schedulées.

---

## Relances existantes

### 1. Devis prestataires — `RelanceDevisPrestataires`

**Cible :** Devis prestataires en statut "Attente prestataire" dont `int_gpType = 0`

**Délais configurables :**
| par_code | Défaut | Description |
|---|---|---|
| `relance_proQuo_active` | `oui` | Active/désactive |
| `relance_proQuo_delay_1` | `5` | Jours → 1ère relance |
| `relance_proQuo_delay_2` | `10` | Jours → 2ème relance |
| `relance_proQuo_delay_closure` | `15` | Jours → 3ème + clôture du devis |

**Templates mail (table `texte`) :**
| tex_code | Usage |
|---|---|
| `relance_devis_first` | 1ère relance auto |
| `relance_devis_second` | 2ème relance auto |
| `relance_devis_third` | 3ème relance + changement statut "Délai dépassé" |

**Champs de tracking (table `provider_quote`) :**
- `proQuo_autoRelaunchCount` — compteur relances auto (0→3)
- `proQuo_lastRelaunchDate` — date dernière relance
- (distinct de `proQuo_RelaunchCount` = compteur relances **manuelles**)

**Log :** `storage/logs/relance_auto_devis_prestataires.log`

---

### 2. Factures/BIs prestataires — `RelanceFacturesBI`

**Cible :** Commandes prestataires avec statut dans le groupe `sta_proreq_relanceFac_auto` (383, 360, 356, 392)

| Statut | Signification |
|---|---|
| 383 (`sta_defaut_bi_recu`) | BI reçu, facture manquante |
| 360 (`sta_default_att_fac_bi`) | Facture et BI manquants |
| 356 | Facture reçue, BI manquant |
| 392 (`sta_default_att_bi`) | Attente BI |

**Référence temporelle :** `proReq_achievementDate` (date d'exécution de la commande)

**Délais configurables :**
| par_code | Défaut | Description |
|---|---|---|
| `relance_factBI_active` | `oui` | Active/désactive |
| `relance_factBI_delay_1` | `5` | Jours → 1ère relance |
| `relance_factBI_delay_2` | `10` | Jours → 2ème relance |
| `relance_factBI_delay_ultime` | `15` | Jours → relance ultime |
| `relance_factBI_email_compta` | _(vide)_ | Emails CC relance ultime (séparés par `;`) |

**Templates mail :**
| tex_code | Usage |
|---|---|
| `relance_factBI_first_second` | Relances 1 et 2 (variable `{{num_relance}}`) |
| `relance_factBI_ultime` | Relance 3 + CC comptabilité |

**Champs de tracking (table `provider_request`) :**
- `proReq_autoRelaunchCount` — compteur (0→3)
- `proReq_lastAutoRelaunchDate` — date dernière relance auto
- `proReq_lastDocumentType` — `'facture'`, `'BI'` ou `'facture et BI'`

**Log :** `storage/logs/relance_auto_factures_bi.log`

---

### 3. Factures clients impayées — `RelanceFacturesClients`

**Cible :** Factures clients statut "Attente paiement", `cusInv_payed=0`, échéance dépassée de N jours, et `cusInv_autoRelaunched=0` (non encore relancée)

**Particularité :** Les factures sont **groupées par client** — un seul mail par client avec tableau de toutes ses factures.

**Délais configurables :**
| par_code | Défaut | Description |
|---|---|---|
| `relance_cusInv_active` | `oui` | Active/désactive |
| `relance_cusInv_delay` | `7` | Jours après échéance pour déclencher |
| `relance_cusInv_email_cc` | _(email)_ | Emails CC (séparés par `;`) |

**Template mail :**
| tex_code | Variables disponibles |
|---|---|
| `relance_auto_cusInv` | `{{CONTACT_NAME}}`, `{{MONTANT_TOTAL}}`, `{{LISTE_FACTURES}}` (tableau HTML) |

**Champs de tracking (table `customer_invoice`) :**
- `cusInv_autoRelaunched` — 0/1 (a été relancée ou non)
- `cusInv_autoRelaunchDate` — date de la relance

> **Important :** Une facture n'est relancée **qu'une seule fois** (pas de relance répétée contrairement aux devis). Pour re-relancer, remettre `cusInv_autoRelaunched=0`.

**Log :** `storage/logs/relance_auto_factures_clients.log`

---

## Fonctionnement du mail — envoyerMail() et Mail_ElanStandard

```php
// mailing.php
envoyerMail($to, $type, $params, $params2=null, $direct=0)
```

Flux :
1. `envoyerMail()` crée un objet `Mail_ElanStandard($type, $params)` selon le `$type`
2. `Mail_ElanStandard` cherche le template dans la table `texte` par `tex_code`
3. Remplace les variables `{{variable}}` dans le corps et le sujet
4. Ajoute header/footer standard
5. Envoie via queue ou direct selon paramètre `email_sending_method`
6. Optionnellement log dans `intervention_message` si paramètre `mails_in_messages='oui'`

---

## Paramétrage UI

Route : `GET /parametrage/parametres` → onglet "Relances autos"

Les paramètres sont modifiables en back-office. Chaque paramètre est stocké dans la table `parameter` :
```
par_type = 'relances_autos'
par_code = 'relance_xxx_yyy'
par_value = valeur actuelle
```

---

## Guide : créer une nouvelle relance automatique

### Étape 1 — Créer la classe de relance

`app/Classes/relances_auto/RelanceNomType.php`

```php
<?php
namespace App\Classes\relances_auto;

use App\Models\Parameter;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class RelanceNomType
{
    private $delay;

    public function __construct()
    {
        $this->delay = Parameter::where('par_code', 'relance_nomtype_delay')
                                ->value('par_value') ?? 7;
    }

    public function execute(): array
    {
        Log::channel('relance_auto_nomtype')->info('Démarrage relances nomtype');

        // 1. Récupérer les entités éligibles
        $items = MonModele::where('statut', 'eligible')
                          ->whereNull('nomtype_autoRelaunched')
                          ->where('date_reference', '<=', Carbon::now()->subDays($this->delay))
                          ->get();

        $count = 0;

        foreach ($items as $item) {
            try {
                // 2. Envoyer le mail
                $params = [
                    'variable_cle' => $item->champ_exemple,
                    // ...
                ];
                envoyerMail($item->email_destinataire, 'relance_nomtype', $params);

                // 3. Mettre à jour tracking
                $item->update([
                    'nomtype_autoRelaunched'   => 1,
                    'nomtype_autoRelaunchDate' => Carbon::now()->toDateString(),
                ]);

                $count++;
                Log::channel('relance_auto_nomtype')->info("Relancé : #{$item->id}");
            } catch (\Exception $e) {
                Log::channel('relance_auto_nomtype')->error("Erreur #{$item->id} : " . $e->getMessage());
            }
        }

        Log::channel('relance_auto_nomtype')->info("Fin : {$count} relances envoyées");
        return ['status' => 'ok', 'count' => $count];
    }
}
```

### Étape 2 — Migration paramètres

```php
// database/migrations/YYYY_MM_DD_add_relance_nomtype_parameters.php
DB::table('parameter')->insert([
    ['par_type' => 'relances_autos', 'par_code' => 'relance_nomtype_active',
     'par_descriptionFr' => 'Activer les relances auto nomtype', 'par_value' => 'oui'],
    ['par_type' => 'relances_autos', 'par_code' => 'relance_nomtype_delay',
     'par_descriptionFr' => 'Délai (jours) avant relance nomtype', 'par_value' => '7'],
]);
```

### Étape 3 — Migration template mail

```php
// database/migrations/YYYY_MM_DD_add_relance_nomtype_texte.php
DB::table('texte')->insert([
    'tex_code'      => 'relance_nomtype',
    'tex_type'      => 'mail',
    'tex_nameFr'    => 'Relance - Nom Type',
    'tex_mailObject'=> 'Objet : {{variable_cle}}',
    'tex_textFr'    => '<div>Bonjour,<br>...<br>{{variable_cle}}<br>Cordialement</div>',
]);
```

### Étape 4 — Enregistrer le type dans mailing.php

Dans `app/Functions/mailing.php`, ajouter le cas dans `envoyerMail()` :

```php
case "relance_nomtype":
    $leMail = new Mail_ElanStandard("relance_nomtype", $params);
    break;
```

### Étape 5 — Traitement dans Mail_ElanStandard

Dans `app/Mail/Mail_ElanStandard.php`, ajouter le remplacement des variables :

```php
case "relance_nomtype":
    $texte   = Texte::where('tex_code', 'relance_nomtype')->first();
    $Contenu = str_replace('{{variable_cle}}', $Infos['variable_cle'], $texte->tex_textFr);
    $Sujet   = str_replace('{{variable_cle}}', $Infos['variable_cle'], $texte->tex_mailObject);
    $this->Subject = $Sujet;
    $this->Body    = $Contenu;
    break;
```

### Étape 6 — Ajouter dans TasksController

Dans `app/Http/Controllers/TasksController.php` :

```php
// Dans general_tasks() :
$isActive = Parameter::where('par_code', 'relance_nomtype_active')->value('par_value');
if ($isActive == 'oui') {
    $this->relance_auto_nomtype();
}

// Nouvelle méthode :
public function relance_auto_nomtype()
{
    try {
        $service = new \App\Classes\relances_auto\RelanceNomType();
        $result  = $service->execute();
        return response()->json($result);
    } catch (\Exception $e) {
        Log::channel('relance_auto_nomtype')->error($e->getMessage());
        return response()->json(['error' => $e->getMessage()], 500);
    }
}
```

### Étape 7 — Ajouter la route (optionnel)

```php
Route::get('tasks/relance_auto_nomtype', [TasksController::class, 'relance_auto_nomtype']);
```

### Étape 8 — Configurer le canal de log

Dans `config/logging.php`, ajouter dans `channels` :

```php
'relance_auto_nomtype' => [
    'driver' => 'single',
    'path'   => storage_path('logs/relance_auto_nomtype.log'),
    'level'  => 'debug',
],
```

### Étape 9 — Migration champs de tracking

```php
Schema::table('ma_table', function (Blueprint $table) {
    $table->tinyInteger('nomtype_autoRelaunched')->default(0)->after('...');
    $table->date('nomtype_autoRelaunchDate')->nullable()->after('nomtype_autoRelaunched');
});
```

---

## Récapitulatif des fichiers clés

| Fichier | Rôle |
|---|---|
| [TasksController.php](app/Http/Controllers/TasksController.php) | Orchestrateur cron HTTP |
| [RelanceDevisPrestataires.php](app/Classes/relances_auto/RelanceDevisPrestataires.php) | Logique relances devis |
| [RelanceFacturesBI.php](app/Classes/relances_auto/RelanceFacturesBI.php) | Logique relances factures/BI |
| [RelanceFacturesClients.php](app/Classes/relances_auto/RelanceFacturesClients.php) | Logique relances factures clients |
| [Mail_ElanStandard.php](app/Mail/Mail_ElanStandard.php) | Envoi mail + substitution variables |
| [mailing.php](app/Functions/mailing.php) | `envoyerMail()` + routage types mail |
| [ActionsRelancesController.php](app/Http/Controllers/ActionsRelancesController.php) | Relances manuelles (UI) |

## Tableau synthétique

| Relance | Classe | Fréquence | Champs tracking | Unique/Multiple |
|---|---|---|---|---|
| Devis presta | `RelanceDevisPrestataires` | J+5,10,15 (3 relances max) | `proQuo_autoRelaunchCount`, `proQuo_lastRelaunchDate` | Multiple (jusqu'à 3) |
| Factures/BI presta | `RelanceFacturesBI` | J+5,10,15 après réalisation | `proReq_autoRelaunchCount`, `proReq_lastAutoRelaunchDate`, `proReq_lastDocumentType` | Multiple (jusqu'à 3) |
| Factures clients | `RelanceFacturesClients` | J+N après échéance (1 fois) | `cusInv_autoRelaunched`, `cusInv_autoRelaunchDate` | **Unique** (remettre à 0 pour re-relancer) |
