From 0e8d423406bdc330d1e03512d14f8df19b634b2c Mon Sep 17 00:00:00 2001 From: adminjeroen Date: Tue, 7 Jul 2026 11:50:08 +0200 Subject: [PATCH] Aanpassing voor de collections Collections kwamen niet door --- ...alletways BI - Ochtendoverzicht Excel.json | 103 +++--------------- 1 file changed, 15 insertions(+), 88 deletions(-) diff --git a/palletways/Palletways BI - Ochtendoverzicht Excel.json b/palletways/Palletways BI - Ochtendoverzicht Excel.json index 6b203b5..72b933c 100644 --- a/palletways/Palletways BI - Ochtendoverzicht Excel.json +++ b/palletways/Palletways BI - Ochtendoverzicht Excel.json @@ -12,28 +12,28 @@ ] } }, - "id": "b2ebd182-4cad-40d9-9400-639953715491", + "id": "4c6c7cc4-6f30-4086-8f9f-06e012625a7d", "name": "Schedule Trigger - werkdagen 08:30", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ - 0, - 0 + -832, + 16 ] }, { "parameters": { "operation": "executeQuery", - "query": "WITH latest_event AS (\n SELECT DISTINCT ON (tracking_id)\n tracking_id,\n interpreted_status,\n note_text,\n event_at\n FROM palletways_status_events\n ORDER BY tracking_id, event_at DESC NULLS LAST, id DESC\n),\nbase AS (\n SELECT\n s.tracking_id,\n s.account_name,\n s.collection_company,\n s.collection_town,\n s.delivery_company,\n s.delivery_town,\n COALESCE(s.current_status, le.interpreted_status, 'ONBEKEND') AS laatste_status,\n le.note_text AS laatste_note_text,\n s.due_date,\n s.due_time,\n s.is_collection_by_us,\n s.is_delivery_by_us,\n s.is_collection_role,\n s.is_delivery_role,\n s.is_manifested,\n s.is_delivered,\n s.is_deleted,\n s.is_never_arrived,\n s.planned_collection_date,\n s.planned_delivery_date,\n s.collection_list_date,\n s.delivery_list_date\n FROM palletways_shipments s\n LEFT JOIN latest_event le\n ON le.tracking_id = s.tracking_id\n WHERE COALESCE(s.is_deleted, false) = false\n AND COALESCE(s.is_never_arrived, false) = false\n AND COALESCE(s.is_our_paying_depot, false) = true\n)\nSELECT\n 'Op te halen' AS sheet_name,\n tracking_id AS \"TrackingID\",\n account_name AS \"Klant account\",\n collection_company AS \"Laadnaam\",\n collection_town AS \"Laadplaats\",\n delivery_company AS \"Losnaam\",\n delivery_town AS \"Losplaats\",\n laatste_status AS \"Laatste status\",\n laatste_note_text AS \"Laatste note text\",\n due_date AS \"DueDate\",\n 1 AS sort_sheet,\n COALESCE(planned_collection_date, collection_list_date, due_date) AS sort_date\nFROM base\nWHERE (\n COALESCE(is_collection_by_us, false) = true\n OR COALESCE(is_collection_role, false) = true\n )\n AND COALESCE(is_manifested, false) = false\n AND COALESCE(is_delivered, false) = false\n\nUNION ALL\n\nSELECT\n 'Te leveren' AS sheet_name,\n tracking_id AS \"TrackingID\",\n account_name AS \"Klant account\",\n collection_company AS \"Laadnaam\",\n collection_town AS \"Laadplaats\",\n delivery_company AS \"Losnaam\",\n delivery_town AS \"Losplaats\",\n laatste_status AS \"Laatste status\",\n laatste_note_text AS \"Laatste note text\",\n due_date AS \"DueDate\",\n 2 AS sort_sheet,\n COALESCE(planned_delivery_date, delivery_list_date, due_date) AS sort_date\nFROM base\nWHERE (\n COALESCE(is_delivery_by_us, false) = true\n OR COALESCE(is_delivery_role, false) = true\n )\n AND COALESCE(is_delivered, false) = false\n\nUNION ALL\n\nSELECT\n 'Te laat' AS sheet_name,\n tracking_id AS \"TrackingID\",\n account_name AS \"Klant account\",\n collection_company AS \"Laadnaam\",\n collection_town AS \"Laadplaats\",\n delivery_company AS \"Losnaam\",\n delivery_town AS \"Losplaats\",\n laatste_status AS \"Laatste status\",\n laatste_note_text AS \"Laatste note text\",\n due_date AS \"DueDate\",\n 3 AS sort_sheet,\n due_date AS sort_date\nFROM base\nWHERE COALESCE(is_delivered, false) = false\n AND due_date IS NOT NULL\n AND (\n due_date < CURRENT_DATE\n OR (\n due_date = CURRENT_DATE\n AND due_time IS NOT NULL\n AND due_time < LOCALTIME\n )\n )\nORDER BY sort_sheet, sort_date NULLS LAST, \"TrackingID\";", + "query": "WITH latest_event AS (\n SELECT DISTINCT ON (tracking_id)\n tracking_id,\n interpreted_status,\n note_text,\n event_at\n FROM palletways_status_events\n ORDER BY tracking_id, event_at DESC NULLS LAST, id DESC\n),\nbase AS (\n SELECT\n s.tracking_id,\n COALESCE(s.con_no, s.consignment_number) AS con_no,\n s.account_name,\n\n s.paying_depot,\n s.collection_depot,\n s.delivery_depot,\n\n s.collection_company,\n s.collection_town,\n s.collection_country,\n\n s.delivery_company,\n s.delivery_town,\n s.delivery_postcode,\n s.delivery_country,\n\n COALESCE(s.current_status, le.interpreted_status, 'ONBEKEND') AS laatste_status,\n COALESCE(s.last_note_text, le.note_text) AS laatste_note_text,\n\n s.planned_collection_date,\n s.collection_list_date,\n\n CASE\n WHEN NULLIF(s.raw_json->'source_context'->>'date_entered', '') ~ '^\\d{4}-\\d{2}-\\d{2}'\n THEN (NULLIF(s.raw_json->'source_context'->>'date_entered', '')::timestamp)::date\n WHEN NULLIF(s.raw_json->'source_context'->>'date_entered', '') ~ '^\\d{2}/\\d{2}/\\d{4}'\n THEN to_date(NULLIF(s.raw_json->'source_context'->>'date_entered', ''), 'DD/MM/YYYY')\n WHEN s.manifest_date IS NOT NULL\n THEN s.manifest_date\n WHEN s.first_seen_at IS NOT NULL\n THEN s.first_seen_at::date\n ELSE NULL\n END AS boekdatum,\n\n COALESCE(\n s.planned_collection_date,\n s.collection_list_date,\n (\n CASE\n WHEN NULLIF(s.raw_json->'source_context'->>'date_entered', '') ~ '^\\d{4}-\\d{2}-\\d{2}'\n THEN (NULLIF(s.raw_json->'source_context'->>'date_entered', '')::timestamp)::date\n WHEN NULLIF(s.raw_json->'source_context'->>'date_entered', '') ~ '^\\d{2}/\\d{2}/\\d{4}'\n THEN to_date(NULLIF(s.raw_json->'source_context'->>'date_entered', ''), 'DD/MM/YYYY')\n WHEN s.manifest_date IS NOT NULL\n THEN s.manifest_date\n WHEN s.first_seen_at IS NOT NULL\n THEN s.first_seen_at::date\n ELSE NULL\n END\n ) + 1\n ) AS berekende_afhaaldatum,\n\n s.due_date,\n s.due_time,\n\n s.is_collected,\n s.is_delivered,\n s.is_deleted,\n s.is_never_arrived,\n\n s.last_status_poll_at,\n s.updated_at\n FROM palletways_shipments s\n LEFT JOIN latest_event le\n ON le.tracking_id = s.tracking_id\n WHERE\n s.tracking_id IS NOT NULL\n AND s.paying_depot = 464\n AND COALESCE(s.is_deleted, false) = false\n AND COALESCE(s.is_never_arrived, false) = false\n)\n\nSELECT\n 'Op te halen' AS sheet_name,\n tracking_id,\n con_no,\n account_name,\n collection_depot,\n delivery_depot,\n collection_company,\n collection_town,\n collection_country,\n delivery_company,\n delivery_town,\n delivery_postcode,\n delivery_country,\n laatste_status,\n laatste_note_text,\n boekdatum,\n planned_collection_date,\n collection_list_date,\n berekende_afhaaldatum,\n due_date,\n due_time,\n 1 AS sort_sheet,\n berekende_afhaaldatum AS sort_date\nFROM base\nWHERE\n collection_depot IS NOT NULL\n AND collection_depot <> 464\n AND COALESCE(is_collected, false) = false\n AND COALESCE(is_delivered, false) = false\n AND berekende_afhaaldatum IS NOT NULL\n AND berekende_afhaaldatum <= CURRENT_DATE\n\nUNION ALL\n\nSELECT\n 'Te leveren' AS sheet_name,\n tracking_id,\n con_no,\n account_name,\n collection_depot,\n delivery_depot,\n collection_company,\n collection_town,\n collection_country,\n delivery_company,\n delivery_town,\n delivery_postcode,\n delivery_country,\n laatste_status,\n laatste_note_text,\n boekdatum,\n planned_collection_date,\n collection_list_date,\n berekende_afhaaldatum,\n due_date,\n due_time,\n 2 AS sort_sheet,\n due_date AS sort_date\nFROM base\nWHERE\n due_date = CURRENT_DATE\n AND COALESCE(is_delivered, false) = false\n\nUNION ALL\n\nSELECT\n 'Te laat' AS sheet_name,\n tracking_id,\n con_no,\n account_name,\n collection_depot,\n delivery_depot,\n collection_company,\n collection_town,\n collection_country,\n delivery_company,\n delivery_town,\n delivery_postcode,\n delivery_country,\n laatste_status,\n laatste_note_text,\n boekdatum,\n planned_collection_date,\n collection_list_date,\n berekende_afhaaldatum,\n due_date,\n due_time,\n 3 AS sort_sheet,\n due_date AS sort_date\nFROM base\nWHERE\n COALESCE(is_delivered, false) = false\n AND due_date IS NOT NULL\n AND (\n due_date < CURRENT_DATE\n OR (\n due_date = CURRENT_DATE\n AND due_time IS NOT NULL\n AND due_time < LOCALTIME\n )\n )\n\nORDER BY\n sort_sheet,\n sort_date NULLS LAST,\n tracking_id;", "options": {} }, - "id": "0e7f696b-785d-43fc-b25c-f21ccf74c08a", + "id": "1f3ff64b-9181-4663-a532-6911aa07f835", "name": "Postgres - Ochtendoverzicht data", "type": "n8n-nodes-base.postgres", "typeVersion": 2.6, "position": [ - 240, - 0 + -592, + 16 ], "credentials": { "postgres": { @@ -44,57 +44,17 @@ }, { "parameters": { - "jsCode": "\n// Maakt één XLSX met meerdere tabs zonder externe libraries.\n// Verwacht input-items uit Postgres met sheet_name en de gevraagde kolommen.\n\nconst columns = [\n 'TrackingID',\n 'Klant account',\n 'Laadnaam',\n 'Laadplaats',\n 'Losnaam',\n 'Losplaats',\n 'Laatste status',\n 'Laatste note text',\n 'DueDate',\n];\n\nconst sheetNames = ['Op te halen', 'Te leveren', 'Te laat'];\n\nconst grouped = {};\nfor (const name of sheetNames) grouped[name] = [];\n\nfor (const item of items) {\n const row = item.json;\n const sheet = row.sheet_name || 'Overig';\n if (!grouped[sheet]) grouped[sheet] = [];\n grouped[sheet].push(row);\n}\n\nfunction xmlEscape(value) {\n if (value === null || value === undefined) return '';\n return String(value)\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction colLetter(n) {\n let s = '';\n while (n > 0) {\n const m = (n - 1) % 26;\n s = String.fromCharCode(65 + m) + s;\n n = Math.floor((n - m) / 26);\n }\n return s;\n}\n\nfunction cellXml(r, c, value, style = 0) {\n const ref = `${colLetter(c)}${r}`;\n const s = style ? ` s=\"${style}\"` : '';\n if (value === null || value === undefined || value === '') {\n return ``;\n }\n return `${xmlEscape(value)}`;\n}\n\nfunction sheetXml(rows) {\n let xml = `\n\n\n\n\n\n\n\n\n\n\n\n\n\n`;\n\n xml += ``;\n columns.forEach((h, idx) => xml += cellXml(1, idx + 1, h, 1));\n xml += ``;\n\n let r = 2;\n for (const row of rows) {\n xml += ``;\n columns.forEach((col, idx) => {\n let value = row[col];\n if (col === 'DueDate' && value) value = String(value).slice(0, 10);\n xml += cellXml(r, idx + 1, value, 0);\n });\n xml += ``;\n r++;\n }\n\n const lastRow = Math.max(1, rows.length + 1);\n xml += `\n\n`;\n return xml;\n}\n\nconst sheets = sheetNames.map((name, idx) => ({\n name,\n id: idx + 1,\n path: `xl/worksheets/sheet${idx + 1}.xml`,\n xml: sheetXml(grouped[name] || []),\n}));\n\nconst workbookXml = `\n\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst workbookRels = `\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst rootRels = `\n\n\n`;\n\nconst contentTypes = `\n\n\n\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst stylesXml = `\n\n\n\n\n\n\n\n\n\n\n\n\n`;\n\n// ZIP zonder compressie, inclusief CRC32.\nfunction makeCrcTable() {\n const table = [];\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n table[n] = c >>> 0;\n }\n return table;\n}\nconst crcTable = makeCrcTable();\n\nfunction crc32(buf) {\n let crc = 0 ^ -1;\n for (let i = 0; i < buf.length; i++) {\n crc = (crc >>> 8) ^ crcTable[(crc ^ buf[i]) & 0xFF];\n }\n return (crc ^ -1) >>> 0;\n}\n\nfunction dosDateTime(date = new Date()) {\n const time = (date.getHours() << 11) | (date.getMinutes() << 5) | Math.floor(date.getSeconds() / 2);\n const d = ((date.getFullYear() - 1980) << 9) | ((date.getMonth() + 1) << 5) | date.getDate();\n return { time, date: d };\n}\n\nfunction u16(n) {\n const b = Buffer.alloc(2);\n b.writeUInt16LE(n);\n return b;\n}\nfunction u32(n) {\n const b = Buffer.alloc(4);\n b.writeUInt32LE(n >>> 0);\n return b;\n}\n\nfunction createZip(files) {\n const parts = [];\n const central = [];\n let offset = 0;\n const dt = dosDateTime();\n\n for (const file of files) {\n const nameBuf = Buffer.from(file.name, 'utf8');\n const dataBuf = Buffer.from(file.data, 'utf8');\n const crc = crc32(dataBuf);\n\n const local = Buffer.concat([\n u32(0x04034b50), u16(20), u16(0), u16(0),\n u16(dt.time), u16(dt.date),\n u32(crc), u32(dataBuf.length), u32(dataBuf.length),\n u16(nameBuf.length), u16(0),\n nameBuf, dataBuf\n ]);\n\n parts.push(local);\n\n const cent = Buffer.concat([\n u32(0x02014b50), u16(20), u16(20), u16(0), u16(0),\n u16(dt.time), u16(dt.date),\n u32(crc), u32(dataBuf.length), u32(dataBuf.length),\n u16(nameBuf.length), u16(0), u16(0), u16(0), u16(0),\n u32(0), u32(offset), nameBuf\n ]);\n central.push(cent);\n offset += local.length;\n }\n\n const centralStart = offset;\n const centralBuf = Buffer.concat(central);\n const end = Buffer.concat([\n u32(0x06054b50), u16(0), u16(0),\n u16(files.length), u16(files.length),\n u32(centralBuf.length), u32(centralStart),\n u16(0)\n ]);\n\n return Buffer.concat([...parts, centralBuf, end]);\n}\n\nconst files = [\n { name: '[Content_Types].xml', data: contentTypes },\n { name: '_rels/.rels', data: rootRels },\n { name: 'xl/workbook.xml', data: workbookXml },\n { name: 'xl/_rels/workbook.xml.rels', data: workbookRels },\n { name: 'xl/styles.xml', data: stylesXml },\n ...sheets.map(s => ({ name: s.path, data: s.xml })),\n];\n\nconst xlsx = createZip(files);\n\nconst today = new Date().toISOString().slice(0, 10);\nconst fileName = `Palletways_ochtendoverzicht_${today}.xlsx`;\n\nconst binaryData = await this.helpers.prepareBinaryData(\n xlsx,\n fileName,\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n);\n\nreturn [{\n json: {\n fileName,\n aantal_op_te_halen: grouped['Op te halen'].length,\n aantal_te_leveren: grouped['Te leveren'].length,\n aantal_te_laat: grouped['Te laat'].length,\n },\n binary: {\n data: binaryData,\n },\n}];\n" + "jsCode": "// Maakt één XLSX met meerdere tabs zonder externe libraries.\n// Deze versie gebruikt vaste technische kolomnamen uit SQL.\n// Daardoor blijft het tabblad niet leeg als n8n/Postgres kolomnamen anders teruggeeft.\n\nconst columns = [\n { key: 'tracking_id', label: 'TrackingID' },\n { key: 'con_no', label: 'ConNo' },\n { key: 'account_name', label: 'Klant account' },\n { key: 'collection_depot', label: 'Collection depot' },\n { key: 'delivery_depot', label: 'Delivery depot' },\n { key: 'collection_company', label: 'Laadnaam' },\n { key: 'collection_town', label: 'Laadplaats' },\n { key: 'collection_country', label: 'Laadland' },\n { key: 'delivery_company', label: 'Losnaam' },\n { key: 'delivery_town', label: 'Losplaats' },\n { key: 'delivery_postcode', label: 'Lospostcode' },\n { key: 'delivery_country', label: 'Losland' },\n { key: 'laatste_status', label: 'Laatste status' },\n { key: 'laatste_note_text', label: 'Laatste note text' },\n { key: 'boekdatum', label: 'Boekdatum', isDate: true },\n { key: 'planned_collection_date', label: 'Planned collection', isDate: true },\n { key: 'collection_list_date', label: 'Collection list date', isDate: true },\n { key: 'berekende_afhaaldatum', label: 'Berekende afhaaldatum', isDate: true },\n { key: 'due_date', label: 'DueDate', isDate: true },\n { key: 'due_time', label: 'DueTime' },\n];\n\nconst columnWidths = [18, 16, 28, 16, 16, 32, 20, 12, 32, 20, 14, 12, 24, 70, 14, 18, 18, 22, 14, 12];\n\nconst sheetNames = ['Op te halen', 'Te leveren', 'Te laat'];\n\nconst grouped = {};\nfor (const name of sheetNames) grouped[name] = [];\n\nfor (const item of items) {\n const row = item.json;\n const sheet = row.sheet_name || 'Overig';\n if (!grouped[sheet]) grouped[sheet] = [];\n grouped[sheet].push(row);\n}\n\nfunction xmlEscape(value) {\n if (value === null || value === undefined) return '';\n return String(value)\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction colLetter(n) {\n let s = '';\n while (n > 0) {\n const m = (n - 1) % 26;\n s = String.fromCharCode(65 + m) + s;\n n = Math.floor((n - m) / 26);\n }\n return s;\n}\n\nfunction cellXml(r, c, value, style = 0) {\n const ref = `${colLetter(c)}${r}`;\n const s = style ? ` s=\"${style}\"` : '';\n if (value === null || value === undefined || value === '') {\n return ``;\n }\n return `${xmlEscape(value)}`;\n}\n\nfunction formatValue(value, col) {\n if (value === null || value === undefined || value === '') return '';\n if (col.isDate) return String(value).slice(0, 10);\n return value;\n}\n\nfunction sheetXml(rows) {\n let xml = `\n\n\n`;\n\n columnWidths.forEach((width, idx) => {\n const col = idx + 1;\n xml += ``;\n });\n\n xml += `\n`;\n\n xml += ``;\n columns.forEach((col, idx) => xml += cellXml(1, idx + 1, col.label, 1));\n xml += ``;\n\n let r = 2;\n for (const row of rows) {\n xml += ``;\n columns.forEach((col, idx) => {\n const value = formatValue(row[col.key], col);\n xml += cellXml(r, idx + 1, value, 0);\n });\n xml += ``;\n r++;\n }\n\n const lastRow = Math.max(1, rows.length + 1);\n const lastCol = colLetter(columns.length);\n\n xml += `\n\n`;\n return xml;\n}\n\nconst sheets = sheetNames.map((name, idx) => ({\n name,\n id: idx + 1,\n path: `xl/worksheets/sheet${idx + 1}.xml`,\n xml: sheetXml(grouped[name] || []),\n}));\n\nconst workbookXml = `\n\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst workbookRels = `\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst rootRels = `\n\n\n`;\n\nconst contentTypes = `\n\n\n\n\n${sheets.map(s => ``).join('')}\n\n`;\n\nconst stylesXml = `\n\n\n\n\n\n\n\n\n\n\n\n\n`;\n\n// ZIP zonder compressie, inclusief CRC32.\nfunction makeCrcTable() {\n const table = [];\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n table[n] = c >>> 0;\n }\n return table;\n}\nconst crcTable = makeCrcTable();\n\nfunction crc32(buf) {\n let crc = 0 ^ -1;\n for (let i = 0; i < buf.length; i++) {\n crc = (crc >>> 8) ^ crcTable[(crc ^ buf[i]) & 0xFF];\n }\n return (crc ^ -1) >>> 0;\n}\n\nfunction dosDateTime(date = new Date()) {\n const time = (date.getHours() << 11) | (date.getMinutes() << 5) | Math.floor(date.getSeconds() / 2);\n const d = ((date.getFullYear() - 1980) << 9) | ((date.getMonth() + 1) << 5) | date.getDate();\n return { time, date: d };\n}\n\nfunction u16(n) {\n const b = Buffer.alloc(2);\n b.writeUInt16LE(n);\n return b;\n}\nfunction u32(n) {\n const b = Buffer.alloc(4);\n b.writeUInt32LE(n >>> 0);\n return b;\n}\n\nfunction createZip(files) {\n const parts = [];\n const central = [];\n let offset = 0;\n const dt = dosDateTime();\n\n for (const file of files) {\n const nameBuf = Buffer.from(file.name, 'utf8');\n const dataBuf = Buffer.from(file.data, 'utf8');\n const crc = crc32(dataBuf);\n\n const local = Buffer.concat([\n u32(0x04034b50), u16(20), u16(0), u16(0),\n u16(dt.time), u16(dt.date),\n u32(crc), u32(dataBuf.length), u32(dataBuf.length),\n u16(nameBuf.length), u16(0),\n nameBuf, dataBuf\n ]);\n\n parts.push(local);\n\n const cent = Buffer.concat([\n u32(0x02014b50), u16(20), u16(20), u16(0), u16(0),\n u16(dt.time), u16(dt.date),\n u32(crc), u32(dataBuf.length), u32(dataBuf.length),\n u16(nameBuf.length), u16(0), u16(0), u16(0), u16(0),\n u32(0), u32(offset), nameBuf\n ]);\n central.push(cent);\n offset += local.length;\n }\n\n const centralStart = offset;\n const centralBuf = Buffer.concat(central);\n const end = Buffer.concat([\n u32(0x06054b50), u16(0), u16(0),\n u16(files.length), u16(files.length),\n u32(centralBuf.length), u32(centralStart),\n u16(0)\n ]);\n\n return Buffer.concat([...parts, centralBuf, end]);\n}\n\nconst files = [\n { name: '[Content_Types].xml', data: contentTypes },\n { name: '_rels/.rels', data: rootRels },\n { name: 'xl/workbook.xml', data: workbookXml },\n { name: 'xl/_rels/workbook.xml.rels', data: workbookRels },\n { name: 'xl/styles.xml', data: stylesXml },\n ...sheets.map(s => ({ name: s.path, data: s.xml })),\n];\n\nconst xlsx = createZip(files);\n\nconst today = new Date().toISOString().slice(0, 10);\nconst fileName = `Palletways_ochtendoverzicht_${today}.xlsx`;\n\nconst binaryData = await this.helpers.prepareBinaryData(\n xlsx,\n fileName,\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n);\n\nreturn [{\n json: {\n fileName,\n aantal_op_te_halen: grouped['Op te halen'].length,\n aantal_te_leveren: grouped['Te leveren'].length,\n aantal_te_laat: grouped['Te laat'].length,\n },\n binary: {\n data: binaryData,\n },\n}];" }, - "id": "2874591d-280c-4ec5-90b2-fc1ec9d6f283", + "id": "ea555100-7cea-4730-9a24-24db8393e71b", "name": "Code - Maak Excel met 3 tabbladen", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 480, + -352, 16 ] }, - { - "parameters": { - "resource": "draft", - "subject": "=Palletways ochtendoverzicht {{$now.format('yyyy-MM-dd')}}", - "bodyContent": "=Goedemorgen,\n\nIn de bijlage staat het Palletways ochtendoverzicht.\n\nOp te halen: {{$json.aantal_op_te_halen}}\nTe leveren: {{$json.aantal_te_leveren}}\nTe laat: {{$json.aantal_te_laat}}\n\nMet vriendelijke groet,\nDe Wit Transport", - "additionalFields": { - "bodyContentType": "html" - } - }, - "type": "n8n-nodes-base.microsoftOutlook", - "typeVersion": 2, - "position": [ - 688, - -80 - ], - "id": "352b28cd-5eef-4a81-bc44-130d5ed93ec5", - "name": "Create a draft", - "webhookId": "cc6bad10-59ab-4c17-9a48-3858cf8b3b89", - "credentials": { - "microsoftOutlookOAuth2Api": { - "id": "PGANiL6y4sGEEvao", - "name": "Microsoft Outlook Palletways" - } - } - }, - { - "parameters": { - "mode": "combine", - "combineBy": "combineByPosition", - "options": {} - }, - "type": "n8n-nodes-base.merge", - "typeVersion": 3.2, - "position": [ - 896, - 0 - ], - "id": "7814fdca-24e9-483a-88a5-c73242d7ee81", - "name": "Merge" - }, { "parameters": { "toRecipients": "j.daudeij@dewittransport.nl", @@ -114,10 +74,10 @@ "type": "n8n-nodes-base.microsoftOutlook", "typeVersion": 2, "position": [ - 1104, - 0 + -112, + 16 ], - "id": "45831e69-cb63-48d1-b40e-e6d4078cbbe7", + "id": "2ef54e77-07d3-4745-b237-24e69e1bc1f7", "name": "Send a message", "webhookId": "e5838636-9bd5-47d0-8423-320ddfe510db", "credentials": { @@ -153,33 +113,6 @@ ] }, "Code - Maak Excel met 3 tabbladen": { - "main": [ - [ - { - "node": "Create a draft", - "type": "main", - "index": 0 - }, - { - "node": "Merge", - "type": "main", - "index": 1 - } - ] - ] - }, - "Create a draft": { - "main": [ - [ - { - "node": "Merge", - "type": "main", - "index": 0 - } - ] - ] - }, - "Merge": { "main": [ [ { @@ -189,11 +122,6 @@ } ] ] - }, - "Send a message": { - "main": [ - [] - ] } }, "active": true, @@ -201,12 +129,11 @@ "executionOrder": "v1", "binaryMode": "separate" }, - "versionId": "c28b3d47-551f-4e70-a868-d22d3f3360b0", + "versionId": "cb35bc94-13d7-44a4-81fa-cf618360b6f0", "meta": { - "templateCredsSetupCompleted": true, "instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f" }, "nodeGroups": [], - "id": "ZMrqeaFjjQ5OZWuJ", + "id": "duswLc5Shfnd0Rcw", "tags": [] } \ No newline at end of file