module Ledger.Entry
where
import Ledger.Utils
import Ledger.Types
import Ledger.Dates
import Ledger.RawTransaction
import Ledger.Amount
instance Show Entry where show = showEntry
instance Show ModifierEntry where
show e = "= " ++ (valueexpr e) ++ "\n" ++ unlines (map show (m_transactions e))
instance Show PeriodicEntry where
show e = "~ " ++ (periodicexpr e) ++ "\n" ++ unlines (map show (p_transactions e))
nullentry = Entry {
edate=parsedate "1900/1/1",
estatus=False,
ecode="",
edescription="",
ecomment="",
etransactions=[],
epreceding_comment_lines=""
}
showEntry :: Entry -> String
showEntry = showEntry' True
showEntryUnelided :: Entry -> String
showEntryUnelided = showEntry' False
showEntry' :: Bool -> Entry -> String
showEntry' elide e =
unlines $ [description] ++ (showtxns $ etransactions e) ++ [""]
where
precedingcomment = epreceding_comment_lines e
description = concat [date, status, code, desc]
date = showdate $ edate e
status = if estatus e then " *" else ""
code = if (length $ ecode e) > 0 then (printf " (%s)" $ ecode e) else ""
desc = " " ++ edescription e
comment = if (length $ ecomment e) > 0 then " ; "++(ecomment e) else ""
showtxns ts
| elide && length ts == 2 = [showtxn (ts !! 0), showtxnnoamt (ts !! 1)]
| otherwise = map showtxn ts
showtxn t = showacct t ++ " " ++ (showamount $ tamount t) ++ (showcomment $ tcomment t)
showtxnnoamt t = showacct t ++ " " ++ (showcomment $ tcomment t)
showacct t = " " ++ showstatus t ++ (showaccountname $ taccount t)
showamount = printf "%12s" . showMixedAmount
showaccountname s = printf "%-34s" s
showcomment s = if (length s) > 0 then " ; "++s else ""
showdate d = printf "%-10s" (showDate d)
showstatus t = case tstatus t of
True -> "* "
False -> ""
isEntryBalanced :: Entry -> Bool
isEntryBalanced (Entry {etransactions=ts}) =
isZeroMixedAmount $ costOfMixedAmount $ sum $ map tamount $ filter isReal ts
balanceEntry :: Entry -> Either String Entry
balanceEntry e@Entry{etransactions=ts}
| length missingamounts > 1 = Left $ showerr "could not balance this entry, too many missing amounts"
| not $ isEntryBalanced e' = Left $ showerr "could not balance this entry, amounts do not balance"
| otherwise = Right e'
where
(withamounts, missingamounts) = partition hasAmount $ filter isReal ts
e' = e{etransactions=ts'}
ts' | length missingamounts == 1 = map balance ts
| otherwise = ts
where
balance t | isReal t && not (hasAmount t) = t{tamount = costOfMixedAmount (otherstotal)}
| otherwise = t
where otherstotal = sum $ map tamount withamounts
showerr s = printf "%s:\n%s" s (showEntryUnelided e)