feat(exams): refine exam form
This commit is contained in:
parent
f7a92a4ce5
commit
014a17a3be
@ -1329,17 +1329,20 @@ ExamClosedTip: Prüfungsämter, die im System Noten einsehen, werden zu diesem Z
|
|||||||
ExamShowGrades: Klausur ist benotet
|
ExamShowGrades: Klausur ist benotet
|
||||||
ExamShowGradesTip: Sollen genaue Noten angezeigt werden, oder sollen Teilnehmer und Prüfungsämter nur informiert werden, ob die Klausur bestanden wurde?
|
ExamShowGradesTip: Sollen genaue Noten angezeigt werden, oder sollen Teilnehmer und Prüfungsämter nur informiert werden, ob die Klausur bestanden wurde?
|
||||||
ExamPublicStatistics: Statistik veröffentlichen
|
ExamPublicStatistics: Statistik veröffentlichen
|
||||||
ExamPublicStatisticsTip: Soll die statistische Auswertung auch den Teilnehmern angezeigt werden, sobald diese ihre Noten einsehen können?
|
ExamPublicStatisticsTip: Soll die automatisch berechnete statistische Auswertung auch den Teilnehmern angezeigt werden, sobald diese ihre Noten einsehen können?
|
||||||
|
ExamAutomaticGrading: Automatische Notenberechnung
|
||||||
|
ExamAutomaticGradingTip: Sollen die Gesamtleistungen der Teilnehmer automatisch aus den in den einzelnen Teilprüfungen erreichten Leistungen berechnet werden? Etwaige Bonuspunkte werden dabei berücksichtigt. Manuelles Überschreiben der Gesamtleistung ist dennoch möglich.
|
||||||
ExamGradingRule: Notenberechnung
|
ExamGradingRule: Notenberechnung
|
||||||
ExamGradingManual': Keine automatische Berechnung
|
ExamGradingManual': Keine automatische Berechnung
|
||||||
ExamGradingKey': Nach Schlüssel
|
ExamGradingKey': Nach Schlüssel
|
||||||
ExamGradingKey: Notenschlüssel
|
ExamGradingKey: Notenschlüssel
|
||||||
ExamGradingKeyTip: Die Grenzen beziehen sich auf die effektive Maximalpunktzahl, nachdem etwaige Bonuspunkte aus dem Übungsbetrieb angerechnet und die Ergebnise der Teilaufgaben mit ihrem Gewicht multipliziert wurden
|
ExamGradingKeyTip: Die Grenzen beziehen sich auf die effektive Maximalpunktzahl, nachdem etwaige Bonuspunkte aus dem Übungsbetrieb angerechnet und die Ergebnise der Teilprüfungen mit ihrem Gewicht multipliziert wurden
|
||||||
Points: Punkte
|
Points: Punkte
|
||||||
PointsMustBeNonNegative: Punktegrenzen dürfen nicht negativ sein
|
PointsMustBeNonNegative: Punktegrenzen dürfen nicht negativ sein
|
||||||
PointsMustBeMonotonic: Punktegrenzen müssen aufsteigend sein
|
PointsMustBeMonotonic: Punktegrenzen müssen aufsteigend sein
|
||||||
GradingFrom: Ab
|
GradingFrom: Ab
|
||||||
ExamNew: Neue Prüfung
|
ExamNew: Neue Prüfung
|
||||||
|
ExamBonus: Bonuspunkte-System
|
||||||
ExamBonusRule: Prüfungsbonus aus Übungsbetrieb
|
ExamBonusRule: Prüfungsbonus aus Übungsbetrieb
|
||||||
ExamNoBonus': Kein automatischer Bonus
|
ExamNoBonus': Kein automatischer Bonus
|
||||||
ExamBonusPoints': Umrechnung von Übungspunkten
|
ExamBonusPoints': Umrechnung von Übungspunkten
|
||||||
@ -1350,7 +1353,9 @@ ExamBonusMaxPoints: Maximal erreichbare Prüfungs-Bonuspunkte
|
|||||||
ExamBonusMaxPointsNonPositive: Maximaler Prüfungsbonus muss positiv und größer null sein
|
ExamBonusMaxPointsNonPositive: Maximaler Prüfungsbonus muss positiv und größer null sein
|
||||||
ExamBonusOnlyPassed: Bonus nur nach Bestehen anrechnen
|
ExamBonusOnlyPassed: Bonus nur nach Bestehen anrechnen
|
||||||
|
|
||||||
ExamOccurrenceRule: Automatische Termin- bzw. Raumzuteilung
|
ExamAutomaticOccurrenceAssignment: Automatische Termin- bzw. Raumzuteilung
|
||||||
|
ExamAutomaticOccurrenceAssignmentTip: Sollen Prüfungsteilnehmer zum Zeitpunkt der Bekanntgabe der Raum- bzw. Terminzuteilung automatisch auf die zur Verfügung stehenden Räume bzw. Termine verteilt werden? Manuelle Umverteilung bzw. vorheriges Festlegen von Zuteilungen einzelner Teilnehmer ist trotzdem möglich.
|
||||||
|
ExamOccurrenceRule: Verfahren
|
||||||
ExamOccurrenceRuleParticipant: Termin- bzw. Raumzuteilungsverfahren
|
ExamOccurrenceRuleParticipant: Termin- bzw. Raumzuteilungsverfahren
|
||||||
ExamRoomManual': Keine automatische Zuteilung
|
ExamRoomManual': Keine automatische Zuteilung
|
||||||
ExamRoomSurname': Nach Nachname
|
ExamRoomSurname': Nach Nachname
|
||||||
@ -1384,9 +1389,9 @@ ExamFormParts: Teile
|
|||||||
ExamCorrectors: Korrektoren
|
ExamCorrectors: Korrektoren
|
||||||
ExamCorrectorAlreadyAdded: Ein Korrektor mit dieser E-Mail ist bereits für diese Prüfung eingetragen
|
ExamCorrectorAlreadyAdded: Ein Korrektor mit dieser E-Mail ist bereits für diese Prüfung eingetragen
|
||||||
|
|
||||||
ExamParts: Teilaufgaben
|
ExamParts: Teilprüfungen/Aufgaben
|
||||||
ExamPartWeightNegative: Gewicht aller Teilaufgaben muss größer oder gleich Null sein
|
ExamPartWeightNegative: Gewicht aller Teilprüfungen muss größer oder gleich Null sein
|
||||||
ExamPartAlreadyExists: Teilaufgabe mit diesem Namen existiert bereits
|
ExamPartAlreadyExists: Teilprüfunge mit diesem Namen existiert bereits
|
||||||
ExamPartNumber: Nummer
|
ExamPartNumber: Nummer
|
||||||
ExamPartNumberTip: Wird als interne Bezeichnung z.B. bei CSV-Export verwendet
|
ExamPartNumberTip: Wird als interne Bezeichnung z.B. bei CSV-Export verwendet
|
||||||
ExamPartName: Name
|
ExamPartName: Name
|
||||||
@ -1524,7 +1529,7 @@ ExamUserCsvDeregister: Teilnehmer von der Prüfung abmelden
|
|||||||
ExamUserCsvSetCourseField: Kurs-assoziiertes Studienfach ändern
|
ExamUserCsvSetCourseField: Kurs-assoziiertes Studienfach ändern
|
||||||
ExamUserCsvOverrideResult: Ergebnis entgegen automatischer Notenberechnung überschreiben
|
ExamUserCsvOverrideResult: Ergebnis entgegen automatischer Notenberechnung überschreiben
|
||||||
ExamUserCsvSetResult: Ergebnis eintragen
|
ExamUserCsvSetResult: Ergebnis eintragen
|
||||||
ExamUserCsvSetPartResult: Ergebnis einer Teilaufgabe eintragen
|
ExamUserCsvSetPartResult: Ergebnis einer Teilprüfung eintragen
|
||||||
ExamUserCsvSetCourseNote: Teilnehmer-Notizen anpassen
|
ExamUserCsvSetCourseNote: Teilnehmer-Notizen anpassen
|
||||||
|
|
||||||
ExamUserCsvCourseNoteDeleted: Notiz wird gelöscht
|
ExamUserCsvCourseNoteDeleted: Notiz wird gelöscht
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
Exam
|
Exam
|
||||||
course CourseId
|
course CourseId
|
||||||
name ExamName
|
name ExamName
|
||||||
gradingRule ExamGradingRule
|
gradingRule ExamGradingRule Maybe
|
||||||
bonusRule ExamBonusRule
|
bonusRule ExamBonusRule Maybe
|
||||||
occurrenceRule ExamOccurrenceRule
|
occurrenceRule ExamOccurrenceRule Maybe
|
||||||
visibleFrom UTCTime Maybe
|
visibleFrom UTCTime Maybe
|
||||||
registerFrom UTCTime Maybe
|
registerFrom UTCTime Maybe
|
||||||
registerTo UTCTime Maybe
|
registerTo UTCTime Maybe
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import Text.Blaze.Html.Renderer.String (renderHtml)
|
|||||||
data ExamForm = ExamForm
|
data ExamForm = ExamForm
|
||||||
{ efName :: ExamName
|
{ efName :: ExamName
|
||||||
, efDescription :: Maybe Html
|
, efDescription :: Maybe Html
|
||||||
|
, efShowGrades :: Bool
|
||||||
, efStart :: Maybe UTCTime
|
, efStart :: Maybe UTCTime
|
||||||
, efEnd :: Maybe UTCTime
|
, efEnd :: Maybe UTCTime
|
||||||
, efVisibleFrom :: Maybe UTCTime
|
, efVisibleFrom :: Maybe UTCTime
|
||||||
@ -35,11 +36,10 @@ data ExamForm = ExamForm
|
|||||||
, efPublishOccurrenceAssignments :: Maybe UTCTime
|
, efPublishOccurrenceAssignments :: Maybe UTCTime
|
||||||
, efFinished :: Maybe UTCTime
|
, efFinished :: Maybe UTCTime
|
||||||
, efOccurrences :: Set ExamOccurrenceForm
|
, efOccurrences :: Set ExamOccurrenceForm
|
||||||
, efShowGrades :: Bool
|
|
||||||
, efPublicStatistics :: Bool
|
, efPublicStatistics :: Bool
|
||||||
, efGradingRule :: ExamGradingRule
|
, efGradingRule :: Maybe ExamGradingRule
|
||||||
, efBonusRule :: ExamBonusRule
|
, efBonusRule :: Maybe ExamBonusRule
|
||||||
, efOccurrenceRule :: ExamOccurrenceRule
|
, efOccurrenceRule :: Maybe ExamOccurrenceRule
|
||||||
, efCorrectors :: Set (Either UserEmail UserId)
|
, efCorrectors :: Set (Either UserEmail UserId)
|
||||||
, efExamParts :: Set ExamPartForm
|
, efExamParts :: Set ExamPartForm
|
||||||
}
|
}
|
||||||
@ -80,6 +80,7 @@ examForm template html = do
|
|||||||
flip (renderAForm FormStandard) html $ ExamForm
|
flip (renderAForm FormStandard) html $ ExamForm
|
||||||
<$> areq ciField (fslpI MsgExamName (mr MsgExamName) & setTooltip MsgExamNameTip) (efName <$> template)
|
<$> areq ciField (fslpI MsgExamName (mr MsgExamName) & setTooltip MsgExamNameTip) (efName <$> template)
|
||||||
<*> (assertM (not . null . renderHtml) <$> aopt htmlField (fslpI MsgExamDescription "Html") (efDescription <$> template))
|
<*> (assertM (not . null . renderHtml) <$> aopt htmlField (fslpI MsgExamDescription "Html") (efDescription <$> template))
|
||||||
|
<*> apopt checkBoxField (fslI MsgExamShowGrades & setTooltip MsgExamShowGradesTip) (efShowGrades <$> template <|> Just True)
|
||||||
<* aformSection MsgExamFormTimes
|
<* aformSection MsgExamFormTimes
|
||||||
<*> aopt utcTimeField (fslpI MsgExamStart (mr MsgDate) & setTooltip MsgExamTimeTip) (efStart <$> template)
|
<*> aopt utcTimeField (fslpI MsgExamStart (mr MsgDate) & setTooltip MsgExamTimeTip) (efStart <$> template)
|
||||||
<*> aopt utcTimeField (fslpI MsgExamEnd (mr MsgDate) & setTooltip MsgExamTimeTip) (efEnd <$> template)
|
<*> aopt utcTimeField (fslpI MsgExamEnd (mr MsgDate) & setTooltip MsgExamTimeTip) (efEnd <$> template)
|
||||||
@ -92,11 +93,10 @@ examForm template html = do
|
|||||||
<* aformSection MsgExamFormOccurrences
|
<* aformSection MsgExamFormOccurrences
|
||||||
<*> examOccurrenceForm (efOccurrences <$> template)
|
<*> examOccurrenceForm (efOccurrences <$> template)
|
||||||
<* aformSection MsgExamFormAutomaticFunctions
|
<* aformSection MsgExamFormAutomaticFunctions
|
||||||
<*> apopt checkBoxField (fslI MsgExamShowGrades & setTooltip MsgExamShowGradesTip) (efShowGrades <$> template <|> Just True)
|
|
||||||
<*> apopt checkBoxField (fslI MsgExamPublicStatistics & setTooltip MsgExamPublicStatisticsTip) (efPublicStatistics <$> template <|> Just True)
|
<*> apopt checkBoxField (fslI MsgExamPublicStatistics & setTooltip MsgExamPublicStatisticsTip) (efPublicStatistics <$> template <|> Just True)
|
||||||
<*> examGradingRuleForm (efGradingRule <$> template)
|
<*> optionalActionA (examGradingRuleForm $ efGradingRule =<< template) (fslI MsgExamAutomaticGrading & setTooltip MsgExamAutomaticGradingTip) (is _Just . efGradingRule <$> template)
|
||||||
<*> examBonusRuleForm (efBonusRule <$> template)
|
<*> optionalActionA (examBonusRuleForm $ efBonusRule =<< template) (fslI MsgExamBonus) (is _Just . efBonusRule <$> template)
|
||||||
<*> examOccurrenceRuleForm (efOccurrenceRule <$> template)
|
<*> optionalActionA (examOccurrenceRuleForm $ efOccurrenceRule =<< template) (fslI MsgExamAutomaticOccurrenceAssignment & setTooltip MsgExamAutomaticOccurrenceAssignmentTip) (is _Just . efOccurrenceRule <$> template)
|
||||||
<* aformSection MsgExamFormCorrection
|
<* aformSection MsgExamFormCorrection
|
||||||
<*> examCorrectorsForm (efCorrectors <$> template)
|
<*> examCorrectorsForm (efCorrectors <$> template)
|
||||||
<* aformSection MsgExamFormParts
|
<* aformSection MsgExamFormParts
|
||||||
|
|||||||
@ -103,7 +103,7 @@ examGrade (Entity _ Exam{..}) bonusPossible bonusAchieved (otoList -> results)
|
|||||||
|
|
||||||
withBonus :: Points -> Points
|
withBonus :: Points -> Points
|
||||||
withBonus ps
|
withBonus ps
|
||||||
| ExamBonusPoints{..} <- examBonusRule
|
| Just ExamBonusPoints{..} <- examBonusRule
|
||||||
= if
|
= if
|
||||||
| not bonusOnlyPassed
|
| not bonusOnlyPassed
|
||||||
|| fmap (view passingGrade) (pointsToGrade ps) == Just (_Wrapped # True)
|
|| fmap (view passingGrade) (pointsToGrade ps) == Just (_Wrapped # True)
|
||||||
@ -126,7 +126,7 @@ examGrade (Entity _ Exam{..}) bonusPossible bonusAchieved (otoList -> results)
|
|||||||
|
|
||||||
pointsToGrade :: Points -> Maybe ExamGrade
|
pointsToGrade :: Points -> Maybe ExamGrade
|
||||||
pointsToGrade ps
|
pointsToGrade ps
|
||||||
| ExamGradingKey{..} <- examGradingRule
|
| Just ExamGradingKey{..} <- examGradingRule
|
||||||
= Just $ gradeFromKey examGradingKey
|
= Just $ gradeFromKey examGradingKey
|
||||||
| otherwise
|
| otherwise
|
||||||
= Nothing
|
= Nothing
|
||||||
|
|||||||
@ -518,8 +518,7 @@ submissionModeForm prev = multiActionA actions (fslI MsgSheetSubmissionMode) $ c
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
data ExamBonusRule' = ExamNoBonus'
|
data ExamBonusRule' = ExamBonusPoints'
|
||||||
| ExamBonusPoints'
|
|
||||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
||||||
instance Universe ExamBonusRule'
|
instance Universe ExamBonusRule'
|
||||||
instance Finite ExamBonusRule'
|
instance Finite ExamBonusRule'
|
||||||
@ -529,7 +528,6 @@ embedRenderMessage ''UniWorX ''ExamBonusRule' id
|
|||||||
|
|
||||||
classifyBonusRule :: ExamBonusRule -> ExamBonusRule'
|
classifyBonusRule :: ExamBonusRule -> ExamBonusRule'
|
||||||
classifyBonusRule = \case
|
classifyBonusRule = \case
|
||||||
ExamNoBonus -> ExamNoBonus'
|
|
||||||
ExamBonusPoints{} -> ExamBonusPoints'
|
ExamBonusPoints{} -> ExamBonusPoints'
|
||||||
|
|
||||||
examBonusRuleForm :: Maybe ExamBonusRule -> AForm Handler ExamBonusRule
|
examBonusRuleForm :: Maybe ExamBonusRule -> AForm Handler ExamBonusRule
|
||||||
@ -537,18 +535,14 @@ examBonusRuleForm prev = multiActionA actions (fslI MsgExamBonusRule) $ classify
|
|||||||
where
|
where
|
||||||
actions :: Map ExamBonusRule' (AForm Handler ExamBonusRule)
|
actions :: Map ExamBonusRule' (AForm Handler ExamBonusRule)
|
||||||
actions = Map.fromList
|
actions = Map.fromList
|
||||||
[ ( ExamNoBonus'
|
[ ( ExamBonusPoints'
|
||||||
, pure ExamNoBonus
|
|
||||||
)
|
|
||||||
, ( ExamBonusPoints'
|
|
||||||
, ExamBonusPoints
|
, ExamBonusPoints
|
||||||
<$> apreq (checkBool (> 0) MsgExamBonusMaxPointsNonPositive pointsField) (fslI MsgExamBonusMaxPoints) (preview _bonusMaxPoints =<< prev)
|
<$> apreq (checkBool (> 0) MsgExamBonusMaxPointsNonPositive pointsField) (fslI MsgExamBonusMaxPoints) (preview _bonusMaxPoints =<< prev)
|
||||||
<*> (fromMaybe False <$> aopt checkBoxField (fslI MsgExamBonusOnlyPassed) (Just <$> preview _bonusOnlyPassed =<< prev))
|
<*> (fromMaybe False <$> aopt checkBoxField (fslI MsgExamBonusOnlyPassed) (Just <$> preview _bonusOnlyPassed =<< prev))
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
data ExamOccurrenceRule' = ExamRoomManual'
|
data ExamOccurrenceRule' = ExamRoomSurname'
|
||||||
| ExamRoomSurname'
|
|
||||||
| ExamRoomMatriculation'
|
| ExamRoomMatriculation'
|
||||||
| ExamRoomRandom'
|
| ExamRoomRandom'
|
||||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
||||||
@ -560,7 +554,6 @@ embedRenderMessage ''UniWorX ''ExamOccurrenceRule' id
|
|||||||
|
|
||||||
classifyExamOccurrenceRule :: ExamOccurrenceRule -> ExamOccurrenceRule'
|
classifyExamOccurrenceRule :: ExamOccurrenceRule -> ExamOccurrenceRule'
|
||||||
classifyExamOccurrenceRule = \case
|
classifyExamOccurrenceRule = \case
|
||||||
ExamRoomManual -> ExamRoomManual'
|
|
||||||
ExamRoomSurname -> ExamRoomSurname'
|
ExamRoomSurname -> ExamRoomSurname'
|
||||||
ExamRoomMatriculation -> ExamRoomMatriculation'
|
ExamRoomMatriculation -> ExamRoomMatriculation'
|
||||||
ExamRoomRandom -> ExamRoomRandom'
|
ExamRoomRandom -> ExamRoomRandom'
|
||||||
@ -569,13 +562,11 @@ examOccurrenceRuleForm :: Maybe ExamOccurrenceRule -> AForm Handler ExamOccurren
|
|||||||
examOccurrenceRuleForm = fmap reverseClassify . areq (selectField optionsFinite) (fslI MsgExamOccurrenceRule) . fmap classifyExamOccurrenceRule
|
examOccurrenceRuleForm = fmap reverseClassify . areq (selectField optionsFinite) (fslI MsgExamOccurrenceRule) . fmap classifyExamOccurrenceRule
|
||||||
where
|
where
|
||||||
reverseClassify = \case
|
reverseClassify = \case
|
||||||
ExamRoomManual' -> ExamRoomManual
|
|
||||||
ExamRoomSurname' -> ExamRoomSurname
|
ExamRoomSurname' -> ExamRoomSurname
|
||||||
ExamRoomMatriculation' -> ExamRoomMatriculation
|
ExamRoomMatriculation' -> ExamRoomMatriculation
|
||||||
ExamRoomRandom' -> ExamRoomRandom
|
ExamRoomRandom' -> ExamRoomRandom
|
||||||
|
|
||||||
data ExamGradingRule' = ExamGradingManual'
|
data ExamGradingRule' = ExamGradingKey'
|
||||||
| ExamGradingKey'
|
|
||||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
||||||
instance Universe ExamGradingRule'
|
instance Universe ExamGradingRule'
|
||||||
instance Finite ExamGradingRule'
|
instance Finite ExamGradingRule'
|
||||||
@ -585,7 +576,6 @@ embedRenderMessage ''UniWorX ''ExamGradingRule' id
|
|||||||
|
|
||||||
classifyExamGradingRule :: ExamGradingRule -> ExamGradingRule'
|
classifyExamGradingRule :: ExamGradingRule -> ExamGradingRule'
|
||||||
classifyExamGradingRule = \case
|
classifyExamGradingRule = \case
|
||||||
ExamGradingManual -> ExamGradingManual'
|
|
||||||
ExamGradingKey{} -> ExamGradingKey'
|
ExamGradingKey{} -> ExamGradingKey'
|
||||||
|
|
||||||
examGradingRuleForm :: Maybe ExamGradingRule -> AForm Handler ExamGradingRule
|
examGradingRuleForm :: Maybe ExamGradingRule -> AForm Handler ExamGradingRule
|
||||||
@ -593,10 +583,7 @@ examGradingRuleForm prev = multiActionA actions (fslI MsgExamGradingRule) $ clas
|
|||||||
where
|
where
|
||||||
actions :: Map ExamGradingRule' (AForm Handler ExamGradingRule)
|
actions :: Map ExamGradingRule' (AForm Handler ExamGradingRule)
|
||||||
actions = Map.fromList
|
actions = Map.fromList
|
||||||
[ ( ExamGradingManual'
|
[ ( ExamGradingKey'
|
||||||
, pure ExamGradingManual
|
|
||||||
)
|
|
||||||
, ( ExamGradingKey'
|
|
||||||
, ExamGradingKey <$> gradingKeyForm (fslI MsgExamGradingKey & setTooltip MsgExamGradingKeyTip) (preview _examGradingKey =<< prev)
|
, ExamGradingKey <$> gradingKeyForm (fslI MsgExamGradingKey & setTooltip MsgExamGradingKeyTip) (preview _examGradingKey =<< prev)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@ -523,6 +523,20 @@ customMigrations = Map.fromListWith (>>)
|
|||||||
renameExamParts _ = return ()
|
renameExamParts _ = return ()
|
||||||
runConduit $ getExamEntries .| C.mapM_ renameExamParts
|
runConduit $ getExamEntries .| C.mapM_ renameExamParts
|
||||||
)
|
)
|
||||||
|
, ( AppliedMigrationKey [migrationVersion|21.0.0|] [version|22.0.0|]
|
||||||
|
, whenM (tableExists "exam") $
|
||||||
|
[executeQQ|
|
||||||
|
ALTER TABLE "exam" ALTER COLUMN "grading_rule" DROP NOT NULL;
|
||||||
|
ALTER TABLE "exam" ALTER COLUMN "bonus_rule" DROP NOT NULL;
|
||||||
|
ALTER TABLE "exam" ALTER COLUMN "occurrence_rule" DROP NOT NULL;
|
||||||
|
|
||||||
|
UPDATE "exam" SET "grading_rule" = NULL WHERE "grading_rule" = '{ "rule": "manual" }';
|
||||||
|
UPDATE "exam" SET "bonus_rule" = NULL WHERE "bonus_rule" = '{ "rule": "no-bonus"}';
|
||||||
|
UPDATE "exam" SET "occurrence_rule" = NULL WHERE "occurrence_rule" = '"manual"';
|
||||||
|
|
||||||
|
UPDATE "exam" SET "occurrence_rule" = json_build_object('rule', "occurrence_rule");
|
||||||
|
|]
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -116,28 +116,32 @@ instance Universe res => Universe (ExamResult' res) where
|
|||||||
instance Finite res => Finite (ExamResult' res)
|
instance Finite res => Finite (ExamResult' res)
|
||||||
|
|
||||||
|
|
||||||
data ExamBonusRule = ExamNoBonus
|
data ExamBonusRule = ExamBonusPoints
|
||||||
| ExamBonusPoints
|
|
||||||
{ bonusMaxPoints :: Points
|
{ bonusMaxPoints :: Points
|
||||||
, bonusOnlyPassed :: Bool
|
, bonusOnlyPassed :: Bool
|
||||||
}
|
}
|
||||||
deriving (Show, Read, Eq, Ord, Generic, Typeable)
|
deriving (Show, Read, Eq, Ord, Generic, Typeable)
|
||||||
deriveJSON defaultOptions
|
deriveJSON defaultOptions
|
||||||
{ constructorTagModifier = camelToPathPiece' 1
|
{ fieldLabelModifier = camelToPathPiece' 1
|
||||||
, fieldLabelModifier = camelToPathPiece' 1
|
, constructorTagModifier = camelToPathPiece' 1
|
||||||
|
, allNullaryToStringTag = False
|
||||||
, sumEncoding = TaggedObject "rule" "settings"
|
, sumEncoding = TaggedObject "rule" "settings"
|
||||||
|
, unwrapUnaryRecords = False
|
||||||
|
, tagSingleConstructors = True
|
||||||
} ''ExamBonusRule
|
} ''ExamBonusRule
|
||||||
derivePersistFieldJSON ''ExamBonusRule
|
derivePersistFieldJSON ''ExamBonusRule
|
||||||
|
|
||||||
data ExamOccurrenceRule = ExamRoomManual
|
data ExamOccurrenceRule = ExamRoomSurname
|
||||||
| ExamRoomSurname
|
|
||||||
| ExamRoomMatriculation
|
| ExamRoomMatriculation
|
||||||
| ExamRoomRandom
|
| ExamRoomRandom
|
||||||
deriving (Show, Read, Eq, Ord, Generic, Typeable)
|
deriving (Show, Read, Eq, Ord, Generic, Typeable)
|
||||||
deriveJSON defaultOptions
|
deriveJSON defaultOptions
|
||||||
{ constructorTagModifier = camelToPathPiece' 2
|
{ fieldLabelModifier = camelToPathPiece' 1
|
||||||
, fieldLabelModifier = camelToPathPiece' 1
|
, constructorTagModifier = camelToPathPiece' 2
|
||||||
|
, allNullaryToStringTag = False
|
||||||
, sumEncoding = TaggedObject "rule" "settings"
|
, sumEncoding = TaggedObject "rule" "settings"
|
||||||
|
, unwrapUnaryRecords = False
|
||||||
|
, tagSingleConstructors = True
|
||||||
} ''ExamOccurrenceRule
|
} ''ExamOccurrenceRule
|
||||||
derivePersistFieldJSON ''ExamOccurrenceRule
|
derivePersistFieldJSON ''ExamOccurrenceRule
|
||||||
|
|
||||||
@ -211,15 +215,17 @@ instance PersistFieldSql ExamGrade where
|
|||||||
|
|
||||||
|
|
||||||
data ExamGradingRule
|
data ExamGradingRule
|
||||||
= ExamGradingManual
|
= ExamGradingKey
|
||||||
| ExamGradingKey
|
|
||||||
{ examGradingKey :: [Points] -- ^ @[n1, n2, n3, ..., n11]@ means @0 <= p < n1 -> p ~= 5@, @n1 <= p < n2 -> p ~ 4@, @n2 <= p < n3 -> p ~ 3.7@, ..., @n10 <= p -> p ~ 1.0@
|
{ examGradingKey :: [Points] -- ^ @[n1, n2, n3, ..., n11]@ means @0 <= p < n1 -> p ~= 5@, @n1 <= p < n2 -> p ~ 4@, @n2 <= p < n3 -> p ~ 3.7@, ..., @n10 <= p -> p ~ 1.0@
|
||||||
}
|
}
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||||
deriveJSON defaultOptions
|
deriveJSON defaultOptions
|
||||||
{ constructorTagModifier = camelToPathPiece' 2
|
{ fieldLabelModifier = camelToPathPiece' 2
|
||||||
, fieldLabelModifier = camelToPathPiece' 2
|
, constructorTagModifier = camelToPathPiece' 2
|
||||||
|
, allNullaryToStringTag = False
|
||||||
, sumEncoding = TaggedObject "rule" "settings"
|
, sumEncoding = TaggedObject "rule" "settings"
|
||||||
|
, unwrapUnaryRecords = False
|
||||||
|
, tagSingleConstructors = True
|
||||||
} ''ExamGradingRule
|
} ''ExamGradingRule
|
||||||
derivePersistFieldJSON ''ExamGradingRule
|
derivePersistFieldJSON ''ExamGradingRule
|
||||||
|
|
||||||
|
|||||||
@ -59,31 +59,30 @@ $maybe desc <- examDescription
|
|||||||
<dt .deflist__dt>_{MsgExamClosed}
|
<dt .deflist__dt>_{MsgExamClosed}
|
||||||
<dd .deflist__dd>^{formatTimeW SelFormatDateTime closed}
|
<dd .deflist__dd>^{formatTimeW SelFormatDateTime closed}
|
||||||
$if gradingShown
|
$if gradingShown
|
||||||
$if examGradingRule /= ExamGradingManual
|
$maybe gradingRule <- examGradingRule
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
_{MsgExamGradingRule}
|
_{MsgExamGradingRule}
|
||||||
$if not gradingVisible
|
$if not gradingVisible
|
||||||
\ ^{isVisible False}
|
\ ^{isVisible False}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
$case examGradingRule
|
$case gradingRule
|
||||||
$of ExamGradingManual
|
|
||||||
_{MsgExamGradingManual'}
|
|
||||||
$of ExamGradingKey{..}
|
$of ExamGradingKey{..}
|
||||||
^{gradingKeyW examGradingKey}
|
^{gradingKeyW examGradingKey}
|
||||||
$if examBonusRule /= ExamNoBonus
|
$maybe bonusRule <- examBonusRule
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
_{MsgExamBonusRule}
|
_{MsgExamBonusRule}
|
||||||
$if not gradingVisible
|
$if not gradingVisible
|
||||||
\ ^{isVisible False}
|
\ ^{isVisible False}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
^{examBonusW examBonusRule}
|
^{examBonusW bonusRule}
|
||||||
$if occurrenceAssignmentsShown
|
$maybe occurrenceRule <- examOccurrenceRule
|
||||||
<dt .deflist__dt>
|
$if occurrenceAssignmentsShown
|
||||||
_{MsgExamOccurrenceRuleParticipant}
|
<dt .deflist__dt>
|
||||||
$if not occurrenceAssignmentsVisible
|
_{MsgExamOccurrenceRuleParticipant}
|
||||||
\ ^{isVisible False}
|
$if not occurrenceAssignmentsVisible
|
||||||
<dd .deflist__dd>
|
\ ^{isVisible False}
|
||||||
_{classifyExamOccurrenceRule examOccurrenceRule}
|
<dd .deflist__dd>
|
||||||
|
_{classifyExamOccurrenceRule occurrenceRule}
|
||||||
$maybe registerWdgt <- registerWidget
|
$maybe registerWdgt <- registerWidget
|
||||||
<dt .deflist__dt>_{MsgExamRegistration}
|
<dt .deflist__dt>_{MsgExamRegistration}
|
||||||
<dd .deflist__dd>^{registerWdgt}
|
<dd .deflist__dd>^{registerWdgt}
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
$newline never
|
$newline never
|
||||||
$case bonusRule
|
$case bonusRule
|
||||||
$of ExamNoBonus
|
|
||||||
_{MsgExamNoBonus'}
|
|
||||||
$of ExamBonusPoints ps False
|
$of ExamBonusPoints ps False
|
||||||
_{MsgExamBonusPoints ps}
|
_{MsgExamBonusPoints ps}
|
||||||
$of ExamBonusPoints ps True
|
$of ExamBonusPoints ps True
|
||||||
|
|||||||
@ -467,6 +467,31 @@ fillDb = do
|
|||||||
,(tinaTester, Just sfTTc)
|
,(tinaTester, Just sfTTc)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
examFFP <- insert' $ Exam
|
||||||
|
{ examCourse = ffp
|
||||||
|
, examName = "Klausur"
|
||||||
|
, examGradingRule = Nothing
|
||||||
|
, examBonusRule = Nothing
|
||||||
|
, examOccurrenceRule = Nothing
|
||||||
|
, examVisibleFrom = Just now
|
||||||
|
, examRegisterFrom = Just now
|
||||||
|
, examRegisterTo = Just $ addUTCTime (14 * nominalDay) now
|
||||||
|
, examDeregisterUntil = Just $ addUTCTime (15 * nominalDay) now
|
||||||
|
, examPublishOccurrenceAssignments = Just $ addUTCTime (15 * nominalDay) now
|
||||||
|
, examStart = Just $ addUTCTime (16 * nominalDay) now
|
||||||
|
, examEnd = Just $ addUTCTime (17 * nominalDay) now
|
||||||
|
, examFinished = Just $ addUTCTime (21 * nominalDay) now
|
||||||
|
, examClosed = Nothing
|
||||||
|
, examPublicStatistics = True
|
||||||
|
, examShowGrades = True
|
||||||
|
, examDescription = Nothing
|
||||||
|
}
|
||||||
|
void . insertMany $ map (\u -> ExamRegistration examFFP u Nothing now)
|
||||||
|
[ fhamann
|
||||||
|
, maxMuster
|
||||||
|
, tinaTester
|
||||||
|
]
|
||||||
|
|
||||||
-- EIP
|
-- EIP
|
||||||
eip <- insert' Course
|
eip <- insert' Course
|
||||||
{ courseName = "Einführung in die Programmierung"
|
{ courseName = "Einführung in die Programmierung"
|
||||||
|
|||||||
Reference in New Issue
Block a user