Zet Systematic csv om naar Transpas formaat
This commit is contained in:
1 parent
17dbfda67e
commit
949cc364ea
1 file changed
+135
@@ -0,0 +1,135 @@
|
|||||||
|
{
|
||||||
|
"name": "Systematic",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"formTitle": "Systematic File upload",
|
||||||
|
"formFields": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"fieldLabel": "Upload file",
|
||||||
|
"fieldType": "file",
|
||||||
|
"fieldName": "uploadFile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.formTrigger",
|
||||||
|
"typeVersion": 2.5,
|
||||||
|
"position": [
|
||||||
|
-64,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"id": "441716c7-ed61-47db-aff7-dd8ed680c747",
|
||||||
|
"name": "On form submission",
|
||||||
|
"webhookId": "f6c9a170-d2b5-4d4b-8c44-44bff00a6e27"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"operation": "xlsx",
|
||||||
|
"binaryPropertyName": "=uploadFile",
|
||||||
|
"options": {
|
||||||
|
"headerRow": true,
|
||||||
|
"range": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.extractFromFile",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
96,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"id": "95e801c3-d23f-4bb4-af50-941cdcfbb059",
|
||||||
|
"name": "Extract from File1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// n8n Code node (Run once for all items)\n// Input: items (1 per Excel-rij) OF 1 item met array van rijen\n// Output: meerdere items -> { filename, xml, reference }\n\n// ======= vaste Transpas pickup address_id =======\nconst PICKUP_ADDRESS_ID = \"69110\"; // Systematic BV\n\nconst inItems = $input.all();\nlet rows = [];\n\n// 1) input kan zijn: 1 item met array als .json, of meerdere items met .json per rij\nif (inItems.length === 1 && Array.isArray(inItems[0].json)) {\n rows = inItems[0].json;\n} else {\n rows = inItems.map(i => i.json);\n}\n\n// ---------- helpers ----------\nconst AMP_FIX_RE = /&(?!amp;|lt;|gt;|quot;|apos;|#\\d+;|#x[0-9A-Fa-f]+;)/g;\nfunction xmlEscape(str) {\n return String(str ?? \"\")\n .replace(AMP_FIX_RE, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction isBlankRow(r) {\n return Object.values(r || {}).every(v => v === null || v === undefined || String(v).trim() === \"\");\n}\n\nfunction isTotalRow(r) {\n const eta = r?.[\"ETD start\"];\n return typeof eta === \"string\" && eta.trim().toLowerCase() === \"totaal\";\n}\n\nfunction isDimsOnlyRow(r) {\n const hasDims = r?.[\"Breedte\"] != null || r?.[\"Hoogte\"] != null || r?.[\"Lengte\"] != null;\n const hasRef = !!getReference(r);\n const hasLos =\n !!(r?.[\"Los naam\"] || r?.[\"Los land\"] || r?.[\"Los postcode\"] || r?.[\"Los plaats\"] || r?.[\"Los adresregel\"]);\n const hasEtaEtd = r?.[\"ETA start\"] != null || r?.[\"ETD start\"] != null;\n return hasDims && !hasRef && !hasLos && !hasEtaEtd;\n}\n\nfunction num(v) {\n const n = parseFloat(String(v ?? \"\").replace(\",\", \".\"));\n return Number.isFinite(n) ? n : null;\n}\n\n// Excel serial (1900 date system) -> YYYY-MM-DD\nfunction excelDateToISO(val) {\n if (typeof val !== \"number\" || !Number.isFinite(val)) return \"\";\n const base = new Date(Date.UTC(1899, 11, 30)); // Excel epoch\n const d = new Date(base.getTime() + val * 86400000);\n return d.toISOString().slice(0, 10);\n}\n\n// Format Date -> YYYY-MM-DD (zonder UTC-dagverschuiving)\nfunction formatDate(d) {\n const yyyy = d.getFullYear();\n const mm = String(d.getMonth() + 1).padStart(2, \"0\");\n const dd = String(d.getDate()).padStart(2, \"0\");\n return `${yyyy}-${mm}-${dd}`;\n}\n\nfunction getNextWorkday(date) {\n const d = new Date(date);\n do {\n d.setDate(d.getDate() + 1);\n } while (d.getDay() === 0 || d.getDay() === 6);\n return d;\n}\n\nfunction pickFirstNonEmpty(...vals) {\n for (const v of vals) {\n if (v !== null && v !== undefined && String(v).trim() !== \"\") return String(v).trim();\n }\n return \"\";\n}\n\nfunction joinAddressLines(...lines) {\n return lines.map(l => String(l ?? \"\").trim()).filter(Boolean).join(\" \");\n}\n\n// >>> BELANGRIJK: jouw input gebruikt \"Nummer\" i.p.v. \"Referentie\"\nfunction getReference(r) {\n return pickFirstNonEmpty(\n r?.[\"Referentie\"],\n r?.[\"Nummer\"], // <-- jouw bestand\n r?.[\"Reference\"],\n r?.[\"Ref\"]\n );\n}\n\n// Pallettype op footprint: Breedte x Lengte\nfunction palletUnitId(width, length) {\n const w = Number(width);\n const l = Number(length);\n if (!Number.isFinite(w) || !Number.isFinite(l)) return \"PW pallet\";\n\n const pair = `${w}x${l}`;\n const pairRev = `${l}x${w}`;\n\n if (pair === \"80x120\" || pairRev === \"80x120\") return \"Euroformaat\";\n if (pair === \"100x120\" || pairRev === \"100x120\") return \"Blokpallet\";\n return \"PW pallet\";\n}\n\nfunction extractDims(r) {\n return {\n width: num(r[\"Breedte\"]),\n height: num(r[\"Hoogte\"]),\n length: num(r[\"Lengte\"]),\n stackable: num(r[\"Stapelbaar\"]) ?? 0\n };\n}\n\n// ---------- 1) schoonmaken + groeperen (dims-only aan vorige koppelen) ----------\nconst shipments = [];\nlet current = null;\n\nfor (const r of rows) {\n if (!r || isBlankRow(r) || isTotalRow(r)) continue;\n\n const ref = getReference(r);\n\n if (ref) {\n current = { main: r, dims: [extractDims(r)], reference: ref };\n shipments.push(current);\n continue;\n }\n\n if (isDimsOnlyRow(r) && current) {\n current.dims.push(extractDims(r));\n continue;\n }\n // overige rommelregels: negeren (zoals \"Aangemaakt op ...\")\n}\n\n// Debug: als er niets overblijft, geef 1 item terug met info ipv \"geen output\"\nif (!shipments.length) {\n return [{\n json: {\n error: \"Geen shipments aangemaakt (geen Referentie/Nummer gevonden).\",\n rowCount: rows.length,\n firstRowKeys: rows[0] ? Object.keys(rows[0]) : []\n }\n }];\n}\n\n// ---------- 2) per shipment -> Transpas XML ----------\nconst CUSTOMER_ID = \"28834\";\nconst DEBTOR_ID = \"28834\";\nconst DEPARTMENT_ID = \"Dep DeWit\";\nconst PLANGROUP_ID = \"2\";\nconst PRODUCT_ID = \"123\";\nconst PRODUCT_DESC = \"General Cargo\";\n\nfunction splitWeight(total, n) {\n const t = Number(total);\n if (!Number.isFinite(t) || n <= 0) return ArraLine truncated
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
288,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"id": "1b8bf47f-bc47-4169-b11a-21efc1b99248",
|
||||||
|
"name": "Build Transpas XML"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"operation": "upload",
|
||||||
|
"path": "=/prod/totp/{{ $json.filename }}",
|
||||||
|
"binaryData": false,
|
||||||
|
"fileContent": "={{ $json.xml }}",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.ftp",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
544,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"id": "179f79c5-8ce3-46e7-802a-ae19b3ea9a64",
|
||||||
|
"name": "FTP1",
|
||||||
|
"credentials": {
|
||||||
|
"ftp": {
|
||||||
|
"id": "oLAZ4OgmkOopMHAq",
|
||||||
|
"name": "FTP De Wit Transport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pinData": {},
|
||||||
|
"connections": {
|
||||||
|
"Extract from File1": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Build Transpas XML",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Build Transpas XML": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "FTP1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"On form submission": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Extract from File1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"active": false,
|
||||||
|
"settings": {
|
||||||
|
"executionOrder": "v1",
|
||||||
|
"binaryMode": "separate",
|
||||||
|
"availableInMCP": false,
|
||||||
|
"timeSavedMode": "fixed",
|
||||||
|
"errorWorkflow": "1Ps5lukDf2sgcGL7",
|
||||||
|
"callerPolicy": "workflowsFromSameOwner"
|
||||||
|
},
|
||||||
|
"versionId": "a5a249df-bb32-4171-afdf-5ae57ecf588e",
|
||||||
|
"meta": {
|
||||||
|
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
|
||||||
|
},
|
||||||
|
"nodeGroups": [],
|
||||||
|
"id": "JapyhfpdzChol1xDx0_eX",
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
Reference in new issue
Block a user