aboutsummaryrefslogtreecommitdiff
path: root/server/src/Controller/Income.hs
blob: 784a2db1df2de93107bc5d7c4c2728cbcf2f59f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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 (Failure, Success))
import qualified Network.HTTP.Types.Status as Status
import           Web.Scotty                hiding (delete)

import           Common.Model              (CreateIncomeForm (..),
                                            EditIncomeForm (..),
                                            IncomeHeader (..), IncomeId,
                                            IncomePage (..), User (..))

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.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
  )