feat(exams): allow forced deregistration

This commit is contained in:
Gregor Kleen 2019-07-17 11:14:15 +02:00
parent fccd2a49b1
commit 1b532c4e4d
3 changed files with 49 additions and 6 deletions

View File

@ -1186,6 +1186,8 @@ VersionHistory: Versionsgeschichte
KnownBugs: Bekannte Bugs
ExamUsersHeading: Klausurteilnehmer
ExamUserDeregister: Teilnehmer von Klausur abmelden
ExamUsersDeregistered count@Int64: #{show count} Teilnehmer abgemeldet
CsvFile: CSV-Datei
CsvModifyExisting: Existierende Einträge angleichen

2
routes
View File

@ -143,7 +143,7 @@
/show EShowR GET !time
/edit EEditR GET POST
/corrector-invite ECInviteR GET POST
/users EUsersR GET POST !timeANDcorrector
/users EUsersR GET POST
/users/new EAddUserR GET POST
/users/invite EInviteR GET POST
/register ERegisterR POST !timeANDcourse-registered !timeANDexam-registered

View File

@ -36,6 +36,8 @@ import qualified Data.Conduit.List as C
import Numeric.Lens (integral)
import Database.Persist.Sql (deleteWhereCount)
-- Dedicated ExamRegistrationButton
@ -809,6 +811,9 @@ queryStudyDegree = $(sqlIJproj 3 2) . $(sqlLOJproj 2 2) . $(sqlLOJproj 3 3)
queryStudyField :: ExamUserTableExpr -> E.SqlExpr (Maybe (Entity StudyTerms))
queryStudyField = $(sqlIJproj 3 3) . $(sqlLOJproj 2 2) . $(sqlLOJproj 3 3)
resultExamRegistration :: Lens' ExamUserTableData (Entity ExamRegistration)
resultExamRegistration = _dbrOutput . _1
resultUser :: Lens' ExamUserTableData (Entity User)
resultUser = _dbrOutput . _2
@ -866,10 +871,18 @@ instance CsvColumnsExplained ExamUserTableCsv where
, ('csvEUserExercisePassesMax, MsgCsvColumnExamUserExercisePassesMax )
]
data ExamUserAction = ExamUserDeregister
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
instance Universe ExamUserAction
instance Finite ExamUserAction
nullaryPathPiece ''ExamUserAction $ camelToPathPiece' 2
embedRenderMessage ''UniWorX ''ExamUserAction id
getEUsersR, postEUsersR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html
getEUsersR = postEUsersR
postEUsersR tid ssh csh examn = do
((), examUsersTable) <- runDB $ do
(registrationResult, examUsersTable) <- runDB $ do
exam@(Entity eid Exam{..}) <- fetchExam tid ssh csh examn
bonus <- examBonus exam
@ -894,8 +907,9 @@ postEUsersR tid ssh csh examn = do
return (examRegistration, user, occurrence, studyFeatures, studyDegree, studyField)
dbtRowKey = queryExamRegistration >>> (E.^. ExamRegistrationId)
dbtProj = return
dbtColonnade = dbColonnade . mconcat $ catMaybes
[ pure $ colUserNameLink (CourseR tid ssh csh . CUserR)
dbtColonnade = mconcat $ catMaybes
[ pure $ dbSelect (applying _2) id $ return . view (resultExamRegistration . _entityKey)
, pure $ colUserNameLink (CourseR tid ssh csh . CUserR)
, pure colUserMatriclenr
, pure $ colField resultStudyField
, pure $ colDegreeShort resultStudyDegree
@ -937,7 +951,20 @@ postEUsersR tid ssh csh examn = do
, prismAForm (singletonFilter "occurrence") mPrev $ aopt textField (fslI MsgExamOccurrence)
]
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
dbtParams = def
dbtParams = DBParamsForm
{ dbParamsFormMethod = POST
, dbParamsFormAction = Just . SomeRoute $ CExamR tid ssh csh examn EUsersR
, dbParamsFormAttrs = []
, dbParamsFormSubmit = FormSubmit
, dbParamsFormAdditional = \csrf -> do
(res, vw) <- mreq (selectField optionsFinite) "" Nothing
let formWgt = toWidget csrf <> fvInput vw
formRes = (, mempty) . First . Just <$> res
return (formRes, formWgt)
, dbParamsFormEvaluate = liftHandlerT . runFormPost
, dbParamsFormResult = id
, dbParamsFormIdent = def
}
dbtIdent :: Text
dbtIdent = "exam-users"
dbtCsvEncode :: DBTCsvEncode ExamUserTableData ExamUserTableCsv
@ -956,7 +983,21 @@ postEUsersR tid ssh csh examn = do
dbtCsvDecode = Nothing
examUsersDBTableValidator = def
dbTable examUsersDBTableValidator examUsersDBTable
postprocess :: FormResult (First ExamUserAction, DBFormResult ExamRegistrationId Bool ExamUserTableData) -> FormResult (ExamUserAction, Set ExamRegistrationId)
postprocess inp = do
(First (Just act), regMap) <- inp
let regSet = Map.keysSet . Map.filter id $ getDBFormResult (const False) regMap
return (act, regSet)
over _1 postprocess <$> dbTable examUsersDBTableValidator examUsersDBTable
formResult registrationResult $ \case
(ExamUserDeregister, selectedRegistrations) -> do
nrDel <- runDB $ deleteWhereCount
[ ExamRegistrationId <-. Set.toList selectedRegistrations
]
addMessageI Success $ MsgExamUsersDeregistered nrDel
redirect $ CExamR tid ssh csh examn EUsersR
siteLayoutMsg (prependCourseTitle tid ssh csh MsgExamUsersHeading) $ do
setTitleI $ prependCourseTitle tid ssh csh MsgExamUsersHeading