diff --git a/URGENT-API-FIX.md b/URGENT-API-FIX.md new file mode 100644 index 0000000..13a82cc --- /dev/null +++ b/URGENT-API-FIX.md @@ -0,0 +1,114 @@ +# Fix Urgent - API Enregistrement + Icône + +## ✅ Problèmes Identifiés et Corrigés + +### 1. **Doublon d'endpoint API** ❌ → ✅ +**Problème :** Deux endpoints `PUT /api/deliveries/:id` (lignes 670 et 766) +- Premier endpoint : Logique complète (auto-sync + auto-validation) +- Deuxième endpoint : Simple mise à jour MAIS écrase le premier ! + +**Solution :** +- ✅ Supprimé le doublon (ligne 766+) +- ✅ Conservé le premier avec toute la logique +- ✅ Ajouté logs debug pour traçabilité + +### 2. **Erreurs TypeScript** 🔧 → ✅ +**Problème :** 93 erreurs LSP → 88 erreurs LSP +- `userGroups` non typé +- `getSupplier()` n'existe pas + +**Solution :** +- ✅ Cast `(user as any).userGroups?.map()` avec fallback `|| []` +- ✅ Remplacé `storage.getSupplier()` par `storage.getSuppliers().find()` + +### 3. **Icône Interface** 👁️ → ⚙️ +**Changement :** Eye icon → Settings icon comme demandé +- ✅ Changé dans onglet manuel ET automatique +- ✅ Tooltip mis à jour : "Modifier les données de rapprochement" + +## 🔧 API Endpoint Final + +```typescript +PUT /api/deliveries/:id +├── 🔒 Authentication + Permissions +├── 📝 Validation insertDeliverySchema.partial() +├── 💾 storage.updateDelivery(id, data) +├── 🔄 Auto-sync Order (si status = 'delivered') +├── 🤖 Auto-validation Rapprochement (fournisseur automatique) +└── ✅ Response avec delivery mis à jour +``` + +## 🐛 Debug Logs Ajoutés + +### Console Backend +``` +🔄 Updating delivery: { id, data, user } +✅ Delivery updated successfully: { id, updatedDelivery } +🔄 Auto-sync: Delivery #X marked as delivered... +🤖 Auto-reconciliation: Delivery #X from automatic supplier... +``` + +### Console Frontend +``` +Sending update for delivery: X with data: {...} +Update response: {...} +``` + +## 🧪 Tests de Validation + +### Test 1 : Enregistrement Modal +- [ ] Ouvrir modal (icône ⚙️) +- [ ] Modifier N° BL, montants +- [ ] Cliquer "Enregistrer" +- [ ] **Vérifier console :** Logs "🔄 Updating delivery" et "✅ Delivery updated" +- [ ] Toast "Succès" affiché +- [ ] Modal se ferme +- [ ] Données mises à jour dans tableau + +### Test 2 : Validation Rapprochement +- [ ] Modal ouvert avec N° BL renseigné +- [ ] Cliquer "Valider le rapprochement" +- [ ] **Vérifier console :** `reconciled: true, validatedAt: ...` +- [ ] Toast "Succès" +- [ ] Ligne devient verte (rapproché) + +### Test 3 : Auto-validation +- [ ] Fournisseur en mode automatique +- [ ] Livraison status "delivered" + N° BL présent +- [ ] **Vérifier console :** "🤖 Auto-reconciliation" +- [ ] Rapprochement automatiquement validé + +## 🚨 Debug Si Toujours Erreur + +### 1. Vérifier Console F12 +```javascript +// Dans DevTools Network +PUT /api/deliveries/123 +Status: 200 ✅ ou 4xx/5xx ❌ +Response: {...} ou Error message +``` + +### 2. Vérifier Console Serveur +```bash +# Rechercher logs +grep "Updating delivery" logs +grep "Error updating delivery" logs +``` + +### 3. Test API Direct +```bash +curl -X PUT /api/deliveries/123 \ + -H "Content-Type: application/json" \ + -d '{"blNumber": "TEST123", "blAmount": 100}' +``` + +## 📊 Status + +- ✅ Doublon endpoint supprimé +- ✅ Logs debug ajoutés +- ✅ Types corrigés (88 erreurs vs 93) +- ✅ Icône Settings remplace Eye +- ✅ Modal avec debug console +- 🔄 **À tester en production** + +**L'enregistrement devrait maintenant fonctionner !** \ No newline at end of file diff --git a/attached_assets/{EBE743A0-E190-4BE7-84A1-DEBE974124BA}_1754998681214.png b/attached_assets/{EBE743A0-E190-4BE7-84A1-DEBE974124BA}_1754998681214.png new file mode 100644 index 0000000..6c38f7b Binary files /dev/null and b/attached_assets/{EBE743A0-E190-4BE7-84A1-DEBE974124BA}_1754998681214.png differ diff --git a/client/src/components/modals/ReconciliationModal.tsx b/client/src/components/modals/ReconciliationModal.tsx index d402164..702138e 100644 --- a/client/src/components/modals/ReconciliationModal.tsx +++ b/client/src/components/modals/ReconciliationModal.tsx @@ -50,7 +50,10 @@ export default function ReconciliationModal({ const updateDeliveryMutation = useMutation({ mutationFn: async (data: any) => { - await apiRequest(`/api/deliveries/${delivery?.id}`, "PUT", data); + console.log('Sending update for delivery:', delivery?.id, 'with data:', data); + const response = await apiRequest(`/api/deliveries/${delivery?.id}`, "PUT", data); + console.log('Update response:', response); + return response; }, onSuccess: () => { toast({ @@ -58,13 +61,15 @@ export default function ReconciliationModal({ description: "Données de rapprochement mises à jour avec succès", }); queryClient.invalidateQueries({ queryKey: ['/api/deliveries/bl'] }); + queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); if (onSave) onSave(); onClose(); }, - onError: (error) => { + onError: (error: any) => { + console.error('Update error:', error); toast({ title: "Erreur", - description: "Impossible de mettre à jour les données", + description: `Impossible de mettre à jour les données: ${error?.message || 'Erreur inconnue'}`, variant: "destructive", }); } diff --git a/client/src/pages/BLReconciliation.tsx b/client/src/pages/BLReconciliation.tsx index a790f36..b040e9c 100644 --- a/client/src/pages/BLReconciliation.tsx +++ b/client/src/pages/BLReconciliation.tsx @@ -464,13 +464,13 @@ export default function BLReconciliation() { )} )} - {/* Bouton Voir les détails toujours disponible */} + {/* Bouton Modifier toujours disponible */} @@ -613,9 +613,9 @@ export default function BLReconciliation() { {/* Dévalider automatique - admin uniquement */} {user?.role === 'admin' && ( diff --git a/server/routes.ts b/server/routes.ts index 0e0d498..dc7414f 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -683,14 +683,16 @@ export async function registerRoutes(app: Express): Promise { // Check permissions if (user.role !== 'admin') { - const userGroupIds = user.userGroups.map(ug => ug.groupId); + const userGroupIds = (user as any).userGroups?.map((ug: any) => ug.groupId) || []; if (!userGroupIds.includes(delivery.groupId)) { return res.status(403).json({ message: "Access denied" }); } } + console.log('🔄 Updating delivery:', { id, data: req.body, user: user.id }); const data = insertDeliverySchema.partial().parse(req.body); const updatedDelivery = await storage.updateDelivery(id, data); + console.log('✅ Delivery updated successfully:', { id, updatedDelivery }); // SYNCHRONISATION AUTOMATIQUE : Si livraison devient "delivered", marquer la commande associée comme "delivered" if (data.status === 'delivered' && updatedDelivery.orderId) { @@ -706,8 +708,9 @@ export async function registerRoutes(app: Express): Promise { // AUTO-VALIDATION RAPPROCHEMENT AUTOMATIQUE : Si fournisseur en mode automatique, livraison delivered + BL → auto-valider if (data.status === 'delivered' || data.blNumber) { try { - // Récupérer le fournisseur pour vérifier le mode automatique - const supplier = await storage.getSupplier(updatedDelivery.supplierId); + // Récupérer le fournisseur pour vérifier le mode automatique + const suppliers = await storage.getSuppliers(); + const supplier = suppliers.find((s: any) => s.id === updatedDelivery.supplierId); if (supplier?.automaticReconciliation && updatedDelivery.status === 'delivered' && @@ -763,36 +766,7 @@ export async function registerRoutes(app: Express): Promise { } }); - app.put('/api/deliveries/:id', isAuthenticated, async (req: any, res) => { - try { - const user = await storage.getUserWithGroups(req.user.claims ? req.user.claims.sub : req.user.id); - if (!user) { - return res.status(404).json({ message: "User not found" }); - } - - const id = parseInt(req.params.id); - const delivery = await storage.getDelivery(id); - - if (!delivery) { - return res.status(404).json({ message: "Delivery not found" }); - } - - // Check permissions - if (user.role !== 'admin') { - const userGroupIds = user.userGroups.map(ug => ug.groupId); - if (!userGroupIds.includes(delivery.groupId)) { - return res.status(403).json({ message: "Access denied" }); - } - } - - const data = insertDeliverySchema.partial().parse(req.body); - const updatedDelivery = await storage.updateDelivery(id, data); - res.json(updatedDelivery); - } catch (error) { - console.error("Error updating delivery:", error); - res.status(500).json({ message: "Failed to update delivery" }); - } - }); + // SUPPRIMÉ : Doublon d'endpoint PUT /api/deliveries/:id (le premier endpoint avec logique complète est conservé) app.delete('/api/deliveries/:id', isAuthenticated, async (req: any, res) => { try {