module Controller.Income ( list , deprecatedList , 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 (Failure, Success)) import qualified Network.HTTP.Types.Status as Status import Web.Scotty hiding (delete) import Common.Model (CreateIncomeForm (..), EditIncomeForm (..), Income (..), IncomeHeader (..), IncomeId, IncomePage (..), User (..)) import qualified Common.Model as CM 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 firstPayment <- PaymentPersistence.firstPunctualDay allIncomes <- IncomePersistence.listAll let since = CM.useIncomesFrom (map _user_id users) allIncomes firstPayment let byUser = case since of Just s -> M.fromList . flip map users $ \user -> ( _user_id user , CM.cumulativeIncomesSince currentTime s $ filter ((==) (_user_id user) . _income_userId) allIncomes ) Nothing -> M.empty incomes <- IncomePersistence.list page perPage return $ IncomePage (IncomeHeader since byUser) incomes count) >>= json ) deprecatedList :: ActionM () deprecatedList = Secure.loggedAction (\_ -> (liftIO . Query.run $ IncomePersistence.listAll) >>= 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.jsonOrBadRequest ) edit :: EditIncomeForm -> ActionM () edit form = Secure.loggedAction (\user -> (liftIO . Query.run $ do case IncomeValidation.editIncome form of Success (EditIncome incomeId amount date) -> do Right <$> (IncomePersistence.edit (_user_id user) incomeId date amount) Failure validationError -> return $ Left validationError ) >>= ControllerHelper.jsonOrBadRequest ) delete :: IncomeId -> ActionM () delete incomeId = Secure.loggedAction (\user -> do _ <- liftIO . Query.run $ IncomePersistence.delete (_user_id user) incomeId status Status.ok200 )