Giter Club home page Giter Club logo

beancount2ledger'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]>

beancount2ledger's People

Contributors

blais avatar davidhelbig avatar tbm avatar zacchiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

beancount2ledger's Issues

Add support for ledger lot dates and notes to bean-report

Original report by Marin Bernard (Bitbucket: marinbernard, GitHub: marinbernard).


While bean-report supports the conversion of beancount lot expressions to ledger syntax, it currently discards lot dates and notes. The following transaction:

2020-01-01 open Assets:Bank
2020-01-01 open Expenses:Computers
2020-01-01 commodity COMPUTER
    format: "1, COMPUTER"

2020-01-01 commodity USD

option "operating_currency" "USD"

2020-02-01 * "Super Shop"  "New computer"
    Expenses:Computers       1 COMPUTER {900.00 USD, 2019-12-25, "DiscountedComputer"} @ 1100.00 USD
    Assets:Bank

Is currently rendered as:

account Assets:Bank                                    

account Expenses:Computers                             

commodity COMPUTER

commodity USD

2020-02-01 * Super Shop | New computer
  Expenses:Computers                    1 COMPUTER {900.00 USD} @ 1100.00 USD
  Assets:Bank                                      -900.00 USD

Since ledger also supports lot dates/notes, bean-report should ideally include them in the output, like:

account Assets:Bank                                    

account Expenses:Computers                             

commodity COMPUTER

commodity USD

2020-01-01 * Super Shop | New computer
    Expenses:Computers  1 COMPUTER [2019-12-25] {900.00 USD} (ChristmasDiscountedComputer) @ 1100.00 USD
    Assets:Bank

This would actually make bean-report usable as a converter for complex journals full of lot annotations.

allow to read input from stdin

As per title.

Weirdly enough, currently beancount2ledger accepts "-" as an argument, without failing, but it does nothing:

$ beancount2ledger - < current.beancount

$

$ beancount2ledger < current.beancount 
usage: beancount2ledger [-h] [-f {ledger,hledger}] [-V] file
beancount2ledger: error: the following arguments are required: file
$

$ beancount2ledger current.beancount 
# this works as expected

Changes account names in meta-data strings

Test case:

2022-12-21 * "Test"
  foo: "Assets:Test"
  Assets:Test                           10.00 EUR
  Assets:Test                          -10.00 EUR
  foo: "Assets:Test"

Config:

account_map:
  "Assets:Test": "Assets:Bar"

Output:

2022-12-21 * Test
  ; foo: Assets:Test
  Assets:Bar                                                     10.00 EUR
  Assets:Bar                                                    -10.00 EUR
    ; foo: Assets:Bar

The first foo meta-data stays the same, but the second one is modified - it shouldn't be because it's a string.

Add @ entries if ledger can't do implicit conversion

Converting this to ledger works fine:

2020-10-23 * "Test"
    Assets:Property                   0.1 FOO {300.00 EUR}
    Assets:Property                   0.2 BAR {200.00 EUR}
    Equity:Opening-Balance

But if we change it to

2020-10-23 * "Test"
    Assets:Property                   0.1 FOO {300.00 EUR, 2020-10-22}
    Assets:Property                   0.2 BAR {200.00 EUR}
    Equity:Opening-Balance

we get:

0.2 BAR {200.000 EUR}
         -70.000 EUR
0.1 FOO {300.000 EUR} [20-Oct-22]
Amount to balance against:
0.2 BAR {200.000 EUR}
0.1 FOO {300.000 EUR} [20-Oct-22]
Error: Transaction does not balance

This is because the date make it not just EUR. (I wonder if this is a bug in ledger or not.)

I need to think about the different scenarios but it would be good to deal with this somehow.

Should preserve metadata

Metadata is currently lost in conversion:

2020-07-17 * "Test"
  string: "foo"
  year: 2020
  date: 2020-07-19
  Assets:Test     10.00 EUR
  Assets:Test    -10.00 EUR

Result:

2020-07-17 * Test
  Assets:Test                                                      10.00 EUR
  Assets:Test                                                      -10.00 EUR

Missing yaml dependency for python package

After installing beancount2ledger using pip install beancount2ledger on Windows, I'm getting this error:

PS C:\Users\brrts\git\ledger> beancount2ledger
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\brrts\scoop\apps\python\current\Scripts\beancount2ledger.exe\__main__.py", line 4, in <module>
  File "C:\Users\brrts\scoop\apps\python\current\Lib\site-packages\beancount2ledger\cli.py", line 16, in <module>
    import yaml
ModuleNotFoundError: No module named 'yaml'

Running pip install pyyaml resolves the issue.

`pad` directive not being fully converted

If I have this in beancount:

2022-01-01 pad Assets:US:Chase:Checking Equity:Opening-Balances
2022-04-07 balance Assets:US:Chase:Checking 1000.00 USD

This tool outputs:

;; Pad: 2022-01-01 Assets:US:Chase:Checking Equity:Opening-Balances

2022-01-01 (Padding inserted for Balance of 1000.00 USD for difference 1000.00 USD)
  Assets:US:Chase:Checking                                      1000.00 USD

I expecting the output to also contain Equity:Opening-Balances -1000.00 USD, but this was missing and this causes the transaction to not balance.

bean-report produces invalid hledger postings for lots with both a price and a cost

Original report by Marin Bernard (Bitbucket: marinbernard, GitHub: marinbernard).


For instance, invoking bean-report hledger with the following journal file:

2020-01-01 open Assets:Bank
2020-01-01 open Expenses:Grocery
2020-01-01 commodity SALAD
2020-01-01 commodity USD

option "operating_currency" "USD"

2020-01-01 * "Grocery"  "Salad"
    Expenses:Grocery                5 SALAD  {1.00 USD} @   1.00 USD
    Assets:Bank

2020-01-01 * "Grocery"  "Salad"
    Expenses:Grocery                5 SALAD  {1.00 USD} @@  5.00 USD
    Assets:Bank

2020-01-01 * "Grocery"  "Salad"
    Expenses:Grocery                5 SALAD {{5.00 USD}} @  1.00 USD
    Assets:Bank

2020-01-01 * "Grocery"  "Salad"
    Expenses:Grocery                5 SALAD {{5.00 USD}} @@ 5.00 USD
    Assets:Bank

Returns:

;; Open: 2020-01-01 close Assets:Bank

;; Open: 2020-01-01 close Expenses:Grocery

commodity SALAD

commodity USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                                 5 SALAD @ 1.00 USD       @ 1.00 USD
  Assets:Bank                                                             -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                                 5 SALAD @ 1.00 USD       @ 1.00 USD
  Assets:Bank                                                             -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                                 5 SALAD @ 1.00 USD       @ 1.00 USD
  Assets:Bank                                                             -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                                 5 SALAD @ 1.00 USD       @ 1.00 USD
  Assets:Bank                                                             -5.00 USD

Expected output:

;; Open: 2020-01-01 close Assets:Bank

;; Open: 2020-01-01 close Expenses:Grocery

commodity SALAD

commodity USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                    5 SALAD @ 1.00 USD
  Assets:Bank                                                  -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                    5 SALAD @ 1.00 USD
  Assets:Bank                                                  -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                    5 SALAD @ 1.00 USD
  Assets:Bank                                                  -5.00 USD

2020-01-01 * Grocery | Salad
  Expenses:Grocery                                    5 SALAD @ 1.00 USD
  Assets:Bank                                                  -5.00 USD

Even if specifying equal costs and prices does not make sense, this is still legal beancount syntax, and should result in valid hledger data.

PyYAML not declared as dependency

PYYaml is used in the cli.py module without being set as a dependency in setup.cfg and requirements.txt.

This prevents the cli from running in environments where PYaml is not already installed.

ModuleNotFoundError: No module named 'yaml'

Step to reproduce:
Install current master branch in a fresh virtual environment and run beancount2ledger command.

Multiline strings lead to error

Beancount strings can be split across several lines:

2010-01-01 open Assets:Test
2010-01-01 open Equity:Opening-Balance

2019-03-05 txn "Foo
bar"
  Assets:Test                        10.00 EUR
  Equity:Opening-Balance            -10.00 EUR

This leads to an invalid ledger file.

Map accounts and currencies?

I'm wondering if beancount2ledger should have the functionality to map account names and currencies.

I see two big disadvantages:

  • It makes the code more complex
  • All beancount account names and currencies are valid in ledger (*), so this isn't "needed".

(*) I thought one character was allowed in beancount currencies but not in ledger, but I can't find any evidence for this right now and maybe I was wrong.

OTOH, this would be useful for those going the ledger -> beancount -> ledger route and who might have different account names in ledger and beancount.

Arguably, it could be solved with a "contrib" Perl script, and maybe this is the way to go (although a simple s/.../.../ might not be enough, and if we start adding complexity why not do it in beancount2ledger itself?). Then again, maybe I'm overcomplicating things and a fairly simple s/.../.../ is good enough.

@zacchiro any opinion on this?

Initially I was going to add it to beancount2ledger itself, but it's not as easy as I thought, and now I'm thinking a contrib script might be better.

Support aux dates

Support aux dates from (configurable) meta-date:

2018-03-17 * "Test with transaction aux date"
  aux-date: 2018-03-16
  Assets:Test                        10.00 EUR
  Equity:Opening-Balance            -10.00 EUR

TypeError: 'NoneType' object is not iterable on padding transaction

2000-01-01 open Assets:Test1
2000-01-01 open Assets:Test2

2019-01-21 pad Assets:Test1 Assets:Test2
2019-01-22 balance Assets:Test1   10.00 GBP

results in

  File "/home/tbm/src/tbm/beancount2ledger/beancount2ledger/ledger.py", line 167, in Posting
    for key, val in user_meta(posting.meta).items():
  File "/home/tbm/src/tbm/beancount2ledger/beancount2ledger/ledger.py", line 39, in user_meta
    return {key: meta[key] for key in meta if key not in ignore}
TypeError: 'NoneType' object is not iterable

Creates too much precision for unrelated commodity

2020-10-23 * "Test"
    Assets:Property                   0.11111 FOO {300.00 EUR}
    Equity:Opening-Balance

leads to

2020-10-23 * Test
  Assets:Property                                  0.11111 FOO {300.00 EUR}
  Equity:Opening-Balance                                    -33.3330000 EUR

The precision for EUR is wrong.

Error with commodity containing - or .

Generally, ledger is more permissive than beancount. However, beancount allows the minus symbol in commodities, which is not allowed in ledger.

2000-01-01 open Assets:Test

2020-07-24 * "Commodity with minus"
  Assets:Test                  10 GBP-EUR
  Assets:Test
ledger -f x bal                                                                                          master
While parsing file "/home/tbm/src/tbm/beancount2ledger/x", line 4:
While parsing posting:
  Assets:Test                                                    10 GBP-EUR
                                                                 ^^^^^^^^^^
Error: Unexpected char '-' (Note: inline math requires parentheses)

map_account not applied if no amount and followed by meta-data

The first Assets:Rename-Me does not get renamed whereas the second does:

2022-12-22 * "Test for account_map"
  Expenses:Foo                             10.00 EUR
  Assets:Rename-Me
    card: 1234

2022-12-22 * "Test for account_map"
  Expenses:Foo                             10.00 EUR
  Assets:Rename-Me                        -10.00 EUR
    card: 1234

Config

account_map:
  "Assets:Rename-Me": "Assets:New-Name"

Output:

2022-12-22 * Test for account_map
  Expenses:Foo                                                    10.00 EUR
  Assets:Rename-Me
    ; card:: 1234

2022-12-22 * Test for account_map
  Expenses:Foo                                                    10.00 EUR
  Assets:New-Name                                               -10.00 EUR
    ; card:: 1234

Add balance assertions

          # We cannot output balance directive equivalents because Ledger only
          # supports file assertions and not dated assertions.

Right, but there could be an option to turn it on.

Preserve comments when exporting to ledger

Original report by Alen Šiljak (Bitbucket: Alen Siljak, GitHub: MisterY).


bean-report ledger seems a good option to export/convert to ledger format directly. It would be useful to keep as much information as possible.

Since account directives store less information than in ledger format, it would be useful to preserve comments.

I.e. The account description, number, contact details, URLs, and other metadata may be stored in comments next to the account.

Relicense to GPLv2 or later

I'd like to distribute beancount2ledger under GPLv2 or later. Beancount is GPLV2 only.

@blais can you give permission to re-license your code (the bean-report ledger/hledger related code) under GPLv2 or later.

Adds posting amount even when not given


2020-01-01 open Assets:Test

2020-07-24 * "Test"
  Assets:Test     100.00 EUR
  Assets:Test

becomes:

account Assets:Test

2020-07-24 * Test
  Assets:Test                                                    100.00 EUR
  Assets:Test                                                   -100.00 EUR

But -100.00 EUR was not specified, so it might be more idiomatic not to show it.

Be smarter about rounding entries

I'm seeing entries like, which I'm sure are not necessary, and actually make things worse:

  Equity:Rounding                                          0.00000000000000000000001 GBP

Reading from stdin broken

This used to work, but after upgrading from buster to bullseye it stopped working for me:

$ beancount2ledger x
2021-01-06 * Test
    Assets:Current                                                -0.04 USD
    Equity:Rounding                                                0.04 USD
$ cat x | beancount2ledger -

$

And my shell script which does:

bean-extract beancount/config.py | beancount2ledger -

now shows:

Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipeError: [Errno 32] Broken pipe

ValueError: Sign not allowed in string format specifier

  File "/home/tbm/src/tbm/beancount2ledger/beancount2ledger/ledger.py", line 122, in Transaction
    self.Posting(posting, entry)
  File "/home/tbm/src/tbm/beancount2ledger/beancount2ledger/ledger.py", line 163, in Posting
    posting_str = f'  {flag_posting}  {quote_currency(pos_str):>{len_amount}} {quote_currency(price_str)}'
ValueError: Sign not allowed in string format specifier

Only one posting with null amount allowed per transaction

Consider:

2010-01-01 open Assets:Cash
2010-01-01 open Equity:Opening-balance

2020-01-01 * "Opening balance: cash"
  Assets:Cash                                               0.10 EUR
  Assets:Cash                                               1.00 GBP
  Equity:Opening-balance

This leads to:

account Assets:Cash

account Equity:Opening-balance

2020-01-01 * Opening balance: cash
  Assets:Cash                                                      0.10 EUR
  Equity:Opening-balance
  Assets:Cash                                                      1.00 GBP
  Equity:Opening-balance

which leads to:

While parsing file "/home/tbm/src/tbm/beancount2ledger/x", line 11:
Error: Only one posting with null amount allowed per transaction

Doesn't quote commodities that contains spaces

b2l doesn't quote commodities that contains spaces.

I think that's a bug I introduced when I added the account renaming feature. We can now rename accounts and those new names can contain characters not allowed by beancount, so we need to take them into consideration too.

docs: order of tags can change

Meta-data is not ordered in beancount.

Test:

2020-01-01 open Assets:Test

2022-12-26 * "Test order of tags"
    #foo
    #bar
    Assets:Test         10.00 EUR
    Assets:Test        -10.00 EUR

Output:

2022-12-26 * Test order of tags
    ; :bar:foo:
    Assets:Test                                                   10.00 EUR
    Assets:Test                                                  -10.00 EUR

This is a known issue, so needs to be documented.

Loses precision on amounts!

b2l turns 10.2253 units into 10.22 units, which means the file no longer balances.

It seems the precision is influenced by other transactions. If the transaction is followed by 2 or more with lower precision, that precision is adopted. If there's only 1 other transaction, it's not lost.

2022-12-21 * "Investment"
    Assets:Investments  10.2253 GB00B80QFW04 {2.984917082 GBP}
    Assets:Investments

2022-12-21 * "Investment"
    Assets:Investments   1.12 GB00B80QFW04 {2.984917082 GBP}
    Assets:Investments

2022-12-21 * "Investment"
    Assets:Investments   2.23 GB00B80QFW04 {2.984917082 GBP}
    Assets:Investments

Output:

2022-12-21 * Investment
    Assets:Investments               10.23 "GB00B80QFW04" {2.984917082 GBP}
    Assets:Investments
...

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.