{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
-- | Parser for downloaded OFX files.
--
-- This parser was written based on the OFX version 1.03
-- specification, which is available at
--
-- <http://www.ofx.net>
--
-- It will probably work on earlier versions of OFX without
-- incident. However, it may or may not not work on newer versions of
-- OFX, which are XML based (this version of OFX is SGML based.)
--
-- It will also parse QFX files, which are OFX files with minor
-- proprietary additions by Intuit, the maker of Quicken.
--
-- An OFX file consists of three parts: the HTTP headers (which this
-- parser does NOT handle because typically they will not show up in
-- files downloaded to disk), the OFX headers, and the OFX data. This
-- parser handles the OFX headers and the OFX data.
--
-- The parser in this module simply parses the tags and data into a
-- tree, which you can manipulate with other functions. Some functions
-- are provided to find the transactions in the tree and place them
-- into a 'Transaction' type, which is the data you are most likely
-- interested in. If you are interested in other data you can query
-- the 'Tag' tree for what you need.
--
-- The @ofx@ package includes two executable files that you can use at
-- the command line to test the library and see how it works.  The
-- @renderTransactions@ executable reads an OFX file on standard
-- input, runs it through the 'prettyRenderTransactions' function, and
-- prints the result to standard output.  The @renderOfx@ executable
-- reads an OFX file on standard input, runs it through the
-- 'prettyRenderOfxFile' function, and prints the result to standard
-- output.

module Data.OFX
  ( -- * Error handling
    Err
  
    -- * The OFX data tree
  , HeaderTag
  , HeaderValue
  , OFXHeader(..)
  , TagName
  , TagData
  , Tag(..)
  , OFXFile(..)

  -- * Manipulating the OFX tag tree
  , find
  , findPath
  , tagData
  , pathData
  , findData

  -- * Extracting specific data
  , fiName
  , creditCardNumber
  , bankAccountNumber
  , accountNumber

  -- * Types to represent specific OFX data
  , Transaction(..)
  , transaction
  , transactions
  , TrnType(..)
  , trnType
  , Payee(..)
  , payee
  , CorrectAction(..)
  , BankAcctTo(..)
  , bankAcctTo
  , CCAcctTo(..)
  , ccAcctTo
  , AcctType(..)
  , acctType
  , CurrencyData(..)
  , currencyData
  , Currency(..)
  , currency
  , OrigCurrency(..)
  , origCurrency

  -- * Running parsers
  , parseOfxFile
  , loadOfxFile
  , parseTransactions
  , loadTransactions
  , prettyRenderOfxFile
  , prettyRenderTransactions

  -- * Parsec parsers
  , ofxFile
  , newline
  , escChar
  , header
  , openingTag
  , closingTag
  , tag
  , date
  , time
  , tzOffset

  -- * Pretty printers
  , pPayee
  , pTransaction
  , pTag
  , pHeader
  , pFile
  , pEither
  , pMaybe
  , pList
  , label
  , pExceptional
  ) where

--
-- # Imports
--

import Control.Applicative (many, optional, (<|>))
import Control.Monad (replicateM, (<=<))
import Data.Data (Data)
import Data.Maybe (listToMaybe)
import Data.Monoid ((<>))
import qualified Data.Monoid as M
import qualified Data.Time as T
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Text.Parsec.String (Parser)
import Text.Parsec
  ( lookAhead, char, manyTill, anyChar, (<?>), eof,
    try, digit, many1, spaces, string, choice, parse )
import qualified Text.Parsec as P
import Text.PrettyPrint
  ( Doc, hang, text, sep, vcat, nest, (<+>), ($$),
    parens, brackets, render )


--
-- # Error handling
--

-- | Error handling. Errors are indicated with a Left String;
-- successes with a Right.
type Err = Either String

--
-- # Data types
--

-- | Headers consists of simple @tag:value@ pairs; this represents the
-- tag.
type HeaderTag = String

-- | The value in an OFX header.
type HeaderValue = String

-- | An OFX file starts with a number of headers, which take the form
-- @tag:value@ followed by a newline. These are followed by a blank
-- line.
data OFXHeader = OFXHeader HeaderTag HeaderValue
  deriving (OFXHeader -> OFXHeader -> Bool
(OFXHeader -> OFXHeader -> Bool)
-> (OFXHeader -> OFXHeader -> Bool) -> Eq OFXHeader
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OFXHeader -> OFXHeader -> Bool
$c/= :: OFXHeader -> OFXHeader -> Bool
== :: OFXHeader -> OFXHeader -> Bool
$c== :: OFXHeader -> OFXHeader -> Bool
Eq, Int -> OFXHeader -> ShowS
[OFXHeader] -> ShowS
OFXHeader -> String
(Int -> OFXHeader -> ShowS)
-> (OFXHeader -> String)
-> ([OFXHeader] -> ShowS)
-> Show OFXHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OFXHeader] -> ShowS
$cshowList :: [OFXHeader] -> ShowS
show :: OFXHeader -> String
$cshow :: OFXHeader -> String
showsPrec :: Int -> OFXHeader -> ShowS
$cshowsPrec :: Int -> OFXHeader -> ShowS
Show, ReadPrec [OFXHeader]
ReadPrec OFXHeader
Int -> ReadS OFXHeader
ReadS [OFXHeader]
(Int -> ReadS OFXHeader)
-> ReadS [OFXHeader]
-> ReadPrec OFXHeader
-> ReadPrec [OFXHeader]
-> Read OFXHeader
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [OFXHeader]
$creadListPrec :: ReadPrec [OFXHeader]
readPrec :: ReadPrec OFXHeader
$creadPrec :: ReadPrec OFXHeader
readList :: ReadS [OFXHeader]
$creadList :: ReadS [OFXHeader]
readsPrec :: Int -> ReadS OFXHeader
$creadsPrec :: Int -> ReadS OFXHeader
Read, Typeable OFXHeader
Constr
DataType
Typeable OFXHeader =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> OFXHeader -> c OFXHeader)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OFXHeader)
-> (OFXHeader -> Constr)
-> (OFXHeader -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OFXHeader))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXHeader))
-> ((forall b. Data b => b -> b) -> OFXHeader -> OFXHeader)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> OFXHeader -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> OFXHeader -> r)
-> (forall u. (forall d. Data d => d -> u) -> OFXHeader -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> OFXHeader -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader)
-> Data OFXHeader
OFXHeader -> Constr
OFXHeader -> DataType
(forall b. Data b => b -> b) -> OFXHeader -> OFXHeader
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXHeader -> c OFXHeader
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXHeader
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> OFXHeader -> u
forall u. (forall d. Data d => d -> u) -> OFXHeader -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXHeader
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXHeader -> c OFXHeader
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OFXHeader)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXHeader)
$cOFXHeader :: Constr
$tOFXHeader :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
gmapMp :: (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
gmapM :: (forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OFXHeader -> m OFXHeader
gmapQi :: Int -> (forall d. Data d => d -> u) -> OFXHeader -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OFXHeader -> u
gmapQ :: (forall d. Data d => d -> u) -> OFXHeader -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> OFXHeader -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXHeader -> r
gmapT :: (forall b. Data b => b -> b) -> OFXHeader -> OFXHeader
$cgmapT :: (forall b. Data b => b -> b) -> OFXHeader -> OFXHeader
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXHeader)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXHeader)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c OFXHeader)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OFXHeader)
dataTypeOf :: OFXHeader -> DataType
$cdataTypeOf :: OFXHeader -> DataType
toConstr :: OFXHeader -> Constr
$ctoConstr :: OFXHeader -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXHeader
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXHeader
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXHeader -> c OFXHeader
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXHeader -> c OFXHeader
$cp1Data :: Typeable OFXHeader
Data, (forall x. OFXHeader -> Rep OFXHeader x)
-> (forall x. Rep OFXHeader x -> OFXHeader) -> Generic OFXHeader
forall x. Rep OFXHeader x -> OFXHeader
forall x. OFXHeader -> Rep OFXHeader x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OFXHeader x -> OFXHeader
$cfrom :: forall x. OFXHeader -> Rep OFXHeader x
Generic, Typeable)

-- | The name of an OFX tag
type TagName = String

-- | The data accompanying an OFX tag.
type TagData = String

-- | The main OFX data consists of a series of tags. OFX 1.03 is SGML,
-- not XML. This means that opening tags need not have closing
-- tags. In OFX, a tag either has data and no child elements, or it
-- has no data and it has child elements.
data Tag = Tag TagName (Either TagData [Tag])
  deriving (Tag -> Tag -> Bool
(Tag -> Tag -> Bool) -> (Tag -> Tag -> Bool) -> Eq Tag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tag -> Tag -> Bool
$c/= :: Tag -> Tag -> Bool
== :: Tag -> Tag -> Bool
$c== :: Tag -> Tag -> Bool
Eq, Int -> Tag -> ShowS
[Tag] -> ShowS
Tag -> String
(Int -> Tag -> ShowS)
-> (Tag -> String) -> ([Tag] -> ShowS) -> Show Tag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Tag] -> ShowS
$cshowList :: [Tag] -> ShowS
show :: Tag -> String
$cshow :: Tag -> String
showsPrec :: Int -> Tag -> ShowS
$cshowsPrec :: Int -> Tag -> ShowS
Show, ReadPrec [Tag]
ReadPrec Tag
Int -> ReadS Tag
ReadS [Tag]
(Int -> ReadS Tag)
-> ReadS [Tag] -> ReadPrec Tag -> ReadPrec [Tag] -> Read Tag
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Tag]
$creadListPrec :: ReadPrec [Tag]
readPrec :: ReadPrec Tag
$creadPrec :: ReadPrec Tag
readList :: ReadS [Tag]
$creadList :: ReadS [Tag]
readsPrec :: Int -> ReadS Tag
$creadsPrec :: Int -> ReadS Tag
Read, Typeable Tag
Constr
DataType
Typeable Tag =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Tag -> c Tag)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Tag)
-> (Tag -> Constr)
-> (Tag -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Tag))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Tag))
-> ((forall b. Data b => b -> b) -> Tag -> Tag)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r)
-> (forall u. (forall d. Data d => d -> u) -> Tag -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Tag -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Tag -> m Tag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Tag -> m Tag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Tag -> m Tag)
-> Data Tag
Tag -> Constr
Tag -> DataType
(forall b. Data b => b -> b) -> Tag -> Tag
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tag -> c Tag
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Tag
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Tag -> u
forall u. (forall d. Data d => d -> u) -> Tag -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Tag -> m Tag
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tag -> m Tag
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Tag
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tag -> c Tag
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Tag)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Tag)
$cTag :: Constr
$tTag :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Tag -> m Tag
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tag -> m Tag
gmapMp :: (forall d. Data d => d -> m d) -> Tag -> m Tag
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tag -> m Tag
gmapM :: (forall d. Data d => d -> m d) -> Tag -> m Tag
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Tag -> m Tag
gmapQi :: Int -> (forall d. Data d => d -> u) -> Tag -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Tag -> u
gmapQ :: (forall d. Data d => d -> u) -> Tag -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Tag -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Tag -> r
gmapT :: (forall b. Data b => b -> b) -> Tag -> Tag
$cgmapT :: (forall b. Data b => b -> b) -> Tag -> Tag
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Tag)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Tag)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Tag)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Tag)
dataTypeOf :: Tag -> DataType
$cdataTypeOf :: Tag -> DataType
toConstr :: Tag -> Constr
$ctoConstr :: Tag -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Tag
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Tag
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tag -> c Tag
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tag -> c Tag
$cp1Data :: Typeable Tag
Data, (forall x. Tag -> Rep Tag x)
-> (forall x. Rep Tag x -> Tag) -> Generic Tag
forall x. Rep Tag x -> Tag
forall x. Tag -> Rep Tag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Tag x -> Tag
$cfrom :: forall x. Tag -> Rep Tag x
Generic, Typeable)

-- | All the data from an OFX file.
data OFXFile = OFXFile
  { OFXFile -> [OFXHeader]
fHeader :: [OFXHeader]

  , OFXFile -> Tag
fTag :: Tag
  -- ^ All the data will be contained in a root tag with the TagName
  -- @OFX@.

  } deriving (OFXFile -> OFXFile -> Bool
(OFXFile -> OFXFile -> Bool)
-> (OFXFile -> OFXFile -> Bool) -> Eq OFXFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OFXFile -> OFXFile -> Bool
$c/= :: OFXFile -> OFXFile -> Bool
== :: OFXFile -> OFXFile -> Bool
$c== :: OFXFile -> OFXFile -> Bool
Eq, Int -> OFXFile -> ShowS
[OFXFile] -> ShowS
OFXFile -> String
(Int -> OFXFile -> ShowS)
-> (OFXFile -> String) -> ([OFXFile] -> ShowS) -> Show OFXFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OFXFile] -> ShowS
$cshowList :: [OFXFile] -> ShowS
show :: OFXFile -> String
$cshow :: OFXFile -> String
showsPrec :: Int -> OFXFile -> ShowS
$cshowsPrec :: Int -> OFXFile -> ShowS
Show, ReadPrec [OFXFile]
ReadPrec OFXFile
Int -> ReadS OFXFile
ReadS [OFXFile]
(Int -> ReadS OFXFile)
-> ReadS [OFXFile]
-> ReadPrec OFXFile
-> ReadPrec [OFXFile]
-> Read OFXFile
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [OFXFile]
$creadListPrec :: ReadPrec [OFXFile]
readPrec :: ReadPrec OFXFile
$creadPrec :: ReadPrec OFXFile
readList :: ReadS [OFXFile]
$creadList :: ReadS [OFXFile]
readsPrec :: Int -> ReadS OFXFile
$creadsPrec :: Int -> ReadS OFXFile
Read, Typeable OFXFile
Constr
DataType
Typeable OFXFile =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> OFXFile -> c OFXFile)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OFXFile)
-> (OFXFile -> Constr)
-> (OFXFile -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OFXFile))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXFile))
-> ((forall b. Data b => b -> b) -> OFXFile -> OFXFile)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> OFXFile -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> OFXFile -> r)
-> (forall u. (forall d. Data d => d -> u) -> OFXFile -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> OFXFile -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile)
-> Data OFXFile
OFXFile -> Constr
OFXFile -> DataType
(forall b. Data b => b -> b) -> OFXFile -> OFXFile
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXFile -> c OFXFile
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXFile
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> OFXFile -> u
forall u. (forall d. Data d => d -> u) -> OFXFile -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXFile
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXFile -> c OFXFile
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OFXFile)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXFile)
$cOFXFile :: Constr
$tOFXFile :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
gmapMp :: (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
gmapM :: (forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OFXFile -> m OFXFile
gmapQi :: Int -> (forall d. Data d => d -> u) -> OFXFile -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OFXFile -> u
gmapQ :: (forall d. Data d => d -> u) -> OFXFile -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> OFXFile -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OFXFile -> r
gmapT :: (forall b. Data b => b -> b) -> OFXFile -> OFXFile
$cgmapT :: (forall b. Data b => b -> b) -> OFXFile -> OFXFile
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXFile)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OFXFile)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c OFXFile)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OFXFile)
dataTypeOf :: OFXFile -> DataType
$cdataTypeOf :: OFXFile -> DataType
toConstr :: OFXFile -> Constr
$ctoConstr :: OFXFile -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXFile
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OFXFile
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXFile -> c OFXFile
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OFXFile -> c OFXFile
$cp1Data :: Typeable OFXFile
Data, (forall x. OFXFile -> Rep OFXFile x)
-> (forall x. Rep OFXFile x -> OFXFile) -> Generic OFXFile
forall x. Rep OFXFile x -> OFXFile
forall x. OFXFile -> Rep OFXFile x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OFXFile x -> OFXFile
$cfrom :: forall x. OFXFile -> Rep OFXFile x
Generic, Typeable)

--
-- # Parsers
--

-- | Parses either a UNIX or an MS-DOS newline. According to 1.2.2,
-- OFX does not contain any white space between tags. However, since I
-- have seen OFX files that do have whitespace between tags, the
-- parser makes allowance for this.
newline :: Parser ()
newline :: Parser ()
newline = () () -> ParsecT String () Identity Char -> Parser ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\n' Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> () () -> ParsecT String () Identity Char -> Parser ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\r' ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\n')
          Parser () -> String -> Parser ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "newline"

-- | Parses a character, possibly with an escape sequence. The
-- greater-than sign, less-than sign, and ampersand must be entered
-- with escape sequences.
--
-- According to OFX spec section 2.3.2.1, ampersands, less-than signs,
-- and greater-than signs must appear as entities.  However some banks
-- deliver broken OFX files that do not use entities for ampersands
-- (and possibly for less-than or greater-than signs too, although I
-- have not yet observed such behavior.) There is now an error message
-- that reflects this problem.  Client code can filter the OFX data
-- for known offenders before passing it to this library.
escChar :: Parser Char
escChar :: ParsecT String () Identity Char
escChar =
  do
    Char
c <- ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
    case Char
c of
      '&' -> do
        let mkParser :: (a, String) -> ParsecT s u m a
mkParser (ch :: a
ch, str :: String
str) = ParsecT s u m a -> ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (a
ch a -> ParsecT s u m String -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
str)
        Char
ent <- [ParsecT String () Identity Char]
-> ParsecT String () Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice (((Char, String) -> ParsecT String () Identity Char)
-> [(Char, String)] -> [ParsecT String () Identity Char]
forall a b. (a -> b) -> [a] -> [b]
map (Char, String) -> ParsecT String () Identity Char
forall s (m :: * -> *) a u.
Stream s m Char =>
(a, String) -> ParsecT s u m a
mkParser
                [('<', "lt"), ('>', "gt"), ('&', "amp")])
                ParsecT String () Identity Char
-> String -> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> ( "entity (\"lt\", \"gt\", or \"amp\")\n"
                      String -> ShowS
forall a. [a] -> [a] -> [a]
++ "some banks create broken OFX files. Try\n"
                      String -> ShowS
forall a. [a] -> [a] -> [a]
++ "removing the ampersands from the file and\n"
                      String -> ShowS
forall a. [a] -> [a] -> [a]
++ "trying again.")
        Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ';'
        Char -> ParsecT String () Identity Char
forall (m :: * -> *) a. Monad m => a -> m a
return Char
ent
      _ -> Char -> ParsecT String () Identity Char
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c
  ParsecT String () Identity Char
-> String -> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "character"

header :: Parser OFXHeader
header :: Parser OFXHeader
header
  = String -> String -> OFXHeader
OFXHeader
  (String -> String -> OFXHeader)
-> ParsecT String () Identity String
-> ParsecT String () Identity (String -> OFXHeader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ':')
  ParsecT String () Identity (String -> OFXHeader)
-> ParsecT String () Identity (Maybe String)
-> ParsecT String () Identity (String -> OFXHeader)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*  ParsecT String () Identity String
-> ParsecT String () Identity (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ' '))
  ParsecT String () Identity (String -> OFXHeader)
-> ParsecT String () Identity String -> Parser OFXHeader
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Char
-> Parser () -> ParsecT String () Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar Parser ()
newline
  Parser OFXHeader -> String -> Parser OFXHeader
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "OFX header"
  
-- | Parses any opening tag. Returns the name of the tag.
openingTag :: Parser TagName
openingTag :: ParsecT String () Identity String
openingTag =
  do
    Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '<'
    String
cs <- ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
escChar (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '>')
    case String
cs of
      [] -> String -> ParsecT String () Identity String
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "opening tag with empty name"
      x :: Char
x:_ ->
        if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '/'
        then String -> ParsecT String () Identity String
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "this is a closing tag"
        else String -> ParsecT String () Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
cs
  ParsecT String () Identity String
-> String -> ParsecT String () Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "opening tag"

-- | Parses a closing tag with the given name.
closingTag :: TagName -> Parser ()
closingTag :: String -> Parser ()
closingTag n :: String
n =
  do
    Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '<'
    Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '/'
    String
cs <- ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
escChar (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '>')
    if String
cs String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
n
      then () -> Parser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      else String -> Parser ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ()) -> String -> Parser ()
forall a b. (a -> b) -> a -> b
$ "expecting closing tag named " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
n
                  String -> ShowS
forall a. [a] -> [a] -> [a]
++ "; saw closing tag named " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cs
  Parser () -> String -> Parser ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "closing tag named " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
n

-- | Parses any tag. The tag itself must be followed by at least one
-- character: either the next tag if this is an aggregate tag, or the
-- data if this is a data tag. OFX does not allow empty tags.
--
-- The OFX spec seems to say that OFX files do not include trailing
-- newlines after tags or data, but I have seen these newlines in QFX
-- files, so this parses optional trailing newlines and spaces.
tag :: Parser Tag
tag :: Parser Tag
tag =
  do
    -- try is needed because openingTag will overlap with closingTag
    String
n <- ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity String
openingTag ParsecT String () Identity String
-> Parser () -> ParsecT String () Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces)
    [Tag]
children <- Parser Tag -> ParsecT String () Identity [Tag]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser Tag
tag
    if [Tag] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Tag]
children
      then String -> Either String [Tag] -> Tag
Tag String
n (Either String [Tag] -> Tag)
-> (String -> Either String [Tag]) -> String -> Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String [Tag]
forall a b. a -> Either a b
Left
           (String -> Tag) -> ParsecT String () Identity String -> Parser Tag
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
-> Parser () -> ParsecT String () Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
escChar
                (Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser () -> Parser ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (() () -> ParsecT String () Identity Char -> Parser ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '<') Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
newline)
           Parser Tag -> Parser () -> Parser Tag
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
           Parser Tag -> ParsecT String () Identity (Maybe ()) -> Parser Tag
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser () -> ParsecT String () Identity (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser () -> Parser ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser ()
closingTag String
n))
           Parser Tag -> Parser () -> Parser Tag
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
      else String -> Either String [Tag] -> Tag
Tag String
n ([Tag] -> Either String [Tag]
forall a b. b -> Either a b
Right [Tag]
children) Tag -> Parser () -> Parser Tag
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces Parser Tag -> Parser () -> Parser Tag
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> Parser ()
closingTag String
n
                                  Parser Tag -> Parser () -> Parser Tag
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
  Parser Tag -> String -> Parser Tag
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "OFX tag"
        

-- | Parses an entire OFX file, including headers.
ofxFile :: Parser OFXFile
ofxFile :: Parser OFXFile
ofxFile
  = [OFXHeader] -> Tag -> OFXFile
OFXFile
  ([OFXHeader] -> Tag -> OFXFile)
-> ParsecT String () Identity [OFXHeader]
-> ParsecT String () Identity (Tag -> OFXFile)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser OFXHeader
-> Parser () -> ParsecT String () Identity [OFXHeader]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill Parser OFXHeader
header Parser ()
newline
  ParsecT String () Identity (Tag -> OFXFile)
-> Parser Tag -> Parser OFXFile
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Tag
tag
  Parser OFXFile -> Parser () -> Parser OFXFile
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
  Parser OFXFile -> Parser () -> Parser OFXFile
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
  Parser OFXFile -> String -> Parser OFXFile
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "OFX file"

-- | Parses an OFX date; provides an error message if the parse fails.
parseDate :: String -> Err T.ZonedTime
parseDate :: String -> Err ZonedTime
parseDate s :: String
s = case Parsec String () ZonedTime
-> String -> String -> Either ParseError ZonedTime
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse Parsec String () ZonedTime
date "" String
s of
  Left e :: ParseError
e -> String -> Err ZonedTime
forall a b. a -> Either a b
Left (String -> Err ZonedTime) -> String -> Err ZonedTime
forall a b. (a -> b) -> a -> b
$ "could not parse date: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ ": "
            String -> ShowS
forall a. [a] -> [a] -> [a]
++ ParseError -> String
forall a. Show a => a -> String
show ParseError
e
  Right g :: ZonedTime
g -> ZonedTime -> Err ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return ZonedTime
g

-- | Parses an OFX date. Fails if the date is not valid or if there is
-- no date to be parsed.
date :: Parser T.ZonedTime
date :: Parsec String () ZonedTime
date =
  do
    Integer
ys <- (String -> Integer)
-> ParsecT String () Identity String
-> ParsecT String () Identity Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Integer
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Integer)
-> ParsecT String () Identity String
-> ParsecT String () Identity Integer
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 4 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Int
ms <- (String -> Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 2 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Int
ds <- (String -> Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 2 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Day
day <- case Integer -> Int -> Int -> Maybe Day
T.fromGregorianValid Integer
ys Int
ms Int
ds of
      Nothing -> String -> ParsecT String () Identity Day
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ParsecT String () Identity Day)
-> String -> ParsecT String () Identity Day
forall a b. (a -> b) -> a -> b
$ "invalid date: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
ys
                        String -> ShowS
forall a. [a] -> [a] -> [a]
++ "-" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
ms String -> ShowS
forall a. [a] -> [a] -> [a]
++ "-" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
ds
      Just d :: Day
d -> Day -> ParsecT String () Identity Day
forall (m :: * -> *) a. Monad m => a -> m a
return Day
d
    Maybe (TimeOfDay, TimeZone)
mayTime <- ParsecT String () Identity (TimeOfDay, TimeZone)
-> ParsecT String () Identity (Maybe (TimeOfDay, TimeZone))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT String () Identity (TimeOfDay, TimeZone)
time
    case Maybe (TimeOfDay, TimeZone)
mayTime of
      Nothing ->
        let localTime :: LocalTime
localTime = Day -> TimeOfDay -> LocalTime
T.LocalTime Day
day TimeOfDay
T.midnight
        in ZonedTime -> Parsec String () ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ZonedTime -> Parsec String () ZonedTime)
-> ZonedTime -> Parsec String () ZonedTime
forall a b. (a -> b) -> a -> b
$ LocalTime -> TimeZone -> ZonedTime
T.ZonedTime LocalTime
localTime TimeZone
T.utc
      Just (t :: TimeOfDay
t, z :: TimeZone
z) -> ZonedTime -> Parsec String () ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ZonedTime -> Parsec String () ZonedTime)
-> ZonedTime -> Parsec String () ZonedTime
forall a b. (a -> b) -> a -> b
$ LocalTime -> TimeZone -> ZonedTime
T.ZonedTime (Day -> TimeOfDay -> LocalTime
T.LocalTime Day
day TimeOfDay
t) TimeZone
z
  Parsec String () ZonedTime -> String -> Parsec String () ZonedTime
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "date"

  
-- | Parses an OFX time. Fails if the time is not valid or if there is
-- no time to parse. Fails if there is no time to parse; however, if
-- there is a time but no zone, returns the time and UTC for the zone.
time :: Parser (T.TimeOfDay, T.TimeZone)
time :: ParsecT String () Identity (TimeOfDay, TimeZone)
time =
  do
    Int
h <- (String -> Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 2 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Int
m <- (String -> Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Int)
-> ParsecT String () Identity String
-> ParsecT String () Identity Int
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 2 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Pico
s <- (String -> Pico)
-> ParsecT String () Identity String
-> ParsecT String () Identity Pico
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Pico
forall a. Read a => String -> a
read (ParsecT String () Identity String
 -> ParsecT String () Identity Pico)
-> ParsecT String () Identity String
-> ParsecT String () Identity Pico
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 2 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    (milli :: Pico
milli, tz :: TimeZone
tz) <- do
      Maybe Char
mayDot <- ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '.')
      case Maybe Char
mayDot of
        Nothing -> (Pico, TimeZone) -> ParsecT String () Identity (Pico, TimeZone)
forall (m :: * -> *) a. Monad m => a -> m a
return (0, TimeZone
T.utc)
        Just _ -> do
          Pico
mil <- (String -> Pico)
-> ParsecT String () Identity String
-> ParsecT String () Identity Pico
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ 1000) (Pico -> Pico) -> (String -> Pico) -> String -> Pico
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Pico
forall a. Read a => String -> a
read) (ParsecT String () Identity String
 -> ParsecT String () Identity Pico)
-> ParsecT String () Identity String
-> ParsecT String () Identity Pico
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM 3 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
          Maybe TimeZone
mayTz <- ParsecT String () Identity TimeZone
-> ParsecT String () Identity (Maybe TimeZone)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT String () Identity TimeZone
tzOffset
          case Maybe TimeZone
mayTz of
            Nothing -> (Pico, TimeZone) -> ParsecT String () Identity (Pico, TimeZone)
forall (m :: * -> *) a. Monad m => a -> m a
return (Pico
mil, TimeZone
T.utc)
            Just t :: TimeZone
t -> (Pico, TimeZone) -> ParsecT String () Identity (Pico, TimeZone)
forall (m :: * -> *) a. Monad m => a -> m a
return (Pico
mil, TimeZone
t)
    let sec :: Pico
sec = Pico
s Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
+ Pico
milli
    (TimeOfDay, TimeZone)
-> ParsecT String () Identity (TimeOfDay, TimeZone)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Int -> Pico -> TimeOfDay
T.TimeOfDay Int
h Int
m Pico
sec, TimeZone
tz)
  ParsecT String () Identity (TimeOfDay, TimeZone)
-> String -> ParsecT String () Identity (TimeOfDay, TimeZone)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "time"
                

-- | Parses a time zone offset. Fails if there is no time zone offset
-- to parse.
tzOffset :: Parser T.TimeZone
tzOffset :: ParsecT String () Identity TimeZone
tzOffset =
  do
    Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '['
    Int -> Int
sn <- ParsecT String () Identity (Int -> Int)
forall u. ParsecT String u Identity (Int -> Int)
parseSign
    String
whole <- ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Maybe Char
mayDot <- ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '.')
    String
frac <- case Maybe Char
mayDot of
      Nothing -> String -> ParsecT String () Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return "0"
      Just _ -> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    Maybe Char
mayColon <- ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ':')
    String
name <- case Maybe Char
mayColon of
      Nothing -> String -> ParsecT String () Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return ""
      Just _ -> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.letter
    Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ']'
    let off :: Int
off = Int -> Int
sn (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round ((String -> Double
forall a. Read a => String -> a
read (String
whole String -> ShowS
forall a. [a] -> [a] -> [a]
++ "." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
frac))
                                Double -> Double -> Double
forall a. Num a => a -> a -> a
* (60 :: Double))
    TimeZone -> ParsecT String () Identity TimeZone
forall (m :: * -> *) a. Monad m => a -> m a
return (TimeZone -> ParsecT String () Identity TimeZone)
-> TimeZone -> ParsecT String () Identity TimeZone
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> String -> TimeZone
T.TimeZone Int
off Bool
False String
name
  ParsecT String () Identity TimeZone
-> String -> ParsecT String () Identity TimeZone
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "time zone offset"
  where
    parseSign :: ParsecT String u Identity (Int -> Int)
parseSign = do
      Maybe Char
mayMinus <- ParsecT String u Identity Char
-> ParsecT String u Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '-')
      case Maybe Char
mayMinus of
        Nothing -> do
          Maybe Char
mayPlus <- ParsecT String u Identity Char
-> ParsecT String u Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '+')
          (Int -> Int) -> ParsecT String u Identity (Int -> Int)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int -> Int) -> ParsecT String u Identity (Int -> Int))
-> (Int -> Int) -> ParsecT String u Identity (Int -> Int)
forall a b. (a -> b) -> a -> b
$ case Maybe Char
mayPlus of
            Nothing -> Int -> Int
forall a. a -> a
id
            Just _ -> Int -> Int
forall a. Num a => a -> a
negate
        Just _ -> (Int -> Int) -> ParsecT String u Identity (Int -> Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Int -> Int
forall a. Num a => a -> a
negate

--
-- # Manipulating trees of tags
--

-- | Finds child tags with the given name. When a tag is found, that
-- tag is not searched for further children with the same name.
find :: TagName -> Tag -> [Tag]
find :: String -> Tag -> [Tag]
find n :: String
n t :: Tag
t@(Tag x :: String
x p :: Either String [Tag]
p)
  | String
n String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
x = [Tag
t]
  | Bool
otherwise = case Either String [Tag]
p of
      Left _ -> []
      Right ts :: [Tag]
ts -> (Tag -> [Tag]) -> [Tag] -> [Tag]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> Tag -> [Tag]
find String
n) [Tag]
ts

-- | Descends through a tree of tags to find a tag at a specific
-- location in the tree. Fails if any part of the search fails. For
-- example, to find the financial institution ORG tag, where @t@ is
-- the root @OFX@ tag:
--
-- > findPath ["SIGNONMSGSRSV1", "SONRS", "FI", "ORG"] t

findPath :: [TagName] -> Tag -> Maybe Tag
findPath :: [String] -> Tag -> Maybe Tag
findPath [] t :: Tag
t = Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
t
findPath (n :: String
n:ns :: [String]
ns) t :: Tag
t = case [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe (String -> Tag -> [Tag]
find String
n Tag
t) of
  Nothing -> Maybe Tag
forall a. Maybe a
Nothing
  Just r :: Tag
r -> [String] -> Tag -> Maybe Tag
findPath [String]
ns Tag
r

-- | Gets the data from a tag, if it is a tag with data.
tagData :: Tag -> Maybe TagData
tagData :: Tag -> Maybe String
tagData (Tag _ ei :: Either String [Tag]
ei) = (String -> Maybe String)
-> ([Tag] -> Maybe String) -> Either String [Tag] -> Maybe String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Maybe String
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe String -> [Tag] -> Maybe String
forall a b. a -> b -> a
const Maybe String
forall a. Maybe a
Nothing) Either String [Tag]
ei

-- | Goes to a certain path in the tag hierarchy and pulls the
-- requested data, if the tag is present and it is a data tag.  For
-- example, to get the name of the financial institution:
--
-- > pathData ["SIGNONMSGSRSV1", "SONRS", "FI", "ORG"] f
pathData :: [TagName] -> OFXFile -> Maybe TagData
pathData :: [String] -> OFXFile -> Maybe String
pathData p :: [String]
p (OFXFile _ t :: Tag
t) = [String] -> Tag -> Maybe Tag
findPath [String]
p Tag
t Maybe Tag -> (Tag -> Maybe String) -> Maybe String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Tag -> Maybe String
tagData


-- | Gets the name of the financial institution from the FI tag, if
-- available. The OFX spec does not require this tag to be present.
fiName :: OFXFile -> Maybe TagData
fiName :: OFXFile -> Maybe String
fiName = [String] -> OFXFile -> Maybe String
pathData ["SIGNONMSGSRSV1", "SONRS", "FI", "ORG"]


-- | Gets the credit card number, if available. The OFX spec does not
-- require this tag to be present.
creditCardNumber :: OFXFile -> Maybe TagData
creditCardNumber :: OFXFile -> Maybe String
creditCardNumber =
  [String] -> OFXFile -> Maybe String
pathData [ "CREDITCARDMSGSRSV1", "CCSTMTTRNRS", "CCSTMTRS",
             "CCACCTFROM", "ACCTID" ]

-- | Gets the bank account number, if available. The OFX spec does not
-- require this tag to be present.
bankAccountNumber :: OFXFile -> Maybe TagData
bankAccountNumber :: OFXFile -> Maybe String
bankAccountNumber =
  [String] -> OFXFile -> Maybe String
pathData [ "BANKMSGSRSV1", "STMTTRNRS", "STMTRS",
             "BANKACCTFROM", "ACCTID" ]

-- | Gets either the credit card or bank account number, if available.
accountNumber :: OFXFile -> Maybe TagData
accountNumber :: OFXFile -> Maybe String
accountNumber f :: OFXFile
f = OFXFile -> Maybe String
creditCardNumber OFXFile
f Maybe String -> Maybe String -> Maybe String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> OFXFile -> Maybe String
bankAccountNumber OFXFile
f
  

-- | Finds the first tag (either this tag or any children) that has
-- the given name and that is a data tag (not an aggregate tag.) If no
-- data tag with the given name is found, returns Nothing.
findData :: TagName -> Tag -> Maybe TagData
findData :: String -> Tag -> Maybe String
findData n :: String
n (Tag tn :: String
tn e :: Either String [Tag]
e) = case Either String [Tag]
e of
  Left d :: String
d -> if String
tn String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
n then String -> Maybe String
forall a. a -> Maybe a
Just String
d else Maybe String
forall a. Maybe a
Nothing
  Right ts :: [Tag]
ts -> First String -> Maybe String
forall a. First a -> Maybe a
M.getFirst (First String -> Maybe String)
-> ([Tag] -> First String) -> [Tag] -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [First String] -> First String
forall a. Monoid a => [a] -> a
M.mconcat ([First String] -> First String)
-> ([Tag] -> [First String]) -> [Tag] -> First String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  (Maybe String -> First String) -> [Maybe String] -> [First String]
forall a b. (a -> b) -> [a] -> [b]
map Maybe String -> First String
forall a. Maybe a -> First a
M.First
              ([Maybe String] -> [First String])
-> ([Tag] -> [Maybe String]) -> [Tag] -> [First String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag -> Maybe String) -> [Tag] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Tag -> Maybe String
findData String
n) ([Tag] -> Maybe String) -> [Tag] -> Maybe String
forall a b. (a -> b) -> a -> b
$ [Tag]
ts


-- | Finds the first tag (either this tag or any children) that has
-- the given name and that is a data tag. Gives an error message if
-- the tag is not found.
required :: TagName -> Tag -> Err TagData
required :: String -> Tag -> Err String
required n :: String
n t :: Tag
t = case String -> Tag -> Maybe String
findData String
n Tag
t of
  Nothing -> String -> Err String
forall a b. a -> Either a b
Left (String -> Err String) -> String -> Err String
forall a b. (a -> b) -> a -> b
$ "required tag missing: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
n
  Just r :: String
r -> String -> Err String
forall (m :: * -> *) a. Monad m => a -> m a
return String
r


--
-- # OFX data
-- 

-- | OFX transaction types. These are used in STMTTRN aggregates, see
-- OFX spec section 11.4.2.3.1.1.
data TrnType
  = TCREDIT
  | TDEBIT

  | TINT
  -- ^ Interest earned or paid (which it is depends on sign of amount)

  | TDIV
  -- ^ Dividend

  | TFEE
  | TSRVCHG

  | TDEP
  -- ^ Deposit

  | TATM
  -- ^ ATM debit or credit (which it is depends on sign of amount)

  | TPOS
  -- ^ Point of sale debit or credit (which it is depends on sign of
  -- amount)

  | TXFER
  -- ^ Transfer

  | TCHECK
  | TPAYMENT
  -- ^ Electronic payment

  | TCASH
  -- ^ Cash withdrawal

  | TDIRECTDEP
  -- ^ Direct deposit

  | TDIRECTDEBIT
  -- ^ Merchant initiated debit

  | TREPEATPMT
  -- ^ Repeating payment / standing order

  | TOTHER
  deriving (TrnType -> TrnType -> Bool
(TrnType -> TrnType -> Bool)
-> (TrnType -> TrnType -> Bool) -> Eq TrnType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TrnType -> TrnType -> Bool
$c/= :: TrnType -> TrnType -> Bool
== :: TrnType -> TrnType -> Bool
$c== :: TrnType -> TrnType -> Bool
Eq, Eq TrnType
Eq TrnType =>
(TrnType -> TrnType -> Ordering)
-> (TrnType -> TrnType -> Bool)
-> (TrnType -> TrnType -> Bool)
-> (TrnType -> TrnType -> Bool)
-> (TrnType -> TrnType -> Bool)
-> (TrnType -> TrnType -> TrnType)
-> (TrnType -> TrnType -> TrnType)
-> Ord TrnType
TrnType -> TrnType -> Bool
TrnType -> TrnType -> Ordering
TrnType -> TrnType -> TrnType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TrnType -> TrnType -> TrnType
$cmin :: TrnType -> TrnType -> TrnType
max :: TrnType -> TrnType -> TrnType
$cmax :: TrnType -> TrnType -> TrnType
>= :: TrnType -> TrnType -> Bool
$c>= :: TrnType -> TrnType -> Bool
> :: TrnType -> TrnType -> Bool
$c> :: TrnType -> TrnType -> Bool
<= :: TrnType -> TrnType -> Bool
$c<= :: TrnType -> TrnType -> Bool
< :: TrnType -> TrnType -> Bool
$c< :: TrnType -> TrnType -> Bool
compare :: TrnType -> TrnType -> Ordering
$ccompare :: TrnType -> TrnType -> Ordering
$cp1Ord :: Eq TrnType
Ord, Int -> TrnType -> ShowS
[TrnType] -> ShowS
TrnType -> String
(Int -> TrnType -> ShowS)
-> (TrnType -> String) -> ([TrnType] -> ShowS) -> Show TrnType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TrnType] -> ShowS
$cshowList :: [TrnType] -> ShowS
show :: TrnType -> String
$cshow :: TrnType -> String
showsPrec :: Int -> TrnType -> ShowS
$cshowsPrec :: Int -> TrnType -> ShowS
Show, ReadPrec [TrnType]
ReadPrec TrnType
Int -> ReadS TrnType
ReadS [TrnType]
(Int -> ReadS TrnType)
-> ReadS [TrnType]
-> ReadPrec TrnType
-> ReadPrec [TrnType]
-> Read TrnType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TrnType]
$creadListPrec :: ReadPrec [TrnType]
readPrec :: ReadPrec TrnType
$creadPrec :: ReadPrec TrnType
readList :: ReadS [TrnType]
$creadList :: ReadS [TrnType]
readsPrec :: Int -> ReadS TrnType
$creadsPrec :: Int -> ReadS TrnType
Read, Typeable TrnType
Constr
DataType
Typeable TrnType =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> TrnType -> c TrnType)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TrnType)
-> (TrnType -> Constr)
-> (TrnType -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TrnType))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TrnType))
-> ((forall b. Data b => b -> b) -> TrnType -> TrnType)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TrnType -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TrnType -> r)
-> (forall u. (forall d. Data d => d -> u) -> TrnType -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> TrnType -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TrnType -> m TrnType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TrnType -> m TrnType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TrnType -> m TrnType)
-> Data TrnType
TrnType -> Constr
TrnType -> DataType
(forall b. Data b => b -> b) -> TrnType -> TrnType
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TrnType -> c TrnType
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TrnType
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TrnType -> u
forall u. (forall d. Data d => d -> u) -> TrnType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TrnType -> m TrnType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TrnType -> m TrnType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TrnType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TrnType -> c TrnType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TrnType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TrnType)
$cTOTHER :: Constr
$cTREPEATPMT :: Constr
$cTDIRECTDEBIT :: Constr
$cTDIRECTDEP :: Constr
$cTCASH :: Constr
$cTPAYMENT :: Constr
$cTCHECK :: Constr
$cTXFER :: Constr
$cTPOS :: Constr
$cTATM :: Constr
$cTDEP :: Constr
$cTSRVCHG :: Constr
$cTFEE :: Constr
$cTDIV :: Constr
$cTINT :: Constr
$cTDEBIT :: Constr
$cTCREDIT :: Constr
$tTrnType :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> TrnType -> m TrnType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TrnType -> m TrnType
gmapMp :: (forall d. Data d => d -> m d) -> TrnType -> m TrnType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TrnType -> m TrnType
gmapM :: (forall d. Data d => d -> m d) -> TrnType -> m TrnType
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TrnType -> m TrnType
gmapQi :: Int -> (forall d. Data d => d -> u) -> TrnType -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TrnType -> u
gmapQ :: (forall d. Data d => d -> u) -> TrnType -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TrnType -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TrnType -> r
gmapT :: (forall b. Data b => b -> b) -> TrnType -> TrnType
$cgmapT :: (forall b. Data b => b -> b) -> TrnType -> TrnType
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TrnType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TrnType)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c TrnType)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TrnType)
dataTypeOf :: TrnType -> DataType
$cdataTypeOf :: TrnType -> DataType
toConstr :: TrnType -> Constr
$ctoConstr :: TrnType -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TrnType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TrnType
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TrnType -> c TrnType
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TrnType -> c TrnType
$cp1Data :: Typeable TrnType
Data, (forall x. TrnType -> Rep TrnType x)
-> (forall x. Rep TrnType x -> TrnType) -> Generic TrnType
forall x. Rep TrnType x -> TrnType
forall x. TrnType -> Rep TrnType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TrnType x -> TrnType
$cfrom :: forall x. TrnType -> Rep TrnType x
Generic, Typeable)

-- | A single STMTTRN, see OFX spec section 11.4.2.3.1. This is most
-- likely what you are interested in after downloading a statement
-- from a bank.
data Transaction = Transaction
  { Transaction -> TrnType
txTRNTYPE :: TrnType
    -- ^ Transaction type

  , Transaction -> ZonedTime
txDTPOSTED :: T.ZonedTime
    -- ^ Date transaction was posted to account

  , Transaction -> Maybe ZonedTime
txDTUSER :: Maybe T.ZonedTime
    -- ^ Date user initiated transaction, if known

  , Transaction -> Maybe ZonedTime
txDTAVAIL :: Maybe T.ZonedTime
    -- ^ Date funds are available

  , Transaction -> String
txTRNAMT :: String
    -- ^ Amount of transaction. This is left as the string that was
    -- originally in the download. That means the transaction may
    -- include a plus or minus sign (no sign is the same as a plus
    -- sign.) According to section 3.2.9.2, amounts are always signed
    -- from the perspective of the customer.
    --
    -- Typically negative amounts:
    --
    -- * Investment buy amount, investment sell quantity
    --
    -- * Bank statement debit amounts, checks, fees
    --
    -- * Credit card purchases
    --
    -- * Margin balance (unless the institution owes the client money)
    --
    -- Typically positive amounts:
    --
    -- * Investment sell amount, investment buy quantity
    --
    -- * Bank statement credits
    --
    -- * Credit card payments
    --
    -- * Ledger balance (unless the account is overdrawn)
    --
    -- Formats for amounts are described in 3.2.9.1. If there is no
    -- decimal point, there is an implied decimal point at the end of
    -- the value. Trailing and leading spaces \"should\" be
    -- stripped. Positive or minus is indicated with a leading sign; a
    -- plus sign is assumed if there is no sign.
    --
    -- An amount has a maximum of 32 alphanumeric characters,
    -- including digits and punctuation.
    --
    -- The radix point is indicated with either a period or a
    -- comma. Amounts \"should\" not include any digit grouping
    -- characters.

    , Transaction -> String
txFITID :: String
    -- ^ Transaction ID issued by financial institution. Used to
    -- detect duplicate downloads.

    , Transaction -> Maybe String
txCORRECTFITID :: Maybe String
    -- ^ If present, this indicates the FITID of a previously sent
    -- transaction that is corrected by this record. This transaction
    -- replaces or deletes the transaction that it corrects, based on
    -- the value of CORRECTACTION below.

    , Transaction -> Maybe CorrectAction
txCORRECTACTION :: Maybe CorrectAction
    -- ^ See 'CorrectAction' and 'txCORRECTFITID'

    , Transaction -> Maybe String
txSRVRTID :: Maybe String
    -- ^ Server assigned transaction ID; used for transactions
    -- initiated by client, such as payment or funds transfer

    , Transaction -> Maybe String
txCHECKNUM :: Maybe String
    -- ^ Check or other reference number

    , Transaction -> Maybe String
txREFNUM :: Maybe String
    -- ^ Reference number that uniquely identifies the
    -- transaction. Can be used in addition to or instead of a
    -- CHECKNUM.

    , Transaction -> Maybe String
txSIC :: Maybe String
    -- ^ Standard Industrial Code

    , Transaction -> Maybe String
txPAYEEID :: Maybe String
    -- ^ Payee identifier if available

    , Transaction -> Maybe (Either String Payee)
txPayeeInfo :: Maybe (Either String Payee)
    -- ^ Information on the payee. The OFX spec seems to be saying
    -- that every transaction must have either NAME, wich is \"name of
    -- payee or description of transaction\", or the Payee
    -- aggregate. The former is indicated with a Left, the latter with
    -- a Right.

    , Transaction -> Maybe (Either BankAcctTo CCAcctTo)
txAccountTo :: Maybe (Either BankAcctTo CCAcctTo)
    -- ^ Information on a transfer. If this transaction wa sa
    -- transfer, this may contain information about the account being
    -- transferred to.

    , Transaction -> Maybe String
txMEMO :: Maybe String
    -- ^ Extra information not in NAME

    , Transaction -> Maybe (Either Currency OrigCurrency)
txCurrency :: Maybe (Either Currency OrigCurrency)
    -- ^ Currency option. OFX spec says to choose either CURRENCY or
    -- ORIGCURRENCY.
    } deriving (Int -> Transaction -> ShowS
[Transaction] -> ShowS
Transaction -> String
(Int -> Transaction -> ShowS)
-> (Transaction -> String)
-> ([Transaction] -> ShowS)
-> Show Transaction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Transaction] -> ShowS
$cshowList :: [Transaction] -> ShowS
show :: Transaction -> String
$cshow :: Transaction -> String
showsPrec :: Int -> Transaction -> ShowS
$cshowsPrec :: Int -> Transaction -> ShowS
Show, ReadPrec [Transaction]
ReadPrec Transaction
Int -> ReadS Transaction
ReadS [Transaction]
(Int -> ReadS Transaction)
-> ReadS [Transaction]
-> ReadPrec Transaction
-> ReadPrec [Transaction]
-> Read Transaction
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Transaction]
$creadListPrec :: ReadPrec [Transaction]
readPrec :: ReadPrec Transaction
$creadPrec :: ReadPrec Transaction
readList :: ReadS [Transaction]
$creadList :: ReadS [Transaction]
readsPrec :: Int -> ReadS Transaction
$creadsPrec :: Int -> ReadS Transaction
Read, Typeable Transaction
Constr
DataType
Typeable Transaction =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Transaction -> c Transaction)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Transaction)
-> (Transaction -> Constr)
-> (Transaction -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Transaction))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Transaction))
-> ((forall b. Data b => b -> b) -> Transaction -> Transaction)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Transaction -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Transaction -> r)
-> (forall u. (forall d. Data d => d -> u) -> Transaction -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Transaction -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Transaction -> m Transaction)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Transaction -> m Transaction)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Transaction -> m Transaction)
-> Data Transaction
Transaction -> Constr
Transaction -> DataType
(forall b. Data b => b -> b) -> Transaction -> Transaction
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Transaction -> c Transaction
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Transaction
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Transaction -> u
forall u. (forall d. Data d => d -> u) -> Transaction -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Transaction -> m Transaction
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Transaction -> m Transaction
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Transaction
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Transaction -> c Transaction
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Transaction)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Transaction)
$cTransaction :: Constr
$tTransaction :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Transaction -> m Transaction
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Transaction -> m Transaction
gmapMp :: (forall d. Data d => d -> m d) -> Transaction -> m Transaction
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Transaction -> m Transaction
gmapM :: (forall d. Data d => d -> m d) -> Transaction -> m Transaction
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Transaction -> m Transaction
gmapQi :: Int -> (forall d. Data d => d -> u) -> Transaction -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Transaction -> u
gmapQ :: (forall d. Data d => d -> u) -> Transaction -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Transaction -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Transaction -> r
gmapT :: (forall b. Data b => b -> b) -> Transaction -> Transaction
$cgmapT :: (forall b. Data b => b -> b) -> Transaction -> Transaction
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Transaction)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Transaction)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Transaction)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Transaction)
dataTypeOf :: Transaction -> DataType
$cdataTypeOf :: Transaction -> DataType
toConstr :: Transaction -> Constr
$ctoConstr :: Transaction -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Transaction
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Transaction
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Transaction -> c Transaction
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Transaction -> c Transaction
$cp1Data :: Typeable Transaction
Data, (forall x. Transaction -> Rep Transaction x)
-> (forall x. Rep Transaction x -> Transaction)
-> Generic Transaction
forall x. Rep Transaction x -> Transaction
forall x. Transaction -> Rep Transaction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Transaction x -> Transaction
$cfrom :: forall x. Transaction -> Rep Transaction x
Generic, Typeable)

data Payee = Payee
  { Payee -> String
peNAME :: String
  , Payee -> String
peADDR1 :: String
  , Payee -> Maybe String
peADDR2 :: Maybe String
  , Payee -> Maybe String
peADDR3 :: Maybe String
  , Payee -> String
peCITY :: String
  , Payee -> String
peSTATE :: String
  , Payee -> String
pePOSTALCODE :: String
  , Payee -> Maybe String
peCOUNTRY :: Maybe String
  , Payee -> String
pePHONE :: String
  } deriving (Payee -> Payee -> Bool
(Payee -> Payee -> Bool) -> (Payee -> Payee -> Bool) -> Eq Payee
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Payee -> Payee -> Bool
$c/= :: Payee -> Payee -> Bool
== :: Payee -> Payee -> Bool
$c== :: Payee -> Payee -> Bool
Eq, Int -> Payee -> ShowS
[Payee] -> ShowS
Payee -> String
(Int -> Payee -> ShowS)
-> (Payee -> String) -> ([Payee] -> ShowS) -> Show Payee
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Payee] -> ShowS
$cshowList :: [Payee] -> ShowS
show :: Payee -> String
$cshow :: Payee -> String
showsPrec :: Int -> Payee -> ShowS
$cshowsPrec :: Int -> Payee -> ShowS
Show, ReadPrec [Payee]
ReadPrec Payee
Int -> ReadS Payee
ReadS [Payee]
(Int -> ReadS Payee)
-> ReadS [Payee]
-> ReadPrec Payee
-> ReadPrec [Payee]
-> Read Payee
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Payee]
$creadListPrec :: ReadPrec [Payee]
readPrec :: ReadPrec Payee
$creadPrec :: ReadPrec Payee
readList :: ReadS [Payee]
$creadList :: ReadS [Payee]
readsPrec :: Int -> ReadS Payee
$creadsPrec :: Int -> ReadS Payee
Read, Typeable Payee
Constr
DataType
Typeable Payee =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Payee -> c Payee)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Payee)
-> (Payee -> Constr)
-> (Payee -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Payee))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Payee))
-> ((forall b. Data b => b -> b) -> Payee -> Payee)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r)
-> (forall u. (forall d. Data d => d -> u) -> Payee -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Payee -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Payee -> m Payee)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Payee -> m Payee)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Payee -> m Payee)
-> Data Payee
Payee -> Constr
Payee -> DataType
(forall b. Data b => b -> b) -> Payee -> Payee
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Payee -> c Payee
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Payee
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Payee -> u
forall u. (forall d. Data d => d -> u) -> Payee -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Payee -> m Payee
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Payee -> m Payee
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Payee
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Payee -> c Payee
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Payee)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Payee)
$cPayee :: Constr
$tPayee :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Payee -> m Payee
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Payee -> m Payee
gmapMp :: (forall d. Data d => d -> m d) -> Payee -> m Payee
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Payee -> m Payee
gmapM :: (forall d. Data d => d -> m d) -> Payee -> m Payee
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Payee -> m Payee
gmapQi :: Int -> (forall d. Data d => d -> u) -> Payee -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Payee -> u
gmapQ :: (forall d. Data d => d -> u) -> Payee -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Payee -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Payee -> r
gmapT :: (forall b. Data b => b -> b) -> Payee -> Payee
$cgmapT :: (forall b. Data b => b -> b) -> Payee -> Payee
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Payee)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Payee)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Payee)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Payee)
dataTypeOf :: Payee -> DataType
$cdataTypeOf :: Payee -> DataType
toConstr :: Payee -> Constr
$ctoConstr :: Payee -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Payee
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Payee
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Payee -> c Payee
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Payee -> c Payee
$cp1Data :: Typeable Payee
Data, (forall x. Payee -> Rep Payee x)
-> (forall x. Rep Payee x -> Payee) -> Generic Payee
forall x. Rep Payee x -> Payee
forall x. Payee -> Rep Payee x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Payee x -> Payee
$cfrom :: forall x. Payee -> Rep Payee x
Generic, Typeable)

-- | Can be either REPLACE or DELETE.
data CorrectAction
  = REPLACE
  -- ^ Replaces the transaction referenced by the CORRECTFITID

  | DELETE
  -- ^ Deletes the transaction referenced by the CORRECTFITID
  deriving (CorrectAction -> CorrectAction -> Bool
(CorrectAction -> CorrectAction -> Bool)
-> (CorrectAction -> CorrectAction -> Bool) -> Eq CorrectAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CorrectAction -> CorrectAction -> Bool
$c/= :: CorrectAction -> CorrectAction -> Bool
== :: CorrectAction -> CorrectAction -> Bool
$c== :: CorrectAction -> CorrectAction -> Bool
Eq, Int -> CorrectAction -> ShowS
[CorrectAction] -> ShowS
CorrectAction -> String
(Int -> CorrectAction -> ShowS)
-> (CorrectAction -> String)
-> ([CorrectAction] -> ShowS)
-> Show CorrectAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CorrectAction] -> ShowS
$cshowList :: [CorrectAction] -> ShowS
show :: CorrectAction -> String
$cshow :: CorrectAction -> String
showsPrec :: Int -> CorrectAction -> ShowS
$cshowsPrec :: Int -> CorrectAction -> ShowS
Show, ReadPrec [CorrectAction]
ReadPrec CorrectAction
Int -> ReadS CorrectAction
ReadS [CorrectAction]
(Int -> ReadS CorrectAction)
-> ReadS [CorrectAction]
-> ReadPrec CorrectAction
-> ReadPrec [CorrectAction]
-> Read CorrectAction
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CorrectAction]
$creadListPrec :: ReadPrec [CorrectAction]
readPrec :: ReadPrec CorrectAction
$creadPrec :: ReadPrec CorrectAction
readList :: ReadS [CorrectAction]
$creadList :: ReadS [CorrectAction]
readsPrec :: Int -> ReadS CorrectAction
$creadsPrec :: Int -> ReadS CorrectAction
Read, Typeable CorrectAction
Constr
DataType
Typeable CorrectAction =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CorrectAction -> c CorrectAction)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CorrectAction)
-> (CorrectAction -> Constr)
-> (CorrectAction -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CorrectAction))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c CorrectAction))
-> ((forall b. Data b => b -> b) -> CorrectAction -> CorrectAction)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CorrectAction -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CorrectAction -> r)
-> (forall u. (forall d. Data d => d -> u) -> CorrectAction -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CorrectAction -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction)
-> Data CorrectAction
CorrectAction -> Constr
CorrectAction -> DataType
(forall b. Data b => b -> b) -> CorrectAction -> CorrectAction
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CorrectAction -> c CorrectAction
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CorrectAction
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CorrectAction -> u
forall u. (forall d. Data d => d -> u) -> CorrectAction -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CorrectAction
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CorrectAction -> c CorrectAction
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CorrectAction)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CorrectAction)
$cDELETE :: Constr
$cREPLACE :: Constr
$tCorrectAction :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
gmapMp :: (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
gmapM :: (forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CorrectAction -> m CorrectAction
gmapQi :: Int -> (forall d. Data d => d -> u) -> CorrectAction -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CorrectAction -> u
gmapQ :: (forall d. Data d => d -> u) -> CorrectAction -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CorrectAction -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CorrectAction -> r
gmapT :: (forall b. Data b => b -> b) -> CorrectAction -> CorrectAction
$cgmapT :: (forall b. Data b => b -> b) -> CorrectAction -> CorrectAction
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CorrectAction)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CorrectAction)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c CorrectAction)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CorrectAction)
dataTypeOf :: CorrectAction -> DataType
$cdataTypeOf :: CorrectAction -> DataType
toConstr :: CorrectAction -> Constr
$ctoConstr :: CorrectAction -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CorrectAction
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CorrectAction
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CorrectAction -> c CorrectAction
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CorrectAction -> c CorrectAction
$cp1Data :: Typeable CorrectAction
Data, (forall x. CorrectAction -> Rep CorrectAction x)
-> (forall x. Rep CorrectAction x -> CorrectAction)
-> Generic CorrectAction
forall x. Rep CorrectAction x -> CorrectAction
forall x. CorrectAction -> Rep CorrectAction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CorrectAction x -> CorrectAction
$cfrom :: forall x. CorrectAction -> Rep CorrectAction x
Generic, Typeable)

data BankAcctTo = BankAcctTo
  { BankAcctTo -> String
btBANKID :: String
  -- ^ Routing and transit number

  , BankAcctTo -> Maybe String
btBRANCHID :: Maybe String
  -- ^ Bank identifier for international banks

  , BankAcctTo -> String
btACCTID :: String
  -- ^ Account number

  , BankAcctTo -> AcctType
btACCTTYPE :: AcctType
  -- ^ Type of account

  , BankAcctTo -> Maybe String
btACCTKEY :: Maybe String
  -- ^ Checksum for international banks
  } deriving (Int -> BankAcctTo -> ShowS
[BankAcctTo] -> ShowS
BankAcctTo -> String
(Int -> BankAcctTo -> ShowS)
-> (BankAcctTo -> String)
-> ([BankAcctTo] -> ShowS)
-> Show BankAcctTo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BankAcctTo] -> ShowS
$cshowList :: [BankAcctTo] -> ShowS
show :: BankAcctTo -> String
$cshow :: BankAcctTo -> String
showsPrec :: Int -> BankAcctTo -> ShowS
$cshowsPrec :: Int -> BankAcctTo -> ShowS
Show, ReadPrec [BankAcctTo]
ReadPrec BankAcctTo
Int -> ReadS BankAcctTo
ReadS [BankAcctTo]
(Int -> ReadS BankAcctTo)
-> ReadS [BankAcctTo]
-> ReadPrec BankAcctTo
-> ReadPrec [BankAcctTo]
-> Read BankAcctTo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BankAcctTo]
$creadListPrec :: ReadPrec [BankAcctTo]
readPrec :: ReadPrec BankAcctTo
$creadPrec :: ReadPrec BankAcctTo
readList :: ReadS [BankAcctTo]
$creadList :: ReadS [BankAcctTo]
readsPrec :: Int -> ReadS BankAcctTo
$creadsPrec :: Int -> ReadS BankAcctTo
Read, Typeable BankAcctTo
Constr
DataType
Typeable BankAcctTo =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> BankAcctTo -> c BankAcctTo)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c BankAcctTo)
-> (BankAcctTo -> Constr)
-> (BankAcctTo -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c BankAcctTo))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c BankAcctTo))
-> ((forall b. Data b => b -> b) -> BankAcctTo -> BankAcctTo)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r)
-> (forall u. (forall d. Data d => d -> u) -> BankAcctTo -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> BankAcctTo -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo)
-> Data BankAcctTo
BankAcctTo -> Constr
BankAcctTo -> DataType
(forall b. Data b => b -> b) -> BankAcctTo -> BankAcctTo
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BankAcctTo -> c BankAcctTo
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BankAcctTo
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> BankAcctTo -> u
forall u. (forall d. Data d => d -> u) -> BankAcctTo -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BankAcctTo
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BankAcctTo -> c BankAcctTo
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BankAcctTo)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BankAcctTo)
$cBankAcctTo :: Constr
$tBankAcctTo :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
gmapMp :: (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
gmapM :: (forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BankAcctTo -> m BankAcctTo
gmapQi :: Int -> (forall d. Data d => d -> u) -> BankAcctTo -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BankAcctTo -> u
gmapQ :: (forall d. Data d => d -> u) -> BankAcctTo -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> BankAcctTo -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BankAcctTo -> r
gmapT :: (forall b. Data b => b -> b) -> BankAcctTo -> BankAcctTo
$cgmapT :: (forall b. Data b => b -> b) -> BankAcctTo -> BankAcctTo
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BankAcctTo)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BankAcctTo)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c BankAcctTo)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BankAcctTo)
dataTypeOf :: BankAcctTo -> DataType
$cdataTypeOf :: BankAcctTo -> DataType
toConstr :: BankAcctTo -> Constr
$ctoConstr :: BankAcctTo -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BankAcctTo
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BankAcctTo
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BankAcctTo -> c BankAcctTo
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BankAcctTo -> c BankAcctTo
$cp1Data :: Typeable BankAcctTo
Data, (forall x. BankAcctTo -> Rep BankAcctTo x)
-> (forall x. Rep BankAcctTo x -> BankAcctTo) -> Generic BankAcctTo
forall x. Rep BankAcctTo x -> BankAcctTo
forall x. BankAcctTo -> Rep BankAcctTo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BankAcctTo x -> BankAcctTo
$cfrom :: forall x. BankAcctTo -> Rep BankAcctTo x
Generic, Typeable)

data CCAcctTo = CCAcctTo
  { CCAcctTo -> String
ctACCTID :: String
  -- ^ Account number

  , CCAcctTo -> Maybe String
ctACCTKEY :: Maybe String
  -- ^ Checksum for international banks

  } deriving (CCAcctTo -> CCAcctTo -> Bool
(CCAcctTo -> CCAcctTo -> Bool)
-> (CCAcctTo -> CCAcctTo -> Bool) -> Eq CCAcctTo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CCAcctTo -> CCAcctTo -> Bool
$c/= :: CCAcctTo -> CCAcctTo -> Bool
== :: CCAcctTo -> CCAcctTo -> Bool
$c== :: CCAcctTo -> CCAcctTo -> Bool
Eq, Int -> CCAcctTo -> ShowS
[CCAcctTo] -> ShowS
CCAcctTo -> String
(Int -> CCAcctTo -> ShowS)
-> (CCAcctTo -> String) -> ([CCAcctTo] -> ShowS) -> Show CCAcctTo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CCAcctTo] -> ShowS
$cshowList :: [CCAcctTo] -> ShowS
show :: CCAcctTo -> String
$cshow :: CCAcctTo -> String
showsPrec :: Int -> CCAcctTo -> ShowS
$cshowsPrec :: Int -> CCAcctTo -> ShowS
Show, ReadPrec [CCAcctTo]
ReadPrec CCAcctTo
Int -> ReadS CCAcctTo
ReadS [CCAcctTo]
(Int -> ReadS CCAcctTo)
-> ReadS [CCAcctTo]
-> ReadPrec CCAcctTo
-> ReadPrec [CCAcctTo]
-> Read CCAcctTo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CCAcctTo]
$creadListPrec :: ReadPrec [CCAcctTo]
readPrec :: ReadPrec CCAcctTo
$creadPrec :: ReadPrec CCAcctTo
readList :: ReadS [CCAcctTo]
$creadList :: ReadS [CCAcctTo]
readsPrec :: Int -> ReadS CCAcctTo
$creadsPrec :: Int -> ReadS CCAcctTo
Read, Typeable CCAcctTo
Constr
DataType
Typeable CCAcctTo =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CCAcctTo -> c CCAcctTo)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CCAcctTo)
-> (CCAcctTo -> Constr)
-> (CCAcctTo -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CCAcctTo))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCAcctTo))
-> ((forall b. Data b => b -> b) -> CCAcctTo -> CCAcctTo)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r)
-> (forall u. (forall d. Data d => d -> u) -> CCAcctTo -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> CCAcctTo -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo)
-> Data CCAcctTo
CCAcctTo -> Constr
CCAcctTo -> DataType
(forall b. Data b => b -> b) -> CCAcctTo -> CCAcctTo
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCAcctTo -> c CCAcctTo
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCAcctTo
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CCAcctTo -> u
forall u. (forall d. Data d => d -> u) -> CCAcctTo -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCAcctTo
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCAcctTo -> c CCAcctTo
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CCAcctTo)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCAcctTo)
$cCCAcctTo :: Constr
$tCCAcctTo :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
gmapMp :: (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
gmapM :: (forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CCAcctTo -> m CCAcctTo
gmapQi :: Int -> (forall d. Data d => d -> u) -> CCAcctTo -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CCAcctTo -> u
gmapQ :: (forall d. Data d => d -> u) -> CCAcctTo -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CCAcctTo -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCAcctTo -> r
gmapT :: (forall b. Data b => b -> b) -> CCAcctTo -> CCAcctTo
$cgmapT :: (forall b. Data b => b -> b) -> CCAcctTo -> CCAcctTo
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCAcctTo)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCAcctTo)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c CCAcctTo)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CCAcctTo)
dataTypeOf :: CCAcctTo -> DataType
$cdataTypeOf :: CCAcctTo -> DataType
toConstr :: CCAcctTo -> Constr
$ctoConstr :: CCAcctTo -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCAcctTo
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCAcctTo
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCAcctTo -> c CCAcctTo
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCAcctTo -> c CCAcctTo
$cp1Data :: Typeable CCAcctTo
Data, (forall x. CCAcctTo -> Rep CCAcctTo x)
-> (forall x. Rep CCAcctTo x -> CCAcctTo) -> Generic CCAcctTo
forall x. Rep CCAcctTo x -> CCAcctTo
forall x. CCAcctTo -> Rep CCAcctTo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CCAcctTo x -> CCAcctTo
$cfrom :: forall x. CCAcctTo -> Rep CCAcctTo x
Generic, Typeable)

data AcctType
  = ACHECKING
  | ASAVINGS
  | AMONEYMRKT
  | ACREDITLINE
  deriving (AcctType -> AcctType -> Bool
(AcctType -> AcctType -> Bool)
-> (AcctType -> AcctType -> Bool) -> Eq AcctType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AcctType -> AcctType -> Bool
$c/= :: AcctType -> AcctType -> Bool
== :: AcctType -> AcctType -> Bool
$c== :: AcctType -> AcctType -> Bool
Eq, Int -> AcctType -> ShowS
[AcctType] -> ShowS
AcctType -> String
(Int -> AcctType -> ShowS)
-> (AcctType -> String) -> ([AcctType] -> ShowS) -> Show AcctType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AcctType] -> ShowS
$cshowList :: [AcctType] -> ShowS
show :: AcctType -> String
$cshow :: AcctType -> String
showsPrec :: Int -> AcctType -> ShowS
$cshowsPrec :: Int -> AcctType -> ShowS
Show, Eq AcctType
Eq AcctType =>
(AcctType -> AcctType -> Ordering)
-> (AcctType -> AcctType -> Bool)
-> (AcctType -> AcctType -> Bool)
-> (AcctType -> AcctType -> Bool)
-> (AcctType -> AcctType -> Bool)
-> (AcctType -> AcctType -> AcctType)
-> (AcctType -> AcctType -> AcctType)
-> Ord AcctType
AcctType -> AcctType -> Bool
AcctType -> AcctType -> Ordering
AcctType -> AcctType -> AcctType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AcctType -> AcctType -> AcctType
$cmin :: AcctType -> AcctType -> AcctType
max :: AcctType -> AcctType -> AcctType
$cmax :: AcctType -> AcctType -> AcctType
>= :: AcctType -> AcctType -> Bool
$c>= :: AcctType -> AcctType -> Bool
> :: AcctType -> AcctType -> Bool
$c> :: AcctType -> AcctType -> Bool
<= :: AcctType -> AcctType -> Bool
$c<= :: AcctType -> AcctType -> Bool
< :: AcctType -> AcctType -> Bool
$c< :: AcctType -> AcctType -> Bool
compare :: AcctType -> AcctType -> Ordering
$ccompare :: AcctType -> AcctType -> Ordering
$cp1Ord :: Eq AcctType
Ord, ReadPrec [AcctType]
ReadPrec AcctType
Int -> ReadS AcctType
ReadS [AcctType]
(Int -> ReadS AcctType)
-> ReadS [AcctType]
-> ReadPrec AcctType
-> ReadPrec [AcctType]
-> Read AcctType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [AcctType]
$creadListPrec :: ReadPrec [AcctType]
readPrec :: ReadPrec AcctType
$creadPrec :: ReadPrec AcctType
readList :: ReadS [AcctType]
$creadList :: ReadS [AcctType]
readsPrec :: Int -> ReadS AcctType
$creadsPrec :: Int -> ReadS AcctType
Read, Typeable AcctType
Constr
DataType
Typeable AcctType =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> AcctType -> c AcctType)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AcctType)
-> (AcctType -> Constr)
-> (AcctType -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AcctType))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AcctType))
-> ((forall b. Data b => b -> b) -> AcctType -> AcctType)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AcctType -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AcctType -> r)
-> (forall u. (forall d. Data d => d -> u) -> AcctType -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> AcctType -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AcctType -> m AcctType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AcctType -> m AcctType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AcctType -> m AcctType)
-> Data AcctType
AcctType -> Constr
AcctType -> DataType
(forall b. Data b => b -> b) -> AcctType -> AcctType
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> AcctType -> c AcctType
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c AcctType
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> AcctType -> u
forall u. (forall d. Data d => d -> u) -> AcctType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> AcctType -> m AcctType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> AcctType -> m AcctType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c AcctType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> AcctType -> c AcctType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c AcctType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AcctType)
$cACREDITLINE :: Constr
$cAMONEYMRKT :: Constr
$cASAVINGS :: Constr
$cACHECKING :: Constr
$tAcctType :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> AcctType -> m AcctType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> AcctType -> m AcctType
gmapMp :: (forall d. Data d => d -> m d) -> AcctType -> m AcctType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> AcctType -> m AcctType
gmapM :: (forall d. Data d => d -> m d) -> AcctType -> m AcctType
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> AcctType -> m AcctType
gmapQi :: Int -> (forall d. Data d => d -> u) -> AcctType -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AcctType -> u
gmapQ :: (forall d. Data d => d -> u) -> AcctType -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> AcctType -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> AcctType -> r
gmapT :: (forall b. Data b => b -> b) -> AcctType -> AcctType
$cgmapT :: (forall b. Data b => b -> b) -> AcctType -> AcctType
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AcctType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AcctType)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c AcctType)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c AcctType)
dataTypeOf :: AcctType -> DataType
$cdataTypeOf :: AcctType -> DataType
toConstr :: AcctType -> Constr
$ctoConstr :: AcctType -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c AcctType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c AcctType
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> AcctType -> c AcctType
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> AcctType -> c AcctType
$cp1Data :: Typeable AcctType
Data, (forall x. AcctType -> Rep AcctType x)
-> (forall x. Rep AcctType x -> AcctType) -> Generic AcctType
forall x. Rep AcctType x -> AcctType
forall x. AcctType -> Rep AcctType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep AcctType x -> AcctType
$cfrom :: forall x. AcctType -> Rep AcctType x
Generic, Typeable)

acctType :: String -> Err AcctType
acctType :: String -> Err AcctType
acctType s :: String
s
  | String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "CHECKING" = AcctType -> Err AcctType
forall (m :: * -> *) a. Monad m => a -> m a
return AcctType
ACHECKING
  | String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "SAVINGS" = AcctType -> Err AcctType
forall (m :: * -> *) a. Monad m => a -> m a
return AcctType
ASAVINGS
  | String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "MONEYMRKT" = AcctType -> Err AcctType
forall (m :: * -> *) a. Monad m => a -> m a
return AcctType
AMONEYMRKT
  | String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "CREDITLINE" = AcctType -> Err AcctType
forall (m :: * -> *) a. Monad m => a -> m a
return AcctType
ACREDITLINE
  | Bool
otherwise = String -> Err AcctType
forall a b. a -> Either a b
Left (String -> Err AcctType) -> String -> Err AcctType
forall a b. (a -> b) -> a -> b
$ "unrecognized account type: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s

-- | Holds all data both for CURRENCY and for ORIGCURRENCY.
data CurrencyData = CurrencyData

  { CurrencyData -> String
cdCURRATE :: String
  -- ^ Ratio of CURDEF currency to CURSYM currency, in decimal form

  , CurrencyData -> String
cdCURSYM :: String
  -- ^ ISO-4217 3-letter currency identifier
  } deriving (CurrencyData -> CurrencyData -> Bool
(CurrencyData -> CurrencyData -> Bool)
-> (CurrencyData -> CurrencyData -> Bool) -> Eq CurrencyData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CurrencyData -> CurrencyData -> Bool
$c/= :: CurrencyData -> CurrencyData -> Bool
== :: CurrencyData -> CurrencyData -> Bool
$c== :: CurrencyData -> CurrencyData -> Bool
Eq, Int -> CurrencyData -> ShowS
[CurrencyData] -> ShowS
CurrencyData -> String
(Int -> CurrencyData -> ShowS)
-> (CurrencyData -> String)
-> ([CurrencyData] -> ShowS)
-> Show CurrencyData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CurrencyData] -> ShowS
$cshowList :: [CurrencyData] -> ShowS
show :: CurrencyData -> String
$cshow :: CurrencyData -> String
showsPrec :: Int -> CurrencyData -> ShowS
$cshowsPrec :: Int -> CurrencyData -> ShowS
Show, ReadPrec [CurrencyData]
ReadPrec CurrencyData
Int -> ReadS CurrencyData
ReadS [CurrencyData]
(Int -> ReadS CurrencyData)
-> ReadS [CurrencyData]
-> ReadPrec CurrencyData
-> ReadPrec [CurrencyData]
-> Read CurrencyData
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CurrencyData]
$creadListPrec :: ReadPrec [CurrencyData]
readPrec :: ReadPrec CurrencyData
$creadPrec :: ReadPrec CurrencyData
readList :: ReadS [CurrencyData]
$creadList :: ReadS [CurrencyData]
readsPrec :: Int -> ReadS CurrencyData
$creadsPrec :: Int -> ReadS CurrencyData
Read, Typeable CurrencyData
Constr
DataType
Typeable CurrencyData =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CurrencyData -> c CurrencyData)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CurrencyData)
-> (CurrencyData -> Constr)
-> (CurrencyData -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CurrencyData))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c CurrencyData))
-> ((forall b. Data b => b -> b) -> CurrencyData -> CurrencyData)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CurrencyData -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CurrencyData -> r)
-> (forall u. (forall d. Data d => d -> u) -> CurrencyData -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CurrencyData -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData)
-> Data CurrencyData
CurrencyData -> Constr
CurrencyData -> DataType
(forall b. Data b => b -> b) -> CurrencyData -> CurrencyData
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CurrencyData -> c CurrencyData
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CurrencyData
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CurrencyData -> u
forall u. (forall d. Data d => d -> u) -> CurrencyData -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CurrencyData
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CurrencyData -> c CurrencyData
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CurrencyData)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CurrencyData)
$cCurrencyData :: Constr
$tCurrencyData :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
gmapMp :: (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
gmapM :: (forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CurrencyData -> m CurrencyData
gmapQi :: Int -> (forall d. Data d => d -> u) -> CurrencyData -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CurrencyData -> u
gmapQ :: (forall d. Data d => d -> u) -> CurrencyData -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CurrencyData -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CurrencyData -> r
gmapT :: (forall b. Data b => b -> b) -> CurrencyData -> CurrencyData
$cgmapT :: (forall b. Data b => b -> b) -> CurrencyData -> CurrencyData
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CurrencyData)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CurrencyData)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c CurrencyData)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CurrencyData)
dataTypeOf :: CurrencyData -> DataType
$cdataTypeOf :: CurrencyData -> DataType
toConstr :: CurrencyData -> Constr
$ctoConstr :: CurrencyData -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CurrencyData
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CurrencyData
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CurrencyData -> c CurrencyData
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CurrencyData -> c CurrencyData
$cp1Data :: Typeable CurrencyData
Data, (forall x. CurrencyData -> Rep CurrencyData x)
-> (forall x. Rep CurrencyData x -> CurrencyData)
-> Generic CurrencyData
forall x. Rep CurrencyData x -> CurrencyData
forall x. CurrencyData -> Rep CurrencyData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CurrencyData x -> CurrencyData
$cfrom :: forall x. CurrencyData -> Rep CurrencyData x
Generic, Typeable)

data Currency = Currency CurrencyData
  deriving (Currency -> Currency -> Bool
(Currency -> Currency -> Bool)
-> (Currency -> Currency -> Bool) -> Eq Currency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Currency -> Currency -> Bool
$c/= :: Currency -> Currency -> Bool
== :: Currency -> Currency -> Bool
$c== :: Currency -> Currency -> Bool
Eq, Int -> Currency -> ShowS
[Currency] -> ShowS
Currency -> String
(Int -> Currency -> ShowS)
-> (Currency -> String) -> ([Currency] -> ShowS) -> Show Currency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Currency] -> ShowS
$cshowList :: [Currency] -> ShowS
show :: Currency -> String
$cshow :: Currency -> String
showsPrec :: Int -> Currency -> ShowS
$cshowsPrec :: Int -> Currency -> ShowS
Show, ReadPrec [Currency]
ReadPrec Currency
Int -> ReadS Currency
ReadS [Currency]
(Int -> ReadS Currency)
-> ReadS [Currency]
-> ReadPrec Currency
-> ReadPrec [Currency]
-> Read Currency
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Currency]
$creadListPrec :: ReadPrec [Currency]
readPrec :: ReadPrec Currency
$creadPrec :: ReadPrec Currency
readList :: ReadS [Currency]
$creadList :: ReadS [Currency]
readsPrec :: Int -> ReadS Currency
$creadsPrec :: Int -> ReadS Currency
Read, Typeable Currency
Constr
DataType
Typeable Currency =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Currency -> c Currency)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Currency)
-> (Currency -> Constr)
-> (Currency -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Currency))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Currency))
-> ((forall b. Data b => b -> b) -> Currency -> Currency)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Currency -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Currency -> r)
-> (forall u. (forall d. Data d => d -> u) -> Currency -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Currency -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Currency -> m Currency)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Currency -> m Currency)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Currency -> m Currency)
-> Data Currency
Currency -> Constr
Currency -> DataType
(forall b. Data b => b -> b) -> Currency -> Currency
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Currency -> c Currency
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Currency
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Currency -> u
forall u. (forall d. Data d => d -> u) -> Currency -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Currency -> m Currency
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Currency -> m Currency
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Currency
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Currency -> c Currency
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Currency)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Currency)
$cCurrency :: Constr
$tCurrency :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Currency -> m Currency
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Currency -> m Currency
gmapMp :: (forall d. Data d => d -> m d) -> Currency -> m Currency
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Currency -> m Currency
gmapM :: (forall d. Data d => d -> m d) -> Currency -> m Currency
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Currency -> m Currency
gmapQi :: Int -> (forall d. Data d => d -> u) -> Currency -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Currency -> u
gmapQ :: (forall d. Data d => d -> u) -> Currency -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Currency -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Currency -> r
gmapT :: (forall b. Data b => b -> b) -> Currency -> Currency
$cgmapT :: (forall b. Data b => b -> b) -> Currency -> Currency
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Currency)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Currency)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Currency)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Currency)
dataTypeOf :: Currency -> DataType
$cdataTypeOf :: Currency -> DataType
toConstr :: Currency -> Constr
$ctoConstr :: Currency -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Currency
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Currency
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Currency -> c Currency
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Currency -> c Currency
$cp1Data :: Typeable Currency
Data, (forall x. Currency -> Rep Currency x)
-> (forall x. Rep Currency x -> Currency) -> Generic Currency
forall x. Rep Currency x -> Currency
forall x. Currency -> Rep Currency x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Currency x -> Currency
$cfrom :: forall x. Currency -> Rep Currency x
Generic, Typeable)

data OrigCurrency = OrigCurrency CurrencyData
  deriving (OrigCurrency -> OrigCurrency -> Bool
(OrigCurrency -> OrigCurrency -> Bool)
-> (OrigCurrency -> OrigCurrency -> Bool) -> Eq OrigCurrency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OrigCurrency -> OrigCurrency -> Bool
$c/= :: OrigCurrency -> OrigCurrency -> Bool
== :: OrigCurrency -> OrigCurrency -> Bool
$c== :: OrigCurrency -> OrigCurrency -> Bool
Eq, Int -> OrigCurrency -> ShowS
[OrigCurrency] -> ShowS
OrigCurrency -> String
(Int -> OrigCurrency -> ShowS)
-> (OrigCurrency -> String)
-> ([OrigCurrency] -> ShowS)
-> Show OrigCurrency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OrigCurrency] -> ShowS
$cshowList :: [OrigCurrency] -> ShowS
show :: OrigCurrency -> String
$cshow :: OrigCurrency -> String
showsPrec :: Int -> OrigCurrency -> ShowS
$cshowsPrec :: Int -> OrigCurrency -> ShowS
Show, ReadPrec [OrigCurrency]
ReadPrec OrigCurrency
Int -> ReadS OrigCurrency
ReadS [OrigCurrency]
(Int -> ReadS OrigCurrency)
-> ReadS [OrigCurrency]
-> ReadPrec OrigCurrency
-> ReadPrec [OrigCurrency]
-> Read OrigCurrency
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [OrigCurrency]
$creadListPrec :: ReadPrec [OrigCurrency]
readPrec :: ReadPrec OrigCurrency
$creadPrec :: ReadPrec OrigCurrency
readList :: ReadS [OrigCurrency]
$creadList :: ReadS [OrigCurrency]
readsPrec :: Int -> ReadS OrigCurrency
$creadsPrec :: Int -> ReadS OrigCurrency
Read, Typeable OrigCurrency
Constr
DataType
Typeable OrigCurrency =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> OrigCurrency -> c OrigCurrency)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c OrigCurrency)
-> (OrigCurrency -> Constr)
-> (OrigCurrency -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c OrigCurrency))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c OrigCurrency))
-> ((forall b. Data b => b -> b) -> OrigCurrency -> OrigCurrency)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r)
-> (forall u. (forall d. Data d => d -> u) -> OrigCurrency -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> OrigCurrency -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency)
-> Data OrigCurrency
OrigCurrency -> Constr
OrigCurrency -> DataType
(forall b. Data b => b -> b) -> OrigCurrency -> OrigCurrency
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrigCurrency -> c OrigCurrency
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrigCurrency
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> OrigCurrency -> u
forall u. (forall d. Data d => d -> u) -> OrigCurrency -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrigCurrency
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrigCurrency -> c OrigCurrency
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OrigCurrency)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c OrigCurrency)
$cOrigCurrency :: Constr
$tOrigCurrency :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
gmapMp :: (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
gmapM :: (forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OrigCurrency -> m OrigCurrency
gmapQi :: Int -> (forall d. Data d => d -> u) -> OrigCurrency -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OrigCurrency -> u
gmapQ :: (forall d. Data d => d -> u) -> OrigCurrency -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> OrigCurrency -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrigCurrency -> r
gmapT :: (forall b. Data b => b -> b) -> OrigCurrency -> OrigCurrency
$cgmapT :: (forall b. Data b => b -> b) -> OrigCurrency -> OrigCurrency
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c OrigCurrency)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c OrigCurrency)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c OrigCurrency)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OrigCurrency)
dataTypeOf :: OrigCurrency -> DataType
$cdataTypeOf :: OrigCurrency -> DataType
toConstr :: OrigCurrency -> Constr
$ctoConstr :: OrigCurrency -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrigCurrency
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrigCurrency
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrigCurrency -> c OrigCurrency
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrigCurrency -> c OrigCurrency
$cp1Data :: Typeable OrigCurrency
Data, (forall x. OrigCurrency -> Rep OrigCurrency x)
-> (forall x. Rep OrigCurrency x -> OrigCurrency)
-> Generic OrigCurrency
forall x. Rep OrigCurrency x -> OrigCurrency
forall x. OrigCurrency -> Rep OrigCurrency x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OrigCurrency x -> OrigCurrency
$cfrom :: forall x. OrigCurrency -> Rep OrigCurrency x
Generic, Typeable)

--
-- # Helpers to build aggregates
--
trnType :: TagData -> Maybe TrnType
trnType :: String -> Maybe TrnType
trnType d :: String
d = case String
d of
  "CREDIT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TCREDIT
  "DEBIT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TDEBIT
  "INT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TINT
  "DIV" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TDIV
  "FEE" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TFEE
  "SRVCHG" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TSRVCHG
  "DEP" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TDEP
  "ATM" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TATM
  "POS" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TPOS
  "XFER" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TXFER
  "CHECK" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TCHECK
  "PAYMENT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TPAYMENT
  "CASH" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TCASH
  "DIRECTDEP" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TDIRECTDEP
  "DIRECTDEBIT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TDIRECTDEBIT
  "REPEATPMT" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TREPEATPMT
  "OTHER" -> TrnType -> Maybe TrnType
forall a. a -> Maybe a
Just TrnType
TOTHER
  _ -> Maybe TrnType
forall a. Maybe a
Nothing


-- | Gets a single Transaction from a tag. The tag should be the one
-- named STMTTRN. Fails with an error message if any required field
-- was not present.
transaction :: Tag -> Err Transaction
transaction :: Tag -> Err Transaction
transaction t :: Tag
t = do
  let fromMaybe :: a -> Maybe b -> Either a b
fromMaybe e :: a
e = Either a b -> (b -> Either a b) -> Maybe b -> Either a b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (a -> Either a b
forall a b. a -> Either a b
Left a
e) b -> Either a b
forall a b. b -> Either a b
Right
  String
trntyStr <- String -> Tag -> Err String
required "TRNTYPE" Tag
t
  TrnType
trnTy <- String -> Maybe TrnType -> Either String TrnType
forall a b. a -> Maybe b -> Either a b
fromMaybe ("could not parse transaction type: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
trntyStr)
           (Maybe TrnType -> Either String TrnType)
-> Maybe TrnType -> Either String TrnType
forall a b. (a -> b) -> a -> b
$ String -> Maybe TrnType
trnType String
trntyStr

  String
dtpStr <- String -> Tag -> Err String
required "DTPOSTED" Tag
t
  ZonedTime
dtp <- String -> Err ZonedTime
parseDate String
dtpStr

  let mayDtuStr :: Maybe String
mayDtuStr = String -> Tag -> Maybe String
findData "DTUSER" Tag
t
  Maybe ZonedTime
dtu <- Either String (Maybe ZonedTime)
-> (String -> Either String (Maybe ZonedTime))
-> Maybe String
-> Either String (Maybe ZonedTime)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe ZonedTime -> Either String (Maybe ZonedTime)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ZonedTime
forall a. Maybe a
Nothing) ((ZonedTime -> Maybe ZonedTime)
-> Err ZonedTime -> Either String (Maybe ZonedTime)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ZonedTime -> Maybe ZonedTime
forall a. a -> Maybe a
Just (Err ZonedTime -> Either String (Maybe ZonedTime))
-> (String -> Err ZonedTime)
-> String
-> Either String (Maybe ZonedTime)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Err ZonedTime
parseDate) Maybe String
mayDtuStr
      
  let mayDtAvail :: Maybe String
mayDtAvail = String -> Tag -> Maybe String
findData "DTAVAIL" Tag
t

  Maybe ZonedTime
dta <- Either String (Maybe ZonedTime)
-> (String -> Either String (Maybe ZonedTime))
-> Maybe String
-> Either String (Maybe ZonedTime)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe ZonedTime -> Either String (Maybe ZonedTime)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ZonedTime
forall a. Maybe a
Nothing) ((ZonedTime -> Maybe ZonedTime)
-> Err ZonedTime -> Either String (Maybe ZonedTime)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ZonedTime -> Maybe ZonedTime
forall a. a -> Maybe a
Just (Err ZonedTime -> Either String (Maybe ZonedTime))
-> (String -> Err ZonedTime)
-> String
-> Either String (Maybe ZonedTime)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Err ZonedTime
parseDate) Maybe String
mayDtAvail
  String
amt <- String -> Tag -> Err String
required "TRNAMT" Tag
t
  String
fitid <- String -> Tag -> Err String
required "FITID" Tag
t
  let correctFitId :: Maybe String
correctFitId = String -> Tag -> Maybe String
findData "CORRECTFITID" Tag
t
  Maybe CorrectAction
correctAct <-
    case String -> Tag -> Maybe String
findData "CORRECTACTION" Tag
t of
      Nothing -> Maybe CorrectAction -> Either String (Maybe CorrectAction)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe CorrectAction
forall a. Maybe a
Nothing
      Just d :: String
d -> 
        Either String (Maybe CorrectAction)
-> (Maybe (Maybe CorrectAction)
    -> Either String (Maybe CorrectAction))
-> Maybe (Maybe (Maybe CorrectAction))
-> Either String (Maybe CorrectAction)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe CorrectAction -> Either String (Maybe CorrectAction)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe CorrectAction
forall a. Maybe a
Nothing)
          (String
-> Maybe (Maybe CorrectAction)
-> Either String (Maybe CorrectAction)
forall a b. a -> Maybe b -> Either a b
fromMaybe ("could not parse correct action: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
d))
        (Maybe (Maybe (Maybe CorrectAction))
 -> Either String (Maybe CorrectAction))
-> (String -> Maybe (Maybe (Maybe CorrectAction)))
-> String
-> Either String (Maybe CorrectAction)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe (Maybe (Maybe CorrectAction))
forall a. Read a => String -> Maybe a
safeRead
        (String -> Either String (Maybe CorrectAction))
-> String -> Either String (Maybe CorrectAction)
forall a b. (a -> b) -> a -> b
$ String
d
  let srvrtid :: Maybe String
srvrtid = String -> Tag -> Maybe String
findData "SRVRTID" Tag
t
      checknum :: Maybe String
checknum = String -> Tag -> Maybe String
findData "CHECKNUM" Tag
t
      refnum :: Maybe String
refnum = String -> Tag -> Maybe String
findData "REFNUM" Tag
t
      sic :: Maybe String
sic = String -> Tag -> Maybe String
findData "SIC" Tag
t
      payeeId :: Maybe String
payeeId = String -> Tag -> Maybe String
findData "PAYEEID" Tag
t

  let mayPyeInfo :: Maybe (Either String (Either String Payee))
mayPyeInfo = (String -> Either String (Either String Payee))
-> Maybe String -> Maybe (Either String (Either String Payee))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either String Payee -> Either String (Either String Payee)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String Payee -> Either String (Either String Payee))
-> (String -> Either String Payee)
-> String
-> Either String (Either String Payee)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String Payee
forall a b. a -> Either a b
Left) (String -> Tag -> Maybe String
findData "NAME" Tag
t)
                   Maybe (Either String (Either String Payee))
-> Maybe (Either String (Either String Payee))
-> Maybe (Either String (Either String Payee))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Either String Payee -> Either String (Either String Payee))
-> Maybe (Either String Payee)
-> Maybe (Either String (Either String Payee))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Payee -> Either String Payee)
-> Either String Payee -> Either String (Either String Payee)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Payee -> Either String Payee
forall a b. b -> Either a b
Right) (Tag -> Maybe (Either String Payee)
payee Tag
t)
  Maybe (Either String Payee)
pyeInfo <- Either String (Maybe (Either String Payee))
-> (Either String (Either String Payee)
    -> Either String (Maybe (Either String Payee)))
-> Maybe (Either String (Either String Payee))
-> Either String (Maybe (Either String Payee))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (Either String Payee)
-> Either String (Maybe (Either String Payee))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either String Payee)
forall a. Maybe a
Nothing) ((Either String Payee -> Maybe (Either String Payee))
-> Either String (Either String Payee)
-> Either String (Maybe (Either String Payee))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either String Payee -> Maybe (Either String Payee)
forall a. a -> Maybe a
Just) Maybe (Either String (Either String Payee))
mayPyeInfo
 
  let mayAcctTo :: Maybe (Either String (Either BankAcctTo CCAcctTo))
mayAcctTo = ((Either String BankAcctTo
 -> Either String (Either BankAcctTo CCAcctTo))
-> Maybe (Either String BankAcctTo)
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((BankAcctTo -> Either BankAcctTo CCAcctTo)
-> Either String BankAcctTo
-> Either String (Either BankAcctTo CCAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BankAcctTo -> Either BankAcctTo CCAcctTo
forall a b. a -> Either a b
Left) (Maybe (Either String BankAcctTo)
 -> Maybe (Either String (Either BankAcctTo CCAcctTo)))
-> Maybe (Either String BankAcctTo)
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
forall a b. (a -> b) -> a -> b
$ Tag -> Maybe (Either String BankAcctTo)
bankAcctTo Tag
t)
               Maybe (Either String (Either BankAcctTo CCAcctTo))
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Either String CCAcctTo
 -> Either String (Either BankAcctTo CCAcctTo))
-> Maybe (Either String CCAcctTo)
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CCAcctTo -> Either BankAcctTo CCAcctTo)
-> Either String CCAcctTo
-> Either String (Either BankAcctTo CCAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CCAcctTo -> Either BankAcctTo CCAcctTo
forall a b. b -> Either a b
Right) (Maybe (Either String CCAcctTo)
 -> Maybe (Either String (Either BankAcctTo CCAcctTo)))
-> Maybe (Either String CCAcctTo)
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
forall a b. (a -> b) -> a -> b
$ Tag -> Maybe (Either String CCAcctTo)
ccAcctTo Tag
t)
      mayCcy :: Maybe (Either String (Either Currency OrigCurrency))
mayCcy = ((Either String Currency
 -> Either String (Either Currency OrigCurrency))
-> Maybe (Either String Currency)
-> Maybe (Either String (Either Currency OrigCurrency))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Currency -> Either Currency OrigCurrency)
-> Either String Currency
-> Either String (Either Currency OrigCurrency)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Currency -> Either Currency OrigCurrency
forall a b. a -> Either a b
Left) (Maybe (Either String Currency)
 -> Maybe (Either String (Either Currency OrigCurrency)))
-> Maybe (Either String Currency)
-> Maybe (Either String (Either Currency OrigCurrency))
forall a b. (a -> b) -> a -> b
$ Tag -> Maybe (Either String Currency)
currency Tag
t)
            Maybe (Either String (Either Currency OrigCurrency))
-> Maybe (Either String (Either Currency OrigCurrency))
-> Maybe (Either String (Either Currency OrigCurrency))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Either String OrigCurrency
 -> Either String (Either Currency OrigCurrency))
-> Maybe (Either String OrigCurrency)
-> Maybe (Either String (Either Currency OrigCurrency))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((OrigCurrency -> Either Currency OrigCurrency)
-> Either String OrigCurrency
-> Either String (Either Currency OrigCurrency)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OrigCurrency -> Either Currency OrigCurrency
forall a b. b -> Either a b
Right) (Maybe (Either String OrigCurrency)
 -> Maybe (Either String (Either Currency OrigCurrency)))
-> Maybe (Either String OrigCurrency)
-> Maybe (Either String (Either Currency OrigCurrency))
forall a b. (a -> b) -> a -> b
$ Tag -> Maybe (Either String OrigCurrency)
origCurrency Tag
t)
  Maybe (Either BankAcctTo CCAcctTo)
acctTo <- Either String (Maybe (Either BankAcctTo CCAcctTo))
-> (Either String (Either BankAcctTo CCAcctTo)
    -> Either String (Maybe (Either BankAcctTo CCAcctTo)))
-> Maybe (Either String (Either BankAcctTo CCAcctTo))
-> Either String (Maybe (Either BankAcctTo CCAcctTo))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (Either BankAcctTo CCAcctTo)
-> Either String (Maybe (Either BankAcctTo CCAcctTo))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either BankAcctTo CCAcctTo)
forall a. Maybe a
Nothing) ((Either BankAcctTo CCAcctTo -> Maybe (Either BankAcctTo CCAcctTo))
-> Either String (Either BankAcctTo CCAcctTo)
-> Either String (Maybe (Either BankAcctTo CCAcctTo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either BankAcctTo CCAcctTo -> Maybe (Either BankAcctTo CCAcctTo)
forall a. a -> Maybe a
Just) Maybe (Either String (Either BankAcctTo CCAcctTo))
mayAcctTo
  Maybe (Either Currency OrigCurrency)
ccy <- Either String (Maybe (Either Currency OrigCurrency))
-> (Either String (Either Currency OrigCurrency)
    -> Either String (Maybe (Either Currency OrigCurrency)))
-> Maybe (Either String (Either Currency OrigCurrency))
-> Either String (Maybe (Either Currency OrigCurrency))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (Either Currency OrigCurrency)
-> Either String (Maybe (Either Currency OrigCurrency))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either Currency OrigCurrency)
forall a. Maybe a
Nothing) ((Either Currency OrigCurrency
 -> Maybe (Either Currency OrigCurrency))
-> Either String (Either Currency OrigCurrency)
-> Either String (Maybe (Either Currency OrigCurrency))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Currency OrigCurrency
-> Maybe (Either Currency OrigCurrency)
forall a. a -> Maybe a
Just) Maybe (Either String (Either Currency OrigCurrency))
mayCcy
  let memo :: Maybe String
memo = String -> Tag -> Maybe String
findData "MEMO" Tag
t

  Transaction -> Err Transaction
forall (m :: * -> *) a. Monad m => a -> m a
return Transaction :: TrnType
-> ZonedTime
-> Maybe ZonedTime
-> Maybe ZonedTime
-> String
-> String
-> Maybe String
-> Maybe CorrectAction
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe (Either String Payee)
-> Maybe (Either BankAcctTo CCAcctTo)
-> Maybe String
-> Maybe (Either Currency OrigCurrency)
-> Transaction
Transaction
    { txTRNTYPE :: TrnType
txTRNTYPE = TrnType
trnTy
    , txDTPOSTED :: ZonedTime
txDTPOSTED = ZonedTime
dtp
    , txDTUSER :: Maybe ZonedTime
txDTUSER = Maybe ZonedTime
dtu
    , txDTAVAIL :: Maybe ZonedTime
txDTAVAIL = Maybe ZonedTime
dta
    , txTRNAMT :: String
txTRNAMT = String
amt
    , txFITID :: String
txFITID = String
fitid
    , txCORRECTFITID :: Maybe String
txCORRECTFITID = Maybe String
correctFitId
    , txCORRECTACTION :: Maybe CorrectAction
txCORRECTACTION = Maybe CorrectAction
correctAct
    , txSRVRTID :: Maybe String
txSRVRTID = Maybe String
srvrtid
    , txCHECKNUM :: Maybe String
txCHECKNUM = Maybe String
checknum
    , txREFNUM :: Maybe String
txREFNUM = Maybe String
refnum
    , txSIC :: Maybe String
txSIC = Maybe String
sic
    , txPAYEEID :: Maybe String
txPAYEEID = Maybe String
payeeId
    , txPayeeInfo :: Maybe (Either String Payee)
txPayeeInfo = Maybe (Either String Payee)
pyeInfo
    , txAccountTo :: Maybe (Either BankAcctTo CCAcctTo)
txAccountTo = Maybe (Either BankAcctTo CCAcctTo)
acctTo
    , txMEMO :: Maybe String
txMEMO = Maybe String
memo
    , txCurrency :: Maybe (Either Currency OrigCurrency)
txCurrency = Maybe (Either Currency OrigCurrency)
ccy
    }      

-- | Parses a Payee record from its parent tag.
payee
  :: Tag
  -- ^ The tag which contains the PAYEE tag, if there is one. This
  -- would typically be a STMTTRN tag.

  -> Maybe (Err Payee)
  -- ^ Nothing if there is no PAYEE tag. Just if a PAYEE tag is found,
  -- with a Left if the tag is lacking a required element, or a
  -- Right if the tag is successfully parsed.
  --
  -- If there is more than one PAYEE tag, only the first one is
  -- considered.
payee :: Tag -> Maybe (Either String Payee)
payee = (Tag -> Either String Payee)
-> Maybe Tag -> Maybe (Either String Payee)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tag -> Either String Payee
getPayee (Maybe Tag -> Maybe (Either String Payee))
-> (Tag -> Maybe Tag) -> Tag -> Maybe (Either String Payee)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe ([Tag] -> Maybe Tag) -> (Tag -> [Tag]) -> Tag -> Maybe Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "PAYEE"
  where
    getPayee :: Tag -> Either String Payee
getPayee t :: Tag
t = String
-> String
-> Maybe String
-> Maybe String
-> String
-> String
-> String
-> Maybe String
-> String
-> Payee
Payee
      (String
 -> String
 -> Maybe String
 -> Maybe String
 -> String
 -> String
 -> String
 -> Maybe String
 -> String
 -> Payee)
-> Err String
-> Either
     String
     (String
      -> Maybe String
      -> Maybe String
      -> String
      -> String
      -> String
      -> Maybe String
      -> String
      -> Payee)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tag -> Err String
required "NAME" Tag
t
      Either
  String
  (String
   -> Maybe String
   -> Maybe String
   -> String
   -> String
   -> String
   -> Maybe String
   -> String
   -> Payee)
-> Err String
-> Either
     String
     (Maybe String
      -> Maybe String
      -> String
      -> String
      -> String
      -> Maybe String
      -> String
      -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "ADDR1" Tag
t
      Either
  String
  (Maybe String
   -> Maybe String
   -> String
   -> String
   -> String
   -> Maybe String
   -> String
   -> Payee)
-> Either String (Maybe String)
-> Either
     String
     (Maybe String
      -> String -> String -> String -> Maybe String -> String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "ADDR2" Tag
t)
      Either
  String
  (Maybe String
   -> String -> String -> String -> Maybe String -> String -> Payee)
-> Either String (Maybe String)
-> Either
     String
     (String -> String -> String -> Maybe String -> String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "ADDR3" Tag
t)
      Either
  String
  (String -> String -> String -> Maybe String -> String -> Payee)
-> Err String
-> Either
     String (String -> String -> Maybe String -> String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "CITY" Tag
t
      Either String (String -> String -> Maybe String -> String -> Payee)
-> Err String
-> Either String (String -> Maybe String -> String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "STATE" Tag
t
      Either String (String -> Maybe String -> String -> Payee)
-> Err String -> Either String (Maybe String -> String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "POSTALCODE" Tag
t
      Either String (Maybe String -> String -> Payee)
-> Either String (Maybe String) -> Either String (String -> Payee)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "COUNTRY" Tag
t)
      Either String (String -> Payee)
-> Err String -> Either String Payee
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "PHONE" Tag
t
  

currency :: Tag -> Maybe (Err Currency)
currency :: Tag -> Maybe (Either String Currency)
currency
  = (Either String CurrencyData -> Either String Currency)
-> Maybe (Either String CurrencyData)
-> Maybe (Either String Currency)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CurrencyData -> Currency)
-> Either String CurrencyData -> Either String Currency
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CurrencyData -> Currency
Currency)
  (Maybe (Either String CurrencyData)
 -> Maybe (Either String Currency))
-> (Tag -> Maybe (Either String CurrencyData))
-> Tag
-> Maybe (Either String Currency)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag -> Either String CurrencyData)
-> Maybe Tag -> Maybe (Either String CurrencyData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tag -> Either String CurrencyData
currencyData
  (Maybe Tag -> Maybe (Either String CurrencyData))
-> (Tag -> Maybe Tag) -> Tag -> Maybe (Either String CurrencyData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe
  ([Tag] -> Maybe Tag) -> (Tag -> [Tag]) -> Tag -> Maybe Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "CURRENCY"

origCurrency :: Tag -> Maybe (Err OrigCurrency)
origCurrency :: Tag -> Maybe (Either String OrigCurrency)
origCurrency
  = (Either String CurrencyData -> Either String OrigCurrency)
-> Maybe (Either String CurrencyData)
-> Maybe (Either String OrigCurrency)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CurrencyData -> OrigCurrency)
-> Either String CurrencyData -> Either String OrigCurrency
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CurrencyData -> OrigCurrency
OrigCurrency)
  (Maybe (Either String CurrencyData)
 -> Maybe (Either String OrigCurrency))
-> (Tag -> Maybe (Either String CurrencyData))
-> Tag
-> Maybe (Either String OrigCurrency)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag -> Either String CurrencyData)
-> Maybe Tag -> Maybe (Either String CurrencyData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tag -> Either String CurrencyData
currencyData
  (Maybe Tag -> Maybe (Either String CurrencyData))
-> (Tag -> Maybe Tag) -> Tag -> Maybe (Either String CurrencyData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe
  ([Tag] -> Maybe Tag) -> (Tag -> [Tag]) -> Tag -> Maybe Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "ORIGCURRENCY"


-- | Parses currency data.
currencyData
  :: Tag
  -- ^ The tag that contains the data, e.g. CURRENCY or ORIGCURRENCY.

  -> Err CurrencyData
currencyData :: Tag -> Either String CurrencyData
currencyData t :: Tag
t = String -> String -> CurrencyData
CurrencyData
  (String -> String -> CurrencyData)
-> Err String -> Either String (String -> CurrencyData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tag -> Err String
required "CURRATE" Tag
t
  Either String (String -> CurrencyData)
-> Err String -> Either String CurrencyData
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "CURSYM" Tag
t

bankAcctTo :: Tag -> Maybe (Err BankAcctTo)
bankAcctTo :: Tag -> Maybe (Either String BankAcctTo)
bankAcctTo = (Tag -> Either String BankAcctTo)
-> Maybe Tag -> Maybe (Either String BankAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tag -> Either String BankAcctTo
getTo (Maybe Tag -> Maybe (Either String BankAcctTo))
-> (Tag -> Maybe Tag) -> Tag -> Maybe (Either String BankAcctTo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe ([Tag] -> Maybe Tag) -> (Tag -> [Tag]) -> Tag -> Maybe Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "BANKACCTTO"
  where
    getTo :: Tag -> Either String BankAcctTo
getTo t :: Tag
t = String
-> Maybe String -> String -> AcctType -> Maybe String -> BankAcctTo
BankAcctTo
      (String
 -> Maybe String
 -> String
 -> AcctType
 -> Maybe String
 -> BankAcctTo)
-> Err String
-> Either
     String
     (Maybe String -> String -> AcctType -> Maybe String -> BankAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tag -> Err String
required "BANKID" Tag
t
      Either
  String
  (Maybe String -> String -> AcctType -> Maybe String -> BankAcctTo)
-> Either String (Maybe String)
-> Either String (String -> AcctType -> Maybe String -> BankAcctTo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "BRANCHID" Tag
t)
      Either String (String -> AcctType -> Maybe String -> BankAcctTo)
-> Err String
-> Either String (AcctType -> Maybe String -> BankAcctTo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> Tag -> Err String
required "ACCTID" Tag
t
      Either String (AcctType -> Maybe String -> BankAcctTo)
-> Err AcctType -> Either String (Maybe String -> BankAcctTo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Tag -> Err String
required "ACCTTYPE" Tag
t Err String -> (String -> Err AcctType) -> Err AcctType
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Err AcctType
acctType)
      Either String (Maybe String -> BankAcctTo)
-> Either String (Maybe String) -> Either String BankAcctTo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "ACCTKEY" Tag
t)

ccAcctTo :: Tag -> Maybe (Err CCAcctTo)
ccAcctTo :: Tag -> Maybe (Either String CCAcctTo)
ccAcctTo = (Tag -> Either String CCAcctTo)
-> Maybe Tag -> Maybe (Either String CCAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tag -> Either String CCAcctTo
getTo (Maybe Tag -> Maybe (Either String CCAcctTo))
-> (Tag -> Maybe Tag) -> Tag -> Maybe (Either String CCAcctTo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tag] -> Maybe Tag
forall a. [a] -> Maybe a
listToMaybe ([Tag] -> Maybe Tag) -> (Tag -> [Tag]) -> Tag -> Maybe Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "CCACCTTO"
  where
    getTo :: Tag -> Either String CCAcctTo
getTo t :: Tag
t = String -> Maybe String -> CCAcctTo
CCAcctTo
      (String -> Maybe String -> CCAcctTo)
-> Err String -> Either String (Maybe String -> CCAcctTo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tag -> Err String
required "ACCTID" Tag
t
      Either String (Maybe String -> CCAcctTo)
-> Either String (Maybe String) -> Either String CCAcctTo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe String -> Either String (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Tag -> Maybe String
findData "ACCTKEY" Tag
t)

safeRead :: Read a => String -> Maybe a
safeRead :: String -> Maybe a
safeRead s :: String
s = case ReadS a
forall a. Read a => ReadS a
reads String
s of
  (x :: a
x, ""):[] -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
  _ -> Maybe a
forall a. Maybe a
Nothing


-- | Pulls all Transactions from a file. Might fail if the OFX file
-- does not conform to the specification (or if there are bugs in this
-- library.) In case of the former, you can manually parse the
-- transaction information yourself using functions like
-- 'pathData'. In case of the latter, please send bugreports :-)
transactions :: OFXFile -> Err [Transaction]
transactions :: OFXFile -> Err [Transaction]
transactions = (Tag -> Err Transaction) -> [Tag] -> Err [Transaction]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Tag -> Err Transaction
transaction ([Tag] -> Err [Transaction])
-> (OFXFile -> [Tag]) -> OFXFile -> Err [Transaction]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Tag -> [Tag]
find "STMTTRN" (Tag -> [Tag]) -> (OFXFile -> Tag) -> OFXFile -> [Tag]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OFXFile -> Tag
fTag

--
-- # Pretty printers
--
pPayee :: Payee -> Doc
pPayee :: Payee -> Doc
pPayee p :: Payee
p = Doc -> Int -> Doc -> Doc
hang "Payee:" 2 Doc
ls
  where
    ls :: Doc
ls = [Doc] -> Doc
sep [ String -> Doc -> Doc
label "Name" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
peNAME (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Addr1" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
peADDR1 (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Addr2" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc) -> (Payee -> Maybe String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> Maybe String
peADDR2 (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Addr3" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc) -> (Payee -> Maybe String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> Maybe String
peADDR3 (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "City" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
peCITY (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "State" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
peSTATE (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Postal" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
pePOSTALCODE (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Country" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc) -> (Payee -> Maybe String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> Maybe String
peCOUNTRY (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             , String -> Doc -> Doc
label "Phone" (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
pePHONE (Payee -> Doc) -> Payee -> Doc
forall a b. (a -> b) -> a -> b
$ Payee
p)
             ]

pTransaction :: Transaction -> Doc
pTransaction :: Transaction -> Doc
pTransaction a :: Transaction
a = Doc -> Int -> Doc -> Doc
hang "Transaction:" 2 Doc
ls
  where
    ls :: Doc
ls = [Doc] -> Doc
sep [ String -> Doc -> Doc
label "TRNTYPE" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TrnType -> String
forall a. Show a => a -> String
show (TrnType -> String)
-> (Transaction -> TrnType) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> TrnType
txTRNTYPE (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "DTPOSTED" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> String
forall a. Show a => a -> String
show (ZonedTime -> String)
-> (Transaction -> ZonedTime) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> ZonedTime
txDTPOSTED (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "DTUSER" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe ZonedTime -> String
forall a. Show a => a -> String
show (Maybe ZonedTime -> String)
-> (Transaction -> Maybe ZonedTime) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe ZonedTime
txDTUSER (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "DTAVAIL" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe ZonedTime -> String
forall a. Show a => a -> String
show (Maybe ZonedTime -> String)
-> (Transaction -> Maybe ZonedTime) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe ZonedTime
txDTAVAIL (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "TRNAMT" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> String
txTRNAMT (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "FITID" (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> String
txFITID (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "CORRECTFITID"
               ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txCORRECTFITID (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "CORRECTACTION"
               (String -> Doc
text (String -> Doc) -> (Transaction -> String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe CorrectAction -> String
forall a. Show a => a -> String
show (Maybe CorrectAction -> String)
-> (Transaction -> Maybe CorrectAction) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe CorrectAction
txCORRECTACTION (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "SRVRTID" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txSRVRTID (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "CHECKNUM" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txCHECKNUM (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "REFNUM" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txREFNUM (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "SIC" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txSIC (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "PAYEEID" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txPAYEEID (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "PAYEEINFO"
               ((Either String Payee -> Doc) -> Maybe (Either String Payee) -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe ((String -> Doc) -> (Payee -> Doc) -> Either String Payee -> Doc
forall a b. (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pEither String -> Doc
text (String -> Doc
text (String -> Doc) -> (Payee -> String) -> Payee -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Payee -> String
forall a. Show a => a -> String
show)) (Maybe (Either String Payee) -> Doc)
-> (Transaction -> Maybe (Either String Payee))
-> Transaction
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe (Either String Payee)
txPayeeInfo (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "ACCOUNTTO"
               ((Doc -> Doc) -> Maybe Doc -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe Doc -> Doc
forall a. a -> a
id (Maybe Doc -> Doc)
-> (Transaction -> Maybe Doc) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either BankAcctTo CCAcctTo -> Doc)
-> Maybe (Either BankAcctTo CCAcctTo) -> Maybe Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Doc
text (String -> Doc)
-> (Either BankAcctTo CCAcctTo -> String)
-> Either BankAcctTo CCAcctTo
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either BankAcctTo CCAcctTo -> String
forall a. Show a => a -> String
show)
                          (Maybe (Either BankAcctTo CCAcctTo) -> Maybe Doc)
-> (Transaction -> Maybe (Either BankAcctTo CCAcctTo))
-> Transaction
-> Maybe Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe (Either BankAcctTo CCAcctTo)
txAccountTo (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "MEMO" ((String -> Doc) -> Maybe String -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe String -> Doc
text (Maybe String -> Doc)
-> (Transaction -> Maybe String) -> Transaction -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe String
txMEMO (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             , String -> Doc -> Doc
label "CURRENCY"
               ((Either Currency OrigCurrency -> Doc)
-> Maybe (Either Currency OrigCurrency) -> Doc
forall a. (a -> Doc) -> Maybe a -> Doc
pMaybe (String -> Doc
text (String -> Doc)
-> (Either Currency OrigCurrency -> String)
-> Either Currency OrigCurrency
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either Currency OrigCurrency -> String
forall a. Show a => a -> String
show) (Maybe (Either Currency OrigCurrency) -> Doc)
-> (Transaction -> Maybe (Either Currency OrigCurrency))
-> Transaction
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Maybe (Either Currency OrigCurrency)
txCurrency (Transaction -> Doc) -> Transaction -> Doc
forall a b. (a -> b) -> a -> b
$ Transaction
a)
             ]

pTag :: Tag -> Doc
pTag :: Tag -> Doc
pTag (Tag n :: String
n ei :: Either String [Tag]
ei) = case Either String [Tag]
ei of
  Left d :: String
d -> "<" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
n Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> ">" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
d
  Right ts :: [Tag]
ts -> [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ "<" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
n Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> ">"
                   Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: (Tag -> Doc) -> [Tag] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Doc -> Doc
nest 2 (Doc -> Doc) -> (Tag -> Doc) -> Tag -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tag -> Doc
pTag) [Tag]
ts
                   [Doc] -> [Doc] -> [Doc]
forall a. [a] -> [a] -> [a]
++ ["</" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
n Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> ">"]

pHeader :: OFXHeader -> Doc
pHeader :: OFXHeader -> Doc
pHeader (OFXHeader t :: String
t v :: String
v) = String -> Doc
text String
t Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> ": " Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
v

pFile :: OFXFile -> Doc
pFile :: OFXFile -> Doc
pFile (OFXFile hs :: [OFXHeader]
hs t :: Tag
t)
  = "OFX file:"
  Doc -> Doc -> Doc
$$ Int -> Doc -> Doc
nest 2 ([Doc] -> Doc
vcat [ [Doc] -> Doc
pList ([Doc] -> Doc) -> ([OFXHeader] -> [Doc]) -> [OFXHeader] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OFXHeader -> Doc) -> [OFXHeader] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map OFXHeader -> Doc
pHeader ([OFXHeader] -> Doc) -> [OFXHeader] -> Doc
forall a b. (a -> b) -> a -> b
$ [OFXHeader]
hs
                   , Doc
forall a. Monoid a => a
mempty
                   , Tag -> Doc
pTag Tag
t ])

pEither :: (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pEither :: (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pEither fa :: a -> Doc
fa fb :: b -> Doc
fb = (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\l :: a
l -> "Left" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (a -> Doc
fa a
l))
                       (\r :: b
r -> "Right" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (b -> Doc
fb b
r))

pMaybe :: (a -> Doc) -> Maybe a -> Doc
pMaybe :: (a -> Doc) -> Maybe a -> Doc
pMaybe f :: a -> Doc
f = Doc -> (a -> Doc) -> Maybe a -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "Nothing" (\x :: a
x -> "Just" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (a -> Doc
f a
x))

pList :: [Doc] -> Doc
pList :: [Doc] -> Doc
pList ds :: [Doc]
ds = case [Doc]
ds of
  [] -> "[]"
  x :: Doc
x:[] -> Doc -> Doc
brackets Doc
x
  x :: Doc
x:xs :: [Doc]
xs -> [Doc] -> Doc
sep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> Int -> Doc -> Doc
hang "[" 2 Doc
x
              Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: (Doc -> Doc) -> [Doc] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\d :: Doc
d -> Doc -> Int -> Doc -> Doc
hang "," 2 Doc
d) [Doc]
xs
              [Doc] -> [Doc] -> [Doc]
forall a. [a] -> [a] -> [a]
++ [ "]" ]

label :: String -> Doc -> Doc
label :: String -> Doc -> Doc
label s :: String
s = Doc -> Int -> Doc -> Doc
hang (String -> Doc
text (String
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ ":")) (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)

pExceptional
  :: (e -> Doc)
  -> (a -> Doc)
  -> Either e a
  -> Doc
pExceptional :: (e -> Doc) -> (a -> Doc) -> Either e a -> Doc
pExceptional fe :: e -> Doc
fe fa :: a -> Doc
fa =
  (e -> Doc) -> (a -> Doc) -> Either e a -> Doc
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e :: e
e -> Doc -> Int -> Doc -> Doc
hang "Exception:" 2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> Doc
parens (e -> Doc
fe e
e))
         (\g :: a
g -> Doc -> Int -> Doc -> Doc
hang "Success:" 2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> Doc
parens (a -> Doc
fa a
g))

-- # Running Parsers

-- | Parses an input file.  Returns either an error message or the
-- resulting 'OFXFile'.
parseOfxFile :: String -> Err OFXFile
parseOfxFile :: String -> Err OFXFile
parseOfxFile = (ParseError -> Err OFXFile)
-> (OFXFile -> Err OFXFile)
-> Either ParseError OFXFile
-> Err OFXFile
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Err OFXFile
forall a b. a -> Either a b
Left (String -> Err OFXFile)
-> (ParseError -> String) -> ParseError -> Err OFXFile
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> String
forall a. Show a => a -> String
show) (OFXFile -> Err OFXFile
forall a b. b -> Either a b
Right (OFXFile -> Err OFXFile)
-> (OFXFile -> OFXFile) -> OFXFile -> Err OFXFile
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OFXFile -> OFXFile
forall a. a -> a
id) (Either ParseError OFXFile -> Err OFXFile)
-> (String -> Either ParseError OFXFile) -> String -> Err OFXFile
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser OFXFile -> String -> String -> Either ParseError OFXFile
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse Parser OFXFile
ofxFile ""

-- | Parses an OFX file and gets the list of 'Transaction'.
parseTransactions :: String -> Err [Transaction]
parseTransactions :: String -> Err [Transaction]
parseTransactions = OFXFile -> Err [Transaction]
transactions (OFXFile -> Err [Transaction])
-> (String -> Err OFXFile) -> String -> Err [Transaction]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Err OFXFile
parseOfxFile

-- | Loads an OFX file from disk, parses it, and returns the
-- resulting 'OFXFile'.  Uses 'fail' if the parse fails.
loadOfxFile :: FilePath -> IO OFXFile
loadOfxFile :: String -> IO OFXFile
loadOfxFile fp :: String
fp = do
  String
txt <- String -> IO String
readFile String
fp
  case String -> Err OFXFile
parseOfxFile String
txt of
    Left e :: String
e -> String -> IO OFXFile
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
e
    Right g :: OFXFile
g -> OFXFile -> IO OFXFile
forall (m :: * -> *) a. Monad m => a -> m a
return OFXFile
g

-- | Loads an OFX file from disk, parses it, and returns the resulting list of
-- 'Transaction'.  Uses 'fail' if the parse fails.
loadTransactions :: FilePath -> IO [Transaction]
loadTransactions :: String -> IO [Transaction]
loadTransactions fp :: String
fp = do
  String
txt <- String -> IO String
readFile String
fp
  case String -> Err [Transaction]
parseTransactions String
txt of
    Left e :: String
e -> String -> IO [Transaction]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
e
    Right g :: [Transaction]
g -> [Transaction] -> IO [Transaction]
forall (m :: * -> *) a. Monad m => a -> m a
return [Transaction]
g

-- # Parsing and pretty printing

-- | Parses an input file to an OfxFile.  Returns a pretty-printed
-- string with the results of the parse.
prettyRenderOfxFile
  :: String
  -- ^ File contents to parse
  -> String
  -- ^ Pretty printed result of rending the result of the parse, which
  -- is either an error message or an 'OFXFile'.
prettyRenderOfxFile :: ShowS
prettyRenderOfxFile
  = Doc -> String
render
  (Doc -> String) -> (String -> Doc) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Doc) -> (OFXFile -> Doc) -> Err OFXFile -> Doc
forall a b. (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pExceptional String -> Doc
text OFXFile -> Doc
pFile
  (Err OFXFile -> Doc) -> (String -> Err OFXFile) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Err OFXFile
parseOfxFile

-- | Parses an input file to an OfxFile, and then to a list of
-- 'Transaction'.  Returns a pretty-printed string with the results.
prettyRenderTransactions
  :: String
  -- ^ File contents to parse
  -> String
  -- ^ Pretty printed result of rendering the result of the parse,
  -- which is either an error message or a list of 'Transaction'.
prettyRenderTransactions :: ShowS
prettyRenderTransactions
  = Doc -> String
render
  (Doc -> String) -> (String -> Doc) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Doc)
-> ([Transaction] -> Doc) -> Err [Transaction] -> Doc
forall a b. (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pExceptional String -> Doc
text ([Doc] -> Doc
pList ([Doc] -> Doc) -> ([Transaction] -> [Doc]) -> [Transaction] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Transaction -> Doc) -> [Transaction] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Transaction -> Doc
pTransaction)
  (Err [Transaction] -> Doc)
-> (String -> Err [Transaction]) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Err [Transaction]
parseTransactions