Skip to content

About

Importer of transactions from the zenmoney export to the beancount format

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

beancount-zenmoney

PyPI version Python versions License CI codecov

A Beancount importer for Zenmoney CSV exports, built on beangulp.

Installation

pip install beancount-zenmoney

Or with uv:

uv add beancount-zenmoney

Requirements

  • Python 3.10+
  • Beancount 3.x
  • beangulp

Quick Start

Create an import.py file for beangulp (see examples/import.py for a complete example):

from beancount_zenmoney import ZenMoneyImporter

account_map = {
    "PKO - PLN": "Assets:Bank:PKO:PLN",
    "Revolut - EUR": "Assets:Bank:Revolut:EUR",
}

category_map = {
    "Salary": "Income:Salary",
    "Food / Groceries": "Expenses:Food:Groceries",
    "Gifts": {"income": "Income:Gifts", "expense": "Expenses:Gifts"},
}

importers = [
    ZenMoneyImporter(
        account_map=account_map,
        category_map=category_map,
    ),
]

Run with beangulp:

beangulp extract -e ledger.beancount import.py zenmoney_export.csv

Configuration Options

ZenMoneyImporter(
    # Required: Map Zenmoney account names to Beancount accounts
    account_map={
        "Bank - PLN": "Assets:Bank:PLN",
    },

    # Optional: Map Zenmoney categories to Beancount accounts
    category_map={
        "Food": "Expenses:Food",
    },

    # Optional: Base account for the importer (default: "Assets:ZenMoney")
    base_account="Assets:Import:ZenMoney",

    # Optional: Default expense account for unknown categories
    default_expense="Expenses:Unknown",

    # Optional: Default income account for unknown categories
    default_income="Income:Unknown",

    # Optional: Default asset account for unknown Zenmoney accounts
    default_account="Assets:Unknown",

    # Optional: Default expense account for commission in same-currency transfers
    default_commission_expense="Expenses:Financial:Commissions",

    # Optional: Transaction flag - "*" for cleared (default), "!" for pending
    flag="!",
)

Features

Transaction Types

Zenmoney Transaction Beancount Result
Expense (outcome only) Debit from asset, credit to expense
Income (income only) Credit to asset, debit from income
Transfer (same currency) Debit from source, credit to destination
Currency exchange Debit in one currency, credit in another with price
Refund Credit to asset, debit from expense

Currency Exchange with Price

Currency exchanges automatically include price annotations for proper cost tracking:

2025-12-12 * "" "FX EXCHANGE EUR/PLN 4.25"
  Assets:Bank:PKO:PLN   -4250.00 PLN
  Assets:Bank:PKO:EUR    1000.00 EUR @ 4.25 PLN

Commission Handling in Transfers

When a same-currency transfer occurs with a difference between the outcome and income amounts, the difference is automatically treated as a commission and posted to a configurable expense account (Expenses:Financial:Commissions by default).

For example, a transfer of 200 PLN out and 195 PLN in from the same currency would result in an additional posting:

2025-02-03 * "Bank Transfer Fee" "Transfer fee"
  Assets:Bank:MainBank:PLN       -200.00 PLN
  Assets:Bank:DigitalWallet:PLN    195.00 PLN
  Expenses:Financial:Commissions     5.00 PLN

This ensures that such transactions balance correctly in Beancount.

Metadata Preservation

Each transaction includes metadata from ZenMoney:

2025-12-14 * "SuperMarket" ""
  zenmoney_created: "2025-12-14 10:30:00"
  zenmoney_changed: "2025-12-14 11:00:00"
  zenmoney_category: "Food / Groceries"
  Assets:Bank:PKO:PLN       -125.50 PLN
  Expenses:Food:Groceries    125.50 PLN

File Archiving Support

The importer implements date() and filename() methods for beangulp archiving:

# Archive files with automatic date-based naming
beangulp archive -e ledger.beancount import.py zenmoney_export.csv
# Creates: documents/Assets/Import/ZenMoney/2025-11-29-to-2025-12-15.zenmoney.csv

Logging

Skipped rows are logged as warnings for troubleshooting:

import logging
logging.basicConfig(level=logging.WARNING)

Exporting from Zenmoney

  1. Open the Zenmoney app or web interface
  2. Go to Menu → Export
  3. Select CSV format
  4. Choose the date range for export
  5. Download the CSV file

The CSV file should have semicolon-separated columns including:

  • date, categoryName, payee, comment
  • outcomeAccountName, outcome, outcomeCurrencyShortTitle
  • incomeAccountName, income, incomeCurrencyShortTitle
  • createdDate, changedDate

Example Output

Expense transaction:

2025-12-14 * "SuperMarket" ""
  Assets:Bank:PKO:PLN       -125.50 PLN
  Expenses:Food:Groceries    125.50 PLN

Internal transfer:

2025-12-11 * "" ""
  Assets:Bank:PKO:PLN       -2000.00 PLN
  Assets:Cash:PLN            2000.00 PLN

Income transaction:

2025-12-15 * "ACME CORP" "DECEMBER SALARY"
  Assets:Bank:PKO:PLN    15000.00 PLN
  Income:Salary         -15000.00 PLN

Development

Setup

git clone https://github.com/MrLokans/beancount-zenmoney.git
cd beancount-zenmoney
make install

Releasing

The package is automatically published to PyPI when a version tag is pushed:

make release VERSION=0.2.0

This script will:

  • Run all checks (lint, format, typecheck, tests)
  • Validate the version format and ensure the tag doesn't exist
  • Update version in pyproject.toml and __init__.py
  • Commit, tag, and push to remote

Available Commands

make install              # Install dependencies
make test                 # Run tests
make lint                 # Run linter
make format               # Format code (ruff check --fix + ruff format)
make typecheck            # Run type checker
make check                # Run all checks (lint, format-check, typecheck, test)
make build                # Build package
make clean                # Clean build artifacts
make release VERSION=X.Y.Z  # Create and push a release

Running Tests

make test

Tests use pytest with fixtures for sample CSV data. Test coverage is reported automatically.

License

MIT License - see LICENSE for details.

About

Importer of transactions from the zenmoney export to the beancount format

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages