-
-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exact assertions & multi commodity balances #871
Changes from 1 commit
71d86f7
e430f40
d6bfc1b
259f185
df966ed
a34950f
f89d198
893ca13
5c6c0d0
e3ecb30
d5063a8
3752e08
7415279
55883aa
df9755f
3696bee
03c6092
ce58572
d7f9028
f091455
b9b09ee
20a8cac
9aa3238
7b7160e
ae2ea34
b3dbe88
edb9ba7
f6f047e
3be314b
1a9fccc
2add5c2
34ebedb
7730f4a
a577404
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -356,6 +356,38 @@ when an amountless posting is balanced using a price's commodity, or | |
when -V is used.) If you find this causing problems, set the desired | ||
format with a commodity directive. | ||
|
||
#### Amount Expressions | ||
|
||
An amount may also be comprised of multiple parts joined by basic | ||
arithmetic operators; in this case, each individual value follows the | ||
structure described above, while the joins allow: | ||
|
||
- addition, subtraction, and multiplication using the standard ASCII | ||
operators (`+`, `-`, `*`), either adjacent to the amount(s) or | ||
separated by spaces | ||
- parenthesised (sub-)expressions, to be evaluated before any | ||
operations outside them. Note, however, that all commodity symbols | ||
must be attached to an amount inside the parentheses: `($10 * 0.2)` | ||
works, `$(10 * 0.2)` does not. | ||
- multiple commodities in the same expression | ||
|
||
Multiplication of commodities is handled a bit differently than may be | ||
expected; if the amount to the right of the operator includes an | ||
explicit commodity, that commodity replaces any to the left for | ||
compatibility with [automated postings](#automated-postings). If that | ||
right value includes multiple commodities itself (parenthesised to obey | ||
the order of operations), the left value is multiplied by each | ||
individually. | ||
|
||
As examples, with the value each expression simplifies to (if | ||
applicable): | ||
|
||
`$47.18-$7.13` -> `$40.05` | ||
`$47.18 - ($20 + $7.13)` -> `$20.05` | ||
`$6.10 + £4.35 * 0.8 €` -> `$6.10 + 3.48 €` | ||
`($6.10 + £4.35) * 0.8 €` -> `8.36 €` | ||
`$6.10 * (£0.2 + 0.8 €)` -> `£1.22 + 4.88 €` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think folks will immediately want division ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding it won't be hard at all, except for divide-by-zero; the operation parser wound up being amazingly extensible. I'm tempted to just make it silently fail, but it's probably better to work through the error reporting system to ensure sanity. I've not looked at that yet, though, so I might put division off until the end of the refactor, if you think that's all right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. division can be a problem too... What would be the amount for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1.6666666666666666... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant: 0.016666666666666666... |
||
### Virtual Postings | ||
|
||
When you parenthesise the account name in a posting, we call that a | ||
|
@@ -460,6 +492,28 @@ that no matter how many assertions you add, you can't be sure the | |
account does not contain some unexpected commodity. (We'll add support | ||
for this kind of total balance assertion if there's demand.) | ||
|
||
|
||
The asserted balance checks only the amount(s) of each listed commodity's | ||
balance within the (possibly larger) account balance. We could call this a | ||
partial balance assertion. This is compatible with Ledger, and makes it | ||
possible to make assertions about accounts containing multiple commodities | ||
without needing to manually track every commodity the account contains. | ||
|
||
To instead assert a balance to the exclusion of all other commodities, use the | ||
exact assertion form `==EXPECTEDBALANCE`. This ensures that the account does | ||
ag-eitilt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
not contain some unexpected commodity, or, equivalently, that the balance of | ||
any unlisted commodities is 0. | ||
|
||
``` {.journal} | ||
2013/1/1 | ||
a $1 = $1 | ||
b = $-1 | ||
|
||
2013/1/2 | ||
a 1€ = $1 + 1€ | ||
b -1€ = $-1 - 1€ | ||
``` | ||
|
||
#### Assertions and subaccounts | ||
|
||
Balance assertions do not count the balance from subaccounts; they check | ||
|
@@ -1242,9 +1296,14 @@ something.): | |
``` | ||
|
||
The posting amounts can be of the form `*N`, which means "the amount of | ||
the matched transaction's first posting, multiplied by N". They can also | ||
be ordinary fixed amounts. Fixed amounts with no commodity symbol will | ||
be given the same commodity as the matched transaction's first posting. | ||
the matching posting(s), multiplied by N". They can also be ordinary | ||
fixed amounts (which are inserted unchanged) or [amount | ||
expressions](#amount-expressions) headed by either (only the | ||
multiplication to the left of the first addition or subtraction will be | ||
applied to the posting value). | ||
|
||
Any postings in real transactions which attempt to use this | ||
multiplication-headed form will ignore the value instead. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't understand "headed by" onward exactly. Shall we simplify again, deleting those lines ? Ie we will accept an amount, an amount expression, or a numeric multiplier ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blame a couple years of linguistics. That's the passage that was primary in the "first draft" naming of the commit. I'll revisit this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the "those can wait", I might actually put the first step of the PR together without multiplication entirely. Addition and subtraction are a much more contained change, and seem to generate much less discussion (while being more frequently requested). We should definitely keep working out the questions around multiplication, but splitting things further like that means there's less pressure to resolve it so we can find something we're all happier with. |
||
|
||
This example adds a corresponding ([unbalanced](#virtual-postings)) | ||
budget posting to every transaction involving the `expenses:gifts` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should discard commodities. Can we instead disallow multiplying by amounts, ie only multiplying by a number will be legal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, and that was actually my first plan, but then I looked into the transaction modifiers and found that this is exactly how they currently operate. It's undocumented behaviour, so reverting that wouldn't as bad as it could be, but I was afraid someone else might have figured that out and was relying on that in their ledgers -- I can come up with a scheme managing gift cards/certificates (via different commodities) easily enough that that I'm sure there's more realistic usages out there as well.
I can probably rework the parsing to enforce that distinction, but we really don't want to have one type of multiplication at the beginning of transaction modifiers and another in expressions. Is disallowing multiplying by amounts worth potentially breaking journals? I obviously don't think so (it might not be what's immediately expected, but I feel it wouldn't be particularly tricky for users to get the hang of), but I'm not so strongly strongly attached to that that I'll argue this any further, if you still prefer it. Give the word and I'll add it to the cleanup list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! I'd rather enforce that the multiplier is a commodityless number for now. Quietly discarding information from one side of an expression is something we should avoid. I'll clarify this in docs. I agree that it should work the same in transaction modifiers and in amount expressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First take of it at #913, pending further discussion.