{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} module CoinbasePro.Authenticated.Report ( ReportId (..) , ReportRequest (..) , ReportResponse (..) , FillsReportRequest , AccountsReportRequest , accountsReportRequest , fillsReportRequest ) where import Data.Aeson (ToJSON (..), object, (.=)) import Data.Aeson.Casing (snakeCase) import Data.Aeson.TH (constructorTagModifier, defaultOptions, deriveJSON, fieldLabelModifier, unwrapUnaryRecords) import qualified Data.Char as Char import Data.Text (Text) import Data.Time.Clock (UTCTime) import Data.UUID (UUID) import Servant.API (ToHttpApiData) import CoinbasePro.Authenticated.Accounts (AccountId) import CoinbasePro.Types (CreatedAt, ProductId) newtype ReportId = ReportId { unReportId:: UUID } deriving (Eq, Show, ToHttpApiData) deriveJSON defaultOptions { fieldLabelModifier = snakeCase , unwrapUnaryRecords = True } ''ReportId data ReportFormat = PDF | CSV deriving Show deriveJSON defaultOptions { constructorTagModifier = fmap Char.toLower } ''ReportFormat newtype Email = Email Text deriving Show deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''Email data Request = Request { rStartDate :: UTCTime , rEndDate :: UTCTime , rFormat :: Maybe ReportFormat , rEmail :: Maybe Email } deriving Show data FillsReportRequest = FillsReportRequest { frProductId :: ProductId , frAccountId :: Maybe AccountId , frRequest :: Request } deriving Show data AccountsReportRequest = AccountsReportRequest { arAccountId :: AccountId , arProductId :: Maybe ProductId , arRequest :: Request } deriving Show data ReportRequest = Fills FillsReportRequest | Accounts AccountsReportRequest deriving Show accountsReportRequest :: AccountId -> Maybe ProductId -- ^ start date -> UTCTime -- ^ end date -> UTCTime -- ^ pdf or csv -> Maybe ReportFormat -> Maybe Email -> ReportRequest accountsReportRequest aid prid start end format = Accounts . AccountsReportRequest aid prid . Request start end format fillsReportRequest :: ProductId -> Maybe AccountId -- ^ start date -> UTCTime -- ^ end date -> UTCTime -- ^ pdf or csv -> Maybe ReportFormat -> Maybe Email -> ReportRequest fillsReportRequest prid aid start end format = Fills . FillsReportRequest prid aid . Request start end format instance ToJSON ReportRequest where toJSON (Fills frr) = object ([ "type" .= ("fills" :: Text) , "start_date" .= rStartDate (frRequest frr) , "end_date" .= rEndDate (frRequest frr) , "product_id" .= frProductId frr ] <> maybe mempty (\aid -> ["account_id" .= aid]) (frAccountId frr) <> maybe mempty (\em -> ["email" .= em]) (rEmail (frRequest frr)) <> maybe mempty (\fmt -> ["format" .= fmt]) (rFormat (frRequest frr)) ) toJSON (Accounts arr) = object ([ "type" .= ("account" :: Text) , "start_date" .= rStartDate (arRequest arr) , "end_date" .= rEndDate (arRequest arr) , "account_id" .= arAccountId arr ] <> maybe mempty (\prid -> ["product_id" .= prid]) (arProductId arr) <> maybe mempty (\em -> ["email" .= em]) (rEmail (arRequest arr)) <> maybe mempty (\fmt -> ["format" .= fmt]) (rFormat (arRequest arr)) ) data ReportRequestType = FillsType | AccountType instance Show ReportRequestType where show FillsType = "fills" show AccountType = "account" deriveJSON defaultOptions { constructorTagModifier = snakeCase . init . init . init . init } ''ReportRequestType data ReportStatus = Pending | Creating | Ready instance Show ReportStatus where show Pending = "pending" show Creating = "creating" show Ready = "ready" deriveJSON defaultOptions { constructorTagModifier = fmap Char.toLower , fieldLabelModifier = snakeCase } ''ReportStatus data ReportParams = ReportParams { startDate :: UTCTime , endDate :: UTCTime } deriving Show deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''ReportParams {-| Example JSON Response: { "id": "0428b97b-bec1-429e-a94c-59232926778d", "type": "fills", "status": "pending", "created_at": "2015-01-06T10:34:47.000Z", "completed_at": undefined, "expires_at": "2015-01-13T10:35:47.000Z", "file_url": undefined, "params": { "start_date": "2014-11-01T00:00:00.000Z", "end_date": "2014-11-30T23:59:59.000Z" } } -} data ReportResponse = ReportResponse { rrId :: ReportId , rrType :: ReportRequestType , rrStatus :: ReportStatus , rrCreatedAt :: Maybe CreatedAt , rrCompletedAt :: Maybe UTCTime , rrExpiresAt :: Maybe UTCTime , rrFileUrl :: Maybe Text , rrParams :: Maybe ReportParams } deriving Show deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 2 } ''ReportResponse