mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Merge pull request #521 from R0m1k3/1.1
Improve invoice sending by proxying through backend
This commit is contained in:
6 files changed
+357
-50
No files matched your search
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
|
||||
storeId: 2,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-24T11:26:13.521Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 17,
|
||||
|
||||
title: 'Module Avoir',
|
||||
|
||||
content: "Le module d'avoir est en place",
|
||||
|
||||
type: 'error',
|
||||
|
||||
storeId: 1,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-09T07:47:47.650Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 16,
|
||||
|
||||
title: 'Mise à jour Prix',
|
||||
|
||||
content: 'Merci de mettre vos prix a jour tous les matins, certain magasin ne le font pas.',
|
||||
|
||||
type: 'success',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-08-18T10:45:08.585Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 8,
|
||||
|
||||
title: 'Bon de Livraison',
|
||||
|
||||
content: 'Lorsque vous rentrez un numéro de bon de livraison, faite le a l identique, même les majuscules. Pour My candy Shop, prendre le numéro de commande.',
|
||||
|
||||
type: 'info',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin_local',
|
||||
|
||||
createdAt: 2025-08-07T11:04:38.123Z
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin_local
|
||||
|
||||
❌ [PRODUCTION] User not found with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Not found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🎯 [PRODUCTION] Found announcements: 4
|
||||
|
||||
GET /api/announcements 304 in 8ms
|
||||
|
||||
📢 [SERVER] Fetching announcements for user: _1754936203292 environment: production
|
||||
|
||||
📢 [SERVER] User found: { username: 'ff292', role: 'employee' }
|
||||
|
||||
🎯 [PRODUCTION] Using PostgreSQL DASHBOARD_MESSAGES table
|
||||
|
||||
🔍 [PRODUCTION] Raw messages from DB: 4 items: [
|
||||
|
||||
{
|
||||
|
||||
id: 20,
|
||||
|
||||
title: 'DLC',
|
||||
|
||||
content: 'Attention des DLC sont en expiré bientôt ou expiré, il faut s en occuper',
|
||||
|
||||
type: 'success',
|
||||
|
||||
storeId: 2,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-24T11:26:13.521Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 17,
|
||||
|
||||
title: 'Module Avoir',
|
||||
|
||||
content: "Le module d'avoir est en place",
|
||||
|
||||
type: 'error',
|
||||
|
||||
storeId: 1,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-09T07:47:47.650Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 16,
|
||||
|
||||
title: 'Mise à jour Prix',
|
||||
|
||||
content: 'Merci de mettre vos prix a jour tous les matins, certain magasin ne le font pas.',
|
||||
|
||||
type: 'success',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-08-18T10:45:08.585Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 8,
|
||||
|
||||
title: 'Bon de Livraison',
|
||||
|
||||
content: 'Lorsque vous rentrez un numéro de bon de livraison, faite le a l identique, même les majuscules. Pour My candy Shop, prendre le numéro de commande.',
|
||||
|
||||
type: 'info',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin_local',
|
||||
|
||||
createdAt: 2025-08-07T11:04:38.123Z
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
❌ [PRODUCTION] User not found with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Not found
|
||||
|
||||
🎯 [PRODUCTION] Found announcements: 4
|
||||
|
||||
GET /api/announcements 304 in 9ms
|
||||
|
||||
GET /api/groups 304 in 3ms
|
||||
|
||||
GET /api/user 304 in 5ms
|
||||
|
||||
GET /api/suppliers 304 in 4ms
|
||||
|
||||
GET /api/dlc-products 304 in 45ms
|
||||
|
||||
HEAD /api/health 200 in 0ms
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
@@ -515,26 +515,25 @@ export default function BLReconciliation() {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', selectedFile);
|
||||
formData.append('webhookUrl', selectedDeliveryForInvoice.group.webhookUrl);
|
||||
formData.append('supplier', selectedDeliveryForInvoice.supplier?.name || '');
|
||||
formData.append('blNumber', selectedDeliveryForInvoice.blNumber || '');
|
||||
formData.append('type', 'Facture');
|
||||
|
||||
// Créer un AbortController pour gérer le timeout
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 secondes
|
||||
|
||||
const response = await fetch(selectedDeliveryForInvoice.group.webhookUrl, {
|
||||
// Envoyer via notre route backend proxy (évite problèmes CORS et erreurs webhook)
|
||||
const response = await fetch('/api/reconciliation/send-invoice', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
signal: controller.signal,
|
||||
credentials: 'include' // Important pour l'authentification
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur ${response.status}: ${response.statusText}`);
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || `Erreur ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
handleCloseWaitingModal();
|
||||
|
||||
toast({
|
||||
|
||||
Generated
+119
-11
@@ -43,6 +43,7 @@
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/memoizee": "^0.4.12",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/node-fetch": "^2.6.13",
|
||||
"@types/pg": "^8.15.4",
|
||||
"bcrypt": "^6.0.0",
|
||||
@@ -67,6 +68,7 @@
|
||||
"lucide-react": "^0.453.0",
|
||||
"memoizee": "^0.4.17",
|
||||
"memorystore": "^1.6.7",
|
||||
"multer": "^2.0.2",
|
||||
"nanoid": "^5.1.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"node-cron": "^4.2.1",
|
||||
@@ -3617,7 +3619,6 @@
|
||||
"version": "1.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
|
||||
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
@@ -3628,7 +3629,6 @@
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
@@ -3720,7 +3720,6 @@
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
@@ -3733,7 +3732,6 @@
|
||||
"version": "4.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
@@ -3765,7 +3763,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
|
||||
"integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/memoizee": {
|
||||
@@ -3778,9 +3775,17 @@
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/multer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.0.0.tgz",
|
||||
"integrity": "sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.16.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz",
|
||||
@@ -3855,14 +3860,12 @@
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
@@ -3890,7 +3893,6 @@
|
||||
"version": "0.17.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
|
||||
"integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
@@ -3901,7 +3903,6 @@
|
||||
"version": "1.15.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
|
||||
"integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
@@ -4005,6 +4006,12 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/append-field": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
@@ -4214,7 +4221,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bufferutil": {
|
||||
@@ -4231,6 +4237,17 @@
|
||||
"node": ">=6.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"dependencies": {
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@@ -4442,6 +4459,21 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/connect-pg-simple": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/connect-pg-simple/-/connect-pg-simple-10.0.0.tgz",
|
||||
@@ -6978,6 +7010,15 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
@@ -7050,6 +7091,36 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
|
||||
"integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^1.6.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"mkdirp": "^0.5.6",
|
||||
"object-assign": "^4.1.1",
|
||||
"type-is": "^1.6.18",
|
||||
"xtend": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/multer/node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
@@ -8045,6 +8116,20 @@
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -8493,6 +8578,23 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
@@ -8860,6 +8962,12 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/memoizee": "^0.4.12",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/node-fetch": "^2.6.13",
|
||||
"@types/pg": "^8.15.4",
|
||||
"bcrypt": "^6.0.0",
|
||||
@@ -69,6 +70,7 @@
|
||||
"lucide-react": "^0.453.0",
|
||||
"memoizee": "^0.4.17",
|
||||
"memorystore": "^1.6.7",
|
||||
"multer": "^2.0.2",
|
||||
"nanoid": "^5.1.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"node-cron": "^4.2.1",
|
||||
|
||||
+26
-30
@@ -128,6 +128,7 @@ import { invoiceVerificationService } from "./invoiceVerification";
|
||||
import { backupService } from "./backupService";
|
||||
import { weatherService } from "./weatherService.js";
|
||||
import fetch from "node-fetch";
|
||||
import multer from "multer";
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Detect environment
|
||||
@@ -788,8 +789,11 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Configuration multer pour upload en mémoire
|
||||
const upload = multer({ storage: multer.memoryStorage() });
|
||||
|
||||
// Route proxy pour envoi de factures vers webhook (accessible admin + directeur)
|
||||
app.post('/api/reconciliation/send-invoice-webhook', isAuthenticated, async (req: any, res) => {
|
||||
app.post('/api/reconciliation/send-invoice', isAuthenticated, upload.single('file'), async (req: any, res) => {
|
||||
try {
|
||||
const userId = req.user?.claims?.sub || req.user?.id;
|
||||
if (!userId) {
|
||||
@@ -806,45 +810,40 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(403).json({ error: 'Accès refusé - Admin ou Directeur uniquement' });
|
||||
}
|
||||
|
||||
const { webhookUrl, formDataFields } = req.body;
|
||||
|
||||
if (!webhookUrl || !formDataFields) {
|
||||
return res.status(400).json({ error: 'Données manquantes: webhookUrl ou formDataFields' });
|
||||
if (!req.file || !req.body.webhookUrl) {
|
||||
return res.status(400).json({ error: 'Fichier ou URL webhook manquant' });
|
||||
}
|
||||
|
||||
const { webhookUrl, supplier, blNumber, type } = req.body;
|
||||
|
||||
console.log('📤 INVOICE: Envoi facture via webhook', {
|
||||
webhookUrl: webhookUrl.substring(0, 50) + '...',
|
||||
userId: user.id,
|
||||
userRole: user.role,
|
||||
fieldsCount: Object.keys(formDataFields).length
|
||||
fileName: req.file.originalname,
|
||||
fileSize: req.file.size
|
||||
});
|
||||
|
||||
// Utiliser le FormData natif de Node.js (disponible depuis Node 18+)
|
||||
const { FormData, File, Blob } = await import('node:buffer');
|
||||
// Importer form-data dynamiquement pour ESM
|
||||
const FormDataLib = await eval('import("form-data")');
|
||||
const FormData = FormDataLib.default;
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
// Ajouter tous les champs du formData
|
||||
for (const [key, value] of Object.entries(formDataFields)) {
|
||||
if (key === 'file' && typeof value === 'object' && (value as any).base64) {
|
||||
// Reconstituer le fichier depuis base64
|
||||
const fileData = value as { base64: string; filename: string; contentType: string };
|
||||
const buffer = Buffer.from(fileData.base64, 'base64');
|
||||
|
||||
// Créer un Blob/File natif Node.js
|
||||
const blob = new Blob([buffer], { type: fileData.contentType });
|
||||
const file = new File([blob], fileData.filename, { type: fileData.contentType });
|
||||
formData.append('file', file);
|
||||
} else {
|
||||
formData.append(key, value as string);
|
||||
}
|
||||
}
|
||||
formData.append('file', req.file.buffer, {
|
||||
filename: req.file.originalname,
|
||||
contentType: req.file.mimetype
|
||||
});
|
||||
formData.append('supplier', supplier || '');
|
||||
formData.append('blNumber', blNumber || '');
|
||||
formData.append('type', type || 'Facture');
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 secondes
|
||||
const timeoutId = setTimeout(() => controller.abort(), 60000);
|
||||
|
||||
const response = await fetch(webhookUrl, {
|
||||
method: 'POST',
|
||||
body: formData as any,
|
||||
headers: formData.getHeaders(),
|
||||
signal: controller.signal
|
||||
});
|
||||
|
||||
@@ -853,7 +852,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ INVOICE: Erreur webhook', { status: response.status, errorText: errorText.substring(0, 200) });
|
||||
throw new Error(`Erreur webhook: ${response.status} ${response.statusText}`);
|
||||
return res.status(500).json({ error: `Erreur webhook: ${response.status}`, details: errorText });
|
||||
}
|
||||
|
||||
const result = await response.text();
|
||||
@@ -866,10 +865,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('❌ INVOICE: Erreur envoi facture:', {
|
||||
name: error.name,
|
||||
message: error.message
|
||||
});
|
||||
console.error('❌ INVOICE: Erreur envoi facture:', error);
|
||||
|
||||
let errorMessage = 'Erreur lors de l\'envoi de la facture';
|
||||
if (error.name === 'AbortError') {
|
||||
|
||||
Reference in new issue
Block a user