Automatic transaction to add tags?

216 views
Skip to first unread message

Martin Michlmayr

unread,
Aug 4, 2015, 4:17:35 PM8/4/15
to ledge...@googlegroups.com
I've come to the conclusion that I have to add a Tax-Year tag to all
postings involving Expenses:Tax because tax refunds or payments can
come years later and --pivot Tax-Year will allow me to figure out how
much tax I paid for a given tax year.

I started adding Tax-Year meta tags to my ledger files when I realized
that this approach is ugly. Instead, it makes more sense to tag
certain outliers with the tag manually and tag everything else
automatically.

Unfortunately, this is rather complex in my case. Is there a way to
do something like this in ledger:

if account =~ /^Income:Tax/ && (commodity == EUR or commodity == USD) && !has_tag('Tax-Year'):
add_tag('Tax-Year', $effective_date.year)

if account =~ /^Income:Tax/ && commodity == GBP && !has_tag('Tax-Year'):
if $effective_date >= $year-04-06 # the UK tax year starts on yyy-04-06
add_tag('Tax-Year', $year-$year+1)
else
add_tag('Tax-Year', $year-1-$year)

I assume the answer is "no", but is there a way to do this in ledger?
(Maybe with a Python function embedded in ledger code?)

(I assume Martin Blais will say this is trivial to do in beancount
with a plugin, but I think I'll ask about this on the beancount list.)
--
Martin Michlmayr
http://www.cyrius.com/

Peter Keen

unread,
Aug 4, 2015, 4:26:37 PM8/4/15
to Ledger
Try this:

= /Income:Tax/ and not %Tax-Year and expr date >= [2015/04/06] && date < [2016/04/05] && commodity == "GBP"
    ; Tax-Year: 2015

I don't think you can drop a calculation into the tag value, unfortunately, but this would apply the tag correctly. You'd just have to have a string of them for each tax year you have.

--

---
You received this message because you are subscribed to the Google Groups "Ledger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ledger-cli+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Peter Keen

unread,
Aug 4, 2015, 4:27:12 PM8/4/15
to Ledger
Sorry, that should be:

= /Income:Tax/ and not %Tax-Year and expr date >= [2015/04/06] && date < [2016/04/06] && commodity == "GBP"
    ; Tax-Year: 2015

John Wiegley

unread,
Aug 4, 2015, 4:33:07 PM8/4/15
to ledge...@googlegroups.com
>>>>> Martin Michlmayr <t...@cyrius.com> writes:

> if account =~ /^Income:Tax/ && (commodity == EUR or commodity == USD) && !has_tag('Tax-Year'):
> add_tag('Tax-Year', $effective_date.year)

I think something along the lines of...

= expr account =~ /^Income:Tax/ && (commodity == EUR or commodity == USD) && !has_tag('Tax-Year')
; Tax-Year: (format_date("%Y", effective_date))

Though I'm a bit rusty at these now. However, you can use automated
transaction to annotate metadata for the matching posting/transaction.

John

Martin Michlmayr

unread,
Aug 4, 2015, 5:53:07 PM8/4/15
to ledge...@googlegroups.com
Thanks Peter and John.

This one will work for countries where the tax year == the calendar year,
regardless of the year:

= /^Expenses:Tax/ and not %Tax-Year and expr commodity == 'EUR' or commodity == 'USD'
; Tax-Year:: (format_date(effective_date or date, "%Y"))

Unfortunately, despite John's help on IRC, I couldn't figure out how to do
this for countries where the tax year differes. So I'll go with Peter's
solution:

= /^Expenses:Tax/ and not %Tax-Year and expr commodity == 'GBP' and date >= [2014-04-06] && date < [2015-04-06]
; Tax-Year: 2014-15

= /^Expenses:Tax/ and not %Tax-Year and expr commodity == 'GBP' and date >= [2015-04-06] && date < [2016-04-06]
; Tax-Year: 2015-16

(Note that this doesn't work if there's an effective_date that is in a
different tax year as date; I tried to use:
(effective_date or date) >= [2013-04-06]
but that gives an error.)

With John's help, I came up with the following:

= /^Expenses:Tax/ and not %Tax-Year and expr commodity == 'GBP' and effective_date or date < [April 6]
; Tax-Year:: str(int(format_date(effective_date or date, "%Y")) - 1) + "-" + (format_date(effective_date or date, "%g")))

= /^Expenses:Tax/ and not %Tax-Year and expr commodity == 'GBP' and effective_date or date >= [April 6]
; Tax-Year:: (format_date(effective_date or date, "%Y")) + "-" + str(int(format_date(effective_date or date, "%g")) + 1))

but the problem is that [April 6] uses the current year and not the year of
the transaction.



* Peter Keen <peter...@bugsplat.info> [2015-08-04 16:27]:

Martin Blais

unread,
Aug 4, 2015, 10:54:47 PM8/4/15
to ledger-cli
On Tue, Aug 4, 2015 at 4:17 PM, Martin Michlmayr <t...@cyrius.com> wrote:
I've come to the conclusion that I have to add a Tax-Year tag to all
postings involving Expenses:Tax because tax refunds or payments can
come years later and --pivot Tax-Year will allow me to figure out how
much tax I paid for a given tax year.
[...] 
(I assume Martin Blais will say this is trivial to do in beancount
with a plugin, but I think I'll ask about this on the beancount list.)

Come on Martin you know me better than this...

This is actually a perfect case for putting it in the account name. I know we've disagreed about this usage before and I do realize that in many cases using metadata (Ledger "tags") can work too, but in this case it definitely makes sense to use dedicated accounts, because the governments - at least the Canada and US govts - maintain per-year balances for you.

I create the accounts like this:

2015-01-01 open Expenses:Taxes:TY2015:US:Installments                            USD ; Estimated payments 1040ES
2015-01-01 open Expenses:Taxes:TY2015:US:Medicare                                USD ; "Employee Medicare"
2015-01-01 open Expenses:Taxes:TY2015:US:Federal                                 USD ; "Federal Income Tax"
2015-01-01 open Expenses:Taxes:TY2015:US:CityNYC                                 USD ; "New York R"
2015-01-01 open Expenses:Taxes:TY2015:US:SDI                                     USD ; "NY Disability Employee"
2015-01-01 open Expenses:Taxes:TY2015:US:StateNY                                 USD ; "NY State Income Tax"
2015-01-01 open Expenses:Taxes:TY2015:US:SocSec                                  USD ; "Social Security Employee Tax"

I close the accounts the following year once I get confirmation that my balance is zero, with similar "close" directives.

I don't see a need to automate this, in fact, I think it might be dangerous to do so especially if you're being called on to make back-payments many years behind (some states have a tendency to perform their audits right before their deadline to do so you can get a letter 3 years after you file for that year), but if you really do want to book everything to the same accounts, hum, I would say "it is trivial to do in Beancount with a plugin." ;-)



Martin Michlmayr

unread,
Aug 6, 2015, 12:06:33 PM8/6/15
to ledge...@googlegroups.com
* Martin Blais <bl...@furius.ca> [2015-08-04 22:54]:
> This is actually a perfect case for putting it in the account name.
> I know we've disagreed about this usage before

Yeah, and I'm still not convinced of putting it in the account name.
I guess the advantage of your approach is that you *have* to specify a
tax year whereas in my approach using metadata it would be optional so
there's more risk of not adding a right tag.

My approach (a simple account name, plus metadata to define the tax
year where it deviates plus an automated transaction to assign default
tax years based on the date of a transaction) seems more elegant to
me, but who knows... I'm refining my ledger usage all the time.

Simon Michael

unread,
Aug 6, 2015, 2:30:05 PM8/6/15
to ledge...@googlegroups.com
On 8/4/15 7:54 PM, Martin Blais wrote:
> makes sense to use dedicated accounts, because the governments - at least
> the Canada and US govts - maintain per-year balances for you.

+1, that's how I do it too, because for me it seems the most direct way
to model "reality.

Kyle Spaans

unread,
Aug 11, 2015, 11:18:29 AM8/11/15
to ledge...@googlegroups.com
+1 from me too! I also use an explicit sub-account with the fiscal year and country(!!!) for both taxes and income. (I had to pay income tax in both Canada and the UK last year.)

Reply all
Reply to author
Forward
0 new messages