From 3f87f20eb14e5db8a63c61885c4570689169ebed Mon Sep 17 00:00:00 2001 From: Sarah Vaupel Date: Fri, 11 Jun 2021 14:03:09 +0200 Subject: [PATCH] feat(sheets): introduce sheet-specific statements for exam-unrelated sheets and as exam-statement overrides --- .../categories/courses/sheet/de-de-formal.msg | 5 +- .../categories/courses/sheet/en-eu.msg | 5 +- models/sheets.model | 2 +- src/Handler/Sheet/Edit.hs | 11 ++-- src/Handler/Sheet/Form.hs | 56 ++++++++----------- src/Handler/Sheet/New.hs | 2 +- test/Database/Fill.hs | 10 ++-- 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/messages/uniworx/categories/courses/sheet/de-de-formal.msg b/messages/uniworx/categories/courses/sheet/de-de-formal.msg index f830472ee..b24c3cc85 100644 --- a/messages/uniworx/categories/courses/sheet/de-de-formal.msg +++ b/messages/uniworx/categories/courses/sheet/de-de-formal.msg @@ -153,8 +153,8 @@ SheetGradingPassBinary: Bestanden/Nicht Bestanden SheetGradingPassAlways: Automatisch bestanden, sobald korrigiert SheetAuthorshipStatementSection: Eigenständigkeitserklärung -SheetAuthorshipStatementRequired: Falls nicht-prüfungsrelevant: Eigenständigkeitserklärung einfordern? -SheetAuthorshipStatementRequiredTip: Soll jeder Abgebende (bei Abgabegruppen jedes Gruppenmitglied) aufgefordert werden, eine Eigenständigkeitserklärung zu akzeptieren? +SheetAuthorshipStatementRequired: Eigenständigkeitserklärung einfordern? +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. 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 @@ -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.) SheetAuthorshipStatementCustom: Benutzerdefinierte Erklärung SheetAuthorshipStatementSchoolDefault: Vorgabe des Instituts +SheetAuthorshipStatementContent: Eigenständigkeitserklärung diff --git a/messages/uniworx/categories/courses/sheet/en-eu.msg b/messages/uniworx/categories/courses/sheet/en-eu.msg index 0ce9116f1..b7e46a205 100644 --- a/messages/uniworx/categories/courses/sheet/en-eu.msg +++ b/messages/uniworx/categories/courses/sheet/en-eu.msg @@ -152,8 +152,8 @@ SheetGradingPassBinary: Pass/Fail SheetGradingPassAlways: Automatically passed when corrected SheetAuthorshipStatementSection: Statement of Authorship -SheetAuthorshipStatementRequired: For exam-unrelated sheets: 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? +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? (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. 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 @@ -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.) SheetAuthorshipStatementCustom: Custom statement SheetAuthorshipStatementSchoolDefault: School preset +SheetAuthorshipStatementContent: Statement of Authorship diff --git a/models/sheets.model b/models/sheets.model index 796ebbe76..1fde7ec1b 100644 --- a/models/sheets.model +++ b/models/sheets.model @@ -15,7 +15,7 @@ Sheet -- exercise sheet for a given course anonymousCorrection Bool default=true requireExamRegistration ExamId Maybe -- Students may only submit if they are registered for the given exam 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 deriving Generic SheetEdit -- who edited when a row in table "Course", kept indefinitely diff --git a/src/Handler/Sheet/Edit.hs b/src/Handler/Sheet/Edit.hs index 7e370a960..76dfd4448 100644 --- a/src/Handler/Sheet/Edit.hs +++ b/src/Handler/Sheet/Edit.hs @@ -22,8 +22,8 @@ import Handler.Sheet.PersonalisedFiles getSEditR, postSEditR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html getSEditR = postSEditR postSEditR tid ssh csh shn = do - (Entity sid Sheet{..}, sheetFileIds, currentLoads, hasPersonalisedFiles) <- runDB $ do - ent@(Entity sid _) <- fetchSheet tid ssh csh shn + (Entity sid Sheet{..}, sheetFileIds, currentLoads, hasPersonalisedFiles, mAuthorshipStatement) <- runDB $ do + ent@(Entity sid oldSheet) <- fetchSheet tid ssh csh shn fti <- getFtIdMap $ entityKey ent cLoads <- Map.union <$> 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 -- definitionId <- MaybeT . return $ schoolSheetAuthorshipStatementDefinition -- MaybeT . getEntity $ definitionId - -- mAuthorshipStatement <- maybe (pure Nothing) getEntity sheetAuthorshipStatement - return (ent, fti, cLoads, hasPersonalisedFiles) + mAuthorshipStatement <- maybe (pure Nothing) getEntity (oldSheet ^. _sheetAuthorshipStatement) + return (ent, fti, cLoads, hasPersonalisedFiles, mAuthorshipStatement) let template = Just $ SheetForm { sfName = sheetName , sfDescription = sheetDescription @@ -61,6 +61,7 @@ postSEditR tid ssh csh shn = do , spffAllowNonPersonalisedSubmission = sheetAllowNonPersonalisedSubmission , 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 @@ -118,7 +119,7 @@ handleSheetEdit tid ssh csh msId template dbAction = do , sheetAnonymousCorrection = sfAnonymousCorrection , sheetRequireExamRegistration = sfRequireExamRegistration , sheetAllowNonPersonalisedSubmission = maybe True spffAllowNonPersonalisedSubmission sfPersonalF - -- , sheetAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements + , sheetAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements } mbsid <- dbAction newSheet case mbsid of diff --git a/src/Handler/Sheet/Form.hs b/src/Handler/Sheet/Form.hs index 4a1bcd754..32c886c06 100644 --- a/src/Handler/Sheet/Form.hs +++ b/src/Handler/Sheet/Form.hs @@ -42,7 +42,7 @@ data SheetForm = SheetForm , sfMarkingText :: Maybe StoredMarkup , sfAnonymousCorrection :: Bool , sfCorrectors :: Loads - -- , sfAuthorshipStatement :: Maybe (Either AuthorshipStatementDefinitionId StoredMarkup) -- TODO: exam-unrelated statement, override for exam setting + , sfAuthorshipStatement :: Maybe StoredMarkup } data SheetPersonalisedFilesForm = SheetPersonalisedFilesForm @@ -66,7 +66,6 @@ makeSheetForm cId msId template = identifyForm FIDsheet . validateForm validateS (Just sId) -> liftHandler $ runDB $ getFtIdMap sId MsgRenderer mr <- getMsgRenderer ctime <- ceilingQuarterHour <$> liftIO getCurrentTime - -- TODO: use ((_school, _mSchoolAuthorshipStatement), _course) <- liftHandler . runDB $ do course@Course{courseSchool} <- get404 cId school@School{..} <- get404 courseSchool @@ -106,37 +105,30 @@ makeSheetForm cId msId template = identifyForm FIDsheet . validateForm validateS <*> aopt htmlField (fslI MsgSheetMarking) (sfMarkingText <$> template) <*> apopt checkBoxField (fslI MsgSheetAnonymousCorrection & setTooltip MsgSheetAnonymousCorrectionTip) (sfAnonymousCorrection <$> template) <*> correctorForm (maybe mempty sfCorrectors template) - -- <* 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 + <* aformSection MsgSheetAuthorshipStatementSection + -- 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) - -- <*> optionalActionA - -- ( optionalActionA - -- ( apreq htmlField - -- (fslI MsgSheetAuthorshipStatementCustom) - -- (join (join (sfAuthorshipStatement <$> template) <|> (Just . authorshipStatementDefinitionContent . entityVal <$> mSchoolAuthorshipStatement))) - -- ) - -- ( fslI MsgSheetAuthorshipStatementUseSchoolDefault - -- & setTooltip MsgSheetAuthorshipStatementUseSchoolDefaultTip - -- -- TODO: disable if school mode prevents custom statements - -- -- & addAttr "disabled" "disabled" - -- ) - -- ( - -- -- TODO: set accordingly if school mode prevents custom statements - -- pure $ is _Just mSchoolAuthorshipStatement - -- ) - -- -- TODO: display current school statement - -- -- <* maybe (pure ()) (authorshipStatementDefinitionContent . entityVal) mSchoolAuthorshipStatement - -- ) - -- ( fslI MsgSheetAuthorshipStatementRequired - -- & setTooltip MsgSheetAuthorshipStatementRequiredTip - -- -- 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) - -- ) + <*> optionalActionA + ( areq htmlField + (fslI MsgSheetAuthorshipStatementContent) + ( + -- TODO: select correct school settings wrt. exam-related/exam-unrelated + -- TODO: if school enforces school-wide statement, take school-wide statement + -- TODO: otherwise, take value from template, or take exam-wide statement if there is any, or take the school default if there is any + Nothing + ) + ) + ( fslI MsgSheetAuthorshipStatementRequired + & setTooltip MsgSheetAuthorshipStatementRequiredTip + -- TODO: set disabled attr if school mode disables or enforces statements + -- 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: 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 + -- TODO: otherwise, take value from template, or `Just True` if the school has a non-empty school-wide default + Nothing + ) where makeSheetPersonalisedFilesForm :: Maybe SheetPersonalisedFilesForm -> MForm Handler (AForm Handler SheetPersonalisedFilesForm) makeSheetPersonalisedFilesForm template' = do diff --git a/src/Handler/Sheet/New.hs b/src/Handler/Sheet/New.hs index e2fe398e0..f235e9363 100644 --- a/src/Handler/Sheet/New.hs +++ b/src/Handler/Sheet/New.hs @@ -70,7 +70,7 @@ postSheetNewR tid ssh csh = do , sfAnonymousCorrection = sheetAnonymousCorrection , sfRequireExamRegistration = Nothing , sfPersonalF = Nothing - -- , sfAuthorshipStatement = mAuthorshipStatement + , sfAuthorshipStatement = Nothing -- TODO: implement sheet-specific statements } _other -> Nothing let action = -- More specific error message for new sheet could go here, if insertUnique returns Nothing diff --git a/test/Database/Fill.hs b/test/Database/Fill.hs index 3ae3e5c12..68e33f41a 100644 --- a/test/Database/Fill.hs +++ b/test/Database/Fill.hs @@ -657,7 +657,7 @@ fillDb = do , sheetAnonymousCorrection = True , sheetRequireExamRegistration = Nothing , sheetAllowNonPersonalisedSubmission = True - -- , sheetAuthorshipStatement = Nothing + , sheetAuthorshipStatement = Nothing } insert_ $ SheetEdit gkleen now adhoc feste <- insert Sheet @@ -677,7 +677,7 @@ fillDb = do , sheetAnonymousCorrection = True , sheetRequireExamRegistration = Nothing , sheetAllowNonPersonalisedSubmission = True - -- , sheetAuthorshipStatement = Nothing + , sheetAuthorshipStatement = Nothing } insert_ $ SheetEdit gkleen now feste keine <- insert Sheet @@ -697,7 +697,7 @@ fillDb = do , sheetAnonymousCorrection = True , sheetRequireExamRegistration = Nothing , sheetAllowNonPersonalisedSubmission = True - -- , sheetAuthorshipStatement = Nothing + , sheetAuthorshipStatement = Nothing } insert_ $ SheetEdit gkleen now keine void . insertMany $ map (\u -> CourseParticipant ffp u now Nothing CourseParticipantActive) @@ -944,7 +944,7 @@ fillDb = do , sheetAnonymousCorrection = True , sheetRequireExamRegistration = Nothing , sheetAllowNonPersonalisedSubmission = True - -- , sheetAuthorshipStatement = Nothing + , sheetAuthorshipStatement = Nothing } void . insert $ SheetEdit jost now shId when (submissionModeCorrector sheetSubmissionMode) $ @@ -1188,7 +1188,7 @@ fillDb = do , sheetAnonymousCorrection = True , sheetRequireExamRegistration = Nothing , sheetAllowNonPersonalisedSubmission = True - -- , sheetAuthorshipStatement = if shNr == 14 then Just ifiAuthorshipStatement else Nothing + , sheetAuthorshipStatement = Nothing } manyUsers' <- shuffleM $ take 1024 manyUsers groupSizes <- getRandomRs (1, 3)