diff --git a/ECART-COLUMN-FEATURE.md b/ECART-COLUMN-FEATURE.md
new file mode 100644
index 0000000..bdd7124
--- /dev/null
+++ b/ECART-COLUMN-FEATURE.md
@@ -0,0 +1,154 @@
+# Ajout Colonne Écart - Module Rapprochement
+
+## 🎯 Demande Utilisateur
+
+Ajouter une colonne **"Écart"** dans le module rapprochement qui calcule la différence entre le montant BL et le montant Facture.
+
+## âś… Implementation
+
+### 1. **Structure des Tableaux**
+
+#### **Onglet Manuel**
+```
+| Fournisseur | N° BL | Date Livr. | Montant BL | Ref. Facture | Montant Fact. | **Écart** | Magasin | Actions |
+```
+
+#### **Onglet Automatique**
+```
+| Fournisseur | N° BL | Date Livr. | Date Valid. | Montant BL | Ref. Facture | Montant Fact. | **Écart** | Magasin | Actions |
+```
+
+### 2. **Logique de Calcul**
+
+```typescript
+const blAmount = delivery.blAmount ? parseFloat(delivery.blAmount) : 0;
+const invoiceAmount = delivery.invoiceAmount ? parseFloat(delivery.invoiceAmount) : 0;
+
+if (blAmount && invoiceAmount) {
+ const diff = blAmount - invoiceAmount;
+ // BL > Facture = +XX.XX€ (positif)
+ // BL < Facture = -XX.XX€ (négatif)
+ // BL = Facture = 0.00€ (équilibré)
+}
+```
+
+### 3. **Couleurs Indicatives**
+
+```css
+/* Aucun écart - Parfait */
+diff === 0 → text-green-600
+
+/* Écart faible (≤ 10€) - Attention */
+diffAbs ≤ 10 → text-orange-600
+
+/* Écart important (> 10€) - Problème */
+diffAbs > 10 → text-red-600
+```
+
+### 4. **Affichage par Cas**
+
+#### **Cas Complet** (BL + Facture renseignés)
+- `+15.50€` (BL supérieur de 15.50€)
+- `-8.25€` (Facture supérieure de 8.25€)
+- `0.00€` (Montants identiques)
+
+#### **Cas Incomplet** (données manquantes)
+- `-` (grisé, données insuffisantes)
+
+### 5. **Headers de Colonnes**
+
+```typescript
+// Manuel
+
Écart |
+
+// Automatique
+Écart |
+```
+
+## 🎨 Rendu Visuel
+
+### Exemples d'Affichage
+
+| Montant BL | Montant Fact. | Écart | Couleur |
+|------------|---------------|--------|---------|
+| 150.00€ | 150.00€ | `0.00€` | 🟢 Vert |
+| 155.50€ | 150.00€ | `+5.50€` | 🟠Orange |
+| 140.00€ | 165.75€ | `-25.75€` | 🔴 Rouge |
+| 100.00€ | - | `-` | ⚪ Gris |
+
+### États Visuels par Seuil
+
+```css
+/* Équilibré - Vert */
+.text-green-600 { color: #16a34a; }
+
+/* Écart modéré - Orange */
+.text-orange-600 { color: #ea580c; }
+
+/* Écart important - Rouge */
+.text-red-600 { color: #dc2626; }
+
+/* Non applicable - Gris */
+.text-gray-400 { color: #9ca3af; }
+```
+
+## đź”§ Code Implementation
+
+### Header (Manuel)
+```typescript
+
+ Écart
+ |
+```
+
+### Cellule Data
+```typescript
+
+ {(() => {
+ const blAmount = delivery.blAmount ? parseFloat(delivery.blAmount) : 0;
+ const invoiceAmount = delivery.invoiceAmount ? parseFloat(delivery.invoiceAmount) : 0;
+ if (blAmount && invoiceAmount) {
+ const diff = blAmount - invoiceAmount;
+ const diffAbs = Math.abs(diff);
+ return (
+ 10 ? 'text-red-600' : 'text-orange-600'
+ }`}>
+ {diff > 0 ? '+' : ''}{diff.toFixed(2)}€
+
+ );
+ }
+ return -;
+ })()}
+ |
+```
+
+## đź§Ş Tests de Validation
+
+### Test 1 : Calcul d'Écart
+1. BL: 100.00€, Facture: 95.00€
+2. **Vérifier** : Écart = `+5.00€` (orange)
+
+### Test 2 : Équilibre
+1. BL: 150.00€, Facture: 150.00€
+2. **Vérifier** : Écart = `0.00€` (vert)
+
+### Test 3 : Écart Important
+1. BL: 200.00€, Facture: 185.00€
+2. **Vérifier** : Écart = `+15.00€` (rouge)
+
+### Test 4 : Données Manquantes
+1. BL: 100.00€, Facture: non renseigné
+2. **Vérifier** : Écart = `-` (gris)
+
+## 📊 Status
+
+- ✅ Colonne Écart ajoutée sur onglet Manuel
+- ✅ Colonne Écart ajoutée sur onglet Automatique
+- âś… Calcul automatique (BL - Facture)
+- âś… Couleurs indicatives par seuil
+- ✅ Gestion des cas de données manquantes
+- ✅ Format d'affichage cohérent (+/-XX.XX€)
+
+**La colonne Écart permet maintenant de visualiser instantanément les différences entre BL et factures !**
\ No newline at end of file
diff --git a/RECONCILIATION-MODAL-FIX.md b/RECONCILIATION-MODAL-FIX.md
index cf0be6b..477ebf2 100644
--- a/RECONCILIATION-MODAL-FIX.md
+++ b/RECONCILIATION-MODAL-FIX.md
@@ -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
+
+
+// Après : Modifier seulement si non validé
+{!delivery.reconciled && (
+
+)}
```
-### 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
+
+
+ {admin && }
+
-### 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
+
+ {admin && delivery.reconciled && }
+ {admin && }
+ {!delivery.reconciled && }
+
```
-### 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
\ No newline at end of file
+### 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 !**
\ No newline at end of file
diff --git a/client/src/pages/BLReconciliation.tsx b/client/src/pages/BLReconciliation.tsx
index 6fd07f7..c2243a9 100644
--- a/client/src/pages/BLReconciliation.tsx
+++ b/client/src/pages/BLReconciliation.tsx
@@ -355,6 +355,9 @@ export default function BLReconciliation() {
Montant Fact.
|
+
+ Écart
+ |
Magasin
|
@@ -415,6 +418,25 @@ export default function BLReconciliation() {
}
+
+ {(() => {
+ const blAmount = delivery.blAmount ? parseFloat(delivery.blAmount) : 0;
+ const invoiceAmount = delivery.invoiceAmount ? parseFloat(delivery.invoiceAmount) : 0;
+ if (blAmount && invoiceAmount) {
+ const diff = blAmount - invoiceAmount;
+ const diffAbs = Math.abs(diff);
+ return (
+ 10 ? 'text-red-600' : 'text-orange-600'
+ }`}>
+ {diff > 0 ? '+' : ''}{diff.toFixed(2)}€
+
+ );
+ }
+ return -;
+ })()}
+ |
{delivery.group?.name}
@@ -468,14 +490,16 @@ export default function BLReconciliation() {
)}
>
)}
- {/* Bouton Modifier toujours disponible */}
-
+ {/* Bouton Modifier : disponible seulement si pas encore validé */}
+ {!delivery.reconciled && (
+
+ )}
|
@@ -544,6 +568,9 @@ export default function BLReconciliation() {
Montant Fact.
|
+
+ Écart
+ |
Magasin
|
@@ -611,6 +638,25 @@ export default function BLReconciliation() {
}
+
+ {(() => {
+ const blAmount = delivery.blAmount ? parseFloat(delivery.blAmount) : 0;
+ const invoiceAmount = delivery.invoiceAmount ? parseFloat(delivery.invoiceAmount) : 0;
+ if (blAmount && invoiceAmount) {
+ const diff = blAmount - invoiceAmount;
+ const diffAbs = Math.abs(diff);
+ return (
+ 10 ? 'text-red-600' : 'text-orange-600'
+ }`}>
+ {diff > 0 ? '+' : ''}{diff.toFixed(2)}€
+
+ );
+ }
+ return -;
+ })()}
+ |
{delivery.group?.name}
@@ -618,15 +664,7 @@ export default function BLReconciliation() {
|
-
- {/* Dévalider automatique - admin uniquement */}
- {user?.role === 'admin' && (
+ {user?.role === 'admin' && delivery.reconciled && (
)}
+ {user?.role === 'admin' && (
+
+ )}
+ {/* Bouton Modifier : disponible seulement si pas encore validé */}
+ {!delivery.reconciled && (
+
+ )}
|