Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
hledger scripting exercise
#!/usr/bin/env runhaskell
Print monthly average cashflow by account.
$ average-cashflow.hs YEAR [JOURNALFILE]
module Main where
import Hledger
import Data.Maybe (catMaybes)
import Control.Monad (forM_)
import Text.Printf (printf)
import Safe (headDef)
import System.Environment (getArgs)
-- needs Hledger.Data.Dates spanFromSmartDate
matchMonth y m = Date $ spanFromSmartDate nulldate (show y, show m, "")
allOneCommodity = all (\(Mixed as) -> let c = acommodity $ head as in all ((==c).acommodity) as)
averageMixedAmounts ms
| null ms = mixed $ num 0
| allOneCommodity ms = let Mixed [a@Amount{aquantity=q}] = sum ms in Mixed [a{aquantity=q / fromIntegral (length ms)}]
| otherwise = error "Can't calculate the average of multi-commodity amounts."
main = do
-- parse args
year:rest <- getArgs
deffile <- defaultJournalPath
let file = headDef deffile rest
-- read file
j <- readJournalFile Nothing Nothing file >>= either error' return
-- calculate averages
let accts = journalAccountNames j
months = [1..12]
acctbalsbymonth = [(m, map (\(a,_,_,bal)->(a,bal)) $ fst $ accountsReport defreportopts (matchMonth year m) j) | m <- months]
monthlyBalsForAcct a = catMaybes [lookup a monthbals | (_,monthbals) <- acctbalsbymonth]
averagebalbyacct = [(a, averageMixedAmounts $ monthlyBalsForAcct a) | a <- accts]
-- display report
printf "Average monthly cashflow by account in %s\n" year
forM_ averagebalbyacct $ \(a,b) -> printf "%12s %s\n" (showMixedAmount b) a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.