module Handler.Term ( getTermShowR , getTermEditR, postTermEditR , getTermEditExistR, postTermEditExistR ) where import Import import Utils.Course (mayViewCourse) import Handler.Utils import qualified Data.Map as Map import qualified Database.Esqueleto as E import qualified Data.Set as Set import qualified Control.Monad.State.Class as State import Data.Time.Calendar.WeekDate data TermDay = TermDayStart | TermDayEnd | TermDayLectureStart | TermDayLectureEnd deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable) deriving anyclass (Universe, Finite) guessDay :: TermIdentifier -> TermDay -> Day guessDay TermIdentifier{ year, season = Winter } TermDayStart = fromGregorian year 10 1 guessDay TermIdentifier{ year, season = Winter } TermDayEnd = fromGregorian (succ year) 3 31 guessDay TermIdentifier{ year, season = Summer } TermDayStart = fromGregorian year 4 1 guessDay TermIdentifier{ year, season = Summer } TermDayEnd = fromGregorian year 9 30 guessDay tid@TermIdentifier{ year, season = Winter } TermDayLectureStart = fromWeekDate year (wWeekStart + 2) 1 where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart guessDay tid@TermIdentifier{ year, season = Winter } TermDayLectureEnd = fromWeekDate (succ year) ((wWeekStart + 21) `div` bool 53 54 longYear) 5 where longYear = is _Just $ fromWeekDateValid year 53 1 (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart guessDay tid@TermIdentifier{ year, season = Summer } TermDayLectureStart = fromWeekDate year (wWeekStart + 2) 1 where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart guessDay tid@TermIdentifier{ year, season = Summer } TermDayLectureEnd = fromWeekDate year (wWeekStart + 17) 5 where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart validateTerm :: (MonadHandler m, HandlerSite m ~ UniWorX) => FormValidator Term m () validateTerm = do Term{..} <- State.get guardValidation MsgTermStartMustMatchName $ termStart `withinTerm` termName guardValidation MsgTermEndMustBeAfterStart $ termStart < termEnd guardValidation MsgTermLectureEndMustBeAfterStart $ termLectureStart < termLectureEnd guardValidation MsgTermStartMustBeBeforeLectureStart $ termStart <= termLectureStart guardValidation MsgTermEndMustBeAfterLectureEnd $ termEnd >= termLectureEnd getTermShowR :: Handler Html getTermShowR = do muid <- maybeAuthId now <- liftIO getCurrentTime ata <- getSessionActiveAuthTags table <- runDB $ let termDBTable = DBTable{..} where dbtSQLQuery term = return (term, courseCount) where courseCount = E.subSelectCount . E.from $ \course -> E.where_ $ term E.^. TermId E.==. course E.^. CourseTerm E.&&. mayViewCourse muid ata now course Nothing dbtRowKey = (E.^. TermId) dbtProj = return . dbrOutput dbtColonnade = widgetColonnade $ mconcat [ sortable (Just "term-id") (i18nCell MsgTermShort) $ \(Entity tid _, _) -> cell $ do mayEdit <- hasWriteAccessTo $ TermEditExistR tid [whamlet| $newline never #{toPathPiece tid} $if mayEdit   #{iconMenuAdmin} |] , sortable (Just "lecture-start") (i18nCell MsgLectureStart) $ \(Entity _ Term{..},_) -> cell $ formatTime SelFormatDate termLectureStart >>= toWidget , sortable (Just "lecture-end") (i18nCell MsgTermLectureEnd) $ \(Entity _ Term{..},_) -> cell $ formatTime SelFormatDate termLectureEnd >>= toWidget , sortable Nothing (i18nCell MsgTermActive) $ \(Entity _ Term{..},_) -> tickmarkCell termActive , sortable Nothing (i18nCell MsgTermCourseCount) $ \(_, E.Value numCourses) -> cell [whamlet|_{MsgNumCourses numCourses}|] , sortable (Just "start") (i18nCell MsgTermStart) $ \(Entity _ Term{..},_) -> cell $ formatTime SelFormatDate termStart >>= toWidget , sortable (Just "end") (i18nCell MsgTermEnd) $ \(Entity _ Term{..},_) -> cell $ formatTime SelFormatDate termEnd >>= toWidget , sortable Nothing (i18nCell MsgTermHolidays) $ \(Entity _ Term{..},_) -> cell $ do let termHolidays' = groupHolidays termHolidays [whamlet| $newline never