{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} module Owner where import Data.Aeson import qualified Data.Bson as B import Data.Maybe import qualified Data.Text as T import Data.Time.Clock import Data.Typeable import Database.MongoDB import GHC.Generics -- | Type to represent a ZGo shop owner/business data Owner = Owner { o_id :: Maybe ObjectId , oaddress :: T.Text , oname :: T.Text , ocurrency :: T.Text , otax :: Bool , otaxValue :: Double , ovat :: Bool , ovatValue :: Double , ofirst :: T.Text , olast :: T.Text , oemail :: T.Text , ostreet :: T.Text , ocity :: T.Text , ostate :: T.Text , opostal :: T.Text , ophone :: T.Text , owebsite :: T.Text , ocountry :: T.Text , opaid :: Bool , ozats :: Bool , oinvoices :: Bool , oexpiration :: UTCTime , opayconf :: Bool , oviewkey :: T.Text , ocrmToken :: T.Text } deriving (Eq, Show, Generic, Typeable) instance ToJSON Owner where toJSON (Owner i a n c t tV v vV f l e s ct st p ph w co paid zats inv eTs pc vk cT) = case i of Just oid -> object [ "_id" .= show oid , "address" .= a , "name" .= n , "currency" .= c , "tax" .= t , "taxValue" .= tV , "vat" .= v , "vatValue" .= vV , "first" .= f , "last" .= l , "email" .= e , "street" .= s , "city" .= ct , "state" .= st , "postal" .= p , "phone" .= ph , "website" .= w , "country" .= co , "paid" .= paid , "zats" .= zats , "invoices" .= inv , "expiration" .= eTs , "payconf" .= pc , "viewkey" .= vk , "crmToken" .= cT ] Nothing -> object [ "_id" .= ("" :: String) , "address" .= a , "name" .= n , "currency" .= c , "tax" .= t , "taxValue" .= tV , "vat" .= v , "vatValue" .= vV , "first" .= f , "last" .= l , "email" .= e , "street" .= s , "city" .= ct , "state" .= st , "postal" .= p , "phone" .= ph , "website" .= w , "country" .= co , "paid" .= paid , "zats" .= zats , "invoices" .= inv , "expiration" .= eTs , "payconf" .= pc , "viewkey" .= vk , "crmToken" .= cT ] instance FromJSON Owner where parseJSON = withObject "Owner" $ \obj -> do i <- obj .: "_id" a <- obj .: "address" n <- obj .: "name" c <- obj .: "currency" t <- obj .: "tax" tV <- obj .: "taxValue" v <- obj .: "vat" vV <- obj .: "vatValue" f <- obj .: "first" l <- obj .: "last" e <- obj .: "email" s <- obj .: "street" ct <- obj .: "city" st <- obj .: "state" p <- obj .: "postal" ph <- obj .: "phone" w <- obj .: "website" co <- obj .: "country" paid <- obj .: "paid" zats <- obj .: "zats" inv <- obj .: "invoices" ets <- obj .: "expiration" pc <- obj .:? "payconf" vk <- obj .:? "viewkey" cT <- obj .:? "crmToken" pure $ Owner (if not (null i) then Just (read i) else Nothing) a n c t tV v vV f l e s ct st p ph w co paid zats inv ets (fromMaybe False pc) (fromMaybe "" vk) (fromMaybe "" cT) instance Val Owner where cast' (Doc d) = do i <- B.lookup "_id" d a <- B.lookup "address" d n <- B.lookup "name" d c <- B.lookup "currency" d t <- B.lookup "tax" d tV <- B.lookup "taxValue" d v <- B.lookup "vat" d vV <- B.lookup "vatValue" d f <- B.lookup "first" d l <- B.lookup "last" d e <- B.lookup "email" d s <- B.lookup "street" d ct <- B.lookup "city" d st <- B.lookup "state" d p <- B.lookup "postal" d ph <- B.lookup "phone" d w <- B.lookup "website" d co <- B.lookup "country" d paid <- B.lookup "paid" d zats <- B.lookup "zats" d inv <- B.lookup "invoices" d ets <- B.lookup "expiration" d pc <- B.lookup "payconf" d vk <- B.lookup "viewKey" d cT <- B.lookup "crmToken" d Just (Owner i a n c t tV v vV f l e s ct st p ph w co paid zats inv ets pc vk cT) cast' _ = Nothing val (Owner i a n c t tV v vV f l e s ct st p ph w co paid zats inv ets pc vk cT) = case i of Just oid -> Doc [ "_id" =: oid , "address" =: a , "name" =: n , "currency" =: c , "tax" =: t , "taxValue" =: tV , "vat" =: v , "vatValue" =: vV , "first" =: f , "last" =: l , "email" =: e , "street" =: s , "city" =: ct , "state" =: st , "postal" =: p , "phone" =: ph , "website" =: w , "country" =: co , "paid" =: paid , "zats" =: zats , "invoices" =: inv , "expiration" =: ets , "payconf" =: pc , "viewKey" =: vk , "crmToken" =: cT ] Nothing -> Doc [ "address" =: a , "name" =: n , "currency" =: c , "tax" =: t , "taxValue" =: tV , "vat" =: v , "vatValue" =: vV , "first" =: f , "last" =: l , "email" =: e , "street" =: s , "city" =: ct , "state" =: st , "postal" =: p , "phone" =: ph , "website" =: w , "country" =: co , "paid" =: paid , "zats" =: zats , "invoices" =: inv , "expiration" =: ets , "payconf" =: pc , "viewKey" =: vk , "crmToken" =: cT ] -- | Type to represent informational data for Owners from UI data OwnerData = OwnerData { od_first :: T.Text , od_last :: T.Text , od_name :: T.Text , od_street :: T.Text , od_city :: T.Text , od_state :: T.Text , od_postal :: T.Text , od_country :: T.Text , od_email :: T.Text , od_website :: T.Text , od_phone :: T.Text } deriving (Eq, Show, Generic) instance FromJSON OwnerData where parseJSON = withObject "OwnerData" $ \obj -> do f <- obj .: "first" l <- obj .: "last" n <- obj .: "name" s <- obj .: "street" c <- obj .: "city" st <- obj .: "state" p <- obj .: "postal" co <- obj .: "country" e <- obj .: "email" w <- obj .: "website" ph <- obj .: "phone" pure $ OwnerData f l n s c st p co e w ph data OwnerSettings = OwnerSettings { os_id :: Maybe ObjectId , os_address :: T.Text , os_name :: T.Text , os_currency :: T.Text , os_tax :: Bool , os_taxValue :: Double , os_vat :: Bool , os_vatValue :: Double , os_paid :: Bool , os_zats :: Bool , os_invoices :: Bool , os_expiration :: UTCTime , os_payconf :: Bool , os_crmToken :: T.Text , os_viewKey :: T.Text } deriving (Eq, Show, Generic) instance FromJSON OwnerSettings where parseJSON = withObject "OwnerSettings" $ \obj -> do i <- obj .:? "_id" a <- obj .: "address" n <- obj .: "name" c <- obj .: "currency" t <- obj .: "tax" tV <- obj .: "taxValue" v <- obj .: "vat" vV <- obj .: "vatValue" p <- obj .: "paid" z <- obj .: "zats" inv <- obj .: "invoices" e <- obj .: "expiration" pc <- obj .: "payconf" cT <- obj .: "crmToken" vK <- obj .: "viewkey" pure $ OwnerSettings ((Just . read) =<< i) a n c t tV v vV p z inv e pc cT vK instance ToJSON OwnerSettings where toJSON (OwnerSettings i a n c t tV v vV p z inv e pc cT vK) = object [ "_id" .= maybe "" show i , "address" .= a , "name" .= n , "currency" .= c , "tax" .= t , "taxValue" .= tV , "vat" .= v , "vatValue" .= vV , "paid" .= p , "zats" .= z , "invoices" .= inv , "expiration" .= e , "payconf" .= pc , "crmToken" .= cT , "viewkey" .= keyObfuscate vK ] where keyObfuscate s | s == "" = "" | otherwise = T.take 8 s <> "...." <> T.takeEnd 8 s -- Helper Functions getOwnerSettings :: Owner -> OwnerSettings getOwnerSettings o = OwnerSettings (o_id o) (oaddress o) (oname o) (ocurrency o) (otax o) (otaxValue o) (ovat o) (ovatValue o) (opaid o) (ozats o) (oinvoices o) (oexpiration o) (opayconf o) (ocrmToken o) (oviewkey o) -- Database actions -- | Function to upsert an Owner upsertOwner :: Owner -> Action IO () upsertOwner o = do let owner = val o case owner of Doc d -> upsert (select ["address" =: oaddress o] "owners") d _ -> return () -- | Function to get an Owner findOwner :: T.Text -> Action IO (Maybe Document) findOwner zaddy = findOne (select ["address" =: zaddy] "owners") -- | Function to get an Owner by id findOwnerById :: T.Text -> Action IO (Maybe Document) findOwnerById i = findOne (select ["_id" =: (read (T.unpack i) :: ObjectId)] "owners") findActiveOwners :: Action IO [Document] findActiveOwners = rest =<< find (select ["paid" =: True, "payconf" =: True] "owners") -- | Function to find Owners about to expire findExpiringOwners :: UTCTime -> Action IO [Document] findExpiringOwners now = rest =<< find (select ["paid" =: True, "expiration" =: ["$lte" =: addUTCTime 172800 now]] "owners") findWithKeys :: Action IO [Document] findWithKeys = rest =<< find (select ["paid" =: True, "invoices" =: True, "payconf" =: True] "owners") removePro :: T.Text -> Action IO () removePro o = modify (select ["address" =: o] "owners") ["$set" =: ["invoices" =: False]] updateOwnerSettings :: OwnerSettings -> Action IO () updateOwnerSettings os = modify (select ["_id" =: os_id os] "owners") [ "$set" =: [ "name" =: os_name os , "currency" =: os_currency os , "tax" =: os_tax os , "taxValue" =: os_taxValue os , "vat" =: os_vat os , "vatValue" =: os_vatValue os , "zats" =: os_zats os , "payconf" =: os_payconf os , "crmToken" =: os_crmToken os ] ] upsertViewingKey :: Owner -> String -> Action IO () upsertViewingKey o vk = modify (select ["_id" =: o_id o] "owners") ["$set" =: ["viewKey" =: vk]] -- | Type for a pro session data ZGoProSession = ZGoProSession { ps_id :: Maybe ObjectId , psaddress :: T.Text , psexpiration :: UTCTime , psclosed :: Bool } deriving (Eq, Show) instance Val ZGoProSession where cast' (Doc d) = do i <- B.lookup "_id" d a <- B.lookup "address" d e <- B.lookup "expiration" d p <- B.lookup "closed" d Just (ZGoProSession i a e p) cast' _ = Nothing val (ZGoProSession i a e p) = case i of Just oid -> Doc ["_id" =: oid, "address" =: a, "expiration" =: e, "closed" =: p] Nothing -> Doc ["address" =: a, "expiration" =: e, "closed" =: p] -- | Function to get a pro session findProSession :: T.Text -> Action IO (Maybe Document) findProSession zaddy = findOne (select ["address" =: zaddy, "closed" =: False] "prosessions") -- | Function to get expiring pro sessions findExpiringProSessions :: UTCTime -> Action IO [Document] findExpiringProSessions now = rest =<< find (select ["closed" =: False, "expiration" =: ["$lte" =: now]] "prosessions") -- | Function to upsert a pro session upsertProSession :: ZGoProSession -> Action IO () upsertProSession ps = do let prosession = val ps case prosession of Doc d -> upsert (select ["address" =: psaddress ps, "expiration" =: psexpiration ps] "prosessions") d _ -> return () closeProSession :: ZGoProSession -> Action IO () closeProSession ps = do let prosession = val ps case prosession of Doc d -> modify (select d "prosessions") ["$set" =: ["closed" =: True]] _ -> return ()