module Mondo.Types where
import GHC.Generics
import Control.Monad (mzero)
import Data.Aeson
import Data.Aeson.Types (emptyObject)
import qualified Data.Text as T
import qualified Data.Map as M
import Data.Monoid ((<>))
import Servant.API
data Empty = Empty
instance FromJSON Empty where
parseJSON val
| val == emptyObject = pure Empty
| otherwise = mzero
toUnit :: Empty -> ()
toUnit _ = ()
type AccountID = String
type TransactionID = String
type WebhookID = String
newtype AttachmentID = AttID T.Text
deriving Show
instance FromJSON AttachmentID where
parseJSON (String v) = pure $ AttID v
parseJSON _ = mzero
instance ToFormUrlEncoded AttachmentID where
toFormUrlEncoded (AttID v) = [("id", v)]
data AccountsResponse = AccountsResponse {
accounts :: [Account]
} deriving (Show, Generic)
instance FromJSON AccountsResponse
data Account = Account {
id :: AccountID,
description :: String,
created :: String
} deriving (Show, Generic)
accountID :: Account -> String
accountID (Account x _ _) = x
instance FromJSON Account
data Balance = Balance {
balance :: Integer,
currency :: String,
spend_today :: Integer
} deriving (Show, Generic)
instance FromJSON Balance
data DeclineReason
= InsufficientFunds
| CardInactive
| CardBlocked
| Other
deriving Show
instance FromJSON DeclineReason where
parseJSON (String "INSUFFICIENT_FUNDS") = pure InsufficientFunds
parseJSON (String "CARD_INACTIVE") = pure CardInactive
parseJSON (String "CARD_BLOCKED") = pure CardBlocked
parseJSON (String "OTHER") = pure Other
parseJSON _ = mzero
data Address = Address {
addrAddress :: String,
addrCity :: String,
addrCountry :: String,
addrLatitude :: String,
addrLongitude :: String,
addrPostcode :: String,
addrRegion :: String
} deriving Show
instance FromJSON Address where
parseJSON (Object v) =
Address <$> v .: "address"
<*> v .: "city"
<*> v .: "country"
<*> v .: "latitude"
<*> v .: "longitude"
<*> v .: "postcode"
<*> v .: "region"
parseJSON _ = mzero
data Merchant = Merchant {
merchantAddress :: Maybe Address,
merchantCreated :: Maybe String,
merchantGroupID :: Maybe String,
merchantID :: String,
merchantLogo :: Maybe String,
merchantEmoji :: Maybe String,
merchantName :: Maybe String,
merchantCategory :: Maybe String
} deriving Show
instance FromJSON Merchant where
parseJSON (Object v) =
Merchant <$> v .: "address"
<*> v .: "created"
<*> v .: "group_id"
<*> v .: "id"
<*> v .: "logo"
<*> v .: "emoji"
<*> v .: "name"
<*> v .: "category"
parseJSON _ = mzero
data Transactions = Transactions {
transactions :: [Transaction]
} deriving (Show, Generic)
instance FromJSON Transactions
data TransactionResponse = TransactionResponse {
transaction :: Transaction
} deriving (Show, Generic)
instance FromJSON TransactionResponse
data Transaction = Transaction {
transactionAccountBalance :: Integer,
transactionAmount :: Integer,
transactionCreated :: String,
transactionCurrency :: String,
transactionDescription :: String,
transactionID :: TransactionID,
transactionDeclineReason :: Maybe DeclineReason,
transactionIsLoad :: Bool,
transactionSettled :: Bool,
transactionCategory :: Maybe String,
transactionMerchant :: Merchant,
transactionMetadata :: M.Map String String
} deriving Show
instance FromJSON Transaction where
parseJSON (Object v) =
Transaction <$> v .: "account_balance"
<*> v .: "amount"
<*> v .: "created"
<*> v .: "currency"
<*> v .: "description"
<*> v .: "id"
<*> v .: "decline_reason"
<*> v .: "is_load"
<*> v .: "settled"
<*> v .: "category"
<*> v .: "merchant"
<*> v .: "metadata"
parseJSON _ = mzero
data Metadata = Metadata { metadata :: M.Map String String }
instance ToFormUrlEncoded Metadata where
toFormUrlEncoded (Metadata d) =
[("metadata[" <> T.pack k <> "]", T.pack v) | (k,v) <- M.toList d]
data FeedItemType
= BasicItem
instance Show FeedItemType where
show BasicItem = "basic"
instance ToJSON FeedItemType where
toJSON BasicItem = String "basic"
data FeedItemParams
= BasicFeedItem {
itemTitle :: String,
itemImageURL :: String,
itemBody :: Maybe String,
itemBackgroundColour :: Maybe String,
itemTitleColour :: Maybe String,
itemBodyColour :: Maybe String
}
newBasicFeedItem :: String -> String -> FeedItemParams
newBasicFeedItem title url = BasicFeedItem {
itemTitle = title,
itemImageURL = url,
itemBody = Nothing,
itemBackgroundColour = Nothing,
itemTitleColour = Nothing,
itemBodyColour = Nothing
}
instance ToFormUrlEncoded FeedItemParams where
toFormUrlEncoded (BasicFeedItem {..}) =
[ ( "params[title]" , T.pack itemTitle )
, ( "params[image_url]", T.pack itemImageURL )
]
data FeedItem = FeedItem {
itemAccountID :: AccountID,
itemType :: FeedItemType,
itemParams :: FeedItemParams,
itemURL :: Maybe String
}
instance ToFormUrlEncoded FeedItem where
toFormUrlEncoded item =
[ ( "account_id", T.pack $ itemAccountID item )
, ( "type" , T.pack $ show $ itemType item )
] ++ toFormUrlEncoded (itemParams item)
data Webhooks = Webhooks {
webhooks :: [Webhook]
} deriving (Show, Generic)
instance FromJSON Webhooks
data Webhook = Webhook {
webhookAccountID :: AccountID,
webhookURL :: String,
webhookID :: Maybe WebhookID
} deriving Show
instance FromJSON Webhook where
parseJSON (Object v) =
Webhook <$> v .: "account_id"
<*> v .: "url"
<*> v .: "id"
parseJSON _ = mzero
instance ToFormUrlEncoded Webhook where
toFormUrlEncoded hook =
[ ( "account_id", T.pack $ webhookAccountID hook )
, ( "url" , T.pack $ webhookURL hook )
]
data FileUploadReq = FileUploadReq {
uploadFileName :: String,
uploadFileType :: String
}
instance ToFormUrlEncoded FileUploadReq where
toFormUrlEncoded req =
[ ( "file_name", T.pack $ uploadFileName req )
, ( "file_type", T.pack $ uploadFileType req )
]
data FileUploadRes = FileUploadRes {
uploadURL :: String,
uploadPostURL :: String
}
instance FromJSON FileUploadRes where
parseJSON (Object v) =
FileUploadRes <$> v .: "file_url"
<*> v .: "file_type"
parseJSON _ = mzero
data Attachment = Attachment {
attachmentTransaction :: TransactionID,
attachmentFileType :: String,
attachmentURL :: String,
attachmentID :: Maybe AttachmentID,
attachmentUserID :: Maybe String,
attachmentCreated :: Maybe String
} deriving Show
instance FromJSON Attachment where
parseJSON (Object v) =
Attachment <$> v .: "external_id"
<*> v .: "file_type"
<*> v .: "file_url"
<*> v .: "id"
<*> v .: "user_id"
<*> v .: "created"
parseJSON _ = mzero
instance ToFormUrlEncoded Attachment where
toFormUrlEncoded att =
[ ( "external_id", T.pack $ attachmentTransaction att )
, ( "file_url", T.pack $ attachmentURL att )
, ( "file_type", T.pack $ attachmentFileType att )
]