feat: add "Sans vente 6 mois" tab to Gestion de Stock page

New SQL query pgGetSansVente6Mois returns products with available
stock (qte > 0) whose last sale was over 6 months ago or never.
Third tab added with filtering by supplier, search, sort, and Excel export.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Sonnet 4.6 committed 2026-04-14 13:17:56 +02:00
1 parent dc16beeda4
commit 71241fe0e6
3 files changed
+192 -6

No files matched your search

+48
View File
@@ -920,6 +920,54 @@ export async function pgGetStockNegatif(site?: string): Promise<PgStockNegatifRo
return result.rows as PgStockNegatifRow[];
}
// ---------------------------------------------------------------------------
// Stock sans vente depuis 6 mois
// ---------------------------------------------------------------------------
export interface PgSansVente6MoisRow {
codein: string;
libelle1: string;
fournisseur: string;
site: string;
stock_actuel: number;
derniere_vente: string | null;
jours_sans_vente: number | null;
}
/**
* Retourne les articles ayant du stock disponible (qte > 0)
* mais dont la dernière vente remonte à plus de 6 mois (ou n'ont jamais été vendus).
*/
export async function pgGetSansVente6Mois(site?: string): Promise<PgSansVente6MoisRow[]> {
const siteFilter = site ? sql`AND cs.site = ${site}` : sql``;
const result = await pgNoParallel(sql`
SELECT
a.codein,
COALESCE(a.libelle1, '') AS libelle1,
COALESCE(f.nom, af.code) AS fournisseur,
cs.site,
cs.qte::float AS stock_actuel,
cs.dernierevente::text AS derniere_vente,
CASE
WHEN cs.dernierevente IS NULL THEN NULL
ELSE (CURRENT_DATE - cs.dernierevente::date)
END AS jours_sans_vente
FROM cube_stock cs
JOIN articles a ON a.no_id = cs.artnoid
JOIN artfou1 af ON af.art_no_id = a.no_id AND af.preference = 1
JOIN fouident f ON f.code = af.code
WHERE cs.site IN ('292', '579')
AND cs.qte > 0
AND (
cs.dernierevente IS NULL
OR cs.dernierevente < CURRENT_DATE - INTERVAL '6 months'
)
${siteFilter}
ORDER BY cs.dernierevente ASC NULLS FIRST
`);
return result.rows as PgSansVente6MoisRow[];
}
// ---------------------------------------------------------------------------
// Commandes automatiques — par site + fournisseur avec franco
// ---------------------------------------------------------------------------