---
suivi: 1460
date: 2026-09-04
sujet: Widget factures à valider — seconde source dépôts à compléter
chantier: dashboard
type: feature
statut: poussé
hash: d0013b00e37bf934dacb01bd68eaadb541b4a440
fichiers:
  - app/Services/Dashboard/WidgetDataService.php
  - resources/js/Components/Dashboard/WidgetBody.vue
  - config/dashboard_widgets.php
  - tests/Unit/WidgetFacturesAValider1460Test.php
  - tests/Unit/WidgetFacturesAValider1460SourceTest.php
  - tests/Unit/CompleterSaisieFacture1458SourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
---

# SUIVI #1460 — Widget « Mes factures à valider » + dépôts à compléter

## PROMPT ENVOYÉ

Widget affiche « Aucune facture à valider » alors que l’utilisateur a des dépôts
à compléter (tâches `completer_saisie_facture` #1458). Ajouter une seconde
source dans le même widget, liste unique mélangée, badges « À compléter » /
« À valider », sans nouveau widget ni renommage.

## FICHES LUES

- `#1458` LEÇON : taskable DepotFacture ; rail Mes tâches ; fiche_url
  `/depot-factures?depot={uuid}` ; widget volontairement non touché alors.
- `#1333` LEÇON : limite 4 lignes ; valideur désigné courant ; pas de scroll.
- `#1331` LEÇON : FactureVisibility ; orphelins conservés ; prune interdit.
- `#1354` LEÇON : même pattern widget listes + FV.

## SYNTHÈSE

### Mesures (étape 1)

1. `WidgetDataService::facturesAValider` (~L188+) : Facture NV1/NV2 +
   `workflow_validations` en_attente / validateur_id = user ; FV ; limit 4 ;
   items `{id,reference,fournisseur,programme,programme_id,montant_ht,link,statut}`.
2. `WidgetBody.vue` branche `factures_a_valider` : lignes Link, empty
   « Aucune facture à valider », rest_count / voir_tout `/validations`.
3. `CompleterSaisieFactureTaskSync` : assignee via valideur saisie ;
   `tasks.assignee_id` / email / azure_id ; ouvertes = nouveau|en_cours.
4. User courant = argument `$user` de `getDataForWidget` ; branche NV :
   `FactureVisibility::canViewFacture` ; branche compléter : filtre
   `tasks.assignee_id` (prouvé peuplé).
5. Clic NV : `/factures/fiche/{id}` (inchangé).

### Mapping

| nature (back) | Badge UI | URL | Source |
|---|---|---|---|
| `a_valider` | À valider | `/factures/fiche/{id}` | Facture NV1/NV2 + workflow |
| `a_completer` | À compléter | `/depot-factures?depot={uuid}` | Task completer ouverte, assignee_id |

### Implémentation

- Fusion serveur structure commune + `_sort_ts` ; tri plus ancien en haut.
- Limite existante `FACTURES_WIDGET_LIMIT = 4` ; `total` / `rest_count` incluent les deux.
- Badge compact (`shrink-0`) ; pas de `overflow-x-hidden`.
- `suivanteAValider` et `CompleterSaisieFactureTaskSync` non modifiés.
- Après #1459 : les 14 dépôts sans tâche apparaîtront seuls dès qu’une tâche
  ouverte existe — aucun retouche widget nécessaire.

### Compteur ailleurs

Pas de badge navigation dédié à ce widget. Compteur = `total` / `rest_count`
dans le payload widget uniquement.

## DÉPLOIEMENT-TEST

```bash
git pull origin main
php artisan optimize:clear
php artisan view:clear
# touch OPcache (fichier PHP modifié) — obligatoire OVH mutualisé
touch app/Services/Dashboard/WidgetDataService.php
php artisan journal:sync
# Pas de migration. Pas de npm/composer/optimize/config:cache sur OVH.
```

Bundle dashboard : `assets/Index-DOTckuyW.js`.

## LEÇON

Le widget « à valider » ne voit que des `Facture` : un dépôt amont n’y apparaît
que via une **seconde source** (Task #1458), pas un élargissement de filtre NV.
Normaliser côté serveur les structures de ligne hétérogènes. Tri urgence =
plus ancien en haut après fusion. Isolation = `assignee_id` peuplé, pas
`hasAnyM365Group`.
