module Handler.Allocation.UserForm ( AllocationUserForm(..) , allocationUserForm , CourseParticipantForm(..) , _CourseParticipantFormNotAllocated, _CourseParticipantFormDeregistered, _CourseParticipantFormRegistered, _cpfDeregisterReason, _cpfEverRegistered , CourseParticipantForm' , courseParticipantForm ) where import Import import Handler.Allocation.Application import Handler.Utils import qualified Database.Esqueleto.Legacy as E import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.PostgreSQL as E import qualified Data.Map.Strict as Map import Text.Blaze (toMarkup) data AllocationUserForm = AllocationUserForm { aauUser :: UserId , aauTotalCourses :: Word64 , aauPriority :: Maybe AllocationPriority , aauApplications :: Map CourseId ApplicationForm } allocationUserForm :: forall m backend. ( MonadHandler m, HandlerSite m ~ UniWorX , E.SqlBackendCanRead backend, IsSqlBackend backend ) => AllocationId -> Maybe AllocationUserForm -> AForm (ReaderT backend m) AllocationUserForm allocationUserForm aId mTemplate = wFormToAForm $ do allocCourses <- lift . lift . E.select . E.from $ \(course `E.InnerJoin` allocationCourse) -> do E.on $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId E.where_ $ allocationCourse E.^. AllocationCourseAllocation E.==. E.val aId return ( course , E.exists . E.from $ \courseAppInstructionFile -> E.where_ $ courseAppInstructionFile E.^. CourseAppInstructionFileCourse E.==. course E.^. CourseId , allocationCourse ) MsgRenderer mr <- getMsgRenderer userRes <- case aauUser <$> mTemplate of Just u -> do User{..} <- lift . lift $ get404 u fvId <- newIdent lift . tell $ pure FieldView { fvLabel = toMarkup $ mr MsgAllocationAddUserUser , fvTooltip = Nothing , fvId , fvInput = nameWidget userDisplayName userSurname , fvErrors = Nothing , fvRequired = False } return $ FormSuccess u Nothing -> wreq (checkMap (first $ const MsgAllocationAddUserUserNotFound) Right $ userField False Nothing) (fslpI MsgAllocationAddUserUser (mr MsgAllocationAddUserUserPlaceholder)) Nothing totalCoursesRes <- wreq (posIntFieldI MsgAllocationAddUserTotalCoursesLessThanOne) (fslI MsgAllocationAddUserTotalCourses) ((aauTotalCourses <$> mTemplate) <|> Just 1) priorityRes <- hoist (hoist liftHandler) $ optionalActionW (allocationPriorityForm (fslI MsgAllocationAddUserPriority) $ aauPriority =<< mTemplate) (fslI MsgAllocationAddUserSetPriority) ((is _Just . aauPriority <$> mTemplate) <|> Just True) applicationsRes <- aFormToWForm $ allocationApplicationsForm aId (aauUser <$> mTemplate) (Map.fromList [ (cId, (course, allocationCourse, hasTemplate)) | (Entity cId course, E.Value hasTemplate, Entity _ allocationCourse) <- allocCourses ]) (fslI MsgAllocationAddUserApplications) False return $ AllocationUserForm <$> userRes <*> totalCoursesRes <*> priorityRes <*> applicationsRes allocationApplicationsForm :: forall m backend. ( MonadHandler m, HandlerSite m ~ UniWorX , E.SqlBackendCanRead backend ) => AllocationId -> Maybe UserId -> Map CourseId (Course, AllocationCourse, Bool) -> FieldSettings UniWorX -> Bool -> AForm (ReaderT backend m) (Map CourseId ApplicationForm) allocationApplicationsForm aId muid courses FieldSettings{..} fvRequired = formToAForm $ do now <- liftIO getCurrentTime let afmApplicant = True afmApplicantEdit = True afmLecturer = True appsRes' <- iforM courses $ \cId (course, allocCourse, hasApplicationTemplate) -> do mApplicationTemplate <- runMaybeT $ do guard hasApplicationTemplate let Course{..} = course toTextUrl $ CourseR courseTerm courseSchool courseShorthand CRegisterTemplateR counts <- lift . fmap (maybe (Nothing, 0) $ bimap (assertM' (> 0) . E.unValue) E.unValue) . E.selectMaybe . E.from $ \courseApplication -> do E.where_ $ courseApplication E.^. CourseApplicationCourse E.==. E.val cId E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.justVal aId let hasRating = E.isJust (courseApplication E.^. CourseApplicationRatingPoints) E.||. E.isJust (courseApplication E.^. CourseApplicationRatingComment) E.||. courseApplication E.^. CourseApplicationRatingVeto return ( E.count (courseApplication E.^. CourseApplicationId) `E.filterWhere` hasRating , E.count (courseApplication E.^. CourseApplicationId) `E.filterWhere` (courseApplication E.^. CourseApplicationRatingVeto) ) hoist liftHandler $ over _2 (course, allocCourse, mApplicationTemplate, counts, ) <$> applicationForm (Just aId) cId muid ApplicationFormMode{..} Nothing let appsRes = sequenceA $ view _1 <$> appsRes' appsViews = view _2 <$> appsRes' let fvInput = [whamlet| $newline never