getRankingByArticles now uses GET /api/ranking?foucentrale=<code>
to fetch all rankings for a supplier in a single request instead of
making one request per article. For a 500-article supplier this goes
from ~500 HTTP calls to 2 (count + bulk), eliminating the timeout
that caused the client-side crash on large suppliers.
Falls back to per-article requests if no codeFournisseur is provided
or if the bulk endpoint fails.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
handleSnapshot was only looking at active draftChanges to build the
snapshot. After validation (Valider), drafts are cleared but changes
are applied to row.codeGamme via applyDraftsToRows. This caused
handleSnapshot (Camera/Export) to save an empty snapshot that
overwrote the real one, losing all gamme changes on page reload.
Now handleSnapshot compares (draftChanges[codein] ?? row.codeGamme)
vs row.codeGammeInit to detect ALL changes, whether drafted or
already validated. Uses codeGammeInit as "before" reference (API
value, never modified).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows row counts, gamme/code3 fill rates, and sample rows
for AUXENCE/A025 to diagnose missing classification data.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces raw sql ANY() template (which had array type issues) with
proper Drizzle inArray(), deduplicating by codein in JS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The old fournisseur code stored in ventesProduits may differ from the
new API codefou (e.g. "AUXENCE" vs "A025"), causing zero results.
Querying by codein = ANY(...) finds the classification data regardless
of how the supplier was previously keyed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
api-ff-client.ts:
- FfArticle: add reference (ref_fou_principale) and gtin fields
- getArticlesByFournisseur: map ref_fou_principale → reference, gtin → gtin
get-product-rows.ts:
- ProductRow seeded with reference and gtin from API articles
- Phase 6: read codeGamme, codeGammeInit, code3, libelle3 from ventesProduits
(read-only, DISTINCT ON codein ordered by updated_at DESC)
- Phase 7 snapshot still overrides DB gammes when a snapshot exists
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces bulk mouvements pagination + per-article stock N+1 with a single
batched call to the new mensuel endpoint (confirmed working via diag).
api-ff-client.ts:
- Remove getStockByFournisseur (no longer needed)
- Add FfMensuelEntry/Ventes/Receptions interfaces
- Add getMensuelByArticles(articles, dateDebut, dateFin, batchSize=20)
→ Map<codein, FfMensuelEntry[]> using no_id as API identifier
get-product-rows.ts:
- Phase 2: getMensuelByArticles + getCommandesByFournisseur in parallel
- Phase 5: aggregate mois×site entries → sales12m, stock12m, workingStores
- qte_vendue / ca_ht are negative → Math.abs()
- stock carry-forward for months with no data
- pa from prmp_fin_mois
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- extractList now explicitly checks "mouvements", "articles", "fournisseurs",
"ventes", "stocks", "commandes" wrapper keys before generic array fallback
- Diag endpoint auto-fetches first real codefou from fournisseurs instead
of hardcoded "AUXENCE" (which was supplier nom, not actual codefou)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>