refactor(lms): show deletion days parameter and ensure audit log period is accounted for
This commit is contained in:
parent
9ac275c9eb
commit
60644528fc
@ -8,7 +8,7 @@ QualificationDescription: Beschreibung
|
|||||||
QualificationValidIndicator: Gültigkeit
|
QualificationValidIndicator: Gültigkeit
|
||||||
QualificationValidDuration: Gültigkeitsdauer
|
QualificationValidDuration: Gültigkeitsdauer
|
||||||
QualificationAuditDuration: Aufbewahrung Audit Log
|
QualificationAuditDuration: Aufbewahrung Audit Log
|
||||||
QualificationAuditDurationTooltip: Optionaler Zeitraum zur Löschung von E‑Learning Daten. Hiweis: Der E‑Learning Server kann seine anonymisierten Daten schon früher löschen.
|
QualificationAuditDurationTooltip n@Int: Optionaler Zeitraum zur Löschung von E‑Learning Daten. Hinweis: Der E‑Learning Server kann seine anonymisierten Daten schon früher löschen, aber spätestens #{n} Tage nach Abschluss.
|
||||||
QualificationRefreshWithin: Erneurerungszeitraum
|
QualificationRefreshWithin: Erneurerungszeitraum
|
||||||
QualificationRefreshWithinTooltip: Optionaler Zeitraum vor Ablauf für automatischen Start des E‑Learnings und Versand einer Benachrichtigung per Brief oder Email.
|
QualificationRefreshWithinTooltip: Optionaler Zeitraum vor Ablauf für automatischen Start des E‑Learnings und Versand einer Benachrichtigung per Brief oder Email.
|
||||||
QualificationRefreshReminder: 2. Erinnerung
|
QualificationRefreshReminder: 2. Erinnerung
|
||||||
|
|||||||
@ -8,7 +8,7 @@ QualificationDescription: Description
|
|||||||
QualificationValidIndicator: Validity
|
QualificationValidIndicator: Validity
|
||||||
QualificationValidDuration: Validity period
|
QualificationValidDuration: Validity period
|
||||||
QualificationAuditDuration: Audit log keept
|
QualificationAuditDuration: Audit log keept
|
||||||
QualificationAuditDurationTooltip: Optional period for deletion of e‑learning data. Note that the e‑learning server may delete its anonymised data earlier.
|
QualificationAuditDurationTooltip n@Int: Optional period for deletion of e‑learning data. Note that the e‑learning server may delete its anonymised data earlier, at most #{n} days after closing.
|
||||||
QualificationRefreshWithin: Refresh within
|
QualificationRefreshWithin: Refresh within
|
||||||
QualificationRefreshWithinTooltip: Optional period before expiry to start e‑learning and send a notification by post or email.
|
QualificationRefreshWithinTooltip: Optional period before expiry to start e‑learning and send a notification by post or email.
|
||||||
QualificationRefreshReminder: 2. Reminder
|
QualificationRefreshReminder: 2. Reminder
|
||||||
|
|||||||
@ -105,8 +105,9 @@ postLmsAllR = do
|
|||||||
, formSubmit = FormNoSubmit
|
, formSubmit = FormNoSubmit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LmsConf{lmsDeletionDays} <- getsYesod $ view _appLmsConf
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
view _2 <$> mkLmsAllTable isAdmin
|
view _2 <$> mkLmsAllTable isAdmin lmsDeletionDays
|
||||||
siteLayoutMsg MsgMenuLms $ do
|
siteLayoutMsg MsgMenuLms $ do
|
||||||
setTitleI MsgMenuLms
|
setTitleI MsgMenuLms
|
||||||
$(widgetFile "lms-all")
|
$(widgetFile "lms-all")
|
||||||
@ -122,8 +123,8 @@ resultAllQualificationTotal :: Lens' AllQualificationTableData Word64
|
|||||||
resultAllQualificationTotal = _dbrOutput . _3 . _unValue
|
resultAllQualificationTotal = _dbrOutput . _3 . _unValue
|
||||||
|
|
||||||
|
|
||||||
mkLmsAllTable :: Bool -> DB (Any, Widget)
|
mkLmsAllTable :: Bool -> Int -> DB (Any, Widget)
|
||||||
mkLmsAllTable isAdmin = do
|
mkLmsAllTable isAdmin lmsDeletionDays = do
|
||||||
svs <- getSupervisees
|
svs <- getSupervisees
|
||||||
let
|
let
|
||||||
resultDBTable = DBTable{..}
|
resultDBTable = DBTable{..}
|
||||||
@ -160,7 +161,7 @@ mkLmsAllTable isAdmin = do
|
|||||||
-- , sortable Nothing (i18nCell MsgQualificationRefreshWithin) $ foldMap textCell . view (resultAllQualification . _qualificationRefreshWithin . to formatCalendarDiffDays) -- does not work, since there is a maybe in between
|
-- , sortable Nothing (i18nCell MsgQualificationRefreshWithin) $ foldMap textCell . view (resultAllQualification . _qualificationRefreshWithin . to formatCalendarDiffDays) -- does not work, since there is a maybe in between
|
||||||
, sortable Nothing (i18nCell MsgQualificationRefreshReminder & cellTooltips [SomeMessage MsgQualificationRefreshReminderTooltip, SomeMessage MsgTableDiffDaysTooltip]) $
|
, sortable Nothing (i18nCell MsgQualificationRefreshReminder & cellTooltips [SomeMessage MsgQualificationRefreshReminderTooltip, SomeMessage MsgTableDiffDaysTooltip]) $
|
||||||
foldMap (textCell . formatCalendarDiffDays ) . view (resultAllQualification . _qualificationRefreshReminder)
|
foldMap (textCell . formatCalendarDiffDays ) . view (resultAllQualification . _qualificationRefreshReminder)
|
||||||
, sortable Nothing (i18nCell MsgQualificationAuditDuration & cellTooltips [SomeMessage MsgQualificationAuditDurationTooltip, SomeMessage MsgTableDiffDaysTooltip]) $
|
, sortable Nothing (i18nCell MsgQualificationAuditDuration & cellTooltips [SomeMessage (MsgQualificationAuditDurationTooltip lmsDeletionDays), SomeMessage MsgTableDiffDaysTooltip]) $
|
||||||
foldMap (textCell . formatCalendarDiffDays . fromMonths) . view (resultAllQualification . _qualificationAuditDuration)
|
foldMap (textCell . formatCalendarDiffDays . fromMonths) . view (resultAllQualification . _qualificationAuditDuration)
|
||||||
, sortable (Just "qelearning") (i18nCell MsgTableLmsElearning & cellTooltip MsgQualificationElearningStart)
|
, sortable (Just "qelearning") (i18nCell MsgTableLmsElearning & cellTooltip MsgQualificationElearningStart)
|
||||||
$ tickmarkCell . view (resultAllQualification . _qualificationElearningStart)
|
$ tickmarkCell . view (resultAllQualification . _qualificationElearningStart)
|
||||||
@ -790,6 +791,7 @@ postLmsR sid qsh = do
|
|||||||
let heading = citext2widget $ "LMS " <> qualificationName quali
|
let heading = citext2widget $ "LMS " <> qualificationName quali
|
||||||
siteLayout heading $ do
|
siteLayout heading $ do
|
||||||
setTitle $ toHtml $ "LMS " <> unSchoolKey sid <> "-" <> qsh
|
setTitle $ toHtml $ "LMS " <> unSchoolKey sid <> "-" <> qsh
|
||||||
|
LmsConf{lmsDeletionDays} <- getsYesod $ view _appLmsConf
|
||||||
$(widgetFile "lms")
|
$(widgetFile "lms")
|
||||||
|
|
||||||
-- redirect to a specific lms user
|
-- redirect to a specific lms user
|
||||||
|
|||||||
@ -90,9 +90,8 @@ instance CsvColumnsExplained LmsUserTableCsv where
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
mkUserTable :: SchoolId -> QualificationShorthand -> QualificationId -> DB (Any, Widget)
|
mkUserTable :: SchoolId -> QualificationShorthand -> QualificationId -> UTCTime -> DB (Any, Widget)
|
||||||
mkUserTable _sid qsh qid = do
|
mkUserTable _sid qsh qid cutoff = do
|
||||||
cutoff <- liftHandler lmsDeletionDate
|
|
||||||
dbtCsvName <- csvFilenameLmsUser qsh
|
dbtCsvName <- csvFilenameLmsUser qsh
|
||||||
let dbtCsvSheetName = dbtCsvName
|
let dbtCsvSheetName = dbtCsvName
|
||||||
let
|
let
|
||||||
@ -158,11 +157,17 @@ mkUserTable _sid qsh qid = do
|
|||||||
& defaultSorting [SortAscBy csvLmsIdent]
|
& defaultSorting [SortAscBy csvLmsIdent]
|
||||||
dbTable userDBTableValidator userDBTable
|
dbTable userDBTableValidator userDBTable
|
||||||
|
|
||||||
|
getQidCutoff :: SchoolId -> QualificationShorthand -> DB (QualificationId, UTCTime)
|
||||||
|
getQidCutoff sid qsh = do
|
||||||
|
Entity{entityKey = qid, entityVal = Qualification{qualificationAuditDuration=auditDur}} <- getBy404 $ SchoolQualificationShort sid qsh
|
||||||
|
cutoff <- liftHandler $ lmsDeletionDate auditDur
|
||||||
|
return (qid, cutoff)
|
||||||
|
|
||||||
getLmsLearnersR :: SchoolId -> QualificationShorthand -> Handler Html
|
getLmsLearnersR :: SchoolId -> QualificationShorthand -> Handler Html
|
||||||
getLmsLearnersR sid qsh = do
|
getLmsLearnersR sid qsh = do
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
(qid, cutoff) <- getQidCutoff sid qsh
|
||||||
view _2 <$> mkUserTable sid qsh qid
|
view _2 <$> mkUserTable sid qsh qid cutoff
|
||||||
siteLayoutMsg MsgMenuLmsLearners $ do
|
siteLayoutMsg MsgMenuLmsLearners $ do
|
||||||
setTitleI MsgMenuLmsLearners
|
setTitleI MsgMenuLmsLearners
|
||||||
lmsTable
|
lmsTable
|
||||||
@ -170,13 +175,13 @@ getLmsLearnersR sid qsh = do
|
|||||||
getLmsLearnersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
getLmsLearnersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
||||||
getLmsLearnersDirectR sid qsh = do
|
getLmsLearnersDirectR sid qsh = do
|
||||||
$logInfoS "LMS" $ "Direct Download Users for " <> tshow qsh <> " at " <> tshow sid
|
$logInfoS "LMS" $ "Direct Download Users for " <> tshow qsh <> " at " <> tshow sid
|
||||||
cutoff <- lmsDeletionDate
|
(lms_users,cutoff) <- runDB $ do
|
||||||
lms_users <- runDB $ do
|
(qid, cutoff) <- getQidCutoff sid qsh
|
||||||
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
lms_users <- selectList [ LmsUserQualification ==. qid
|
||||||
selectList [ LmsUserQualification ==. qid
|
, LmsUserEnded ==. Nothing
|
||||||
, LmsUserEnded ==. Nothing
|
-- , LmsUserReceived ==. Nothing ||. LmsUserResetPin ==. True ||. LmsUserStatus !=. Nothing -- send delta only NOTE: know-how no longer expects delta
|
||||||
-- , LmsUserReceived ==. Nothing ||. LmsUserResetPin ==. True ||. LmsUserStatus !=. Nothing -- send delta only NOTE: know-how no longer expects delta
|
] [Asc LmsUserStarted, Asc LmsUserIdent]
|
||||||
] [Asc LmsUserStarted, Asc LmsUserIdent]
|
return (lms_users, cutoff)
|
||||||
|
|
||||||
{- To avoid exporting unneeded columns, we would need an SqlSelect instance for LmsUserTableCsv; probably not worth it
|
{- To avoid exporting unneeded columns, we would need an SqlSelect instance for LmsUserTableCsv; probably not worth it
|
||||||
Ex.select $ do
|
Ex.select $ do
|
||||||
|
|||||||
@ -83,7 +83,7 @@ instance CsvColumnsExplained LmsUserTableCsv where
|
|||||||
|
|
||||||
mkUserTable :: SchoolId -> QualificationShorthand -> QualificationId -> DB (Any, Widget)
|
mkUserTable :: SchoolId -> QualificationShorthand -> QualificationId -> DB (Any, Widget)
|
||||||
mkUserTable _sid qsh qid = do
|
mkUserTable _sid qsh qid = do
|
||||||
cutoff <- liftHandler lmsDeletionDate
|
cutoff <- liftHandler $ lmsDeletionDate Nothing
|
||||||
dbtCsvName <- csvFilenameLmsUser qsh
|
dbtCsvName <- csvFilenameLmsUser qsh
|
||||||
let dbtCsvSheetName = dbtCsvName
|
let dbtCsvSheetName = dbtCsvName
|
||||||
let
|
let
|
||||||
@ -154,7 +154,7 @@ getLmsUsersR sid qsh = do
|
|||||||
getLmsUsersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
getLmsUsersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
||||||
getLmsUsersDirectR sid qsh = do
|
getLmsUsersDirectR sid qsh = do
|
||||||
$logInfoS "LMS" $ "Direct Download Users for " <> tshow qsh <> " at " <> tshow sid
|
$logInfoS "LMS" $ "Direct Download Users for " <> tshow qsh <> " at " <> tshow sid
|
||||||
cutoff <- lmsDeletionDate
|
cutoff <- lmsDeletionDate Nothing
|
||||||
lms_users <- runDB $ do
|
lms_users <- runDB $ do
|
||||||
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
selectList [ LmsUserQualification ==. qid
|
selectList [ LmsUserQualification ==. qid
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
-- SPDX-FileCopyrightText: 2022-23 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
|||||||
@ -130,11 +130,16 @@ makeLmsFilename ftag (citext2lower -> qsh) = do
|
|||||||
getYMTH :: MonadHandler m => m Text
|
getYMTH :: MonadHandler m => m Text
|
||||||
getYMTH = formatTime' "%Y%m%d%H" =<< liftIO getCurrentTime
|
getYMTH = formatTime' "%Y%m%d%H" =<< liftIO getCurrentTime
|
||||||
|
|
||||||
--
|
-- | Given the QualificationAuditDuration, determines the time to signal the deletion of an LMS User to the e-learning server. Note that the e-learning server ought to delete LMS users on its own
|
||||||
lmsDeletionDate :: Handler UTCTime
|
lmsDeletionDate :: Maybe Int -> Handler UTCTime
|
||||||
lmsDeletionDate = do
|
lmsDeletionDate mbMaxAuditMonths = do
|
||||||
|
now <- liftIO getCurrentTime
|
||||||
LmsConf{lmsDeletionDays} <- getsYesod $ view _appLmsConf
|
LmsConf{lmsDeletionDays} <- getsYesod $ view _appLmsConf
|
||||||
addLocalDays (fromIntegral $ negate lmsDeletionDays) <$> liftIO getCurrentTime
|
let ldd = addDiffDaysRollOver (fromDays $ negate lmsDeletionDays) now
|
||||||
|
return $ case mbMaxAuditMonths of
|
||||||
|
Nothing -> ldd
|
||||||
|
(Just maxAuditMonths) ->
|
||||||
|
max ldd (addDiffDaysRollOver (fromMonths $ negate maxAuditMonths) now)
|
||||||
|
|
||||||
-- | Decide whether LMS platform should delete an identifier
|
-- | Decide whether LMS platform should delete an identifier
|
||||||
lmsUserToDeleteExpr :: UTCTime -> E.SqlExpr (Entity LmsUser) -> E.SqlExpr (E.Value Bool)
|
lmsUserToDeleteExpr :: UTCTime -> E.SqlExpr (Entity LmsUser) -> E.SqlExpr (E.Value Bool)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
$newline never
|
$newline never
|
||||||
|
|
||||||
$# SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
$# SPDX-FileCopyrightText: 2022-23 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
|
||||||
$#
|
$#
|
||||||
$# SPDX-License-Identifier: AGPL-3.0-or-later
|
$# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
@ -15,11 +15,11 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
<dd .deflist__dd>_{MsgMonths (fromIntegral dvalid)}
|
<dd .deflist__dd>_{MsgMonths (fromIntegral dvalid)}
|
||||||
|
|
||||||
$maybe daudit <- qualificationAuditDuration quali
|
$maybe daudit <- qualificationAuditDuration quali
|
||||||
<dt .deflist__dt>_{MsgQualificationAuditDuration} ^{iconTooltip (msg2widget MsgQualificationAuditDurationTooltip) Nothing True}
|
<dt .deflist__dt>_{MsgQualificationAuditDuration} ^{iconTooltip (msg2widget (MsgQualificationAuditDurationTooltip lmsDeletionDays)) Nothing True}
|
||||||
<dd .deflist__dd>_{MsgMonths (fromIntegral daudit)}
|
<dd .deflist__dd>_{MsgMonths (fromIntegral daudit)}
|
||||||
|
|
||||||
$maybe drefresh <- qualificationRefreshWithin quali
|
$maybe drefresh <- qualificationRefreshWithin quali
|
||||||
<dt .deflist__dt>_{MsgQualificationRefreshWithin} ^{iconTooltip (msg2widget MsgQualificationRefreshWithinTooltip) Nothing True}
|
<dt .deflist__dt>_{MsgQualificationRefreshWithin} ^{iconTooltip (msg2widget MsgQualificationRefreshWithinTooltip) Nothing True}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
$with drm <- cdMonths drefresh
|
$with drm <- cdMonths drefresh
|
||||||
$with drd <- cdDays drefresh
|
$with drd <- cdDays drefresh
|
||||||
|
|||||||
Reference in New Issue
Block a user