2008-10-03 06:04:15 +04:00
|
|
|
{-|
|
|
|
|
|
2008-10-16 13:50:22 +04:00
|
|
|
An 'Entry' represents a regular entry in the ledger file. It normally
|
|
|
|
contains two or more balanced 'RawTransaction's.
|
2008-10-03 06:04:15 +04:00
|
|
|
|
|
|
|
-}
|
|
|
|
|
2008-10-03 06:37:19 +04:00
|
|
|
module Ledger.Entry
|
2007-02-16 12:00:17 +03:00
|
|
|
where
|
2008-10-03 04:05:16 +04:00
|
|
|
import Ledger.Utils
|
2008-10-03 04:12:59 +04:00
|
|
|
import Ledger.Types
|
2008-11-27 03:35:00 +03:00
|
|
|
import Ledger.Dates
|
2008-10-03 04:40:06 +04:00
|
|
|
import Ledger.RawTransaction
|
|
|
|
import Ledger.Amount
|
2007-02-16 12:00:17 +03:00
|
|
|
|
|
|
|
|
2008-10-15 10:47:00 +04:00
|
|
|
instance Show Entry where show = showEntry
|
2007-07-03 03:41:07 +04:00
|
|
|
|
2008-10-18 10:45:02 +04:00
|
|
|
instance Show ModifierEntry where
|
|
|
|
show e = "= " ++ (valueexpr e) ++ "\n" ++ unlines (map show (m_transactions e))
|
|
|
|
|
|
|
|
instance Show PeriodicEntry where
|
2008-11-27 22:42:03 +03:00
|
|
|
show e = "~ " ++ (periodicexpr e) ++ "\n" ++ unlines (map show (p_transactions e))
|
2008-10-18 10:45:02 +04:00
|
|
|
|
2008-11-08 23:25:51 +03:00
|
|
|
nullentry = Entry {
|
2008-11-11 15:34:05 +03:00
|
|
|
edate=parsedate "1900/1/1",
|
2008-11-08 23:25:51 +03:00
|
|
|
estatus=False,
|
|
|
|
ecode="",
|
|
|
|
edescription="",
|
|
|
|
ecomment="",
|
|
|
|
etransactions=[],
|
|
|
|
epreceding_comment_lines=""
|
|
|
|
}
|
|
|
|
|
2008-10-01 13:33:05 +04:00
|
|
|
{-|
|
2008-10-18 08:15:43 +04:00
|
|
|
Show a ledger entry, formatted for the print command. ledger 2.x's
|
|
|
|
standard format looks like this:
|
2008-10-01 13:33:05 +04:00
|
|
|
|
|
|
|
@
|
|
|
|
yyyy/mm/dd[ *][ CODE] description......... [ ; comment...............]
|
|
|
|
account name 1..................... ...$amount1[ ; comment...............]
|
|
|
|
account name 2..................... ..$-amount1[ ; comment...............]
|
2007-07-04 13:28:07 +04:00
|
|
|
|
2008-10-18 10:49:40 +04:00
|
|
|
pcodewidth = no limit -- 10 -- mimicking ledger layout.
|
|
|
|
pdescwidth = no limit -- 20 -- I don't remember what these mean,
|
|
|
|
pacctwidth = 35 minimum, no maximum -- they were important at the time.
|
2008-10-01 13:33:05 +04:00
|
|
|
pamtwidth = 11
|
|
|
|
pcommentwidth = no limit -- 22
|
|
|
|
@
|
|
|
|
-}
|
2008-10-03 06:37:19 +04:00
|
|
|
showEntry :: Entry -> String
|
2007-07-04 13:28:07 +04:00
|
|
|
showEntry e =
|
2008-11-22 09:35:10 +03:00
|
|
|
unlines $ [{-precedingcomment ++ -}description] ++ (showtxns $ etransactions e) ++ [""]
|
2007-07-04 13:28:07 +04:00
|
|
|
where
|
2008-06-28 08:44:33 +04:00
|
|
|
precedingcomment = epreceding_comment_lines e
|
2007-07-07 13:05:35 +04:00
|
|
|
description = concat [date, status, code, desc] -- , comment]
|
2008-11-27 07:01:07 +03:00
|
|
|
date = showdate $ edate e
|
2007-07-04 13:28:07 +04:00
|
|
|
status = if estatus e then " *" else ""
|
2007-07-04 16:40:26 +04:00
|
|
|
code = if (length $ ecode e) > 0 then (printf " (%s)" $ ecode e) else ""
|
2007-07-07 13:05:35 +04:00
|
|
|
desc = " " ++ edescription e
|
2007-07-04 16:40:26 +04:00
|
|
|
comment = if (length $ ecomment e) > 0 then " ; "++(ecomment e) else ""
|
2007-07-04 13:28:07 +04:00
|
|
|
showtxns (t1:t2:[]) = [showtxn t1, showtxnnoamt t2]
|
|
|
|
showtxns ts = map showtxn ts
|
2007-07-04 16:05:54 +04:00
|
|
|
showtxn t = showacct t ++ " " ++ (showamount $ tamount t) ++ (showcomment $ tcomment t)
|
2007-07-07 13:05:35 +04:00
|
|
|
showtxnnoamt t = showacct t ++ " " ++ (showcomment $ tcomment t)
|
2007-07-04 13:28:07 +04:00
|
|
|
showacct t = " " ++ (showaccountname $ taccount t)
|
2008-10-18 12:39:08 +04:00
|
|
|
showamount = printf "%12s" . showMixedAmount
|
2007-07-07 13:05:35 +04:00
|
|
|
showaccountname s = printf "%-34s" s
|
2007-07-04 16:40:26 +04:00
|
|
|
showcomment s = if (length s) > 0 then " ; "++s else ""
|
2008-11-27 07:01:07 +03:00
|
|
|
showdate d = printf "%-10s" (showDate d)
|
2008-10-18 08:15:43 +04:00
|
|
|
|
|
|
|
isEntryBalanced :: Entry -> Bool
|
2008-10-18 13:02:19 +04:00
|
|
|
isEntryBalanced (Entry {etransactions=ts}) =
|
2008-12-05 13:04:59 +03:00
|
|
|
isZeroMixedAmount $ costOfMixedAmount $ sum $ map tamount $ filter isReal ts
|
2008-10-18 08:15:43 +04:00
|
|
|
|
2008-12-05 13:04:59 +03:00
|
|
|
-- | Ensure that this entry is balanced, possibly auto-filling a missing
|
|
|
|
-- amount first. We can auto-fill if there is just one non-virtual
|
|
|
|
-- transaction without an amount. The auto-filled balance will be
|
|
|
|
-- converted to cost basis if possible. If the entry can not be balanced,
|
|
|
|
-- raise an error.
|
2008-10-18 10:45:02 +04:00
|
|
|
balanceEntry :: Entry -> Entry
|
2008-12-05 13:04:59 +03:00
|
|
|
balanceEntry e@Entry{etransactions=ts} = (e{etransactions=ts'})
|
|
|
|
where
|
|
|
|
check e
|
|
|
|
| isEntryBalanced e = e
|
|
|
|
| otherwise = error $ "could not balance this entry:\n" ++ show e
|
2008-10-18 10:45:02 +04:00
|
|
|
(withamounts, missingamounts) = partition hasAmount $ filter isReal ts
|
|
|
|
ts' = case (length missingamounts) of
|
|
|
|
0 -> ts
|
|
|
|
1 -> map balance ts
|
|
|
|
otherwise -> error $ "could not balance this entry, too many missing amounts:\n" ++ show e
|
2008-10-18 14:38:01 +04:00
|
|
|
otherstotal = sum $ map tamount withamounts
|
2008-10-18 10:45:02 +04:00
|
|
|
balance t
|
2008-11-22 23:32:58 +03:00
|
|
|
| isReal t && not (hasAmount t) = t{tamount = costOfMixedAmount (-otherstotal)}
|
2008-10-18 10:45:02 +04:00
|
|
|
| otherwise = t
|