make Postings reference their parent Transaction

With this change, Transactions and Postings reference each other
co-recursively.  This makes constructing them more tedious, but it
may also allow LedgerPostings to be dropped and code to be simplified.
Time and space performance of register and balance is as before.
This commit is contained in:
Simon Michael 2009-12-19 03:44:52 +00:00
parent 8405072ff6
commit ec95b0723c
10 changed files with 126 additions and 108 deletions

View File

@ -256,8 +256,7 @@ transactionFromCsvRecord rules fields =
unknownacct | (readDef 0 amountstr' :: Double) < 0 = "income:unknown" unknownacct | (readDef 0 amountstr' :: Double) < 0 = "income:unknown"
| otherwise = "expenses:unknown" | otherwise = "expenses:unknown"
(acct,newdesc) = identify (accountRules rules) unknownacct desc (acct,newdesc) = identify (accountRules rules) unknownacct desc
in t = Transaction {
Transaction {
tdate=date, tdate=date,
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=status, tstatus=status,
@ -271,17 +270,20 @@ transactionFromCsvRecord rules fields =
paccount=acct, paccount=acct,
pamount=amount, pamount=amount,
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Just t
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount=baseAccount rules, paccount=baseAccount rules,
pamount=(-amount), pamount=(-amount),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Just t
} }
] ]
} }
in t
-- | Convert some date string with unknown format to YYYY/MM/DD. -- | Convert some date string with unknown format to YYYY/MM/DD.
normaliseDate :: String -> String normaliseDate :: String -> String

View File

@ -114,7 +114,7 @@ showlp omitdesc lp b = concatBottomPadded [entrydesc ++ p ++ " ", bal] ++ "\n"
datewidth = 10 datewidth = 10
descwidth = datedescwidth - datewidth - 2 descwidth = datedescwidth - datewidth - 2
desc = printf ("%-"++(show descwidth)++"s") $ elideRight descwidth de :: String desc = printf ("%-"++(show descwidth)++"s") $ elideRight descwidth de :: String
p = showPostingWithoutPrice $ Posting s a amt "" tt p = showPostingWithoutPrice $ Posting s a amt "" tt Nothing
bal = padleft 12 (showMixedAmountOrZeroWithoutPrice b) bal = padleft 12 (showMixedAmountOrZeroWithoutPrice b)
LedgerPosting{lpstatus=s,lpdate=da,lpdescription=de,lpaccount=a,lpamount=amt,lptype=tt} = lp LedgerPosting{lpstatus=s,lpdate=da,lpdescription=de,lpaccount=a,lpamount=amt,lptype=tt} = lp

View File

@ -310,8 +310,8 @@ handleAddform l = do
,tdescription=desc ,tdescription=desc
,tcomment="" ,tcomment=""
,tpostings=[ ,tpostings=[
Posting False acct1 amt1' "" RegularPosting Posting False acct1 amt1' "" RegularPosting (Just t')
,Posting False acct2 amt2' "" RegularPosting ,Posting False acct2 amt2' "" RegularPosting (Just t')
] ]
,tpreceding_comment_lines="" ,tpreceding_comment_lines=""
} }

View File

@ -140,7 +140,7 @@ canonicaliseAmounts costbasis rl@(Journal ms ps ts tls hs f fp ft) = Journal ms
where where
fixledgertransaction (Transaction d ed s c de co ts pr) = Transaction d ed s c de co (map fixrawposting ts) pr fixledgertransaction (Transaction d ed s c de co ts pr) = Transaction d ed s c de co (map fixrawposting ts) pr
where where
fixrawposting (Posting s ac a c t) = Posting s ac (fixmixedamount a) c t fixrawposting (Posting s ac a c t txn) = Posting s ac (fixmixedamount a) c t txn
fixmixedamount (Mixed as) = Mixed $ map fixamount as fixmixedamount (Mixed as) = Mixed $ map fixamount as
fixamount = (if costbasis then costOfAmount else id) . fixprice . fixcommodity fixamount = (if costbasis then costOfAmount else id) . fixprice . fixcommodity
fixcommodity a = a{commodity=c} where c = canonicalcommoditymap ! symbol (commodity a) fixcommodity a = a{commodity=c} where c = canonicalcommoditymap ! symbol (commodity a)

View File

@ -317,7 +317,7 @@ ledgerTransaction = do
comment <- ledgercomment <|> return "" comment <- ledgercomment <|> return ""
restofline restofline
postings <- ledgerpostings postings <- ledgerpostings
let t = Transaction date edate status code description comment postings "" let t = txnTieKnot $ Transaction date edate status code description comment postings ""
case balanceTransaction t of case balanceTransaction t of
Right t' -> return t' Right t' -> return t'
Left err -> fail err Left err -> fail err
@ -392,7 +392,7 @@ ledgerposting = do
many spacenonewline many spacenonewline
comment <- ledgercomment <|> return "" comment <- ledgercomment <|> return ""
restofline restofline
return (Posting status account' amount comment ptype) return (Posting status account' amount comment ptype Nothing)
-- Qualify with the parent account from parsing context -- Qualify with the parent account from parsing context
transactionaccountname :: GenParser Char LedgerFileCtx AccountName transactionaccountname :: GenParser Char LedgerFileCtx AccountName

View File

@ -19,29 +19,29 @@ import Ledger.AccountName
instance Show Posting where show = showPosting instance Show Posting where show = showPosting
nullrawposting = Posting False "" nullmixedamt "" RegularPosting nullrawposting = Posting False "" nullmixedamt "" RegularPosting Nothing
showPosting :: Posting -> String showPosting :: Posting -> String
showPosting (Posting _ a amt com lptype) = showPosting (Posting{paccount=a,pamount=amt,pcomment=com,ptype=t}) =
concatTopPadded [showaccountname a ++ " ", showamount amt, comment] concatTopPadded [showaccountname a ++ " ", showamount amt, comment]
where where
ledger3ishlayout = False ledger3ishlayout = False
acctnamewidth = if ledger3ishlayout then 25 else 22 acctnamewidth = if ledger3ishlayout then 25 else 22
showaccountname = printf ("%-"++(show acctnamewidth)++"s") . bracket . elideAccountName width showaccountname = printf ("%-"++(show acctnamewidth)++"s") . bracket . elideAccountName width
(bracket,width) = case lptype of (bracket,width) = case t of
BalancedVirtualPosting -> (\s -> "["++s++"]", acctnamewidth-2) BalancedVirtualPosting -> (\s -> "["++s++"]", acctnamewidth-2)
VirtualPosting -> (\s -> "("++s++")", acctnamewidth-2) VirtualPosting -> (\s -> "("++s++")", acctnamewidth-2)
_ -> (id,acctnamewidth) _ -> (id,acctnamewidth)
showamount = padleft 12 . showMixedAmountOrZero showamount = padleft 12 . showMixedAmountOrZero
comment = if null com then "" else " ; " ++ com comment = if null com then "" else " ; " ++ com
-- XXX refactor -- XXX refactor
showPostingWithoutPrice (Posting _ a amt com lptype) = showPostingWithoutPrice (Posting{paccount=a,pamount=amt,pcomment=com,ptype=t}) =
concatTopPadded [showaccountname a ++ " ", showamount amt, comment] concatTopPadded [showaccountname a ++ " ", showamount amt, comment]
where where
ledger3ishlayout = False ledger3ishlayout = False
acctnamewidth = if ledger3ishlayout then 25 else 22 acctnamewidth = if ledger3ishlayout then 25 else 22
showaccountname = printf ("%-"++(show acctnamewidth)++"s") . bracket . elideAccountName width showaccountname = printf ("%-"++(show acctnamewidth)++"s") . bracket . elideAccountName width
(bracket,width) = case lptype of (bracket,width) = case t of
BalancedVirtualPosting -> (\s -> "["++s++"]", acctnamewidth-2) BalancedVirtualPosting -> (\s -> "["++s++"]", acctnamewidth-2)
VirtualPosting -> (\s -> "("++s++")", acctnamewidth-2) VirtualPosting -> (\s -> "("++s++")", acctnamewidth-2)
_ -> (id,acctnamewidth) _ -> (id,acctnamewidth)

View File

@ -84,6 +84,7 @@ entryFromTimeLogInOut i o
idate = localDay itime idate = localDay itime
hrs = elapsedSeconds (toutc otime) (toutc itime) / 3600 where toutc = localTimeToUTC utc hrs = elapsedSeconds (toutc otime) (toutc itime) / 3600 where toutc = localTimeToUTC utc
amount = Mixed [hours hrs] amount = Mixed [hours hrs]
ps = [Posting False acctname amount "" RegularPosting ps = [Posting{pstatus=False,paccount=acctname,pamount=amount,
pcomment="",ptype=RegularPosting,ptransaction=Just t}
--,Posting "assets:time" (-amount) "" RegularPosting --,Posting "assets:time" (-amount) "" RegularPosting
] ]

View File

@ -131,3 +131,11 @@ ledgerTransactionWithDate :: WhichDate -> Transaction -> Transaction
ledgerTransactionWithDate ActualDate t = t ledgerTransactionWithDate ActualDate t = t
ledgerTransactionWithDate EffectiveDate t = t{tdate=fromMaybe (tdate t) (teffectivedate t)} ledgerTransactionWithDate EffectiveDate t = t{tdate=fromMaybe (tdate t) (teffectivedate t)}
-- | Ensure a transaction's postings refer to it as their transaction.
txnTieKnot :: Transaction -> Transaction
txnTieKnot t@Transaction{tpostings=ps} = t{tpostings=map (settxn t) ps}
-- | Set a posting's parent transaction.
settxn :: Transaction -> Posting -> Posting
settxn t p = p{ptransaction=Just t}

View File

@ -74,7 +74,9 @@ data Posting = Posting {
paccount :: AccountName, paccount :: AccountName,
pamount :: MixedAmount, pamount :: MixedAmount,
pcomment :: String, pcomment :: String,
ptype :: PostingType ptype :: PostingType,
ptransaction :: Maybe Transaction -- ^ this posting's parent transaction (co-recursive types).
-- Tying this knot gets tedious, Maybe makes it easier/optional.
} deriving (Eq) } deriving (Eq)
data ModifierTransaction = ModifierTransaction { data ModifierTransaction = ModifierTransaction {

187
Tests.hs
View File

@ -310,18 +310,18 @@ tests = [
assertBool "detect unbalanced entry, sign error" assertBool "detect unbalanced entry, sign error"
(isLeft $ balanceTransaction (isLeft $ balanceTransaction
(Transaction (parsedate "2007/01/28") Nothing False "" "test" "" (Transaction (parsedate "2007/01/28") Nothing False "" "test" ""
[Posting False "a" (Mixed [dollars 1]) "" RegularPosting, [Posting False "a" (Mixed [dollars 1]) "" RegularPosting Nothing,
Posting False "b" (Mixed [dollars 1]) "" RegularPosting Posting False "b" (Mixed [dollars 1]) "" RegularPosting Nothing
] "")) ] ""))
assertBool "detect unbalanced entry, multiple missing amounts" assertBool "detect unbalanced entry, multiple missing amounts"
(isLeft $ balanceTransaction (isLeft $ balanceTransaction
(Transaction (parsedate "2007/01/28") Nothing False "" "test" "" (Transaction (parsedate "2007/01/28") Nothing False "" "test" ""
[Posting False "a" missingamt "" RegularPosting, [Posting False "a" missingamt "" RegularPosting Nothing,
Posting False "b" missingamt "" RegularPosting Posting False "b" missingamt "" RegularPosting Nothing
] "")) ] ""))
let e = balanceTransaction (Transaction (parsedate "2007/01/28") Nothing False "" "test" "" let e = balanceTransaction (Transaction (parsedate "2007/01/28") Nothing False "" "test" ""
[Posting False "a" (Mixed [dollars 1]) "" RegularPosting, [Posting False "a" (Mixed [dollars 1]) "" RegularPosting Nothing,
Posting False "b" missingamt "" RegularPosting Posting False "b" missingamt "" RegularPosting Nothing
] "") ] "")
assertBool "one missing amount should be ok" (isRight e) assertBool "one missing amount should be ok" (isRight e)
assertEqual "balancing amount is added" assertEqual "balancing amount is added"
@ -405,50 +405,43 @@ tests = [
"my assets" `isAccountNamePrefixOf` "assets:bank" `is` False "my assets" `isAccountNamePrefixOf` "assets:bank" `is` False
,"isTransactionBalanced" ~: do ,"isTransactionBalanced" ~: do
assertBool "detect balanced" let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
(isTransactionBalanced [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" ,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting (Just t)
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting ] ""
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting assertBool "detect balanced" (isTransactionBalanced t)
] "")) let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
assertBool "detect unbalanced" [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
(not $ isTransactionBalanced ,Posting False "c" (Mixed [dollars (-1.01)]) "" RegularPosting (Just t)
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" ] ""
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting assertBool "detect unbalanced" (not $ isTransactionBalanced t)
,Posting False "c" (Mixed [dollars (-1.01)]) "" RegularPosting let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
] "")) [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
assertBool "detect unbalanced, one posting" ] ""
(not $ isTransactionBalanced assertBool "detect unbalanced, one posting" (not $ isTransactionBalanced t)
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [Posting False "b" (Mixed [dollars 0]) "" RegularPosting (Just t)
] "")) ] ""
assertBool "one zero posting is considered balanced for now" assertBool "one zero posting is considered balanced for now" (isTransactionBalanced t)
(isTransactionBalanced let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
[Posting False "b" (Mixed [dollars 0]) "" RegularPosting ,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting (Just t)
] "")) ,Posting False "d" (Mixed [dollars 100]) "" VirtualPosting (Just t)
assertBool "virtual postings don't need to balance" ] ""
(isTransactionBalanced assertBool "virtual postings don't need to balance" (isTransactionBalanced t)
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting ,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting (Just t)
,Posting False "d" (Mixed [dollars 100]) "" VirtualPosting ,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting (Just t)
] "")) ] ""
assertBool "balanced virtual postings need to balance among themselves" assertBool "balanced virtual postings need to balance among themselves" (not $ isTransactionBalanced t)
(not $ isTransactionBalanced let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
(Transaction (parsedate "2009/01/01") Nothing False "" "a" "" [Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting (Just t)
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting ,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting (Just t)
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting ,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting (Just t)
,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting ,Posting False "e" (Mixed [dollars (-100)]) "" BalancedVirtualPosting (Just t)
] "")) ] ""
assertBool "balanced virtual postings need to balance among themselves (2)" assertBool "balanced virtual postings need to balance among themselves (2)" (isTransactionBalanced t)
(isTransactionBalanced
(Transaction (parsedate "2009/01/01") Nothing False "" "a" ""
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting
,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting
,Posting False "e" (Mixed [dollars (-100)]) "" BalancedVirtualPosting
] ""))
,"isSubAccountNameOf" ~: do ,"isSubAccountNameOf" ~: do
"assets" `isSubAccountNameOf` "assets" `is` False "assets" `isSubAccountNameOf` "assets" `is` False
@ -678,11 +671,11 @@ tests = [
," assets:checking" ," assets:checking"
,"" ,""
]) ])
(showTransaction (let t = Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
(Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" [Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting (Just t)
[Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting ,Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting (Just t)
,Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting ] ""
] "")) in showTransaction t)
assertEqual "show a balanced transaction, no eliding" assertEqual "show a balanced transaction, no eliding"
(unlines (unlines
["2007/01/28 coopportunity" ["2007/01/28 coopportunity"
@ -690,11 +683,11 @@ tests = [
," assets:checking $-47.18" ," assets:checking $-47.18"
,"" ,""
]) ])
(showTransactionUnelided (let t = Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
(Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" [Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting (Just t)
[Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting ,Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting (Just t)
,Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting ] ""
] "")) in showTransactionUnelided t)
-- document some cases that arise in debug/testing: -- document some cases that arise in debug/testing:
assertEqual "show an unbalanced transaction, should not elide" assertEqual "show an unbalanced transaction, should not elide"
(unlines (unlines
@ -704,9 +697,9 @@ tests = [
,"" ,""
]) ])
(showTransaction (showTransaction
(Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" (txnTieKnot $ Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
[Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting [Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting Nothing
,Posting False "assets:checking" (Mixed [dollars (-47.19)]) "" RegularPosting ,Posting False "assets:checking" (Mixed [dollars (-47.19)]) "" RegularPosting Nothing
] "")) ] ""))
assertEqual "show an unbalanced transaction with one posting, should not elide" assertEqual "show an unbalanced transaction with one posting, should not elide"
(unlines (unlines
@ -715,8 +708,8 @@ tests = [
,"" ,""
]) ])
(showTransaction (showTransaction
(Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" (txnTieKnot $ Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
[Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting [Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting Nothing
] "")) ] ""))
assertEqual "show a transaction with one posting and a missing amount" assertEqual "show a transaction with one posting and a missing amount"
(unlines (unlines
@ -725,8 +718,8 @@ tests = [
,"" ,""
]) ])
(showTransaction (showTransaction
(Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" (txnTieKnot $ Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
[Posting False "expenses:food:groceries" missingamt "" RegularPosting [Posting False "expenses:food:groceries" missingamt "" RegularPosting Nothing
] "")) ] ""))
,"unicode in balance layout" ~: do ,"unicode in balance layout" ~: do
@ -906,19 +899,19 @@ write_sample_ledger = writeFile "sample.ledger" sample_ledger_str
rawposting1_str = " expenses:food:dining $10.00\n" rawposting1_str = " expenses:food:dining $10.00\n"
rawposting1 = Posting False "expenses:food:dining" (Mixed [dollars 10]) "" RegularPosting rawposting1 = Posting False "expenses:food:dining" (Mixed [dollars 10]) "" RegularPosting Nothing
entry1_str = unlines entry1_str = unlines
["2007/01/28 coopportunity" ["2007/01/28 coopportunity"
," expenses:food:groceries $47.18" ," expenses:food:groceries $47.18"
," assets:checking" ," assets:checking $-47.18"
,"" ,""
] ]
entry1 = entry1 =
Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" "" txnTieKnot $ Transaction (parsedate "2007/01/28") Nothing False "" "coopportunity" ""
[Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting, [Posting False "expenses:food:groceries" (Mixed [dollars 47.18]) "" RegularPosting Nothing,
Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting] "" Posting False "assets:checking" (Mixed [dollars (-47.18)]) "" RegularPosting Nothing] ""
entry2_str = unlines entry2_str = unlines
@ -1064,7 +1057,7 @@ journal7 = Journal
[] []
[] []
[ [
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/01/01", tdate=parsedate "2007/01/01",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1077,20 +1070,22 @@ journal7 = Journal
paccount="assets:cash", paccount="assets:cash",
pamount=(Mixed [dollars 4.82]), pamount=(Mixed [dollars 4.82]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="equity:opening balances", paccount="equity:opening balances",
pamount=(Mixed [dollars (-4.82)]), pamount=(Mixed [dollars (-4.82)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
} }
, ,
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/02/01", tdate=parsedate "2007/02/01",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1103,20 +1098,22 @@ journal7 = Journal
paccount="expenses:vacation", paccount="expenses:vacation",
pamount=(Mixed [dollars 179.92]), pamount=(Mixed [dollars 179.92]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="assets:checking", paccount="assets:checking",
pamount=(Mixed [dollars (-179.92)]), pamount=(Mixed [dollars (-179.92)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
} }
, ,
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/01/02", tdate=parsedate "2007/01/02",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1129,20 +1126,22 @@ journal7 = Journal
paccount="assets:saving", paccount="assets:saving",
pamount=(Mixed [dollars 200]), pamount=(Mixed [dollars 200]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="assets:checking", paccount="assets:checking",
pamount=(Mixed [dollars (-200)]), pamount=(Mixed [dollars (-200)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
} }
, ,
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/01/03", tdate=parsedate "2007/01/03",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1155,20 +1154,22 @@ journal7 = Journal
paccount="expenses:food:dining", paccount="expenses:food:dining",
pamount=(Mixed [dollars 4.82]), pamount=(Mixed [dollars 4.82]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="assets:cash", paccount="assets:cash",
pamount=(Mixed [dollars (-4.82)]), pamount=(Mixed [dollars (-4.82)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
} }
, ,
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/01/03", tdate=parsedate "2007/01/03",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1181,20 +1182,22 @@ journal7 = Journal
paccount="expenses:phone", paccount="expenses:phone",
pamount=(Mixed [dollars 95.11]), pamount=(Mixed [dollars 95.11]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="assets:checking", paccount="assets:checking",
pamount=(Mixed [dollars (-95.11)]), pamount=(Mixed [dollars (-95.11)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
} }
, ,
Transaction { txnTieKnot $ Transaction {
tdate=parsedate "2007/01/03", tdate=parsedate "2007/01/03",
teffectivedate=Nothing, teffectivedate=Nothing,
tstatus=False, tstatus=False,
@ -1207,14 +1210,16 @@ journal7 = Journal
paccount="liabilities:credit cards:discover", paccount="liabilities:credit cards:discover",
pamount=(Mixed [dollars 80]), pamount=(Mixed [dollars 80]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
}, },
Posting { Posting {
pstatus=False, pstatus=False,
paccount="assets:checking", paccount="assets:checking",
pamount=(Mixed [dollars (-80)]), pamount=(Mixed [dollars (-80)]),
pcomment="", pcomment="",
ptype=RegularPosting ptype=RegularPosting,
ptransaction=Nothing
} }
], ],
tpreceding_comment_lines="" tpreceding_comment_lines=""
@ -1253,7 +1258,7 @@ journalWithAmounts as =
Journal Journal
[] []
[] []
[nullledgertxn{tdescription=a,tpostings=[nullrawposting{pamount=parse a}]} | a <- as] [t | a <- as, let t = nullledgertxn{tdescription=a,tpostings=[nullrawposting{pamount=parse a,ptransaction=Just t}]}]
[] []
[] []
"" ""