mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Update interface and fix delivery saving and reconciliation issues
Update the edit button icon from an eye to a gear, fix a duplicate API endpoint, improve type safety, and add backend and frontend debug logs for delivery updates and reconciliation processes. Replit-Commit-Author: Agent Replit-Commit-Session-Id: b163d4c0-de5e-4f4e-a9c0-aed4c7049718 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/b163d4c0-de5e-4f4e-a9c0-aed4c7049718/eBIc7ee
This commit is contained in:
1 parent
e6d261f1f7
commit
7da24cfbe1
5 files changed
+134
-41
No files matched your search
@@ -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 !**
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
@@ -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",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -464,13 +464,13 @@ export default function BLReconciliation() {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{/* Bouton Voir les détails toujours disponible */}
|
||||
{/* Bouton Modifier toujours disponible */}
|
||||
<button
|
||||
onClick={() => handleOpenModal(delivery)}
|
||||
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 p-1 hover:bg-blue-50 rounded"
|
||||
title="Voir les détails / Éditer"
|
||||
title="Modifier les données de rapprochement"
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
<Settings className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -613,9 +613,9 @@ export default function BLReconciliation() {
|
||||
<button
|
||||
onClick={() => handleOpenModal(delivery)}
|
||||
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 p-1 hover:bg-blue-50 rounded"
|
||||
title="Voir les détails / Éditer"
|
||||
title="Modifier les données de rapprochement"
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
<Settings className="w-4 h-4" />
|
||||
</button>
|
||||
{/* Dévalider automatique - admin uniquement */}
|
||||
{user?.role === 'admin' && (
|
||||
|
||||
+7
-33
@@ -683,14 +683,16 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
// 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<Server> {
|
||||
// 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<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
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 {
|
||||
|
||||
Reference in new issue
Block a user