chore(lms): prepare renewal letter sending
This commit is contained in:
parent
e7f29a4f5b
commit
9bd1076a9c
@ -9,7 +9,9 @@ QualificationValidIndicator: Gültigkeit
|
|||||||
QualificationValidDuration: Gültigkeitsdauer
|
QualificationValidDuration: Gültigkeitsdauer
|
||||||
QualificationAuditDuration: Aufbewahrung Audit Log
|
QualificationAuditDuration: Aufbewahrung Audit Log
|
||||||
QualificationRefreshWithin: Erneurerungszeitraum
|
QualificationRefreshWithin: Erneurerungszeitraum
|
||||||
QualificationRefreshWithinTooltip: Zeitraum für Versand einer Benachrichtigung oder für automatischen Start des E‑Learning
|
QualificationRefreshWithinTooltip: Optionaler Zeitraum vor Ablauf für automatischen Start des E‑Learnings und Versand einer Benachrichtigung per Brief oder Email
|
||||||
|
QualificationRefreshReminder: 2. Erinnerung
|
||||||
|
QualificationRefreshReminderTooltip: Optionaler Zeitraum vor Ablauf zur Versendung einer zweiten Erinnerung per Brief oder Email mit identischen Zugangsdaten, sofern in diesem Zeitraum vor Ablauf noch keine Ablaufbenachrichtigung versendet wurde
|
||||||
QualificationElearningStart: Wird das E‑Learning automatisch gestartet?
|
QualificationElearningStart: Wird das E‑Learning automatisch gestartet?
|
||||||
QualificationExpiryNotification: Ungültigkeitsbenachrichtigung?
|
QualificationExpiryNotification: Ungültigkeitsbenachrichtigung?
|
||||||
QualificationExpiryNotificationTooltip: Nutzer werden benachrichtigt, wenn die Qualifikation ungültig wird, sofern der jeweilige Nutzer in seinen Benutzereinstellungen diese Art Benachrichtigung aktiviert hat.
|
QualificationExpiryNotificationTooltip: Nutzer werden benachrichtigt, wenn die Qualifikation ungültig wird, sofern der jeweilige Nutzer in seinen Benutzereinstellungen diese Art Benachrichtigung aktiviert hat.
|
||||||
@ -101,6 +103,7 @@ QualificationStatusBlock l@QualificationShorthand n@Int m@Int: #{n}/#{m} #{l}
|
|||||||
QualificationStatusUnblock l@QualificationShorthand n@Int m@Int: #{n}/#{m} #{l} reaktiviert
|
QualificationStatusUnblock l@QualificationShorthand n@Int m@Int: #{n}/#{m} #{l} reaktiviert
|
||||||
LmsRenewalInstructions: Weitere Anweisungen zur Verlängerung finden Sie im angehängten PDF. Um Missbrauch zu verhindern wurde das PDF mit dem im FRADrive hinterlegten PDF-Passwort des Prüflings verschlüsselt. Falls kein PDF-Passwort manuell hinterlegt wurde, ist das PDF-Passwort die Flughafen Ausweisnummer, inklusive Punkt und der Ziffer danach.
|
LmsRenewalInstructions: Weitere Anweisungen zur Verlängerung finden Sie im angehängten PDF. Um Missbrauch zu verhindern wurde das PDF mit dem im FRADrive hinterlegten PDF-Passwort des Prüflings verschlüsselt. Falls kein PDF-Passwort manuell hinterlegt wurde, ist das PDF-Passwort die Flughafen Ausweisnummer, inklusive Punkt und der Ziffer danach.
|
||||||
LmsNoRenewal: Leider kann diese Qualifikation nicht alleine durch E‑Learning verlängert werden.
|
LmsNoRenewal: Leider kann diese Qualifikation nicht alleine durch E‑Learning verlängert werden.
|
||||||
|
LmsRenewalReminder: Erinnerung
|
||||||
LmsActNotify: Benachrichtigung E‑Learning erneut per Post oder E-Mail versenden
|
LmsActNotify: Benachrichtigung E‑Learning erneut per Post oder E-Mail versenden
|
||||||
LmsActRenewPin: Neues zufällige E‑Learning Passwort zuweisen
|
LmsActRenewPin: Neues zufällige E‑Learning Passwort zuweisen
|
||||||
LmsActRenewNotify: Neue zufällige E‑Learning Passwort zuweisen und Benachrichtigung per Post oder E-Mail versenden
|
LmsActRenewNotify: Neue zufällige E‑Learning Passwort zuweisen und Benachrichtigung per Post oder E-Mail versenden
|
||||||
|
|||||||
@ -9,7 +9,9 @@ QualificationValidIndicator: Validity
|
|||||||
QualificationValidDuration: Validity period
|
QualificationValidDuration: Validity period
|
||||||
QualificationAuditDuration: Audit log keept
|
QualificationAuditDuration: Audit log keept
|
||||||
QualificationRefreshWithin: Refresh within
|
QualificationRefreshWithin: Refresh within
|
||||||
QualificationRefreshWithinTooltip: Period before expiry to send a notification or to start e‑learning
|
QualificationRefreshWithinTooltip: Optional period before expiry to start e‑learning and send a notification by post or email
|
||||||
|
QualificationRefreshReminder: 2. Reminder
|
||||||
|
QualificationRefreshReminderTooltip: Optional period before expiry to send a second notification by post or email once more, provided that no renewal notification was sent in this period before expiry
|
||||||
QualificationElearningStart: Is e‑learning automatically started?
|
QualificationElearningStart: Is e‑learning automatically started?
|
||||||
QualificationExpiryNotification: Invalidity notification?
|
QualificationExpiryNotification: Invalidity notification?
|
||||||
QualificationExpiryNotificationTooltip: Qualification holder are notfied upon invalidity, provided they have activated such notification in their user settings.
|
QualificationExpiryNotificationTooltip: Qualification holder are notfied upon invalidity, provided they have activated such notification in their user settings.
|
||||||
@ -37,13 +39,13 @@ QualificationBlockNotify: Send notification
|
|||||||
QualificationBlockRemoveSupervisor: Remove all supervisors
|
QualificationBlockRemoveSupervisor: Remove all supervisors
|
||||||
QualificationExpired: Expired on
|
QualificationExpired: Expired on
|
||||||
LmsUser: Licensee
|
LmsUser: Licensee
|
||||||
LmsURL: Link E-learning
|
LmsURL: Link E‑learning
|
||||||
TableLmsEmail: Email
|
TableLmsEmail: Email
|
||||||
TableLmsIdent: E-learning user
|
TableLmsIdent: E‑learning user
|
||||||
TableLmsPin: E‑learning password
|
TableLmsPin: E‑learning password
|
||||||
TableLmsElearning: E‑learning
|
TableLmsElearning: E‑learning
|
||||||
TableLmsResetPin: Reset E-learning password?
|
TableLmsResetPin: Reset E‑learning password?
|
||||||
TableLmsDatePin: E-learning password created
|
TableLmsDatePin: E‑learning password created
|
||||||
TableLmsDelete: Delete?
|
TableLmsDelete: Delete?
|
||||||
TableLmsStaff: Staff?
|
TableLmsStaff: Staff?
|
||||||
TableLmsStarted: Started
|
TableLmsStarted: Started
|
||||||
@ -68,7 +70,7 @@ FilterLmsNotificationDue: Notification due
|
|||||||
CsvColumnLmsIdent: E#{nonBreakableDash}learning identifier, unique for each qualification and user
|
CsvColumnLmsIdent: E#{nonBreakableDash}learning identifier, unique for each qualification and user
|
||||||
CsvColumnLmsPin: Password e#{nonBreakableDash}learning access
|
CsvColumnLmsPin: Password e#{nonBreakableDash}learning access
|
||||||
CsvColumnLmsResetPin: Will the e#{nonBreakableDash}learning password be reset upon next synchronisation?
|
CsvColumnLmsResetPin: Will the e#{nonBreakableDash}learning password be reset upon next synchronisation?
|
||||||
CsvColumnLmsDelete: Will the identifier be deleted from the E-learning platfrom upon next synchronisation?
|
CsvColumnLmsDelete: Will the identifier be deleted from the E‑learning platfrom upon next synchronisation?
|
||||||
CsvColumnLmsStaff: Is the user an internal staff member? (Legacy, currently ignored)
|
CsvColumnLmsStaff: Is the user an internal staff member? (Legacy, currently ignored)
|
||||||
CsvColumnLmsSuccess: Timestamp of successful completion (UTC)
|
CsvColumnLmsSuccess: Timestamp of successful completion (UTC)
|
||||||
CsvColumnLmsFailed: Blockier durch LMS, üblicherweise wegen zu vieler Fehlversuche
|
CsvColumnLmsFailed: Blockier durch LMS, üblicherweise wegen zu vieler Fehlversuche
|
||||||
@ -79,7 +81,7 @@ LmsResultUpdate: Update of LMS result
|
|||||||
LmsResultCsvExceptionDuplicatedKey: CSV import with ambiguous key
|
LmsResultCsvExceptionDuplicatedKey: CSV import with ambiguous key
|
||||||
LmsUserlistCsvExceptionDuplicatedKey: CSV import with ambiguous key
|
LmsUserlistCsvExceptionDuplicatedKey: CSV import with ambiguous key
|
||||||
LmsDirectUpload: Direct upload for automated systems
|
LmsDirectUpload: Direct upload for automated systems
|
||||||
LmsErrorNoRefreshElearning: Error: E-learning will not be started automatically due to refresh-within time period not being set.
|
LmsErrorNoRefreshElearning: Error: E‑learning will not be started automatically due to refresh-within time period not being set.
|
||||||
MailSubjectQualificationRenewal qname: Qualification #{qname} must be renewed shortly
|
MailSubjectQualificationRenewal qname: Qualification #{qname} must be renewed shortly
|
||||||
MailSubjectQualificationExpiry qname: Qualification #{qname} expires soon
|
MailSubjectQualificationExpiry qname: Qualification #{qname} expires soon
|
||||||
MailSubjectQualificationExpired qname: Qualification #{qname} is no longer valid
|
MailSubjectQualificationExpired qname: Qualification #{qname} is no longer valid
|
||||||
@ -100,7 +102,8 @@ QualificationActGrantWarning: Use with caution in rare exceptional cases only! A
|
|||||||
QualificationStatusBlock l n m: #{n}/#{m} #{l} revoked
|
QualificationStatusBlock l n m: #{n}/#{m} #{l} revoked
|
||||||
QualificationStatusUnblock l n m: #{n}/#{m} #{l} reactivated
|
QualificationStatusUnblock l n m: #{n}/#{m} #{l} reactivated
|
||||||
LmsRenewalInstructions: Instruction on how to accomplish the renewal are enclosed in the attached PDF. In order to avoid misuse, the PDF is encrypted with the FRADrive PDF-password of the examinee. If no PDF-password had been chosen yet, then the password is the Fraport id card number of the examinee, including the punctuation mark and the digit thereafter.
|
LmsRenewalInstructions: Instruction on how to accomplish the renewal are enclosed in the attached PDF. In order to avoid misuse, the PDF is encrypted with the FRADrive PDF-password of the examinee. If no PDF-password had been chosen yet, then the password is the Fraport id card number of the examinee, including the punctuation mark and the digit thereafter.
|
||||||
LmsNoRenewal: Unfortunately, this particular qualification cannot be renewed through E-learning only.
|
LmsNoRenewal: Unfortunately, this particular qualification cannot be renewed through e‑learning only.
|
||||||
|
LmsRenewalReminder: Reminder
|
||||||
LmsActNotify: Resend e‑learning notification by post or email
|
LmsActNotify: Resend e‑learning notification by post or email
|
||||||
LmsActRenewPin: Randomly replace e‑learning password
|
LmsActRenewPin: Randomly replace e‑learning password
|
||||||
LmsActRenewNotify: Randomly replace e‑learning password and re-send notification by post or email
|
LmsActRenewNotify: Randomly replace e‑learning password and re-send notification by post or email
|
||||||
@ -109,11 +112,11 @@ LmsActRestartWarning: The existing e-learning will be erased immediately! For dr
|
|||||||
LmsActRestartExtend: Ensure validity for the next # days
|
LmsActRestartExtend: Ensure validity for the next # days
|
||||||
LmsActRestartUnblock: Undo any revocations
|
LmsActRestartUnblock: Undo any revocations
|
||||||
LmsActRestartFeedback n@Int m@Int: #{n}/#{m} e-learnings were restarted.
|
LmsActRestartFeedback n@Int m@Int: #{n}/#{m} e-learnings were restarted.
|
||||||
LmsStatusNotificationSent: E-learning password has been sent to examinee or supervisor by letter post or by email; e‑learning is currently open
|
LmsStatusNotificationSent: E‑learning password has been sent to examinee or supervisor by letter post or by email; e‑learning is currently open
|
||||||
LmsNotificationSend n: E-learning notifications will be sent to #{n} #{pluralENs n "examinee"} by letter post or by email.
|
LmsNotificationSend n: E‑learning notifications will be sent to #{n} #{pluralENs n "examinee"} by letter post or by email.
|
||||||
LmsPinRenewal n: E-learning password replaced randomly for #{n} #{pluralENs n "examinee"}.
|
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.
|
LmsActionFailed n: No action for #{n} #{pluralENs n "person"}, since there was no ongoing examination.
|
||||||
LmsStarted: E-learning open since
|
LmsStarted: E‑learning open since
|
||||||
LmsAutomaticQueuing n@Natural: The following functions are executed daily at #{show n} o'clock.
|
LmsAutomaticQueuing n@Natural: The following functions are executed daily at #{show n} o'clock.
|
||||||
LmsManualQueuing: The following functions should be executed daily.
|
LmsManualQueuing: The following functions should be executed daily.
|
||||||
BtnLmsEnqueue: Enqueue users with expiring qualifications for e‑learning and notify them.
|
BtnLmsEnqueue: Enqueue users with expiring qualifications for e‑learning and notify them.
|
||||||
|
|||||||
@ -83,7 +83,8 @@ NotificationTriggerCourseRegistered: Ein:e Kursverwalter:in hat mich zu einer Ku
|
|||||||
NotificationTriggerSubmissionUserCreated: Ich wurde als Mitabgebender zu einer Übungsblatt-Abgabe hinzugefügt
|
NotificationTriggerSubmissionUserCreated: Ich wurde als Mitabgebender zu einer Übungsblatt-Abgabe hinzugefügt
|
||||||
NotificationTriggerSubmissionEdited: Eine meiner Übungsblatt-Abgaben wurde verändert
|
NotificationTriggerSubmissionEdited: Eine meiner Übungsblatt-Abgaben wurde verändert
|
||||||
NotificationTriggerSubmissionUserDeleted: Ich wurde als Mitabgebender von einer Übungsblatt-Abgabe entfernt
|
NotificationTriggerSubmissionUserDeleted: Ich wurde als Mitabgebender von einer Übungsblatt-Abgabe entfernt
|
||||||
NotificationTriggerQualification: Eine meiner Qualifikationen läuft ab
|
NotificationTriggerQualificationExpiry: Eine meiner Qualifikationen läuft ab
|
||||||
|
NotificationTriggerQualificationReminder: Zweite Erinnerung bei Ablauf einer meiner Qualifikationen
|
||||||
|
|
||||||
UserDisplayNameRules: Vorgaben für den angezeigten Namen
|
UserDisplayNameRules: Vorgaben für den angezeigten Namen
|
||||||
|
|
||||||
|
|||||||
@ -83,7 +83,8 @@ NotificationTriggerCourseRegistered: A course administrator has enrolled me in a
|
|||||||
NotificationTriggerSubmissionUserCreated: I was added to an exercise sheet submission
|
NotificationTriggerSubmissionUserCreated: I was added to an exercise sheet submission
|
||||||
NotificationTriggerSubmissionEdited: One of my exercise sheet submissions was changed
|
NotificationTriggerSubmissionEdited: One of my exercise sheet submissions was changed
|
||||||
NotificationTriggerSubmissionUserDeleted: I was removed from one of my exercise sheet submissions
|
NotificationTriggerSubmissionUserDeleted: I was removed from one of my exercise sheet submissions
|
||||||
NotificationTriggerQualification: My Qualifications are about to expire
|
NotificationTriggerQualificationExpiry: My qualifications are about to expire
|
||||||
|
NotificationTriggerQualificationReminder: Send second reminder if one of my qualifications is about to expire
|
||||||
|
|
||||||
UserDisplayNameRules: Specification for display names
|
UserDisplayNameRules: Specification for display names
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ Qualification
|
|||||||
validDuration Int Maybe -- > 0, qualification is valid indefinitely or for a specified number of months, use with addMonthsDay
|
validDuration Int Maybe -- > 0, qualification is valid indefinitely or for a specified number of months, use with addMonthsDay
|
||||||
auditDuration Int Maybe -- > 0, number of months to keep audit log and LmsUserIdents; or indefinitely (dangerous, since LmsIdents may run out)
|
auditDuration Int Maybe -- > 0, number of months to keep audit log and LmsUserIdents; or indefinitely (dangerous, since LmsIdents may run out)
|
||||||
refreshWithin CalendarDiffDays Maybe -- notify users about renewal within this number of month/days before expiry; to be used with addGregorianDurationClip
|
refreshWithin CalendarDiffDays Maybe -- notify users about renewal within this number of month/days before expiry; to be used with addGregorianDurationClip
|
||||||
|
refreshReminder CalendarDiffDays Maybe -- send a second notification about renewal within this number of month/days before expiry
|
||||||
elearningStart Bool -- automatically schedule e-refresher
|
elearningStart Bool -- automatically schedule e-refresher
|
||||||
-- elearningOnly Bool -- successful E-learing automatically increases validity. NO!
|
-- elearningOnly Bool -- successful E-learing automatically increases validity. NO!
|
||||||
expiryNotification Bool default=true -- should expiryNotification be generated for this qualification?
|
expiryNotification Bool default=true -- should expiryNotification be generated for this qualification?
|
||||||
|
|||||||
@ -335,6 +335,7 @@ getAdminTestPdfR = do
|
|||||||
, qualShort = qual ^. _qualificationShorthand . _CI
|
, qualShort = qual ^. _qualificationShorthand . _CI
|
||||||
, qualSchool = qual ^. _qualificationSchool
|
, qualSchool = qual ^. _qualificationSchool
|
||||||
, qualDuration = qual ^. _qualificationValidDuration
|
, qualDuration = qual ^. _qualificationValidDuration
|
||||||
|
, isReminder = False
|
||||||
}
|
}
|
||||||
apcIdent <- letterApcIdent letter encRecipient now
|
apcIdent <- letterApcIdent letter encRecipient now
|
||||||
renderLetterPDF usr letter apcIdent >>= \case
|
renderLetterPDF usr letter apcIdent >>= \case
|
||||||
|
|||||||
@ -690,7 +690,7 @@ postLmsR sid qsh = do
|
|||||||
newPin <- liftIO randomLMSpw
|
newPin <- liftIO randomLMSpw
|
||||||
update lid [LmsUserPin =. newPin, LmsUserDatePin =. now, LmsUserResetPin =. True]
|
update lid [LmsUserPin =. newPin, LmsUserDatePin =. now, LmsUserResetPin =. True]
|
||||||
when (isNotifyAct action) $
|
when (isNotifyAct action) $
|
||||||
queueDBJob $ JobSendNotification { jRecipient = uid, jNotification = NotificationQualificationRenewal qid' }
|
queueDBJob $ JobSendNotification { jRecipient = uid, jNotification = NotificationQualificationRenewal qid' False }
|
||||||
return $ length okUsers
|
return $ length okUsers
|
||||||
let numSelected = length selectedUsers
|
let numSelected = length selectedUsers
|
||||||
diffSelected = numSelected - numExaminees
|
diffSelected = numSelected - numExaminees
|
||||||
|
|||||||
@ -40,26 +40,29 @@ single = uncurry Map.singleton
|
|||||||
|
|
||||||
|
|
||||||
data LRQF = LRQF
|
data LRQF = LRQF
|
||||||
{ lrqfLetter :: Text
|
{ lrqfLetter :: Text
|
||||||
, lrqfUser :: Either UserEmail UserId
|
, lrqfUser :: Either UserEmail UserId
|
||||||
, lrqfSuper :: Maybe (Either UserEmail UserId)
|
, lrqfSuper :: Maybe (Either UserEmail UserId)
|
||||||
, lrqfQuali :: Entity Qualification
|
, lrqfQuali :: Entity Qualification
|
||||||
, lrqfIdent :: LmsIdent
|
, lrqfIdent :: LmsIdent
|
||||||
, lrqfPin :: Text
|
, lrqfPin :: Text
|
||||||
, lrqfExpiry :: Maybe Day
|
, lrqfExpiry :: Maybe Day
|
||||||
|
, lrqfReminder :: Bool
|
||||||
} deriving (Eq, Generic)
|
} deriving (Eq, Generic)
|
||||||
|
|
||||||
makeRenewalForm :: Maybe LRQF -> Form LRQF
|
makeRenewalForm :: Maybe LRQF -> Form LRQF
|
||||||
makeRenewalForm tmpl = identifyForm FIDLmsLetter . validateForm validateLetterRenewQualificationF $ \html -> do
|
makeRenewalForm tmpl = identifyForm FIDLmsLetter . validateForm validateLetterRenewQualificationF $ \html -> do
|
||||||
-- now_day <- utctDay <$> liftIO getCurrentTime
|
-- now_day <- utctDay <$> liftIO getCurrentTime
|
||||||
flip (renderAForm FormStandard) html $ LRQF
|
flip (renderAForm FormStandard) html $ LRQF
|
||||||
<$> areq textField (fslI MsgPrintLetterType) (lrqfLetter <$> tmpl)
|
<$> areq textField (fslI MsgPrintLetterType) (lrqfLetter <$> tmpl)
|
||||||
<*> areq (userField False Nothing) (fslI MsgLmsUser) (lrqfUser <$> tmpl)
|
<*> areq (userField False Nothing) (fslI MsgLmsUser) (lrqfUser <$> tmpl)
|
||||||
<*> aopt (userField False Nothing) (fslI MsgTableSupervisor) (lrqfSuper <$> tmpl)
|
<*> aopt (userField False Nothing) (fslI MsgTableSupervisor) (lrqfSuper <$> tmpl)
|
||||||
<*> areq qualificationFieldEnt (fslI MsgQualificationName) (lrqfQuali <$> tmpl)
|
<*> areq qualificationFieldEnt (fslI MsgQualificationName) (lrqfQuali <$> tmpl)
|
||||||
<*> areq lmsField (fslI MsgTableLmsIdent) (lrqfIdent <$> tmpl)
|
<*> areq lmsField (fslI MsgTableLmsIdent) (lrqfIdent <$> tmpl)
|
||||||
<*> areq textField (fslI MsgTableLmsPin) (lrqfPin <$> tmpl)
|
<*> areq textField (fslI MsgTableLmsPin) (lrqfPin <$> tmpl)
|
||||||
<*> aopt dayField (fslI MsgLmsQualificationValidUntil) (lrqfExpiry <$> tmpl)
|
<*> aopt dayField (fslI MsgLmsQualificationValidUntil) (lrqfExpiry <$> tmpl)
|
||||||
|
<*> areq (boolField . Just $ SomeMessage MsgBoolIrrelevant)
|
||||||
|
(fslI MsgLmsRenewalReminder) (lrqfReminder <$> tmpl)
|
||||||
where
|
where
|
||||||
lmsField = convertField LmsIdent getLmsIdent textField
|
lmsField = convertField LmsIdent getLmsIdent textField
|
||||||
|
|
||||||
@ -86,6 +89,7 @@ lrqf2letter LRQF{..}
|
|||||||
, qualShort = lrqfQuali ^. _qualificationShorthand . _CI
|
, qualShort = lrqfQuali ^. _qualificationShorthand . _CI
|
||||||
, qualSchool = lrqfQuali ^. _qualificationSchool
|
, qualSchool = lrqfQuali ^. _qualificationSchool
|
||||||
, qualDuration = lrqfQuali ^. _qualificationValidDuration
|
, qualDuration = lrqfQuali ^. _qualificationValidDuration
|
||||||
|
, isReminder = lrqfReminder
|
||||||
}
|
}
|
||||||
return (fromMaybe usr rcvr, SomeLetter letter)
|
return (fromMaybe usr rcvr, SomeLetter letter)
|
||||||
| lrqfLetter == "e" || lrqfLetter == "E" = do
|
| lrqfLetter == "e" || lrqfLetter == "E" = do
|
||||||
@ -318,6 +322,7 @@ postPrintSendR = do
|
|||||||
, lrqfIdent = LmsIdent "stuvwxyz"
|
, lrqfIdent = LmsIdent "stuvwxyz"
|
||||||
, lrqfPin = "76543210"
|
, lrqfPin = "76543210"
|
||||||
, lrqfExpiry = Just $ succ nowaday
|
, lrqfExpiry = Just $ succ nowaday
|
||||||
|
, lrqfReminder = False
|
||||||
}
|
}
|
||||||
def_lrqf = mkLetter <$> mbQual
|
def_lrqf = mkLetter <$> mbQual
|
||||||
|
|
||||||
|
|||||||
@ -247,10 +247,11 @@ notificationForm template = wFormToAForm $ do
|
|||||||
NTExamOfficeExamResults -> Just $ NTKFunctionary SchoolExamOffice
|
NTExamOfficeExamResults -> Just $ NTKFunctionary SchoolExamOffice
|
||||||
NTExamOfficeExamResultsChanged -> Just $ NTKFunctionary SchoolExamOffice
|
NTExamOfficeExamResultsChanged -> Just $ NTKFunctionary SchoolExamOffice
|
||||||
NTCourseRegistered -> Just NTKAll
|
NTCourseRegistered -> Just NTKAll
|
||||||
NTQualification -> Just NTKAll
|
NTQualificationExpiry -> Just NTKAll
|
||||||
|
NTQualificationReminder -> Just NTKAll
|
||||||
-- _other -> Nothing
|
-- _other -> Nothing
|
||||||
|
|
||||||
forcedTriggers = [NTUserRightsUpdate, NTUserAuthModeUpdate]
|
forcedTriggers = [NTUserRightsUpdate, NTUserAuthModeUpdate, NTQualificationExpiry]
|
||||||
|
|
||||||
aFormToWForm $ NotificationSettings <$> sectionedFuncForm ntSection nsForm (fslI MsgNotificationSettings) False
|
aFormToWForm $ NotificationSettings <$> sectionedFuncForm ntSection nsForm (fslI MsgNotificationSettings) False
|
||||||
|
|
||||||
|
|||||||
@ -96,9 +96,10 @@ mkQualificationAllTable isAdmin = do
|
|||||||
maybeCell (qualificationDescription quali) markupCellLargeModal
|
maybeCell (qualificationDescription quali) markupCellLargeModal
|
||||||
, sortable Nothing (i18nCell MsgQualificationValidDuration & cellTooltip MsgTableDiffDaysTooltip) $
|
, sortable Nothing (i18nCell MsgQualificationValidDuration & cellTooltip MsgTableDiffDaysTooltip) $
|
||||||
foldMap (textCell . formatCalendarDiffDays . fromMonths) . view (resultAllQualification . _qualificationValidDuration)
|
foldMap (textCell . formatCalendarDiffDays . fromMonths) . view (resultAllQualification . _qualificationValidDuration)
|
||||||
, sortable Nothing (i18nCell MsgQualificationRefreshWithin & cellTooltip MsgTableDiffDaysTooltip) $
|
, sortable Nothing (i18nCell MsgQualificationRefreshWithin & cellTooltip MsgQualificationRefreshWithinTooltip) $
|
||||||
foldMap (textCell . formatCalendarDiffDays ) . view (resultAllQualification . _qualificationRefreshWithin)
|
foldMap (textCell . formatCalendarDiffDays ) . view (resultAllQualification . _qualificationRefreshWithin)
|
||||||
-- , 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 & cellTooltip MsgQualificationRefreshReminderTooltip) $
|
||||||
|
foldMap (textCell . formatCalendarDiffDays ) . view (resultAllQualification . _qualificationRefreshReminder)
|
||||||
, sortable (Just "qelearning") (i18nCell MsgTableLmsElearning & cellTooltip MsgQualificationElearningStart)
|
, sortable (Just "qelearning") (i18nCell MsgTableLmsElearning & cellTooltip MsgQualificationElearningStart)
|
||||||
$ tickmarkCell . view (resultAllQualification . _qualificationElearningStart)
|
$ tickmarkCell . view (resultAllQualification . _qualificationElearningStart)
|
||||||
, sortable (Just "noteexpiry") (i18nCell MsgQualificationExpiryNotification & cellTooltip MsgQualificationExpiryNotificationTooltip)
|
, sortable (Just "noteexpiry") (i18nCell MsgQualificationExpiryNotification & cellTooltip MsgQualificationExpiryNotificationTooltip)
|
||||||
|
|||||||
@ -273,11 +273,41 @@ dispatchJobLmsResults qid = JobHandlerAtomic act
|
|||||||
|
|
||||||
-- processes received input and block qualifications, if applicable
|
-- processes received input and block qualifications, if applicable
|
||||||
dispatchJobLmsUserlist :: QualificationId -> JobHandler UniWorX
|
dispatchJobLmsUserlist :: QualificationId -> JobHandler UniWorX
|
||||||
dispatchJobLmsUserlist qid = JobHandlerAtomic act
|
dispatchJobLmsUserlist qid = JobHandlerAtomic act
|
||||||
where
|
where
|
||||||
act :: YesodJobDB UniWorX ()
|
act :: YesodJobDB UniWorX ()
|
||||||
act = do
|
act = do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
|
-- send reminders first -- TODO: move to dispatchJobLmsEnqueueUser
|
||||||
|
let sendReminders remindPeriod = do
|
||||||
|
let now_day = utctDay now
|
||||||
|
remindDate = addGregorianDurationClip remindPeriod now_day
|
||||||
|
reminders <- E.select $ do
|
||||||
|
(luser :& quser) <- E.from $ E.table @LmsUser `E.innerJoin` E.table @QualificationUser
|
||||||
|
`E.on` (\(luser :& quser) -> luser E.^. LmsUserQualification E.==. quser E.^. QualificationUserQualification
|
||||||
|
E.&&. luser E.^. LmsUserUser E.==. quser E.^. QualificationUserUser
|
||||||
|
)
|
||||||
|
E.where_ $ quser E.^. QualificationUserQualification E.==. E.val qid
|
||||||
|
E.&&. quser E.^. QualificationUserScheduleRenewal
|
||||||
|
E.&&. quser E.^. QualificationUserValidUntil E.>=. E.val now_day
|
||||||
|
E.&&. quser E.^. QualificationUserValidUntil E.<=. E.val remindDate
|
||||||
|
E.&&. E.isNothing (quser E.^. QualificationUserBlockedDue)
|
||||||
|
E.&&. E.isNothing (luser E.^. LmsUserEnded)
|
||||||
|
E.&&. E.isNothing (luser E.^. LmsUserStatus)
|
||||||
|
E.&&. E.isJust (luser E.^. LmsUserNotified)
|
||||||
|
-- E.&&. ((day_ (luser E.^. LmsUserNotified) E.+. E.interval remindPeriod) E.<. quser E.^. QualificationUserValidUntil) -- not sure whether may throw runtime errors, so we check in Haskell-Land instead
|
||||||
|
return (luser, quser E.^. QualificationUserValidUntil)
|
||||||
|
forM_ reminders $ \case
|
||||||
|
(Entity _ (LmsUser{lmsUserUser=luser, lmsUserNotified=Just lnotified}), E.Value quValidUntil)
|
||||||
|
| addGregorianDurationClip remindPeriod (utctDay lnotified) < quValidUntil ->
|
||||||
|
queueDBJob JobSendNotification
|
||||||
|
{ jRecipient = luser
|
||||||
|
, jNotification = NotificationQualificationRenewal { nQualification = qid, nReminder = True }
|
||||||
|
}
|
||||||
|
_ -> return ()
|
||||||
|
maybeM (return ()) sendReminders ((>>= view _qualificationRefreshReminder) <$> get qid)
|
||||||
|
-- now process actual results
|
||||||
|
|
||||||
-- result :: [(Entity LmsUser, Entity LmsUserlist)]
|
-- result :: [(Entity LmsUser, Entity LmsUserlist)]
|
||||||
results <- E.select $ do
|
results <- E.select $ do
|
||||||
(luser :& lulist) <- E.from $
|
(luser :& lulist) <- E.from $
|
||||||
@ -302,7 +332,7 @@ dispatchJobLmsUserlist qid = JobHandlerAtomic act
|
|||||||
when (isNothing $ lmsUserNotified luser) $ do -- notify users that lms is available
|
when (isNothing $ lmsUserNotified luser) $ do -- notify users that lms is available
|
||||||
queueDBJob JobSendNotification
|
queueDBJob JobSendNotification
|
||||||
{ jRecipient = lmsUserUser luser
|
{ jRecipient = lmsUserUser luser
|
||||||
, jNotification = NotificationQualificationRenewal { nQualification = qid }
|
, jNotification = NotificationQualificationRenewal { nQualification = qid, nReminder = False }
|
||||||
}
|
}
|
||||||
|
|
||||||
let isBlocked = lmsUserlistFailed lulist
|
let isBlocked = lmsUserlistFailed lulist
|
||||||
|
|||||||
@ -201,6 +201,6 @@ classifyNotification NotificationCourseRegistered{} = return NTCou
|
|||||||
classifyNotification NotificationSubmissionEdited{} = return NTSubmissionEdited
|
classifyNotification NotificationSubmissionEdited{} = return NTSubmissionEdited
|
||||||
classifyNotification NotificationSubmissionUserCreated{} = return NTSubmissionUserCreated
|
classifyNotification NotificationSubmissionUserCreated{} = return NTSubmissionUserCreated
|
||||||
classifyNotification NotificationSubmissionUserDeleted{} = return NTSubmissionUserDeleted
|
classifyNotification NotificationSubmissionUserDeleted{} = return NTSubmissionUserDeleted
|
||||||
classifyNotification NotificationQualificationExpiry{} = return NTQualification
|
classifyNotification NotificationQualificationExpiry{} = return NTQualificationExpiry
|
||||||
classifyNotification NotificationQualificationExpired{} = return NTQualification
|
classifyNotification NotificationQualificationExpired{} = return NTQualificationExpiry
|
||||||
classifyNotification NotificationQualificationRenewal{} = return NTQualification
|
classifyNotification NotificationQualificationRenewal{} = return NTQualificationReminder
|
||||||
|
|||||||
@ -84,8 +84,8 @@ dispatchNotificationQualificationExpired nQualification jRecipient = do
|
|||||||
|
|
||||||
|
|
||||||
-- NOTE: Renewal expects that LmsUser already exists for recipient
|
-- NOTE: Renewal expects that LmsUser already exists for recipient
|
||||||
dispatchNotificationQualificationRenewal :: QualificationId -> UserId -> Handler ()
|
dispatchNotificationQualificationRenewal :: QualificationId -> Bool -> UserId -> Handler ()
|
||||||
dispatchNotificationQualificationRenewal nQualification jRecipient = do
|
dispatchNotificationQualificationRenewal nQualification nReminder jRecipient = do
|
||||||
encRecipient :: CryptoUUIDUser <- encrypt jRecipient
|
encRecipient :: CryptoUUIDUser <- encrypt jRecipient
|
||||||
query <- runDB $ (,,,)
|
query <- runDB $ (,,,)
|
||||||
<$> get jRecipient
|
<$> get jRecipient
|
||||||
@ -107,6 +107,7 @@ dispatchNotificationQualificationRenewal nQualification jRecipient = do
|
|||||||
, qualShort = CI.original qualificationShorthand
|
, qualShort = CI.original qualificationShorthand
|
||||||
, qualSchool = qualificationSchool
|
, qualSchool = qualificationSchool
|
||||||
, qualDuration = qualificationValidDuration
|
, qualDuration = qualificationValidDuration
|
||||||
|
, isReminder = nReminder
|
||||||
}
|
}
|
||||||
$logInfoS "LMS" $ "Notify " <> tshow encRecipient <> " for renewal of qualification " <> qname
|
$logInfoS "LMS" $ "Notify " <> tshow encRecipient <> " for renewal of qualification " <> qname
|
||||||
notifyOk <- sendEmailOrLetter jRecipient letter
|
notifyOk <- sendEmailOrLetter jRecipient letter
|
||||||
|
|||||||
@ -151,9 +151,9 @@ data Notification
|
|||||||
| NotificationSubmissionEdited { nInitiator :: UserId, nSubmission :: SubmissionId }
|
| NotificationSubmissionEdited { nInitiator :: UserId, nSubmission :: SubmissionId }
|
||||||
| NotificationSubmissionUserCreated { nUser :: UserId, nSubmission :: SubmissionId }
|
| NotificationSubmissionUserCreated { nUser :: UserId, nSubmission :: SubmissionId }
|
||||||
| NotificationSubmissionUserDeleted { nUser :: UserId, nSheet :: SheetId, nSubmission :: SubmissionId }
|
| NotificationSubmissionUserDeleted { nUser :: UserId, nSheet :: SheetId, nSubmission :: SubmissionId }
|
||||||
| NotificationQualificationExpiry { nQualification :: QualificationId, nExpiry :: Day } -- NotificationTrigger: NTQualification TODO: separate
|
| NotificationQualificationExpiry { nQualification :: QualificationId, nExpiry :: Day } -- NotificationTrigger: NTQualificationExpiry TODO: separate
|
||||||
| NotificationQualificationExpired { nQualification :: QualificationId } -- NotificationTrigger: NTQualification
|
| NotificationQualificationExpired { nQualification :: QualificationId } -- NotificationTrigger: NTQualificationExpiry
|
||||||
| NotificationQualificationRenewal { nQualification :: QualificationId } -- NotificationTrigger: NTQualification
|
| NotificationQualificationRenewal { nQualification :: QualificationId, nReminder :: Bool } -- NotificationTrigger: NTQualificationReminder
|
||||||
deriving (Eq, Ord, Show, Read, Generic)
|
deriving (Eq, Ord, Show, Read, Generic)
|
||||||
|
|
||||||
instance Hashable Job
|
instance Hashable Job
|
||||||
|
|||||||
@ -60,7 +60,8 @@ data NotificationTrigger
|
|||||||
| NTExamOfficeExamResults
|
| NTExamOfficeExamResults
|
||||||
| NTExamOfficeExamResultsChanged
|
| NTExamOfficeExamResultsChanged
|
||||||
| NTCourseRegistered
|
| NTCourseRegistered
|
||||||
| NTQualification
|
| NTQualificationExpiry
|
||||||
|
| NTQualificationReminder
|
||||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic)
|
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic)
|
||||||
deriving anyclass (Universe, Finite, Hashable, NFData)
|
deriving anyclass (Universe, Finite, Hashable, NFData)
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ data LetterRenewQualificationF = LetterRenewQualificationF
|
|||||||
, qualShort :: Text
|
, qualShort :: Text
|
||||||
, qualSchool :: SchoolId
|
, qualSchool :: SchoolId
|
||||||
, qualDuration :: Maybe Int
|
, qualDuration :: Maybe Int
|
||||||
|
, isReminder :: Bool
|
||||||
}
|
}
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,18 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
$if drd > 0
|
$if drd > 0
|
||||||
_{MsgDays (fromIntegral drd)}
|
_{MsgDays (fromIntegral drd)}
|
||||||
|
|
||||||
|
$maybe dremind <- qualificationRefreshReminder quali
|
||||||
|
<dt .deflist__dt>_{MsgQualificationRefreshReminder} ^{iconTooltip (msg2widget MsgQualificationRefreshReminderTooltip) Nothing True}
|
||||||
|
<dd .deflist__dd>
|
||||||
|
$with drm <- cdMonths dremind
|
||||||
|
$with drd <- cdDays dremind
|
||||||
|
$if drm > 0
|
||||||
|
_{MsgMonths (fromIntegral drm)}
|
||||||
|
$if drd > 0
|
||||||
|
, #
|
||||||
|
$if drd > 0
|
||||||
|
_{MsgDays (fromIntegral drd)}
|
||||||
|
|
||||||
<dt .deflist__dt>_{MsgQualificationElearningStart}
|
<dt .deflist__dt>_{MsgQualificationElearningStart}
|
||||||
<dd .deflist__dd>#{boolSymbol (qualificationElearningStart quali)}
|
<dd .deflist__dd>#{boolSymbol (qualificationElearningStart quali)}
|
||||||
$if (qualificationElearningStart quali) && isNothing (qualificationRefreshWithin quali)
|
$if (qualificationElearningStart quali) && isNothing (qualificationRefreshWithin quali)
|
||||||
|
|||||||
@ -695,9 +695,9 @@ fillDb = do
|
|||||||
let f_descr = Just $ htmlToStoredMarkup [shamlet|<p>Berechtigung zum Führen eines Fahrzeuges auf den Fahrstrassen des Vorfeldes.|]
|
let f_descr = Just $ htmlToStoredMarkup [shamlet|<p>Berechtigung zum Führen eines Fahrzeuges auf den Fahrstrassen des Vorfeldes.|]
|
||||||
let r_descr = Just $ htmlToStoredMarkup [shamlet|<p>Berechtigung zum Führen eines Fahrzeuges auf dem gesamten Rollfeld.|]
|
let r_descr = Just $ htmlToStoredMarkup [shamlet|<p>Berechtigung zum Führen eines Fahrzeuges auf dem gesamten Rollfeld.|]
|
||||||
let l_descr = Just $ htmlToStoredMarkup [shamlet|<p>für unhabilitierte|]
|
let l_descr = Just $ htmlToStoredMarkup [shamlet|<p>für unhabilitierte|]
|
||||||
qid_f <- insert' $ Qualification avn "F" "Vorfeldführerschein" f_descr (Just 24) (Just 6) (Just $ CalendarDiffDays 0 60) True True (Just AvsLicenceVorfeld) $ Just "F4466"
|
qid_f <- insert' $ Qualification avn "F" "Vorfeldführerschein" f_descr (Just 24) (Just 6) (Just $ CalendarDiffDays 0 60) (Just $ CalendarDiffDays 0 14) True True (Just AvsLicenceVorfeld) $ Just "F4466"
|
||||||
qid_r <- insert' $ Qualification avn "R" "Rollfeldführerschein" r_descr (Just 12) (Just 6) (Just $ CalendarDiffDays 2 3) False False (Just AvsLicenceRollfeld) $ Just "R2801"
|
qid_r <- insert' $ Qualification avn "R" "Rollfeldführerschein" r_descr (Just 12) (Just 6) (Just $ CalendarDiffDays 2 3) Nothing False False (Just AvsLicenceRollfeld) $ Just "R2801"
|
||||||
qid_l <- insert' $ Qualification ifi "L" "Lehrbefähigung" l_descr Nothing (Just 6) Nothing True False Nothing Nothing
|
qid_l <- insert' $ Qualification ifi "L" "Lehrbefähigung" l_descr Nothing (Just 6) Nothing Nothing True False Nothing Nothing
|
||||||
void . insert' $ QualificationUser jost qid_f (n_day 9) (n_day $ -1) (n_day $ -22) (Just $ QualificationBlocked (n_day $ -5) "LMS") True (n_day' $ -9) -- TODO: better dates!
|
void . insert' $ QualificationUser jost qid_f (n_day 9) (n_day $ -1) (n_day $ -22) (Just $ QualificationBlocked (n_day $ -5) "LMS") True (n_day' $ -9) -- TODO: better dates!
|
||||||
void . insert' $ QualificationUser jost qid_r (n_day 99) (n_day $ -11) (n_day $ -222) Nothing True (n_day' $ -9) -- TODO: better dates!
|
void . insert' $ QualificationUser jost qid_r (n_day 99) (n_day $ -11) (n_day $ -222) Nothing True (n_day' $ -9) -- TODO: better dates!
|
||||||
void . insert' $ QualificationUser jost qid_l (n_day 999) (n_day $ -111) (n_day $ -2222) Nothing True (n_day' $ -9) -- TODO: better dates!
|
void . insert' $ QualificationUser jost qid_l (n_day 999) (n_day $ -111) (n_day $ -2222) Nothing True (n_day' $ -9) -- TODO: better dates!
|
||||||
|
|||||||
Reference in New Issue
Block a user