diff --git a/hledger/Hledger/Cli/CliOptions.hs b/hledger/Hledger/Cli/CliOptions.hs index acb9c4c79..368d6e768 100644 --- a/hledger/Hledger/Cli/CliOptions.hs +++ b/hledger/Hledger/Cli/CliOptions.hs @@ -115,6 +115,7 @@ inputflags = [ ,flagReq ["rules-file"] (\s opts -> Right $ setopt "rules-file" s opts) "RFILE" "CSV conversion rules file (default: FILE.rules)" ,flagReq ["alias"] (\s opts -> Right $ setopt "alias" s opts) "OLD=NEW" "display accounts named OLD as NEW" ,flagNone ["ignore-assertions"] (setboolopt "ignore-assertions") "ignore any balance assertions in the journal" + ,flagReq ["pivot"] (\s opts -> Right $ setopt "pivot" s opts) "TAG" "Replace the accounts of postings with TAG by TAG:" ] -- | Common report-related flags: --period, --cost, etc. diff --git a/hledger/Hledger/Cli/Utils.hs b/hledger/Hledger/Cli/Utils.hs index b8aef4e97..d0c9e72cc 100644 --- a/hledger/Hledger/Cli/Utils.hs +++ b/hledger/Hledger/Cli/Utils.hs @@ -71,7 +71,24 @@ withJournalDo opts cmd = do rulespath <- rulesFilePathFromOpts opts journalpaths <- journalFilePathFromOpts opts ej <- readJournalFiles Nothing rulespath (not $ ignore_assertions_ opts) journalpaths - either error' (cmd opts . journalApplyAliases (aliasesFromOpts opts)) ej + either error' (cmd opts . pivotByOpts opts . journalApplyAliases (aliasesFromOpts opts)) ej + +-- | Apply the pivot transformation on a journal, if option is present. +pivotByOpts :: CliOpts -> Journal -> Journal +pivotByOpts opts + | Just tag <- maybeTag = pivot tag + | Nothing <- maybeTag = id + where maybeTag = maybestringopt "pivot" . rawopts_ $ opts + +-- | Apply the pivot transformation by given tag on a journal. +pivot :: String -> Journal -> Journal +pivot tag j = j{jtxns = map pivotTrans . jtxns $ j} + where + pivotTrans t = t{tpostings = map pivotPosting . tpostings $ t} + pivotPosting p + | Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value} + | _ <- tagTuple = p + where tagTuple = find ((tag ==) . fst) . ptags $ p -- | Write some output to stdout or to a file selected by --output-file. writeOutput :: CliOpts -> String -> IO () diff --git a/hledger/doc/examples.m4.md b/hledger/doc/examples.m4.md index 29762a1ce..031ac2316 100644 --- a/hledger/doc/examples.m4.md +++ b/hledger/doc/examples.m4.md @@ -65,3 +65,19 @@ $ hledger print desc:shop # show transactions with shop in the d $ hledger activity -W # show transaction counts per week as a bar chart ``` +With the journal + +```journal +2016/02/16 Member Fee Payment John Doe + assets:bank account 2 EUR + income:member fees -2 EUR + ; member: John Doe +``` + +the --pivot comand will output the following: + +```shells +$ hledger bal --pivot member + 2 EUR assets:bank account + -2 EUR member:John Doe +``` diff --git a/hledger/doc/options.m4.md b/hledger/doc/options.m4.md index 9251f012e..fd91c79f1 100644 --- a/hledger/doc/options.m4.md +++ b/hledger/doc/options.m4.md @@ -104,6 +104,10 @@ Both of these must be written after the command name. `-B --cost ` : show amounts in their cost price's commodity +`--pivot TAG +: will transform the journal before any other processing by replacing the account name of every posting having the tag TAG with content VALUE by the account name "TAG:VALUE". +: The TAG will only match if it is a full-length match. The pivot will only happen if the TAG is on a posting, not if it is on the transaction. If the tag value is a multi:level:account:name the new account name will be "TAG:multi:level:account:name". + ## Multiple files One may specify the `--file FILE` option multiple times. This is equivalent to diff --git a/tests/misc/pivot.test b/tests/misc/pivot.test new file mode 100644 index 000000000..a5b638ff5 --- /dev/null +++ b/tests/misc/pivot.test @@ -0,0 +1,40 @@ +# --pivot tests + +# check pivot with print +hledger -f- --pivot TAG print +<<< +2016/02/16 Test Transaction + Account1 2 EUR + Account2 -2 EUR + ; TAG: value +>>> +2016/02/16 Test Transaction + Account1 2 EUR + TAG:value -2 EUR + ; TAG: value + +>>>=0 + +# check pivot with bal +hledger -f- --pivot member bal --no-total +<<< +2016/02/16 Member Fee Payment John Doe + assets:bank account 2 EUR + income:member fees -2 EUR + ; member: John Doe +>>> + 2 EUR assets:bank account + -2 EUR member:John Doe +>>>=0 + +# check with another example +hledger -f- --pivot budget bal --no-total +<<< +2016/02/16 Donation Freifunk + assets:bank account 2 EUR + income:donations -2 EUR + ; budget: Freifunk +>>> + 2 EUR assets:bank account + -2 EUR budget:Freifunk +>>>=0