mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Improve invoice sending by proxying requests through the backend
Introduces a new backend API endpoint to proxy invoice sending requests, resolving CORS issues and enhancing error handling. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 1e4433b5-47ab-464c-b663-fea2e53367dd Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: df58cf24-9a7e-4197-bdbe-786d56d0c35e Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/1e4433b5-47ab-464c-b663-fea2e53367dd/qOJ89TE
This commit is contained in:
1 parent
e3785d4457
commit
ca576dc289
3 files changed
+87
-9
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
@@ -515,24 +515,21 @@ export default function BLReconciliation() {
|
|||||||
try {
|
try {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', selectedFile);
|
formData.append('file', selectedFile);
|
||||||
|
formData.append('webhookUrl', selectedDeliveryForInvoice.group.webhookUrl);
|
||||||
formData.append('supplier', selectedDeliveryForInvoice.supplier?.name || '');
|
formData.append('supplier', selectedDeliveryForInvoice.supplier?.name || '');
|
||||||
formData.append('blNumber', selectedDeliveryForInvoice.blNumber || '');
|
formData.append('blNumber', selectedDeliveryForInvoice.blNumber || '');
|
||||||
formData.append('type', 'Facture');
|
formData.append('type', 'Facture');
|
||||||
|
|
||||||
// Créer un AbortController pour gérer le timeout
|
// Envoyer via route backend proxy (résout problèmes CORS)
|
||||||
const controller = new AbortController();
|
const response = await fetch('/api/reconciliation/send-invoice', {
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 secondes
|
|
||||||
|
|
||||||
const response = await fetch(selectedDeliveryForInvoice.group.webhookUrl, {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData,
|
body: formData,
|
||||||
signal: controller.signal,
|
credentials: 'include'
|
||||||
});
|
});
|
||||||
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Erreur ${response.status}: ${response.statusText}`);
|
const errorData = await response.json().catch(() => ({ error: 'Erreur inconnue' }));
|
||||||
|
throw new Error(errorData.error || `Erreur ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCloseWaitingModal();
|
handleCloseWaitingModal();
|
||||||
|
|||||||
@@ -788,6 +788,87 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Route proxy SIMPLE pour envoi de factures (admin + directeur)
|
||||||
|
app.post('/api/reconciliation/send-invoice', isAuthenticated, async (req: any, res) => {
|
||||||
|
try {
|
||||||
|
const userId = req.user?.claims?.sub || req.user?.id;
|
||||||
|
if (!userId) {
|
||||||
|
return res.status(401).json({ error: 'Non authentifié' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await storage.getUserWithGroups(userId);
|
||||||
|
if (!user || (user.role !== 'admin' && user.role !== 'directeur')) {
|
||||||
|
return res.status(403).json({ error: 'Accès refusé' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utiliser busboy pour parser le multipart/form-data
|
||||||
|
const busboy = Busboy({ headers: req.headers });
|
||||||
|
const fields: any = {};
|
||||||
|
let fileBuffer: Buffer | null = null;
|
||||||
|
let fileName = '';
|
||||||
|
let mimeType = '';
|
||||||
|
|
||||||
|
busboy.on('file', (fieldname, file, info) => {
|
||||||
|
const chunks: Buffer[] = [];
|
||||||
|
fileName = info.filename;
|
||||||
|
mimeType = info.mimeType;
|
||||||
|
|
||||||
|
file.on('data', (chunk) => chunks.push(chunk));
|
||||||
|
file.on('end', () => {
|
||||||
|
fileBuffer = Buffer.concat(chunks);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
busboy.on('field', (fieldname, value) => {
|
||||||
|
fields[fieldname] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
busboy.on('finish', resolve);
|
||||||
|
busboy.on('error', reject);
|
||||||
|
req.pipe(busboy);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!fileBuffer || !fields.webhookUrl) {
|
||||||
|
return res.status(400).json({ error: 'Fichier ou webhook manquant' });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('📤 INVOICE PROXY: Envoi facture', {
|
||||||
|
userId: user.id,
|
||||||
|
role: user.role,
|
||||||
|
fileName,
|
||||||
|
size: fileBuffer.length
|
||||||
|
});
|
||||||
|
|
||||||
|
// Importer form-data dynamiquement avec eval pour ESM
|
||||||
|
const FormDataModule = await eval('import("form-data")');
|
||||||
|
const FormData = FormDataModule.default;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', fileBuffer, { filename: fileName, contentType: mimeType });
|
||||||
|
formData.append('supplier', fields.supplier || '');
|
||||||
|
formData.append('blNumber', fields.blNumber || '');
|
||||||
|
formData.append('type', fields.type || 'Facture');
|
||||||
|
|
||||||
|
const response = await fetch(fields.webhookUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData as any,
|
||||||
|
headers: formData.getHeaders()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('❌ INVOICE PROXY: Webhook error', response.status);
|
||||||
|
return res.status(500).json({ error: `Webhook error: ${response.status}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ INVOICE PROXY: Success');
|
||||||
|
res.json({ success: true, message: 'Facture envoyée' });
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('❌ INVOICE PROXY: Error', error);
|
||||||
|
res.status(500).json({ error: error.message || 'Erreur serveur' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Auth routes handled by authSwitch (local or Replit)
|
// Auth routes handled by authSwitch (local or Replit)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user