beancount / ledger2beancount

Ledger to Beancount text-based converter
GNU General Public License v3.0
79 stars 15 forks source link

Use ledger transaction note as beancount transaction narration #249

Closed bratekarate closed 3 years ago

bratekarate commented 3 years ago

I know that there is the option narration_tag that let's me specify the tag that is to be used as the beancount narration of a transaction. The issue is that I feel the equivalent of a beancount transaction "narration" is a ledger transaction "note". So far I have been unable to find a way to tell ledger2beancount to use my transaction notes from ledger as narrations.

When using ledger convert to import my csv data into ledger, it is not possible to use a tag for the transaction note, it's just a plain note.

The fields ledger can recognize contain these case-insensitive strings date, posted, code, payee or desc or description, amount, cost, total, and note.

-- https://www.ledger-cli.org/3.0/doc/ledger3.html#The-convert-command

Ledger entries such as the following are imported through my import script setup:

2021/03/22 * Some Payee
    ;Order Number or other description
    Expenses:Unknown                                EUR 122.94
    Assets:Current:Checkings

And this is what I would like to achieve after conversion through ledger2beancount:

2021-03-22 * "Some Payee" "Order Number or other description"
    Expenses:Unknown                                122.94 EUR
    Assets:Current:Checkings

It is therefore kind of a pain to change my notes to a tag with a certain key just so that ledger2beancount can later use it as the narration. Telling beancount to use my transaction notes as narrations would be much more convenient and feel more natural to the way ledger sees things. I hope I am not overlooking something in the documentation.

tbm commented 3 years ago

I hope I am not overlooking something in the documentation.

No, you didn't.

Telling beancount to use my transaction notes as narrations would be much more convenient and feel more natural to the way ledger sees things.

The problem is that these notes are just free-form comments. They could be on one line, one several lines; before or after postings. I don't really see a generic way how you'd access the notes from a config variable in a nice way.

I think the best solution is to write a small pre-processing script that converts the note to a meta-data tag.

tbm commented 3 years ago

Example:

pre-processing script

#!/usr/bin/perl

use warnings;
use strict;

my $in_txn = 0;
my $before_posting = 1;
while (<>) {
    if (/^\d/) {
        $in_txn = 1;
        $note = undef;
        print;
    } elsif (/^\s*$/) {
        $in_txn = 0;
        print;
    } elsif (/^\s+[^;\s]/) {
        $before_posting = 0;
        print;
    } elsif (/^\s+;(.*)/) {
        my $note = $1;
        if ($in_txn && $before_posting) {
            print "    ;narration: $note\n";
        } else {
            print;
        }
    } else {
        print;
    }
}

This converts your sample txn to

2021/03/22 * Some Payee
    ;narration: Order Number or other description
    Expenses:Unknown                                EUR 122.94
    Assets:Current:Checkings

and with .yaml:

payee_split:
 - (?<payee>.*)

narration_tag: narration

you get the expected output:

2021-03-22 * "Some Payee" "Order Number or other description"
tbm commented 3 years ago

I don't know how common your scenario is. Maybe there should be a section in the manual about pre-processing output with examples, but I don't know.

Also, if you can think of a more elegant solution, let me know.

bratekarate commented 3 years ago

Thanks for the preprocessing example. I suspected that currently it's simply not possible and that it would be too complex to implement. But that's the perfect reason for me to learn some perl :) So far I used shell with awk and sed scripts extensively, at times to an extent where it causes more headaches than good.

tbm commented 3 years ago
2021/03/22 * Some Payee
    ;Order Number or other description

how do you get this result?

When I use ledger convert, the payee is on the same line as the narration:

date,payee,note,amount
12/13/2011,"Withdrawal","ACE HARDWARE",-8.80
ledger convert ~/d --input-date-format "%m/%d/%Y" --account Assets:Bank
2011-12-13 * Withdrawal  ;ACE HARDWARE
    Expenses:Unknown                            -8.8
    Assets:Bank

which is something that payee_split can handle.

How do you call ledger so the payee is on the next line?

tbm commented 3 years ago

I'll add something to the docs about pre- and post-processing.

bratekarate commented 3 years ago

I don't think it has anything to do with how I call it. Some notes are on the same line, some on the next. AFAIK there is no semantic difference to ledger, it's both a transaction note.

I just tested it and it seems like it is only determined by the combined length of payee and note:

Input:

date,posted,code,note,payee,amount
31.03.21,06.04.21,CODE,Long note that will be printed on the next line,Short Payee,EUR -7.99,EUR
31.03.21,06.04.21,CODE,Short note,Short Payee,EUR -7.99,EUR
31.03.21,06.04.21,CODE,Short note,Long Payee Name that leaves no more room,EUR -7.99,EUR

Convert command:

ledger convert \   
  --invert \
  --account "Assets:Current:Checking" \
  --input-date-format %d.%m.%y \       
  prep.csv

Output:

2021/03/31=2021/04/06 * (CODE) Short Payee                             
    ;Long note that will be printed on the next line
    Expenses:Unknown                        EUR 7.99
    Assets:Current:Checkings

2021/03/31=2021/04/06 * (CODE) Short Payee  ;Short note
    Expenses:Unknown                        EUR 7.99
    Assets:Current:Checkings

2021/03/31=2021/04/06 * (CODE) Long Payee Name that leaves no more room
    ;Short note
    Expenses:Unknown                        EUR 7.99
    Assets:Current:Checkings

If there was an option for ledger convert to ignore the length and still print everything in one line, then payee split could probably handle all cases. I don't think it's mentioned in the docs, I may just resort to a perl preprocessor. Thanks anyways for your help.

tbm commented 3 years ago

Thanks for these examples. I've updated the example (and Perl script) in the documentation. I figured this might be of wider interest since other people probably use ledger convert too.

https://ledger2beancount.readthedocs.io/tips/