module Handler.Term ( getTermShowR , getTermEditR, postTermEditR , getTermEditExistR, postTermEditExistR ) where import Import import Utils.Course (mayViewCourse) import Handler.Utils import qualified Data.Map.Strict as Map import Data.Map.Strict ((!)) import qualified Database.Esqueleto.Legacy 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 TermForm m () validateTerm = do TermForm{..} <- State.get guardValidation MsgTermStartMustMatchName $ tfStart `withinTerm` tfName guardValidation MsgTermEndMustBeAfterStart $ tfStart < tfEnd guardValidation MsgTermLectureEndMustBeAfterStart $ tfLectureStart < tfLectureEnd guardValidation MsgTermStartMustBeBeforeLectureStart $ tfStart <= tfLectureStart guardValidation MsgTermEndMustBeAfterLectureEnd $ tfEnd >= tfLectureEnd getTermShowR :: Handler Html getTermShowR = do muid <- maybeAuthId now <- liftIO getCurrentTime ata <- getSessionActiveAuthTags table <- runDB $ let termDBTable = DBTable{..} where dbtSQLQuery term = return (term, courseCount, isActive) where courseCount = E.subSelectCount . E.from $ \(course `E.LeftOuterJoin` allocation) -> do E.on . E.exists . E.from $ \allocationCourse -> E.where_ $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId E.&&. E.just (allocationCourse E.^. AllocationCourseAllocation) E.==. allocation E.?. AllocationId E.where_ $ term E.^. TermId E.==. course E.^. CourseTerm E.&&. mayViewCourse muid ata now course (allocation E.?. AllocationId) isActive = termIsActiveE (E.val now) (E.val muid) (term E.^. TermId) dbtRowKey = (E.^. TermId) dbtProj = dbrOutput <$> dbtProjId 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) $ \(_, _, E.Value isActive) -> tickmarkCell isActive , 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