{
  "nodes": [
    {
      "parameters": {
        "jsCode": "// Get the body - handle different webhook data structures\nconst body = $json.body || $json;\n\nconst contentBytes = body.contentBytes;\nconst filename = body.filename || 'document.pdf';\nconst contentType = body.contentType || 'application/pdf';\n\nif (!contentBytes) {\n  throw new Error(`contentBytes is undefined. Available keys: ${Object.keys($json).join(', ')}`);\n}\n\nconst buffer = Buffer.from(contentBytes, 'base64');\nconst binaryData = await this.helpers.prepareBinaryData(\n  buffer,\n  filename,\n  contentType\n);\n\nreturn [{ json: body, binary: { data: binaryData } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9600,
        -4576
      ],
      "id": "79188892-b285-411e-95cc-ae83c81d2ba3",
      "name": "Code in JavaScript1"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "neg-invoice",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -9808,
        -4576
      ],
      "id": "93664de5-4cde-467b-a35c-21c58b9b6870",
      "name": "Webhook",
      "webhookId": "c6597904-9fb1-4b1a-a0f0-a2c008253a0d"
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "3f3c2a31-1557-4274-b73d-011e5ebb5f37",
      "name": "Skip - No Attachments",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3,
      "position": [
        -10720,
        -4224
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "$binary",
        "options": {}
      },
      "id": "21901c8b-0f8e-490e-8bb3-1aba9d03df96",
      "name": "2. Split Attachments",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        -10720,
        -4416
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ $json.hasAttachments }}",
              "rightValue": 0,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "3946c9ce-f718-4973-bd2a-a2fb8e6eaa37"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "a9b9c02a-4883-498d-9dcc-221daff5463a",
      "name": "Has Attachments?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -10944,
        -4320
      ]
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "filters": {
          "readStatus": "unread"
        },
        "options": {
          "downloadAttachments": true
        }
      },
      "id": "8fcd8c63-d93a-4dd2-9e4c-e99e91e00e2c",
      "name": "1. Check Invoice Emails",
      "type": "n8n-nodes-base.microsoftOutlookTrigger",
      "typeVersion": 1,
      "position": [
        -11168,
        -4320
      ],
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "id": "iwvMhNMsMLJo3rIZ",
          "name": "Rechunung - NEG Address"
        }
      },
      "notes": "⚠️ SETUP: Configure Microsoft 365 OAuth2 for rechnungen@neg.ag"
    },
    {
      "parameters": {
        "jsCode": "// Get the input item\nconst item = $input.item;\n\n// Check if binary data exists\nif (!item.binary || Object.keys(item.binary).length === 0) {\n  throw new Error('No binary data found. Make sure previous node has attachments.');\n}\n\n// Extract binary data\nconst binaryKey = Object.keys(item.binary)[0]; // 'attachment_0'\nconst binaryData = item.binary[binaryKey];\n\n// Pass through to HTTP node\nreturn {\n  json: {\n    binaryKey: binaryKey,\n    mimeType: binaryData.mimeType,\n    fileName: binaryData.fileName\n  },\n  binary: {\n    data: binaryData  // Rename to 'data' for easier reference\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -10480,
        -4416
      ],
      "id": "90ce3564-45ea-4c29-83dc-1c4b8795baf1",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://neg-document-intelligence.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-invoice:analyze?api-version=2024-07-31-preview",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "binaryData",
        "inputDataFieldName": "data",
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": false,
              "responseFormat": "json"
            }
          },
          "pagination": {}
        }
      },
      "id": "57d131d9-b4a5-4076-ba5b-3c4f216d7c79",
      "name": "3. OCR Invoice (Azure)1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        -10272,
        -4416
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "4y9aoSeutj4AavHP",
          "name": "Vansh Personal Azure OCR"
        }
      }
    },
    {
      "parameters": {
        "amount": 5,
        "unit": "seconds"
      },
      "id": "d3460377-dacc-4dbb-a19f-a7eaba9bfeac",
      "name": "Wait for OCR1",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        -10048,
        -4416
      ],
      "webhookId": "7cca2607-a9e8-472b-b21b-a39661dcd674"
    },
    {
      "parameters": {
        "url": "={{ $json.headers['operation-location'] }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "id": "e768d23b-b7c9-4ac3-9d71-44fdc93bae1e",
      "name": "Get OCR Result1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        -9808,
        -4416
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "4y9aoSeutj4AavHP",
          "name": "Vansh Personal Azure OCR"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * STEP 4: Parse invoice data from OCR (email) or webhook (pre-OCR'd).\n * Webhook path skips Azure OCR — Document workflow already ran it.\n *\n * WEBHOOK fields from Document workflow:\n *   internalNumber, type, typeGerman, confidence, sender, vendorName,\n *   vendorAccountCode, vendorIsKnown, amount, docDate, projectCode,\n *   companyCode, companyName, filename, contentType, folderPath, filePath,\n *   folderId, folderMapped, emailId, emailFrom, emailSubject, emailDate,\n *   extractedText, documentText, extractionMethod, contentBytes, ...\n *\n * EMAIL fields from Azure OCR:\n *   analyzeResult.documents[0].fields.InvoiceId, InvoiceDate, DueDate,\n *   VendorName, VendorAddress, CustomerName, InvoiceTotal, SubTotal,\n *   TotalTax, PaymentDetails, etc.\n */\nconst mergedData = $input.first();\nconst inputJson = mergedData.json;\n\n// ═══════════════════════════════════════════\n// DETECT SOURCE\n// ═══════════════════════════════════════════\n// Webhook payloads from the Document workflow have these unique fields\nconst isWebhookDirect = !!(\n  inputJson?.sourceWorkflow ||\n  inputJson?.extractionMethod ||\n  inputJson?.folderMapped !== undefined ||\n  inputJson?.folderId ||\n  inputJson?.type ||\n  inputJson?.contentBytes\n);\n\nlet emailData = null;\nlet webhookData = null;\n\nif (isWebhookDirect) {\n  webhookData = inputJson;\n} else {\n  try { emailData = $('1. Check Invoice Emails').first()?.json; } catch (e) {}\n  try { webhookData = $('Code in JavaScript1').first()?.json; } catch (e) {}\n}\n\nconst isWebhook = isWebhookDirect ||\n  !!webhookData?.sourceWorkflow ||\n  !!webhookData?.extractionMethod ||\n  !!webhookData?.folderId;\n\n// ═══════════════════════════════════════════\n// HELPERS\n// ═══════════════════════════════════════════\nconst extractValue = (field) => {\n  if (!field) return null;\n  return field.value || field.content || null;\n};\n\nconst extractAmount = (field) => {\n  if (!field) return null;\n  const val = field.value ?? field.content;\n  if (typeof val === 'number') return val;\n  if (typeof val === 'object' && val.amount != null) return val.amount;\n  if (typeof val === 'string') {\n    const cleaned = val.replace(/[€$£CHF\\s]/g, '').trim();\n    if (!cleaned) return null;\n    if (cleaned.includes(',') && cleaned.includes('.')) {\n      return parseFloat(cleaned.replace(/\\./g, '').replace(',', '.')) || null;\n    }\n    if (cleaned.includes(',') && !cleaned.includes('.')) {\n      return parseFloat(cleaned.replace(',', '.')) || null;\n    }\n    return parseFloat(cleaned.replace(/,/g, '')) || null;\n  }\n  return null;\n};\n\nconst parseDate = (str) => {\n  if (!str) return null;\n  let d = new Date(str);\n  if (!isNaN(d.getTime())) return d.toISOString().split('T')[0];\n  const dotMatch = str.match(/(\\d{1,2})\\.(\\d{1,2})\\.(\\d{4})/);\n  if (dotMatch) {\n    d = new Date(dotMatch[3], parseInt(dotMatch[2]) - 1, parseInt(dotMatch[1]));\n    if (!isNaN(d.getTime())) return d.toISOString().split('T')[0];\n  }\n  const slashMatch = str.match(/(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})/);\n  if (slashMatch) {\n    d = new Date(slashMatch[3], parseInt(slashMatch[2]) - 1, parseInt(slashMatch[1]));\n    if (!isNaN(d.getTime())) return d.toISOString().split('T')[0];\n  }\n  return null;\n};\n\nconst parseCurrency = (field) => {\n  const c = field?.valueCurrency;\n  if (!c) return 'EUR';\n  if (typeof c === 'string') return c;\n  return c.currencyCode || c.currencySymbol || 'EUR';\n};\n\n// ═══════════════════════════════════════════\n// BUILD INVOICE OBJECT\n// ═══════════════════════════════════════════\nlet invoice;\n\nif (isWebhook) {\n  // ─── WEBHOOK PATH ───\n  // Map from Document workflow field names to our internal names\n  const wd = webhookData;\n  invoice = {\n    invoiceNumber:  wd.invoiceNumber || wd.internalNumber || null,\n    invoiceDate:    parseDate(wd.invoiceDate || wd.docDate),\n    dueDate:        parseDate(wd.dueDate || null),\n    vendor:         wd.vendorName || wd.vendor || wd.sender || null,\n    vendorAddress:  wd.vendorAddress || null,\n    customerName:   wd.customerName || wd.companyName || null,\n    totalAmount:    typeof wd.totalAmount === 'number' ? wd.totalAmount\n                  : typeof wd.amount === 'number' ? wd.amount\n                  : null,\n    netAmount:      typeof wd.netAmount === 'number' ? wd.netAmount : null,\n    vatAmount:      typeof wd.vatAmount === 'number' ? wd.vatAmount : null,\n    vatRate:        wd.vatRate || null,\n    iban:           wd.iban || null,\n    currency:       wd.currency || 'EUR',\n    ocrConfidence:  wd.ocrConfidence || wd.confidence || 1,\n    extractedText:  wd.extractedText || wd.documentText || ''\n  };\n} else {\n  // ─── EMAIL + AZURE OCR PATH ───\n  const documents = inputJson.analyzeResult?.documents || [];\n  const fields = documents[0]?.fields || {};\n  invoice = {\n    invoiceNumber:  extractValue(fields.InvoiceId),\n    invoiceDate:    parseDate(extractValue(fields.InvoiceDate)),\n    dueDate:        parseDate(extractValue(fields.DueDate)),\n    vendor:         extractValue(fields.VendorName),\n    vendorAddress:  extractValue(fields.VendorAddress),\n    customerName:   extractValue(fields.CustomerName),\n    totalAmount:    extractAmount(fields.InvoiceTotal),\n    netAmount:      extractAmount(fields.SubTotal),\n    vatAmount:      extractAmount(fields.TotalTax),\n    vatRate:        null,\n    iban:           extractValue(fields.PaymentDetails),\n    currency:       parseCurrency(fields.InvoiceTotal),\n    ocrConfidence:  documents[0]?.confidence || 0,\n    extractedText:  inputJson.analyzeResult?.content || ''\n  };\n}\n\n// ═══════════════════════════════════════════\n// VENDOR MATCHING (12 known vendors)\n// ═══════════════════════════════════════════\nconst VENDORS = [\n  { id: 'vodafone',       name: 'Vodafone',                patterns: ['vodafone', 'vodafone gmbh'],               accountCode: '4210' },\n  { id: 'telekom',        name: 'Telekom',                 patterns: ['telekom', 'deutsche telekom', 't-mobile'],  accountCode: '4220' },\n  { id: 'stadtwerke',     name: 'Leipziger Stadtwerke',    patterns: ['stadtwerke', 'leipziger stadtwerke'],       accountCode: '4230' },\n  { id: 'veolia',         name: 'Veolia',                  patterns: ['veolia'],                                   accountCode: '4240' },\n  { id: 'google',         name: 'Google',                  patterns: ['google', 'google ireland', 'google ads'],   accountCode: '4250' },\n  { id: 'immoscout',      name: 'Immoscout24',             patterns: ['immoscout', 'immobilienscout', 'scout24'],  accountCode: '4260' },\n  { id: 'iks',            name: 'IKS Holding',             patterns: ['iks', 'iks holding'],                       accountCode: '4270' },\n  { id: 'neueMedien',     name: 'Neue Medien Muennich',    patterns: ['neue medien', 'muennich', 'münnich', 'munnich'], accountCode: '4280' },\n  { id: 'rupprecht',      name: 'Rupprecht & Partner',     patterns: ['rupprecht'],                                accountCode: '4290' },\n  { id: 'schlosser',      name: 'Schlosser & Pfeiffer',    patterns: ['schlosser', 'pfeiffer'],                    accountCode: '4295' },\n  { id: 'stadtLeipzig',   name: 'Stadt Leipzig',           patterns: ['stadt leipzig', 'stadtverwaltung leipzig'], accountCode: '4300' },\n  { id: 'bundesanzeiger', name: 'Bundesanzeiger',          patterns: ['bundesanzeiger'],                           accountCode: '4310' }\n];\n\n// Build search text for pattern matching\nconst searchText = [\n  invoice.vendor || '',\n  invoice.vendorAddress || '',\n  emailData?.from?.emailAddress?.address || '',\n  emailData?.subject || '',\n  (webhookData?.sender || ''),\n  invoice.extractedText.substring(0, 500)\n].join(' ').toLowerCase();\n\n// If webhook already sent vendorIsKnown with vendor info, trust it directly\nlet matchedVendor;\n\nif (isWebhook && webhookData?.vendorIsKnown && webhookData?.vendorName) {\n  matchedVendor = {\n    id: webhookData.vendorId || null,\n    name: webhookData.vendorName,\n    accountCode: webhookData.vendorAccountCode || null,\n    isKnown: true\n  };\n} else {\n  // Fall back to pattern matching\n  matchedVendor = { name: invoice.vendor || 'Unknown', accountCode: null, isKnown: false };\n\n  for (const v of VENDORS) {\n    if (v.patterns.some(p => searchText.includes(p))) {\n      matchedVendor = { id: v.id, name: v.name, accountCode: v.accountCode, isKnown: true };\n      break;\n    }\n  }\n\n  // Last resort for webhook: use whatever the doc workflow sent\n  if (!matchedVendor.isKnown && isWebhook && webhookData?.vendorName) {\n    matchedVendor = {\n      name: webhookData.vendorName,\n      accountCode: webhookData.vendorAccountCode || null,\n      isKnown: !!webhookData.vendorIsKnown\n    };\n  }\n}\n\n// ═══════════════════════════════════════════\n// PROJECT MATCHING (20 projects)\n// ═══════════════════════════════════════════\nconst PROJECTS = {\n  'B69':  ['berliner str', 'berliner straße 69', 'b69', 'titanic'],\n  'B69a': ['berliner 69a', 'b69a', 'berliner straße 69a'],\n  'R100': ['riesaer', 'r100', 'riesaer straße'],\n  'HH':   ['konsul', 'hotel konsul', 'hh'],\n  'HR':   ['hegelring', 'schkeuditz'],\n  'T42':  ['theklaer', 't42'],\n  'B8':   ['bitterfelder', 'b8'],\n  'E25':  ['essener', 'e25'],\n  'TG':   ['großpösna', 'grosspösna', 'seiferts'],\n  'PB38': ['brehnaer', 'pohritzsch', 'pb38'],\n  'SF':   ['freirodaer', 'sf'],\n  'GD15': ['gustebin', 'dorfostr', 'gd15'],\n  'MN10': ['taucha', 'mn10'],\n  'GF4':  ['fleischergasse', 'gf4'],\n  'H/S':  ['seenallee', 'markkleeberg'],\n  'Z1':   ['büroeinheiten', 'office units', 'z1'],\n  'BA66': ['adelsberg', 'ba66'],\n  'BJL':  ['borsdorf', 'justus', 'liebig', 'bjl'],\n  'GS':   ['gs'],\n  'AFL':  ['alter flughafen', 'flughafen mockau', 'mockau', 'afl']\n};\n\nlet projectCode = 'Allgemein';\n\n// Webhook: trust the document workflow's projectCode first\nif (isWebhook && webhookData?.projectCode && webhookData.projectCode !== 'Allgemein') {\n  projectCode = webhookData.projectCode;\n} else {\n  const fullText = (searchText + ' ' + (invoice.invoiceNumber || '')).toLowerCase();\n  for (const [code, patterns] of Object.entries(PROJECTS)) {\n    if (patterns.some(p => fullText.includes(p))) {\n      projectCode = code;\n      break;\n    }\n  }\n}\n\n// ═══════════════════════════════════════════\n// COMPANY / SPV MATCHING (25 companies)\n// ═══════════════════════════════════════════\nconst COMPANIES = {\n  'NEG_AG':     { name: 'NEG AG',                         patterns: ['neg ag', 'northgate'] },\n  'Messeblick': { name: 'Messeblick Leipzig GmbH',        patterns: ['messeblick'] },\n  'ACI':        { name: 'ARTCAS Invest GmbH',             patterns: ['artcas invest'] },\n  'APG':        { name: 'ARTCAS Projekt GmbH',            patterns: ['artcas projekt gmbh'] },\n  'BSG':        { name: 'BSG mbH',                        patterns: ['bsg mbh'] },\n  'AFL':        { name: 'Alter Flughafen Leipzig GmbH',   patterns: ['alter flughafen', 'flughafen mockau'] },\n  'B69':        { name: 'ARTCAS Projekt B69 GmbH',        patterns: ['ap b69', 'projekt b69'] },\n  'B69a':       { name: 'ARTCAS Projekt B69a GmbH',       patterns: ['ap b69a', 'projekt b69a'] },\n  'T42':        { name: 'ARTCAS Projekt T42 GmbH',        patterns: ['ap t42', 'projekt t42'] },\n  'R100':       { name: 'ARTCAS Projekt R100 GmbH',       patterns: ['ap r100', 'projekt r100'] },\n  'B8':         { name: 'ARTCAS Projekt B8 GmbH',         patterns: ['ap b8', 'projekt b8'] },\n  'HR':         { name: 'ARTCAS Projekt HR GmbH',         patterns: ['ap hr', 'projekt hr'] },\n  'HS':         { name: 'ARTCAS Projekt H/S GmbH',        patterns: ['ap h/s', 'projekt h/s', 'h/s gmbh'] },\n  'Z1':         { name: 'ARTCAS Projekt Z1 GmbH',         patterns: ['ap z1', 'projekt z1'] },\n  'HH':         { name: 'ARTCAS Projekt HH GmbH',         patterns: ['ap hh', 'projekt hh', 'hotel konsul'] },\n  'GF4':        { name: 'ARTCAS Projekt GF4 GmbH',        patterns: ['ap gf4', 'projekt gf4', 'fleischergasse'] },\n  'BJL':        { name: 'ARTCAS Projekt BJL GmbH',        patterns: ['ap bjl', 'projekt bjl', 'borsdorf'] },\n  'BA66':       { name: 'ARTCAS Projekt BA66 GmbH',       patterns: ['ap ba66', 'projekt ba66', 'adelsberg'] },\n  'GD15':       { name: 'ARTCAS Projekt GD15 GmbH',       patterns: ['ap gd15', 'projekt gd15', 'gustebin'] },\n  'TG':         { name: 'ARTCAS Projekt TG GmbH',         patterns: ['ap tg', 'projekt tg'] },\n  'GS':         { name: 'ARTCAS Projekt GS GmbH',         patterns: ['ap gs', 'projekt gs'] },\n  'E25':        { name: 'ARTCAS Projekt E25 GmbH',        patterns: ['ap e25', 'projekt e25', 'essener'] },\n  'PB38':       { name: 'ARTCAS Projekt PB38 GmbH',       patterns: ['ap pb38', 'projekt pb38', 'brehnaer'] },\n  'SF':         { name: 'ARTCAS Projekt SF GmbH',         patterns: ['ap sf', 'projekt sf', 'freirodaer'] },\n  'MN10':       { name: 'ARTCAS Projekt MN10 GmbH',       patterns: ['ap mn10', 'projekt mn10'] }\n};\n\nconst PROJECT_TO_COMPANY = {\n  'B69': 'B69', 'B69a': 'B69a', 'R100': 'R100',\n  'HH': 'HH', 'HR': 'HR', 'T42': 'T42',\n  'B8': 'B8', 'E25': 'E25', 'TG': 'TG',\n  'PB38': 'PB38', 'SF': 'SF', 'GD15': 'GD15',\n  'MN10': 'MN10', 'GF4': 'GF4', 'H/S': 'HS',\n  'Z1': 'Z1', 'BA66': 'BA66', 'BJL': 'BJL',\n  'GS': 'GS', 'AFL': 'AFL'\n};\n\nlet companyCode = 'NEG_AG';\n\n// Webhook: trust the document workflow's companyCode first\nif (isWebhook && webhookData?.companyCode) {\n  companyCode = webhookData.companyCode;\n} else if (projectCode !== 'Allgemein' && PROJECT_TO_COMPANY[projectCode]) {\n  companyCode = PROJECT_TO_COMPANY[projectCode];\n} else {\n  const companyText = (invoice.customerName || '').toLowerCase() + ' ' + searchText;\n  for (const [code, co] of Object.entries(COMPANIES)) {\n    if (co.patterns.some(p => companyText.includes(p))) {\n      companyCode = code;\n      break;\n    }\n  }\n}\n\n// ═══════════════════════════════════════════\n// FOLDER ABBREVIATION\n// ═══════════════════════════════════════════\nconst PROJECT_TO_FOLDER_ABBR = {\n  'B69': 'B69', 'B69a': 'B69A', 'R100': 'R100',\n  'HH': 'HH', 'HR': 'HR', 'T42': 'T42',\n  'B8': 'B8', 'E25': 'E25', 'TG': 'TG',\n  'PB38': 'PB38', 'SF': 'SF', 'GD15': 'GD15',\n  'MN10': 'MN10', 'GF4': 'GF4', 'H/S': 'HS',\n  'Z1': 'Z1', 'BA66': 'BA66', 'BJL': 'BJL',\n  'GS': 'GS', 'AFL': 'AFL'\n};\n\nconst COMPANY_TO_FOLDER_ABBR = {\n  'NEG_AG': 'NEG', 'Messeblick': 'MESS', 'ACI': 'ACI',\n  'APG': 'APG', 'BSG': 'BSG'\n};\n\nlet folderAbbr = 'NEG';\nif (projectCode !== 'Allgemein' && PROJECT_TO_FOLDER_ABBR[projectCode]) {\n  folderAbbr = PROJECT_TO_FOLDER_ABBR[projectCode];\n} else if (COMPANY_TO_FOLDER_ABBR[companyCode]) {\n  folderAbbr = COMPANY_TO_FOLDER_ABBR[companyCode];\n}\n\n// ═══════════════════════════════════════════\n// FOLDER PATH with Year/Month\n// ═══════════════════════════════════════════\nconst invDate = invoice.invoiceDate ? new Date(invoice.invoiceDate) : new Date();\nconst invYear = invDate.getFullYear();\nconst invMonth = String(invDate.getMonth() + 1).padStart(2, '0');\n\nconst folderPlaceholder = `PH_BUCH_${folderAbbr}_VERB`;\nconst folderPath = `50_BUCHHALTUNG/${folderAbbr}/Verbindlichkeiten/${invYear}/${invMonth}`;\n\n// ═══════════════════════════════════════════\n// SEQUENTIAL COUNTER\n// ═══════════════════════════════════════════\nconst year = new Date().getFullYear();\nlet counter = $getWorkflowStaticData('global');\nif (!counter.invoiceCounter || counter.counterYear !== year) {\n  counter.invoiceCounter = 0;\n  counter.counterYear = year;\n}\ncounter.invoiceCounter++;\nconst seq = String(counter.invoiceCounter).padStart(4, '0');\nconst internalNumber = `INV-${year}-${seq}`;\n\n// ═══════════════════════════════════════════\n// FILENAME\n// ═══════════════════════════════════════════\nconst sanitize = (str) => {\n  if (!str) return 'Unknown';\n  return str.replace(/[<>:\"\\/\\\\|?*]/g, '').replace(/\\s+/g, '-')\n    .replace(/[äÄ]/g, 'ae').replace(/[öÖ]/g, 'oe')\n    .replace(/[üÜ]/g, 'ue').replace(/ß/g, 'ss')\n    .replace(/-+/g, '-').replace(/^-|-$/g, '').substring(0, 30);\n};\n\nlet filename;\nif (isWebhook && webhookData?.filename) {\n  // Use the filename the document workflow already built\n  filename = webhookData.filename;\n} else {\n  const dateStr = invoice.invoiceDate || new Date().toISOString().split('T')[0];\n  filename = `${dateStr}_Rechnung_${sanitize(projectCode)}_${sanitize(matchedVendor.name)}.pdf`;\n}\n\n// ═══════════════════════════════════════════\n// STAMP TEXT\n// ═══════════════════════════════════════════\nconst today = new Date().toLocaleDateString('de-DE');\nconst stampText = `${internalNumber} | ${projectCode} | Eingegangen: ${today} | Konto: ${matchedVendor.accountCode || 'TBD'} | Zur Freigabe`;\n\n// ═══════════════════════════════════════════\n// APPROVAL LOGIC\n// ═══════════════════════════════════════════\nconst amount = invoice.totalAmount || 0;\nconst approvalNeeded = amount >= 100;\nconst approvalSteps = amount < 100 ? 0 : (amount < 5000 ? 2 : 3);\n\n// ═══════════════════════════════════════════\n// BINARY — grab from correct source\n// ═══════════════════════════════════════════\nlet binaryData;\nif (isWebhook) {\n  // Webhook path: binary was prepared by \"Code in JavaScript1\" from contentBytes\n  binaryData = mergedData.binary || {};\n  // If still empty, try the Code in JavaScript1 node directly\n  if (!binaryData || Object.keys(binaryData).length === 0) {\n    try {\n      binaryData = $('Code in JavaScript1').first().binary || {};\n    } catch (e) {\n      binaryData = {};\n    }\n  }\n} else {\n  // Email path: binary was prepared by \"Code in JavaScript\" (Prep Binary)\n  try {\n    binaryData = $('Code in JavaScript').first().binary || {};\n  } catch (e) {\n    binaryData = {};\n  }\n}\n\n// ═══════════════════════════════════════════\n// FINAL OUTPUT\n// ═══════════════════════════════════════════\nreturn {\n  json: {\n    source: isWebhook ? 'webhook' : 'email',\n    emailId: emailData?.id || webhookData?.emailId || null,\n    emailFrom: emailData?.from?.emailAddress?.address || webhookData?.emailFrom || null,\n    emailSubject: emailData?.subject || webhookData?.emailSubject || null,\n    invoiceNumber: invoice.invoiceNumber,\n    invoiceDate: invoice.invoiceDate,\n    dueDate: invoice.dueDate,\n    vendor: invoice.vendor,\n    vendorAddress: invoice.vendorAddress,\n    customerName: invoice.customerName,\n    totalAmount: invoice.totalAmount,\n    netAmount: invoice.netAmount,\n    vatAmount: invoice.vatAmount,\n    vatRate: invoice.vatRate,\n    iban: invoice.iban,\n    currency: invoice.currency,\n    ocrConfidence: invoice.ocrConfidence,\n    extractedText: invoice.extractedText,\n    vendorName: matchedVendor.name,\n    vendorAccountCode: matchedVendor.accountCode,\n    vendorIsKnown: matchedVendor.isKnown,\n    projectCode,\n    companyCode,\n    companyName: COMPANIES[companyCode]?.name || webhookData?.companyName || 'NEG AG',\n    internalNumber,\n    filename,\n    folderAbbr,\n    folderPlaceholder,\n    folderPath,\n    filePath: `${folderPath}/${filename}`,\n    yearFolder: String(invYear),\n    monthFolder: invMonth,\n    stampText,\n    approvalNeeded,\n    approvalSteps,\n    docWorkflowRef: webhookData?.internalNumber || null\n  },\n  binary: binaryData\n};"
      },
      "id": "fd2e79f6-e086-4858-a2e1-f4d1b5b7e200",
      "name": "4. Process Invoice Data2",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9344,
        -4432
      ],
      "notes": "Enhanced: Project matching (17 projects), Sequential counter, Enhanced stamp with status"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ $json.vendorIsKnown }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "id": "b2f17c7e-606c-4bca-84c0-cc3513347595"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "11f80720-f7fa-4b64-97bd-165cae6b0867",
      "name": "Vendor Known?2",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -7232,
        -3264
      ],
      "disabled": true
    },
    {
      "parameters": {
        "subject": "=⚠️ Unbekannter Lieferant: {{ $json.vendorName || $json.vendor || 'Unbekannt' }}",
        "additionalFields": {}
      },
      "id": "1951d79f-ee01-4d73-a1cd-e4927a5d224e",
      "name": "Notify Unknown Vendor2",
      "type": "n8n-nodes-base.microsoftOutlook",
      "typeVersion": 2,
      "position": [
        -7184,
        -3072
      ],
      "webhookId": "0935408d-8767-40d0-a98d-2cb659f3dd76",
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "id": "JkENlhnvoCwv5aDV",
          "name": "Saits - Vansh"
        }
      },
      "disabled": true
    },
    {
      "parameters": {
        "jsCode": "/* \n * STEP 5: Prepare Cover Sheet HTML\n */\nconst invoice = $input.first().json;\nconst base64Content = $('Extract from File1').first().json.data;\n\nconst stampHtml = `\n<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    @page { margin: 0; size: A4; }\n    body { \n      margin: 0; padding: 0; \n      font-family: Arial, sans-serif;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      height: 100vh;\n      background: #fff;\n    }\n    \n    .cover-box {\n        border: 4px double #333;\n        padding: 40px;\n        text-align: center;\n        width: 60%;\n        background: #f9f9f9;\n        box-shadow: 0 4px 15px rgba(0,0,0,0.1);\n    }\n    \n    h1 { margin: 0 0 20px 0; color: #d32f2f; text-transform: uppercase; }\n    .label { font-size: 12px; color: #666; margin-top: 15px; }\n    .value { font-size: 18px; font-weight: bold; color: #000; }\n    \n  </style>\n</head>\n<body>\n  <div class=\"cover-box\">\n    <h1>Invoice Approved</h1>\n    <div style=\"border-bottom: 1px solid #ccc; margin: 20px 0;\"></div>\n    \n    <div class=\"label\">VENDOR</div>\n    <div class=\"value\">${invoice.vendorName || 'Unknown'}</div>\n    \n    <div class=\"label\">PROJECT</div>\n    <div class=\"value\">${invoice.projectCode || 'General'}</div>\n    \n    <div class=\"label\">INTERNAL REF</div>\n    <div class=\"value\">${invoice.internalNumber || 'Pending'}</div>\n    \n    <div class=\"label\">DATE RECEIVED</div>\n    <div class=\"value\">${new Date().toLocaleDateString('de-DE')}</div>\n    \n    <div style=\"margin-top: 30px; font-size: 10px; color: #999;\">\n      Digitally Processed by NEG Automation\n    </div>\n  </div>\n</body>\n</html>\n`;\n\nreturn {\n  json: { \n    originalPdfBase64: base64Content, \n    filename: invoice.filename \n  },\n  binary: {\n    index: {\n      data: Buffer.from(stampHtml).toString('base64'),\n      mimeType: 'text/html',\n      fileName: 'index.html'\n    }\n  }\n};"
      },
      "id": "ae6e55fa-8620-41ef-9acd-8015b4d1cca4",
      "name": "5. Create Digital Stamp (PDF)1",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -6752,
        -3104
      ],
      "disabled": true,
      "notes": "Uses pdf-lib to actually modify the PDF with stamp"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://gotenberg:3000/forms/chromium/convert/html",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "index",
              "inputDataFieldName": "index"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -6528,
        -3104
      ],
      "id": "f338b3ae-416b-4a82-9249-6b1b0b8608be",
      "name": "6. Convert to PDF1",
      "disabled": true
    },
    {
      "parameters": {
        "jsCode": "/* \n * STEP 3A (Fixed Order): Combine Invoice + Stamp \n * RESULT: Page 1..N = Invoice, Last Page = Stamp\n */\nconst item = items[0];\n\n// 1. Get Stamp PDF Binary (from previous node)\nconst stampBinaryObject = item.binary.data; \n\n// 2. Retrieve Original PDF Base64 (from JSON)\nconst originalPdfBase64 = item.json.originalPdfBase64;\n\nreturn {\n  json: { filename: item.json.filename },\n  binary: {\n    // ORDER MATTERS FOR MERGE:\n    \n    // File 1: ORIGINAL INVOICE (Comes First)\n    file1: {\n      data: originalPdfBase64,\n      mimeType: 'application/pdf',\n      fileName: '01_Invoice.pdf'\n    },\n    \n    // File 2: STAMP PAGE (Comes Last)\n    file2: stampBinaryObject\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -6320,
        -3104
      ],
      "id": "0571a5c1-a0c6-4447-b572-8d2b955857d5",
      "name": "7. Get Invoice & Stamp1",
      "disabled": true
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://gotenberg:3000/forms/pdfengines/merge",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "files",
              "inputDataFieldName": "file1"
            },
            {
              "parameterType": "formBinaryData",
              "name": "files",
              "inputDataFieldName": "file2"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -6096,
        -3104
      ],
      "id": "b543a341-a13c-48dc-937d-cc15dfac1332",
      "name": "8. Combine PDFs1",
      "disabled": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "cf3aa6bb-a120-4e66-992c-8c16d1ad8639",
              "leftValue": "={{ $json.status }}",
              "rightValue": "succeeded",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -9584,
        -4416
      ],
      "id": "462745f0-934a-42d0-aead-7ab53d5d8d07",
      "name": "If1"
    },
    {
      "parameters": {
        "jsCode": "const d = $input.first().json;\n\nreturn {\n  json: {\n    \"Lfd. Nr.\": d.internalNumber,\n    \"RE-Nr.\": d.invoiceNumber,\n    \"RE-Datum\": d.invoiceDate,\n    \"Eingangsdatum\": new Date().toISOString().split('T')[0],\n    \"Faelligkeitsdatum\": d.dueDate,\n    \"Lieferant\": d.vendorName,\n    \"Kred.-Konto\": d.vendorAccountCode,\n    \"Projekt\": d.projectCode,\n    \"Gesellschaft\": d.companyName,\n    \"Bruttobetrag\": d.totalAmount,\n    \"Nettobetrag\": d.netAmount,\n    \"MwSt.\": d.vatAmount,\n    \"MwSt.-Satz\": d.vatRate,\n    \"Waehrung\": d.currency,\n    \"IBAN\": d.iban,\n    \"Buchungskonto\": d.vendorAccountCode,\n    \"Kostenstelle\": d.projectCode,\n    \"Zahlungsstatus\": \"Offen\",\n    \"Freigabestufe\": d.approvalSteps === 0 ? 'Auto' : d.approvalSteps === 2 ? '2-Stufen' : '3-Stufen',\n    \"Freigegeben von\": \"\",\n    \"Freigabedatum\": \"\",\n    \"Dateiname\": d.filename,\n    \"OneDrive-Pfad\": d.folderPath,\n    \"Bemerkung\": d.source === 'webhook' && d.docWorkflowRef ? 'Ref: ' + d.docWorkflowRef : ''\n  }\n};"
      },
      "id": "93c6ec8e-6f08-49cf-8aaa-0f111f37b7cc",
      "name": "Map to Excel",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9168,
        -4432
      ]
    },
    {
      "parameters": {
        "resource": "worksheet",
        "operation": "append",
        "workbook": {
          "__rl": true,
          "value": "016ZC2UENNX3FINPJ7TBFJT6K37BFNTZJD",
          "mode": "list",
          "cachedResultName": "NEG_Rechnungseingangsbuch_Template 1",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
        },
        "worksheet": {
          "__rl": true,
          "value": "{00000000-0001-0000-0000-000000000000}",
          "mode": "list",
          "cachedResultName": "Rechnungseingangsbuch",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Rechnungseingangsbuch!A1"
        },
        "fieldsUi": {
          "values": [
            {
              "column": "Lfd. Nr.",
              "fieldValue": "={{ $json['Lfd. Nr.'] }}"
            },
            {
              "column": "RE-Nr.",
              "fieldValue": "={{ $json['RE-Nr.'] }}"
            },
            {
              "column": "RE-Datum",
              "fieldValue": "={{ $json['RE-Datum'] }}"
            },
            {
              "column": "Eingangsdatum",
              "fieldValue": "={{ $json.Eingangsdatum }}"
            },
            {
              "column": "Faelligkeitsdatum",
              "fieldValue": "={{ $json.Faelligkeitsdatum }}"
            },
            {
              "column": "Lieferant",
              "fieldValue": "={{ $json.Lieferant }}"
            },
            {
              "column": "Kred.-Konto",
              "fieldValue": "={{ $json['Kred.-Konto'] }}"
            },
            {
              "column": "Projekt",
              "fieldValue": "={{ $json.Projekt }}"
            },
            {
              "column": "Gesellschaft",
              "fieldValue": "={{ $json.Gesellschaft }}"
            },
            {
              "column": "Bruttobetrag",
              "fieldValue": "={{ $json.Bruttobetrag }}"
            },
            {
              "column": "Nettobetrag",
              "fieldValue": "={{ $json.Nettobetrag }}"
            },
            {
              "column": "MwSt.",
              "fieldValue": "={{ $json['MwSt.'] }}"
            },
            {
              "column": "MwSt.-Satz",
              "fieldValue": "={{ $json['MwSt.-Satz'] }}"
            },
            {
              "column": "Waehrung",
              "fieldValue": "={{ $json.Waehrung }}"
            },
            {
              "column": "IBAN",
              "fieldValue": "={{ $json.IBAN }}"
            },
            {
              "column": "Buchungskonto",
              "fieldValue": "={{ $json.Buchungskonto }}"
            },
            {
              "column": "Kostenstelle",
              "fieldValue": "={{ $json.Kostenstelle }}"
            },
            {
              "column": "Zahlungsstatus",
              "fieldValue": "={{ $json.Zahlungsstatus }}"
            },
            {
              "column": "Freigabestufe",
              "fieldValue": "={{ $json.Freigabestufe }}"
            },
            {
              "column": "Freigegeben von",
              "fieldValue": "={{ $json['Freigegeben von'] }}"
            },
            {
              "column": "Freigabedatum",
              "fieldValue": "={{ $json.Freigabedatum }}"
            },
            {
              "column": "Dateiname",
              "fieldValue": "={{ $json.Dateiname }}"
            },
            {
              "column": "OneDrive-Pfad",
              "fieldValue": "={{ $json['OneDrive-Pfad'] }}"
            },
            {
              "column": "Bemerkung",
              "fieldValue": "={{ $json.Bemerkung }}"
            }
          ]
        },
        "options": {}
      },
      "id": "b0def590-f132-4be2-93e7-d05e731b248d",
      "name": "Append to Excel",
      "type": "n8n-nodes-base.microsoftExcel",
      "typeVersion": 2.2,
      "position": [
        -8976,
        -4432
      ],
      "credentials": {
        "microsoftExcelOAuth2Api": {
          "id": "gn9O9iJYh6osoSAu",
          "name": "Microsoft Excel account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "/**\n * Resolve Folder ID + grab binary from Code in JavaScript (Prep Binary).\n */\nconst data = $('4. Process Invoice Data2').first().json;\nconst binary = $('4. Process Invoice Data2').first().binary;\n\nif (!binary || Object.keys(binary).length === 0) {\n  throw new Error('No binary found on Code in JavaScript node');\n}\n\nconst FOLDER_IDS = {\n  'PH_BUCH_NEG_VERB': '016ZC2UEJUEHAFZBDQIREKRW6B4DNP3QKF',\n  'PH_BUCH_MESS_VERB': '016ZC2UEM6DC6MEE63NFHLJLHSQHMLU5CF',\n  'PH_BUCH_ACI_VERB': '016ZC2UEP3LSHAURKU3NCLKPKAJFWKM5AF',\n  'PH_BUCH_APG_VERB': '016ZC2UENWAKPQSTKRDJBKZDBWK3C7YOQV',\n  'PH_BUCH_BSG_VERB': '016ZC2UELPDX5JGJUM6VCY34D2O5EYGRKQ',\n  'PH_BUCH_AFL_VERB': '016ZC2UEOWG7REOAB6RJELQQSQ4R5KIKMZ',\n  'PH_BUCH_B69_VERB': '016ZC2UELTVRUMWHFQPREYRIGDRQ7MOLVE',\n  'PH_BUCH_B69A_VERB': '016ZC2UEI3QZTGKBURINE2EIK7OP63WCZA',\n  'PH_BUCH_T42_VERB': '016ZC2UENMRHVI2YJM35FYYN6PSEK45PJA',\n  'PH_BUCH_R100_VERB': '016ZC2UEOF47VJQ6NNVVFZUET3EBGM25AU',\n  'PH_BUCH_B8_VERB': '016ZC2UEO7QW7XK2BIABEZ6VCSYXC5BJ2O',\n  'PH_BUCH_HR_VERB': '016ZC2UENZ2MJLITW2A5BLAV4TLEYNJA2U',\n  'PH_BUCH_HS_VERB': '016ZC2UEI6JKT3TTWI4RCJGG5PKCWJZILT',\n  'PH_BUCH_Z1_VERB': '016ZC2UEMQMAYIUMZTE5HKTNJDRYDVEBZW',\n  'PH_BUCH_HH_VERB': '016ZC2UEKTI2DUGSHH2BCIW72464RZPP7Y',\n  'PH_BUCH_GF4_VERB': '016ZC2UEJUQTMFP442H5HZWFYV6ZPUTR44',\n  'PH_BUCH_BJL_VERB': '016ZC2UEKYJLPG4FEFUZFY57S5A45NGOFU',\n  'PH_BUCH_BA66_VERB': '016ZC2UEKFQVM4BA47XBB2D5DSSZLUB6HI',\n  'PH_BUCH_GD15_VERB': '016ZC2UEM7GO46A6B6HNGJJCFFLCHPOWOJ',\n  'PH_BUCH_TG_VERB': '016ZC2UEM4GMV3MGTRFVHJME4O6KOUJJRS',\n  'PH_BUCH_GS_VERB': '016ZC2UEN6ZBYP4VCGINF2HO7NXY3YTXA6',\n  'PH_BUCH_E25_VERB': '016ZC2UEIW7XXAG5D6HFGYWXGQNV4I4E32',\n  'PH_BUCH_PB38_VERB': '016ZC2UEM5LP6NUF73HJGKRS4WYV64J5J6',\n  'PH_BUCH_SF_VERB': '016ZC2UEIFYLET6FCNS5CYOG6TT3ZJFKWZ',\n  'PH_BUCH_MN10_VERB': '016ZC2UEJLWZZHI2CIMVEZK56BYO7TWIJB'\n};\n\nconst verbFolderId = FOLDER_IDS[data.folderPlaceholder] || null;\n\nif (!verbFolderId) {\n  throw new Error(`No folder ID for: ${data.folderPlaceholder}`);\n}\n\nreturn {\n  json: {\n    ...data,\n    verbFolderId,\n    uploadPath: `${data.yearFolder}/${data.monthFolder}/${data.filename}`\n  },\n  binary: binary\n};"
      },
      "id": "88e06190-a171-4b34-8430-0b4ba48c64c1",
      "name": "Resolve Folder ID",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8752,
        -4432
      ]
    },
    {
      "parameters": {
        "fileName": "={{ $json.uploadPath || $('If').item.json.filename }}",
        "parentId": "={{ $json.verbFolderId || $('If').item.verbFolderId}}",
        "binaryData": true
      },
      "type": "n8n-nodes-base.microsoftOneDrive",
      "typeVersion": 1.1,
      "position": [
        -8064,
        -4416
      ],
      "id": "324dc1a2-220c-422a-9746-6f6edba93dd8",
      "name": "Upload a file",
      "credentials": {
        "microsoftOneDriveOAuth2Api": {
          "id": "Mk5WZaai042w3fQA",
          "name": "SAITS - Vansh"
        }
      }
    },
    {
      "parameters": {
        "resource": "worksheet",
        "operation": "append",
        "workbook": {
          "__rl": true,
          "value": "016ZC2UENNX3FINPJ7TBFJT6K37BFNTZJD",
          "mode": "list",
          "cachedResultName": "NEG_Rechnungseingangsbuch_Template 1",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
        },
        "worksheet": {
          "__rl": true,
          "value": "{00000000-0001-0000-0000-000000000000}",
          "mode": "list",
          "cachedResultName": "Rechnungseingangsbuch",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Rechnungseingangsbuch!A1"
        },
        "fieldsUi": {
          "values": [
            {
              "column": "Lfd. Nr.",
              "fieldValue": "={{ $('Append to Excel').first().json[\"Lfd. Nr.\"] }}"
            },
            {
              "column": "OneDrive-Pfad",
              "fieldValue": "={{ $('Resolve Folder ID').item.json.verbFolderId }}"
            }
          ]
        },
        "options": {}
      },
      "id": "0e2a9fde-6e9c-4073-8b4b-5c453a76c2b4",
      "name": "Append to Excel1",
      "type": "n8n-nodes-base.microsoftExcel",
      "typeVersion": 2.2,
      "position": [
        -7888,
        -4416
      ],
      "credentials": {
        "microsoftExcelOAuth2Api": {
          "id": "gn9O9iJYh6osoSAu",
          "name": "Microsoft Excel account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "ffa2ad6c-747c-46e5-a625-a585d3a96f43",
              "leftValue": "={{ $binary.data.mimeType}}",
              "rightValue": "pdf",
              "operator": {
                "type": "string",
                "operation": "notContains"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -8544,
        -4432
      ],
      "id": "f09ef075-6c6b-4152-9ab4-86dd93a9c40f",
      "name": "If"
    },
    {
      "parameters": {
        "name": "={{ $binary.data.fileName }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "options": {}
      },
      "name": "1. Upload Image to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -8352,
        -4656
      ],
      "id": "513f5131-a539-4df5-a1da-20351c5962c6",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "K4oMvzrnbNQ5KiuJ",
          "name": "Vansh - Personal"
        }
      }
    },
    {
      "parameters": {
        "operation": "share",
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        },
        "options": {}
      },
      "name": "2. Make Image Public",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -8128,
        -4656
      ],
      "id": "8029f83d-9bc5-4817-a9ee-edf55e0e3371",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "K4oMvzrnbNQ5KiuJ",
          "name": "Vansh - Personal"
        }
      }
    },
    {
      "parameters": {
        "operation": "copy",
        "fileId": {
          "__rl": true,
          "value": "1xQyvEz5Jlb7g-5S36sqSzJQ0oM15ofInvVSjHeaELKE",
          "mode": "id"
        },
        "name": "={{ $('1. Upload Image to Drive').item.json.name }} - PDF Formatted",
        "options": {}
      },
      "name": "3. Copy Slide Template",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -7920,
        -4656
      ],
      "id": "13570397-4fed-4008-9ff9-964cc0f3857b",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "K4oMvzrnbNQ5KiuJ",
          "name": "Vansh - Personal"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://slides.googleapis.com/v1/presentations/{{ $json.id }}:batchUpdate",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleSlidesOAuth2Api",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"requests\": [\n    {\n      \"createImage\": {\n        \"url\": \"{{ $('1. Upload Image to Drive').item.json.webContentLink }}\",\n        \"elementProperties\": {\n          \"pageObjectId\": \"p\"\n        }\n      }\n    }\n  ]\n}",
        "options": {}
      },
      "name": "4. Insert Image",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -7696,
        -4656
      ],
      "id": "bd8fd02f-3bce-4f2e-b177-d9ca78ddc863",
      "credentials": {
        "googleSlidesOAuth2Api": {
          "id": "oHsIkUNe76MhY8au",
          "name": "Google Slides account"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.presentationId }}",
          "mode": "id"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "slidesToFormat": "application/pdf"
            }
          }
        }
      },
      "name": "5. Download as PDF",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -7472,
        -4656
      ],
      "id": "692c02b8-4700-4128-bc1c-ff95e65f4795",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "K4oMvzrnbNQ5KiuJ",
          "name": "Vansh - Personal"
        }
      }
    },
    {
      "parameters": {
        "fileName": "={{ $json.uploadPath || $('If').item.json.filename }}",
        "parentId": "={{ $('If').item.json.verbFolderId }}",
        "binaryData": true
      },
      "type": "n8n-nodes-base.microsoftOneDrive",
      "typeVersion": 1.1,
      "position": [
        -7248,
        -4656
      ],
      "id": "003016f4-d6dc-4e7d-aa61-56ac2bf8a9c3",
      "name": "Upload a file1",
      "credentials": {
        "microsoftOneDriveOAuth2Api": {
          "id": "Mk5WZaai042w3fQA",
          "name": "SAITS - Vansh"
        }
      }
    },
    {
      "parameters": {
        "resource": "worksheet",
        "operation": "append",
        "workbook": {
          "__rl": true,
          "value": "016ZC2UENNX3FINPJ7TBFJT6K37BFNTZJD",
          "mode": "list",
          "cachedResultName": "NEG_Rechnungseingangsbuch_Template 1",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
        },
        "worksheet": {
          "__rl": true,
          "value": "{00000000-0001-0000-0000-000000000000}",
          "mode": "list",
          "cachedResultName": "Rechnungseingangsbuch",
          "cachedResultUrl": "https://rschroedergmbh-my.sharepoint.com/personal/va_saits_ai/_layouts/15/Doc.aspx?sourcedoc=%7B86CABEAD-3FBD-4A98-99F9-5BF84AD9E523%7D&file=NEG_Rechnungseingangsbuch_Template%201.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Rechnungseingangsbuch!A1"
        },
        "fieldsUi": {
          "values": [
            {
              "column": "Lfd. Nr.",
              "fieldValue": "={{ $('Append to Excel').first().json[\"Lfd. Nr.\"] }}"
            },
            {
              "column": "OneDrive-Pfad",
              "fieldValue": "={{ $('Resolve Folder ID').item.json.verbFolderId }}"
            }
          ]
        },
        "options": {}
      },
      "id": "e2df4ca1-0f06-4be0-9cbf-468d62c1b281",
      "name": "Append to Excel2",
      "type": "n8n-nodes-base.microsoftExcel",
      "typeVersion": 2.2,
      "position": [
        -7072,
        -4656
      ],
      "credentials": {
        "microsoftExcelOAuth2Api": {
          "id": "gn9O9iJYh6osoSAu",
          "name": "Microsoft Excel account"
        }
      }
    }
  ],
  "connections": {
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "4. Process Invoice Data2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Split Attachments": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Attachments?": {
      "main": [
        [
          {
            "node": "2. Split Attachments",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip - No Attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Check Invoice Emails": {
      "main": [
        [
          {
            "node": "Has Attachments?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "3. OCR Invoice (Azure)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. OCR Invoice (Azure)1": {
      "main": [
        [
          {
            "node": "Wait for OCR1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for OCR1": {
      "main": [
        [
          {
            "node": "Get OCR Result1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get OCR Result1": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Process Invoice Data2": {
      "main": [
        [
          {
            "node": "Map to Excel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Vendor Known?2": {
      "main": [
        [
          {
            "node": "5. Create Digital Stamp (PDF)1",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Notify Unknown Vendor2": {
      "main": [
        []
      ]
    },
    "5. Create Digital Stamp (PDF)1": {
      "main": [
        [
          {
            "node": "6. Convert to PDF1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. Convert to PDF1": {
      "main": [
        [
          {
            "node": "7. Get Invoice & Stamp1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. Get Invoice & Stamp1": {
      "main": [
        [
          {
            "node": "8. Combine PDFs1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "4. Process Invoice Data2",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Map to Excel": {
      "main": [
        [
          {
            "node": "Append to Excel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append to Excel": {
      "main": [
        [
          {
            "node": "Resolve Folder ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolve Folder ID": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload a file": {
      "main": [
        [
          {
            "node": "Append to Excel1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "1. Upload Image to Drive",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Upload a file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Upload Image to Drive": {
      "main": [
        [
          {
            "node": "2. Make Image Public",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Make Image Public": {
      "main": [
        [
          {
            "node": "3. Copy Slide Template",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. Copy Slide Template": {
      "main": [
        [
          {
            "node": "4. Insert Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Insert Image": {
      "main": [
        [
          {
            "node": "5. Download as PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5. Download as PDF": {
      "main": [
        [
          {
            "node": "Upload a file1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload a file1": {
      "main": [
        [
          {
            "node": "Append to Excel2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {
    "1. Check Invoice Emails": [
      {
        "id": "AAMkAGI2OWYxNmFmLTVhZTQtNDBlMC1hNzJlLTdhYjRhYjBjMWE3MgBGAAAAAAA0Jh3K3BATTYuqRWm7397zBwAosyxhc1KDQLAZyjPgKmn9AAAAAAEMAAAosyxhc1KDQLAZyjPgKmn9AAABvdpjAAA=",
        "conversationId": "AAQkAGI2OWYxNmFmLTVhZTQtNDBlMC1hNzJlLTdhYjRhYjBjMWE3MgAQAFm8ikBFWJ1Fl9RX-dMf3Jw=",
        "subject": "test",
        "bodyPreview": "",
        "from": "va@saits.ai",
        "to": [
          "rechnung@neg.ag"
        ],
        "categories": [],
        "hasAttachments": true
      }
    ]
  },
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "9c1de76795e8803a2ffa944dee021ff74564866a2c2ffdc6044fed6d9556cfc1"
  }
}