module Network.Payments.PayPal.Types.Transaction
( Details(..)
, Amount(..)
, Item(..)
, ItemList(..)
, Transaction(..)
) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif
import Control.Monad
import Data.Aeson
import Data.Aeson.Types
import Data.Maybe
import qualified Data.Text as T
import Network.Payments.PayPal.Types.Address
import Network.Payments.PayPal.Types.Currency
data Details = Details
{ detailsShipping :: MonetaryAmount
, detailsSubtotal :: MonetaryAmount
, detailsTax :: MonetaryAmount
} deriving (Eq, Show)
instance ToJSON Details where
toJSON details =
object ["shipping" .= detailsShipping details,
"subtotal" .= detailsSubtotal details,
"tax" .= detailsTax details]
instance FromJSON Details where
parseJSON (Object obj) =
Details <$>
obj .: "shipping" <*>
obj .: "subtotal" <*>
obj .: "tax"
parseJSON _ = mzero
data Amount = Amount
{ amountCurrency :: Currency
, amountTotal :: MonetaryAmount
, amountDetails :: Details
} deriving (Eq, Show)
instance ToJSON Amount where
toJSON amt =
object ["currency" .= amountCurrency amt,
"total" .= amountTotal amt,
"details" .= amountDetails amt]
instance FromJSON Amount where
parseJSON (Object obj) =
Amount <$>
obj .: "currency" <*>
obj .: "total" <*>
obj .: "details"
parseJSON _ = mzero
data Item = Item
{ itemQuantity :: Integer
, itemName :: String
, itemPrice :: MonetaryAmount
, itemCurrency :: Currency
, itemSku :: String
, itemDescription :: Maybe String
} deriving (Eq, Show)
instance ToJSON Item where
toJSON item =
object (["quantity" .= itemQuantity item,
"name" .= itemName item,
"price" .= itemPrice item,
"currency" .= itemCurrency item,
"sku" .= itemSku item] ++
maybeToList (("description" .=) <$> itemDescription item))
instance FromJSON Item where
parseJSON (Object obj) =
Item <$>
(obj .: "quantity" >>= parseFuzzyJSONInt) <*>
obj .: "name" <*>
obj .: "price" <*>
obj .: "currency" <*>
obj .: "sku" <*>
obj .:? "description"
parseJSON _ = mzero
data ItemList = ItemList
{ itemListItems :: [Item]
, itemListShippingAddress :: Maybe ShippingAddress
} deriving (Eq, Show)
instance ToJSON ItemList where
toJSON list =
object (["items" .= itemListItems list] ++
maybeToList (("shipping_address" .=) <$>
itemListShippingAddress list))
instance FromJSON ItemList where
parseJSON (Object obj) =
ItemList <$>
obj .: "items" <*>
obj .:? "shipping_address"
parseJSON _ = mzero
data Transaction = Transaction
{ transactAmount :: Amount
, transactDescription :: Maybe String
, transactItemList :: ItemList
} deriving (Eq, Show)
instance ToJSON Transaction where
toJSON trans =
object (["amount" .= transactAmount trans,
"item_list" .= transactItemList trans] ++
maybeToList (("description" .=) <$> transactDescription trans))
instance FromJSON Transaction where
parseJSON (Object obj) =
Transaction <$>
obj .: "amount" <*>
obj .:? "description" <*>
obj .: "item_list"
parseJSON _ = mzero
parseFuzzyJSONInt :: (Integral a, Read a) => Value -> Parser a
parseFuzzyJSONInt (String txt) = return $ read $ T.unpack txt
parseFuzzyJSONInt (Number num) = return $ round num
parseFuzzyJSONInt _ = mzero