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 {