parse virtual and balanced virtual transactions, refactor register and transaction output
This commit is contained in:
		
							parent
							
								
									014723497f
								
							
						
					
					
						commit
						dce8fd0dde
					
				| @ -250,7 +250,9 @@ ledgercode :: Parser String | |||||||
| ledgercode = try (do { char '('; code <- anyChar `manyTill` char ')'; many1 spacenonewline; return code } ) <|> return "" | ledgercode = try (do { char '('; code <- anyChar `manyTill` char ')'; many1 spacenonewline; return code } ) <|> return "" | ||||||
| 
 | 
 | ||||||
| ledgertransactions :: Parser [RawTransaction] | ledgertransactions :: Parser [RawTransaction] | ||||||
| ledgertransactions = (ledgertransaction <?> "transaction") `manyTill` (do {newline <?> "blank line"; return ()} <|> eof) | ledgertransactions =  | ||||||
|  |     ((try virtualtransaction <|> try balancedvirtualtransaction <|> ledgertransaction) <?> "transaction")  | ||||||
|  |     `manyTill` (do {newline <?> "blank line"; return ()} <|> eof) | ||||||
| 
 | 
 | ||||||
| ledgertransaction :: Parser RawTransaction | ledgertransaction :: Parser RawTransaction | ||||||
| ledgertransaction = do | ledgertransaction = do | ||||||
| @ -260,7 +262,31 @@ ledgertransaction = do | |||||||
|   many spacenonewline |   many spacenonewline | ||||||
|   comment <- ledgercomment |   comment <- ledgercomment | ||||||
|   restofline |   restofline | ||||||
|   return (RawTransaction account amount comment) |   return (RawTransaction account amount comment RegularTransaction) | ||||||
|  | 
 | ||||||
|  | virtualtransaction :: Parser RawTransaction | ||||||
|  | virtualtransaction = do | ||||||
|  |   many1 spacenonewline | ||||||
|  |   char '(' | ||||||
|  |   account <- ledgeraccountname | ||||||
|  |   char ')' | ||||||
|  |   amount <- transactionamount | ||||||
|  |   many spacenonewline | ||||||
|  |   comment <- ledgercomment | ||||||
|  |   restofline | ||||||
|  |   return (RawTransaction account amount comment VirtualTransaction) | ||||||
|  | 
 | ||||||
|  | balancedvirtualtransaction :: Parser RawTransaction | ||||||
|  | balancedvirtualtransaction = do | ||||||
|  |   many1 spacenonewline | ||||||
|  |   char '[' | ||||||
|  |   account <- ledgeraccountname | ||||||
|  |   char ']' | ||||||
|  |   amount <- transactionamount | ||||||
|  |   many spacenonewline | ||||||
|  |   comment <- ledgercomment | ||||||
|  |   restofline | ||||||
|  |   return (RawTransaction account amount comment BalancedVirtualTransaction) | ||||||
| 
 | 
 | ||||||
| -- | account names may have single spaces inside them, and are terminated by two or more spaces | -- | account names may have single spaces inside them, and are terminated by two or more spaces | ||||||
| ledgeraccountname :: Parser String | ledgeraccountname :: Parser String | ||||||
| @ -268,11 +294,13 @@ ledgeraccountname = do | |||||||
|     accountname <- many1 (accountnamechar <|> singlespace) |     accountname <- many1 (accountnamechar <|> singlespace) | ||||||
|     return $ striptrailingspace accountname |     return $ striptrailingspace accountname | ||||||
|     where  |     where  | ||||||
|       accountnamechar = nonspace <?> "account name character" |  | ||||||
|       singlespace = try (do {spacenonewline; do {notFollowedBy spacenonewline; return ' '}}) |       singlespace = try (do {spacenonewline; do {notFollowedBy spacenonewline; return ' '}}) | ||||||
|       -- couldn't avoid consuming a final space sometimes, harmless |       -- couldn't avoid consuming a final space sometimes, harmless | ||||||
|       striptrailingspace s = if last s == ' ' then init s else s |       striptrailingspace s = if last s == ' ' then init s else s | ||||||
| 
 | 
 | ||||||
|  | accountnamechar = notFollowedBy (oneOf "()[]") >> nonspace | ||||||
|  |     <?> "account name character (non-bracket, non-parenthesis, non-whitespace)" | ||||||
|  | 
 | ||||||
| transactionamount :: Parser Amount | transactionamount :: Parser Amount | ||||||
| transactionamount = | transactionamount = | ||||||
|   try (do |   try (do | ||||||
|  | |||||||
| @ -103,7 +103,7 @@ normaliseRawLedgerAmounts l@(RawLedger ms ps es f) = RawLedger ms ps es' f | |||||||
|       es' = map normaliseEntryAmounts es |       es' = map normaliseEntryAmounts es | ||||||
|       normaliseEntryAmounts (Entry d s c desc comm ts pre) = Entry d s c desc comm ts' pre |       normaliseEntryAmounts (Entry d s c desc comm ts pre) = Entry d s c desc comm ts' pre | ||||||
|           where ts' = map normaliseRawTransactionAmounts ts |           where ts' = map normaliseRawTransactionAmounts ts | ||||||
|       normaliseRawTransactionAmounts (RawTransaction acct a c) = RawTransaction acct a' c |       normaliseRawTransactionAmounts (RawTransaction acct a c t) = RawTransaction acct a' c t | ||||||
|           where a' = normaliseAmount a |           where a' = normaliseAmount a | ||||||
|       normaliseAmount (Amount c q) = Amount (firstoccurrenceof c) q |       normaliseAmount (Amount c q) = Amount (firstoccurrenceof c) q | ||||||
|       firstcommodities = nubBy samesymbol $ allcommodities |       firstcommodities = nubBy samesymbol $ allcommodities | ||||||
|  | |||||||
| @ -13,10 +13,10 @@ import Ledger.Amount | |||||||
| import Ledger.AccountName | import Ledger.AccountName | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| instance Show RawTransaction where show = showLedgerTransaction | instance Show RawTransaction where show = showRawTransaction | ||||||
| 
 | 
 | ||||||
| showLedgerTransaction :: RawTransaction -> String | showRawTransaction :: RawTransaction -> String | ||||||
| showLedgerTransaction t = (showaccountname $ taccount t) ++ " " ++ (showamount $ tamount t)  | showRawTransaction t = (showaccountname $ taccount t) ++ " " ++ (showamount $ tamount t)  | ||||||
|     where |     where | ||||||
|       showaccountname = printf "%-22s" . elideAccountName 22 |       showaccountname = printf "%-22s" . elideAccountName 22 | ||||||
|       showamount = printf "%12s" . showAmountOrZero |       showamount = printf "%12s" . showAmountOrZero | ||||||
|  | |||||||
| @ -58,6 +58,6 @@ entryFromTimeLogInOut i o = | |||||||
|       intime   = parsedatetime $ tldatetime i |       intime   = parsedatetime $ tldatetime i | ||||||
|       outtime  = parsedatetime $ tldatetime o |       outtime  = parsedatetime $ tldatetime o | ||||||
|       amount   = hours $ realToFrac (diffUTCTime outtime intime) / 3600 |       amount   = hours $ realToFrac (diffUTCTime outtime intime) / 3600 | ||||||
|       txns     = [RawTransaction acctname amount "" |       txns     = [RawTransaction acctname amount "" RegularTransaction | ||||||
|                  --,RawTransaction "assets:time" (-amount) "" |                  --,RawTransaction "assets:time" (-amount) "" RegularTransaction | ||||||
|                  ] |                  ] | ||||||
|  | |||||||
| @ -14,15 +14,17 @@ import Ledger.RawTransaction | |||||||
| import Ledger.Amount | import Ledger.Amount | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| instance Show Transaction where  | instance Show Transaction where show=showTransaction | ||||||
|     show (Transaction eno d desc a amt) = unwords [d,desc,a,show amt] | 
 | ||||||
|  | showTransaction :: Transaction -> String | ||||||
|  | showTransaction (Transaction eno d desc a amt ttype) = unwords [d,desc,a,show amt,show ttype] | ||||||
| 
 | 
 | ||||||
| -- | Convert a 'Entry' to two or more 'Transaction's. An id number | -- | Convert a 'Entry' to two or more 'Transaction's. An id number | ||||||
| -- is attached to the transactions to preserve their grouping - it should | -- is attached to the transactions to preserve their grouping - it should | ||||||
| -- be unique per entry. | -- be unique per entry. | ||||||
| flattenEntry :: (Entry, Int) -> [Transaction] | flattenEntry :: (Entry, Int) -> [Transaction] | ||||||
| flattenEntry (Entry d _ _ desc _ ts _, e) =  | flattenEntry (Entry d _ _ desc _ ts _, e) =  | ||||||
|     [Transaction e d desc (taccount t) (tamount t) | t <- ts] |     [Transaction e d desc (taccount t) (tamount t) (rttype t) | t <- ts] | ||||||
| 
 | 
 | ||||||
| accountNamesFromTransactions :: [Transaction] -> [AccountName] | accountNamesFromTransactions :: [Transaction] -> [AccountName] | ||||||
| accountNamesFromTransactions ts = nub $ map account ts | accountNamesFromTransactions ts = nub $ map account ts | ||||||
| @ -30,4 +32,4 @@ accountNamesFromTransactions ts = nub $ map account ts | |||||||
| sumTransactions :: [Transaction] -> Amount | sumTransactions :: [Transaction] -> Amount | ||||||
| sumTransactions = sum . map amount | sumTransactions = sum . map amount | ||||||
| 
 | 
 | ||||||
| nulltxn = Transaction 0 "" "" "" nullamt | nulltxn = Transaction 0 "" "" "" nullamt RegularTransaction | ||||||
|  | |||||||
| @ -36,10 +36,14 @@ data Amount = Amount { | |||||||
| 
 | 
 | ||||||
| type AccountName = String | type AccountName = String | ||||||
| 
 | 
 | ||||||
|  | data TransactionType = RegularTransaction | VirtualTransaction | BalancedVirtualTransaction | ||||||
|  |                        deriving (Eq,Show) | ||||||
|  | 
 | ||||||
| data RawTransaction = RawTransaction { | data RawTransaction = RawTransaction { | ||||||
|       taccount :: AccountName, |       taccount :: AccountName, | ||||||
|       tamount :: Amount, |       tamount :: Amount, | ||||||
|       tcomment :: String |       tcomment :: String, | ||||||
|  |       rttype :: TransactionType | ||||||
|     } deriving (Eq) |     } deriving (Eq) | ||||||
| 
 | 
 | ||||||
| -- | a ledger "modifier" entry. Currently ignored. | -- | a ledger "modifier" entry. Currently ignored. | ||||||
| @ -86,7 +90,8 @@ data Transaction = Transaction { | |||||||
|       date :: Date, |       date :: Date, | ||||||
|       description :: String, |       description :: String, | ||||||
|       account :: AccountName, |       account :: AccountName, | ||||||
|       amount :: Amount |       amount :: Amount, | ||||||
|  |       ttype :: TransactionType | ||||||
|     } deriving (Eq) |     } deriving (Eq) | ||||||
| 
 | 
 | ||||||
| data Account = Account { | data Account = Account { | ||||||
|  | |||||||
| @ -19,28 +19,35 @@ showTransactionsWithBalances opts args l = | |||||||
|     unlines $ showTransactionsWithBalances' ts nulltxn startingbalance |     unlines $ showTransactionsWithBalances' ts nulltxn startingbalance | ||||||
|         where |         where | ||||||
|           ts = filter matchtxn $ ledgerTransactions l |           ts = filter matchtxn $ ledgerTransactions l | ||||||
|           matchtxn (Transaction _ _ desc acct _) = matchLedgerPatterns False apats acct |           matchtxn (Transaction _ _ desc acct _ _) = matchLedgerPatterns False apats acct | ||||||
|           apats = fst $ parseAccountDescriptionArgs args |           apats = fst $ parseAccountDescriptionArgs args | ||||||
|           startingbalance = nullamt |           startingbalance = nullamt | ||||||
|           showTransactionsWithBalances' :: [Transaction] -> Transaction -> Amount -> [String] |           showTransactionsWithBalances' :: [Transaction] -> Transaction -> Amount -> [String] | ||||||
|           showTransactionsWithBalances' [] _ _ = [] |           showTransactionsWithBalances' [] _ _ = [] | ||||||
|           showTransactionsWithBalances' (t:ts) tprev b = |           showTransactionsWithBalances' (t:ts) tprev b = this ++ rest | ||||||
|               (if sameentry t tprev |               where | ||||||
|                then [showTransactionAndBalance t b'] |                 b' = b + (amount t) | ||||||
|                else [showTransactionDescriptionAndBalance t b']) |                 sameentry (Transaction {entryno=e1}) (Transaction {entryno=e2}) = e1 == e2 | ||||||
|               ++ (showTransactionsWithBalances' ts t b') |                 this = if sameentry t tprev | ||||||
|                   where  |                        then [showTransactionWithoutDescription t b'] | ||||||
|                     b' = b + (amount t) |                        else [showTransactionWithDescription t b'] | ||||||
|                     sameentry (Transaction e1 _ _ _ _) (Transaction e2 _ _ _ _) = e1 == e2 |                 rest = showTransactionsWithBalances' ts t b' | ||||||
| 
 | 
 | ||||||
| showTransactionDescriptionAndBalance :: Transaction -> Amount -> String | showTransactionWithDescription :: Transaction -> Amount -> String | ||||||
| showTransactionDescriptionAndBalance t b = | showTransactionWithDescription t b = | ||||||
|     (showEntryDescription $ Entry (date t) False "" (description t) "" [] "")  |     (showEntryDescription $ Entry (date t) False "" (description t) "" [] "")  | ||||||
|     ++ (showLedgerTransaction $ RawTransaction (account t) (amount t) "") ++ (showBalance b) |     ++ (showTransactionFormatted t) | ||||||
|  |     ++ (showBalance b) | ||||||
| 
 | 
 | ||||||
| showTransactionAndBalance :: Transaction -> Amount -> String | showTransactionWithoutDescription :: Transaction -> Amount -> String | ||||||
| showTransactionAndBalance t b = | showTransactionWithoutDescription t b =  | ||||||
|     (replicate 32 ' ') ++ (showLedgerTransaction $ RawTransaction (account t) (amount t) "") ++ (showBalance b) |     (replicate 32 ' ')  | ||||||
|  |     ++ (showTransactionFormatted t)  | ||||||
|  |     ++ (showBalance b) | ||||||
|  | 
 | ||||||
|  | showTransactionFormatted :: Transaction -> String | ||||||
|  | showTransactionFormatted (Transaction eno d desc a amt ttype) =  | ||||||
|  |     showRawTransaction $ RawTransaction a amt "" ttype | ||||||
| 
 | 
 | ||||||
| showBalance :: Amount -> String | showBalance :: Amount -> String | ||||||
| showBalance b = printf " %12s" (showAmountOrZero b) | showBalance b = printf " %12s" (showAmountOrZero b) | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								Tests.hs
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								Tests.hs
									
									
									
									
									
								
							| @ -230,7 +230,7 @@ assertparseequal expected parsed = either printParseError (assertequal expected) | |||||||
| 
 | 
 | ||||||
| rawtransaction1_str  = "  expenses:food:dining  $10.00\n" | rawtransaction1_str  = "  expenses:food:dining  $10.00\n" | ||||||
| 
 | 
 | ||||||
| rawtransaction1 = RawTransaction "expenses:food:dining" (dollars 10) "" | rawtransaction1 = RawTransaction "expenses:food:dining" (dollars 10) "" RegularTransaction | ||||||
| 
 | 
 | ||||||
| entry1_str = "\ | entry1_str = "\ | ||||||
| \2007/01/28 coopportunity\n\ | \2007/01/28 coopportunity\n\ | ||||||
| @ -240,8 +240,8 @@ entry1_str = "\ | |||||||
| 
 | 
 | ||||||
| entry1 = | entry1 = | ||||||
|     (Entry "2007/01/28" False "" "coopportunity" "" |     (Entry "2007/01/28" False "" "coopportunity" "" | ||||||
|      [RawTransaction "expenses:food:groceries" (dollars 47.18) "",  |      [RawTransaction "expenses:food:groceries" (dollars 47.18) "" RegularTransaction,  | ||||||
|       RawTransaction "assets:checking" (dollars (-47.18)) ""] "") |       RawTransaction "assets:checking" (dollars (-47.18)) "" RegularTransaction] "") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| entry2_str = "\ | entry2_str = "\ | ||||||
| @ -386,12 +386,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:cash",  |                 taccount="assets:cash",  | ||||||
|                 tamount=dollars 4.82, |                 tamount=dollars 4.82, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="equity:opening balances",  |                 taccount="equity:opening balances",  | ||||||
|                 tamount=dollars (-4.82), |                 tamount=dollars (-4.82), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
| @ -407,12 +409,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="expenses:vacation",  |                 taccount="expenses:vacation",  | ||||||
|                 tamount=dollars 179.92, |                 tamount=dollars 179.92, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:checking",  |                 taccount="assets:checking",  | ||||||
|                 tamount=dollars (-179.92), |                 tamount=dollars (-179.92), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
| @ -428,12 +432,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:saving",  |                 taccount="assets:saving",  | ||||||
|                 tamount=dollars 200, |                 tamount=dollars 200, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:checking",  |                 taccount="assets:checking",  | ||||||
|                 tamount=dollars (-200), |                 tamount=dollars (-200), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
| @ -449,12 +455,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="expenses:food:dining",  |                 taccount="expenses:food:dining",  | ||||||
|                 tamount=dollars 4.82, |                 tamount=dollars 4.82, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:cash",  |                 taccount="assets:cash",  | ||||||
|                 tamount=dollars (-4.82), |                 tamount=dollars (-4.82), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
| @ -470,12 +478,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="expenses:phone",  |                 taccount="expenses:phone",  | ||||||
|                 tamount=dollars 95.11, |                 tamount=dollars 95.11, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:checking",  |                 taccount="assets:checking",  | ||||||
|                 tamount=dollars (-95.11), |                 tamount=dollars (-95.11), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
| @ -491,12 +501,14 @@ rawledger7 = RawLedger | |||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="liabilities:credit cards:discover",  |                 taccount="liabilities:credit cards:discover",  | ||||||
|                 tamount=dollars 80, |                 tamount=dollars 80, | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               }, |               }, | ||||||
|               RawTransaction { |               RawTransaction { | ||||||
|                 taccount="assets:checking",  |                 taccount="assets:checking",  | ||||||
|                 tamount=dollars (-80), |                 tamount=dollars (-80), | ||||||
|                 tcomment="" |                 tcomment="", | ||||||
|  |                 rttype=RegularTransaction | ||||||
|               } |               } | ||||||
|              ], |              ], | ||||||
|              epreceding_comment_lines="" |              epreceding_comment_lines="" | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user