File: tips.md

package info (click to toggle)
ledger2beancount 2.7-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 904 kB
  • sloc: perl: 1,920; sh: 151; makefile: 22
file content (162 lines) | stat: -rw-r--r-- 4,496 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

# Tips and tricks

## Pre- and post-processing

While ledger2beancount is fairly powerful and configurable, it won't
meet all needs.  In some cases, it makes more sense to pre-process the
input file or post-process the output file rather than to add more
features to ledger2beancount.

An example where pre-processing is useful are ledger transactions that
were created with [ledger's convert](https://www.ledger-cli.org/3.0/doc/ledger3.html#The-convert-command)
command, which allows the generation of transactions from CSV.

Since ledger doesn't distinguish between payee and narration, narration
information can be stored in a transaction note.  The problem with
processing such transactions is that ledger puts the note either on the
same line as the payee or the next line depending on the length of the
payee and narration information.  Furthermore, ledger2beancount doesn't
support taking narration information from transaction notes, so we have
to transform the transaction and store the information as metadata.

Let's take this CSV file as an example:

```csv
date,note,payee,amount
2021-04-21,A very long note that will be printed on the next line,Short Payee,-7.99 EUR
2021-04-21,Short note,Short Payee,-7.99 EUR
2021-04-21,Short note,A Long Payee Name that leaves no more room for the note,-7.99 EUR
```

The command `ledger convert --account Assets:Bank` produces this
output:

```ledger
2021-04-21 * Short Payee
    ;A very long note that will be printed on the next line
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank

2021-04-21 * Short Payee  ;Short note
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank

2021-04-21 * A Long Payee Name that leaves no more room for the note
    ;Short note
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank
```

The following script takes the transaction notes (either the transaction
note on the same line as the payee or the first comment of a transaction)
and stores them as metadata with the key `narration`:

```perl
#!/usr/bin/perl

use warnings;
use strict;

my $before_posting = 1;
my $seen_note = 0;
while (<>) {
    if (/^\d/) { # Transaction header
        $before_posting = 1;
        if (/  ;/) {
            my ($header, $note) = split /  ;/;
            print "$header\n";
            print "    ; narration: $note";
            $seen_note = 1;
        } else {
            print;
            $seen_note = 0;
        }
    } elsif (/^\s+[^;\s]/) { # Posting
        $before_posting = 0;
        print;
    } elsif (/^\s+;(.*)/) { # Comment
        my $note = $1;
        if ($before_posting && !$seen_note) {
            print "    ; narration: $note\n";
            $seen_note = 1;
        } else {
            print;
        }
    } else {
        print;
    }
}
```

This changes the input file to:

```ledger
2021-04-21 * Short Payee
    ; narration: A very long note that will be printed on the next line
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank

2021-04-21 * Short Payee
    ; narration: Short note
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank

2021-04-21 * A Long Payee Name that leaves no more room for the note
    ; narration: Short note
    Expenses:Unknown                       -7.99 EUR
    Assets:Bank
```

Now the comment is metadata and we can use the following configuration:

```yaml
payee_split:
 - (?<payee>.*)

narration_tag: narration
```

to get the expected output:

```beancount
2021-04-21 * "Short Payee" "A very long note that will be printed on the next line"
  Expenses:Unknown                       -7.99 EUR
  Assets:Bank

2021-04-21 * "Short Payee" "Short note"
  Expenses:Unknown                       -7.99 EUR
  Assets:Bank

2021-04-21 * "A Long Payee Name that leaves no more room for the note" "Short note"
  Expenses:Unknown                       -7.99 EUR
  Assets:Bank
...
```

An example of post-processing is to change the variable type of ledger
codes from string to integer.  Using `code_tag`, the ledger code from
transactions is stored as metadata.  Since ledger codes can be
anything, they are stored as strings by default:

```beancount
2021-04-14 * "Code"
  code: "1201"
...
```

If you know that all your codes are integer, you can remove the
quotation marks to turn them from strings into integers:

```shell
perl -pi -e 's/^(\s+code: )"(\d+)"$/$1$2/' *.beancount
```

The `code` metadata is now an integer:

```beancount
2021-04-14 * "Code"
  code: 1201
...
```