From e668506d26f668988825e40aae484399deaa7413 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Fri, 9 Jun 2023 11:00:01 -0700 Subject: [PATCH] feat: cli: Support colon-delimited --pivot (#2050) feat:cli: --pivot now can construct an account name from multiple colon-delimited fields --- hledger-lib/Hledger/Data/Journal.hs | 27 +++++++++++++++++---------- hledger/hledger.m4.md | 12 ++++++++++-- hledger/test/pivot.test | 11 +++++++++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 540e94370..6853d500c 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -1083,16 +1083,23 @@ transactionPivot fieldortagname t = t{tpostings = map (postingPivot fieldortagna -- | Replace this posting's account name with the value -- of the given field or tag, if any, otherwise the empty string. postingPivot :: Text -> Posting -> Posting -postingPivot fieldortagname p = p{paccount = pivotedacct, poriginal = Just $ originalPosting p} - where - pivotedacct - | Just t <- ptransaction p, fieldortagname == "code" = tcode t - | Just t <- ptransaction p, fieldortagname == "description" = tdescription t - | Just t <- ptransaction p, fieldortagname == "payee" = transactionPayee t - | Just t <- ptransaction p, fieldortagname == "note" = transactionNote t - | Just t <- ptransaction p, fieldortagname == "status" = T.pack . show . tstatus $ t - | Just (_, value) <- postingFindTag fieldortagname p = value - | otherwise = "" +postingPivot fieldortagname p = + p{paccount = pivotAccount fieldortagname p, poriginal = Just $ originalPosting p} + +pivotAccount :: Text -> Posting -> Text +pivotAccount fieldortagname p = + T.intercalate ":" [pivotComponent x p | x <- T.splitOn ":" fieldortagname] + +pivotComponent :: Text -> Posting -> Text +pivotComponent fieldortagname p + | fieldortagname == "acct" = paccount p + | Just t <- ptransaction p, fieldortagname == "code" = tcode t + | Just t <- ptransaction p, fieldortagname == "description" = tdescription t + | Just t <- ptransaction p, fieldortagname == "payee" = transactionPayee t + | Just t <- ptransaction p, fieldortagname == "note" = transactionNote t + | Just t <- ptransaction p, fieldortagname == "status" = T.pack . show . tstatus $ t + | Just (_, value) <- postingFindTag fieldortagname p = value + | otherwise = "" postingFindTag :: TagName -> Posting -> Maybe (TagName, TagValue) postingFindTag tagname p = find ((tagname==) . fst) $ postingAllTags p diff --git a/hledger/hledger.m4.md b/hledger/hledger.m4.md index 355ea189b..03650f843 100644 --- a/hledger/hledger.m4.md +++ b/hledger/hledger.m4.md @@ -4742,16 +4742,17 @@ see the discussion at [#1625](https://github.com/simonmichael/hledger/issues/162 Normally, hledger groups and sums amounts within each account. The `--pivot FIELD` option substitutes some other transaction field for account names, causing amounts to be grouped and summed by that field's value instead. -FIELD can be any of the transaction fields `status`, `code`, `description`, `payee`, `note`, or a tag name. +FIELD can be any of the transaction fields `acct`, `status`, `code`, `description`, `payee`, `note`, or a tag name. When pivoting on a tag and a posting has multiple values of that tag, only the first value is displayed. Values containing `colon:separated:parts` will be displayed hierarchically, like account names. +Multiple, colon-delimited fields can be pivoted simultaneously, generating a hierarchical account name. Some examples: ```journal 2016/02/16 Yearly Dues Payment assets:bank account 2 EUR - income:dues -2 EUR ; member: John Doe + income:dues -2 EUR ; member: John Doe, kind: Lifetime ``` Normal balance report showing account names: ```shell @@ -4783,6 +4784,13 @@ $ hledger balance --pivot member acct:. -------------------- -2 EUR ``` +Hierarchical reports can be generated with multiple pivots: +```shell +$ hledger balance Income:Dues --pivot kind:member + -2 EUR Lifetime:John Doe +-------------------- + -2 EUR +``` # Generating data diff --git a/hledger/test/pivot.test b/hledger/test/pivot.test index 960c8fe01..b3b90d335 100644 --- a/hledger/test/pivot.test +++ b/hledger/test/pivot.test @@ -117,3 +117,14 @@ $ hledger -f- --pivot payee reg -D ^expense 2016-02-16 Auchan 22 EUR 22 EUR StarBars 5 EUR 27 EUR 2016-02-17 Auchan 30 EUR 57 EUR +# 11. pivot on multiple tags +< +2023-01-01 compound purchase + expenses 10 ; project: job1, kind: equipment + expenses 20 ; project: job2, kind: equipment + expenses 25 ; project: job2, kind: fee + assets +$ hledger -f- --pivot acct:kind:project bal ^expense -N + 10 expenses:equipment:job1 + 20 expenses:equipment:job2 + 25 expenses:fee:job2