Stuurt iedere ochtend een mail met de te laden of af te leveren zendingen
This commit is contained in:
1 parent
2b98b3dad3
commit
ec6059904a
1 file changed
+212
@@ -0,0 +1,212 @@
|
|||||||
|
{
|
||||||
|
"name": "Palletways BI - Ochtendoverzicht Excel",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"rule": {
|
||||||
|
"interval": [
|
||||||
|
{
|
||||||
|
"field": "cronExpression",
|
||||||
|
"expression": "30 8 * * 1-5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "b2ebd182-4cad-40d9-9400-639953715491",
|
||||||
|
"name": "Schedule Trigger - werkdagen 08:30",
|
||||||
|
"type": "n8n-nodes-base.scheduleTrigger",
|
||||||
|
"typeVersion": 1.2,
|
||||||
|
"position": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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\";",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "0e7f696b-785d-43fc-b25c-f21ccf74c08a",
|
||||||
|
"name": "Postgres - Ochtendoverzicht data",
|
||||||
|
"type": "n8n-nodes-base.postgres",
|
||||||
|
"typeVersion": 2.6,
|
||||||
|
"position": [
|
||||||
|
240,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"credentials": {
|
||||||
|
"postgres": {
|
||||||
|
"id": "a0jnANQ89VLSby0b",
|
||||||
|
"name": "Palletways DB"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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 .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 `<c r=\"${ref}\"${s}/>`;\n }\n return `<c r=\"${ref}\" t=\"inlineStr\"${s}><is><t>${xmlEscape(value)}</t></is></c>`;\n}\n\nfunction sheetXml(rows) {\n let xml = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n<sheetViews><sheetView workbookViewId=\"0\"><pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/></sheetView></sheetViews>\n<cols>\n<col min=\"1\" max=\"1\" width=\"18\" customWidth=\"1\"/>\n<col min=\"2\" max=\"2\" width=\"28\" customWidth=\"1\"/>\n<col min=\"3\" max=\"3\" width=\"32\" customWidth=\"1\"/>\n<col min=\"4\" max=\"4\" width=\"20\" customWidth=\"1\"/>\n<col min=\"5\" max=\"5\" width=\"32\" customWidth=\"1\"/>\n<col min=\"6\" max=\"6\" width=\"20\" customWidth=\"1\"/>\n<col min=\"7\" max=\"7\" width=\"24\" customWidth=\"1\"/>\n<col min=\"8\" max=\"8\" width=\"70\" customWidth=\"1\"/>\n<col min=\"9\" max=\"9\" width=\"14\" customWidth=\"1\"/>\n</cols>\n<sheetData>`;\n\n xml += `<row r=\"1\">`;\n columns.forEach((h, idx) => xml += cellXml(1, idx + 1, h, 1));\n xml += `</row>`;\n\n let r = 2;\n for (const row of rows) {\n xml += `<row r=\"${r}\">`;\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 += `</row>`;\n r++;\n }\n\n const lastRow = Math.max(1, rows.length + 1);\n xml += `</sheetData>\n<autoFilter ref=\"A1:I${lastRow}\"/>\n</worksheet>`;\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 = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n<sheets>\n${sheets.map(s => `<sheet name=\"${xmlEscape(s.name)}\" sheetId=\"${s.id}\" r:id=\"rId${s.id}\"/>`).join('')}\n</sheets>\n</workbook>`;\n\nconst workbookRels = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n${sheets.map(s => `<Relationship Id=\"rId${s.id}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet${s.id}.xml\"/>`).join('')}\n<Relationship Id=\"rId${sheets.length + 1}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>`;\n\nconst rootRels = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>`;\n\nconst contentTypes = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n<Default Extension=\"xml\" ContentType=\"application/xml\"/>\n<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n${sheets.map(s => `<Override PartName=\"/xl/worksheets/sheet${s.id}.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>`).join('Line truncated
|
||||||
|
},
|
||||||
|
"id": "2874591d-280c-4ec5-90b2-fc1ec9d6f283",
|
||||||
|
"name": "Code - Maak Excel met 3 tabbladen",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
480,
|
||||||
|
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",
|
||||||
|
"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": {
|
||||||
|
"attachments": {
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"binaryPropertyName": "data"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bodyContentType": "html"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.microsoftOutlook",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1104,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"id": "45831e69-cb63-48d1-b40e-e6d4078cbbe7",
|
||||||
|
"name": "Send a message",
|
||||||
|
"webhookId": "e5838636-9bd5-47d0-8423-320ddfe510db",
|
||||||
|
"credentials": {
|
||||||
|
"microsoftOutlookOAuth2Api": {
|
||||||
|
"id": "PGANiL6y4sGEEvao",
|
||||||
|
"name": "Microsoft Outlook Palletways"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pinData": {},
|
||||||
|
"connections": {
|
||||||
|
"Schedule Trigger - werkdagen 08:30": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Postgres - Ochtendoverzicht data",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Postgres - Ochtendoverzicht data": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Maak Excel met 3 tabbladen",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"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": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Send a message",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Send a message": {
|
||||||
|
"main": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"active": true,
|
||||||
|
"settings": {
|
||||||
|
"executionOrder": "v1",
|
||||||
|
"binaryMode": "separate"
|
||||||
|
},
|
||||||
|
"versionId": "c28b3d47-551f-4e70-a868-d22d3f3360b0",
|
||||||
|
"meta": {
|
||||||
|
"templateCredsSetupCompleted": true,
|
||||||
|
"instanceId": "bef8d409866a58c0777dfe7cca1b9c2400fd051c056d361501393ab423006b5f"
|
||||||
|
},
|
||||||
|
"nodeGroups": [],
|
||||||
|
"id": "ZMrqeaFjjQ5OZWuJ",
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
Reference in new issue
Block a user