diff --git a/bin/hledger-report1.hs b/bin/hledger-report1.hs new file mode 100755 index 000000000..4577e8b29 --- /dev/null +++ b/bin/hledger-report1.hs @@ -0,0 +1,58 @@ +#!/usr/bin/env stack +-- stack runghc --verbosity error --package hledger --package hledger-lib --package text --package safe +-- ^ use a local source hledger (in case you need the latest) +-- -- stack script --compile --resolver nightly-2023-10-13 --verbosity info --package hledger --package text +-- -- ^ or use a released hledger from stackage + +-- A custom compound report - like incomestatement but with different +-- subheadings/subreports. More verbose and haskelly than +-- hledger-report1.sh but also more robust and powerful. + +{-# LANGUAGE OverloadedStrings, PackageImports #-} + +import Hledger.Cli.Script +import qualified "text" Data.Text as T +import qualified "text" Data.Text.IO as T + +cmdmode = hledgerCommandMode (unlines + -- Command name, then --help text, then _FLAGS; empty help lines get stripped: + ["report1" + ,"A custom compound report - like the incomestatement command but easier to customise." + ,"Usage: hledger-report1 [OPTS] [ARGS]" + ,"or: hledger report1 -- [OPTS] [ARGS]" + ]) [] [generalflagsgroup1] [] ([], Just $ argsFlag "[ARGS]") + +main = do + opts@CliOpts{reportspec_=rspec} <- getHledgerCliOpts cmdmode + withJournalDo opts $ flip compoundBalanceCommand opts $ + -- define the custom report + -- see https://hackage.haskell.org/package/hledger/docs/Hledger-Cli-CompoundBalanceCommand.html + -- and https://hackage.haskell.org/package/hledger-lib-1.31/docs/Hledger-Query.html + CompoundBalanceCommandSpec { + cbcdoc = "report1 help text", + cbctitle = "Report1 Statement", + cbcqueries = [ + CBCSubreportSpec{ + cbcsubreporttitle="Revenues" + ,cbcsubreportquery=Type [Revenue] + ,cbcsubreportoptions=(\ropts -> ropts{normalbalance_=Just NormallyNegative}) + ,cbcsubreporttransform=fmap maNegate + ,cbcsubreportincreasestotal=True + } + ,CBCSubreportSpec{ + cbcsubreporttitle="Operating Expenses" + ,cbcsubreportquery=And [Type [Expense], Acct $ toRegex' "Operating"] + ,cbcsubreportoptions=(\ropts -> ropts{normalbalance_=Just NormallyPositive}) + ,cbcsubreporttransform=id + ,cbcsubreportincreasestotal=False + } + ,CBCSubreportSpec{ + cbcsubreporttitle="Other Expenses" + ,cbcsubreportquery=And [Type [Expense], Not $ Acct $ toRegex' "Operating"] + ,cbcsubreportoptions=(\ropts -> ropts{normalbalance_=Just NormallyPositive}) + ,cbcsubreporttransform=id + ,cbcsubreportincreasestotal=False + } + ], + cbcaccum = PerPeriod + } diff --git a/bin/hledger-report1.sh b/bin/hledger-report1.sh new file mode 100755 index 000000000..41dabdab1 --- /dev/null +++ b/bin/hledger-report1.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# A custom compound report - like incomestatement but with different +# subheadings/subreports. A bit hacky but quick and short. +# See also hledger-report1.hs. + +echo "Report1 Statement `date +%Y-%m-%d`" +printf "\nRevenues\n" +hledger bal expr:"type:r and $@" | tail +2 +printf "\nOperating Expenses\n" +hledger bal expr:"type:x and operating and $@" | tail +2 +printf "\nOther expenses\n" +hledger bal expr:"type:x and not:operating and $@" | tail +2 +printf "\nGrand Total\n" +hledger bal expr:"type:rx and $@" | tail -1 diff --git a/bin/hledger-script-example.hs b/bin/hledger-script-example.hs index 3b52c64fd..2a419061d 100755 --- a/bin/hledger-script-example.hs +++ b/bin/hledger-script-example.hs @@ -104,12 +104,12 @@ execute permission, and start tweaking the code. Requirements: -This is a stack script, requiring stack to run. hledger addons do not -have to be stack scripts, but this one is, as they work well for this. -If you prefer you can adapt it to be a cabal script, or you can -install the required haskell libraries (see above) and then -run/compile it with a suitable runghc/ghc command. -The script may require specific versions of the libraries. +This is a stack script, best run or compiled with stack. +Once compiled it doesn't require stack. +If you prefer you can adapt it to be a cabal script, +or you can manually install the required haskell libraries +(see above) and then run/compile it just with ghc or runghc. + If run/compiled from inside the hledger source tree, it will use that hledger version and the libs of the stackage resolver in stack.yaml. If run/compiled from outside the hledger source tree, it will use the hledger