feat(sheets): introduce sheet-specific statements for exam-unrelated sheets and as exam-statement overrides

This commit is contained in:
Sarah Vaupel 2021-06-11 14:03:09 +02:00 committed by Gregor Kleen
parent 1e87aa2dfe
commit 3f87f20eb1
7 changed files with 43 additions and 48 deletions

View File

@ -153,8 +153,8 @@ SheetGradingPassBinary: Bestanden/Nicht Bestanden
SheetGradingPassAlways: Automatisch bestanden, sobald korrigiert SheetGradingPassAlways: Automatisch bestanden, sobald korrigiert
SheetAuthorshipStatementSection: Eigenständigkeitserklärung SheetAuthorshipStatementSection: Eigenständigkeitserklärung
SheetAuthorshipStatementRequired: Falls nicht-prüfungsrelevant: Eigenständigkeitserklärung einfordern? SheetAuthorshipStatementRequired: Eigenständigkeitserklärung einfordern?
SheetAuthorshipStatementRequiredTip: Soll jeder Abgebende (bei Abgabegruppen jedes Gruppenmitglied) aufgefordert werden, eine Eigenständigkeitserklärung zu akzeptieren? SheetAuthorshipStatementRequiredTip: Soll jeder Abgebende (bei Abgabegruppen jedes Gruppenmitglied) aufgefordert werden, eine Eigenständigkeitserklärung zu akzeptieren? (Hinweis: Gehört dieses Übungsblatt zu einer Prüfung und sind für die Prüfung Eigenständigkeitserklärungen aktiviert, so überschreibt diese Erklärung die prüfungsweite Eigenständigkeitserklärung für dieses Übungsblatt.)
SheetAuthorshipStatementRequiredDisabled: Eigenständigkeitserklärungen für nicht-prüfungsrelevante Übungsblattabgaben sind institutsweit deaktiviert. SheetAuthorshipStatementRequiredDisabled: Eigenständigkeitserklärungen für nicht-prüfungsrelevante Übungsblattabgaben sind institutsweit deaktiviert.
SheetAuthorshipStatementRequiredForced: Es ist institutsweit vorgeschrieben, dass bei Übungsblattabgaben jeder Abgebende (bei Abgabegruppen jedes Gruppenmitglied) aufgefordert werden muss, eine Eigenständigkeitserklärung zu akzeptieren. SheetAuthorshipStatementRequiredForced: Es ist institutsweit vorgeschrieben, dass bei Übungsblattabgaben jeder Abgebende (bei Abgabegruppen jedes Gruppenmitglied) aufgefordert werden muss, eine Eigenständigkeitserklärung zu akzeptieren.
SheetAuthorshipStatementIsRequiredTrue: Erforderlich SheetAuthorshipStatementIsRequiredTrue: Erforderlich
@ -163,3 +163,4 @@ SheetAuthorshipStatementUseSchoolDefault: Vorgabe des Instituts verwenden?
SheetAuthorshipStatementUseSchoolDefaultTip: Soll die aktuelle Vorgabe des Instituts (siehe unten) verwendet werden? (Hinweis: Um über alle Abgaben eines Blattes hinweg konsistente Eigenständigkeitserklärungen zu gewährleisten, werden Änderungen an der Vorgabe des Instituts nur für neue Blätter angewandt.) SheetAuthorshipStatementUseSchoolDefaultTip: Soll die aktuelle Vorgabe des Instituts (siehe unten) verwendet werden? (Hinweis: Um über alle Abgaben eines Blattes hinweg konsistente Eigenständigkeitserklärungen zu gewährleisten, werden Änderungen an der Vorgabe des Instituts nur für neue Blätter angewandt.)
SheetAuthorshipStatementCustom: Benutzerdefinierte Erklärung SheetAuthorshipStatementCustom: Benutzerdefinierte Erklärung
SheetAuthorshipStatementSchoolDefault: Vorgabe des Instituts SheetAuthorshipStatementSchoolDefault: Vorgabe des Instituts
SheetAuthorshipStatementContent: Eigenständigkeitserklärung

View File

@ -152,8 +152,8 @@ SheetGradingPassBinary: Pass/Fail
SheetGradingPassAlways: Automatically passed when corrected SheetGradingPassAlways: Automatically passed when corrected
SheetAuthorshipStatementSection: Statement of Authorship SheetAuthorshipStatementSection: Statement of Authorship
SheetAuthorshipStatementRequired: For exam-unrelated sheets: Require Statement of Authorship for submissions? SheetAuthorshipStatementRequired: Require Statement of Authorship for submissions?
SheetAuthorshipStatementRequiredTip: Should each submittor (in case of submission groups each group member) be required to accept a Statement of Authorship? SheetAuthorshipStatementRequiredTip: Should each submittor (in case of submission groups each group member) be required to accept a Statement of Authorship? (Hint: If this sheet is related to an exam and a Statement of Authorship is activated for this exam, this statement will override the exam-wide Statement of Authorship for this specific sheet.)
SheetAuthorshipStatementRequiredDisabled: The school settings prohibit Statements of Authorship for exam-unrelated exercise sheet submissions. SheetAuthorshipStatementRequiredDisabled: The school settings prohibit Statements of Authorship for exam-unrelated exercise sheet submissions.
SheetAuthorshipStatementRequiredForced: The school settings enforce that each submittor (in case of submission groups each group member) is required to accept a Statement of Authorship. SheetAuthorshipStatementRequiredForced: The school settings enforce that each submittor (in case of submission groups each group member) is required to accept a Statement of Authorship.
SheetAuthorshipStatementIsRequiredTrue: Required SheetAuthorshipStatementIsRequiredTrue: Required
@ -162,3 +162,4 @@ SheetAuthorshipStatementUseSchoolDefault: Use school preset?
SheetAuthorshipStatementUseSchoolDefaultTip: Should the school-wide preset be used? (Hint: To ensure consistent statements across all submissions for a sheet, changes of the school-wide preset will only apply to new exercise sheets.) SheetAuthorshipStatementUseSchoolDefaultTip: Should the school-wide preset be used? (Hint: To ensure consistent statements across all submissions for a sheet, changes of the school-wide preset will only apply to new exercise sheets.)
SheetAuthorshipStatementCustom: Custom statement SheetAuthorshipStatementCustom: Custom statement
SheetAuthorshipStatementSchoolDefault: School preset SheetAuthorshipStatementSchoolDefault: School preset
SheetAuthorshipStatementContent: Statement of Authorship

View File

@ -15,7 +15,7 @@ Sheet -- exercise sheet for a given course
anonymousCorrection Bool default=true anonymousCorrection Bool default=true
requireExamRegistration ExamId Maybe -- Students may only submit if they are registered for the given exam requireExamRegistration ExamId Maybe -- Students may only submit if they are registered for the given exam
allowNonPersonalisedSubmission Bool default=true allowNonPersonalisedSubmission Bool default=true
-- authorshipStatement AuthorshipStatementDefinitionId Maybe -- TODO: sheet-specific authorship statement; for exam-unrelated sheets and for exam setting overrides authorshipStatement AuthorshipStatementDefinitionId Maybe -- sheet-specific authorship statement; for exam-unrelated sheets and as exam setting overrides
CourseSheet course name CourseSheet course name
deriving Generic deriving Generic
SheetEdit -- who edited when a row in table "Course", kept indefinitely SheetEdit -- who edited when a row in table "Course", kept indefinitely

View File

@ -22,8 +22,8 @@ import Handler.Sheet.PersonalisedFiles
getSEditR, postSEditR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html getSEditR, postSEditR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html
getSEditR = postSEditR getSEditR = postSEditR
postSEditR tid ssh csh shn = do postSEditR tid ssh csh shn = do
(Entity sid Sheet{..}, sheetFileIds, currentLoads, hasPersonalisedFiles) <- runDB $ do (Entity sid Sheet{..}, sheetFileIds, currentLoads, hasPersonalisedFiles, mAuthorshipStatement) <- runDB $ do
ent@(Entity sid _) <- fetchSheet tid ssh csh shn ent@(Entity sid oldSheet) <- fetchSheet tid ssh csh shn
fti <- getFtIdMap $ entityKey ent fti <- getFtIdMap $ entityKey ent
cLoads <- Map.union cLoads <- Map.union
<$> fmap (foldMap $ \(Entity _ SheetCorrector{..}) -> Map.singleton (Right sheetCorrectorUser) (InvDBDataSheetCorrector sheetCorrectorLoad sheetCorrectorState, InvTokenDataSheetCorrector)) (selectList [ SheetCorrectorSheet ==. sid ] []) <$> fmap (foldMap $ \(Entity _ SheetCorrector{..}) -> Map.singleton (Right sheetCorrectorUser) (InvDBDataSheetCorrector sheetCorrectorLoad sheetCorrectorState, InvTokenDataSheetCorrector)) (selectList [ SheetCorrectorSheet ==. sid ] [])
@ -34,8 +34,8 @@ postSEditR tid ssh csh shn = do
-- Entity _ School{..} <- MaybeT . getEntity $ ssh -- Entity _ School{..} <- MaybeT . getEntity $ ssh
-- definitionId <- MaybeT . return $ schoolSheetAuthorshipStatementDefinition -- definitionId <- MaybeT . return $ schoolSheetAuthorshipStatementDefinition
-- MaybeT . getEntity $ definitionId -- MaybeT . getEntity $ definitionId
-- mAuthorshipStatement <- maybe (pure Nothing) getEntity sheetAuthorshipStatement mAuthorshipStatement <- maybe (pure Nothing) getEntity (oldSheet ^. _sheetAuthorshipStatement)
return (ent, fti, cLoads, hasPersonalisedFiles) return (ent, fti, cLoads, hasPersonalisedFiles, mAuthorshipStatement)
let template = Just $ SheetForm let template = Just $ SheetForm
{ sfName = sheetName { sfName = sheetName
, sfDescription = sheetDescription , sfDescription = sheetDescription
@ -61,6 +61,7 @@ postSEditR tid ssh csh shn = do
, spffAllowNonPersonalisedSubmission = sheetAllowNonPersonalisedSubmission , spffAllowNonPersonalisedSubmission = sheetAllowNonPersonalisedSubmission
, spffFiles = Nothing , spffFiles = Nothing
} }
, sfAuthorshipStatement = authorshipStatementDefinitionContent . entityVal <$> mAuthorshipStatement
} }
let action = uniqueReplace sid -- More specific error message for edit old sheet could go here by using myReplaceUnique instead let action = uniqueReplace sid -- More specific error message for edit old sheet could go here by using myReplaceUnique instead
@ -118,7 +119,7 @@ handleSheetEdit tid ssh csh msId template dbAction = do
, sheetAnonymousCorrection = sfAnonymousCorrection , sheetAnonymousCorrection = sfAnonymousCorrection
, sheetRequireExamRegistration = sfRequireExamRegistration , sheetRequireExamRegistration = sfRequireExamRegistration
, sheetAllowNonPersonalisedSubmission = maybe True spffAllowNonPersonalisedSubmission sfPersonalF , sheetAllowNonPersonalisedSubmission = maybe True spffAllowNonPersonalisedSubmission sfPersonalF
-- , sheetAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements , sheetAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements
} }
mbsid <- dbAction newSheet mbsid <- dbAction newSheet
case mbsid of case mbsid of

View File

@ -42,7 +42,7 @@ data SheetForm = SheetForm
, sfMarkingText :: Maybe StoredMarkup , sfMarkingText :: Maybe StoredMarkup
, sfAnonymousCorrection :: Bool , sfAnonymousCorrection :: Bool
, sfCorrectors :: Loads , sfCorrectors :: Loads
-- , sfAuthorshipStatement :: Maybe (Either AuthorshipStatementDefinitionId StoredMarkup) -- TODO: exam-unrelated statement, override for exam setting , sfAuthorshipStatement :: Maybe StoredMarkup
} }
data SheetPersonalisedFilesForm = SheetPersonalisedFilesForm data SheetPersonalisedFilesForm = SheetPersonalisedFilesForm
@ -66,7 +66,6 @@ makeSheetForm cId msId template = identifyForm FIDsheet . validateForm validateS
(Just sId) -> liftHandler $ runDB $ getFtIdMap sId (Just sId) -> liftHandler $ runDB $ getFtIdMap sId
MsgRenderer mr <- getMsgRenderer MsgRenderer mr <- getMsgRenderer
ctime <- ceilingQuarterHour <$> liftIO getCurrentTime ctime <- ceilingQuarterHour <$> liftIO getCurrentTime
-- TODO: use
((_school, _mSchoolAuthorshipStatement), _course) <- liftHandler . runDB $ do ((_school, _mSchoolAuthorshipStatement), _course) <- liftHandler . runDB $ do
course@Course{courseSchool} <- get404 cId course@Course{courseSchool} <- get404 cId
school@School{..} <- get404 courseSchool school@School{..} <- get404 courseSchool
@ -106,37 +105,30 @@ makeSheetForm cId msId template = identifyForm FIDsheet . validateForm validateS
<*> aopt htmlField (fslI MsgSheetMarking) (sfMarkingText <$> template) <*> aopt htmlField (fslI MsgSheetMarking) (sfMarkingText <$> template)
<*> apopt checkBoxField (fslI MsgSheetAnonymousCorrection & setTooltip MsgSheetAnonymousCorrectionTip) (sfAnonymousCorrection <$> template) <*> apopt checkBoxField (fslI MsgSheetAnonymousCorrection & setTooltip MsgSheetAnonymousCorrectionTip) (sfAnonymousCorrection <$> template)
<*> correctorForm (maybe mempty sfCorrectors template) <*> correctorForm (maybe mempty sfCorrectors template)
-- <* aformSection MsgSheetAuthorshipStatementSection <* aformSection MsgSheetAuthorshipStatementSection
-- TODO: add info: applies to exam-unrelated sheets only, will be overriden if sheet is related to an exam and this exam has an authorship statement -- TODO: add info: applies to exam-unrelated sheets and overrides exam definition if sheet is related to an exam and this exam has an authorship statement
-- TODO: compare versions: school > msId if school statement is newer than msId statement, msId > school otherwise (TODO: add lastEdited to model) -- TODO: compare versions: school > msId if school statement is newer than msId statement, msId > school otherwise (TODO: add lastEdited to model)
-- <*> optionalActionA <*> optionalActionA
-- ( optionalActionA ( areq htmlField
-- ( apreq htmlField (fslI MsgSheetAuthorshipStatementContent)
-- (fslI MsgSheetAuthorshipStatementCustom) (
-- (join (join (sfAuthorshipStatement <$> template) <|> (Just . authorshipStatementDefinitionContent . entityVal <$> mSchoolAuthorshipStatement))) -- TODO: select correct school settings wrt. exam-related/exam-unrelated
-- ) -- TODO: if school enforces school-wide statement, take school-wide statement
-- ( fslI MsgSheetAuthorshipStatementUseSchoolDefault -- TODO: otherwise, take value from template, or take exam-wide statement if there is any, or take the school default if there is any
-- & setTooltip MsgSheetAuthorshipStatementUseSchoolDefaultTip Nothing
-- -- TODO: disable if school mode prevents custom statements )
-- -- & addAttr "disabled" "disabled" )
-- ) ( fslI MsgSheetAuthorshipStatementRequired
-- ( & setTooltip MsgSheetAuthorshipStatementRequiredTip
-- -- TODO: set accordingly if school mode prevents custom statements -- TODO: set disabled attr if school mode disables or enforces statements
-- pure $ is _Just mSchoolAuthorshipStatement -- TODO: select school mode wrt. exam-related/exam-unrelated: Is this sheet related to an exam? If yes, take school exam sheet mode, otherwise take school sheet mode
-- ) )
-- -- TODO: display current school statement (
-- -- <* maybe (pure ()) (authorshipStatementDefinitionContent . entityVal) mSchoolAuthorshipStatement -- TODO: if school disables/enforces statements for this sheet (exam-related/exam-unrelated?), set value accordingly
-- ) -- TODO: if this sheet is related to an exam and this exam enforces statements, set value accordingly
-- ( fslI MsgSheetAuthorshipStatementRequired -- TODO: otherwise, take value from template, or `Just True` if the school has a non-empty school-wide default
-- & setTooltip MsgSheetAuthorshipStatementRequiredTip Nothing
-- -- TODO: disable if school mode enforces/disables statements for this sheet )
-- -- & addAttr "disabled" "disabled"
-- )
-- (
-- -- TODO: set accordingly if school mode enforces/disables statements for this sheet
-- -- TODO: school statement > template iff the school statement is newer
-- (is _Just . sfAuthorshipStatement <$> template) <|> (pure $ is _Just mSchoolAuthorshipStatement)
-- )
where where
makeSheetPersonalisedFilesForm :: Maybe SheetPersonalisedFilesForm -> MForm Handler (AForm Handler SheetPersonalisedFilesForm) makeSheetPersonalisedFilesForm :: Maybe SheetPersonalisedFilesForm -> MForm Handler (AForm Handler SheetPersonalisedFilesForm)
makeSheetPersonalisedFilesForm template' = do makeSheetPersonalisedFilesForm template' = do

View File

@ -70,7 +70,7 @@ postSheetNewR tid ssh csh = do
, sfAnonymousCorrection = sheetAnonymousCorrection , sfAnonymousCorrection = sheetAnonymousCorrection
, sfRequireExamRegistration = Nothing , sfRequireExamRegistration = Nothing
, sfPersonalF = Nothing , sfPersonalF = Nothing
-- , sfAuthorshipStatement = mAuthorshipStatement , sfAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements
} }
_other -> Nothing _other -> Nothing
let action = -- More specific error message for new sheet could go here, if insertUnique returns Nothing let action = -- More specific error message for new sheet could go here, if insertUnique returns Nothing

View File

@ -657,7 +657,7 @@ fillDb = do
, sheetAnonymousCorrection = True , sheetAnonymousCorrection = True
, sheetRequireExamRegistration = Nothing , sheetRequireExamRegistration = Nothing
, sheetAllowNonPersonalisedSubmission = True , sheetAllowNonPersonalisedSubmission = True
-- , sheetAuthorshipStatement = Nothing , sheetAuthorshipStatement = Nothing
} }
insert_ $ SheetEdit gkleen now adhoc insert_ $ SheetEdit gkleen now adhoc
feste <- insert Sheet feste <- insert Sheet
@ -677,7 +677,7 @@ fillDb = do
, sheetAnonymousCorrection = True , sheetAnonymousCorrection = True
, sheetRequireExamRegistration = Nothing , sheetRequireExamRegistration = Nothing
, sheetAllowNonPersonalisedSubmission = True , sheetAllowNonPersonalisedSubmission = True
-- , sheetAuthorshipStatement = Nothing , sheetAuthorshipStatement = Nothing
} }
insert_ $ SheetEdit gkleen now feste insert_ $ SheetEdit gkleen now feste
keine <- insert Sheet keine <- insert Sheet
@ -697,7 +697,7 @@ fillDb = do
, sheetAnonymousCorrection = True , sheetAnonymousCorrection = True
, sheetRequireExamRegistration = Nothing , sheetRequireExamRegistration = Nothing
, sheetAllowNonPersonalisedSubmission = True , sheetAllowNonPersonalisedSubmission = True
-- , sheetAuthorshipStatement = Nothing , sheetAuthorshipStatement = Nothing
} }
insert_ $ SheetEdit gkleen now keine insert_ $ SheetEdit gkleen now keine
void . insertMany $ map (\u -> CourseParticipant ffp u now Nothing CourseParticipantActive) void . insertMany $ map (\u -> CourseParticipant ffp u now Nothing CourseParticipantActive)
@ -944,7 +944,7 @@ fillDb = do
, sheetAnonymousCorrection = True , sheetAnonymousCorrection = True
, sheetRequireExamRegistration = Nothing , sheetRequireExamRegistration = Nothing
, sheetAllowNonPersonalisedSubmission = True , sheetAllowNonPersonalisedSubmission = True
-- , sheetAuthorshipStatement = Nothing , sheetAuthorshipStatement = Nothing
} }
void . insert $ SheetEdit jost now shId void . insert $ SheetEdit jost now shId
when (submissionModeCorrector sheetSubmissionMode) $ when (submissionModeCorrector sheetSubmissionMode) $
@ -1188,7 +1188,7 @@ fillDb = do
, sheetAnonymousCorrection = True , sheetAnonymousCorrection = True
, sheetRequireExamRegistration = Nothing , sheetRequireExamRegistration = Nothing
, sheetAllowNonPersonalisedSubmission = True , sheetAllowNonPersonalisedSubmission = True
-- , sheetAuthorshipStatement = if shNr == 14 then Just ifiAuthorshipStatement else Nothing , sheetAuthorshipStatement = Nothing
} }
manyUsers' <- shuffleM $ take 1024 manyUsers manyUsers' <- shuffleM $ take 1024 manyUsers
groupSizes <- getRandomRs (1, 3) groupSizes <- getRandomRs (1, 3)