-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Parser for OFX data
--   
--   A parser for Open Financial Exchange (OFX) financial data. This
--   handles OFX version 1.03, which is documented at
--   http://www.ofx.net This also handles QFX, which is OFX plus
--   some minor additions made by Intuit, the publishers of Quicken.
--   
--   The parser will place all the data into a tree, which you can query
--   for whatever data you may need, although you will need to be familiar
--   with the OFX spec to do this. There is also a Transaction type which
--   you can easily parse from the tree; this will contain most, if not
--   all, of the data you will be interested in if your OFX file is from a
--   bank or credit card account.
--   
--   All the OFX and QFX files I have seen use the format from the 1.0
--   series of OFX, which is primarily SGML based. OFX version 2 is XML
--   based. If this parser works on those files, consider it a happy
--   accident.
--   
--   The OFX spec is available at http://www.ofx.net
@package ofx
@version 0.4.0.4

-- | 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.
--   
--   For example, to read in the filename given on the command line and
--   parse it and print it nicely:
--   
--   
--   import System.Environment
--   import Text.Parsec
--   import Text.PrettyPrint
--   import Data.OFX
--   import System.IO
--   import System.Exit
--   
--   main :: IO ()
--   main = do
--     filename:[] <- getArgs
--     contents <- readFile filename
--     ofx <- case parse ofxFile filename contents of
--       Left e -> do
--         hPutStrLn stderr . show $ e
--         exitFailure
--       Right g -> return g
--     putStrLn . render . pFile $ ofx
--     putStrLn
--       . render
--       . pExceptional text (pList . map pTransaction)
--       . transactions
--       $ ofx
--     putStrLn . render . pMaybe text . fiName $ ofx
--     putStrLn . render . pMaybe text . accountNumber $ ofx
--   
module Data.OFX

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

-- | 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 -> OFXHeader

-- | 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]) -> Tag

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

-- | All the data will be contained in a root tag with the TagName
--   OFX.
[fTag] :: OFXFile -> Tag

-- | 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]

-- | 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

-- | Gets the data from a tag, if it is a tag with data.
tagData :: Tag -> Maybe TagData

-- | 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

-- | 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

-- | 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

-- | Gets the credit card number, if available. The OFX spec does not
--   require this tag to be present.
creditCardNumber :: OFXFile -> Maybe TagData

-- | Gets the bank account number, if available. The OFX spec does not
--   require this tag to be present.
bankAccountNumber :: OFXFile -> Maybe TagData

-- | Gets either the credit card or bank account number, if available.
accountNumber :: OFXFile -> Maybe TagData

-- | 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 :: 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 type
[txTRNTYPE] :: Transaction -> TrnType

-- | Date transaction was posted to account
[txDTPOSTED] :: Transaction -> ZonedTime

-- | Date user initiated transaction, if known
[txDTUSER] :: Transaction -> Maybe ZonedTime

-- | Date funds are available
[txDTAVAIL] :: Transaction -> Maybe ZonedTime

-- | 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.
[txTRNAMT] :: Transaction -> String

-- | Transaction ID issued by financial institution. Used to detect
--   duplicate downloads.
[txFITID] :: Transaction -> 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.
[txCORRECTFITID] :: Transaction -> Maybe String

-- | See CorrectAction and txCORRECTFITID
[txCORRECTACTION] :: Transaction -> Maybe CorrectAction

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

-- | Check or other reference number
[txCHECKNUM] :: Transaction -> Maybe String

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

-- | Standard Industrial Code
[txSIC] :: Transaction -> Maybe String

-- | Payee identifier if available
[txPAYEEID] :: Transaction -> Maybe String

-- | 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.
[txPayeeInfo] :: Transaction -> Maybe (Either String Payee)

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

-- | Extra information not in NAME
[txMEMO] :: Transaction -> Maybe String

-- | Currency option. OFX spec says to choose either CURRENCY or
--   ORIGCURRENCY.
[txCurrency] :: Transaction -> Maybe (Either Currency OrigCurrency)

-- | 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

-- | 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]

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

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

-- | Dividend
TDIV :: TrnType
TFEE :: TrnType
TSRVCHG :: TrnType

-- | Deposit
TDEP :: TrnType

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

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

-- | Transfer
TXFER :: TrnType
TCHECK :: TrnType

-- | Electronic payment
TPAYMENT :: TrnType

-- | Cash withdrawal
TCASH :: TrnType

-- | Direct deposit
TDIRECTDEP :: TrnType

-- | Merchant initiated debit
TDIRECTDEBIT :: TrnType

-- | Repeating payment / standing order
TREPEATPMT :: TrnType
TOTHER :: TrnType
trnType :: TagData -> Maybe TrnType
data Payee
Payee :: String -> String -> Maybe String -> Maybe String -> String -> String -> String -> Maybe String -> String -> Payee
[peNAME] :: Payee -> String
[peADDR1] :: Payee -> String
[peADDR2] :: Payee -> Maybe String
[peADDR3] :: Payee -> Maybe String
[peCITY] :: Payee -> String
[peSTATE] :: Payee -> String
[pePOSTALCODE] :: Payee -> String
[peCOUNTRY] :: Payee -> Maybe String
[pePHONE] :: Payee -> String

-- | Parses a Payee record from its parent tag.
payee :: Tag -> Maybe (Err Payee)

-- | Can be either REPLACE or DELETE.
data CorrectAction

-- | Replaces the transaction referenced by the CORRECTFITID
REPLACE :: CorrectAction

-- | Deletes the transaction referenced by the CORRECTFITID
DELETE :: CorrectAction
data BankAcctTo
BankAcctTo :: String -> Maybe String -> String -> AcctType -> Maybe String -> BankAcctTo

-- | Routing and transit number
[btBANKID] :: BankAcctTo -> String

-- | Bank identifier for international banks
[btBRANCHID] :: BankAcctTo -> Maybe String

-- | Account number
[btACCTID] :: BankAcctTo -> String

-- | Type of account
[btACCTTYPE] :: BankAcctTo -> AcctType

-- | Checksum for international banks
[btACCTKEY] :: BankAcctTo -> Maybe String
bankAcctTo :: Tag -> Maybe (Err BankAcctTo)
data CCAcctTo
CCAcctTo :: String -> Maybe String -> CCAcctTo

-- | Account number
[ctACCTID] :: CCAcctTo -> String

-- | Checksum for international banks
[ctACCTKEY] :: CCAcctTo -> Maybe String
ccAcctTo :: Tag -> Maybe (Err CCAcctTo)
data AcctType
ACHECKING :: AcctType
ASAVINGS :: AcctType
AMONEYMRKT :: AcctType
ACREDITLINE :: AcctType
acctType :: String -> Err AcctType

-- | Holds all data both for CURRENCY and for ORIGCURRENCY.
data CurrencyData
CurrencyData :: String -> String -> CurrencyData

-- | Ratio of CURDEF currency to CURSYM currency, in decimal form
[cdCURRATE] :: CurrencyData -> String

-- | ISO-4217 3-letter currency identifier
[cdCURSYM] :: CurrencyData -> String

-- | Parses currency data.
currencyData :: Tag -> Err CurrencyData
data Currency
Currency :: CurrencyData -> Currency
currency :: Tag -> Maybe (Err Currency)
data OrigCurrency
OrigCurrency :: CurrencyData -> OrigCurrency
origCurrency :: Tag -> Maybe (Err OrigCurrency)

-- | Parses an entire OFX file, including headers.
ofxFile :: Parser OFXFile

-- | 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 ()

-- | 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
header :: Parser OFXHeader

-- | Parses any opening tag. Returns the name of the tag.
openingTag :: Parser TagName

-- | Parses a closing tag with the given name.
closingTag :: TagName -> Parser ()

-- | 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

-- | Parses an OFX date. Fails if the date is not valid or if there is no
--   date to be parsed.
date :: Parser ZonedTime

-- | 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 (TimeOfDay, TimeZone)

-- | Parses a time zone offset. Fails if there is no time zone offset to
--   parse.
tzOffset :: Parser TimeZone
pPayee :: Payee -> Doc
pTransaction :: Transaction -> Doc
pTag :: Tag -> Doc
pHeader :: OFXHeader -> Doc
pFile :: OFXFile -> Doc
pEither :: (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
pMaybe :: (a -> Doc) -> Maybe a -> Doc
pList :: [Doc] -> Doc
label :: String -> Doc -> Doc
pExceptional :: (e -> Doc) -> (a -> Doc) -> Either e a -> Doc
instance GHC.Show.Show Data.OFX.Transaction
instance GHC.Show.Show Data.OFX.OrigCurrency
instance GHC.Classes.Eq Data.OFX.OrigCurrency
instance GHC.Show.Show Data.OFX.Currency
instance GHC.Classes.Eq Data.OFX.Currency
instance GHC.Show.Show Data.OFX.CurrencyData
instance GHC.Classes.Eq Data.OFX.CurrencyData
instance GHC.Show.Show Data.OFX.BankAcctTo
instance GHC.Classes.Ord Data.OFX.AcctType
instance GHC.Show.Show Data.OFX.AcctType
instance GHC.Classes.Eq Data.OFX.AcctType
instance GHC.Show.Show Data.OFX.CCAcctTo
instance GHC.Classes.Eq Data.OFX.CCAcctTo
instance GHC.Read.Read Data.OFX.CorrectAction
instance GHC.Show.Show Data.OFX.CorrectAction
instance GHC.Classes.Eq Data.OFX.CorrectAction
instance GHC.Show.Show Data.OFX.Payee
instance GHC.Classes.Eq Data.OFX.Payee
instance GHC.Show.Show Data.OFX.TrnType
instance GHC.Classes.Ord Data.OFX.TrnType
instance GHC.Classes.Eq Data.OFX.TrnType
instance GHC.Show.Show Data.OFX.OFXFile
instance GHC.Classes.Eq Data.OFX.OFXFile
instance GHC.Show.Show Data.OFX.Tag
instance GHC.Classes.Eq Data.OFX.Tag
instance GHC.Show.Show Data.OFX.OFXHeader
instance GHC.Classes.Eq Data.OFX.OFXHeader
