chore(lms): split qualification-check-hour into two

This commit is contained in:
Steffen Jost 2023-11-23 11:53:14 +01:00
parent 9c047ae749
commit e723dd9b17
9 changed files with 134 additions and 38 deletions

View File

@ -90,8 +90,9 @@ synchronise-avs-users-interval: "_env:SYNCHRONISE_AVS_INTERVAL:21600" # alle 6
study-features-recache-relevance-within: 172800
study-features-recache-relevance-interval: 293
# Enqueue at specified hour, dequeue 30min later
qualification-check-hour: 3
# Enqueue at specified hour, a few minutes later
job-lms-qualifications-enqueue-hour: 15
job-lms-qualifications-dequeue-hour: 3
log-settings:
detailed: "_env:DETAILED_LOGGING:false"

View File

@ -138,7 +138,5 @@ LmsNotificationSend n@Int: ELearning Benachrichtigungen an #{n} #{pluralDE n
LmsPinRenewal n@Int: ELearning Passwort ausgetauscht für #{n} #{pluralDE n "Prüfling" "Prüflinge"}.
LmsActionFailed n@Int: Aktion nicht durchgeführt für #{n} #{pluralDE n "Person" "Personen"}, da diese derzeit nicht an einer Prüfung teilnehmen.
LmsStarted: ELearning eröffnet
LmsAutomaticQueuing n@Natural: Die folgenden Funktionen werden normalerweise einmal pro Tag um #{show n} Uhr ausgeführt.
LmsManualQueuing: Die folgenden Funktionen sollten einmal pro Tag ausgeführt werden.
BtnLmsEnqueue: Nutzer mit ablaufenden Qualifikationen zum ELearning anmelden und benachrichtigen
BtnLmsDequeue: Nutzer mit beendetem ELearning ggf. benachrichtigen und aufräumen
BtnLmsDequeue: Nutzer mit beendetem ELearning aufräumen und ggf. benachrichtigen

View File

@ -7,7 +7,7 @@ QualificationName: Qualification
QualificationDescription: Description
QualificationValidIndicator: Validity
QualificationValidDuration: Validity period
QualificationAuditDuration: Audit log keept
QualificationAuditDuration: Audit log retention period
QualificationAuditDurationTooltip n@Int: Optional period for deletion of elearning data. Note that the elearning server may delete its anonymised data earlier, at most #{n} days after closing.
QualificationRefreshWithin: Refresh within
QualificationRefreshWithinTooltip: Optional period before expiry to start elearning and send a notification by post or email.
@ -19,7 +19,7 @@ QualificationExpiryNotificationTooltip: Qualification holder are notfied upon in
TableQualificationCountActive: Active
TableQualificationCountActiveTooltip: Number of currently valid qualification holders
TableQualificationCountTotal: Total
TableQualificationIsAvsLicence: AVS Driving License
TableQualificationIsAvsLicence: AVS driving license
TableQualificationIsAvsLicenceTooltip: Under which name is this qualification synchronized with AVS, if any? Only applies to qualification holders having an AVS PersonID.
TableQualificationSapExport: Sent to SAP
TableQualificationSapExportTooltip: Is this qualification transmitted to SAP? Only applies to qualification holder having a Fraport AG personnel number.
@ -138,7 +138,5 @@ LmsNotificationSend n: Elearning notifications will be sent to #{n} #{pluralE
LmsPinRenewal n: Elearning password replaced randomly for #{n} #{pluralENs n "examinee"}.
LmsActionFailed n: No action for #{n} #{pluralENs n "person"}, since there was no ongoing examination.
LmsStarted: Elearning open since
LmsAutomaticQueuing n@Natural: The following functions are executed daily at #{show n} o'clock.
LmsManualQueuing: The following functions should be executed daily.
BtnLmsEnqueue: Enqueue users with expiring qualifications for elearning and notify them.
BtnLmsDequeue: Dequeue users with finished elearning and notify, if appropriate.
BtnLmsEnqueue: Enqueue users with expiring qualifications for elearning and notify them
BtnLmsDequeue: Dequeue users with finished elearning and notify failed users

View File

@ -76,7 +76,7 @@ embedRenderMessage ''UniWorX ''ButtonManualLms id
instance Button UniWorX ButtonManualLms where
btnClasses BtnLmsEnqueue = [BCIsButton, BCPrimary]
btnClasses BtnLmsDequeue = [BCIsButton, BCDefault]
btnClasses BtnLmsDequeue = [BCIsButton, BCPrimary]
getLmsSchoolR :: SchoolId -> Handler Html
@ -86,7 +86,8 @@ getLmsAllR, postLmsAllR :: Handler Html
getLmsAllR = postLmsAllR
postLmsAllR = do
isAdmin <- hasReadAccessTo AdminR
mbQcheck <- getsYesod $ view _appQualificationCheckHour
mbJLQenqueue <- getsYesod $ view _appJobLmsQualificationsEnqueueHour
mbJLQdequeue <- getsYesod $ view _appJobLmsQualificationsDequeueHour
-- TODO: Move this functionality elsewhere without the need for `isAdmin`
mbBtnForm <- if not isAdmin then return Nothing else do
((btnResult, btnWdgt), btnEnctype) <- runFormPost $ identifyForm ("buttons" :: Text) (buttonForm :: Form ButtonManualLms)
@ -110,7 +111,7 @@ postLmsAllR = do
view _2 <$> mkLmsAllTable isAdmin lmsDeletionDays
siteLayoutMsg MsgMenuLms $ do
setTitleI MsgMenuLms
$(widgetFile "lms-all")
$(i18nWidgetFile "lms-all")
type AllQualificationTableData = DBRow (Entity Qualification, Ex.Value Word64, Ex.Value Word64)
resultAllQualification :: Lens' AllQualificationTableData Qualification

View File

@ -393,26 +393,26 @@ determineCrontab = execWriterT $ do
-- }
whenIsJust appQualificationCheckHour $ \hour -> tell $ HashMap.singleton
whenIsJust appJobLmsQualificationsEnqeueHour $ \hour -> tell $ HashMap.singleton
(JobCtlQueue JobLmsQualificationsEnqueue)
Cron
{ cronInitial = CronAsap -- time after scheduling
, cronRepeat = CronRepeatScheduled $ cronCalendarAny { cronDayOfWeek = CronMatchSome . impureNonNull . Set.fromList $ [1..5]
, cronHour = cronMatchOne hour -- cronHour = CronMatchSome (impureNonNull $ Set.fromList [3,15] )
, cronMinute = cronMatchOne 3
, cronMinute = cronMatchOne 2
, cronSecond = cronMatchOne 27
}
, cronRateLimit = 600 -- minimal time between two executions, before the second job is skipped
, cronNotAfter = Right CronNotScheduled -- maximal delay of an execution, before it is skipped entirely
}
whenIsJust appQualificationCheckHour $ \hour -> tell $ HashMap.singleton
whenIsJust appJobLmsQualificationsDequeueHour $ \hour -> tell $ HashMap.singleton
(JobCtlQueue JobLmsQualificationsDequeue)
Cron
{ cronInitial = CronAsap -- time after scheduling
, cronRepeat = CronRepeatScheduled $ cronCalendarAny { cronDayOfWeek = CronMatchSome . impureNonNull . Set.fromList $ [1..5]
, cronHour = cronMatchOne hour -- cronHour = CronMatchSome (impureNonNull $ Set.fromList [3,15] )
, cronMinute = cronMatchOne 33
, cronMinute = cronMatchOne 7
, cronSecond = cronMatchOne 27
}
, cronRateLimit = 600 -- minimal time between two executions, before the second job is skipped

View File

@ -233,7 +233,8 @@ data AppSettings = AppSettings
, appStudyFeaturesRecacheRelevanceWithin :: Maybe NominalDiffTime
, appStudyFeaturesRecacheRelevanceInterval :: NominalDiffTime
, appQualificationCheckHour :: Maybe Natural
, appJobLmsQualificationsEnqueueHour :: Maybe Natural
, appJobLmsQualificationsDequeueHour :: Maybe Natural
, appFileSourceARCConf :: Maybe (ARCConf Int)
, appFileSourcePrewarmConf :: Maybe PrewarmCacheConf
@ -784,7 +785,8 @@ instance FromJSON AppSettings where
appStudyFeaturesRecacheRelevanceWithin <- o .:? "study-features-recache-relevance-within"
appStudyFeaturesRecacheRelevanceInterval <- o .: "study-features-recache-relevance-interval"
appQualificationCheckHour <- o .:? "qualification-check-hour"
appJobLmsQualificationsEnqueueHour <- o .:? "job-lms-qualifications-enqueue-hour"
appJobLmsQualificationsDequeueHour <- o .:? "job-lms-qualifications-dequeue-hour"
appFileSourceARCConf <- assertM isValidARCConf <$> o .:? "file-source-arc"

View File

@ -0,0 +1,57 @@
$newline never
$# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>
$#
$# SPDX-License-Identifier: AGPL-3.0-or-later
<section>
^{lmsTable}
$maybe btnForm <- mbBtnForm
<section>
<h3>
ELearning Starten und Aufräumen
<p>
Die folgenden Funktionen sollten normalerweise mindestens einmal pro Tag ausgeführt werden, #
können aber auch bedenkenlos mehrfach pro Tag ausgeführt werden. #
Die erste Funktion benachrichtigt Inhaber von ablaufenden Lizenzen und #
lädt diese ggf. zum ELearning ein. #
Die zweite Funktion benachrichtigt Inhaber von bereits abgelaufenen Lizenzen und #
räumte beendete ELearning Teilnehmer auf, falls der jeweilige Aufbewahrungszeitraum abgelaufen ist. #
Ein Abgleich mit dem Ausweisverwaltungssystem findet dadurch jedoch noch nicht statt. #
<p>
<h4>
Automatische Ausführung
<dl .deflist>
<dt .deflist_dt>
Start ELearning: #
<dd .deflist_dd>
&nbsp;
$maybe hour <- mbJLQenqueue
jeden Wochentag kurz nach #
<b>
#{hour} Uhr
$nothing
<em>
keine automatische Ausführung
<dt .deflist_dt>
Sperren/Aufräumen: #
<dd .deflist_dd>
&nbsp;
$maybe hour <- mbJLQdequeue
jeden Wochentag kurz nach #
<b>
#{hour} Uhr
$nothing
<em>
keine automatische Ausführung
<p>
<h4>
Manuelle Ausführung
^{btnForm}

View File

@ -0,0 +1,57 @@
$newline never
$# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>
$#
$# SPDX-License-Identifier: AGPL-3.0-or-later
<section>
^{lmsTable}
$maybe btnForm <- mbBtnForm
<section>
<h3>
Starting and cleaning elearning
<p>
The following functions should be executed at least once per day, #
but a repeated execution is harmless. #
The first function notifies holders of expiring licences and #
enlists them for elearning, if appropriate for the respective qualification. #
The second function notifies holders of already expired licences and #
cleans finished elearnings after their respective rentention periods. #
Note that these functions do not trigger an AVS-synchronisation. #
<p>
<h4>
Automatic execution
<dl .deflist>
<dt .deflist_dt>
Start elearning: #
<dd .deflist_dd>
&nbsp;
$maybe hour <- mbJLQenqueue
every weekday shortly after #
<b>
#{hour} o'clock
$nothing
<em>
no automatic execution
<dt .deflist_dt>
Block/Clean: #
<dd .deflist_dd>
&nbsp;
$maybe hour <- mbJLQdequeue
every weekday shortly after #
<b>
#{hour} o'clock
$nothing
<em>
no automatic execution
<p>
<h4>
Manual execution
^{btnForm}

View File

@ -1,18 +0,0 @@
$newline never
$# SPDX-FileCopyrightText: 2022 Steffen Jost <jost@tcs.ifi.lmu.de>
$#
$# SPDX-License-Identifier: AGPL-3.0-or-later
<p>
^{lmsTable}
$maybe btnForm <- mbBtnForm
<section>
<p>
$maybe qcheck <- mbQcheck
_{MsgLmsAutomaticQueuing qcheck}
$nothing
_{MsgLmsManualQueuing}
<p>
^{btnForm}