journal: allow account types to be set with a type: tag
This commit is contained in:
		
							parent
							
								
									573a13fc27
								
							
						
					
					
						commit
						a61216ac3c
					
				| @ -446,7 +446,7 @@ data AccountDeclarationInfo = AccountDeclarationInfo { | ||||
|   ,aditags             :: [Tag]  -- ^ tags extracted from the account comment, if any | ||||
|   ,adideclarationorder :: Int    -- ^ the order in which this account was declared, | ||||
|                                  --   relative to other account declarations, during parsing (1..) | ||||
| } deriving (Eq,Data,Generic) | ||||
| } deriving (Eq,Show,Data,Generic) | ||||
| 
 | ||||
| instance NFData AccountDeclarationInfo | ||||
| 
 | ||||
|  | ||||
| @ -68,7 +68,6 @@ import qualified Control.Exception as C | ||||
| import Control.Monad | ||||
| import Control.Monad.Except (ExceptT(..), runExceptT) | ||||
| import Control.Monad.State.Strict | ||||
| import Data.Maybe | ||||
| import qualified Data.Map.Strict as M | ||||
| import Data.Text (Text) | ||||
| import Data.String | ||||
| @ -257,31 +256,62 @@ orRethrowIOError io msg = do | ||||
| -- list of account declarations. | ||||
| accountdirectivep :: JournalParser m () | ||||
| accountdirectivep = do | ||||
|   off <- getOffset -- XXX figure out a more precise position later | ||||
| 
 | ||||
|   string "account" | ||||
|   lift (skipSome spacenonewline) | ||||
| 
 | ||||
|   -- the account name, possibly modified by preceding alias or apply account directives | ||||
|   acct <- modifiedaccountnamep | ||||
|   -- maybe an account type code after two or more spaces | ||||
|   matype :: Maybe AccountType <- lift $ fmap (fromMaybe Nothing) $ optional $ try $ do | ||||
| 
 | ||||
|   -- maybe an account type code (ALERX) after two or more spaces | ||||
|   -- XXX added in 1.11, deprecated in 1.13, remove in 1.14 | ||||
|   mtypecode :: Maybe Char <- lift $ optional $ try $ do | ||||
|     skipSome spacenonewline -- at least one more space in addition to the one consumed by modifiedaccountp  | ||||
|     choice [ | ||||
|       -- a letter account type code (ALERX), as added in 1.11 ? | ||||
|        char 'A' >> return (Just Asset)  | ||||
|       ,char 'L' >> return (Just Liability)  | ||||
|       ,char 'E' >> return (Just Equity)  | ||||
|       ,char 'R' >> return (Just Revenue)  | ||||
|       ,char 'X' >> return (Just Expense)  | ||||
|       ] | ||||
|     choice $ map char "ALERX" | ||||
| 
 | ||||
|   -- maybe a comment, on this and/or following lines | ||||
|   (cmt, tags) <- lift transactioncommentp | ||||
|    | ||||
|   -- maybe Ledger-style subdirectives (ignored) | ||||
|   skipMany indentedlinep | ||||
| 
 | ||||
|   -- an account type may have been set by account type code or a tag; | ||||
|   -- the latter takes precedence | ||||
|   let | ||||
|     mtypecode' :: Maybe Text = maybe | ||||
|       (T.singleton <$> mtypecode) | ||||
|       Just | ||||
|       $ lookup accountTypeTagName tags | ||||
|     metype = parseAccountTypeCode <$> mtypecode' | ||||
| 
 | ||||
|   -- update the journal | ||||
|   addAccountDeclaration (acct, cmt, tags) | ||||
|   case matype of | ||||
|     Nothing    -> return () | ||||
|     Just atype -> addDeclaredAccountType acct atype | ||||
|   case metype of | ||||
|     Nothing         -> return () | ||||
|     Just (Right t)  -> addDeclaredAccountType acct t | ||||
|     Just (Left err) -> customFailure $ parseErrorAt off err | ||||
| 
 | ||||
| -- The special tag used for declaring account type. XXX change to "class" ? | ||||
| accountTypeTagName = "type" | ||||
| 
 | ||||
| parseAccountTypeCode :: Text -> Either String AccountType | ||||
| parseAccountTypeCode s = | ||||
|   case T.toLower s of | ||||
|     "asset"     -> Right Asset | ||||
|     "a"         -> Right Asset | ||||
|     "liability" -> Right Liability | ||||
|     "l"         -> Right Liability | ||||
|     "equity"    -> Right Equity | ||||
|     "e"         -> Right Equity | ||||
|     "revenue"   -> Right Revenue | ||||
|     "r"         -> Right Revenue | ||||
|     "expense"   -> Right Expense | ||||
|     "x"         -> Right Expense | ||||
|     _           -> Left err | ||||
|   where | ||||
|     err = "invalid account type code "++T.unpack s++", should be one of " ++ | ||||
|           (intercalate ", " $ ["A","L","E","R","X","ASSET","LIABILITY","EQUITY","REVENUE","EXPENSE"]) | ||||
| 
 | ||||
| -- Add an account declaration to the journal, auto-numbering it. | ||||
| addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m () | ||||
| @ -855,10 +885,16 @@ tests_JournalReader = tests "JournalReader" [ | ||||
|     ] | ||||
| 
 | ||||
|   ,test "accountdirectivep" $ do | ||||
|     test "with-comment" $ expectParse accountdirectivep "account a:b  ; a comment\n" | ||||
|     test "with-comment"       $ expectParse accountdirectivep "account a:b  ; a comment\n" | ||||
|     test "does-not-support-!" $ expectParseError accountdirectivep "!account a:b\n" "" | ||||
|     test "account-type-code" $ expectParse accountdirectivep "account a:b  A\n" | ||||
|     test "account-type-tag" $ expectParse accountdirectivep "account a:b  ; type:asset\n" | ||||
|     test "account-type-code"  $ expectParse accountdirectivep "account a:b  A\n" | ||||
|     test "account-type-tag"   $ expectParseStateOn accountdirectivep "account a:b  ; type:asset\n" | ||||
|       jdeclaredaccounts | ||||
|       [("a:b", AccountDeclarationInfo{adicomment          = "type:asset\n" | ||||
|                                      ,aditags             = [("type","asset")] | ||||
|                                      ,adideclarationorder = 1 | ||||
|                                      }) | ||||
|       ] | ||||
| 
 | ||||
|   ,test "commodityconversiondirectivep" $ do | ||||
|      expectParse commodityconversiondirectivep "C 1h = $50.00\n" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user