Hi,

Am 15.05.19 um 02:57 schrieb Martin Blais:> But why are you trying to do 
this? What's your purpose?
My importer applies a set of rules to convert payee names and assign 
certain kind of transactions to accounts:

# List of tuples (regular expression, replacement)
payee_replacements = [
    ("^AMAZON", "Amazon"),
]

# List of tuples (python expression to match, second account to set)
accounts_assignments = [
    ("desc == 'Miete PSW 1'", "Expenses:Miete"),
    ("payee in ['REWE', 'Kaufland', 'ALDI']", "Expenses:Groceries"),
    ("True", "Expenses:Unknown")
]


def transform_txn(txn):
    payee = txn.payee

    for pattern, substitute in payee_replacements:
        if re.match(pattern, payee):
            payee = substitute
            break

    txn = txn._replace(payee = payee)

    local_vars = {"payee" : txn.payee, "desc" : txn.narration, 
"buchungsart" : txn.meta["buchungsart"]}    
    if txn.postings[1].account == "Expenses:Unknown":
        for expr, acc in accounts_assignments:
            if eval(expr, local_vars):
                account = acc
                break

        txn.postings[1] = txn.postings[1]._replace(account = account)
        
    return txn


These two rulesets are applied on import.

I want to also apply them on existing ledgers.

Usecase: I identify a recurring transaction pattern, such as "buchungsart 
== 'GAA,Spk.Netz'. All matching transaction to imported as well as existing 
ones should have the account "Assets:Bargeld" assigned. For that, I need a 
method to read in all transactions, transform them and write them to a 
beancount file.

This is my solution to this question: 
https://groups.google.com/forum/#!topic/beancount/e93VI4s4YCQ

An alternative approach are plugins. So far I understand plugins they only 
apply live transformations, i.e., they transform data as it is loaded from 
a file, but do not write back the data to the file.

>> A workaround I see, is to read in main.beancount and write out the 
entries to different files based on entries[6].meta["filename"]. Basically 
rewriting the entire ledger.
> 
> I was going to suggest this. 
> Still, when you write entries out, they won't look precisely the same as 
the input. Numbers will have been filled in, cost bases will show up, etc. 
I don't see the point.
Yes, I have noticed that, but that seems ok to me.

I hope I was able to explain my use case. I am open to any thoughts and 
ideas to achieve that differently.

Best Regards,
Florian

> 
> 
> 
> On Mon, May 13, 2019 at 10:36 AM Florian Lindner <mailingli...@xgm.de 
<mailto:mailingli...@xgm.de>> wrote:
> 
>         I see.
>         Well FWIW, entries which have errors are not guaranteed to show 
up in the output stream at all.
>         It's unclear to me whether this is always the best outcome, but a 
long while ago I decided to do this for transactions and for some other 
directives.
>         
https://bitbucket.org/blais/beancount/src/d1b2cbf2841669e988f6692ec1d39db3708730cc/beancount/ops/balance.py#lines-119
> 
>         I don't have a solution for you. This is an unusual case.
> 
> 
>     I tried to apply the workaround I mentioned:
> 
>         entries, error, option_map = bc.loader.load_file(args.inputfile)
>         sorted_entries = {} # file -> list of entries
> 
>         for e in entries:
>             entry = transform_txn(e) if type(e) == data.Transaction else e
>             name = entry.meta["filename"]
>             sorted_entries[name] = sorted_entries.get(name, []) + [entry]
>       
>         for filename in sorted_entries:
>             with open(filename, "w") as f:
>                 bc.parser.printer.print_entries(sorted_entries[filename], 
file = f)
> 
>     A problem that shows up, is that in main.beancount I have some 
options set (e.g. operation_currency). They don't show up in entries, but 
in option_map. However, I don't know how to write them to file.
> 
>     Another idea: At a first try, it seems that reading the entire file 
into a string and use |beancount.parser.parser.||parse_many|would work and 
also parser the balances:
> 
>         with open(args.inputfile, "r") as f:
>             instr = f.read()
>        
>         entries = bc.parser.parser.parse_many(instr)
> 
>     Seems to work fine so far. What do you think?

-- 
You received this message because you are subscribed to the Google Groups 
"Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beancount+unsubscr...@googlegroups.com.
To post to this group, send email to beancount@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beancount/a404f3ac-e9db-4470-b15c-4ee2bc611525%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to