feat(exam-correct): return user lookup result even for failure
This commit is contained in:
parent
0d4dcf8658
commit
8e41820c9d
@ -1186,7 +1186,7 @@ MenuTutorialEdit: Tutorium editieren
|
|||||||
MenuTutorialComm: Mitteilung an Teilnehmer
|
MenuTutorialComm: Mitteilung an Teilnehmer
|
||||||
MenuExamList: Prüfungen
|
MenuExamList: Prüfungen
|
||||||
MenuExamNew: Neue Prüfung anlegen
|
MenuExamNew: Neue Prüfung anlegen
|
||||||
MenuExamEdit: Bearbeiten
|
MenuExamEdit: Prüfung bearbeiten
|
||||||
MenuExamUsers: Teilnehmer
|
MenuExamUsers: Teilnehmer
|
||||||
MenuExamGrades: Prüfungsleistungen
|
MenuExamGrades: Prüfungsleistungen
|
||||||
MenuExamAddMembers: Prüfungsteilnehmer hinzufügen
|
MenuExamAddMembers: Prüfungsteilnehmer hinzufügen
|
||||||
@ -1402,7 +1402,6 @@ ExamCorrectHeading examname@Text: Prüfungsergebnisse für #{examname} eintragen
|
|||||||
|
|
||||||
ExamCorrectHeadDate: Zeit
|
ExamCorrectHeadDate: Zeit
|
||||||
ExamCorrectHeadParticipant: Teilnehmer
|
ExamCorrectHeadParticipant: Teilnehmer
|
||||||
ExamCorrectHeadParticipantTooltip:
|
|
||||||
ExamCorrectHeadPart exampartnum@ExamPartNumber: #{exampartnum}
|
ExamCorrectHeadPart exampartnum@ExamPartNumber: #{exampartnum}
|
||||||
ExamCorrectHeadPartName exampartname@ExamPartName: #{exampartname}
|
ExamCorrectHeadPartName exampartname@ExamPartName: #{exampartname}
|
||||||
ExamCorrectHeadStatus: Status
|
ExamCorrectHeadStatus: Status
|
||||||
@ -1411,6 +1410,8 @@ ExamCorrectButtonSend: Senden
|
|||||||
|
|
||||||
ExamCorrectErrorMultipleMatchingParticipants: Dem Identifikator konnten mehrere Prüfungsteilnehmer zugeordnet werden.
|
ExamCorrectErrorMultipleMatchingParticipants: Dem Identifikator konnten mehrere Prüfungsteilnehmer zugeordnet werden.
|
||||||
ExamCorrectErrorNoMatchingParticipants: Dem Identifikator konnte kein Prüfungsteilnehmer zugeordnet werden.
|
ExamCorrectErrorNoMatchingParticipants: Dem Identifikator konnte kein Prüfungsteilnehmer zugeordnet werden.
|
||||||
|
ExamCorrectErrorPartResultOutOfBounds examPartNumber@ExamPartNumber: Prüfungsergebnis für Teil #{examPartNumber} ist nicht größer Null.
|
||||||
|
ExamCorrectErrorPartResultOutOfBoundsMax examPartNumber@ExamPartNumber maxPoints@Points: Prüfungsergebnis für Teil #{examPartNumber} liegt nicht zwischen 0 und #{maxPoints}.
|
||||||
|
|
||||||
SubmissionUserInvitationAccepted shn@SheetName: Sie wurden als Mitabgebende(r) für eine Abgabe zu #{shn} eingetragen
|
SubmissionUserInvitationAccepted shn@SheetName: Sie wurden als Mitabgebende(r) für eine Abgabe zu #{shn} eingetragen
|
||||||
SubmissionUserInvitationDeclined shn@SheetName: Sie haben die Einladung, Mitabgebende(r) für #{shn} zu werden, abgelehnt
|
SubmissionUserInvitationDeclined shn@SheetName: Sie haben die Einladung, Mitabgebende(r) für #{shn} zu werden, abgelehnt
|
||||||
|
|||||||
@ -1185,7 +1185,7 @@ MenuTutorialEdit: Edit tutorial
|
|||||||
MenuTutorialComm: Send course message
|
MenuTutorialComm: Send course message
|
||||||
MenuExamList: Exams
|
MenuExamList: Exams
|
||||||
MenuExamNew: Create new exam
|
MenuExamNew: Create new exam
|
||||||
MenuExamEdit: Edit
|
MenuExamEdit: Edit exam
|
||||||
MenuExamUsers: Participants
|
MenuExamUsers: Participants
|
||||||
MenuExamGrades: Exam results
|
MenuExamGrades: Exam results
|
||||||
MenuExamAddMembers: Add exam participants
|
MenuExamAddMembers: Add exam participants
|
||||||
@ -1408,6 +1408,8 @@ ExamCorrectButtonSend: Submit
|
|||||||
|
|
||||||
ExamCorrectErrorMultipleMatchingParticipants: This identifier matches on multiple exam participants.
|
ExamCorrectErrorMultipleMatchingParticipants: This identifier matches on multiple exam participants.
|
||||||
ExamCorrectErrorNoMatchingParticipants: This identifier does not match on any exam participant.
|
ExamCorrectErrorNoMatchingParticipants: This identifier does not match on any exam participant.
|
||||||
|
ExamCorrectErrorPartResultOutOfBounds examPartNumber: Exam part result for #{examPartNumber} ist not greater zero.
|
||||||
|
ExamCorrectErrorPartResultOutOfBoundsMax examPartNumber maxPoints: Exam part result for #{examPartNumber} is not between 0 and #{maxPoints}.
|
||||||
|
|
||||||
SubmissionUserInvitationAccepted shn: You now participate in a submission for #{shn}
|
SubmissionUserInvitationAccepted shn: You now participate in a submission for #{shn}
|
||||||
SubmissionUserInvitationDeclined shn: You have declined the invitation to participate in a submission for #{shn}
|
SubmissionUserInvitationDeclined shn: You have declined the invitation to participate in a submission for #{shn}
|
||||||
@ -1629,6 +1631,7 @@ ExamFormCorrection: Correction
|
|||||||
ExamFormParts: Exam parts
|
ExamFormParts: Exam parts
|
||||||
|
|
||||||
ExamCorrectors: Correctors
|
ExamCorrectors: Correctors
|
||||||
|
ExamCorrectorsTip: Correctors configured here may, after the start of the exam and until "Results visible from", enter exam part results for all exam parts and participants.
|
||||||
ExamCorrectorAlreadyAdded: A corrector with this email address already exists
|
ExamCorrectorAlreadyAdded: A corrector with this email address already exists
|
||||||
|
|
||||||
ExamParts: Exam parts/questions
|
ExamParts: Exam parts/questions
|
||||||
|
|||||||
@ -38,7 +38,8 @@ data CorrectInterfaceResponse
|
|||||||
, ciraMessage :: Text
|
, ciraMessage :: Text
|
||||||
}
|
}
|
||||||
| CorrectInterfaceResponseFailure
|
| CorrectInterfaceResponseFailure
|
||||||
{ cirfMessage :: Text
|
{ cirfUser :: Maybe CorrectInterfaceUser
|
||||||
|
, cirfMessage :: Text
|
||||||
}
|
}
|
||||||
| CorrectInterfaceResponseNoOp
|
| CorrectInterfaceResponseNoOp
|
||||||
{ cirnUsers :: Set CorrectInterfaceUser
|
{ cirnUsers :: Set CorrectInterfaceUser
|
||||||
@ -103,11 +104,11 @@ postECorrectR tid ssh csh examn = do
|
|||||||
|
|
||||||
CorrectInterfaceRequest{..} <- requireCheckJsonBody
|
CorrectInterfaceRequest{..} <- requireCheckJsonBody
|
||||||
|
|
||||||
response <- runDB $ do
|
response <- exceptT return return . hoist runDB $ do
|
||||||
Entity eId Exam{..} <- fetchExam tid ssh csh examn
|
Entity eId Exam{..} <- lift $ fetchExam tid ssh csh examn
|
||||||
euid <- traverse decrypt ciqUser
|
euid <- traverse decrypt ciqUser
|
||||||
|
|
||||||
participantMatches <- E.select . E.from $ \(examRegistration `E.InnerJoin` user) -> do
|
participantMatches <- lift . E.select . E.from $ \(examRegistration `E.InnerJoin` user) -> do
|
||||||
E.on $ examRegistration E.^. ExamRegistrationUser E.==. user E.^. UserId
|
E.on $ examRegistration E.^. ExamRegistrationUser E.==. user E.^. UserId
|
||||||
E.where_ $ examRegistration E.^. ExamRegistrationExam E.==. E.val eId
|
E.where_ $ examRegistration E.^. ExamRegistrationExam E.==. E.val eId
|
||||||
|
|
||||||
@ -150,10 +151,10 @@ postECorrectR tid ssh csh examn = do
|
|||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
newExamPartResults <- if
|
newExamPartResults <- if
|
||||||
| Just results <- ciqResults -> iforM (toNullable results) $ \partNumber mPartResult -> do
|
| Just results <- ciqResults -> iforM (toNullable results) $ \partNumber mPartResult -> do
|
||||||
(Entity examPartId ExamPart{..}) <- getBy404 $ UniqueExamPartNumber eId partNumber
|
(Entity examPartId ExamPart{..}) <- lift . getBy404 $ UniqueExamPartNumber eId partNumber
|
||||||
mOldResult <- getBy $ UniqueExamPartResult examPartId uid
|
mOldResult <- lift . getBy $ UniqueExamPartResult examPartId uid
|
||||||
if
|
if
|
||||||
| Just (Entity oldId _) <- mOldResult, is _Nothing mPartResult -> do
|
| Just (Entity oldId _) <- mOldResult, is _Nothing mPartResult -> lift $ do
|
||||||
delete oldId
|
delete oldId
|
||||||
audit $ TransactionExamPartResultDeleted examPartId uid
|
audit $ TransactionExamPartResultDeleted examPartId uid
|
||||||
return Nothing
|
return Nothing
|
||||||
@ -162,29 +163,36 @@ postECorrectR tid ssh csh examn = do
|
|||||||
mNew = ExamAttended <$> mPartResult
|
mNew = ExamAttended <$> mPartResult
|
||||||
resultVal = _entityVal . _examPartResultResult
|
resultVal = _entityVal . _examPartResultResult
|
||||||
in if
|
in if
|
||||||
| mOld /= mNew -> let
|
| mOld /= mNew -> do
|
||||||
-- cut off part results that exceed the maximum number of points for this exam part for now
|
let
|
||||||
-- TODO answer with new failure response type instead
|
partResultAcceptable = 0 <= partResult
|
||||||
partResult' = if
|
&& maybe True (partResult <=) examPartMaxPoints
|
||||||
| Just maxPts <- examPartMaxPoints, maxPts < partResult -> maxPts
|
guardMExceptT partResultAcceptable $
|
||||||
| otherwise -> partResult
|
let
|
||||||
in do
|
msg | Just maxPoints <- examPartMaxPoints
|
||||||
newExamPartResult <- upsert ExamPartResult
|
= MsgExamCorrectErrorPartResultOutOfBoundsMax partNumber maxPoints
|
||||||
|
| otherwise
|
||||||
|
= MsgExamCorrectErrorPartResultOutOfBounds partNumber
|
||||||
|
in CorrectInterfaceResponseFailure
|
||||||
|
<$> (Just <$> userToResponse match)
|
||||||
|
<*> (getMessageRender <*> pure msg)
|
||||||
|
|
||||||
|
newExamPartResult <- lift $ upsert ExamPartResult
|
||||||
{ examPartResultExamPart = examPartId
|
{ examPartResultExamPart = examPartId
|
||||||
, examPartResultUser = uid
|
, examPartResultUser = uid
|
||||||
, examPartResultResult = ExamAttended partResult'
|
, examPartResultResult = ExamAttended partResult
|
||||||
, examPartResultLastChanged = now
|
, examPartResultLastChanged = now
|
||||||
}
|
}
|
||||||
[ ExamPartResultResult =. ExamAttended partResult'
|
[ ExamPartResultResult =. ExamAttended partResult
|
||||||
, ExamPartResultLastChanged =. now
|
, ExamPartResultLastChanged =. now
|
||||||
]
|
]
|
||||||
audit $ TransactionExamPartResultEdit examPartId uid
|
lift . audit $ TransactionExamPartResultEdit examPartId uid
|
||||||
return $ newExamPartResult ^? resultVal
|
return $ newExamPartResult ^? resultVal
|
||||||
| otherwise -> return $ mOldResult ^? _Just . resultVal
|
| otherwise -> return $ mOldResult ^? _Just . resultVal
|
||||||
| otherwise -> return Nothing
|
| otherwise -> return Nothing
|
||||||
| otherwise -> return mempty
|
| otherwise -> return mempty
|
||||||
|
|
||||||
newExamResult <- do
|
newExamResult <- lift $ do
|
||||||
mOldResult <- getBy $ UniqueExamResult eId uid
|
mOldResult <- getBy $ UniqueExamResult eId uid
|
||||||
if
|
if
|
||||||
| Just (Entity oldId _) <- mOldResult, is _Nothing ciqGrade -> do
|
| Just (Entity oldId _) <- mOldResult, is _Nothing ciqGrade -> do
|
||||||
@ -222,7 +230,8 @@ postECorrectR tid ssh csh examn = do
|
|||||||
|
|
||||||
-- on match with no exam participant, answer with 400
|
-- on match with no exam participant, answer with 400
|
||||||
| [] <- participantMatches -> return CorrectInterfaceResponseFailure
|
| [] <- participantMatches -> return CorrectInterfaceResponseFailure
|
||||||
{ cirfMessage = mr MsgExamCorrectErrorNoMatchingParticipants
|
{ cirfUser = Nothing
|
||||||
|
, cirfMessage = mr MsgExamCorrectErrorNoMatchingParticipants
|
||||||
}
|
}
|
||||||
|
|
||||||
-- on match with multiple exam participants, answer with 400 and a set of all matches
|
-- on match with multiple exam participants, answer with 400 and a set of all matches
|
||||||
|
|||||||
Reference in New Issue
Block a user