summaryrefslogtreecommitdiff
path: root/Handler/Vacation.hs
blob: 233d737473733cca8564ea5c847dcfacebc30c00 (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
{-# LANGUAGE TupleSections, OverloadedStrings #-}
module Handler.Vacation where

import Import hiding (get)
import Control.Monad (when)
import Control.Monad.Trans.RWS.Lazy (RWST, ask, tell, get, put, execRWST)
import qualified Data.Text as T
import Data.Time (UTCTime, fromGregorian, getCurrentTime, utctDay)
import Yesod.Auth (maybeAuth)
import qualified Data.Map as Map
import Text.Printf (printf)
import PTO

type Month = (Integer, Int)

fmtHours :: Rational -> String
fmtHours r = printf "%.2f" d
    where d = fromRational r :: Double

getAnniversaryMax :: [Employment] -> Month -> Maybe Rational
getAnniversaryMax es (y, m) =
    case capOverride of
      Just 0.0 -> Nothing
      Just v   -> Just (toRational v)
      Nothing  -> Just 160.0
  where
    empMap = Map.fromList [(employmentStartDate e, e) | e <- es]
    today = fromGregorian y m 0

    todaysEmp :: Maybe Employment
    todaysEmp =
      Map.lookupLE today empMap >>=
	\(_, emp) ->
	  case employmentEndDate emp of
 	    Just end
	      | end < today -> Nothing 
	    _               -> Just emp
    
    capOverride :: Maybe Double
    capOverride = todaysEmp >>= employmentPtoMaxRollover

getVacationR :: UserId -> Handler Html
getVacationR cid = do
    user <- runDB $ get404 cid
    ma <- maybeAuth
    today <- fmap utctDay (liftIO getCurrentTime)
    employments <- runDB $ fmap (map entityVal) (selectList [EmploymentUser ==. cid] [])
    let username = userIdent user
        current@(currentyear, currentmonth) = monthOf today
	months = takeWhile (< current) [(y, m) | y <- [2005..], m <- [1..12]]
    (_, transacts') <- execRWST' (cid, employments) 0 $ mapM anotherMonth months
    let transacts = reverse $ transacts' :: [(String, Rational)]
    defaultLayout $ do
        aDomId <- newIdent
        (setTitle . toHtml) ("Vacation report for " `T.append` username)
        $(widgetFile "vacationpage")
    where
        execRWST' = flip .  flip execRWST

anotherMonth :: Month -> RWST (UserId, [Employment]) [(String, Rational)] Rational Handler ()
anotherMonth (y,m) = do
    (u, employments@(e:_)) <- ask
    (plus, minus) <- lift . runDB $ monthlyTransactions u (y,m)
    when (plus > 0) (add plus)
    when (minus > 0) (subtract (toRational minus))
    let twoyear = twoYearsFrom $ employmentStartDate e
        ptoMax = getAnniversaryMax employments (y,m)
    when ((snd . monthOf) twoyear == m) $
         maybe (return ()) kneecap ptoMax
    where
        add x = get >>= \o -> tell [(show y ++ "-" ++ show m ++ ": adding " ++ fmtHours x ++ " hours", o + x)] >> put (o + x)
        subtract x = get >>= \o -> tell [(show y ++ "-" ++ show m ++ ": subtracting " ++ fmtHours x ++ " hours", o - x)] >> put (o - x)
	kneecap cap = get >>= \o -> when (o > cap) (tell [(show y ++ "-" ++ show m ++ ": over anniversary max, subtracting " ++ fmtHours (o - cap) ++ " hours", cap)] >> put cap)