hledger icon indicating copy to clipboard operation
hledger copied to clipboard

Balance assignment with subaccounts affects other commodities

Open wgslr opened this issue 1 year ago • 2 comments

Using the =* balance assignment on an account with subaccounts sets all other commodities balance to 0. According to the documentation, other commodities should be unaffected as long as I'm using =* and not ==*. Compare the following examples:

Without subaccounts - correct behaviour

2023-10-01 | Add EUR
    equity            -10eur
    assets             10eur

2023-10-01 | Add USD
    equity            -12usd
    assets             12usd

2023-10-02 | Assign
    assets                 =* 20usd
    equity

The assignment transaction adds $8 to achieve the balance of $20, but eur is unaffected - as expected:

$ hledger print -x
2023-10-01 | Add EUR
    equity          -10eur
    assets           10eur

2023-10-01 | Add USD
    equity          -12usd
    assets           12usd

2023-10-02 | Assign
    assets            8usd =* 20usd
    equity           -8usd
$ hledger balance assets
               10eur
               20usd  assets
--------------------
               10eur
               20usd  

With subaccounts - unexpected behaviour

Asserting total balance of an account which has subacounts

2023-10-01 | Add EUR
    equity          -10eur
    assets           10eur

2023-10-01 | Add USD
    equity          -12usd
    assets           12usd

2023-10-02 | Assign
    assets                 =* 20usd
    equity

Now, a -10eur posting appears and clears the eur balance of assets:

$ hledger print -x
2023-10-01 | Add EUR
    equity               -10eur
    assets:cash           10eur

2023-10-01 | Add USD
    equity               -12usd
    assets:cash           12usd

2023-10-02 | Assign
    assets          -10eur
    assets            8usd =* 20usd
    equity           10eur
    equity           -8usd

$ hledger reg assets
2023-10-01 | Add EUR             assets:cash                  10eur         10eur
2023-10-01 | Add USD             assets:cash                  12usd         10eur
                                                                            12usd
2023-10-02 | Assign              assets                      -10eur              
                                                               8usd         20usd

$ hledger balance assets
              -10eur
                8usd  assets
               10eur
               12usd  assets:cash
--------------------
               20usd  

Expected behaviour

I'd expect a single posting assets 8usd be generated to get the correct usd balance, and eur balance to remain -10eur.

Note that this works correctly when the posting value is given explicitely:

# journal.hledger
2023-10-01 | Add EUR
    equity   -10eur
    assets:cash   10eur

2023-10-01 | Add USD
    equity   -12usd
    assets:cash  12usd

2023-10-02 | Assert
    assets   8usd =* 20usd
    equity   
hledger balance assets
                8usd  assets
               10eur
               12usd  assets:cash
--------------------
               10eur
               20usd  

wgslr avatar Oct 01 '23 19:10 wgslr

Thanks for the report. I see what you mean. It seems to me that https://hledger.org/dev/hledger.html#balance-assignments documents this, but https://hledger.org/dev/hledger.html#balance-assignments is not clear; it only says "These are like balance assertions...". So I can understand your expectation and perhaps that is how it should work; I'm not opposed. I think some test cases and some consideration/discussion of the impact of changing the behaviour are needed.

simonmichael avatar Oct 05 '23 17:10 simonmichael

Thanks for the response! If it was simply a matter of '=* balance assignment is always the same as ==*' I could agree that believing otherwise was an unfounded assumption based on the analogy to balance assertions. But that is not the case, as the behavior differs between a leaf account and one that has subaccounts. ==* will always zero the other commodities, but =* will only do so if subaccounts are involved. That seems like a good indicator that the current behaviour is a bug.

I think some test cases and some consideration/discussion of the impact of changing the behaviour are needed.

That's a fair point, someone might rely on the current behavior and have a journal using =* as if it was ==*. On the other hand, I'd hope it's a niche feature, as proven by the issue not being reported earlier. And at least in my case, the current behaviour meant less usage of =*, since I couldn't use it on multicommodity accounts.

wgslr avatar Oct 13 '23 19:10 wgslr