mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-12 01:37:40 +02:00
Send credit note details via webhook when status changes to received
Implement webhook functionality to send credit note information to configured groups when the status is updated to 'Reçu'. The webhook payload includes credit note details, sender information, and group details. Default group ID is set to 1 for administrators if not specified. Also, adds a visual indicator for sent webhooks on the frontend. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9fcf4b21-eb0c-4e53-a567-e2ce4a6ad869 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/9fcf4b21-eb0c-4e53-a567-e2ce4a6ad869/liv4dfe
This commit is contained in:
1 parent
208b07b4dd
commit
986c8e6ce0
2 files changed
+54
-4
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { Plus, Search, FileText, CheckCircle, AlertCircle, Clock, Edit, Trash2, UserCheck } from "lucide-react";
|
||||
import { Plus, Search, FileText, CheckCircle, AlertCircle, Clock, Edit, Trash2, UserCheck, Send } from "lucide-react";
|
||||
import { useStore } from "@/components/Layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -159,7 +159,7 @@ export default function Avoirs() {
|
||||
// ✅ FIX: Invalider toutes les variations de queryKey avoirs
|
||||
queryClient.invalidateQueries({
|
||||
predicate: (query) => {
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs');
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs') || false;
|
||||
}
|
||||
});
|
||||
setIsCreateDialogOpen(false);
|
||||
@@ -197,7 +197,7 @@ export default function Avoirs() {
|
||||
// ✅ FIX: Invalider toutes les variations de queryKey avoirs
|
||||
queryClient.invalidateQueries({
|
||||
predicate: (query) => {
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs');
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs') || false;
|
||||
}
|
||||
});
|
||||
setIsEditDialogOpen(false);
|
||||
@@ -232,7 +232,7 @@ export default function Avoirs() {
|
||||
// ✅ FIX: Invalider toutes les variations de queryKey avoirs
|
||||
queryClient.invalidateQueries({
|
||||
predicate: (query) => {
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs');
|
||||
return query.queryKey[0]?.toString().includes('/api/avoirs') || false;
|
||||
}
|
||||
});
|
||||
setIsDeleteDialogOpen(false);
|
||||
@@ -660,6 +660,11 @@ export default function Avoirs() {
|
||||
<UserCheck className="h-4 w-4 text-blue-600 ml-2" />
|
||||
</div>
|
||||
)}
|
||||
{avoir.webhookSent && (
|
||||
<div title="Webhook envoyé">
|
||||
<Send className="h-4 w-4 text-green-600 ml-2" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
|
||||
@@ -2508,6 +2508,51 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
const updatedAvoir = await storage.updateAvoir(id, validatedData);
|
||||
console.log('✅ Avoir updated:', id, 'by user:', user.id);
|
||||
|
||||
// 🎯 WEBHOOK QUAND STATUT PASSE À "Reçu"
|
||||
if (validatedData.status === 'Reçu' && existingAvoir.status !== 'Reçu') {
|
||||
try {
|
||||
// Utiliser groupe par défaut (1) pour admin si pas de groupe sélectionné
|
||||
const groupId = updatedAvoir.groupId || (user.role === 'admin' ? 1 : updatedAvoir.groupId);
|
||||
const group = await storage.getGroup(groupId);
|
||||
|
||||
if (group && group.webhookUrl) {
|
||||
const webhookData = {
|
||||
type: "Avoir",
|
||||
avoirId: updatedAvoir.id,
|
||||
invoiceReference: updatedAvoir.invoiceReference,
|
||||
amount: updatedAvoir.amount,
|
||||
supplierName: "Fournisseur", // Sera enrichi avec relations
|
||||
groupName: group.name,
|
||||
comment: updatedAvoir.comment || "",
|
||||
commercialProcessed: updatedAvoir.commercialProcessed,
|
||||
status: "Reçu",
|
||||
createdBy: user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : user.username,
|
||||
processedAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
console.log('🌐 Envoi webhook avoir reçu:', { groupId, webhookUrl: group.webhookUrl });
|
||||
|
||||
const webhookResponse = await fetch(group.webhookUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(webhookData)
|
||||
});
|
||||
|
||||
if (webhookResponse.ok) {
|
||||
await storage.updateAvoirWebhookStatus(updatedAvoir.id, true);
|
||||
console.log('✅ Webhook avoir reçu envoyé:', updatedAvoir.id);
|
||||
} else {
|
||||
console.error('❌ Échec envoi webhook avoir:', webhookResponse.status);
|
||||
}
|
||||
}
|
||||
} catch (webhookError) {
|
||||
console.error('❌ Erreur webhook avoir reçu:', webhookError);
|
||||
}
|
||||
}
|
||||
|
||||
res.json(updatedAvoir);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
|
||||
Reference in new issue
Block a user