Fava

repository·main·Indexed 25 days ago

https://github.com/beancount/fava

A web interface for the Beancount accounting tool that provides a visual way to interact with financial data. Documentation covers installation via pip, development environment setup, and various deployment strategies including Docker, systemd, PythonAnywhere, and Apache reverse proxies with OAuth2 Proxy and Let's Encrypt SSL.

Tokens
20.4K
Snippets
47
Records
129
Agent score
82%

What's inside fava

  1. How Fava extensions work

    main

    Fava extensions are composed of three main capabilities:

    1. Hooks: Python methods that trigger during specific lifecycle events (e.g., loading files, modifying entries).
    2. Reports: If your extension class has a report_title attribute, Fava will treat it as a report page. The HTML template must be located in a templates subdirectory named after the class (e.g., fava/ext/MyExtension/templates/MyExtension.html).
    3. Frontend JavaScript: If the extension sets has_js_module = True, Fava will load a JavaScript file matching the class name (e.g., MyExtension.js).

    JavaScript Lifecycle Events:

    • init: Called when a Fava report is first opened.
    • onPageLoad: Called when any page in Fava is loaded (initial open and subsequent navigation).
    • onExtensionPageLoad: Called specifically when the extension's report is loaded.
  2. Configure Up-to-date Indicators

    main

    Fava displays colored indicators next to accounts to help track if they are up-to-date. These appear if the account's Open directive has the metadata fava-uptodate-indication: TRUE set.

    Indicator Colors:

    • Green: The last entry for this account is a passing balance check.
    • Red: The last entry is a failed balance check.
    • Yellow: The last entry is not a balance check.
    • Grey Dot: The account has not been updated within the period defined by the uptodate-indicator-grey-lookback-days option.
  3. Define Account Hierarchies and Root Accounts

    main

    Accounts in Beancount are defined using a colon-separated list of capitalized words (e.g., Assets:Cash). This creates an implicit hierarchy where Assets:Cash is a sub-account of Assets.

    By default, all accounts must begin with one of the five root accounts:

    NameTypeContains
    Assets+Cash, Checking-Account, etc.
    Liabilities-Credit Card, etc.
    Income-Salary, etc.
    Expenses+Expense categories
    Equity-Almost always auto-generated

    Note: + indicates an increase in balance, - indicates a decrease.

  4. Understand Fava conversion modes

    main

    Fava provides several modes for converting inventory positions in reports:

    • At Cost: Shows inventories at their original cost. For example, a position of 10 STOCK {4 USD} is converted to 40 USD.
    • At Market Value: Shows inventories at their current market value (converting to the cost currency at the current price). For example, a position of 10 STOCK {4 USD} is converted to 50 USD if the current price of STOCK is 5 USD.
    • Units: Displays the plain units of all positions without currency conversion (e.g., 10 STOCK).
    • Converted to X: Converts positions to a specific currency X. If no direct price for the asset in X exists, Fava attempts a conversion via the cost currency (e.g., if STOCK is priced in USD and X is also priced in USD).
    • Converted to X,Y: Allows chaining conversions by selecting multiple currencies in the dropdown. Conversions are applied sequentially (e.g., STOCK $\rightarrow$ X $\rightarrow$ Y).

    Note on failed conversions: Fava will not silently drop amounts. If a conversion is impossible, the original un-converted units will be displayed.

  5. How time filters summarize balances (Clamp summarisation)

    main

    When a time filter is applied, Fava uses Beancount's "clamp" summarisation to ensure reports reflect the state within that specific interval:

    • Income and Expenses: All balances prior to the filtered period are transferred to the account_previous_earnings (retained earnings) account. These accounts effectively start with a zero balance in the report.
    • Assets and Liabilities: All transactions before the start date are summarised against the account_previous_balances (opening balances) account, allowing these accounts to show their accumulated balance.
    • Post-period entries: All entries occurring after the end date are removed from the view.
    • Conversions: A conversion entry is added to the account_current_conversions account to account for changes occurring within the filtered period.
  6. Display source data for imported entries

    main

    To see the original source text (such as a CSV row or XML fragment) for an entry in the Fava import list, set the special metadata key __source__ on the entry.

    Note: Fava will strip this metadata key (and all other keys starting with an underscore _) before saving the entry to your Beancount file.

  7. Filter by metadata, tags, and attributes

    main

    Use the metadata filter to target specific entry attributes. Filters are case-insensitive and support Python-style regular expressions.

    Common Metadata Filters

    • Tags and Links: Use #tag or ^link.
    • Amount: Use comparison operators on the absolute value, e.g., = 100.20 or >= 100.
    • Specific Attributes: Use attribute:"value".
      • payee:"restaurant"
      • narration:'Dinner with Joe'
    • General Search: If no attribute is specified, Fava searches payee and narration. For Note directives, it searches the comment.
    • Metadata Keys: Use key:"value" (e.g., document:"\.pdf$"). If an entry has a standard attribute with the same name as the metadata key, the filter applies to the attribute instead.

    Logical Operators and Combinations

    • AND (Space): Separate filters with a space to require all conditions (e.g., #tag payee:"Joe").
    • OR (Comma): Separate filters with a comma to match any condition (e.g., #tag,payee:"Joe").
    • NOT (Minus sign): Prepend - to exclude matches (e.g., -#tag or -(^link #tag)).
    • Grouping: Use parentheses to control precedence (e.g., (filter1 or filter2) and filter3).
  8. Build and watch the Fava frontend

    main

    Fava's frontend is built using JavaScript. If you modify frontend code, you must rebuild it.

    • Manual build: Run make to rebuild the frontend.
    • Automatic build: Run make watch to automatically rerun the build whenever files change.
  9. Configure Fava options in Beancount

    main

    To customize Fava's behavior, add custom "fava-option" entries directly to your Beancount file. Each option follows the format: YYYY-MM-DD custom "fava-option" "option-name" "value".

    2016-06-14 custom "fava-option" "default-file"
    2016-04-14 custom "fava-option" "auto-reload" "true"
    2016-04-14 custom "fava-option" "currency-column" "100"
  10. Set up Let's Encrypt with Nginx and Docker

    main

    To secure your deployment with automated SSL, run three containers that work together using the --volumes-from flag to share Nginx configuration and certificate paths. This setup requires exposing ports 80 and 443 on your host.

    1. Nginx Container: The core web server.
    2. Nginx-Gen (docker-gen): Watches for changes and regenerates Nginx configurations.
    3. Nginx-Letsencrypt (companion): Manages the actual Let's Encrypt certificate lifecycle.

    Note: These containers require access to the Docker socket (/var/run/docker.sock) to monitor other containers and trigger configuration updates.

    # 1. Run Nginx
    docker run --detach --publish 80:80 --publish 443:443 \
        --name nginx \
        --volume /etc/nginx/conf.d \
        --volume /etc/nginx/vhost.d \
        --volume /usr/share/nginx/html \
        --volume $(pwd)/certs:/etc/nginx/certs:ro \
        --volume $(pwd)/htpasswd:/etc/nginx/htpasswd:ro \
        --label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true \
        nginx
    
    # 2. Run Nginx-Gen
    docker run --detach \
        --name nginx-gen \
        --volumes-from nginx \
        --volume /var/run/docker.sock:/tmp/docker.sock:ro \
        jwilder/docker-gen \
        -notify-sighup nginx -watch -only-exposed -wait 5s:30s \
        /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    
    # 3. Run Nginx-Letsencrypt
    docker run --detach \
        --name nginx-letsencrypt \
        --env "NGINX_DOCKER_GEN_CONTAINER=nginx-gen" \
        --volumes-from nginx \
        --volume $(dirname $(realpath $0))/certs:/etc/nginx/certs:rw \
        --volume /var/run/docker.sock:/var/run/docker.sock:ro \
        jrcs/letsencrypt-nginx-proxy-companion
  11. Filter entries by time and date ranges

    main

    Use the time filter input to display entries within specific periods. Fava supports absolute dates, intervals, and relative date math.

    Date Formats

    • Years: 2015
    • Quarters: 2012-Q1
    • Months: 2010-10
    • ISO Weeks: 2016-W12
    • Full Dates: 2015-06-12
    • Ranges: 2010 - 2012-10 (displays entries from the start of 2010 to the end of October 2012).

    Relative Date Variables

    You can use year, quarter, month, week, and day to refer to the current date. These support addition and subtraction.

    • year - day: All entries in the current year up to today.
    • year-1 - year: All entries from the last year and the current year.

    Note on Parentheses: Use parentheses to prevent subtraction from the variable itself.

    • (month)-10 refers to the 10th of the current month.
    • month-10 refers to 10 months ago.