المصروفات الشهرية حسب البند، بالبريد إلى محاسبك

في أول كل شهر، اجمع مصروفات الشهر الماضي حسب البند وأرسل الملخص إلى محاسبك.

سهل توفّر ~2 ساعة شهريًا المالية والإدارةبواسطة فريق Flowngn

تعمل مع n8n · Make · Zapier

كيف تعمل

المشغّل: جدول زمني — أول كل شهر الساعة 9:00
  1. اقرأ جدول Expenses (التاريخ، المبلغ، البند).
  2. اجمع الشهر الماضي حسب البند مع نسبة كل بند.
  3. أرسل الملخص إلى محاسبك.

المخطط

1st of the month 9:…Schedule TriggerGRead expensesGoogle Sheets{ }Total by categoryCodeGEmail accountantGmail
مشغّل تطبيق كود

الكود

كود JavaScript المستخدم في خطوات Code، وهو مضمَّن بالفعل في القالب بالأسفل.

Total by category · عقدة Code
// Expenses sheet columns: date (YYYY-MM-DD) | amount | category | description
// Totals last month's expenses by category for the accountant email.
const now = new Date();
const first = new Date(now.getFullYear(), now.getMonth() - 1, 1);
const month = `${first.getFullYear()}-${String(first.getMonth() + 1).padStart(2, "0")}`;
const label = first.toLocaleString("en-US", { month: "long", year: "numeric" });

const totals = {};
let total = 0;
for (const { json: e } of $input.all()) {
  if (String(e.date).slice(0, 7) !== month) continue;
  const amount = Number(String(e.amount).replace(/[^0-9.-]/g, "")) || 0;
  const cat = e.category || "Other";
  totals[cat] = (totals[cat] || 0) + amount;
  total += amount;
}

const fmt = (n) => n.toLocaleString("en-US", { maximumFractionDigits: 2 });
const lines = Object.entries(totals)
  .sort((a, b) => b[1] - a[1])
  .map(([cat, sum]) => `${cat}: ${fmt(sum)} (${Math.round((sum / total) * 100)}%)`);

return [{
  json: {
    subject: `Expenses for ${label}: ${fmt(total)}`,
    body:
      `Hi,\n\nHere are our expenses for ${label} by category:\n\n${lines.join("\n") || "No expenses recorded."}\n\n` +
      `Total: ${fmt(total)}\n\nThe full list is in the Expenses sheet.\n\nThanks`,
  },
}];

ابنِها بأداتك

اختر أداتك — نفس الأتمتة، خطوة بخطوة.

انسخه والصقه مباشرة في مساحة عمل n8n (Ctrl+V)، أو حمّله واستخدم Import from File. بعد ذلك اربط حساباتك واستبدل كل قيمة تبدأ بـ YOUR_.

ملف Workflow JSON
عرض الكود (139 سطر)
{
  "name": "المصروفات الشهرية حسب البند، بالبريد إلى محاسبك (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## المصروفات الشهرية حسب البند، بالبريد إلى محاسبك\nفي أول كل شهر، اجمع مصروفات الشهر الماضي حسب البند وأرسل الملخص إلى محاسبك.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "2f780998-9838-445d-a923-1c16b94b02ed",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 1 * *"
            }
          ]
        }
      },
      "id": "2f780998-9838-445d-a923-1c16b94b02ed",
      "name": "1st of the month 9:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Expenses",
          "mode": "name"
        },
        "options": {}
      },
      "id": "2f780998-9838-445d-a923-1c16b94b02ed",
      "name": "Read expenses",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Expenses sheet columns: date (YYYY-MM-DD) | amount | category | description\n// Totals last month's expenses by category for the accountant email.\nconst now = new Date();\nconst first = new Date(now.getFullYear(), now.getMonth() - 1, 1);\nconst month = `${first.getFullYear()}-${String(first.getMonth() + 1).padStart(2, \"0\")}`;\nconst label = first.toLocaleString(\"en-US\", { month: \"long\", year: \"numeric\" });\n\nconst totals = {};\nlet total = 0;\nfor (const { json: e } of $input.all()) {\n  if (String(e.date).slice(0, 7) !== month) continue;\n  const amount = Number(String(e.amount).replace(/[^0-9.-]/g, \"\")) || 0;\n  const cat = e.category || \"Other\";\n  totals[cat] = (totals[cat] || 0) + amount;\n  total += amount;\n}\n\nconst fmt = (n) => n.toLocaleString(\"en-US\", { maximumFractionDigits: 2 });\nconst lines = Object.entries(totals)\n  .sort((a, b) => b[1] - a[1])\n  .map(([cat, sum]) => `${cat}: ${fmt(sum)} (${Math.round((sum / total) * 100)}%)`);\n\nreturn [{\n  json: {\n    subject: `Expenses for ${label}: ${fmt(total)}`,\n    body:\n      `Hi,\\n\\nHere are our expenses for ${label} by category:\\n\\n${lines.join(\"\\n\") || \"No expenses recorded.\"}\\n\\n` +\n      `Total: ${fmt(total)}\\n\\nThe full list is in the Expenses sheet.\\n\\nThanks`,\n  },\n}];"
      },
      "id": "2f780998-9838-445d-a923-1c16b94b02ed",
      "name": "Total by category",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "sendTo": "accountant@example.com",
        "subject": "={{ $json.subject }}",
        "emailType": "text",
        "message": "={{ $json.body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "2f780998-9838-445d-a923-1c16b94b02ed",
      "name": "Email accountant",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "1st of the month 9:00": {
      "main": [
        [
          {
            "node": "Read expenses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read expenses": {
      "main": [
        [
          {
            "node": "Total by category",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Total by category": {
      "main": [
        [
          {
            "node": "Email accountant",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

← افتحها في ساحة التجربة لتعديلها

نصائح

  • يعمل جيدًا مع أتمتة تتبع المصروفات على تيليجرام ورسائل البنك، فهي تملأ نفس الجدول.

أتمتات مشابهة