{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE PolyKinds #-} ------------------------------------------------------------------------------ -- | -- Module : QuickBooks.Requests -- Description : -- Copyright : -- License : -- Maintainer : -- Stability : -- Portability : -- -- -- ------------------------------------------------------------------------------ module QuickBooks.Invoice ( createInvoiceRequest , readInvoiceRequest , updateInvoiceRequest , deleteInvoiceRequest , sendInvoiceRequest ) where import Data.Aeson (encode, eitherDecode, object, Value(String)) import Data.String.Interpolate (i) import Network.HTTP.Client (httpLbs ,parseUrl ,Request(..) ,RequestBody(..) ,Response(responseBody)) import Network.HTTP.Types.Header (hAccept,hContentType) import QuickBooks.Authentication (oauthSignRequest) import QuickBooks.Types (APIConfig(..) ,Invoice ,InvoiceId(..) ,QuickBooksResponse ,SyncToken(..) ,DeletedInvoice(..) ,OAuthToken ,APIEnv) import Text.Email.Validate (EmailAddress, toByteString) import QuickBooks.Logging (logAPICall) -- | Create an invoice. createInvoiceRequest :: APIEnv => OAuthToken -> Invoice -> IO (Either String (QuickBooksResponse Invoice)) createInvoiceRequest tok = postInvoice tok -- | Update an invoice. updateInvoiceRequest :: APIEnv => OAuthToken -> Invoice -> IO (Either String (QuickBooksResponse Invoice)) updateInvoiceRequest tok = postInvoice tok -- | Read an invoice. readInvoiceRequest :: APIEnv => OAuthToken -> InvoiceId -> IO (Either String (QuickBooksResponse Invoice)) readInvoiceRequest tok iId = do let apiConfig = ?apiConfig req <- oauthSignRequest tok =<< parseUrl [i|#{invoiceURITemplate apiConfig}#{unInvoiceId iId}|] let oauthHeaders = requestHeaders req let req' = req{method = "GET", requestHeaders = oauthHeaders ++ [(hAccept, "application/json")]} resp <- httpLbs req' ?manager logAPICall req' return $ eitherDecode $ responseBody resp -- | Delete an invoice. deleteInvoiceRequest :: APIEnv => OAuthToken -> InvoiceId -> SyncToken -> IO (Either String (QuickBooksResponse DeletedInvoice)) deleteInvoiceRequest tok iId syncToken = do let apiConfig = ?apiConfig req <- parseUrl [i|#{invoiceURITemplate apiConfig}?operation=delete|] req' <- oauthSignRequest tok req{ method = "POST" , requestBody = RequestBodyLBS $ encode body , requestHeaders = [ (hAccept, "application/json") , (hContentType, "application/json") ] } resp <- httpLbs req' ?manager logAPICall req' return $ eitherDecode $ responseBody resp where body = object [ ("Id", String (unInvoiceId iId)) , ("SyncToken", String (unSyncToken syncToken)) ] -- | email and invoice sendInvoiceRequest :: APIEnv => OAuthToken -> InvoiceId -> EmailAddress -> IO (Either String (QuickBooksResponse Invoice)) sendInvoiceRequest tok iId emailAddr = do let apiConfig = ?apiConfig req <- parseUrl [i|#{invoiceURITemplate apiConfig}#{unInvoiceId iId}/send?sendTo=#{toByteString emailAddr}|] req' <- oauthSignRequest tok req{ method = "POST" , requestHeaders = [ (hAccept, "application/json") ] } logAPICall req' resp <- httpLbs req' ?manager return $ eitherDecode $ responseBody resp invoiceURITemplate :: APIConfig -> String invoiceURITemplate APIConfig{..} = [i|https://#{hostname}/v3/company/#{companyId}/invoice/|] postInvoice :: APIEnv => OAuthToken -> Invoice -> IO (Either String (QuickBooksResponse Invoice)) postInvoice tok invoice = do let apiConfig = ?apiConfig req <- parseUrl [i|#{invoiceURITemplate apiConfig}|] req' <- oauthSignRequest tok req{ method = "POST" , requestBody = RequestBodyLBS $ encode invoice , requestHeaders = [ (hAccept, "application/json") , (hContentType, "application/json") ] } resp <- httpLbs req' ?manager logAPICall req' return $ eitherDecode $ responseBody resp