feat(r3.3): écrans web de la gestion — stock, achats, coûts OT, documents, statistiques

- Stock : alertes sous seuil (strie ambre), « Préparer le BC » sur la ligne ;
  fiche pièce où les mouvements SONT le stock (entrée / ajustement motivé)
- Bons de commande : liste + panneau (envoi, annulation, réception → entrées
  de stock à PU figé) ; création préremplie depuis l'alerte de seuil
- Fiche OT : carte « Pièces & main-d'œuvre » réelle (consommation à prix figé
  annoncé avant le clic, temps au taux figé) + carte Documents (upload/download) ;
  même carte Documents sur la fiche ascenseur
- Statistiques : 4 KPI, pannes par organe (bilans codés), coûts par mois,
  top équipements ; le tableau de bord allume « Pannes par organe »
- Tiers, bibliothèque (upload rattaché, filtre par type), taux horaire
  éditable dans Personnes ; nav Ressources/Pilotage activée par la matrice
- Recette R3 Playwright (2 parcours autonomes) ; cleanup-e2e étendu aux
  entités R3 ; le formulaire BC attend la fin du refetch (stock périmé en cache)

13/13 e2e verts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pr-daaif
2026-07-16 22:16:56 +01:00
parent a4e98c2000
commit c5382a5538
20 changed files with 2056 additions and 28 deletions

View File

@@ -6,6 +6,39 @@ import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// R3 — d'abord les traces de gestion (les mouvements liés à un OT E2E
// seraient orphelins après sa suppression et fausseraient les stocks seedés)
await prisma.stockMovement.deleteMany({
where: {
OR: [
{ part: { designation: { contains: 'E2E' } } },
{ workOrder: { title: { contains: 'E2E' } } },
{ purchaseOrder: { supplier: { name: { contains: 'E2E' } } } },
],
},
});
await prisma.document.deleteMany({
where: {
OR: [
{ fileName: { contains: 'e2e' } },
{ workOrder: { title: { contains: 'E2E' } } },
],
},
});
await prisma.purchaseOrderLine.deleteMany({
where: {
OR: [
{ part: { designation: { contains: 'E2E' } } },
{ purchaseOrder: { supplier: { name: { contains: 'E2E' } } } },
],
},
});
await prisma.purchaseOrder.deleteMany({
where: { supplier: { name: { contains: 'E2E' } } },
});
await prisma.part.deleteMany({ where: { designation: { contains: 'E2E' } } });
await prisma.partner.deleteMany({ where: { name: { contains: 'E2E' } } });
await prisma.request.deleteMany({ where: { description: { contains: 'E2E' } } });
await prisma.workOrder.deleteMany({ where: { title: { contains: 'E2E' } } });
await prisma.meterReading.deleteMany({ where: { value: { gte: 90_000_000 } } });