diff --git a/client/src/pages/BLReconciliation.tsx b/client/src/pages/BLReconciliation.tsx index f5b1570..1ee3c86 100644 --- a/client/src/pages/BLReconciliation.tsx +++ b/client/src/pages/BLReconciliation.tsx @@ -12,10 +12,11 @@ import { useStore } from "@/components/Layout"; import { useAuthUnified } from "@/hooks/useAuthUnified"; import { usePermissions } from "@shared/permissions"; import { Pagination, usePagination } from "@/components/ui/pagination"; -import { Search, Edit, FileText, Settings, Eye, AlertTriangle, X, Check, Trash2, Ban, Filter, Upload, CheckCircle, XCircle, Clock } from "lucide-react"; +import { Search, Edit, FileText, Settings, Eye, AlertTriangle, X, Check, Trash2, Ban, Filter, Upload, CheckCircle, XCircle, Clock, MessageSquare } from "lucide-react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; import ReconciliationModal from "@/components/modals/ReconciliationModal"; export default function BLReconciliation() { @@ -66,6 +67,11 @@ export default function BLReconciliation() { const [verificationResults, setVerificationResults] = useState>({}); const [verifyingDeliveries, setVerifyingDeliveries] = useState>(new Set()); + // État pour le modal de commentaire + const [showCommentModal, setShowCommentModal] = useState(false); + const [selectedDeliveryForComment, setSelectedDeliveryForComment] = useState(null); + const [commentText, setCommentText] = useState(""); + // Récupérer les fournisseurs pour la logique automatique const { data: suppliers = [] } = useQuery({ queryKey: ['/api/suppliers'], @@ -137,6 +143,42 @@ export default function BLReconciliation() { } }); + // Mutation pour mettre à jour les notes + const updateNoteMutation = useMutation({ + mutationFn: async ({ deliveryId, notes }: { deliveryId: number; notes: string }) => { + const response = await apiRequest(`/api/deliveries/${deliveryId}/notes`, 'PUT', { notes }); + return response; + }, + onSuccess: () => { + toast({ + title: "Commentaire sauvegardé", + description: "Le commentaire a été mis à jour avec succès", + }); + // Rafraîchir les données + queryClient.invalidateQueries({ queryKey: ['/api/deliveries/bl'] }); + queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); + handleCloseCommentModal(); + }, + onError: (error) => { + console.error('Erreur sauvegarde commentaire:', error); + toast({ + title: "Erreur", + description: "Impossible de sauvegarder le commentaire", + variant: "destructive", + }); + } + }); + + // Fonction pour sauvegarder le commentaire + const handleSaveComment = () => { + if (!selectedDeliveryForComment) return; + + updateNoteMutation.mutate({ + deliveryId: selectedDeliveryForComment.id, + notes: commentText + }); + }; + // Fonction pour déclencher la vérification const handleVerifyInvoice = (delivery: any, forceRefresh: boolean = false) => { // Accepter soit une référence de facture soit un numéro BL @@ -347,6 +389,19 @@ export default function BLReconciliation() { setShowInvoiceModal(true); }; + // Fonctions pour le modal de commentaire + const handleOpenCommentModal = (delivery: any) => { + setSelectedDeliveryForComment(delivery); + setCommentText(delivery.notes || ""); + setShowCommentModal(true); + }; + + const handleCloseCommentModal = () => { + setShowCommentModal(false); + setSelectedDeliveryForComment(null); + setCommentText(""); + }; + const handleCloseInvoiceModal = () => { setShowInvoiceModal(false); setSelectedDeliveryForInvoice(null); @@ -926,6 +981,15 @@ export default function BLReconciliation() { )} + {!delivery.reconciled ? ( <> {permissions.canValidate('reconciliation') && ( @@ -1129,6 +1193,17 @@ export default function BLReconciliation() { )} + {(permissions.canEdit('reconciliation') || permissions.canValidate('reconciliation')) && (