diff --git a/config/settings.yml b/config/settings.yml index b3c228991..ecc94093d 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -90,9 +90,8 @@ 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, a few minutes later -job-lms-qualifications-enqueue-hour: 15 -job-lms-qualifications-dequeue-hour: 3 +# Enqueue at specified hour, dequeue 30min later +# qualification-check-hour: 3 log-settings: detailed: "_env:DETAILED_LOGGING:false" diff --git a/messages/uniworx/categories/qualification/de-de-formal.msg b/messages/uniworx/categories/qualification/de-de-formal.msg index 10d3de31e..ce59e03ed 100644 --- a/messages/uniworx/categories/qualification/de-de-formal.msg +++ b/messages/uniworx/categories/qualification/de-de-formal.msg @@ -137,5 +137,7 @@ LmsNotificationSend n@Int: E‑Learning Benachrichtigungen an #{n} #{pluralDE n LmsPinRenewal n@Int: E‑Learning 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: E‑Learning 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 E‑Learning anmelden und benachrichtigen -BtnLmsDequeue: Nutzer mit beendetem E‑Learning aufräumen und ggf. benachrichtigen +BtnLmsDequeue: Nutzer mit beendetem E‑Learning ggf. benachrichtigen und aufräumen diff --git a/messages/uniworx/categories/qualification/en-eu.msg b/messages/uniworx/categories/qualification/en-eu.msg index caf321e2c..6e949fc4f 100644 --- a/messages/uniworx/categories/qualification/en-eu.msg +++ b/messages/uniworx/categories/qualification/en-eu.msg @@ -7,7 +7,7 @@ QualificationName: Qualification QualificationDescription: Description QualificationValidIndicator: Validity QualificationValidDuration: Validity period -QualificationAuditDuration: Audit log retention period +QualificationAuditDuration: Audit log keept 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 QualificationRefreshWithinTooltip: Optional period before expiry to start e‑learning 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. @@ -137,5 +137,7 @@ LmsNotificationSend n: E‑learning notifications will be sent to #{n} #{pluralE LmsPinRenewal n: E‑learning password replaced randomly for #{n} #{pluralENs n "examinee"}. LmsActionFailed n: No action for #{n} #{pluralENs n "person"}, since there was no ongoing examination. LmsStarted: E‑learning open since -BtnLmsEnqueue: Enqueue users with expiring qualifications for e‑learning and notify them -BtnLmsDequeue: Dequeue users with finished e‑learning and notify failed users +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 e‑learning and notify them. +BtnLmsDequeue: Dequeue users with finished e‑learning and notify, if appropriate. diff --git a/src/Handler/LMS.hs b/src/Handler/LMS.hs index 9e820dd21..ae49a06c5 100644 --- a/src/Handler/LMS.hs +++ b/src/Handler/LMS.hs @@ -76,7 +76,7 @@ embedRenderMessage ''UniWorX ''ButtonManualLms id instance Button UniWorX ButtonManualLms where btnClasses BtnLmsEnqueue = [BCIsButton, BCPrimary] - btnClasses BtnLmsDequeue = [BCIsButton, BCPrimary] + btnClasses BtnLmsDequeue = [BCIsButton, BCDefault] getLmsSchoolR :: SchoolId -> Handler Html @@ -86,8 +86,7 @@ getLmsAllR, postLmsAllR :: Handler Html getLmsAllR = postLmsAllR postLmsAllR = do isAdmin <- hasReadAccessTo AdminR - mbJLQenqueue <- getsYesod $ view _appJobLmsQualificationsEnqueueHour - mbJLQdequeue <- getsYesod $ view _appJobLmsQualificationsDequeueHour + mbQcheck <- getsYesod $ view _appQualificationCheckHour -- 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) @@ -111,7 +110,7 @@ postLmsAllR = do view _2 <$> mkLmsAllTable isAdmin lmsDeletionDays siteLayoutMsg MsgMenuLms $ do setTitleI MsgMenuLms - $(i18nWidgetFile "lms-all") + $(widgetFile "lms-all") type AllQualificationTableData = DBRow (Entity Qualification, Ex.Value Word64, Ex.Value Word64) resultAllQualification :: Lens' AllQualificationTableData Qualification diff --git a/src/Jobs/Crontab.hs b/src/Jobs/Crontab.hs index 109e6c884..e352758ef 100644 --- a/src/Jobs/Crontab.hs +++ b/src/Jobs/Crontab.hs @@ -392,24 +392,24 @@ determineCrontab = execWriterT $ do -- , cronNotAfter = Right . CronTimestamp . utcToLocalTimeTZ appTZ $ addUTCTime appStudyFeaturesRecacheRelevanceInterval nextIntervalTime -- } - whenIsJust appJobLmsQualificationsEnqueueHour $ \hour -> tell $ HashMap.singleton + whenIsJust appQualificationCheckHour $ \hour -> tell $ HashMap.singleton (JobCtlQueue JobLmsQualificationsEnqueue) Cron { cronInitial = CronAsap -- time after scheduling , cronRepeat = CronRepeatScheduled $ cronCalendarAny { cronHour = cronMatchOne hour -- cronHour = CronMatchSome (impureNonNull $ Set.fromList [3,15] ) - , cronMinute = cronMatchOne 2 + , cronMinute = cronMatchOne 3 , cronSecond = cronMatchOne 27 } , cronRateLimit = nominalDay / 2 -- minimal time between two executions, before the second job is skipped , cronNotAfter = Left nominalDay -- maximal delay of an execution, before it is skipped entirely } - whenIsJust appJobLmsQualificationsDequeueHour $ \hour -> tell $ HashMap.singleton + whenIsJust appQualificationCheckHour $ \hour -> tell $ HashMap.singleton (JobCtlQueue JobLmsQualificationsDequeue) Cron { cronInitial = CronAsap -- time after scheduling , cronRepeat = CronRepeatScheduled $ cronCalendarAny { cronHour = cronMatchOne hour -- cronHour = CronMatchSome (impureNonNull $ Set.fromList [3,15] ) - , cronMinute = cronMatchOne 7 + , cronMinute = cronMatchOne 33 , cronSecond = cronMatchOne 27 } , cronRateLimit = nominalDay / 2 -- minimal time between two executions, before the second job is skipped diff --git a/src/Settings.hs b/src/Settings.hs index a6c008a1e..5b6c139cb 100644 --- a/src/Settings.hs +++ b/src/Settings.hs @@ -233,8 +233,7 @@ data AppSettings = AppSettings , appStudyFeaturesRecacheRelevanceWithin :: Maybe NominalDiffTime , appStudyFeaturesRecacheRelevanceInterval :: NominalDiffTime - , appJobLmsQualificationsEnqueueHour :: Maybe Natural - , appJobLmsQualificationsDequeueHour :: Maybe Natural + , appQualificationCheckHour :: Maybe Natural , appFileSourceARCConf :: Maybe (ARCConf Int) , appFileSourcePrewarmConf :: Maybe PrewarmCacheConf @@ -785,8 +784,7 @@ instance FromJSON AppSettings where appStudyFeaturesRecacheRelevanceWithin <- o .:? "study-features-recache-relevance-within" appStudyFeaturesRecacheRelevanceInterval <- o .: "study-features-recache-relevance-interval" - appJobLmsQualificationsEnqueueHour <- o .:? "job-lms-qualifications-enqueue-hour" - appJobLmsQualificationsDequeueHour <- o .:? "job-lms-qualifications-dequeue-hour" + appQualificationCheckHour <- o .:? "qualification-check-hour" appFileSourceARCConf <- assertM isValidARCConf <$> o .:? "file-source-arc" diff --git a/templates/i18n/lms-all/de-de-formal.hamlet b/templates/i18n/lms-all/de-de-formal.hamlet deleted file mode 100644 index c93ddfb58..000000000 --- a/templates/i18n/lms-all/de-de-formal.hamlet +++ /dev/null @@ -1,57 +0,0 @@ -$newline never - -$# SPDX-FileCopyrightText: 2022 Steffen Jost -$# -$# SPDX-License-Identifier: AGPL-3.0-or-later - -
- ^{lmsTable} - -$maybe btnForm <- mbBtnForm -
-

- E‑Learning Starten und Aufräumen -

- 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 E‑Learning ein. # - - Die zweite Funktion benachrichtigt Inhaber von bereits abgelaufenen Lizenzen und # - räumte beendete E‑Learning Teilnehmer auf, falls der jeweilige Aufbewahrungszeitraum abgelaufen ist. # - - Ein Abgleich mit dem Ausweisverwaltungssystem findet dadurch jedoch noch nicht statt. # - -

-

- Automatische Ausführung - -
-
- Start E‑Learning: # -
-   - $maybe hour <- mbJLQenqueue - jeden Wochentag kurz nach # - - #{hour} Uhr - $nothing - - keine automatische Ausführung -
- Sperren/Aufräumen: # -
-   - $maybe hour <- mbJLQdequeue - jeden Wochentag kurz nach # - - #{hour} Uhr - $nothing - - keine automatische Ausführung -

-

- Manuelle Ausführung - - ^{btnForm} \ No newline at end of file diff --git a/templates/i18n/lms-all/en-eu.hamlet b/templates/i18n/lms-all/en-eu.hamlet deleted file mode 100644 index 69aa8df82..000000000 --- a/templates/i18n/lms-all/en-eu.hamlet +++ /dev/null @@ -1,57 +0,0 @@ -$newline never - -$# SPDX-FileCopyrightText: 2022 Steffen Jost -$# -$# SPDX-License-Identifier: AGPL-3.0-or-later - -
- ^{lmsTable} - -$maybe btnForm <- mbBtnForm -
-

- Starting and cleaning e‑learning -

- 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 e‑learning, if appropriate for the respective qualification. # - - The second function notifies holders of already expired licences and # - cleans finished e‑learnings after their respective rentention periods. # - - Note that these functions do not trigger an AVS-synchronisation. # - -

-

- Automatic execution - -
-
- Start e‑learning: # -
-   - $maybe hour <- mbJLQenqueue - every weekday shortly after # - - #{hour} o'clock - $nothing - - no automatic execution -
- Block/Clean: # -
-   - $maybe hour <- mbJLQdequeue - every weekday shortly after # - - #{hour} o'clock - $nothing - - no automatic execution -

-

- Manual execution - - ^{btnForm} \ No newline at end of file diff --git a/templates/lms-all.hamlet b/templates/lms-all.hamlet new file mode 100644 index 000000000..b4e5077fd --- /dev/null +++ b/templates/lms-all.hamlet @@ -0,0 +1,18 @@ +$newline never + +$# SPDX-FileCopyrightText: 2022 Steffen Jost +$# +$# SPDX-License-Identifier: AGPL-3.0-or-later + +

+ ^{lmsTable} + +$maybe btnForm <- mbBtnForm +

+

+ $maybe qcheck <- mbQcheck + _{MsgLmsAutomaticQueuing qcheck} + $nothing + _{MsgLmsManualQueuing} +

+ ^{btnForm} \ No newline at end of file