---
suivi: 1756
date: 2026-09-30
sujet: Fournisseur dans l'ERP dès la validation de la demande
chantier: fournisseurs
type: evolution
statut: poussé
hash:
fichiers:
  - app/Support/Intacct/FournisseurMiroir.php
  - app/Services/DemandesFournisseurs/FournisseurApresValidation.php
  - app/Services/DemandesFournisseurs/DemandeFournisseurSuiviService.php
  - app/Services/IntacctService.php
  - app/Jobs/SyncFournisseursDepuisIntacct.php
  - app/Http/Controllers/Admin/DemandeFournisseurAdminController.php
  - routes/web.php
  - resources/js/Pages/Admin/DemandesFournisseurs/Show.vue
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - tests/Unit/FournisseurMiroirApresValidation1756SourceTest.php
  - public/build/
  - docs/suivi/SUIVI_1756_synchro_fournisseur_apres_validation.md
---

# SUIVI #1756 — fournisseur dans l'ERP dès la validation

## PROMPT ENVOYÉ

Après une création Sage réussie, relire ce seul fournisseur et l'écrire avec le même point que la synchro. Si la relecture échoue, la validation reste réussie, avec un message et un bouton pour réessayer. Les coordonnées bancaires absentes de Sage se complètent depuis la demande. Alerte et Teams inchangés, avec « disponible dans l'ERP » si la fiche est écrite.

## FICHES LUES

- #1685 LEÇON : ne pas écrire le miroir avec le XML envoyé. Une seule fonction d'écriture, celle de la synchro. Relecture en échec : rien écrit, le geste métier reste réussi.
- #1742 LEÇON : Teams uniquement depuis le web. La clôture et l'alerte restent dans `cloturerApresTraitement`. Le refus n'est pas touché.

## CONSTAT

- Validation : `DemandeFournisseurAdminController::valider` (`app/Http/Controllers/Admin/DemandeFournisseurAdminController.php:127`). `IntacctService::creerFournisseur` (`app/Services/IntacctService.php:1324`) envoie IBAN → `BANKACCOUNTNUMBER`, BIC → `BUSINESSIDCODE`. Le VENDORID relu est `response['operation']['result']['data']['vendor']['VENDORID']`, sinon `result.key` (`:1377-1379`). Un `IntacctException` renvoie HTTP 500 et ne pose pas `statut=valide` (`:135-145`).
- Écriture synchro : `SyncFournisseursDepuisIntacct::handle`, `Fournisseur::query()->updateOrCreate(['intacct_id' => $intacctId], …)` (avant ce lot, lignes 120-123). Mapping nom, SIRET, statut, contact, encours, banque via `VendorBankDetailRowResolver`. Lecture unitaire déjà là : `readVendorPayloadByVendorId` (`IntacctService.php:373`).
- Lien demande → fiche : pas de colonne `fournisseur_id` sur `demandes_fournisseurs`. Le lien existant est `demandes_fournisseurs.intacct_vendor_id` = `fournisseurs.intacct_id` (`DemandeFournisseur.php:28`). Aucune colonne ajoutée.

## SYNTHÈSE

`FournisseurMiroir::ecrire` est le seul `updateOrCreate` du chemin heureux. La synchro complète l'appelle. Après validation réussie, `FournisseurApresValidation` relit le VENDOR et ses lignes bancaires, puis appelle `ecrire`. Si l'IBAN ou le BIC manque encore, ils sont recopiés depuis la demande, seulement s'ils sont vides. Relecture VENDOR en échec : validation conservée, journal `intacct`, message affiché, bouton « Synchroniser ce fournisseur ». Le repli d'erreur de la synchro complète (fiche minimale + `intacct_error`) est inchangé.

## DÉPLOIEMENT-TEST

- `git pull origin main`
- `php artisan route:clear`
- `php artisan view:clear`
- `php artisan journal:sync`

Pas de migration.

1. Valider une demande : la fiche est dans la liste des fournisseurs tout de suite (identifiant Sage, nom, SIRET, IBAN masqué au dépôt).
2. Elle est proposable à la saisie de facture sans attendre.
3. Relecture en échec : la demande est quand même validée, le message s'affiche, le bouton réessaie.
4. Une synchro complète ensuite met à jour la même fiche (`intacct_id`), sans doublon.
5. Un refus de demande ne change pas.

## LEÇON

Ne pas écrire le fournisseur avec le XML de création. `demandes_fournisseurs` n'a pas de `fournisseur_id` : le rattachement est `intacct_vendor_id`. `probeVendorBankFileDetailsByVendorId` relit tout l'index bancaire : la relecture unitaire ne doit pas l'appeler.
