Giter Club home page Giter Club logo

fava's Introduction

beancount: Double-Entry Accounting from Text Files

Description

A double-entry bookkeeping computer language that lets you define financial transaction records in a text file, read them in memory, generate a variety of reports from them, and provides a web interface.

Documentation

Documentation can be read at:

https://beancount.github.io/docs/

Documentation authoring happens on Google Docs, where you can contribute by requesting access or commenting on individual documents. An index of all source documents is available here:

http://furius.ca/beancount/doc/index

There's a mailing-list dedicated to Beancount, please post questions there, so others can share in the responses. More general discussions about command-line accounting also occur on the Ledger mailing-list so you might be interested in that group as well.

Download & Installation

You can obtain the source code from the official Git repository on Github:

See the Installing Beancount document for more details.

Versions

There are three versions

  • Version 3 (branch master): The in-development next version of Beancount since June 2020. This is unstable and you want to use version 2 below. The scope of changes is described in this document.
  • Version 2 (branch v2): The current stable version of Beancount, in maintenance mode as of July 2020. This was a complete rewrite of the first version, which introduced a number of constraints and a new grammar and much more. Use this now.
  • Version 1 (branch v1): The original version of Beancount. Development on this version halted in 2013. This initial version was intended to be similar to and partially compatible with Ledger. Do not use this.

Filing Bugs

Tickets can be filed at on the Github project page:

https://github.com/beancount/beancount/issues

Copyright (C) 2007-2022 Martin Blais. All Rights Reserved.

This code is distributed under the terms of the "GNU GPLv2 only". See COPYING file for details.

Donations

Beancount has found itself being useful to many users, companies, and foundations since I started it around 2007. I never ask for money, as my intent with this project is to build something that is useful to me first, as well as for others, in the simplest, most durable manner, and I believe in the genuinely free and open stance of Open Source software. Though its ends are utilitarian -it is about doing my own accounting in the first order - it is also a labor of love and I take great pride in it, pride which has pushed me to add the polish so that it would be usable and understandable by others. This is one of the rare areas of my software practice where I can let my desire for perfection and minimalism run untamed from the demands of time and external constraints.

Many people have asked where they can donate for the project. If you would like to give back, you can send a donation via Wise (preferably):

https://wise.com/share/martinb4019

or PayPal at:

https://www.paypal.com/paypalme/misislavski

Your donation is always appreciated in any amount, and while the countless hours spent on building this project are impossible to match, the impact of each donation is much larger than its financial import. I truly appreciate every person who offers one; software can be a lonely endeavour, and those donations as well as words of appreciation keep reminding me of the positive impact my side projects can have on others. I feel gratitude for all users of Beancount.

Thank you!

Author

Martin Blais <[email protected]>

fava's People

Contributors

adamgibbins avatar andreasgerstmayr avatar aumayr avatar cgrinds avatar cheif avatar corani avatar cruizh avatar dependabot-preview[bot] avatar jbms avatar jeffwheeler avatar johannesjh avatar mechanarchy avatar mjochim avatar pmarciniak avatar pre-commit-ci[bot] avatar redstreet avatar seltzered avatar tbm avatar tschicke avatar tumetsu avatar upsuper avatar vianney avatar wylfen avatar wzyboy avatar xentac avatar xinluh avatar xuhcc avatar yagebu avatar yegle avatar zacchiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fava's Issues

Treemap colors include background color

One of the colors the treemap is currently rendering is the background color of the web page itself (white or close to it). This also happens to be the text label color. Obviously, the entire rectangle and its text disappears.

Could this color please be removed? Thanks!

ImportError: No module named 'beancount_web.util'

When trying to start beancount-web after install, I get the following error:

$ beancount-web 
Traceback (most recent call last):
  File "/usr/local/bin/beancount-web", line 9, in <module>
    load_entry_point('beancount-web==0.1.0a1', 'console_scripts', 'beancount-web')()
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 351, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2363, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2088, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a1-py3.4.egg/beancount_web/cli.py", line 8, in <module>
    from beancount_web.api import BeancountReportAPI
  File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a1-py3.4.egg/beancount_web/api.py", line 27, in <module>
    from beancount_web.util.dateparser import parse_date
ImportError: No module named 'beancount_web.util'

"git-bisect" tells me:

a9b61255ba5bc3f4933c0a23bab748cb4cdd11e6 is the first bad commit
commit a9b61255ba5bc3f4933c0a23bab748cb4cdd11e6
Author: Jakob Schnitzer <[email protected]>
Date:   Fri Dec 11 14:17:25 2015 +0100

    use beancount.query for the filtering

:040000 040000 ca9f989836b11dd2cecefe20c5c6431dd01519dc e221fe28cbee06590563c6226cf08d2ae4117722 M  beancount_web

Add CHANGES.md

Add a CHANGES.md-document where big changes are noted, like in beancount.

Context view doesn't work

When I click on any link to a context page, I get the following exception:

Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1836, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/application.py", line 104, in context
context = app.api.context(ehash)
File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/api.py", line 786, in context
self.entries, self.options, entry)
TypeError: render_entry_context() missing 2 required positional arguments: 'filename' and 'lineno'

Change Watcher works only once

On my system (Ubuntu 14.04), it appears the change watcher works only once. If I make one change and refresh the page, the change shows up. Subsequent changes don't show up after page refresh.

When I restart the application, they (obviously) do show up again.

Selectively hiding accounts in the account hierarchy

This is a feature request, if it interests you: it would be useful to be optionally able to not display leaf accounts in the hierarchy in various situations:

  • when there are zero transactions for a given account in the current context (period/filters)
  • when the final balance is zero in the current context
  • when the account has been closed (when you don't want to see a bunch of irrelevant accounts from the past)
  • specific set of accounts listed in the config file

This would help reduce clutter, particularly for folks with detailed hierarchies and/or long histories.

Global option to render numbers in their absolute value

@blais (from the Mailing list):

Given how "pro" this looks, you may consider adding a global option to render the numbers in their absolute value, that is, negate the income, equity and liabilities numbers everywhere. I've been considering adding this to Beancount myself (both for input syntax and output reports actually), wondering if I could find a way to do that in a way you could reuse. This would make the presention easier to follow for "real" accountants by removing the surprising signs.

Treemap labels on top of filters

When the treemap on the balance sheet page is shown, it's labels will show on top of the filter-dropdown menus.

Browser: Version 45.0.2454.101 Ubuntu 14.04 (64-bit)

screenshot from 2015-12-30 11 27 14

Clickable graphs [feature request]

Making graphs clickable at various points to intuitively narrow down a search would be convenient. I have no idea how easy/difficult this is, but putting it in here to see if you like the idea.

Two currently obvious places:

  • with treemaps, clicking on a rectangle would apply an additional filter of the account clicked on, going to a page as if the account was clicked
  • with bar graphs used in monthly plots, clicking would apply an additional filter of the month clicked on, to the existing account

Treemap: Option to display negative numbers

redstreet0 on negative numbers:

Yes, this is one drawback of Treemaps. However, I think that for what it would mainly be used for in personal finance (getting a quick view of the big picture of each of Expense/Income/Asset/Liabilities), it is mostly safe to simply ignore them in the treemap, especially for small numbers.

However, one possible exception and an approach: show the magnitude of negative subaccounts, but with a special marker. Eg: show only negative accounts in red (or stripes or whatever). Allow for this to be an option, and by default, turn it off - i.e., ignore negative subaccounts like you're doing. The place where turning it on would help is to find problems. For instance, a significant negative number under an Expense or an Asset account (or a flipped Income or Liability account) might be an indication of a problem.

Render Journal entries asynchronously and with sensible defaults

Right now all the data for Journal entries is stored in the HTML of the page, and rendered as full, before filtering the already rendered HTML-elements via JavaScript. Additionally, legs are shown by default, which is what many users do not want.

  • Request Journal entries data via AJAX (non-blocking the UI)
  • Only render the Journal entry types selected by the user (filter)
  • Only render legs if requested (default: not shown)

Historical background from on the Mailing list:

@blais (and others):

I've been meaning to remove the rendering of postings in journals, to make them collapsible (and collapsed by default) like you did, but to only fetch the detail from the server when expanding a particular transaction or hovering over a particular link. This would have two advantages: (1) the journals would render much faster, by avoiding rendering all of these postings details by default, which is slow, and which is really an overkill amount of detail for the most part, and (2) the journals would look smaller on-screen and be much easier to read.

First Impression Feedback

Sorry about my original post. When I first logged into Github to view this issue tracker, I saw a message that Github thought I was a robot and to contact support to make my profile public again, and then the textbox for posting, which I quickly posted that I was a human. Then I saw it was your issue tracker -how embarassing! So, I decided to overwrite it and give you my feedback for beancount-web here.

First of all let me say I LOVE what you've done with beancount-web! I've had it on my list to dig into some javascript frameworks/libraries and hack something together myself, in particular to give some data visualation in the form of charts graphs. You have done that and so much more - not being much more than a novice myself, I never could have done so much, so well, so fast. So great job, and thanks for your work. I've been using beancount for a little over a year, and really like it. I found myself using bean-web more and more viewing reports, eventually using it exclusively for viewing data, and the text file for editing/data entry. You've made a lot of improvements, and gave it a clean, pro-looking interface. The charts/graphs are great, filters handy, and bean-query custom functionality the icing on the cake. I'll be using beancount, giving feedback and perhaps contributions where I can.

I also have a few initial questions/suggestions.

  1. I really like how the balance sheet has a "net work in (op curr)" graph. It seems to be totalling and then converting all currencies to that one op curr? My question is, where does it get the exchange rate? It doesn't seem to be using the price directives that I've provided in my data file.
  2. I think someone mentioned in the beancount mailing list about negative values in the charts. For example, when viewing monthly income graph in the income statement view, the bars are "upside down." I realize this is because income entries are negative because of the accounting equation, but somehow my brain still wants to view them in the graph as "rightside-up." Is this a more pro/accounting way of looking at it? In my experience with personal finance software (Quicken, Gnucash, iBank, etc.), I've always seen income presented as positive values in charts/graphs.
  3. For tables, I find myself wanting to see the default view as collapsed, giving a bird's eye view first, and then drilling down to the details by expanding. I realize others may not like this, but I suggest putting some discrete "collapse all"/"expand all" buttons (esp. for balance sheet and trial balance views).
  4. Perhaps this goes against the whole premise behind the ledger/CLI accounting movement (where recording transactions and other info is strictly done in the text files), but does anyone ever think about using the web interface to write/edit data (transactions, notes, etc.). Like I said, I may be missing the point altogether, but I find myself missing this feature of mainstream personal finance software.

Anyway, again great job. If there's a particular area where you would like some help/ contributions, let me know, and if it's within my abilities, I'll do my best to help.

~Danny

Update LICENSE

  • Figure out what License would be best for beancount-web
  • Add a LICENSE-file
  • Add a license-note to all files

Crashes when an invalid (?) time filter is chosen

I tried to type "2014-2015" into the Time filter. It would be nice if that format worked (sneaking in a feature request here!), but given that it doesn't, I get an error:

http://localhost:5000/account/Assets:Bank:BankNane/monthly_balances/?filter_time=2014-2015

builtins.TypeError
TypeError: 'NoneType' object is not iterable

Traceback (most recent call last)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
Open an interactive python shell in this frameraise value
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1473, in full_dispatch_request
rv = self.preprocess_request()
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1666, in preprocess_request
rv = func()
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/application.py", line 250, in perform_global_filters
payees=app.entry_filters.get('payees', set()).copy())
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/api.py", line 238, in filter
self.apply_filters()
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/api.py", line 207, in apply_filters
begin_date, end_date = parse_date(self.filters['time_str'])
TypeError: 'NoneType' object is not iterable
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

Data up-to-date indication

[email protected] (via Mailing list):

When displaying the balance sheet, for Assets and Liabilities, I typically always compare my current balance to what the bank/credit-card/financial institution currently shows. Once they compare correctly, I put in a 'balance' directive for that account.

It would be immensely helpful if account names were optionally color coded in the balance sheet display to help with this process, like so:

Show account in:

  • green: if the latest posting is a balance check that passed (i.e., known-good)
  • red: if the latest posting is a balance check that failed (i.e., known-bad)
  • yellow: if the latest posting is not a balance check (i.e., unknown)

@blais (via Mailing list):

That's a cool idea, and I would add maybe a "gray" if the account hasn't been updated in a while (as compared to the last available date in the file).

Create balance check entries in the uptodate-status table/page

It would be nice to have a button that generates the beancount entries required to "promote" accounts from their current uptodate-status to the best uptodate-status (green), and copies it into the clipboard, so the user can paste it into their source and edit as required. This is helpful when the user has just updated their accounts, and sees that the balances correspond with their institution, and wants an easy way to mark all or many accounts as green (known-good).

The text copied would look like:

2015-12-23 balance Assets:Bank:Duck-Bank 27 USD
2015-12-23 balance Liabilities:Duck-Card -7 USD
...

where 27 USD and -7 USD are the current balances in the accounts. A line has to be created for each commodity in each account.

The button could be close to the table that summarizes the uptodate-statuses.

Add script to "scrape-test" the frontend

@blais (on the Mailing list):

One kind of test that is easily implemented and which has been really beneficial in avoiding total undetected breakage in bean-web is a generic "scrape everything and check for errors" automated test, like I do it:
https://bitbucket.org/blais/beancount/src/c5252218c11b9f96c57e1423fb3f38314916149b/src/python/beancount/web/scrape.py?at=default&fileviewer=file-view-default

This just runs as part of my suite of unit tests and gives me a sense that changes to the core don't break the front-end. You may want to consider adding something like this to beancount-web.

Crashes upon clicking on any account

c52710f crashes upon clicking any account name:

Using git bisect:
e6a49a9 is the first bad commit

jinja2.exceptions.TemplateSyntaxError
jinja2.exceptions.TemplateSyntaxError: unexpected ']', expected ')'

Traceback (most recent call last)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1836, in call
return self.wsgi_app(environ, start_response)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3.4/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/application.py", line 27, in account_with_journal
return account(account_name=name, with_journal=True)
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/application.py", line 51, in account
return render_template('account.html', account_name=account_name, journal=journal, linechart_data=linechart_data)
File "/usr/lib/python3.4/site-packages/flask/templating.py", line 128, in render_template
context, ctx.app)
File "/usr/lib/python3.4/site-packages/flask/templating.py", line 110, in _render
rv = template.render(context)
File "/usr/lib/python3.4/site-packages/jinja2/environment.py", line 989, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python3.4/site-packages/jinja2/environment.py", line 754, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/_account_name_header.html", line 15, in template
{% with status=api.is_account_uptodate(account_name, look_back_days=config.getint('uptodate-indicator-grey-lookback-days'])) %}
File "/usr/lib/python3.4/site-packages/jinja2/environment.py", line 986, in render
return concat(self.root_render_func(self.new_context(vars)))
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/account.html", line 2, in top-level template code
{% set active_page = 'trial_balance' %}
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/_layout.html", line 76, in top-level template code
{% block content %}{% endblock %}
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/account.html", line 13, in block "content"
{% include "_account_name_header.html" %}
File "/usr/lib/python3.4/site-packages/jinja2/environment.py", line 754, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.4/site-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "/usr/lib/python3.4/site-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/_account_name_header.html", line 15, in template
{% with status=api.is_account_uptodate(account_name, look_back_days=config.getint('uptodate-indicator-grey-lookback-days'])) %}
File "/usr/lib/python3.4/site-packages/jinja2/environment.py", line 470, in parse
return Parser(self, source, name, encode_filename(filename)).parse()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 897, in parse
result = nodes.Template(self.subparse(), lineno=1)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 879, in subparse
rv = self.parse_statement()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 121, in parse_statement
return getattr(self, 'parse
' + self.stream.current.value)()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 203, in parse_if
'name:endif'))
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 156, in parse_statements
result = self.subparse(end_tokens)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 879, in subparse
rv = self.parse_statement()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 128, in parse_statement
return ext(self)
File "/usr/lib/python3.4/site-packages/jinja2/ext.py", line 426, in parse
expr = parser.parse_expression()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 390, in parse_expression
return self.parse_condexpr()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 395, in parse_condexpr
expr1 = self.parse_or()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 408, in parse_or
left = self.parse_and()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 417, in parse_and
left = self.parse_not()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 428, in parse_not
return self.parse_compare()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 432, in parse_compare
expr = self.parse_add()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 454, in parse_add
left = self.parse_sub()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 464, in parse_sub
left = self.parse_concat()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 474, in parse_concat
args = [self.parse_mul()]
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 484, in parse_mul
left = self.parse_div()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 494, in parse_div
left = self.parse_floordiv()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 504, in parse_floordiv
left = self.parse_mod()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 514, in parse_mod
left = self.parse_pow()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 524, in parse_pow
left = self.parse_unary()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 543, in parse_unary
node = self.parse_postfix(node)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 672, in parse_postfix
node = self.parse_call(node)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 781, in parse_call
value = self.parse_expression()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 390, in parse_expression
return self.parse_condexpr()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 395, in parse_condexpr
expr1 = self.parse_or()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 408, in parse_or
left = self.parse_and()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 417, in parse_and
left = self.parse_not()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 428, in parse_not
return self.parse_compare()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 432, in parse_compare
expr = self.parse_add()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 454, in parse_add
left = self.parse_sub()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 464, in parse_sub
left = self.parse_concat()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 474, in parse_concat
args = [self.parse_mul()]
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 484, in parse_mul
left = self.parse_div()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 494, in parse_div
left = self.parse_floordiv()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 504, in parse_floordiv
left = self.parse_mod()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 514, in parse_mod
left = self.parse_pow()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 524, in parse_pow
left = self.parse_unary()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 543, in parse_unary
node = self.parse_postfix(node)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 672, in parse_postfix
node = self.parse_call(node)
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 786, in parse_call
args.append(self.parse_expression())
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 390, in parse_expression
return self.parse_condexpr()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 395, in parse_condexpr
expr1 = self.parse_or()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 408, in parse_or
left = self.parse_and()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 417, in parse_and
left = self.parse_not()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 428, in parse_not
return self.parse_compare()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 432, in parse_compare
expr = self.parse_add()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 454, in parse_add
left = self.parse_sub()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 464, in parse_sub
left = self.parse_concat()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 474, in parse_concat
args = [self.parse_mul()]
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 484, in parse_mul
left = self.parse_div()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 494, in parse_div
left = self.parse_floordiv()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 504, in parse_floordiv
left = self.parse_mod()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 514, in parse_mod
left = self.parse_pow()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 524, in parse_pow
left = self.parse_unary()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 542, in parse_unary
node = self.parse_primary()
File "/usr/lib/python3.4/site-packages/jinja2/parser.py", line 560, in parse_primary
next(self.stream)
File "/usr/lib/python3.4/site-packages/jinja2/lexer.py", line 349, in next
self.current = next(self._iter)
File "/usr/lib/python3.4/site-packages/jinja2/lexer.py", line 552, in wrap
for lineno, token, value in stream:
File "/usr/lib/python3.4/site-packages/jinja2/lexer.py", line 685, in tokeniter
filename)
jinja2.exceptions.TemplateSyntaxError: unexpected ']', expected ')'
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

Option to show transactions only in the account, but not children [feature-request]

beancount-web currently shows:
parent-only total: dark black
parent + children total: gray

This is very useful. However, when one clicks on the account, there is no way to see a list of the transactions for only the parent account, without also seeing the the children's transactions intermingled. It would be great to add an option to the set of options (open, close, transaction, etc.) to turn off display of transactions from children accounts, so one can see what transactions add up to the dark black number mentioned above.

Renaming `beancount-web`

Martin Blais (on the Mailing list):

A suggestion: If you gave beancount-web a more distinct name, it might alleviate some of the confusion that will occur to newcomers to the project. "beancount-web" sounds pretty close to "bean-web" and I'm pretty sure not everyone will make the distinction right away, we don't have the most favorable combo of names. Of course that's your call, but I think a better name might also give the project a stronger sense of identity and thus some extra elan.

Some totally wild ideas off the top of my head (feel free to ignore me):

What do you think about renaming the project, @corani, @yagebu, @blais, @jbms?

Commas in axis labels

Hovering over data points on all chart types shows commas, but but the line and bar chart axes don't have commas. Wondering if there is an easy way to turn these on? Thanks.

Filters shouldn't be shown on every page

Currently the filters (Time, Tag, Account, Payee) are shown on all pages. However, they don't make sense for a bunch of them, including Custom Query and the Configuration section pages.

Marketing

Add to README.md:

Create:

  • beancount-Syntax primer
  • Build Syntax primer into Help feature of beancount-web
  • Website for beancount-web?

Anything else?

Remove api where possible?

First of all thank you for the great work you've put into this! Not entirely satisfied with bean-web, I've written my own small web frontend for beancount a while ago, but this massively outperforms it.

At the moment performance is not great. I think in some cases it might be improved by removing the additional layer that the API introduces. The _process_postings functions is not really necessary in my opinion, as all of it could be done in the template (which has to know anyway what the data looks like) as far as I can see. I would submit an PR with this change if you don't oppose it.

Actually, I don't really think it makes sense to have the change and balance column in the general journal as they just seem to keep track of all the currency conversions, for all accounts at once. What do you think about this? If the balances don't have to be calculated, the rendering of this page might be much quicker.

Add "Year to date" time filter

I generate my mortgage payment schedule automatically, so I have data for the next decade in my source file. This makes no sense in day-to-day reports, so I restrict the time range to "2015 - today".

It would be nice to have a predefined "Year to date" option for this in the time-filter dropdown.

Make filter-links bookmark-able

  • Move default filter adding/removing to POST-requests
  • Make filter-links bookmark-able by using request.args.getlist on all filters.
  • Provide the user with a Filter-URL-Builder (or at least a link with the currently set filters) to generate/bookmark the link to all current filters.

Wrapping `beancount-web` with electron.atom.io

As an addition to the beancount-web [filename]-way of starting beancount-web I'm thinking of wrapping it with http://electron.atom.io to create a standalone-version of the "app".

Motivation: My girlfriend want's to use beancount-web, but she has no idea what a Terminal is or how to run commands/programs in it. I do not want to deploy beancount-web to a public webserver, as this creates costs and the beancount-files would be accessible online, which is not what I want.

Is anyone else interested in this?

Insert marker

Specify an insert marker (like ;;; INSERT HERE) in settings and position cursor in Source editor there.

PermissionError when opening "statistics" page

The .webassets-cache folder should probably be created by setup.py, since that's run with the correct privileges.

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/application.py", line 117, in report
    return render_template('{}.html'.format(report_name))
  File "/usr/local/lib/python3.4/dist-packages/flask/templating.py", line 128, in render_template
    context, ctx.app)
  File "/usr/local/lib/python3.4/dist-packages/flask/templating.py", line 110, in _render
    rv = template.render(context)
  File "/usr/local/lib/python3.4/dist-packages/jinja2/environment.py", line 989, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.4/dist-packages/jinja2/environment.py", line 754, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/statistics.html", line 2, in top-level template code
    {% set active_page = 'statistics' %}
  File "/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/templates/_layout.html", line 70, in top-level template code
    {% assets
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/ext/jinja2.py", line 186, in _render_assets
    urls = bundle.urls()
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 787, in urls
    urls.extend(bundle._urls(new_ctx, extra_filters, *args, **kwargs))
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 746, in _urls
    *args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 600, in _build
    force, disable_cache=disable_cache, extra_filters=extra_filters)
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 474, in _merge_and_apply
    ctx.cache, no_cache_read=actually_skip_cache_here,
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 50, in __getattr__
    return self.getattr(self._parent, item)
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/bundle.py", line 58, in getattr
    return getattr(object, item)
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/env.py", line 438, in _get_cache
    cache = get_cache(self._storage['cache'], self)
  File "/usr/local/lib/python3.4/dist-packages/webassets-0.11.1-py3.4.egg/webassets/cache.py", line 231, in get_cache
    os.makedirs(directory)
  File "/usr/lib/python3.4/os.py", line 237, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.4/dist-packages/beancount_web-0.1.0a2-py3.4.egg/beancount_web/static/.webassets-cache'

500-Error in wsgi:355 when running without --debug

After pulling today, I am no longer able to run beancount-web without --debug. When I do, I get an Internal Server Error (500) at wsgi:355.

According to git-bisect, this is since 838afa4. I suspect this may be related to #38.

When I make sure beancount_web/static is writable for me, the problem goes away, and I see that a packed-general.js file is created in beancount_web/static/stylesheets.

Improve support for include directive

It looks like the tool doesn't handle included files properly. Here's a minimal test case that demonstrate the problem.

invest.bean

include "accounts.bean"
include "a.bean"
include "b.bean"

accounts.bean

2015-12-09 open Assets:AccountA
2015-12-09 open Assets:AccountB

a.bean

include "accounts.bean"

2015-12-09 *
    Assets:AccountA -1 USD
    Assets:AccountB 1 USD

b.bean

include "accounts.bean"

2015-12-10 *
    Assets:AccountA -1 USD
    Assets:AccountB 1 USD

Run beancount-web invest.bean there's no error (except for the benign warning because accounts.bean was included twice), but there's no balance shown on the start page.

Use bean-report -f beancount invest.bean print > /tmp/output.beancount to concatenate everything into a single file, beancount-web works again.

Add second "skin"/"theme"

Rubén Gómez (on the mailing list):

I spent some time and tuned the interface to my own taste, if someone is
interested in the "skin" I can share the CSS.
Screenshots are attached.

Dominik:

This looks really good! Can I include the CSS as a secondary
"theme"/"skin" in beancount-web?

Rubén Gómez:

Sure, the files are attached. I use the font 'ShareTech Mono' [1]
because I prefer the zeros with a dash and also is more condensed than
the default one.
Its license is the SIL Open Font [2] allowing be embedded in web
applications.

[1] http://www.dafont.com/share-techmono.font
[2] http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web

style.zip
bean-04
bean-01
bean-02
bean-03

TODO:

  • Cover all colors in SCSS with variables
  • Diff styles.css with the new skin to find out what changed
  • Add a new scss-file with the variables set to the new values

Keyboard shortcuts [feature request]

This is far out there, and I don't want to distract you from the terrific set of much more important features you're putting in currently, but it's an idea and I thought I'd mention it since this project is shaping up to be very well designed and very functional:

Have you considered adding keyboard shortcuts? An well designed example is gmail: if you don't already use it, then enable it in Settings, then press '?' in the main screen.

I can see keyboard shortcuts being useful for several major categories:

  • navigate to one of the main pages on the left bar
  • change between the handful of graph display options shown on each page
  • turn on and off checkbox options (or show/hide legs) in the transactions page
  • pull down the time/tag/component/payee lists on the top

Save Beancount Queries

One of the distinctive features of Beancount is the ability to write SQL like queries to create custom reports. For example, today I needed to get an overview of my expenses per month over the last year:

SELECT
  MONTH(date) AS month,
  SUM(COST(position)) AS balance
WHERE
   account ~ 'Expenses:' AND
   currency = 'CNY' AND
   YEAR(date) = 2015
GROUP BY 1
ORDER BY 1;

Instead of creating these queries from scratch every time (or having to save them elsewhere), it would be useful if it were possible to save them, right from the Custom Query page.

UI wise, I imagine a select box, Save and Delete button next to the existing Submit Query button. The select box would contain a list of saved queries and a Save as new Query option.

Rethink App state vs. Session state

Currently, the set of filters is saved as a global state on the app object. So it doesn't survive restarts of the server and makes it impractical for several users to access the same beancount-web instance. I recommend we change this to save it as a session state. I can think of two possible ways to do this:

  1. "Clean URLs". Filters are sent as POST requests and the current filters are saved as a cookie. Flask allows us to do this easily. Quite similar to the way it is now, although I would remove the /filter/ endpoint (except for the permalink part), as the redirect makes outputting error messages harder. (as I noticed when trying to port my dateparser exception code to master ;) )
  2. Keep everything in the URL query string. Advantage would be that every URL is automatically a permalink. As we don't have to many filter options, I think it would be more transparent to use the query string to save the session state and would remove the need for a separate permalink url route.

@aumayr which option do you prefer? I have slight preference for 2., but both would be an improvement going forward.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.