module Controller.Income ( list , create , edit , delete ) where import Control.Monad.IO.Class (liftIO) import qualified Data.Map as M import qualified Data.Time.Clock as Clock import Data.Validation (Validation (..)) import qualified Network.HTTP.Types.Status as Status import Web.Scotty hiding (delete) import Common.Model (CreateIncomeForm (..), EditIncomeForm (..), IncomeHeader (..), IncomeId, IncomePage (..), User (..)) import qualified Common.Msg as Msg import qualified Controller.Helper as ControllerHelper import Model.CreateIncome (CreateIncome (..)) import Model.EditIncome (EditIncome (..)) import qualified Model.Query as Query import qualified Persistence.Income as IncomePersistence import qualified Persistence.Payment as PaymentPersistence import qualified Persistence.User as UserPersistence import qualified Secure import qualified Validation.Income as IncomeValidation list :: Int -> Int -> ActionM () list page perPage = Secure.loggedAction (\_ -> do currentTime <- liftIO Clock.getCurrentTime (liftIO . Query.run $ do count <- IncomePersistence.count users <- UserPersistence.list let userIds = _user_id <$> users paymentRange <- PaymentPersistence.getRange incomeDefinedForAll <- IncomePersistence.definedForAll userIds let since = max <$> (fst <$> paymentRange) <*> incomeDefinedForAll cumulativeIncome <- case since of Just s -> IncomePersistence.getCumulativeIncome s (Clock.utctDay currentTime) Nothing -> return M.empty incomes <- IncomePersistence.list page perPage return $ IncomePage page (IncomeHeader since cumulativeIncome) incomes count) >>= json ) create :: CreateIncomeForm -> ActionM () create form = Secure.loggedAction (\user -> (liftIO . Query.run $ do case IncomeValidation.createIncome form of Success (CreateIncome amount date) -> do Right <$> (IncomePersistence.create (_user_id user) date amount) Failure validationError -> return $ Left validationError ) >>= ControllerHelper.okOrBadRequest ) edit :: EditIncomeForm -> ActionM () edit form = Secure.loggedAction (\user -> (liftIO . Query.run $ do case IncomeValidation.editIncome form of Success (EditIncome incomeId amount date) -> do isSuccess <- IncomePersistence.edit (_user_id user) incomeId date amount return $ if isSuccess then Right () else Left $ Msg.get Msg.Error_IncomeEdit Failure validationError -> return $ Left validationError ) >>= ControllerHelper.okOrBadRequest ) delete :: IncomeId -> ActionM () delete incomeId = Secure.loggedAction (\user -> do _ <- liftIO . Query.run $ IncomePersistence.delete (_user_id user) incomeId status Status.ok200 )