module Ledger.RawLedger
where
import qualified Data.Map as Map
import Data.Map ((!))
import Ledger.Utils
import Ledger.Types
import Ledger.AccountName
import Ledger.Amount
import Ledger.Entry
import Ledger.Transaction
import Ledger.RawTransaction
import Ledger.TimeLog
instance Show RawLedger where
show l = printf "RawLedger with %d entries, %d accounts: %s"
((length $ entries l) +
(length $ modifier_entries l) +
(length $ periodic_entries l))
(length accounts)
(show accounts)
where accounts = flatten $ rawLedgerAccountNameTree l
rawLedgerEmpty :: RawLedger
rawLedgerEmpty = RawLedger { modifier_entries = []
, periodic_entries = []
, entries = []
, open_timelog_entries = []
, historical_prices = []
, final_comment_lines = []
}
addEntry :: Entry -> RawLedger -> RawLedger
addEntry e l0 = l0 { entries = e : (entries l0) }
addModifierEntry :: ModifierEntry -> RawLedger -> RawLedger
addModifierEntry me l0 = l0 { modifier_entries = me : (modifier_entries l0) }
addPeriodicEntry :: PeriodicEntry -> RawLedger -> RawLedger
addPeriodicEntry pe l0 = l0 { periodic_entries = pe : (periodic_entries l0) }
addHistoricalPrice :: HistoricalPrice -> RawLedger -> RawLedger
addHistoricalPrice h l0 = l0 { historical_prices = h : (historical_prices l0) }
addTimeLogEntry :: TimeLogEntry -> RawLedger -> RawLedger
addTimeLogEntry tle l0 = l0 { open_timelog_entries = tle : (open_timelog_entries l0) }
rawLedgerTransactions :: RawLedger -> [Transaction]
rawLedgerTransactions = txnsof . entries
where txnsof es = concat $ map flattenEntry $ zip es [1..]
rawLedgerAccountNamesUsed :: RawLedger -> [AccountName]
rawLedgerAccountNamesUsed = accountNamesFromTransactions . rawLedgerTransactions
rawLedgerAccountNames :: RawLedger -> [AccountName]
rawLedgerAccountNames = sort . expandAccountNames . rawLedgerAccountNamesUsed
rawLedgerAccountNameTree :: RawLedger -> Tree AccountName
rawLedgerAccountNameTree l = accountNameTreeFrom $ rawLedgerAccountNames l
filterRawLedger :: DateSpan -> [String] -> Bool -> Bool -> RawLedger -> RawLedger
filterRawLedger span pats clearedonly realonly =
filterRawLedgerTransactionsByRealness realonly .
filterRawLedgerEntriesByClearedStatus clearedonly .
filterRawLedgerEntriesByDate span .
filterRawLedgerEntriesByDescription pats
filterRawLedgerEntriesByDescription :: [String] -> RawLedger -> RawLedger
filterRawLedgerEntriesByDescription pats (RawLedger ms ps es tls hs f) =
RawLedger ms ps (filter matchdesc es) tls hs f
where matchdesc = matchpats pats . edescription
filterRawLedgerEntriesByDate :: DateSpan -> RawLedger -> RawLedger
filterRawLedgerEntriesByDate (DateSpan begin end) (RawLedger ms ps es tls hs f) =
RawLedger ms ps (filter matchdate es) tls hs f
where
matchdate e = (maybe True (edate e>=) begin) && (maybe True (edate e<) end)
filterRawLedgerEntriesByClearedStatus :: Bool -> RawLedger -> RawLedger
filterRawLedgerEntriesByClearedStatus False l = l
filterRawLedgerEntriesByClearedStatus True (RawLedger ms ps es tls hs f) =
RawLedger ms ps (filter estatus es) tls hs f
filterRawLedgerTransactionsByRealness :: Bool -> RawLedger -> RawLedger
filterRawLedgerTransactionsByRealness False l = l
filterRawLedgerTransactionsByRealness True (RawLedger ms ps es tls hs f) =
RawLedger ms ps (map filtertxns es) tls hs f
where filtertxns e@Entry{etransactions=ts} = e{etransactions=filter isReal ts}
filterRawLedgerTransactionsByDepth :: Int -> RawLedger -> RawLedger
filterRawLedgerTransactionsByDepth depth (RawLedger ms ps es tls hs f) =
RawLedger ms ps (filter (not . null . etransactions) $ map filtertxns es) tls hs f
where filtertxns e@Entry{etransactions=ts} =
e{etransactions=filter ((<= depth) . accountNameLevel . taccount) ts}
filterRawLedgerEntriesByAccount :: [String] -> RawLedger -> RawLedger
filterRawLedgerEntriesByAccount apats (RawLedger ms ps es tls hs f) =
RawLedger ms ps (filter (any (matchpats apats . taccount) . etransactions) es) tls hs f
canonicaliseAmounts :: Bool -> RawLedger -> RawLedger
canonicaliseAmounts costbasis l@(RawLedger ms ps es tls hs f) = RawLedger ms ps (map fixentry es) tls hs f
where
fixentry (Entry d s c de co ts pr) = Entry d s c de co (map fixrawtransaction ts) pr
fixrawtransaction (RawTransaction s ac a c t) = RawTransaction s ac (fixmixedamount a) c t
fixmixedamount (Mixed as) = Mixed $ map fixamount as
fixamount = fixcommodity . (if costbasis then costOfAmount else id)
fixcommodity a = a{commodity=c} where c = canonicalcommoditymap ! (symbol $ commodity a)
canonicalcommoditymap =
Map.fromList [(s,firstc{precision=maxp}) | s <- commoditysymbols,
let cs = commoditymap ! s,
let firstc = head cs,
let maxp = maximum $ map precision cs
]
commoditymap = Map.fromList [(s,commoditieswithsymbol s) | s <- commoditysymbols]
commoditieswithsymbol s = filter ((s==) . symbol) commodities
commoditysymbols = nub $ map symbol commodities
commodities = map commodity $ concatMap (amounts . amount) $ rawLedgerTransactions l
rawLedgerAmounts :: RawLedger -> [MixedAmount]
rawLedgerAmounts = map amount . rawLedgerTransactions
rawLedgerCommodities :: RawLedger -> [Commodity]
rawLedgerCommodities = map commodity . concatMap amounts . rawLedgerAmounts
rawLedgerPrecisions :: RawLedger -> [Int]
rawLedgerPrecisions = map precision . rawLedgerCommodities
rawLedgerConvertTimeLog :: LocalTime -> RawLedger -> RawLedger
rawLedgerConvertTimeLog t l0 = l0 { entries = convertedTimeLog ++ entries l0
, open_timelog_entries = []
}
where convertedTimeLog = entriesFromTimeLogEntries t $ open_timelog_entries l0