Upload files to "palletways"
This commit is contained in:
1 parent
560b30b2b9
commit
7cefa3d7e0
3 files changed
+1173
No files matched your search
@@ -0,0 +1,643 @@
|
||||
{
|
||||
"name": "Palletways leveringen - outbound",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Get today's date\nconst today = new Date();\n\n\nconst lastWorkday = new Date(today);\n\n// Format as YYYY-MM-DD\nconst yyyy = lastWorkday.getFullYear();\nconst mm = String(lastWorkday.getMonth() + 1).padStart(2, '0');\nconst dd = String(lastWorkday.getDate()).padStart(2, '0');\nconst formattedDate = `${yyyy}-${mm}-${dd}`;\n\nreturn [\n {\n json: {\n lastWorkday: formattedDate\n }\n }\n];"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
0,
|
||||
176
|
||||
],
|
||||
"id": "79604baf-6a53-4f92-8d60-6a9517c89753",
|
||||
"name": "Last workday1"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "/**\n * n8n “Function” node\n * Input : first item’s json.data (XML string)\n * Output: one item per unique <dc_syscon>, shaped as { json: { dc_syscon: \"<value>\" } }\n */\n\n// 1️⃣ Grab the XML from the first incoming item\nconst xmlData = items[0]?.json?.data;\nif (typeof xmlData !== 'string') {\n\tthrow new Error('Expected an XML string in $input.first().json.data');\n}\n\n// 2️⃣ Collect every <dc_syscon>...</dc_syscon> match\nconst dcSysconValues = [];\nconst regex = /<TrackingID>(.*?)<\\/TrackingID>/g;\nlet match;\nwhile ((match = regex.exec(xmlData)) !== null) {\n\tdcSysconValues.push(match[1].trim().toUpperCase());\n}\n\n// 3️⃣ De‑duplicate\nconst uniqueValues = [...new Set(dcSysconValues)];\n\n// 4️⃣ Build one output item per unique value\nreturn uniqueValues.map(value => ({\n\tjson: { trackingid: value },\n}));\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
448,
|
||||
176
|
||||
],
|
||||
"id": "86570f68-7269-41fe-b468-af52f4d16b02",
|
||||
"name": "Code"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "=https://api.palletways.com/lookupDepotNo/{{ $json.Response.Detail.Data.Manifest.Depot.Number }}?apikey=SXJaM7PLjZDqfsnXSDP8Y9wDY6crxJySBg705MQEPus%3D",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"responseFormat": "text"
|
||||
}
|
||||
},
|
||||
"timeout": 10000
|
||||
}
|
||||
},
|
||||
"id": "814a05a5-b8c8-4a26-bfed-7a5744e33851",
|
||||
"name": "Get Paying Depot Address",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [
|
||||
1360,
|
||||
48
|
||||
],
|
||||
"continueOnFail": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {
|
||||
"explicitArray": false,
|
||||
"mergeAttrs": true
|
||||
}
|
||||
},
|
||||
"id": "e666bcfa-ac35-46f2-8179-4610923cf64f",
|
||||
"name": "Parse Paying Depot XML",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1584,
|
||||
48
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {
|
||||
"explicitArray": false,
|
||||
"mergeAttrs": true
|
||||
}
|
||||
},
|
||||
"id": "2d662be5-4701-4f75-8d4e-1aa06c3813ad",
|
||||
"name": "Parse XML Response",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1200,
|
||||
176
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "combine",
|
||||
"combineBy": "combineByPosition",
|
||||
"numberInputs": 3,
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1904,
|
||||
160
|
||||
],
|
||||
"id": "fb7a9070-3276-4800-98e6-7b625c2a9875",
|
||||
"name": "Merge"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "=https://api.palletways.com/getconsignment/{{ $json.trackingid }}?apikey=SXJaM7PLjZDqfsnXSDP8Y9wDY6crxJySBg705MQEPus%3D",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
1008,
|
||||
176
|
||||
],
|
||||
"id": "5a484f33-249d-46af-b664-cdecbb16a2ee",
|
||||
"name": "Get Consigment"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fileFormat": "csv",
|
||||
"options": {
|
||||
"headerRow": false,
|
||||
"includeEmptyCells": true
|
||||
}
|
||||
},
|
||||
"id": "b7226c3d-4d33-4547-9617-020e5c62c164",
|
||||
"name": "Import CSV",
|
||||
"type": "n8n-nodes-base.spreadsheetFile",
|
||||
"position": [
|
||||
256,
|
||||
0
|
||||
],
|
||||
"typeVersion": 2
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "https://portal.palletways.com/api/Planning/?apikey=SXJaM7PLjZDqfsnXSDP8Y9wDY6crxJySBg705MQEPus%3D&output=csv",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"responseFormat": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "874b6714-43dc-44d2-912f-a212c410e084",
|
||||
"name": "Download CSV",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"position": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"typeVersion": 4.1
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Zet deze Code node bij voorkeur op: \"Run once for all items\"\n\nconst get = (obj, path) =>\n path.split('.').reduce((a, k) => (a && a[k] !== undefined ? a[k] : undefined), obj);\n\nconst nz = (v, d = '') => (v === undefined || v === null ? d : v);\nconst ensureArray = (v) => (Array.isArray(v) ? v : v == null ? [] : [v]);\n\nconst cc = (c) => {\n if (!c) return 'NL';\n const u = String(c).toUpperCase();\n return u === 'UK' ? 'GB' : u;\n};\n\nconst xmlEsc = (s) =>\n String(s ?? '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n\nconst parseNum = (v) => {\n if (v === undefined || v === null || v === '') return 0;\n if (typeof v === 'number') return v;\n let s = String(v).trim();\n s = s.replace(',', '.');\n const n = Number(s);\n return isNaN(n) ? 0 : n;\n};\n\nconst firstOf = (obj, paths, def = undefined) => {\n for (const p of paths) {\n const val = get(obj, p);\n if (val !== undefined) return val;\n }\n return def;\n};\n\nfunction buildOne(input) {\n const cons = get(input, 'Response.Detail.Data.Manifest.Depot.Account.Consignment') || {};\n const depotRoot = get(input, 'Response.Detail.Data') || {};\n\n const accountName = nz(get(input, 'Response.Detail.Data.Manifest.Depot.Account.Name'), '');\n const number = nz(cons.Number, '');\n\n // Basisvelden\n const trackingId = nz(cons.TrackingID, nz(cons.Reference, ''));\n const reference = nz(cons.Reference, trackingId);\n const weight = parseNum(nz(cons.Weight, 0));\n const dueDate = nz(cons.DueDate, new Date().toISOString().split('T')[0]);\n const dueTime = nz(cons.DueTime, '') === '20:00' ? '' : nz(cons.DueTime, '');\n const driverInfo = nz(cons.ManifestNote, '');\n\n // Adressen\n const addresses = ensureArray(cons.Address);\n const deliveryAddress = addresses.find((a) => /delivery/i.test(a?.Type || '')) || {};\n const collectionAddress = addresses.find((a) => /collection/i.test(a?.Type || '')) || {};\n\n // Paying depot\n const payingDepot = {\n name: nz(\n depotRoot.CompanyName,\n nz(get(input, 'Response.Detail.Data.Manifest.Depot.Account.Name'), 'Palletways')\n ),\n address1: nz(depotRoot.AddressLine1, ''),\n address2: nz(depotRoot.AddressLine2, ''),\n zipcode: nz(depotRoot.Postcode, ''),\n city: nz(depotRoot.Town, ''),\n country: cc(nz(depotRoot.Countrycode, 'NL')),\n phone: nz(depotRoot.Phone, ''),\n email: nz(depotRoot.Email, ''),\n };\n\n // Return/EU => cargo qty1 (leeg als ontbreekt)\n let euroQty1 = '';\n const returnLines = ensureArray(get(cons, 'Return'));\n for (const r of returnLines) {\n const t = String(nz(r?.Type, '')).toUpperCase();\n if (t === 'EU') {\n const raw = r?.Amount;\n if (raw !== undefined && raw !== null && String(raw).trim() !== '') {\n euroQty1 = String(parseNum(raw));\n }\n break;\n }\n }\n\n // cargo unitamount = lifts\n const lifts = parseNum(nz(cons.Lifts, 1)) || 1;\n\n // BookInRequest -> bool2\n const bookInRaw = String(nz(firstOf(cons, ['BookInRequest', 'Delivery.BookInRequest'], ''))).toLowerCase();\n const bool2 = ['yes', 'true', '1', 'y', 'ja'].includes(bookInRaw);\n\n // taillift -> bool1\n const taillift = String(nz(firstOf(cons, ['TailLift', 'Delivery.TailLift'], ''))).toLowerCase();\n const bool1 = ['yes', 'true', '1', 'y', 'ja'].includes(taillift);\n\n // Prijs\n const csvPrice = parseNum(firstOf(input, ['bedrag'], 0));\n\n // ---- Goodsline opbouw ----\n // 1 goodsline per \"stuk\" in BillUnit (Amount), unitamount=1\n const billUnitsRaw = ensureArray(get(cons, 'BillUnit'));\n const billUnits = billUnitsRaw\n .map((bu) => ({\n type: String(nz(bu?.Type, 'HP')).trim(),\n amount: parseNum(nz(bu?.Amount, 0)),\n }))\n .filter((x) => x.type && x.amount > 0);\n\n // Barcodes uit cons.Pallet (kan string of array zijn)\n const palletsArr = ensureArray(get(cons, 'Pallet'))\n .map((x) => String(x || '').trim())\n .filter((x) => x);\n\n // goodsUnits: 1 entry = 1 goodsline\n const goodsUnits = [];\n\n if (billUnits.length > 0) {\n for (const bu of billUnits) {\n let cnt = Math.round(bu.amount);\n if (cnt <= 0) cnt = 1;\n for (let i = 0; i < cnt; i++) {\n goodsUnits.push({ unit_id: bu.type });\n }\n }\n } else if (palletsArr.length > 0) {\n // geen BillUnit, wel pallets => 1 goodsline per pallet-barcode\n for (let i = 0; i < palletsArr.length; i++) goodsUnits.push({ unit_id: 'HP' });\n } else {\n goodsUnits.push({ unit_id: 'HP' });\n }\n\n const totalLines = goodsUnits.length || 1;\n const weightPerLine = totalLines > 0 ? (weight / totalLines) : 0;\n\n // Als goodsLines > lifts: vanaf lifts-index => oversized (geen barcode + goodsline productdescription)\n const hasOversized = totalLines > lifts;\n\n const goods = [];\n for (let i = 0; i < goodsUnits.length; i++) {\n const oversized = Line truncated
|
||||
},
|
||||
"id": "7329843a-18b7-42b9-a6b3-2e37cfdedbc8",
|
||||
"name": "Transform to Transpas Format v3",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
2208,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.splitInBatches",
|
||||
"typeVersion": 3,
|
||||
"position": [
|
||||
720,
|
||||
176
|
||||
],
|
||||
"id": "bad74b47-8076-4fd2-a4c0-3e1c74b117d8",
|
||||
"name": "Loop Over Items"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"protocol": "sftp",
|
||||
"operation": "upload",
|
||||
"path": "=/dewit/test/to_tp/delivery_{{ $json.filename }}",
|
||||
"binaryData": false,
|
||||
"fileContent": "={{ $json.xml }}",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.ftp",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
2464,
|
||||
240
|
||||
],
|
||||
"id": "bd99d659-63ee-4f66-98ee-f69e96030ee4",
|
||||
"name": "FTP",
|
||||
"credentials": {
|
||||
"sftp": {
|
||||
"id": "uKyzg5cSXQqXOuHI",
|
||||
"name": "SFTP n8n"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"amount": 0.5
|
||||
},
|
||||
"type": "n8n-nodes-base.wait",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
2752,
|
||||
320
|
||||
],
|
||||
"id": "a7c6078c-d03a-465e-a5e3-a50b82d2877f",
|
||||
"name": "Wait",
|
||||
"webhookId": "aca350c1-7a0b-4a9b-844e-c6be79e44f17"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"field": "cronExpression",
|
||||
"expression": "0 21 * * 1-5"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
-288,
|
||||
96
|
||||
],
|
||||
"id": "2cda5c63-4d88-48d7-a46d-0c7b360a6d05",
|
||||
"name": "Schedule Trigger"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "deleteRows",
|
||||
"dataTableId": {
|
||||
"__rl": true,
|
||||
"value": "DFLK6lzDC3xNneBe",
|
||||
"mode": "list",
|
||||
"cachedResultName": "getobman",
|
||||
"cachedResultUrl": "/projects/h6yWgTPhk7LTrXDI/datatables/DFLK6lzDC3xNneBe"
|
||||
},
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "trackingid",
|
||||
"condition": "isNotEmpty"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.dataTable",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1008,
|
||||
16
|
||||
],
|
||||
"id": "f38c1493-4716-43b4-aa41-b88722804062",
|
||||
"name": "Delete row(s)"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "upsert",
|
||||
"dataTableId": {
|
||||
"__rl": true,
|
||||
"value": "DFLK6lzDC3xNneBe",
|
||||
"mode": "list",
|
||||
"cachedResultName": "getobman",
|
||||
"cachedResultUrl": "/projects/h6yWgTPhk7LTrXDI/datatables/DFLK6lzDC3xNneBe"
|
||||
},
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "trackingid",
|
||||
"keyValue": "={{ $json.row[0] }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"columns": {
|
||||
"mappingMode": "defineBelow",
|
||||
"value": {
|
||||
"trackingid": "={{ $json.row[0] }}",
|
||||
"bedrag": "={{ $json.row[76] }}"
|
||||
},
|
||||
"matchingColumns": [],
|
||||
"schema": [
|
||||
{
|
||||
"id": "trackingid",
|
||||
"displayName": "trackingid",
|
||||
"required": false,
|
||||
"defaultMatch": false,
|
||||
"display": true,
|
||||
"type": "string",
|
||||
"readOnly": false,
|
||||
"removed": false
|
||||
},
|
||||
{
|
||||
"id": "bedrag",
|
||||
"displayName": "bedrag",
|
||||
"required": false,
|
||||
"defaultMatch": false,
|
||||
"display": true,
|
||||
"type": "string",
|
||||
"readOnly": false,
|
||||
"removed": false
|
||||
}
|
||||
],
|
||||
"attemptToConvertTypes": false,
|
||||
"convertFieldsToString": false
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.dataTable",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
512,
|
||||
0
|
||||
],
|
||||
"id": "0071e496-3009-4217-91a7-132fdb546003",
|
||||
"name": "Upsert row(s)"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "get",
|
||||
"dataTableId": {
|
||||
"__rl": true,
|
||||
"value": "DFLK6lzDC3xNneBe",
|
||||
"mode": "list",
|
||||
"cachedResultName": "getobman",
|
||||
"cachedResultUrl": "/projects/h6yWgTPhk7LTrXDI/datatables/DFLK6lzDC3xNneBe"
|
||||
},
|
||||
"filters": {
|
||||
"conditions": [
|
||||
{
|
||||
"keyName": "trackingid",
|
||||
"keyValue": "={{ $json.trackingid }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.dataTable",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1424,
|
||||
336
|
||||
],
|
||||
"id": "18f6bde1-aaf1-4c49-91f9-846b160fc409",
|
||||
"name": "Get row(s)",
|
||||
"alwaysOutputData": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "=https://portal.palletways.com/api/getObman/{{ $json.lastWorkday }}?apikey=&output=xml",
|
||||
"sendQuery": true,
|
||||
"queryParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "apikey",
|
||||
"value": "SXJaM7PLjZDqfsnXSDP8Y9wDY6crxJySBg705MQEPus%3D"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "={{ $json[\"lastWorkday\"] }}"
|
||||
},
|
||||
{
|
||||
"name": "output",
|
||||
"value": "xml"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
208,
|
||||
176
|
||||
],
|
||||
"id": "8e44181f-ebe3-43f0-a54f-9000bbac8c5b",
|
||||
"name": "HTTP Request"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// ---------- helpers ----------\nconst get = (obj, path) =>\n path.split('.').reduce((a, k) => (a && a[k] !== undefined ? a[k] : undefined), obj);\n\nconst nz = (v, d = '') => (v === undefined || v === null ? d : v);\nconst ensureArray = (v) => (Array.isArray(v) ? v : v == null ? [] : [v]);\n\nconst cc = (c) => {\n if (!c) return 'NL';\n const u = String(c).toUpperCase();\n return u === 'UK' ? 'GB' : u;\n};\n\nconst xmlEsc = (s) =>\n String(s ?? '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n\nconst parseNum = (v) => {\n if (v === undefined || v === null || v === '') return 0;\n if (typeof v === 'number') return v;\n\n // Spaties weg\n let s = String(v).trim();\n\n // Komma naar punt\n s = s.replace(',', '.');\n\n const n = Number(s);\n return isNaN(n) ? 0 : n;\n};\n\nconst firstOf = (obj, paths, def = undefined) => {\n for (const p of paths) {\n const val = get(obj, p);\n if (val !== undefined) return val;\n }\n return def;\n};\n\n// ---- bron ----\nconst input = $json || {};\nconst cons = get(input, 'Response.Detail.Data.Manifest.Depot.Account.Consignment') || {};\nconst depotRoot = get(input, 'Response.Detail.Data') || {};\n\n// Basisvelden\nconst trackingId = nz(cons.TrackingID, nz(cons.Reference, ''));\nconst reference = nz(cons.Reference, trackingId);\nconst weight = parseNum(nz(cons.Weight, 0));\nconst dueDate = nz(cons.DueDate, new Date().toISOString().split('T')[0]);\nconst dueTime = nz(cons.DueTime, '');\nconst driverInfo = nz(cons.ManifestNote, '');\n\n// Adressen\nconst addresses = ensureArray(cons.Address);\nconst deliveryAddress = addresses.find((a) => /delivery/i.test(a?.Type || '')) || {};\nconst collectionAddress = addresses.find((a) => /collection/i.test(a?.Type || '')) || {};\n\n// Paying depot\nconst payingDepot = {\n name: nz(\n depotRoot.CompanyName,\n nz(get(input, 'Response.Detail.Data.Manifest.Depot.Account.Name'), 'Palletways')\n ),\n address1: nz(depotRoot.AddressLine1, ''),\n address2: nz(depotRoot.AddressLine2, ''),\n zipcode: nz(depotRoot.Postcode, ''),\n city: nz(depotRoot.Town, ''),\n country: cc(nz(depotRoot.Countrycode, 'NL')),\n phone: nz(depotRoot.Phone, ''),\n email: nz(depotRoot.Email, ''),\n};\n\n// --- Goodsline ---\nlet goods = [];\n\nconst palletDetail = get(cons, 'PalletDetail');\nif (palletDetail) {\n // gebruik PalletDetail\n goods.push({\n seq: 1,\n unitamount: 1,\n unit_id: nz(palletDetail.PalletType, 'HP'),\n weight: parseNum(palletDetail.Weight || weight),\n length: parseNum(palletDetail.Length || 120),\n width: parseNum(palletDetail.Width || 80),\n height: parseNum(palletDetail.Height || 150),\n });\n} else {\n // BillUnits\n const billUnits = ensureArray(cons.BillUnit);\n let seq = 1;\n for (const bu of billUnits) {\n const amount = parseNum(bu.Amount || 0);\n if (amount > 0) {\n goods.push({\n seq: seq++,\n unitamount: amount,\n unit_id: nz(bu.Type, 'HP'),\n weight: weight > 0 ? weight / amount : 0,\n length: 120,\n width: 80,\n height: 150,\n });\n }\n }\n // fallback\n if (goods.length === 0) {\n goods.push({\n seq: 1,\n unitamount: 1,\n unit_id: 'HP',\n weight: weight,\n length: 120,\n width: 80,\n height: 150,\n });\n }\n}\n\n// BookInRequest -> bool2\nconst bookInRaw = String(nz(firstOf(cons, ['BookInRequest', 'Delivery.BookInRequest'], ''))).toLowerCase();\nconst bool2 = ['yes', 'true', '1', 'y', 'ja'].includes(bookInRaw);\n\n// taillift -> bool1\nconst taillift = String(nz(firstOf(cons, ['TailLift', 'Delivery.TailLift'], ''))).toLowerCase();\nconst bool1 = ['yes', 'true', '1', 'y', 'ja'].includes(taillift);\n\n// Prijs\nconst csvPrice = parseNum(firstOf(input, ['bedrag'], 0));\n\n// --------- XML ----------\nconst xml = [];\nxml.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\nxml.push('<transportbookings>');\nxml.push(' <transportbooking>');\nxml.push(' <autoacceptmethod>0</autoacceptmethod>');\nxml.push(` <edireference>${xmlEsc(trackingId)}</edireference>`);\nxml.push(' <customer_id matchmode=\"1\">55107</customer_id>');\nxml.push(' <department_id>1</department_id>');\nxml.push(' <currency_id>1</currency_id>');\nxml.push(' <shipments>');\nxml.push(' <shipment>');\nxml.push(` <edireference>${xmlEsc(trackingId)}</edireference>`);\nxml.push(` <reference>${xmlEsc(trackingId)}</reference>`);\nxml.push(' <plangroup_id>33</plangroup_id>');\nxml.push(' <debtor_id>55107</debtor_id>');\nxml.push(' <version>1</version>');\nxml.push(` <fixedprice>${xmlEsc(csvPrice)}</fixedprice>`);\n\n// sender\nxml.push(' <sender>');\nxml.push(` <name>${xmlEsc(nz(collectionAddress.CompanyName, ''))}</name>`);\nxml.push(` <address1>${xmlEsc(nz(collectionAddress.Addr1, ''))}</addLine truncated
|
||||
},
|
||||
"id": "0bdffb34-d13d-459e-b953-10a558a77dcd",
|
||||
"name": "Transform to Transpas Format v",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
2144,
|
||||
-512
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"content": "## Outbound manifest wordt gebruikt voor deze flow",
|
||||
"width": 352
|
||||
},
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
80,
|
||||
-208
|
||||
],
|
||||
"id": "7e6030ff-95b0-4ec7-a087-5ba496ce5876",
|
||||
"name": "Sticky Note"
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Download CSV",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Last workday1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Download CSV": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Import CSV",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Import CSV": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Upsert row(s)",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Last workday1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "HTTP Request",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over Items",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Loop Over Items": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Delete row(s)",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Get Consigment",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Get row(s)",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Consigment": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse XML Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Paying Depot Address": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Paying Depot XML",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse XML Response": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "Get Paying Depot Address",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Paying Depot XML": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Merge": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Transform to Transpas Format v3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Transform to Transpas Format v3": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "FTP",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"FTP": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Wait",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Wait": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Loop Over Items",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get row(s)": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 2
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"HTTP Request": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"binaryMode": "separate",
|
||||
"timezone": "Europe/Amsterdam",
|
||||
"callerPolicy": "workflowsFromSameOwner",
|
||||
"availableInMCP": false
|
||||
},
|
||||
"versionId": "d069831f-6a06-4f66-aecc-ae1d79985359",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
|
||||
},
|
||||
"nodeGroups": [],
|
||||
"id": "qDrWrANHJWpTQm6P",
|
||||
"tags": [
|
||||
{
|
||||
"updatedAt": "2025-11-11T04:59:39.416Z",
|
||||
"createdAt": "2025-11-11T04:59:39.416Z",
|
||||
"id": "ClOZrAjJKoGLFvaO",
|
||||
"name": "Palletways"
|
||||
},
|
||||
{
|
||||
"updatedAt": "2025-11-09T14:44:19.471Z",
|
||||
"createdAt": "2025-11-09T14:44:19.471Z",
|
||||
"id": "DHSMO2U01lFZRZ27",
|
||||
"name": "Productie"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
{
|
||||
"name": "Pre-Alert Kwetsbare Zending",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"path": "prealert",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "06751456-f404-420f-aebc-559b903b6263",
|
||||
"name": "Incoming Data",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
256,
|
||||
-112
|
||||
],
|
||||
"webhookId": "24cbeb29-a571-4e64-affd-3e9149032552"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"keepOnlySet": true,
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "html",
|
||||
"value": "=<div style=\"width:100%; background:#f5f5f5; padding:30px 0; font-family:Arial, sans-serif;\"><div style=\"max-width:650px; margin:0 auto; background:#ffffff; padding:40px; border:1px solid #e0e0e0;\"><h1 style=\"text-align:center; font-size:26px; margin:0; padding:0;\">Pre-alert: Kwetsbare zending voor<br><span style=\"font-size:24px; font-weight:bold;\">{{$json[\"customerCompany\"]}}</span></h1><p style=\"margin-top:30px; font-size:14px; line-height:1.6;\">Beste,<br><br>Graag willen wij u bij deze informeren over een aankomende zending voor onze klant <strong>{{$json[\"customerCompany\"]}}</strong>, waarvoor wij uw extra aandacht vragen.<br><br>De zending bestaat uit <strong>kwetsbare goederen</strong> die gevoelig zijn voor beschadiging bij onzorgvuldige behandeling. Wij verzoeken u daarom vriendelijk om tijdens het transport en de overslag extra zorgvuldigheid in acht te nemen.</p><h2 style=\"margin-top:40px; margin-bottom:15px; font-size:20px;\">Details van de zending:</h2><table style=\"width:100%; font-size:14px; line-height:1.6;\"><tr><td style=\"font-weight:bold; width:180px;\">Klant:</td><td>{{$json[\"customerName\"]}}</td></tr><tr><td style=\"font-weight:bold;\">Bestemming:</td><td>{{$json[\"destination\"]}}</td></tr><tr><td style=\"font-weight:bold;\">DueDate:</td><td>{{$json[\"dueDate\"]}}</td></tr><tr><td style=\"font-weight:bold;\">Aantal colli/pallets:</td><td>{{$json[\"palletCount\"]}}</td></tr><tr><td style=\"font-weight:bold;\">Type goederen:</td><td>{{$json[\"goodsType\"]}}</td></tr><tr><td style=\"font-weight:bold;\">Afmeting (LxBxH):</td><td>{{$json[\"dimensions\"]}}</td></tr><tr><td style=\"font-weight:bold;\">TrackingID:</td><td>{{$json[\"trackingId\"]}}</td></tr></table><p style=\"margin-top:35px; font-size:14px; line-height:1.6;\">Wij vertrouwen erop dat u deze zending met de nodige zorg zult behandelen. Mocht u vragen hebben of aanvullende informatie nodig hebben, neem dan gerust contact met ons op.<br><br>Alvast bedankt voor uw medewerking.<br><br>Met vriendelijke groet,<br><strong>{{$json[\"senderName\"]}}</strong><br>{{$json[\"senderCompany\"]}}</p></div></div>"
|
||||
},
|
||||
{
|
||||
"name": "subject",
|
||||
"value": "=Pre-alert kwetsbare zending {{ $json.trackingId }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "3adeef74-f3ca-4045-9c8d-f2a41b6c8555",
|
||||
"name": "Set HTML Email",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
672,
|
||||
64
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "{\n \"customerCompany\": \"KamadoBBQ B.V.\",\n \"customerName\": \"MDN\",\n \"destination\": \"Konijnenberg 189\",\n \"dueDate\": \"23-01-2026\",\n \"palletCount\": \"1\",\n \"goodsType\": \"HOUTEN PALLET - The Bastard Urban Large Complete BBQ\",\n \"dimensions\": \"120 x 80 x 2200\",\n \"trackingId\": \"60044640865\",\n \"senderName\": \"Team Palletways\",\n \"senderCompany\": \"De Wit Transport\"\n}\n",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
480,
|
||||
64
|
||||
],
|
||||
"id": "ff91d20a-1c41-4075-94c4-186d2a2db791",
|
||||
"name": "Edit Fields"
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
272,
|
||||
64
|
||||
],
|
||||
"id": "a12760e0-de99-4a2d-a421-ba084b095ae2",
|
||||
"name": "When clicking ‘Execute workflow’"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "text",
|
||||
"responseBody": "ok",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.4,
|
||||
"position": [
|
||||
624,
|
||||
-112
|
||||
],
|
||||
"id": "2e366906-a7ff-489f-9bca-853d2a196f59",
|
||||
"name": "Respond to Webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"toRecipients": "jeroen@dmsmail.nl",
|
||||
"subject": "={{ $json.subject }}",
|
||||
"bodyContent": "={{ $json.html }}",
|
||||
"additionalFields": {
|
||||
"bodyContentType": "html"
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.microsoftOutlook",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
944,
|
||||
64
|
||||
],
|
||||
"id": "29cddd6a-dfd9-41e9-86ba-10366b109b1d",
|
||||
"name": "Send a message1",
|
||||
"webhookId": "54154bc4-07a8-4245-a82e-01b148dcbb88",
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "PGANiL6y4sGEEvao",
|
||||
"name": "Microsoft Outlook Palletways"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Incoming Data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Set HTML Email": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send a message1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set HTML Email",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Respond to Webhook",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"When clicking ‘Execute workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"binaryMode": "separate",
|
||||
"timeSavedMode": "fixed",
|
||||
"timezone": "Europe/Amsterdam",
|
||||
"callerPolicy": "workflowsFromSameOwner",
|
||||
"availableInMCP": false
|
||||
},
|
||||
"versionId": "37a34db6-35aa-4f51-add9-0285d2784f25",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
|
||||
},
|
||||
"nodeGroups": [],
|
||||
"id": "dYaxybPLBh4EoljA",
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
{
|
||||
"name": "pw prijzen",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"formTitle": "Palletways tarief bereken",
|
||||
"formFields": {
|
||||
"values": [
|
||||
{
|
||||
"fieldLabel": "Van postcode",
|
||||
"placeholder": "ColPostCode",
|
||||
"defaultValue": "2181vh"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "ColCountryCode",
|
||||
"fieldType": "dropdown",
|
||||
"defaultValue": "NL",
|
||||
"fieldOptions": {
|
||||
"values": [
|
||||
{
|
||||
"option": "NL"
|
||||
},
|
||||
{
|
||||
"option": "DE"
|
||||
},
|
||||
{
|
||||
"option": "IT"
|
||||
},
|
||||
{
|
||||
"option": "BE"
|
||||
},
|
||||
{
|
||||
"option": "ES"
|
||||
},
|
||||
{
|
||||
"option": "FR"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Naar postcode",
|
||||
"placeholder": "DelPostCode",
|
||||
"defaultValue": "2181VH"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Naar land",
|
||||
"fieldType": "dropdown",
|
||||
"defaultValue": "NL",
|
||||
"fieldOptions": {
|
||||
"values": [
|
||||
{
|
||||
"option": "NL"
|
||||
},
|
||||
{
|
||||
"option": "DE"
|
||||
},
|
||||
{
|
||||
"option": "BE"
|
||||
},
|
||||
{
|
||||
"option": "IT"
|
||||
},
|
||||
{
|
||||
"option": "ES"
|
||||
},
|
||||
{
|
||||
"option": "FR"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Lifts",
|
||||
"fieldType": "number",
|
||||
"placeholder": "Lifts",
|
||||
"defaultValue": "1"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Gewicht",
|
||||
"fieldType": "number",
|
||||
"placeholder": "Gewicht",
|
||||
"defaultValue": "700"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Mini Quarter Pallet",
|
||||
"fieldType": "number",
|
||||
"placeholder": "mqp",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Quarter Pallet",
|
||||
"fieldType": "number",
|
||||
"placeholder": "qp",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Half Pallet",
|
||||
"fieldType": "number",
|
||||
"placeholder": "hp",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Euro pallet light",
|
||||
"fieldType": "number",
|
||||
"placeholder": "epl",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Light Pallet",
|
||||
"fieldType": "number",
|
||||
"placeholder": "lp",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "Full Pallet",
|
||||
"fieldType": "number",
|
||||
"placeholder": "fp",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "shuttleCost",
|
||||
"placeholder": "shuttleCost",
|
||||
"defaultValue": "20"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "marginPct",
|
||||
"placeholder": "marginPct",
|
||||
"defaultValue": "20"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "dotPct",
|
||||
"placeholder": "dotPct",
|
||||
"defaultValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.formTrigger",
|
||||
"typeVersion": 2.3,
|
||||
"position": [
|
||||
-432,
|
||||
-96
|
||||
],
|
||||
"id": "6fb1d884-a8eb-42e6-9cce-51e52fcb322f",
|
||||
"name": "On form submission",
|
||||
"webhookId": "7fbd25a6-977d-4db6-878a-99e53ce33352"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "={\n \"QuotationRequest\": {\n \"Date\": \"2025-12-21\",\n \"Time\": \"20:50\",\n \"Account\": { \"Code\": \"100000\" },\n \"Consignment\": {\n \"Type\": \"3\",\n \"Classification\": \"B2B\",\n \"ColCountryCode\": \"{{ $json.ColCountryCode }}\",\n \"ColPostCode\": \"{{ $json['Van postcode'] }}\",\n \"DelCountryCode\": \"{{ $json['Naar land'] }}\",\n \"DelPostCode\": \"{{ $json['Naar postcode'] }}\",\n \"Insurance\": \"standard\",\n \"Lifts\": {{ $json.Lifts }},\n \"Weight\": {{ $json.Gewicht }},\n \"BillUnit\": [\n { \"Type\": \"FP\", \"Amount\": {{ $json['Full Pallet'] }} },\n { \"Type\": \"LP\", \"Amount\": {{ $json['Light Pallet'] }} },\n { \"Type\": \"EPL\", \"Amount\": {{ $json['Euro pallet light'] }} },\n { \"Type\": \"QP\", \"Amount\": {{ $json['Quarter Pallet'] }} },\n { \"Type\": \"MQP\", \"Amount\": {{ $json['Mini Quarter Pallet'] }} }\n ],\n \"Return\": [\n { \"Type\": \"EU\", \"Amount\": 0 },\n { \"Type\": \"EG\", \"Amount\": 0 }\n ],\n \"Handball\": false,\n \"TailLift\": false,\n \"BookInRequest\": false\n }\n }\n }\n",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
-192,
|
||||
-96
|
||||
],
|
||||
"id": "23edf830-f280-42c2-b70f-60371afe2a2b",
|
||||
"name": "Edit Fields"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "jsonToxml",
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
16,
|
||||
-96
|
||||
],
|
||||
"id": "e9b81be0-73d3-447f-afb4-c09f317e5aeb",
|
||||
"name": "XML"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://api.palletways.com/getdepotconsignmentquotations?apikey=SXJaM7PLjZDqfsnXSDP8Y9wDY6crxJySBg705MQEPus%3D&inputformat=xml&outputformat=json",
|
||||
"sendBody": true,
|
||||
"contentType": "form-urlencoded",
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "data",
|
||||
"value": "={{ $json.data }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
256,
|
||||
-96
|
||||
],
|
||||
"id": "1bd888b1-6c57-4f06-b920-298f3d136ba0",
|
||||
"name": "HTTP Request1",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "completion",
|
||||
"respondWith": "showText",
|
||||
"responseText": "={{ $json.formSubmittedText }}"
|
||||
},
|
||||
"type": "n8n-nodes-base.form",
|
||||
"typeVersion": 2.4,
|
||||
"position": [
|
||||
896,
|
||||
-144
|
||||
],
|
||||
"id": "6df73b0d-329a-4a95-9851-3623cb7af4ee",
|
||||
"name": "Form",
|
||||
"webhookId": "e1674065-c8d5-4ca3-aae6-9fd2a13ea847"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const root = $input.first().json;\n\nconst quotations =\n root?.Detail?.Data?.[0]?.Hub?.Quotations?.Quotation ?? [];\n\nreturn quotations.map((q) => ({\n json: {\n colSurchargeName: q?.ColService?.SurchargeName ?? null,\n delSurchargeName: q?.DelService?.SurchargeName ?? null,\n chargeTotal: q?.ChargeTotal ?? null,\n chargeCurrency: q?.ChargeCurrency ?? null, // extra handig\n colServiceName: q?.ColService?.ServiceName ?? null, // extra handig\n delServiceName: q?.DelService?.ServiceName ?? null, // extra handig\n },\n}));\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
464,
|
||||
-96
|
||||
],
|
||||
"id": "06814b2e-4508-4995-bacd-683ab7a8472e",
|
||||
"name": "Code in JavaScript"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const rows = $input.all().map(i => i.json);\n\nconst esc = (s) => String(s ?? '').replace(/</g, '<').replace(/>/g, '>');\n\nlet html = `<b>Offertes</b><br><br>`;\nhtml += `<b>Col surcharge</b> | <b>Del surcharge</b> | <b>Total</b><br>`;\nhtml += `--- | --- | ---<br>`;\n\nhtml += rows\n .map(r =>\n `${esc(r.colSurchargeName)} | ${esc(r.delSurchargeName)} | ${esc(r.chargeTotal)} ${esc(r.chargeCurrency ?? '')}`\n )\n .join('<br>');\n\nreturn [\n {\n json: {\n formSubmittedText: html,\n },\n },\n];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
672,
|
||||
-96
|
||||
],
|
||||
"id": "f5daf975-6102-4c24-8c32-3191e5ab90a8",
|
||||
"name": "Code in JavaScript1"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const data = $input.first().json;\n\n// Pak de API response (robust: werkt of hij nou op root staat of in body/data)\nconst resp =\n data?.Detail ? data :\n data?.body?.Detail ? data.body :\n data?.data?.Detail ? data.data :\n data;\n\n// Quotations array\nconst quotations =\n resp?.Detail?.Data?.[0]?.Hub?.Quotations?.Quotation ?? [];\n\nconst toNum = (v) => {\n const n = Number(String(v ?? \"\").replace(\",\", \".\"));\n return Number.isFinite(n) ? n : 0;\n};\n\n// pallets = lifts\nconst pallets = Math.max(1, Math.round(toNum(data.lifts ?? data.pallets ?? 1)));\n\n// shuttleCost is PER pallet\nconst shuttlePerPallet = toNum(data.shuttleCost);\n\n// percentages\nconst marginPct = toNum(data.marginPct); // bv 12 = 12%\nconst dotPct = toNum(data.dotPct); // bv 5 = 5%\n\n// goedkoopste quote\nconst cheapest = quotations.reduce((best, q) => {\n if (!best) return q;\n return toNum(q.ChargeTotal) < toNum(best.ChargeTotal) ? q : best;\n}, null);\n\n// basis charge: user override of goedkoopste ChargeTotal\nconst hasChargeOverride =\n data.charge !== undefined && data.charge !== null && String(data.charge).trim() !== \"\";\n\nconst baseCharge = hasChargeOverride\n ? toNum(data.charge)\n : (cheapest ? toNum(cheapest.ChargeTotal) : 0);\n\n// === BEREKENING ===\nconst shuttleTotal = shuttlePerPallet * pallets;\n\nconst costExcl = baseCharge + shuttleTotal;\nconst dotAmount = costExcl * (dotPct / 100);\nconst costInclDot = costExcl + dotAmount;\n\nconst tariff = costInclDot * (1 + marginPct / 100);\nconst marginAmount = tariff - costInclDot;\n\nconst fmt = (n) => n.toFixed(2);\n\nconst esc = (s) =>\n String(s ?? \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n\nlet html = `<b>Offertes (Palletways)</b><br>`;\n\nif (!quotations.length) {\n html += `Geen quotes gevonden in response.<br>`;\n} else {\n html += `<br><b>Quotes</b><br><pre>`;\n html += `# | Col surcharge | Del surcharge | Total\\n`;\n html += `---+------------------------------+------------------------------+--------\\n`;\n\n quotations.slice(0, 25).forEach((q, idx) => {\n const col = esc(q?.ColService?.SurchargeName ?? \"\");\n const del = esc(q?.DelService?.SurchargeName ?? \"\");\n const total = esc(q?.ChargeTotal ?? \"\");\n const mark = (cheapest === q) ? \"*\" : \" \";\n html += `${mark}${String(idx + 1).padStart(2, \" \")} | ${col.slice(0, 28).padEnd(28)} | ${del.slice(0, 28).padEnd(28)} | ${total}\\n`;\n });\n\n html += `</pre>* = geselecteerd (laagste ChargeTotal)<br>`;\n}\n\nhtml += `<br><b>Berekening</b><br>`;\nhtml += `Lifts/Pallets: ${pallets}<br>`;\nhtml += `Basis charge: € ${fmt(baseCharge)}<br>`;\nhtml += `Shuttle per pallet: € ${fmt(shuttlePerPallet)} → totaal € ${fmt(shuttleTotal)}<br>`;\nhtml += `DOT (${fmt(dotPct)}%): € ${fmt(dotAmount)}<br>`;\nhtml += `Kosten incl. DOT: € ${fmt(costInclDot)}<br>`;\nhtml += `<b>Totaal tarief: € ${fmt(tariff)}</b><br>`;\nhtml += `Marge (wat je overhoudt): € ${fmt(marginAmount)}<br>`;\nhtml += `Tarief per pallet: € ${fmt(tariff / pallets)}<br>`;\n\nreturn [{ json: { formSubmittedText: html } }];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
464,
|
||||
-320
|
||||
],
|
||||
"id": "ff2c8cbf-336c-4bdf-ac49-08fa94b9d566",
|
||||
"name": "Code in JavaScript2"
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"On form submission": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "XML",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"XML": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "HTTP Request1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"HTTP Request1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code in JavaScript2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code in JavaScript": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code in JavaScript1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code in JavaScript1": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Code in JavaScript2": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Form",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"binaryMode": "separate"
|
||||
},
|
||||
"versionId": "57bec1f7-e133-4e0d-b04f-f53a492772fe",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
|
||||
},
|
||||
"nodeGroups": [],
|
||||
"id": "JAv6gwnDzNjkHkRz",
|
||||
"tags": []
|
||||
}
|
||||
Reference in new issue
Block a user