348 lines
13 KiB
JSON
348 lines
13 KiB
JSON
{
|
|
"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": []
|
|
} |