Drupal is a registered trademark of Dries Buytaert
Release: Leaflet 10.4.11 Minor update available for module leaflet (10.4.11). Release: Session Inspector 1.0.8 Minor update available for module session_inspector (1.0.8). Release: Migrate QA 2.0.4 Minor update available for module migrate_qa (2.0.4). Release: CKEditor Description List 3.0.0 Major update available for module ckeditor_descriptionlist (3.0.0). Release: FlowDrop 2.4.0 Minor update available for module flowdrop (2.4.0). Release: JWT Token Refresh 1.0.4 Minor update available for module jwt_token_refresh (1.0.4). Release: ConReg 1.0.0-beta1 First beta version released for module conreg (1.0.0-beta1). Release: AI Image Studio 1.0.0-beta8 New beta version released for module ai_image_studio (1.0.0-beta8). Usage Milestone: Statistics Counter Module statistics_counter crossed 1,000 active installs. Module Revived: Decoupled Router 2.0.7 Module decoupled_router updated after 11 months of inactivity (2.0.7).

Expense Tracker

7 sites No security coverage
View on drupal.org

This module provides a complete financial management system for Drupal, allowing users to record income and expense transactions through forms or file uploads. It offers interactive charts, tabular statements, and a filterable admin list for data exploration, along with a REST API for integrations. Transactions are stored as fieldable content entities, benefiting from Drupal's core features like multilingual support and Views integration.

Expense Income Tracker gives any Drupal 10 or 11 site a complete, self-contained financial management layer. Record every income and expense transaction through a clean admin form or by uploading a CSV, JSON, XML, or XLSX file — then explore the data through interactive Highcharts charts, tabular statements, and a fully filterable admin list, all without leaving the Drupal administration interface. Transactions are stored as a proper fieldable content entity (et_transaction), so they inherit the full Drupal feature set: multilingual content, URL aliases, comment threads, published/unpublished status, Views integration, and Pathauto support out of the box. A six-endpoint REST API means decoupled frontends and third-party accounting systems can read and write transactions with the same access-control rules that govern the UI. Whether you are managing a personal budget, a small-business cash-flow tracker, a corporate expense-reporting portal, or a multi-user financial intranet, Expense Income Tracker gives you the data model, the UI, and the API you need — with zero external PHP dependencies.

Features

Transactions & Data Model

  • Dedicated content entityet_transaction is a fully fieldable entity with its own database tables, field UI, view modes, access-control handler, and list builder. Attach any Drupal field type to it exactly as you would to a node.
  • Income & expense classification — every transaction is typed as either income or expense; the type can be inherited automatically from a parent category transaction.
  • Category hierarchy — create top-level "category" transactions (e.g. Monthly Rent, Salary) and attach child entries to them. Reports automatically group and total child transactions by category.
  • Multilingual support — the entity is translatable; amounts, notes, and titles can be stored per language.
  • Published / unpublished status — unpublished transactions are excluded from all reports, charts, and API responses.
  • Comment threads — a dedicated et_transaction_comment comment type is installed automatically, giving every transaction a discussion thread powered by Drupal core's Comment module.
  • Free-text notes — an optional memo field stores vendor names, invoice references, project codes, or any other context alongside the monetary data.

Recurring Transactions

  • Cron-driven repeat system — tick Repeat this transaction on the add/edit form and the module auto-generates copies on schedule without any manual work.
  • Seven repeat frequencies — daily, weekly, monthly, yearly, working days (Mon–Fri), specific days of the week, and specific days of the month.
  • Configurable end date — set a cut-off date after which no further copies are generated. Defaults to one month from today.
  • Audit trail — every auto-generated copy records created_type = automatic and stores a parent_transaction_id reference back to the source transaction.

Bulk Import

  • Four supported file formats — CSV, JSON, XML, and XLSX are all accepted through the same upload form at Content → Import Transactions.
  • Batch API processing — files are processed row-by-row through Drupal's Batch API, keeping memory usage flat and preventing PHP timeout errors even for thousands of rows.
  • Duplicate detection — re-importing the same file is safe. If a matching parent-category title already exists, new rows are saved as children rather than creating a duplicate parent.
  • Four bundled sample files — ready-to-use .csv, .json, .xml, and .xlsx examples are downloadable directly from the import page.
  • XLSX without extra libraries — Office Open XML workbooks are parsed by the bundled ExcelReaderService; no additional PHP extensions or Composer packages are required.
  • Extensible column mapping — implement hook_et_transaction_import_row_alter() to map any extra column in your file to a custom entity field. The hook fires for all four file formats and for the REST bulk-import endpoint.

Reports & Charts

  • Interactive Highcharts charts — income-only, expense-only, and combined income-vs-expense charts rendered entirely in the browser. No server-side image generation required.
  • Three report views — Income Reports, Expense Reports, and the side-by-side Income & Expense comparison, each available as a dedicated admin sub-tab under Reports → Income and Expense Reports.
  • Flexible grouping — chart data can be grouped by day, week, month, quarter, or year.
  • Eleven date-range presets — Last 7 days, Last 30 days, This/Last week, This/Last month, This/Last quarter, This/Last year, and All time. All report and statement pages share the same filter options.
  • Category and author filters — drill down to a single user's transactions or a single category directly from the report form.
  • Per-category data tables — below every chart, a breakdown table lists individual transactions and subtotals per category.
  • Summary totals — every report page displays total income, total expenses, and net balance for the chosen period at a glance.
  • Chart export — the bundled Highcharts Exporting plugin lets users save any chart as PNG, JPEG, PDF, or SVG with a single click.
  • Flexible Highcharts delivery — choose between locally bundled files (no external requests, recommended for intranets), the jsDelivr CDN with an optional local fallback, or a fully custom URL.

Statements

  • Tabular, print-friendly summaries — filter by date range and transaction type (All, Income, or Expense) to generate a clean statement backed by the admin transaction list at /admin/expense-tracker/income-expense-statements.
  • Deep-link integration — the statements form redirects to the admin list pre-filtered to the chosen period; a "Go back to Statements" link is automatically injected above the list for easy navigation.

Currency Formatting

  • Fully configurable currency display — set the symbol, position (prefix or suffix), decimal separator, and thousands separator once in settings. The formatting is applied consistently across entity pages, the admin list, Views, chart tooltips, and API responses.
  • International currency support — configure Euro (1.250,50€), British pounds (£1,250.50), Japanese yen (¥1,250), or any other currency by adjusting the four formatting options — no code changes required.

REST API

  • Full CRUDPOST /api/et-transactions, GET /api/et-transactions/{id}, PATCH /api/et-transactions/{id}, and DELETE /api/et-transactions/{id} cover the complete create-read-update-delete lifecycle.
  • Paginated collection endpointGET /api/et-transactions supports filtering by type, date range, author, category, status, repeat flag, and a title LIKE search; sorting by any field; field selection; and pagination up to 500 items per page. Non-admin users automatically receive only their own transactions.
  • Bulk-import endpointPOST /api/et-transactions/import accepts a JSON array of transactions with duplicate detection, optional update-on-match, and per-row error reporting. Ideal for CI pipelines, accounting software integrations, and mobile apps.
  • Structured response envelopes — collection responses include a meta object with total count, pagination info, and income/expense/net totals, alongside the data array and HAL-style links.
  • Multiple authentication methods — session-based CSRF tokens, HTTP Basic Auth, OAuth 2.0 (simple_oauth), and JWT are all supported.
  • Entity access respected everywhere — every REST endpoint enforces the same permissions as the admin UI. There are no bypass routes.

Views Integration

  • Ships with a pre-configured expense_tracker_admin view powering the admin transaction list, complete with currency-formatted amounts, exposed filters for title, author, date range, and transaction type, and a bulk-delete action via Views Bulk Operations.
  • Non-admin users automatically see only their own transactions in every view — enforced at the query level in hook_views_query_alter.
  • Create additional custom views from Structure → Views using the et_transaction entity type exactly as you would with nodes.

Pathauto & Token Support

  • Five tokens[et_transaction:id], [et_transaction:title], [et_transaction:type], [et_transaction:date], and [et_transaction:author] are registered with Drupal's Token system and support sub-token chaining (e.g. [et_transaction:author:name], [et_transaction:date:short]).
  • Pathauto-ready — when the pathauto module is installed, URL aliases are generated automatically using any token pattern, such as /transactions/[et_transaction:type]/[et_transaction:title].

Sample & Demo Data

  • 60 realistic demo transactions spanning January 2025 through June 2026 across 15 income and expense categories (Salary, Freelance, Consulting, Rent, Groceries, Utilities, Transport, Travel, Healthcare, Education, Clothing, Entertainment, Rental Income, Dividends, Bonuses), importable from the Settings page with a single click.
  • Duplicate-safe import — re-importing skips existing entries by default. A one-click Remove All Sample Data button cleans up when you are done exploring.

Developer Experience

  • Five hookshook_et_transaction_api_normalize_alter, hook_et_transaction_api_create_alter, hook_et_transaction_api_update_alter, hook_et_transaction_collection_query_alter, hook_et_transaction_import_row_alter.
  • Injectable servicesexpense_tracker.excel_reader (ExcelReaderService) and expense_tracker.post_render_cache are registered in the service container and available for injection in any custom code.
  • Dedicated logger channel — all module events are grouped under expense_tracker in Reports → Recent log messages, making filtering straightforward.
  • Status report integrationhook_requirements() surfaces a warning on the Drupal Status Report page if the locally bundled Highcharts files are missing at runtime.
  • PHP 8.1+ typed properties and declare(strict_types=1) throughout. PHP 8 attributes (#[RestResource]) are used in place of annotation docblocks.
  • PSR-4 autoloading under the clean Drupal\expense_tracker namespace.
  • Zero third-party PHP dependencies — no Composer packages beyond Drupal core are required. XLSX parsing is handled by a bundled, self-contained service class.
  • Idempotent update hooks — all database and config update hooks are fully guarded so they can be re-run safely on existing installations without side effects.

Post-Installation

After enabling the module and its dependencies, follow these steps to start tracking transactions:

  1. Install via Composer.

    Run composer require drupal/expense_tracker drupal/views_bulk_operations, then enable with drush en expense_tracker -y && drush cr. Alternatively, navigate to Administration → Extend, search for Expense Income Tracker, tick the checkbox, click Install, and clear caches.
  2. Set permissions.

    Go to People → Permissions (/admin/people/permissions) and assign the following to the appropriate roles:
    • access expense_tracker — view own transactions.
    • access all expense_tracker — view all users' transactions.
    • create expense_tracker — add new transactions.
    • edit expense_tracker / edit all expense_tracker — edit own or all transactions.
    • delete expense_tracker / delete all expense_tracker — delete own or all transactions.
    • reports expense_tracker — view charts and statements.
    • import expense_tracker — access the file-upload form and the bulk-import REST endpoint.
    • config expense_tracker — access the Settings form.
    • administer et_transactions — full admin access including Field UI, comment settings, and all module settings. Restrict to trusted roles only.
  3. Adjust global settings.

    Go to Configuration → Content authoring → Transaction settings (/admin/config/content/et-transaction). Key options include:
    • Highcharts library source — Local (bundled), CDN (jsDelivr with optional fallback), or a Custom URL.
    • Currency symbol, position (prefix/suffix), decimal separator, and thousands separator.
  4. Add your first transaction.

    Go to Content → Expense Transactions → Add Transaction (/admin/income-expense-transactions/add). Enter a title, amount, date, and select Income or Expense. For recurring bills or income, enable the Repeat option, choose a frequency and an end date — Drupal cron will generate future copies automatically.
  5. Import existing data.

    Go to Content → Import Transactions (/admin/expense-tracker/import/transactions). Download a bundled sample file to see the exact required format, then upload your own CSV, JSON, XML, or XLSX file. The four required columns are title, amount, date, and type (case-sensitive). The Batch API processor handles large files without timeouts and reports a row count on completion.
  6. Explore reports and charts.

    Go to Reports → Income and Expense Reports (/admin/expense-tracker-reports). Use the sub-tabs to switch between the Income, Expense, and combined Income & Expense views. Apply date range, category, and author filters to narrow the data. Use the export button to download any chart as PNG, JPEG, PDF, or SVG.
  7. Load demo data (optional).

    Go to Configuration → Content authoring → Transaction settings → Sample Data and click Import Sample Data. This loads 60 realistic transactions across 15 categories spanning January 2025 – June 2026, ideal for exploring charts and statements before entering real data. Remove them at any time with Remove All Sample Data.
  8. Enable the REST API (optional).

    Go to Configuration → Web services → REST (/admin/config/services/rest) and enable the three ET Transaction resources. For write operations, pass the CSRF token from GET /session/token in the X-CSRF-Token request header. See the REST permissions at People → Permissions for the full list of required role assignments.

For headless or decoupled frontends, use GET /api/et-transactions?_format=json to list and filter transactions, POST /api/et-transactions?_format=json to create them, and POST /api/et-transactions/import?_format=json for bulk operations. All endpoints return JSON envelopes with data, meta, and links keys.

Upgrading

Always take a full database backup before upgrading any Drupal module. The procedure below applies whether you are moving up a single patch release or jumping across multiple minor versions.

Standard upgrade procedure

  1. Back up your database.

    drush sql-dump --result-file=backup-before-upgrade.sql

    Store the dump outside the web root before proceeding. If something goes wrong you can restore with drush sql-cli < backup-before-upgrade.sql.
  2. Update the module with Composer.

    composer update drupal/expense_tracker --with-all-dependencies

    Composer updates the module files and resolves any dependency version changes automatically. If you also need to update views_bulk_operations, include it in the same command:

    composer update drupal/expense_tracker drupal/views_bulk_operations --with-all-dependencies
  3. Run database updates.

    Via Drush (recommended):

    drush updb -y

    Or via the browser by navigating to /update.php and following the on-screen steps. The module's update hooks are fully idempotent — each step checks for existing data before making any change, so running drush updb more than once on an already-updated site is completely safe.
  4. Clear all caches.

    drush cr

    Or navigate to Administration → Performance → Clear all caches. This step is required even if drush updb reports "No pending updates."
  5. Import new configuration (if the release notes require it).

    Most minor and patch releases do not ship configuration changes. When they do, the release notes will say so explicitly. To import:

    drush config-import -y

    Review the diff first with drush config-diff if you have site-specific config customisations you need to preserve.
  6. Verify the Status Report.

    Go to Administration → Reports → Status report (/admin/reports/status). Resolve any warnings listed under the Expense Tracker heading — the most common post-upgrade warning is a missing bundled Highcharts file when switching from CDN to Local source.

What update hooks do

Each numbered update hook is documented in expense_tracker.install. In general, updates may:

  • Add new configuration keys to expense_tracker.settings with safe default values — existing values are never overwritten.
  • Create or modify database columns on the et_transaction and et_transaction_field_data tables.
  • Install new comment types, entity view displays, or entity form displays required by new features.
  • Fix ordering or weight issues in field displays introduced by earlier installs.

Because all hooks are idempotent and guarded with existence checks, re-running drush updb after a failed or partial update is always safe — completed steps are skipped automatically.

Upgrading Drupal core (10 → 11)

Expense Income Tracker supports Drupal 10 and 11 from the same codebase. When upgrading Drupal core itself, follow the official Drupal core upgrade guide, then run drush updb -y && drush cr as above. No special data-migration steps are required for this module's entity data — all et_transaction records remain intact through a core upgrade.

Rolling back a failed upgrade

If an upgrade causes unexpected breakage, restore your backup and redeploy the previous module version:

  1. Restore the database: drush sql-cli < backup-before-upgrade.sql
  2. Revert to the previous release via Composer: composer require drupal/expense_tracker:^<previous-version> --update-with-all-dependencies
  3. Clear caches: drush cr

All transaction data stored in the database will be intact after the restore.

Additional Requirements

  • Drupal 10.1 or 11.x
  • PHP 8.1 or higher (PHP 8.3+ required for Drupal 11)
  • Drupal core modules: Views, Comment, Path, REST, Serialization, Basic Auth (all included in Drupal core)
  • Contributed module: Views Bulk Operations — required for bulk-delete on the admin transaction list

No third-party PHP libraries, JavaScript frameworks, or external services are required. The module is entirely self-contained.

  • Pathauto
    Automatically generates clean URL aliases for every transaction using the bundled [et_transaction:*] token group. A pattern such as /transactions/[et_transaction:type]/[et_transaction:title] produces SEO-friendly paths like /transactions/expense/monthly-rent with no manual input.
  • Token
    Provides the Token browser UI for Pathauto's pattern editor so editors can discover all available [et_transaction:*] tokens interactively without reading documentation.
  • Simple OAuth
    Recommended for decoupled or mobile frontends that authenticate REST API requests via OAuth 2.0 access tokens rather than session cookies or HTTP Basic Auth.
  • Metatag
    Adds SEO meta tags to canonical transaction pages (/et-transaction/{id}), useful if individual transactions are publicly accessible on a community or e-commerce site.
  • Ultimate Cron
    For fine-grained control over how often the recurring-transaction cron job runs. Lets you schedule the expense_tracker hook independently of other modules without editing the system crontab.
  • JSON:API
    Recommended alongside the built-in REST API for fully decoupled React, Vue, or Angular frontends. Use JSON:API to query related Drupal entities and the Expense Tracker REST API for transaction-specific operations such as bulk imports and filtered collection responses with income/expense totals.

Similar Projects

  • Drupal Commerce
    Commerce is a full e-commerce platform covering products, carts, orders, and payments. Expense Income Tracker focuses specifically on recording and reporting financial transactions in a lightweight, fieldable entity model — without a storefront, checkout flow, or payment gateway. It is well-suited for internal accounting and cash-flow tracking where Commerce would be significant overkill.
  • Bookkeeping
    Bookkeeping implements double-entry accounting with debit/credit ledgers. Expense Income Tracker uses a simpler income/expense model that is faster to set up and easier for non-accountants, while providing features Bookkeeping does not: interactive Highcharts reports, multi-format bulk import, a full REST API, recurring transactions, and Pathauto/token integration.
  • Budget
    Budget provides basic budget-tracking fields on nodes. Expense Income Tracker provides a dedicated, fully fieldable entity type with its own access control, Views integration, REST API, and reporting layer — giving significantly more flexibility for custom field additions, integrations, and display modes.
  • Voting API
    VotingAPI is a developer-focused framework for recording votes and computing results, with no frontend UI or analytics dashboard of its own. Expense Income Tracker delivers a complete, production-ready end-to-end solution — storage, admin UI, interactive charts, statements, REST API, and admin tools — with no additional modules required.

Troubleshooting

Charts are blank or Highcharts is not loading

  • Go to Administration → Reports → Status report (/admin/reports/status) and look for an Expense Tracker – Highcharts warning. It will tell you exactly which file is missing.
  • If using the Local source, confirm that js/highcharts.src.js and js/exporting.js exist inside the module directory. If they are missing, either re-download the full module package or switch the Highcharts source to CDN in settings.
  • If using the CDN source, open your browser's developer console (F12 → Network tab) and look for blocked requests to cdn.jsdelivr.net. A Content Security Policy (CSP) header or browser extension may be blocking the request. Enable the CDN fallback option in settings so local files are served if the CDN is unreachable, then clear caches.
  • If using a Custom URL, confirm the URL is publicly reachable from the browser, uses HTTPS, and points directly to the highcharts.js file — not a directory listing or a redirect.
  • Always clear caches after changing the Highcharts source setting: drush cr. The library attachment is cached in Drupal's asset system and will not update until caches are cleared.

Recurring transactions are not being created

  • Confirm cron is running. Go to Administration → Reports → Recent log messages and filter by type cron. If no recent entries appear, configure cron at Administration → Configuration → System → Cron or add a system crontab entry: 0 * * * * /usr/bin/drush -r /path/to/drupal cron --quiet
  • On the source transaction's edit page, verify that Repeat is checked, the Repeat end date is in the future, and the chosen frequency matches today (e.g. for Specific days of the week, confirm today's weekday is selected).
  • Inspect the last_transaction_time field value on the source transaction. If it holds a future timestamp — which can happen after a timezone change or a manual edit — no new copy will be generated until that time passes.
  • Confirm the source transaction is published. The cron repeat system skips unpublished transactions.
  • Run cron manually to test: drush cron. Check Recent log messages immediately afterwards and filter by expense_tracker to see any errors.

Import fails with "Enter a valid file" or a missing-column error

  • Confirm the file contains all four required header names: title, amount, date, type. Headers are case-sensitive and must not contain leading or trailing spaces.
  • For CSV files, use UTF-8 encoding without a BOM (Byte Order Mark). Files exported from Microsoft Excel may include a BOM — choose Save as → CSV UTF-8 (Comma delimited) in Excel, or open the file in a text editor and remove the BOM manually.
  • Ensure the type column contains exactly income or expense (all lowercase). Any other value — including Income or EXPENSE — will cause that row to be skipped or rejected.
  • For XML files, the root element must be <transactions> and each row must be wrapped in an <element> tag. Download the bundled et_transaction.xml sample from the import page and use it as a structural reference.
  • For XLSX files, confirm the first worksheet row contains the column headers, the file is not password-protected, and the workbook opens cleanly in Excel or LibreOffice before uploading.
  • If the file type itself is rejected before validation begins, Drupal's file-field extension whitelist may be blocking it. Check that the extension is among the allowed types configured on the import form's file field.

REST API returns 403 Forbidden

  • Confirm each of the three ET Transaction REST resources is individually enabled at Configuration → Web services → REST (/admin/config/services/rest). Enabling one does not enable the others.
  • The authenticated user needs both the REST permission (e.g. restful post et_transaction) and the corresponding entity permission (e.g. create expense_tracker). Neither alone is sufficient — check both at People → Permissions.
  • All write requests (POST, PATCH, DELETE) require a valid CSRF token in the X-CSRF-Token header. Fetch a fresh token from GET /session/token before each write session.
  • When using Basic Auth, confirm the drupal:basic_auth module is enabled and the credentials are correctly base64-encoded in the Authorization: Basic <base64(user:pass)> header.
  • Every request must include ?_format=json. Omitting it causes Drupal to return a 406 Not Acceptable or an HTML redirect instead of a JSON response.
  • For anonymous REST access, the relevant REST permissions must be assigned to the Anonymous user role — not only to Authenticated user.

Amounts are not currency-formatted in the transaction list

  • Clear all caches (drush cr). The currency formatter output is cached; a settings change does not take effect until caches are rebuilt.
  • Open the view at Structure → Views → expense_tracker_admin → Edit and confirm the Amount field has not been replaced or customised to use a plain field formatter. It should use the entity reference to et_transaction with the module's built-in currency formatter.
  • Verify the currency symbol and separators are correct at Configuration → Content authoring → Transaction settings → Currency Display.

drush updb or update.php reports errors

  • Read the full error output — it will name the failing hook (e.g. expense_tracker_update_9005). Search the issue queue for that hook name to find known fixes or patches.
  • All update hooks are idempotent. Fix the root cause of the failure, then re-run drush updb -y — steps that already completed will be skipped automatically.
  • If a hook fails with "Config object already exists", the configuration was likely imported manually before the update ran. You can mark the hook as done and re-run: drush php-eval "drupal_set_installed_schema_version('expense_tracker', 9005);" (replace 9005 with the actual failing hook number), then drush updb -y.
  • Check Administration → Reports → Recent log messages filtered by the expense_tracker channel for the full PHP stack trace.

Comment form does not appear on transaction pages

  • Confirm the drupal:comment core module is enabled at Administration → Extend.
  • Go to Administration → Structure → Comment types and verify that et_transaction_comment is listed. If it is absent, run drush updb -y && drush cr to trigger the update hook that creates it.
  • On the Manage Display page for et_transaction (Full content view mode), confirm the Comments field is enabled and not hidden.

Settings page returns 403 (Access denied)

  • The settings page at /admin/config/content/et-transaction requires the config expense_tracker permission. Grant it to the appropriate role at People → Permissions.

Module cannot be uninstalled

  • Drupal will block uninstallation if any et_transaction entities still exist in the database. Delete all transactions first — use the bulk-delete checkbox on the admin list, or run:

    drush php-eval "\Drupal::entityTypeManager()->getStorage('et_transaction')->delete(\Drupal::entityTypeManager()->getStorage('et_transaction')->loadMultiple());"
  • Also confirm that no other enabled module lists expense_tracker as a dependency in its .info.yml file.
  • After deleting all data and resolving dependencies, uninstall with: drush pm-uninstall expense_tracker -y && drush cr

Translations or multilingual content is missing after an upgrade

  • Run drush locale-update to refresh translation strings if a new release ships updated translatable strings.
  • If entity translations are missing, ensure the drupal:content_translation module is enabled and the et_transaction entity type has content translation enabled at Configuration → Regional and language → Content language and translation.

Supporting This Module

If Expense Income Tracker saves you time on your project, the best ways to support continued development are:

  • Report bugs and suggest features in the project issue queue.
  • Contribute patches, automated tests, or documentation improvements via the issue queue.
  • Post a review on the project page — community ratings help other Drupal developers discover the module.
  • Help test release candidates against Drupal 10 and 11 minor updates and report any regressions.

When reporting an issue, please include your Drupal core version, PHP version, the exact steps to reproduce the problem, and any relevant output from Reports → Recent log messages filtered by the expense_tracker channel.

Community Documentation

  • Full installation, configuration, permissions, REST API, hook, and Pathauto documentation is available in the README.md file included with the module.
  • All five developer hooks are documented with complete, runnable code examples in expense_tracker.api.php inside the module directory.
  • Example integrations demonstrating custom column mapping during CSV/REST bulk imports, extra entity-query conditions, and custom REST response fields can be found directly in expense_tracker.api.php.
  • Video walkthroughs and step-by-step tutorials for common use cases (multi-user expense reporting, headless Drupal integrations, recurring payroll entries) are welcome contributions — please link them in the issue queue.

Use Cases

Expense Income Tracker is well suited for:

  • Personal finance dashboards — track income and spending categories month by month with interactive charts, all self-hosted on your own Drupal site.
  • Small-business cash-flow tracking — record invoices, wages, rent, and utilities; filter reports by category and date range; export charts as PDF for accountants or stakeholders.
  • Corporate expense-reporting portals — per-user access control lets employees log and review only their own transactions while finance managers access the full dataset with a single permission toggle.
  • Non-profit grant and project accounting — organise income and expenditure by project using the category hierarchy, then generate per-project statements for grant reporting.
  • Recurring payroll and subscription management — enter a salary or subscription once, enable monthly or yearly repeat, and let cron maintain the ledger automatically — no manual entries each cycle.
  • Decoupled / headless Drupal applications — consume the REST API from a React, Vue, or Angular frontend. Use the collection endpoint's built-in filters, field selection, sorting, and pagination to build custom dashboards without any server-side Drupal rendering.
  • Accounting software integrations — pull CSV exports from QuickBooks, Xero, or any CSV-exporting tool and push them into Drupal via the bulk-import REST endpoint or the file-upload form, with duplicate detection keeping re-runs safe.
  • Learning management systems — track student fees, course revenue, and operational costs in a Drupal-based LMS; use per-role access to give finance staff a clean reporting layer separate from course content.

Activity

Tracked releases
2
Tracked since
Jun 2026
Latest release
1 month ago
Releases (12 mo)
2 ▲ from 0
Maintenance
Active

Releases

Version Type Release date
2.0.0 Stable Jun 28, 2026
2.0.x-dev Dev Jun 28, 2026