# Handoff — einvoicing « file d'attente de synchro » → Pichinov

De la session OPS/einvoicing. Cible : Pichinov einvoicing **1.1.0**, PHP **8.1**, DOL **23.0.1**, base « serious », `custom/einvoicing/`. Feature déjà posée sur OPS (prod) et Serious (prod).

## 0) Réponse à ta question 1 (fork ?)
**NON committé sur un fork** pour l'instant — Jose : **pas de PR/branche amont tant qu'il n'a pas validé**. Donc voie fichiers/diffs ci‑dessous. (À terme, quand Jose valide, ça pourra remonter dans le fork monorepo — d'ici là, à **rejouer après chaque MAJ git** du module, comme un patch #710.)

## 1) ViaPartner / proxy — CONFIRMATION (ta question 3)
Mes modifs de `SuperPDPProvider::syncFlows` sont **uniquement dans la boucle générique de traitement des flux** (gestion d'erreur métier). **Aucune** branche `EINVOICING_SUPERPDP_VIAPARTNER=='proxy'` ni `EINVOICING_PDP=='SUPERPDPViaPartner'` n'est touchée. La seule ligne contenant « ViaPartner » est :
```
$providershort = preg_replace('/ViaPartner$/', '', (string) $this->providerName);
```
→ elle **neutralise** juste le suffixe pour obtenir une clé de file d'attente propre (regroupement), elle ne change RIEN au comportement proxy. **Multi‑instance** : la table de file a une colonne `entity` et tout est filtré par `getEntity('einvoicing')` → cloisonné par instance (OK pour opérateur ~11 instances).

## 2) 4 fichiers NOUVEAUX (dans `new/`, chemins relatifs sous `custom/einvoicing/`)
- `new/sync_pending_list.php`                          → `custom/einvoicing/sync_pending_list.php`
- `new/class/einvoicingsyncpending.class.php`          → `custom/einvoicing/class/einvoicingsyncpending.class.php`
- `new/sql/llx_einvoicing_sync_pending.sql`            → `custom/einvoicing/sql/llx_einvoicing_sync_pending.sql`
- `new/sql/llx_einvoicing_sync_pending.key.sql`        → `custom/einvoicing/sql/llx_einvoicing_sync_pending.key.sql`
(instance‑agnostiques, se copient tels quels)

## 3) 3 diffs (unified, à appliquer DEPUIS `custom/einvoicing/`)
```
cd .../custom/einvoicing
patch -p0 --fuzz=3 class/providers/SuperPDPProvider.class.php < superpdp.patch
patch -p0 --fuzz=5 core/modules/modEInvoicing.class.php      < modEInvoicing.patch
```
Ces diffs sont générés depuis la MÊME base 1.1.0 (OPS original→patché) ; ils s'appliquent proprement sur ta version (testé sur Serious ViaPartner + Pichinov hors‑ligne : 5 hunks SuperPDPProvider OK, modEInvoicing OK, lint php OK).
- **superpdp.patch** = 5 greffes : (a) init compteur `$pendingQueued` + `$providershort` + include classe file ; (b) sur erreur métier `PRODUCT_NOT_FOUND`/`THIRDPARTY_NOT_FOUND`/`SUPPLIER_INVOICE_FOUND_WITH_BAD_AMOUNT` → **enfile + `continue`** au lieu de `break` (skip‑and‑continue) ; (c) retrait de file sur succès ; (d)+(e) compteur dans le récap + le return.
- **modEInvoicing.patch** = ligne copyright Jose + 1 entrée menu (`billing`>`einvoicing_documents`>`einvoicing_sync_pending` → `/einvoicing/sync_pending_list.php`, position 1004).

**Langs** (append si absent) :
```
grep -q 'EInvoiceSyncPending=' langs/fr_FR/einvoicing.lang || cat langs_fr_FR_add.txt >> langs/fr_FR/einvoicing.lang
grep -q 'EInvoiceSyncPending=' langs/en_US/einvoicing.lang || cat langs_en_US_add.txt >> langs/en_US/einvoicing.lang
```

## 4) DDL nouvelle table (ta question 4)
Table `llx_einvoicing_sync_pending` — voir `new/sql/llx_einvoicing_sync_pending.sql` (CREATE) + `.key.sql` (index unique `(entity,provider,flow_id)` + index status). Colonnes : rowid, entity, provider, flow_id, flow_direction, flow_type, tracking_idref, fk_element_type, fk_element_id, reason_code, reason_message, action_data, action_html, match_data, flow_updatedat, nb_attempts, date_lastattempt, status(0=pending/1=resolved/2=ignored), date_creation, tms, fk_user_creat, fk_user_modif.
**Création** : les 2 `.sql` sont auto‑joués par `_load_tables()` à la (ré)activation du module. Sinon, bootstrap CLI qui lit les 2 fichiers et exécute chaque statement (ignorer « already exists »).

## 5) Menu + ordre des opérations (ta question 5)
Le menu est déclaré dans `modEInvoicing.class.php` (via le diff) et inséré en base par la **réactivation du module** (`$mod->init('noboxes')` insère dans `llx_menu`).

**Ordre recommandé** :
1. Backup HORS `htdocs/custom/` des 3 fichiers modifiés (méthode Pichinov, ex. `~/pichinov/backups/einvoicing-syncpending-<date>/`).
2. Copier les 4 nouveaux fichiers + appliquer les 2 patches + append langs. Lint `php -l` (8.1).
3. Créer la table (sql/ ou bootstrap).
4. **Réactiver le module** OU `$mod->init('noboxes')` en CLI (bootstrap OK sur Pichinov, conf.php a le bon chemin `/homez.786/`).
5. ⚠️ **Neutraliser les constantes** : `init()` ré‑insère les consts par défaut du descripteur (sur OPS il a ajouté `EINVOICING_EINVOICE_IN_REAL_TIME=1` qui était absente). **Snapshot `EINVOICING_%` avant/après init, et SUPPRIME toute const AJOUTÉE + RESTAURE toute valeur modifiée** → zéro changement de comportement (sur Serious : 8→8, aucun changement).
6. Smoke‑test : `SELECT ... FROM llx_einvoicing_sync_pending WHERE entity IN (getEntity('einvoicing'))` doit passer (0 ligne).

## État NEUTRE (ta demande)
Il n'y a **pas de toggle on/off** : la feature = « enfiler au lieu d'abandonner » sur des erreurs qui **cassaient déjà** la synchro. C'est donc une amélioration **sans downside** (jamais pire que l'abandon actuel). Si tu veux un « vrai off » avant validation Jose : **applique tout SAUF `superpdp.patch`** (nouveaux fichiers + menu + table restent inertes, UI vide) ; tu appliqueras le patch SuperPDPProvider quand Jose valide la bascule.

## Rollback
Restaurer les 3 fichiers depuis le backup + supprimer les 4 nouveaux + `DROP TABLE llx_einvoicing_sync_pending` + `DELETE FROM llx_menu WHERE url LIKE '%sync_pending_list%'`. (La table est additive, aucune donnée einvoicing existante touchée.)

## Copyright
Chaque fichier créé/modifié porte la ligne copyright Jose (` * Copyright (C) 2026<2tabs>Jose Martinez<4tabs><jose.martinez@pichinov.com>`), format identique à ses PR mergées.
