diff --git a/hledger-lib/Hledger/Read/CsvReader.hs b/hledger-lib/Hledger/Read/CsvReader.hs index 12f0a9a4b..709e3ccc2 100644 --- a/hledger-lib/Hledger/Read/CsvReader.hs +++ b/hledger-lib/Hledger/Read/CsvReader.hs @@ -513,6 +513,7 @@ journalfieldnames = ,"account1" ,"account2" ,"comment" + ,"balance" ] assignmentseparatorp :: CsvRulesParser () @@ -663,6 +664,17 @@ transactionFromCsvRecord sourcepos rules record = t _ -> "expenses:unknown" account1 = T.pack $ maybe "" render (mfieldtemplate "account1") `or` defaccount1 account2 = T.pack $ maybe "" render (mfieldtemplate "account2") `or` defaccount2 + balance = maybe Nothing parsebalance $ mfieldtemplate "balance" + parsebalance "" = Nothing + parsebalance str = Just $ either (balanceerror str) id $ runParser (evalStateT (amountp <* eof) mempty) "" $ T.pack $ (currency++) $ negateIfParenthesised $ render str + balanceerror str err = error' $ unlines + ["error: could not parse \""++str++"\" as balance amount" + ,showRecord record + ,"the balance rule is: "++(fromMaybe "" $ mfieldtemplate "balance") + ,"the currency rule is: "++(fromMaybe "unspecified" $ mfieldtemplate "currency") + ,"the default-currency is: "++fromMaybe "unspecified" mdefaultcurrency + ,"the parse error is: "++show err + ] -- build the transaction t = nulltransaction{ @@ -676,7 +688,7 @@ transactionFromCsvRecord sourcepos rules record = t tpreceding_comment_lines = T.pack precomment, tpostings = [posting {paccount=account2, pamount=amount2, ptransaction=Just t} - ,posting {paccount=account1, pamount=amount1, ptransaction=Just t} + ,posting {paccount=account1, pamount=amount1, ptransaction=Just t, pbalanceassertion=balance} ] } diff --git a/hledger-lib/doc/hledger_csv.5.m4.md b/hledger-lib/doc/hledger_csv.5.m4.md index d9ddc9aa2..cd556cdf3 100644 --- a/hledger-lib/doc/hledger_csv.5.m4.md +++ b/hledger-lib/doc/hledger_csv.5.m4.md @@ -84,7 +84,7 @@ date-format %-m/%-d/%Y %l:%M %p This (a) names the CSV fields, in order (names may not contain whitespace; uninteresting names may be left blank), and (b) assigns them to journal entry fields if you use any of these standard field names: -`date`, `date2`, `status`, `code`, `description`, `comment`, `account1`, `account2`, `amount`, `amount-in`, `amount-out`, `currency`. +`date`, `date2`, `status`, `code`, `description`, `comment`, `account1`, `account2`, `amount`, `amount-in`, `amount-out`, `currency`, `balance`. Eg: ```rules # use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount, @@ -172,3 +172,5 @@ If an amount value is parenthesised, it will be de-parenthesised and sign-flippe The generated journal entries will be sorted by date. The original order of same-day entries will be preserved, usually. + +If you assign anything to the `balance` pseudo field, it would become an assertion of the balance of `account1`. If you assign empty string to it, no assertion will be generated (this can be used to omit balance assertions on some transactions). diff --git a/tests/csv/read.test b/tests/csv/read.test index 8f490f817..f4f2bb113 100644 --- a/tests/csv/read.test +++ b/tests/csv/read.test @@ -58,3 +58,13 @@ # $-1,001.00 income:unknown # $1,001.00 unknown #>>>=0 +# 6. read CSV with balance field + rm -rf t.rules$$; printf 'fields date, description, amount, balance\ndate-format %%d/%%Y/%%m\ncurrency $\naccount1 assets:myacct\n' >t.rules$$; echo '10/2009/09,Flubber Co,50,123' | hledger -f- print --rules-file t.rules$$; rm -rf t.rules$$ +>>> +2009/09/10 Flubber Co + income:unknown $-50 + assets:myacct $50 = $123 + +>>>2 /using conversion rules file.*t.rules/ +>>>=0 +