Permalink
Browse files

parse posting dates, better comment/tag handling, begin using HTF for…

… unit testing
  • Loading branch information...
simonmichael committed Dec 6, 2012
1 parent d0bd066 commit e75abc46259085f24a3f69ec1e4264943b22b8ab
View
@@ -408,6 +408,16 @@ Filtering reports by tag is work in progress. For the moment, you can
match transactions' or postings' tag values by adding `tag
NAME=EXACTVALUE` on the command line.
### Posting dates
You can give individual postings a different date (or dates) from their parent transaction,
by adding posting tags `date:ACTUALDATE` and/or `date2:EFFECTIVEDATE`.
For compatibility, ledger's posting date syntax is also supported
(`[ACTUALDATE]`, `[=EFFECTIVEDATE]` or `[ACTUALDATE=EFFECTIVEDATE]` in a
posting comment), and treated as an alterate spelling of the date and
date2 tags.
### Including other files
You can pull in the content of additional journal files, by writing lines like this:
@@ -1312,7 +1322,7 @@ entries, and the following c++ ledger options and commands:
and "not:" prefixes, unlike ledger 3's free-form parser
- hledger doesn't require a space before command-line option
values, eg either `-f-` or `-f -` is fine
values, eg `-fFILE` or `-f FILE` works
- hledger's weekly reporting intervals always start on mondays
@@ -28,6 +28,7 @@ module Hledger.Data.Dates (
getCurrentYear,
nulldate,
spanContainsDate,
parsedateM,
parsedate,
showDate,
elapsedSeconds,
@@ -64,7 +64,8 @@ instance Show Posting where show = showPosting
nullposting, posting :: Posting
nullposting = Posting
{pstatus=False
{pdate=Nothing
,pstatus=False
,paccount=""
,pamount=nullmixedamt
,pcomment=""
@@ -98,7 +99,7 @@ tagsAsLines :: [(String, String)] -> [String]
tagsAsLines mds = map (\(k,v) -> " ; " ++ k++": "++v) mds
showComment :: String -> String
showComment s = if null s then "" else " ; " ++ s
showComment s = if null s then "" else " ;" ++ s
-- XXX refactor
showPostingForRegister :: Posting -> String
@@ -132,8 +133,13 @@ accountNamesFromPostings = nub . map paccount
sumPostings :: [Posting] -> MixedAmount
sumPostings = sum . map pamount
-- | Get a posting's (primary) date - it's own date if specified,
-- otherwise the parent transaction's primary date (otherwise the null
-- date).
postingDate :: Posting -> Day
postingDate p = maybe nulldate tdate $ ptransaction p
postingDate p = fromMaybe txndate $ pdate p
where
txndate = maybe nulldate tdate $ ptransaction p
-- |Is this posting cleared? If this posting was individually marked
-- as cleared, returns True. Otherwise, return the parent
@@ -231,4 +237,4 @@ tests_Hledger_Data_Posting = TestList [
concatAccountNames ["a","(b)","[c:d]"] `is` "(a:b:c:d)"
]
@@ -115,14 +115,13 @@ tests_showTransactionUnelided = [
]
}
`gives` unlines [
"2012/05/14=2012/05/15 (code) desc ; tcomment1",
" ; tcomment2",
" ; ttag1: val1",
"2012/05/14=2012/05/15 (code) desc",
" ;tcomment1",
" ;tcomment2",
" $1.00",
" * a 2.0h ; pcomment1",
" ; pcomment2",
" ; ptag1: val1",
" ; ptag2: val2",
" * a 2.0h",
" ;pcomment1",
" ;pcomment2",
""
]
]
@@ -131,26 +130,30 @@ tests_showTransactionUnelided = [
showTransaction' :: Bool -> Transaction -> String
showTransaction' elide t =
unlines $ [descriptionline]
++ commentlines
++ (tagsAsLines $ ttags t)
++ multilinecomment
-- ++ (tagsAsLines $ ttags t)
++ (postingsAsLines elide t (tpostings t))
++ [""]
where
descriptionline = rstrip $ concat [date, status, code, desc, firstcomment]
descriptionline = rstrip $ concat [date, status, code, desc, inlinecomment]
date = showdate (tdate t) ++ maybe "" showedate (teffectivedate t)
showdate = printf "%-10s" . showDate
showedate = printf "=%s" . showdate
status = if tstatus t then " *" else ""
code = if length (tcode t) > 0 then printf " (%s)" $ tcode t else ""
desc = if null d then "" else " " ++ d where d = tdescription t
(firstcomment, commentlines) = commentLines $ tcomment t
(inlinecomment, multilinecomment) = commentLines $ tcomment t
-- Render a transaction or posting's comment as indented & prefixed comment lines.
-- Render a transaction or posting's comment as indented, semicolon-prefixed comment lines -
-- an inline comment (when it's a single line) or multiple lines.
commentLines :: String -> (String, [String])
commentLines s
| null s = ("", [])
| otherwise = (" ; " ++ first, map (indent . ("; "++)) rest)
where (first:rest) = lines s
| length ls == 1 = (prefix $ head ls, [])
| otherwise = ("", (prefix $ head ls):(map prefix $ tail ls))
where
ls = lines s
prefix = indent . (";"++)
postingsAsLines :: Bool -> Transaction -> [Posting] -> [String]
postingsAsLines elide t ps
@@ -161,12 +164,12 @@ postingsAsLines elide t ps
postingAsLines :: Bool -> [Posting] -> Posting -> [String]
postingAsLines elideamount ps p =
postinglines
++ commentlines
++ tagsAsLines (ptags p)
++ multilinecomment
-- ++ tagsAsLines (ptags p)
where
postinglines = map rstrip $ lines $ concatTopPadded [showacct p, " ", amount, firstcomment]
postinglines = map rstrip $ lines $ concatTopPadded [showacct p, " ", amount, inlinecomment]
amount = if elideamount then "" else showamt (pamount p)
(firstcomment, commentlines) = commentLines $ pcomment p
(inlinecomment, multilinecomment) = commentLines $ pcomment p
showacct p =
indent $ showstatus p ++ printf (printf "%%-%ds" w) (showAccountName Nothing (ptype p) (paccount p))
where
@@ -178,22 +181,22 @@ postingAsLines elideamount ps p =
tests_postingAsLines = [
"postingAsLines" ~: do
let p `gives` ls = assertEqual "" ls (postingAsLines False [p] p)
nullposting `gives` [" 0"]
nullposting{
posting `gives` [" 0"]
posting{
pstatus=True,
paccount="a",
pamount=Mixed [usd 1, hrs 2],
pcomment="pcomment1\npcomment2\n",
pcomment="pcomment1\npcomment2\n tag3: val3 \n",
ptype=RegularPosting,
ptags=[("ptag1","val1"),("ptag2","val2")]
}
`gives` [
" $1.00",
" * a 2.0h ; pcomment1",
" ; pcomment2",
" ; ptag1: val1",
" ; ptag2: val2"
]
" * a 2.0h",
" ;pcomment1",
" ;pcomment2",
" ; tag3: val3 "
]
]
indent :: String -> String
@@ -76,6 +76,7 @@ data PostingType = RegularPosting | VirtualPosting | BalancedVirtualPosting
type Tag = (String, String)
data Posting = Posting {
pdate :: Maybe Day, -- ^ this posting's clearing date, if different from the transaction's
pstatus :: Bool,
paccount :: AccountName,
pamount :: MixedAmount,
@@ -89,7 +90,7 @@ data Posting = Posting {
-- The equality test for postings ignores the parent transaction's
-- identity, to avoid infinite loops.
instance Eq Posting where
(==) (Posting a1 b1 c1 d1 e1 f1 _) (Posting a2 b2 c2 d2 e2 f2 _) = a1==a2 && b1==b2 && c1==c2 && d1==d2 && e1==e2 && f1==f2
(==) (Posting a1 b1 c1 d1 e1 f1 g1 _) (Posting a2 b2 c2 d2 e2 f2 g2 _) = a1==a2 && b1==b2 && c1==c2 && d1==d2 && e1==e2 && f1==f2 && g1==g2
data Transaction = Transaction {
tdate :: Day,
@@ -247,6 +248,8 @@ data Account = Account {
aboring :: Bool -- ^ used in the accounts report to label elidable parents
}
-- | A Ledger has the journal it derives from, and the accounts
-- derived from that. Accounts are accessible both list-wise and
-- tree-wise, since each one knows its parent and subs; the first
@@ -216,7 +216,7 @@ samplejournal = readJournal' $ unlines
tests_Hledger_Read = TestList $
tests_readJournal'
++ [
tests_Hledger_Read_JournalReader,
-- tests_Hledger_Read_JournalReader,
tests_Hledger_Read_TimelogReader,
tests_Hledger_Read_CsvReader,
Oops, something went wrong.

0 comments on commit e75abc4

Please sign in to comment.