aboutsummaryrefslogtreecommitdiff
path: root/server/src/Controller/Income.hs
blob: 127e3b39692a9d751b3995230d39a25435630a41 (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
  )