feat(exams): allow forced deregistration
This commit is contained in:
parent
fccd2a49b1
commit
1b532c4e4d
@ -1186,6 +1186,8 @@ VersionHistory: Versionsgeschichte
|
|||||||
KnownBugs: Bekannte Bugs
|
KnownBugs: Bekannte Bugs
|
||||||
|
|
||||||
ExamUsersHeading: Klausurteilnehmer
|
ExamUsersHeading: Klausurteilnehmer
|
||||||
|
ExamUserDeregister: Teilnehmer von Klausur abmelden
|
||||||
|
ExamUsersDeregistered count@Int64: #{show count} Teilnehmer abgemeldet
|
||||||
|
|
||||||
CsvFile: CSV-Datei
|
CsvFile: CSV-Datei
|
||||||
CsvModifyExisting: Existierende Einträge angleichen
|
CsvModifyExisting: Existierende Einträge angleichen
|
||||||
|
|||||||
2
routes
2
routes
@ -143,7 +143,7 @@
|
|||||||
/show EShowR GET !time
|
/show EShowR GET !time
|
||||||
/edit EEditR GET POST
|
/edit EEditR GET POST
|
||||||
/corrector-invite ECInviteR GET POST
|
/corrector-invite ECInviteR GET POST
|
||||||
/users EUsersR GET POST !timeANDcorrector
|
/users EUsersR GET POST
|
||||||
/users/new EAddUserR GET POST
|
/users/new EAddUserR GET POST
|
||||||
/users/invite EInviteR GET POST
|
/users/invite EInviteR GET POST
|
||||||
/register ERegisterR POST !timeANDcourse-registered !timeANDexam-registered
|
/register ERegisterR POST !timeANDcourse-registered !timeANDexam-registered
|
||||||
|
|||||||
@ -36,6 +36,8 @@ import qualified Data.Conduit.List as C
|
|||||||
|
|
||||||
import Numeric.Lens (integral)
|
import Numeric.Lens (integral)
|
||||||
|
|
||||||
|
import Database.Persist.Sql (deleteWhereCount)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Dedicated ExamRegistrationButton
|
-- Dedicated ExamRegistrationButton
|
||||||
@ -809,6 +811,9 @@ queryStudyDegree = $(sqlIJproj 3 2) . $(sqlLOJproj 2 2) . $(sqlLOJproj 3 3)
|
|||||||
queryStudyField :: ExamUserTableExpr -> E.SqlExpr (Maybe (Entity StudyTerms))
|
queryStudyField :: ExamUserTableExpr -> E.SqlExpr (Maybe (Entity StudyTerms))
|
||||||
queryStudyField = $(sqlIJproj 3 3) . $(sqlLOJproj 2 2) . $(sqlLOJproj 3 3)
|
queryStudyField = $(sqlIJproj 3 3) . $(sqlLOJproj 2 2) . $(sqlLOJproj 3 3)
|
||||||
|
|
||||||
|
resultExamRegistration :: Lens' ExamUserTableData (Entity ExamRegistration)
|
||||||
|
resultExamRegistration = _dbrOutput . _1
|
||||||
|
|
||||||
resultUser :: Lens' ExamUserTableData (Entity User)
|
resultUser :: Lens' ExamUserTableData (Entity User)
|
||||||
resultUser = _dbrOutput . _2
|
resultUser = _dbrOutput . _2
|
||||||
|
|
||||||
@ -866,10 +871,18 @@ instance CsvColumnsExplained ExamUserTableCsv where
|
|||||||
, ('csvEUserExercisePassesMax, MsgCsvColumnExamUserExercisePassesMax )
|
, ('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 :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html
|
||||||
getEUsersR = postEUsersR
|
getEUsersR = postEUsersR
|
||||||
postEUsersR tid ssh csh examn = do
|
postEUsersR tid ssh csh examn = do
|
||||||
((), examUsersTable) <- runDB $ do
|
(registrationResult, examUsersTable) <- runDB $ do
|
||||||
exam@(Entity eid Exam{..}) <- fetchExam tid ssh csh examn
|
exam@(Entity eid Exam{..}) <- fetchExam tid ssh csh examn
|
||||||
bonus <- examBonus exam
|
bonus <- examBonus exam
|
||||||
|
|
||||||
@ -894,8 +907,9 @@ postEUsersR tid ssh csh examn = do
|
|||||||
return (examRegistration, user, occurrence, studyFeatures, studyDegree, studyField)
|
return (examRegistration, user, occurrence, studyFeatures, studyDegree, studyField)
|
||||||
dbtRowKey = queryExamRegistration >>> (E.^. ExamRegistrationId)
|
dbtRowKey = queryExamRegistration >>> (E.^. ExamRegistrationId)
|
||||||
dbtProj = return
|
dbtProj = return
|
||||||
dbtColonnade = dbColonnade . mconcat $ catMaybes
|
dbtColonnade = mconcat $ catMaybes
|
||||||
[ pure $ colUserNameLink (CourseR tid ssh csh . CUserR)
|
[ pure $ dbSelect (applying _2) id $ return . view (resultExamRegistration . _entityKey)
|
||||||
|
, pure $ colUserNameLink (CourseR tid ssh csh . CUserR)
|
||||||
, pure colUserMatriclenr
|
, pure colUserMatriclenr
|
||||||
, pure $ colField resultStudyField
|
, pure $ colField resultStudyField
|
||||||
, pure $ colDegreeShort resultStudyDegree
|
, pure $ colDegreeShort resultStudyDegree
|
||||||
@ -937,7 +951,20 @@ postEUsersR tid ssh csh examn = do
|
|||||||
, prismAForm (singletonFilter "occurrence") mPrev $ aopt textField (fslI MsgExamOccurrence)
|
, prismAForm (singletonFilter "occurrence") mPrev $ aopt textField (fslI MsgExamOccurrence)
|
||||||
]
|
]
|
||||||
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
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 :: Text
|
||||||
dbtIdent = "exam-users"
|
dbtIdent = "exam-users"
|
||||||
dbtCsvEncode :: DBTCsvEncode ExamUserTableData ExamUserTableCsv
|
dbtCsvEncode :: DBTCsvEncode ExamUserTableData ExamUserTableCsv
|
||||||
@ -956,7 +983,21 @@ postEUsersR tid ssh csh examn = do
|
|||||||
dbtCsvDecode = Nothing
|
dbtCsvDecode = Nothing
|
||||||
|
|
||||||
examUsersDBTableValidator = def
|
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
|
siteLayoutMsg (prependCourseTitle tid ssh csh MsgExamUsersHeading) $ do
|
||||||
setTitleI $ prependCourseTitle tid ssh csh MsgExamUsersHeading
|
setTitleI $ prependCourseTitle tid ssh csh MsgExamUsersHeading
|
||||||
|
|||||||
Reference in New Issue
Block a user