'print' doesn't keep balance assertions?

60 views
Skip to first unread message

Michael Iles

unread,
Apr 27, 2015, 10:06:36 AM4/27/15
to ledge...@googlegroups.com
(Background: in the process of moving from GnuCash; my main draw to ledger is #1 the balance assertions, and #2 that it fits into a typical Linux toolchain, especially that I can use source control for data files.)

I don't know if this is best practice (feedback welcome!) but my current approach to import new transactions is to put them in a file which includes my previous ledger file, and then do 'ledger -f old.ledger --sort d --empty print > new.ledger' to create a new ledger with everything in the right order.

I'm using a lot of balance assertions because I frequently refactor old transactions. I found that balance assertions require the ledger to be fully sorted, so I can't avoid this rewriting step. I found this refactoring to be very painful in GnuCash precisely because it doesn't have the ability to do balance assertions, so anytime the current balance didn't line up I would have to do a laborious binary search through the account history to figure out where things went wrong.

My problem now is that balance assertions aren't preserved when using 'print'... so my rewriting step doesn't work because it doesn't preserve all the information in the ledger.

What should I do? Is there a flag similar to '--empty' that will tell ledger to preserve the balance assertions? This would actually be a showstopper for me, if I was unable to import new transactions and still preserve old transactions.

Thanks,
Mike.


John Wiegley

unread,
Apr 27, 2015, 10:29:16 AM4/27/15
to ledge...@googlegroups.com
>>>>> Michael Iles <michae...@gmail.com> writes:

> My problem now is that balance assertions aren't preserved when using
> 'print'... so my rewriting step doesn't work because it doesn't preserve all
> the information in the ledger.

> What should I do? Is there a flag similar to '--empty' that will tell ledger
> to preserve the balance assertions? This would actually be a showstopper for
> me, if I was unable to import new transactions and still preserve old
> transactions.

Try --raw, which preserves exactly what you specified in the original file,
rather than "cooking" it.

John

Michael Iles

unread,
Apr 27, 2015, 11:13:00 AM4/27/15
to ledge...@googlegroups.com
Ah, I missed `--raw`, thank you! I had an additional problem too, I was doing this:

2015/2/1 initial balance
    Assets     $20
    Income

2015/2/4 Checkpoint
    Assets   = $20

In this case `ledger print --raw --empty` would still fail to display the checkpoint, but when I change to:

2015/2/1 initial balance
    Assets     $20
    Income

2015/2/4 Checkpoint
    Assets   $0 = $20

Then it works. Maybe worthy of a minor bug, or maybe my original syntax isn't legal. In any case I can proceed, thank you!

Mike.

Martin Blais

unread,
Apr 27, 2015, 11:22:28 AM4/27/15
to ledger-cli
On Mon, Apr 27, 2015 at 9:57 AM, Michael Iles <michae...@gmail.com> wrote:
(Background: in the process of moving from GnuCash; my main draw to ledger is #1 the balance assertions, and #2 that it fits into a typical Linux toolchain, especially that I can use source control for data files.)

I don't know if this is best practice (feedback welcome!) but my current approach to import new transactions is to put them in a file which includes my previous ledger file, and then do 'ledger -f old.ledger --sort d --empty print > new.ledger' to create a new ledger with everything in the right order.

I'm using a lot of balance assertions because I frequently refactor old transactions.

Ditto here. I'm using balance assertions liberally, and I love the ability to fix things in the past where I need to! It's a really powerful idea.

I think other types of constraints should be added eventually, e.g. "check that the value of this account never goes under zero" for example, or that accounts should never be allowed to contain two lots of some commodity with differing signs.

 
I found that balance assertions require the ledger to be fully sorted, so I can't avoid this rewriting step.

This is an unfortunate consequence of Ledger's processing model IMO (it processes postings in file order in order to run a single pass over the data). You may want to read this thread, which had a discussion about this in the past:

I discuss two different types of balance assertions here:

In particular, Beancount and Ledger differ on this matter; Ledger processes postings in line order (AFAIK this is purely for efficiency), where Beancount sorts all types of entries (transactions, balance assertions and all others types) by date+line order before processing verifications (to ensure semantics that are independent of declaration ordering).


 
I found this refactoring to be very painful in GnuCash precisely because it doesn't have the ability to do balance assertions, so anytime the current balance didn't line up I would have to do a laborious binary search through the account history to figure out where things went wrong.

Without balance assertions and a significant amount of automated verification my experience it that is simply impossible to enter even just a few years of data without making many mistakes. 

The level of verification and error-detection you will gain from command-line accounting is potentially much higher. As an example, check out this recent feature I've added to automatically detect a class of errors in entering stock transactions:


My problem now is that balance assertions aren't preserved when using 'print'... so my rewriting step doesn't work because it doesn't preserve all the information in the ledger.

What should I do? Is there a flag similar to '--empty' that will tell ledger to preserve the balance assertions? This would actually be a showstopper for me, if I was unable to import new transactions and still preserve old transactions.

My take on this is that you should never have to manipulate your source that way. Source should be pristine, and as your input grows you will want to have lots of comments in there and possibly some organizational structure as well. In particular, you can use org-mode or some other outline mode to segment your transactions in a way that makes sense to you, e.g. by account. This makes manual updates a lot nicer and your input file significantly more readable. Sorting undoes that nice input file, it's not a great compromise.

IMO the semantics of the software should be adjusted to match the expectation of the user. This is what I do in Beancount and why I provide dated assertions. No file rewriting is ever necessary. File-based assertions will be added at some point, but IMO they're superfluous (I'll do it because they're so easy to add, and maybe it'll add some more semantic level of portability between Ledger and Beancount).

The only drawbacks of dated assertions is that they can only occur at the beginning of a day, so (1) you may have to fudge/increment a date here and there, and (2) you won't be able to correctly do intra-day assertions where amounts are posted before and after the assert. Beancount explicit limits time representation to dates (I really wanted to squeeze the design to optimize for simplicity) and while at first sight this may sound like a potential problem, in my experience this limitation has never been a real issue: cases where you'll really have to skip a balance assertion are quite rare in practice.

John Wiegley

unread,
Apr 27, 2015, 11:39:49 AM4/27/15
to ledge...@googlegroups.com
>>>>> Martin Blais <bl...@furius.ca> writes:

> I think other types of constraints should be added eventually, e.g. "check
> that the value of this account never goes under zero" for example, or that
> accounts should never be allowed to contain two lots of some commodity with
> differing signs.

This can be done with a "check" directive associated with the account:

account Foo
check amount > 0

John

maktak

unread,
Jun 14, 2019, 3:30:31 PM6/14/19
to Ledger

On Monday, April 27, 2015 at 11:39:49 AM UTC-4, John Wiegley wrote:

This can be done with a "check" directive associated with the account:

    account Foo
        check amount > 0


Can you specify a value date with the above command? When reconciling account balances, I need to specify the date.
Reply all
Reply to author
Forward
0 new messages