Rapport Google

Avancé

Ceci est unDocument Extraction, AI Chatbotworkflow d'automatisation du domainecontenant 26 nœuds.Utilise principalement des nœuds comme Set, Code, Merge, Aggregate, GoogleSheets. Générer des rapports financiers multi-périodes à partir de Google Sheets avec analyse IA

Prérequis
  • Informations d'identification Google Sheets API
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "p3BhWvtYryFCnIMZ",
  "meta": {
    "instanceId": "eb2e35a6e4ba3ff63ef980c031da61d993b4f2faa0ccc19283b4ab43f9ca13e6"
  },
  "name": "Google Report",
  "tags": [],
  "nodes": [
    {
      "id": "de33033e-aff3-4999-8c76-f586716a8b50",
      "name": "Modèle de Chat DeepSeek",
      "type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
      "position": [
        -360,
        340
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "deepSeekApi": {
          "id": "FiU3VouUwvrGU8CJ",
          "name": "DeepSeek account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "030b27e4-55c0-478d-b401-aca4c9aa14a8",
      "name": "Mémoire Tampon Fenêtre1",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -240,
        360
      ],
      "parameters": {},
      "typeVersion": 1.3
    },
    {
      "id": "c504a6ec-0783-4a36-bdbf-45e5b11963f9",
      "name": "Appeler l'outil de workflow n8n",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        -80,
        360
      ],
      "parameters": {
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "4ASVA3i1vaFwj20h",
          "cachedResultName": "Sub flowBao cao doanh thu"
        },
        "workflowInputs": {
          "value": {
            "End_Current": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_Current', ``, 'string') }}",
            "End_LastYear": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_LastYear', ``, 'string') }}",
            "End_LastMonth": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_LastMonth', ``, 'string') }}",
            "Start_Current": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Current', ``, 'string') }}",
            "Start_LastYear": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_LastYear', ``, 'string') }}",
            "Start_LastMonth": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_LastMonth', ``, 'string') }}"
          },
          "schema": [
            {
              "id": "Start_Current",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start_Current",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End_Current",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End_Current",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Start_LastMonth",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start_LastMonth",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End_LastMonth",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End_LastMonth",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Start_LastYear",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start_LastYear",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End_LastYear",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End_LastYear",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "99e1edc5-f43f-4c1b-8649-99b77ac6479c",
      "name": "Lors de la réception d'un message chat",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -600,
        100
      ],
      "webhookId": "fbf93f24-cc03-4c72-9b6f-5d441f3b097c",
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "0eeaa722-fdf0-4afd-a837-94d26e14c1dd",
      "name": "Agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -300,
        100
      ],
      "parameters": {
        "options": {
          "systemMessage": "=You are the company accountant. Summarize revenue and expense information from the tool, evaluate, compare, and respond accordingly. You are required to provide all information for reporting purposes, including:\n\nStart date (Start_Current),\n\nEnd date (End_Current),\n\nStart date of last month,\n\nEnd date of last month,\n\nStart of last year,\n\nEnd of last year\n\nAll dates must be in the format dd/Mm/yyyy.\n\nGenerate the output as JSON in the format without showing it in the chat, for json format example:\n\n{\n  \"Start_Current\": \"01/07/2025\",\n  \"End_Current\": \"31/07/2025\",\n  \"Start_LastMonth\": \"01/06/2025\",\n  \"End_LastMonth\": \"30/06/2025\",\n  \"Start_LastYear\": \"01/01/2024\",\n  \"End_LastYear\": \"31/12/20"
        },
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "934c56a4-7534-4add-8095-1f085256af7a",
      "name": "Note autocollante",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -360,
        700
      ],
      "parameters": {
        "color": 6,
        "width": 2340,
        "height": 1180,
        "content": "## Sub-Workflow: Google Analytics Data"
      },
      "typeVersion": 1
    },
    {
      "id": "4140bc3a-d19a-4274-8ba4-84f7334a46e7",
      "name": "Lors de l'exécution par un autre workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -100,
        1100
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "Start_Current"
            },
            {
              "name": "End_Current"
            },
            {
              "name": "Start_LastMonth"
            },
            {
              "name": "End_LastMonth"
            },
            {
              "name": "Start_LastYear"
            },
            {
              "name": "End_LastYear"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "8bf4a0f4-1b40-4ac1-8138-6c831f6003e1",
      "name": "Formater la date",
      "type": "n8n-nodes-base.set",
      "position": [
        60,
        1100
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "7bbe88fb-9866-4bae-8db4-48be473fa179",
              "name": "Start_Current",
              "type": "string",
              "value": "={{ $json.Start_Current }}"
            },
            {
              "id": "7566ba91-566f-4a1e-8e85-af9d7975f266",
              "name": "End_Current",
              "type": "string",
              "value": "={{ $json.End_Current }}"
            },
            {
              "id": "db654f49-36d6-48da-9189-ff536bedd21e",
              "name": "Start_LastMonth",
              "type": "string",
              "value": "={{ $json.Start_LastMonth }}"
            },
            {
              "id": "5d708106-3c8f-4a73-b5d2-62fc93fe42f5",
              "name": "End_LastMonth",
              "type": "string",
              "value": "={{ $json.End_LastMonth }}"
            },
            {
              "id": "e4c9946c-21c0-48aa-8327-7135eaf2c4b2",
              "name": "Start_LastYear",
              "type": "string",
              "value": "={{ $json.Start_LastYear }}"
            },
            {
              "id": "38afadf2-7d8d-45d1-9ab0-970ca1497f8f",
              "name": "End_LastYear",
              "type": "string",
              "value": "={{ $json.End_LastYear }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "7fc2f2eb-b4d5-4ea3-bc18-e0324d65c826",
      "name": "Obtenir les revenus de la feuille google",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        340,
        1100
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1168390826,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1UAMO24QtfkR50VGu1wpksuYiWffi28pHfm6bihd5IP8/edit#gid=1168390826",
          "cachedResultName": "Doanh thu theo ngày"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1UAMO24QtfkR50VGu1wpksuYiWffi28pHfm6bihd5IP8",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1UAMO24QtfkR50VGu1wpksuYiWffi28pHfm6bihd5IP8/edit?usp=drivesdk",
          "cachedResultName": "Data Bao cao kinh doanh"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "0Zfrl7z70DMniz8b",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "91092c78-4d3a-478f-b42d-c92c86595f9e",
      "name": "Pivot dernier cycle",
      "type": "n8n-nodes-base.code",
      "onError": "continueRegularOutput",
      "position": [
        540,
        1260
      ],
      "parameters": {
        "jsCode": "// Lấy Start_LastMonth và End_LastMonth từ node Format Date\nconst startCurrentRaw = $('Format Date').first().json.Start_LastMonth;\nconst endCurrentRaw = $('Format Date').first().json.End_LastMonth;\n\n// Debug: In ra giá trị thô của Start_LastMonth và End_LastMonth\nconsole.log('Start Current Raw:', startCurrentRaw);\nconsole.log('End Current Raw:', endCurrentRaw);\n\n// Hàm chuyển đổi định dạng ngày DD/MM/YYYY hoặc YYYY-MM-DD thành Date object\nfunction parseDate(dateStr) {\n  if (!dateStr || typeof dateStr !== 'string') {\n    console.log('Invalid date string:', dateStr);\n    return null;\n  }\n  if (dateStr.includes('/')) {\n    const [day, month, year] = dateStr.split('/').map(Number);\n    return new Date(year, month - 1, day);\n  } else if (dateStr.includes('-')) {\n    return new Date(dateStr);\n  }\n  console.log('Unrecognized date format:', dateStr);\n  return null;\n}\n\n// Chuyển đổi Start_LastMonth và End_LastMonth thành Date object\nconst startCurrent = parseDate(startCurrentRaw);\nconst endCurrent = parseDate(endCurrentRaw);\n\n// Debug: In ra giá trị sau khi chuyển đổi\nconsole.log('Start Current Parsed:', startCurrent);\nconsole.log('End Current Parsed:', endCurrent);\n\n// Kiểm tra nếu Start_LastMonth hoặc End_LastMonth không hợp lệ\nif (!startCurrent || !endCurrent) {\n  throw new Error('Invalid Start_LastMonth or End_LastMonth date format');\n}\n\n// Tạo một object để lưu trữ tổng Số tiền theo Phân loại\nconst aggregatedData = {};\n\n// Hàm chuẩn hóa chuỗi: loại bỏ khoảng trắng thừa và chuyển về chữ thường\nfunction normalizeString(str) {\n  return str ? str.trim().toLowerCase() : '';\n}\n\n// Lọc và tính tổng\nfor (const item of $input.all()) {\n  // Chuyển Date từ định dạng DD/MM/YYYY hoặc YYYY-MM-DD thành Date object\n  const itemDate = parseDate(item.json.Date);\n\n  if (!itemDate) {\n    console.log('Skipping item due to invalid date:', item.json);\n    continue;\n  }\n\n  const amount = Number(item.json['Số tiền']) || 0;\n\n  // Kiểm tra nếu Date nằm trong khoảng Start_LastMonth và End_LastMonth\n  if (itemDate >= startCurrent && itemDate <= endCurrent) {\n    // Chuẩn hóa Phân loại trước khi tạo key\n    const phanLoai = normalizeString(item.json['Phân loại']);\n\n    // Tạo key duy nhất từ Phân loại\n    const key = phanLoai;\n\n    // Debug: In ra key để kiểm tra\n    console.log('Key:', key);\n\n    // Nếu key chưa tồn tại, khởi tạo giá trị ban đầu\n    if (!aggregatedData[key]) {\n      aggregatedData[key] = {\n        'Phân loại': item.json['Phân loại'], // Giữ nguyên giá trị gốc để hiển thị\n        'Tổng số tiền': 0\n      };\n    }\n\n    // Cộng dồn Số tiền vào Tổng số tiền\n    aggregatedData[key]['Tổng số tiền'] += amount;\n  }\n}\n\n// Debug: In ra số lượng nhóm và dữ liệu đã gộp\nconsole.log('Number of groups:', Object.keys(aggregatedData).length);\nconsole.log('Aggregated Data:', aggregatedData);\n\n// Chuyển object aggregatedData thành mảng để trả về\nconst result = Object.values(aggregatedData);\n\nreturn result.map(item => ({ json: item }));"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "03bf6db2-3d53-4507-b286-0b166e8ab8a3",
      "name": "Pivot cycle actuel",
      "type": "n8n-nodes-base.code",
      "onError": "continueRegularOutput",
      "position": [
        480,
        940
      ],
      "parameters": {
        "jsCode": "// Lấy Start_Current và End_Current từ node Format Date\nconst startCurrentRaw = $('Format Date').first().json.Start_Current;\nconst endCurrentRaw = $('Format Date').first().json.End_Current;\n\n// Debug: In ra giá trị thô của Start_Current và End_Current\nconsole.log('Start Current Raw:', startCurrentRaw);\nconsole.log('End Current Raw:', endCurrentRaw);\n\n// Hàm chuyển đổi định dạng ngày DD/MM/YYYY hoặc YYYY-MM-DD thành Date object\nfunction parseDate(dateStr) {\n  if (!dateStr || typeof dateStr !== 'string') {\n    console.log('Invalid date string:', dateStr);\n    return null;\n  }\n  if (dateStr.includes('/')) {\n    const [day, month, year] = dateStr.split('/').map(Number);\n    return new Date(year, month - 1, day);\n  } else if (dateStr.includes('-')) {\n    return new Date(dateStr);\n  }\n  console.log('Unrecognized date format:', dateStr);\n  return null;\n}\n\n// Chuyển đổi Start_Current và End_Current thành Date object\nconst startCurrent = parseDate(startCurrentRaw);\nconst endCurrent = parseDate(endCurrentRaw);\n\n// Debug: In ra giá trị sau khi chuyển đổi\nconsole.log('Start Current Parsed:', startCurrent);\nconsole.log('End Current Parsed:', endCurrent);\n\n// Kiểm tra nếu Start_Current hoặc End_Current không hợp lệ\nif (!startCurrent || !endCurrent) {\n  throw new Error('Invalid Start_Current or End_Current date format');\n}\n\n// Tạo một object để lưu trữ tổng Số tiền theo Phân loại\nconst aggregatedData = {};\n\n// Hàm chuẩn hóa chuỗi: loại bỏ khoảng trắng thừa và chuyển về chữ thường\nfunction normalizeString(str) {\n  return str ? str.trim().toLowerCase() : '';\n}\n\n// Lọc và tính tổng\nfor (const item of $input.all()) {\n  // Chuyển Date từ định dạng DD/MM/YYYY hoặc YYYY-MM-DD thành Date object\n  const itemDate = parseDate(item.json.Date);\n\n  if (!itemDate) {\n    console.log('Skipping item due to invalid date:', item.json);\n    continue;\n  }\n\n  const amount = Number(item.json['Số tiền']) || 0;\n\n  // Kiểm tra nếu Date nằm trong khoảng Start_Current và End_Current\n  if (itemDate >= startCurrent && itemDate <= endCurrent) {\n    // Chuẩn hóa Phân loại trước khi tạo key\n    const phanLoai = normalizeString(item.json['Phân loại']);\n\n    // Tạo key duy nhất từ Phân loại\n    const key = phanLoai;\n\n    // Debug: In ra key để kiểm tra\n    console.log('Key:', key);\n\n    // Nếu key chưa tồn tại, khởi tạo giá trị ban đầu\n    if (!aggregatedData[key]) {\n      aggregatedData[key] = {\n        'Phân loại': item.json['Phân loại'], // Giữ nguyên giá trị gốc để hiển thị\n        'Tổng số tiền': 0\n      };\n    }\n\n    // Cộng dồn Số tiền vào Tổng số tiền\n    aggregatedData[key]['Tổng số tiền'] += amount;\n  }\n}\n\n// Debug: In ra số lượng nhóm và dữ liệu đã gộp\nconsole.log('Number of groups:', Object.keys(aggregatedData).length);\nconsole.log('Aggregated Data:', aggregatedData);\n\n// Chuyển object aggregatedData thành mảng để trả về\nconst result = Object.values(aggregatedData);\n\nreturn result.map(item => ({ json: item }));"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "aa5957fa-35a9-42a2-8c47-cdff23f9e683",
      "name": "Formater les données du cycle actuel",
      "type": "n8n-nodes-base.set",
      "position": [
        700,
        780
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "657e8f86-3f7e-44d0-9428-4150ec0b5e59",
              "name": "currentCycle.startDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.Start_Current }}"
            },
            {
              "id": "e2b7aa83-66d2-4579-9f1b-1cfa08d08f3c",
              "name": "currentCycle.endDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.End_Current }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "82656e1d-2361-4ce1-b28d-19c7469abc99",
      "name": "Somme cycle actuel",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        700,
        940
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "f13eaa1b-bd70-4ee2-a588-e633c5a73c65",
      "name": "Formater les données du dernier cycle",
      "type": "n8n-nodes-base.set",
      "position": [
        720,
        1100
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "657e8f86-3f7e-44d0-9428-4150ec0b5e59",
              "name": "lastMonthCycle.startDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.Start_LastMonth }}"
            },
            {
              "id": "e2b7aa83-66d2-4579-9f1b-1cfa08d08f3c",
              "name": "lastMonthCycle.endDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.End_LastMonth }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6377a403-c89b-4a21-928a-077ee5106019",
      "name": "Somme dernier cycle",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        720,
        1260
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "4fe96658-e302-42a8-8eba-9e059c3583bf",
      "name": "Somme des données du mois de transfert précédent",
      "type": "n8n-nodes-base.merge",
      "position": [
        960,
        1180
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "d2c5d065-a199-4551-a3f5-fb21994186a3",
      "name": "Somme des données du mois de transfert actuel",
      "type": "n8n-nodes-base.merge",
      "position": [
        960,
        800
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "fa5e3abc-df57-4140-a68e-f328b33b6bd6",
      "name": "Modifier le titre 1",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1180,
        800
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "Chu kỳ hiện tại"
      },
      "typeVersion": 1
    },
    {
      "id": "cabe2138-71bb-4b40-add9-f9ac8f7b7f55",
      "name": "Modifier le titre 2",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1180,
        1180
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "Chu kỳ tháng trước"
      },
      "typeVersion": 1
    },
    {
      "id": "db552cf2-6f91-44ee-aa37-84d3753b983c",
      "name": "Tout collecter",
      "type": "n8n-nodes-base.merge",
      "position": [
        1520,
        1180
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.1
    },
    {
      "id": "dcc23ef7-3e1c-4aa5-aee8-dcfc06ee0097",
      "name": "Modifier le titre du résultat",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1740,
        1180
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "data doanh thu"
      },
      "typeVersion": 1
    },
    {
      "id": "e17379be-782f-4c9f-bbd4-b99e8b844613",
      "name": "Formater les données du cycle année précédente",
      "type": "n8n-nodes-base.set",
      "position": [
        720,
        1480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "657e8f86-3f7e-44d0-9428-4150ec0b5e59",
              "name": "lastYearCycle.startDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.Start_LastYear }}"
            },
            {
              "id": "e2b7aa83-66d2-4579-9f1b-1cfa08d08f3c",
              "name": "lastYearCycle.endDate",
              "type": "string",
              "value": "={{ $('Format Date').item.json.End_LastYear }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ef07c8d5-7bb8-41b3-bf52-4d6dd73e1c8c",
      "name": "Pivot cycle année précédente",
      "type": "n8n-nodes-base.code",
      "onError": "continueRegularOutput",
      "position": [
        500,
        1680
      ],
      "parameters": {
        "jsCode": "// Get Start_LastYear and End_LastYear from node Format Date\nconst startCurrentRaw = $('Format Date').first().json.Start_LastYear;\nconst endCurrentRaw = $('Format Date').first().json.End_LastYear;\n\n// Debug: Start_LastYear and End_LastYear\nconsole.log('Start Current Raw:', startCurrentRaw);\nconsole.log('End Current Raw:', endCurrentRaw);\n\n// format DD/MM/YYYY or YYYY-MM-DD to Date object\nfunction parseDate(dateStr) {\n  if (!dateStr || typeof dateStr !== 'string') {\n    console.log('Invalid date string:', dateStr);\n    return null;\n  }\n  if (dateStr.includes('/')) {\n    const [day, month, year] = dateStr.split('/').map(Number);\n    return new Date(year, month - 1, day);\n  } else if (dateStr.includes('-')) {\n    return new Date(dateStr);\n  }\n  console.log('Unrecognized date format:', dateStr);\n  return null;\n}\n\n// change Start_LastYear and End_LastYear to Date object\nconst startCurrent = parseDate(startCurrentRaw);\nconst endCurrent = parseDate(endCurrentRaw);\n\n// Debug: print\nconsole.log('Start Current Parsed:', startCurrent);\nconsole.log('End Current Parsed:', endCurrent);\n\n// Validate Start_LastYear or End_LastYear\nif (!startCurrent || !endCurrent) {\n  throw new Error('Invalid Start_LastYear or End_LastYear date format');\n}\n\n// Create object Sum by Type\nconst aggregatedData = {};\n\n// trim\nfunction normalizeString(str) {\n  return str ? str.trim().toLowerCase() : '';\n}\n\n// Filter and summary\nfor (const item of $input.all()) {\n  // Format DD/MM/YYYY or YYYY-MM-DD to Date object\n  const itemDate = parseDate(item.json.Date);\n\n  if (!itemDate) {\n    console.log('Skipping item due to invalid date:', item.json);\n    continue;\n  }\n\n  const amount = Number(item.json['Số tiền']) || 0;\n\n  // Validate Date between Start_LastYear and End_LastYear\n  if (itemDate >= startCurrent && itemDate <= endCurrent) {\n    // Format\n    const phanLoai = normalizeString(item.json['Phân loại']);\n\n    // create key\n    const key = phanLoai;\n\n    // Debug: print\n    console.log('Key:', key);\n\n    // Check\n    if (!aggregatedData[key]) {\n      aggregatedData[key] = {\n        'Phân loại': item.json['Phân loại'], // Keep\n        'Tổng số tiền': 0\n      };\n    }\n\n    // Add to Sum amount\n    aggregatedData[key]['Tổng số tiền'] += amount;\n  }\n}\n\n// Debug: print\nconsole.log('Number of groups:', Object.keys(aggregatedData).length);\nconsole.log('Aggregated Data:', aggregatedData);\n\n// Format object aggregatedData to array\nconst result = Object.values(aggregatedData);\n\nreturn result.map(item => ({ json: item }));"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "c5695aff-f725-4dd1-8f5f-61c37cc3fb06",
      "name": "Somme cycle année précédente",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        720,
        1680
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "ed643ebd-1524-4af4-b1ba-0ddd705460c8",
      "name": "Ajouter les données de l'année précédente",
      "type": "n8n-nodes-base.merge",
      "position": [
        960,
        1620
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "10b6ecab-05b6-4cb9-ae6f-1e6d242f7a96",
      "name": "Modifier le titre",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1180,
        1620
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "Chu kỳ năm trước"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "eec79b51-8f52-447f-9890-59c12f6b7eb6",
  "connections": {
    "db552cf2-6f91-44ee-aa37-84d3753b983c": {
      "main": [
        [
          {
            "node": "dcc23ef7-3e1c-4aa5-aee8-dcfc06ee0097",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8bf4a0f4-1b40-4ac1-8138-6c831f6003e1": {
      "main": [
        [
          {
            "node": "7fc2f2eb-b4d5-4ea3-bc18-e0324d65c826",
            "type": "main",
            "index": 0
          },
          {
            "node": "aa5957fa-35a9-42a2-8c47-cdff23f9e683",
            "type": "main",
            "index": 0
          },
          {
            "node": "f13eaa1b-bd70-4ee2-a588-e633c5a73c65",
            "type": "main",
            "index": 0
          },
          {
            "node": "e17379be-782f-4c9f-bbd4-b99e8b844613",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10b6ecab-05b6-4cb9-ae6f-1e6d242f7a96": {
      "main": [
        [
          {
            "node": "db552cf2-6f91-44ee-aa37-84d3753b983c",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "fa5e3abc-df57-4140-a68e-f328b33b6bd6": {
      "main": [
        [
          {
            "node": "db552cf2-6f91-44ee-aa37-84d3753b983c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cabe2138-71bb-4b40-add9-f9ac8f7b7f55": {
      "main": [
        [
          {
            "node": "db552cf2-6f91-44ee-aa37-84d3753b983c",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "6377a403-c89b-4a21-928a-077ee5106019": {
      "main": [
        [
          {
            "node": "4fe96658-e302-42a8-8eba-9e059c3583bf",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "91092c78-4d3a-478f-b42d-c92c86595f9e": {
      "main": [
        [
          {
            "node": "6377a403-c89b-4a21-928a-077ee5106019",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ed643ebd-1524-4af4-b1ba-0ddd705460c8": {
      "main": [
        [
          {
            "node": "10b6ecab-05b6-4cb9-ae6f-1e6d242f7a96",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "82656e1d-2361-4ce1-b28d-19c7469abc99": {
      "main": [
        [
          {
            "node": "d2c5d065-a199-4551-a3f5-fb21994186a3",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "de33033e-aff3-4999-8c76-f586716a8b50": {
      "ai_languageModel": [
        [
          {
            "node": "0eeaa722-fdf0-4afd-a837-94d26e14c1dd",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "03bf6db2-3d53-4507-b286-0b166e8ab8a3": {
      "main": [
        [
          {
            "node": "82656e1d-2361-4ce1-b28d-19c7469abc99",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c5695aff-f725-4dd1-8f5f-61c37cc3fb06": {
      "main": [
        [
          {
            "node": "ed643ebd-1524-4af4-b1ba-0ddd705460c8",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "ef07c8d5-7bb8-41b3-bf52-4d6dd73e1c8c": {
      "main": [
        [
          {
            "node": "c5695aff-f725-4dd1-8f5f-61c37cc3fb06",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "030b27e4-55c0-478d-b401-aca4c9aa14a8": {
      "ai_memory": [
        [
          {
            "node": "0eeaa722-fdf0-4afd-a837-94d26e14c1dd",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "c504a6ec-0783-4a36-bdbf-45e5b11963f9": {
      "ai_tool": [
        [
          {
            "node": "0eeaa722-fdf0-4afd-a837-94d26e14c1dd",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "f13eaa1b-bd70-4ee2-a588-e633c5a73c65": {
      "main": [
        [
          {
            "node": "4fe96658-e302-42a8-8eba-9e059c3583bf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "aa5957fa-35a9-42a2-8c47-cdff23f9e683": {
      "main": [
        [
          {
            "node": "d2c5d065-a199-4551-a3f5-fb21994186a3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "99e1edc5-f43f-4c1b-8649-99b77ac6479c": {
      "main": [
        [
          {
            "node": "0eeaa722-fdf0-4afd-a837-94d26e14c1dd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e17379be-782f-4c9f-bbd4-b99e8b844613": {
      "main": [
        [
          {
            "node": "ed643ebd-1524-4af4-b1ba-0ddd705460c8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4fe96658-e302-42a8-8eba-9e059c3583bf": {
      "main": [
        [
          {
            "node": "cabe2138-71bb-4b40-add9-f9ac8f7b7f55",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7fc2f2eb-b4d5-4ea3-bc18-e0324d65c826": {
      "main": [
        [
          {
            "node": "03bf6db2-3d53-4507-b286-0b166e8ab8a3",
            "type": "main",
            "index": 0
          },
          {
            "node": "91092c78-4d3a-478f-b42d-c92c86595f9e",
            "type": "main",
            "index": 0
          },
          {
            "node": "ef07c8d5-7bb8-41b3-bf52-4d6dd73e1c8c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d2c5d065-a199-4551-a3f5-fb21994186a3": {
      "main": [
        [
          {
            "node": "fa5e3abc-df57-4140-a68e-f328b33b6bd6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4140bc3a-d19a-4274-8ba4-84f7334a46e7": {
      "main": [
        [
          {
            "node": "8bf4a0f4-1b40-4ac1-8138-6c831f6003e1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Extraction de documents, Chatbot IA

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds26
Catégorie2
Types de nœuds12
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34