Restrict editing of reconciled entries and add delete option for admins

Implement edit restrictions on reconciled reconciliation entries and introduce a delete button for administrator roles in the BL reconciliation interface.

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/9cpnZSe
This commit is contained in:
michaelschal committed 2025-08-12 11:56:49 +00:00
1 parent 5bef39e835
commit fd54c2a7a6
2 files changed
+123 -111

No files matched your search

+93 -94
View File
@@ -1,111 +1,110 @@
# Fix Complet - Modal de Rapprochement et Actions
# Fix Rapprochement - Restrictions Édition
## ✅ Problèmes Résolus
## 🎯 Demandes Utilisateur
### 1. **Validation impossible** ❌ → ✅
**Avant :** Bouton "Valider" sans vérification des données requises
**Après :**
- Validation conditionnelle : BL number requis
- Message d'erreur explicite : "Le numéro de BL est requis. Cliquez sur 'Voir les détails' pour le renseigner"
- Action rapide si données complètes, sinon redirection vers modal
1. **Les rapprochements validés ne peuvent plus être édités**
2. **Ajouter bouton supprimer pour les admins** (onglet automatique)
### 2. **Pas de modal d'édition** ❌ → ✅
**Avant :** Bouton "Voir les détails" ne faisait rien
**Après :**
- **Modal ReconciliationModal.tsx** complet avec :
- Édition BL : N° BL (requis) + Montant BL
- Édition Facture : Référence + Montant
- Actions : Enregistrer + Valider directement
- Distinction Manuel/Automatique avec badges
- Validation en temps réel
## ✅ Corrections Appliquées
### 3. **Dévalidation automatique** 🔄 → À tester
**Fonctionnalité :**
- Bouton dévalider visible pour admin uniquement
- Confirmation avant action
- API call vers `/api/deliveries/${id}` PUT
## 🎯 Nouvelles Fonctionnalités
### Modal de Rapprochement
### 1. **Onglet Manuel** - Édition Restreinte
```typescript
// Ouverture via bouton "Voir les détails"
const handleOpenModal = (delivery: any) => {
setSelectedDelivery(delivery);
setIsModalOpen(true);
};
// Avant : Bouton modifier toujours disponible
<button onClick={() => handleOpenModal(delivery)}>
<Settings className="w-4 h-4" />
</button>
// Après : Modifier seulement si non validé
{!delivery.reconciled && (
<button onClick={() => handleOpenModal(delivery)}>
<Settings className="w-4 h-4" />
</button>
)}
```
### Actions Intelligentes
- **Validation rapide** : Si BL number présent → validation directe
- **Validation guidée** : Si BL number manquant → ouverture modal
- **Édition complète** : Modal avec tous les champs BL/Facture
### 2. **Onglet Automatique** - Boutons Admin
```typescript
// Avant : Seulement modifier + dévalider
<div className="flex items-center space-x-2">
<button onClick={() => handleOpenModal(delivery)}>Modifier</button>
{admin && <button>Dévalider</button>}
</div>
### Interface Améliorée
- ✅ Boutons d'action fonctionnels avec tooltips
- ✅ Indicateurs visuels par statut
- ✅ Confirmations de sécurité (window.confirm)
- ✅ Messages d'erreur contextuels
## 📋 Tests à Effectuer en Production
### Test 1 : Modal d'Édition
- [ ] Cliquer sur icône "œil" (Eye) → Modal s'ouvre
- [ ] Remplir N° BL obligatoire
- [ ] Remplir montants optionnels
- [ ] Cliquer "Enregistrer" → Données sauvegardées
- [ ] Cliquer "Valider le rapprochement" → Rapprochement validé
### Test 2 : Validation Rapide
- [ ] Livraison avec BL number → Bouton vert "Valider" fonctionne
- [ ] Livraison sans BL number → Message "Données manquantes"
### Test 3 : Dévalidation Automatique
- [ ] Se connecter en tant qu'admin
- [ ] Onglet "Rapprochement Automatique"
- [ ] Cliquer bouton orange "Dévalider" → Confirmation puis action
### Test 4 : Permissions
- **Admin** : Tous boutons visibles (Valider, Supprimer, Dévalider)
- **Directeur** : Valider + Supprimer (pas dévalider)
- **Manager** : Accès refusé au module
- **Employee** : Accès refusé au module
## 🔧 Debug Dévalidation Automatique
Si la dévalidation ne fonctionne toujours pas :
### Vérifier API
```bash
# Test manuel API
curl -X PUT /api/deliveries/[ID] \
-H "Content-Type: application/json" \
-d '{"reconciled": false, "validatedAt": null}'
// Après : Supprimer + édition restreinte
<div className="flex items-center space-x-2">
{admin && delivery.reconciled && <button>Dévalider</button>}
{admin && <button>Supprimer</button>}
{!delivery.reconciled && <button>Modifier</button>}
</div>
```
### Vérifier Permissions
```javascript
// Dans console navigateur
console.log("User role:", user?.role);
console.log("Is admin:", user?.role === 'admin');
## 🔒 Logique des Boutons par État
### **Rapprochement Non Validé** (`delivery.reconciled = false`)
- ✅ **Modifier** : Disponible pour tous les rôles autorisés
- ✅ **Valider** : Disponible selon permissions
- ✅ **Supprimer** : Admin uniquement
### **Rapprochement Validé** (`delivery.reconciled = true`)
- ❌ **Modifier** : BLOQUÉ (plus d'édition possible)
- ✅ **Dévalider** : Admin uniquement
- ✅ **Supprimer** : Admin uniquement
## 🎨 Interface Utilisateur
### États Visuels
```css
/* Non validé */
bg-white (normal) ou bg-red-50 (problème)
/* Validé */
bg-gray-100 opacity-60 text-gray-500 (grisé)
```
### Vérifier Console Erreurs
- F12 → Console → Vérifier erreurs JavaScript
- Network → Vérifier requêtes API (200 vs 4xx/5xx)
### Boutons par Onglet
## 🚀 Déploiement
#### **Manuel**
- Non validé : `[Valider] [Supprimer] [Modifier]`
- Validé : `[Dévalider] [Supprimer]` (admin) ou `[]` (autres)
### Fichiers Modifiés
```
client/src/components/modals/ReconciliationModal.tsx # ✅ Nouveau
client/src/pages/BLReconciliation.tsx # ✅ Modifié
#### **Automatique**
- Non validé : `[Modifier]`
- Validé : `[Dévalider] [Supprimer]` (admin) ou `[]` (autres)
## 🔧 Imports Requis
```typescript
import { Trash2, Ban, Settings, Check } from 'lucide-react';
```
### Points de Contrôle
- ✅ Modal shadcn/ui Dialog (pas React.forwardRef problématique)
- ✅ Confirmations via window.confirm (évite erreurs React)
- ✅ Gestion d'état locale simple (useState)
- ✅ API calls via apiRequest (standardisé)
## 🧪 Tests de Validation
**Status :** ✅ Prêt pour déploiement et test production
### Test 1 : Édition Restreinte
1. Créer une livraison
2. **Vérifier** : Bouton modifier visible
3. Valider le rapprochement
4. **Vérifier** : Bouton modifier DISPARU
5. **Vérifier** : Ligne grisée
### Test 2 : Boutons Admin (Automatique)
1. Se connecter comme admin
2. Aller sur onglet "Automatique"
3. **Vérifier** : Bouton supprimer visible
4. **Vérifier** : Dévalider visible si validé
5. **Vérifier** : Modifier visible si non validé
### Test 3 : Permissions Non-Admin
1. Se connecter comme manager/directeur
2. **Vérifier** : Pas de bouton supprimer
3. **Vérifier** : Pas de bouton dévalider
4. **Vérifier** : Modifier visible si non validé
## 📊 Status
- ✅ Édition bloquée pour rapprochements validés
- ✅ Bouton supprimer ajouté pour admins (automatique)
- ✅ Logique cohérente entre onglets manuel/automatique
- ✅ Permissions respectées selon le rôle
- ✅ Interface claire avec grisage des validés
**Les rapprochements validés sont maintenant protégés contre l'édition !**
+30 -17
View File
@@ -468,14 +468,16 @@ export default function BLReconciliation() {
)}
</>
)}
{/* 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="Modifier les données de rapprochement"
>
<Settings className="w-4 h-4" />
</button>
{/* Bouton Modifier : disponible seulement si pas encore validé */}
{!delivery.reconciled && (
<button
onClick={() => handleOpenModal(delivery)}
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 p-1 hover:bg-blue-50 rounded"
title="Modifier les données de rapprochement"
>
<Settings className="w-4 h-4" />
</button>
)}
</div>
</td>
</tr>
@@ -618,15 +620,7 @@ export default function BLReconciliation() {
</td>
<td className="px-3 py-2 text-sm">
<div className="flex items-center space-x-2">
<button
onClick={() => handleOpenModal(delivery)}
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 p-1 hover:bg-blue-50 rounded"
title="Modifier les données de rapprochement"
>
<Settings className="w-4 h-4" />
</button>
{/* Dévalider automatique - admin uniquement */}
{user?.role === 'admin' && (
{user?.role === 'admin' && delivery.reconciled && (
<button
onClick={() => handleDevalidateAutoReconciliation(delivery.id)}
className="text-gray-600 hover:text-orange-600 transition-colors duration-200 p-1 hover:bg-orange-50 rounded"
@@ -635,6 +629,25 @@ export default function BLReconciliation() {
<Ban className="w-4 h-4" />
</button>
)}
{user?.role === 'admin' && (
<button
onClick={() => handleDeleteDelivery(delivery.id)}
className="text-gray-600 hover:text-red-600 transition-colors duration-200 p-1 hover:bg-red-50 rounded"
title="Supprimer la livraison"
>
<Trash2 className="w-4 h-4" />
</button>
)}
{/* Bouton Modifier : disponible seulement si pas encore validé */}
{!delivery.reconciled && (
<button
onClick={() => handleOpenModal(delivery)}
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 p-1 hover:bg-blue-50 rounded"
title="Modifier les données de rapprochement"
>
<Settings className="w-4 h-4" />
</button>
)}
</div>
</td>
</tr>