Upload files to "Gheeraert"

This commit is contained in:
2026-07-03 07:29:55 +02:00
parent b140307141
commit 560b30b2b9
4 changed files with 1322 additions and 0 deletions
@@ -0,0 +1,366 @@
{
"name": "Gheeraert workflow 5 — POD naar Transpas XML",
"nodes": [
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT\n id,\n order_log_id,\n gheeraert_order_id,\n purchase_order_number,\n status_id,\n tracking_date,\n tracking_comments,\n tracking_url,\n barcode,\n user_name,\n pod_downloaded,\n pod_file_name,\n pod_downloaded_at,\n transpas_export_status,\n transpas_export_error\nFROM public.ghe_status_log\nWHERE status_id = 35\n AND tracking_url IS NOT NULL\n AND COALESCE(pod_downloaded, false) = false\nORDER BY tracking_date, id\nLIMIT 50;",
"options": {}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
-2432,
-80
],
"id": "dde4054e-d2d2-4d79-be5d-ab1f772e23e7",
"name": "Get pending PODs",
"credentials": {
"postgres": {
"id": "pxziuCOuNpsUFKrm",
"name": "transpas_n8n_gheeraert"
}
}
},
{
"parameters": {
"url": "={{ $json.tracking_url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
-2192,
-80
],
"id": "a94882b8-2b42-4a17-ae8a-0f3df1196a0c",
"name": "Download POD",
"onError": "continueErrorOutput"
},
{
"parameters": {
"jsCode": "function safeFilePart(value) {\n return String(value || '')\n .replace(/[^a-zA-Z0-9._-]+/g, '_')\n .replace(/^_+|_+$/g, '')\n .slice(0, 80) || 'pod';\n}\n\nfunction nowStampFromInput(input) {\n const d = input ? new Date(input) : new Date();\n const dt = isNaN(d.getTime()) ? new Date() : d;\n const p = (n) => String(n).padStart(2, '0');\n return `${dt.getFullYear()}${p(dt.getMonth() + 1)}${p(dt.getDate())}_${p(dt.getHours())}${p(dt.getMinutes())}${p(dt.getSeconds())}`;\n}\n\nfunction xmlEsc(value) {\n return String(value ?? '')\n .replace(/&(?!amp;|lt;|gt;|quot;|apos;|#\\d+;|#x[0-9A-Fa-f]+;)/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\nfunction formatATDateTime(input) {\n if (!input) return '';\n const d = new Date(input);\n if (isNaN(d.getTime())) return '';\n const pad = (n) => String(n).padStart(2, '0');\n return (\n d.getFullYear() +\n pad(d.getMonth() + 1) +\n pad(d.getDate()) +\n pad(d.getHours()) +\n pad(d.getMinutes()) +\n pad(d.getSeconds())\n );\n}\n\nconst j = $json;\nif (!j.tracking_url) {\n throw new Error('tracking_url ontbreekt');\n}\nif (!$binary?.data) {\n throw new Error('Geen binary data gevonden in HTTP download');\n}\n\nlet ext = 'bin';\nlet baseName = '';\ntry {\n const u = new URL(j.tracking_url);\n const pathname = u.pathname || '';\n const parts = pathname.split('/').filter(Boolean);\n baseName = parts.length ? parts[parts.length - 1] : '';\n const m = pathname.match(/\\.([A-Za-z0-9]+)$/);\n if (m) ext = m[1].toLowerCase();\n} catch (e) {}\n\nconst podFileName = `GHE_POD_${safeFilePart(j.purchase_order_number)}_${nowStampFromInput(j.tracking_date)}.${ext}`;\nconst transpasXmlFile = `GHE_POD_XML_${safeFilePart(j.purchase_order_number)}_${nowStampFromInput(j.tracking_date)}.xml`;\nconst atDateTime = formatATDateTime(j.tracking_date) || formatATDateTime(new Date().toISOString());\n\nconst binary = $binary.data;\nbinary.fileName = podFileName;\nbinary.mimeType = binary.mimeType || 'application/octet-stream';\nconst base64Data = binary.data;\n\nconst originalName = baseName || podFileName;\nconst fileType = ext || 'bin';\nconst note = [\n 'POD Online',\n j.tracking_comments || '',\n j.tracking_url ? `URL: ${j.tracking_url}` : '',\n].filter(Boolean).join(' - ');\n\nconst transpasXml = [\n '<?xml version=\"1.0\" encoding=\"utf-8\"?>',\n '<xmlStat>',\n ` <dateTime type=\"AT\">${xmlEsc(atDateTime)}</dateTime>`,\n ' <codeList>TLN</codeList>',\n ' <consignmentStat>',\n ` <id type=\"NOC\" datatype=\"varchar(50)\">${xmlEsc(j.purchase_order_number)}</id>`,\n ' <status>35</status>',\n ` <note>${xmlEsc(note)}</note>`,\n ` <signature type=\"CMR\" filetype=\"${xmlEsc(fileType)}\">${base64Data}</signature>`,\n ` <name>${xmlEsc(originalName)}</name>`,\n ' </consignmentStat>',\n '</xmlStat>'\n].join('\\n');\n\nreturn {\n json: {\n ...j,\n pod_file_name: podFileName,\n transpas_xml: transpasXml,\n transpas_xml_file: transpasXmlFile,\n },\n binary: {\n data: binary,\n },\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1952,
-80
],
"id": "bc443c37-8620-4c4a-a37d-7c2632a30827",
"name": "Build POD Transpas XML"
},
{
"parameters": {
"jsCode": "const xml = $json.transpas_xml;\nconst fileName = $json.transpas_xml_file || 'pod_status.xml';\n\nconst binaryData = await this.helpers.prepareBinaryData(\n Buffer.from(xml, 'utf8'),\n fileName,\n 'application/xml'\n);\n\nreturn {\n json: {\n ...$json,\n },\n binary: {\n data: binaryData,\n },\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1712,
-80
],
"id": "6c04eb86-5476-473a-a911-ced8dac43c69",
"name": "Create POD XML Binary"
},
{
"parameters": {
"protocol": "sftp",
"operation": "upload",
"path": "=/dewit/pod_xml/{{ $json.transpas_xml_file }}",
"options": {}
},
"type": "n8n-nodes-base.ftp",
"typeVersion": 1,
"position": [
-1472,
-80
],
"id": "c5300449-3418-4f22-99e0-f017dc3e167d",
"name": "SFTP Upload POD XML",
"credentials": {
"sftp": {
"id": "uKyzg5cSXQqXOuHI",
"name": "SFTP n8n"
}
},
"onError": "continueErrorOutput"
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE public.ghe_status_log\nSET\n pod_downloaded = true,\n pod_file_name = $1::varchar,\n pod_downloaded_at = CURRENT_TIMESTAMP,\n transpas_xml_file = $2::varchar,\n transpas_xml_created_at = CURRENT_TIMESTAMP,\n transpas_export_status = 'exported',\n transpas_export_error = NULL\nWHERE id = $3::bigint;",
"options": {
"queryReplacement": "={{ [$json.pod_file_name, $json.transpas_xml_file, $json.id] }}"
}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
-1232,
-144
],
"id": "117c6ad2-aa7c-41aa-ae45-bf840867fd3b",
"name": "Mark POD Exported",
"credentials": {
"postgres": {
"id": "pxziuCOuNpsUFKrm",
"name": "transpas_n8n_gheeraert"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE public.ghe_order_log\nSET\n pod_downloaded_at = CURRENT_TIMESTAMP,\n next_status_poll_at = CURRENT_TIMESTAMP + INTERVAL '1 day'\nWHERE id = $1::bigint;",
"options": {
"queryReplacement": "={{ [$json.order_log_id] }}"
}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
-992,
-144
],
"id": "1e1a3c7e-189d-4cb0-89c3-a200409c936d",
"name": "Update ghe_order_log POD",
"credentials": {
"postgres": {
"id": "pxziuCOuNpsUFKrm",
"name": "transpas_n8n_gheeraert"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "WITH input AS (\n SELECT $1::jsonb AS j\n)\nUPDATE public.ghe_status_log\nSET\n transpas_export_status = 'error',\n transpas_export_error = COALESCE(NULLIF(transpas_export_error, ''), '') || CASE WHEN COALESCE(NULLIF(transpas_export_error, ''), '') = '' THEN '' ELSE ' | ' END || (j->>'error_text')::text\nFROM input\nWHERE public.ghe_status_log.id = (j->>'id')::bigint;",
"options": {
"queryReplacement": "={{ [JSON.stringify({ id: $json.id, error_text: $json.error_text || 'POD download/upload/XML verwerking mislukt' })] }}"
}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
-1472,
80
],
"id": "0a50219a-8844-49fc-89d1-a60cb38d07c3",
"name": "Log POD Error",
"credentials": {
"postgres": {
"id": "pxziuCOuNpsUFKrm",
"name": "transpas_n8n_gheeraert"
}
}
},
{
"parameters": {
"jsCode": "const err = $json.error || {};\nconst message = err.message || $json.message || 'POD download/upload/XML verwerking mislukt';\nreturn { json: { ...$json, error_text: message } };"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1952,
80
],
"id": "6aad54d4-797f-4713-83f2-1f61d1600a7b",
"name": "Prepare POD Error"
},
{
"parameters": {
"jsCode": "const err = $json.error || {};\nconst message = err.message || $json.message || 'SFTP upload POD XML mislukt';\nreturn { json: { ...$json, error_text: message } };"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1232,
80
],
"id": "895e1542-95c2-40a6-9101-295480730af2",
"name": "Prepare SFTP Error"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "*/20 6-22 * * 1-5"
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-2640,
-80
],
"id": "1917c911-de8d-4c6b-8d71-cd0884573a08",
"name": "Schedule Trigger"
},
{
"parameters": {
"protocol": "sftp",
"operation": "list",
"options": {}
},
"type": "n8n-nodes-base.ftp",
"typeVersion": 1,
"position": [
-992,
64
],
"id": "8f75c195-722e-4e8c-83ad-19d329cda22e",
"name": "FTP",
"credentials": {
"sftp": {
"id": "uKyzg5cSXQqXOuHI",
"name": "SFTP n8n"
}
}
}
],
"pinData": {},
"connections": {
"Get pending PODs": {
"main": [
[
{
"node": "Download POD",
"type": "main",
"index": 0
}
]
]
},
"Download POD": {
"main": [
[
{
"node": "Build POD Transpas XML",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare POD Error",
"type": "main",
"index": 0
}
]
]
},
"Prepare POD Error": {
"main": [
[
{
"node": "Log POD Error",
"type": "main",
"index": 0
}
]
]
},
"Build POD Transpas XML": {
"main": [
[
{
"node": "Create POD XML Binary",
"type": "main",
"index": 0
}
]
]
},
"Create POD XML Binary": {
"main": [
[
{
"node": "SFTP Upload POD XML",
"type": "main",
"index": 0
}
]
]
},
"SFTP Upload POD XML": {
"main": [
[
{
"node": "Mark POD Exported",
"type": "main",
"index": 0
},
{
"node": "FTP",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare SFTP Error",
"type": "main",
"index": 0
}
]
]
},
"Prepare SFTP Error": {
"main": [
[
{
"node": "Log POD Error",
"type": "main",
"index": 0
}
]
]
},
"Mark POD Exported": {
"main": [
[
{
"node": "Update ghe_order_log POD",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get pending PODs",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"versionId": "1761ac71-29de-4791-880a-4d790f991107",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
},
"nodeGroups": [],
"id": "CsLGuXIeZQszqTPz",
"tags": []
}