{ "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, '>');\n\nlet html = `Offertes

`;\nhtml += `Col surcharge | Del surcharge | Total
`;\nhtml += `--- | --- | ---
`;\n\nhtml += rows\n .map(r =>\n `${esc(r.colSurchargeName)} | ${esc(r.delSurchargeName)} | ${esc(r.chargeTotal)} ${esc(r.chargeCurrency ?? '')}`\n )\n .join('
');\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\nlet html = `Offertes (Palletways)
`;\n\nif (!quotations.length) {\n html += `Geen quotes gevonden in response.
`;\n} else {\n html += `
Quotes
`;\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 += `
* = geselecteerd (laagste ChargeTotal)
`;\n}\n\nhtml += `
Berekening
`;\nhtml += `Lifts/Pallets: ${pallets}
`;\nhtml += `Basis charge: € ${fmt(baseCharge)}
`;\nhtml += `Shuttle per pallet: € ${fmt(shuttlePerPallet)} → totaal € ${fmt(shuttleTotal)}
`;\nhtml += `DOT (${fmt(dotPct)}%): € ${fmt(dotAmount)}
`;\nhtml += `Kosten incl. DOT: € ${fmt(costInclDot)}
`;\nhtml += `Totaal tarief: € ${fmt(tariff)}
`;\nhtml += `Marge (wat je overhoudt): € ${fmt(marginAmount)}
`;\nhtml += `Tarief per pallet: € ${fmt(tariff / pallets)}
`;\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": [] }