chore(letter): switch to new letters

- contributes towards #64 and #82
This commit is contained in:
Steffen Jost 2024-06-20 17:04:51 +02:00
parent a2a89a8aad
commit dfe4352575
9 changed files with 36 additions and 337 deletions

View File

@ -339,7 +339,7 @@ getAdminTestPdfR = do
encRecipient :: CryptoUUIDUser <- encrypt $ usr ^. _entityKey encRecipient :: CryptoUUIDUser <- encrypt $ usr ^. _entityKey
now <- liftIO getCurrentTime now <- liftIO getCurrentTime
let nowaday = utctDay now let nowaday = utctDay now
letter = LetterRenewQualificationF letter = LetterRenewQualification
{ lmsLogin = LmsIdent "abcdefgh" { lmsLogin = LmsIdent "abcdefgh"
, lmsPin = "12345678" , lmsPin = "12345678"
, qualHolderID = usr ^. _entityKey , qualHolderID = usr ^. _entityKey

View File

@ -25,8 +25,7 @@ import qualified Database.Esqueleto.Legacy as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import Database.Esqueleto.Utils.TH import Database.Esqueleto.Utils.TH
import Utils.Print hiding (LetterRenewQualificationF) import Utils.Print
import Utils.Print.RenewQualification
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
-- import qualified Data.Text as Text -- import qualified Data.Text as Text
@ -57,7 +56,7 @@ data LRQF = LRQF
} 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 validateLetterRenewQualification $ \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)
@ -72,8 +71,8 @@ makeRenewalForm tmpl = identifyForm FIDLmsLetter . validateForm validateLetterRe
where where
lmsField = convertField LmsIdent getLmsIdent textField lmsField = convertField LmsIdent getLmsIdent textField
validateLetterRenewQualificationF :: FormValidator LRQF Handler () validateLetterRenewQualification :: FormValidator LRQF Handler ()
validateLetterRenewQualificationF = -- do validateLetterRenewQualification = -- do
-- LRQF{..} <- State.get -- LRQF{..} <- State.get
return () return ()

View File

@ -97,7 +97,7 @@ dispatchNotificationQualificationRenewal nQualification nReminder jRecipient = d
case query of case query of
(Just User{userDisplayName, userSurname}, Just Qualification{..}, Just (Entity _ QualificationUser{..}), Just(Entity luid LmsUser{..})) -> do (Just User{userDisplayName, userSurname}, Just Qualification{..}, Just (Entity _ QualificationUser{..}), Just(Entity luid LmsUser{..})) -> do
let qname = CI.original qualificationName let qname = CI.original qualificationName
letter = LetterRenewQualificationF letter = LetterRenewQualification
{ lmsLogin = lmsUserIdent { lmsLogin = lmsUserIdent
, lmsPin = lmsUserPin , lmsPin = lmsUserPin
, qualHolderID = jRecipient , qualHolderID = jRecipient

View File

@ -22,8 +22,7 @@ module Utils.Print
-- , MDMail -- , MDMail
-- , MDLetter -- , MDLetter
, SomeLetter(..) , SomeLetter(..)
, LetterRenewQualificationF(..) , LetterRenewQualification(..)
-- , LetterRenewQualification(..)
, LetterExpireQualification(..) , LetterExpireQualification(..)
-- , LetterCourseCertificate() -- , LetterCourseCertificate()
, makeCourseCertificates , makeCourseCertificates
@ -60,8 +59,7 @@ import Jobs.Handler.SendNotification.Utils
import Utils.Print.Instances () import Utils.Print.Instances ()
import Utils.Print.Letters import Utils.Print.Letters
import Utils.Print.SomeLetter import Utils.Print.SomeLetter
import Utils.Print.RenewQualificationF import Utils.Print.RenewQualification
import Utils.Print.RenewQualification()
import Utils.Print.ExpireQualification import Utils.Print.ExpireQualification
import Utils.Print.CourseCertificate import Utils.Print.CourseCertificate

View File

@ -129,7 +129,6 @@ defWriterOpts t = def { P.writerExtensions = P.pandocExtensions, P.writerTemplat
data LetterKind = Din5008 -- scrlttr2: Standard postal letter with address field, expects peprinted FraportLogo data LetterKind = Din5008 -- scrlttr2: Standard postal letter with address field, expects peprinted FraportLogo
| PinLetter -- Like Din5008, but for special paper with a protected pin field | PinLetter -- Like Din5008, but for special paper with a protected pin field
| PinNew -- New Variant for Pin Letters for R. TODO: Remove/rename/replace PinLetter
| Plain -- scrartcl: Empty, expects empty paper with no preprints | Plain -- scrartcl: Empty, expects empty paper with no preprints
| PlainLogo -- Like plain, but expects to be printed on paper with Logo | PlainLogo -- Like plain, but expects to be printed on paper with Logo
-- | Logo -- Like plain, but prints Fraport Logo in the upper right corner -- | Logo -- Like plain, but prints Fraport Logo in the upper right corner
@ -140,18 +139,15 @@ templateLatex =
let let
tDin5008 = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008.latex") tDin5008 = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008.latex")
tPinLetter = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008with_pin.latex") tPinLetter = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008with_pin.latex")
tPinNew = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008with_pin_new.latex")
tPlain = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/plain_article.latex") tPlain = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/plain_article.latex")
in \case in \case
PinLetter -> tPinLetter PinLetter -> tPinLetter
PinNew -> tPinNew
Din5008 -> tDin5008 Din5008 -> tDin5008
PlainLogo -> tPlain PlainLogo -> tPlain
Plain -> tPlain Plain -> tPlain
paperKind :: LetterKind -> Text -- Muss genau 5 Zeichen haben! paperKind :: LetterKind -> Text -- Muss genau 5 Zeichen haben!
paperKind PinLetter = "a4pin" -- Pin-Brief paperKind PinLetter = "a4pin" -- Pin-Brief
paperKind PinNew = "a4pin" -- Pin-Brief
paperKind Plain = "a4wht" -- Ohne Logo paperKind Plain = "a4wht" -- Ohne Logo
paperKind Din5008 = "a4log" -- Mit Logo paperKind Din5008 = "a4log" -- Mit Logo
paperKind PlainLogo = "a4log" paperKind PlainLogo = "a4log"

View File

@ -9,7 +9,7 @@ module Utils.Print.RenewQualification where
import Import import Import
import Text.Hamlet import Text.Hamlet
-- import Data.Char as Char import Data.Char as Char
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
@ -20,7 +20,7 @@ import Handler.Utils.Widgets (nameHtml) -- , nameHtml')
-- TODO: refactor me and turn me into a qualification property (elearningOnly) -- TODO: refactor me and turn me into a qualification property (elearningOnly)
qualificationPractical :: Text -> Bool qualificationPractical :: Text -> Bool
qualificationPractical qshort = "R" == qshort qualificationPractical qshort = "R" == qshort -- TODO
defaultNotice :: Lang -> Text -> Text -> Text -> [Text] defaultNotice :: Lang -> Text -> Text -> Text -> [Text]
@ -100,9 +100,9 @@ letterRenewalQualificationFData LetterRenewQualification{lmsLogin} = LetterRenew
instance MDLetter LetterRenewQualification where instance MDLetter LetterRenewQualification where
encryptPDFfor _ = PasswordUnderling encryptPDFfor _ = PasswordUnderling
getLetterKind _ = PinNew getLetterKind _ = PinLetter
getLetterEnvelope _ = 'f' -- maybe 'q' (Char.toLower . fst) $ Text.uncons (qualShort l) getLetterEnvelope l = maybe 'q' (Char.toLower . fst) $ Text.uncons (qualShort l)
getTemplate _ = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal_new.md") getTemplate _ = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal.md")
getMailSubject l = SomeMessage $ MsgMailSubjectQualificationRenewal $ qualShort l getMailSubject l = SomeMessage $ MsgMailSubjectQualificationRenewal $ qualShort l
getMailBody l@LetterRenewQualification{..} = Just $ \DateTimeFormatter{ format } -> getMailBody l@LetterRenewQualification{..} = Just $ \DateTimeFormatter{ format } ->
let LetterRenewQualificationData{..} = letterRenewalQualificationFData l let LetterRenewQualificationData{..} = letterRenewalQualificationFData l

View File

@ -1,100 +0,0 @@
-- SPDX-FileCopyrightText: 2023 Steffen Jost <jost@tcs.ifi.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
module Utils.Print.RenewQualificationF where
import Import
import Text.Hamlet
-- import Data.Char as Char
-- import qualified Data.Text as Text
import qualified Data.CaseInsensitive as CI
import Data.FileEmbed (embedFile)
import Utils.Print.Letters
import Handler.Utils.Widgets (nameHtml) -- , nameHtml')
data LetterRenewQualificationF = LetterRenewQualificationF
{ lmsLogin :: LmsIdent
, lmsPin :: Text
, qualHolderID :: UserId
, qualHolderDN :: UserDisplayName
, qualHolderSN :: UserSurname
, qualExpiry :: Day
, qualId :: QualificationId
, qualName :: Text
, qualShort :: Text
, qualSchool :: SchoolId
, qualDuration :: Maybe Int
, isReminder :: Bool
}
deriving (Eq, Show)
-- this datatype is specific to this letter only, and just to avoid code duplication for derived data or constants
data LetterRenewQualificationFData = LetterRenewQualificationFData { lmsUrl, lmsUrlLogin, lmsIdent :: Text }
deriving (Eq, Show)
letterRenewalQualificationFData :: LetterRenewQualificationF -> LetterRenewQualificationFData
letterRenewalQualificationFData LetterRenewQualificationF{lmsLogin} = LetterRenewQualificationFData{..}
where
lmsUrl = "https://drive.fraport.de"
lmsUrlLogin = lmsUrl <> "/?login=" <> lmsIdent
lmsIdent = getLmsIdent lmsLogin
instance MDLetter LetterRenewQualificationF where
encryptPDFfor _ = PasswordUnderling
getLetterKind _ = PinLetter
getLetterEnvelope _ = 'f' -- maybe 'q' (Char.toLower . fst) $ Text.uncons (qualShort l)
getTemplate _ = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal.md")
getMailSubject l = SomeMessage $ MsgMailSubjectQualificationRenewal $ qualShort l
getMailBody l@LetterRenewQualificationF{..} = Just $ \DateTimeFormatter{ format } ->
let LetterRenewQualificationFData{..} = letterRenewalQualificationFData l
in $(ihamletFile "templates/mail/body/qualificationRenewal.hamlet")
letterMeta l@LetterRenewQualificationF{..} DateTimeFormatter{ format } lang Entity{entityKey=rcvrId, entityVal=User{userDisplayName}} =
let LetterRenewQualificationFData{..} = letterRenewalQualificationFData l
isSupervised = rcvrId /= qualHolderID
in mkMeta $
guardMonoid isSupervised
[ toMeta "supervisor" userDisplayName
, toMeta "de-opening" ("Sehr geehrte Damen und Herren,"::Text)
, toMeta "en-opening" ("Dear Sir or Madam,"::Text)
] <>
guardMonoid isReminder
[ toMeta "reminder" ("reminder"::Text)
] <>
[ toMeta "lang" lang
, toMeta "login" lmsIdent
, toMeta "pin" lmsPin
, toMeta "examinee" qualHolderDN
, toMeta "subject-meta" qualHolderDN
, toMeta "expiry" (format SelFormatDate qualExpiry)
, mbMeta "validduration" (show <$> qualDuration)
, toMeta "url-text" lmsUrl
, toMeta "url" lmsUrlLogin
]
getPJId LetterRenewQualificationF{..} =
PrintJobIdentification
{ pjiName = bool "Renewal" "Renewal Reminder" isReminder
, pjiApcAcknowledge = "lms-" <> getLmsIdent lmsLogin
, pjiRecipient = Nothing -- to be filled later
, pjiSender = Nothing
, pjiCourse = Nothing
, pjiQualification = Just qualId
, pjiLmsUser = Just lmsLogin
, pjiFileName = "renew_" <> CI.original (unSchoolKey qualSchool) <> "-" <> qualShort <> "_" <> qualHolderSN
-- let nameRecipient = abbrvName <$> recipient
-- nameSender = abbrvName <$> sender
-- nameCourse = CI.original . courseShorthand <$> course
-- nameQuali = CI.original . qualificationShorthand <$> quali
-- in .. = T.replace " " "-" (T.intercalate "_" . catMaybes $ [Just printJobName, nameQuali, nameCourse, nameSender, nameRecipient])
}

View File

@ -13,7 +13,8 @@
]{scrlttr2} ]{scrlttr2}
\PassOptionsToPackage{hyphens}{url} \PassOptionsToPackage{hyphens}{url}
\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} \PassOptionsToPackage{unicode,$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
%\PassOptionsToPackage{unicode=true, colorlinks=false}{hyperref}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} \IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{ \hypersetup{
@ -43,12 +44,11 @@ $endif$
\usepackage{iftex} \usepackage{iftex}
%\usepackage[ngerman]{babel}
$if(lang)$ $if(lang)$
\ifLuaTeX \ifLuaTeX
\usepackage[bidi=basic]{babel} \usepackage[bidi=basic,english,ngerman]{babel}
\else \else
\usepackage[bidi=default]{babel} \usepackage[bidi=default,english,ngerman]{babel}
\fi \fi
\babelprovide[main,import]{$babel-lang$} \babelprovide[main,import]{$babel-lang$}
$for(babel-otherlangs)$ $for(babel-otherlangs)$
@ -77,6 +77,9 @@ $endif$
\fi \fi
\renewcommand{\familydefault}{\sfdefault} \renewcommand{\familydefault}{\sfdefault}
\let\oldhref\href
\renewcommand{\href}[2]{\oldhref{#1}{\bfseries#2}}
$if(mathspec)$ $if(mathspec)$
\ifXeTeX \ifXeTeX
\usepackage{mathspec} \usepackage{mathspec}
@ -162,7 +165,7 @@ $endif$
\opening{$en-opening$} \opening{$en-opening$}
$endif$ $endif$
\begin{textblock}{65}(84,232)%hpos,vpos \begin{textblock}{65}(92,236)%hpos,vpos Werte in mm
\textcolor{black!39}{ \textcolor{black!39}{
\begin{labeling}{Password:}%Achtung! Die Position des Logins muss sprachunabhängig immer an der gleichen Position sein, sonst kannn die Rückmeldung der Druckerei den Ident nicht mehr identifizieren! \begin{labeling}{Password:}%Achtung! Die Position des Logins muss sprachunabhängig immer an der gleichen Position sein, sonst kannn die Rückmeldung der Druckerei den Ident nicht mehr identifizieren!
$if(is-de)$ $if(is-de)$
@ -190,5 +193,17 @@ $endif$
\setkomavar*{enclseparator}{Anlage} \setkomavar*{enclseparator}{Anlage}
\encl{$encludes$} \encl{$encludes$}
$endif$ $endif$
$if(notice)$
\begin{textblock}{170}(20,262)%hpos,vpos Werte in mm
\scriptsize
\textbf{Hinweise für den Schulungsteilnehmer:}
\newline
$for(notice)$
$notice$
$sep$\newline
$endfor$
\end{textblock}
$endif$
\end{letter} \end{letter}
\end{document} \end{document}

View File

@ -1,209 +0,0 @@
%Based upon https://github.com/benedictdudel/pandoc-letter-din5008
\documentclass[
paper=A4,
foldmarks=BTm, % show foldmarks top, middle, bottom
foldmarks=false, % don't print foldmarks
fromalign=left, % letter head on the right
fromphone=true, % show phone number
fromemail=true, % show email
fromlogo=false, % don't show logo in letter head
version=last, % latest version of KOMA letter
pagenumber=botright, % show pagenumbers on bottom right
firstfoot=false % first-page footer
]{scrlttr2}
\PassOptionsToPackage{hyphens}{url}
\PassOptionsToPackage{unicode,$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
%\PassOptionsToPackage{unicode=true, colorlinks=false}{hyperref}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
$if(subject-meta)$
pdfsubject={$subject-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(lang)$
pdflang={$lang$},
$endif$
$if(is-de)$
$if(de-subject)$
pdftitle={$de-subject$},
$endif$
$else$
$if(en-subject)$
pdftitle={$en-subject$},
$endif$
$endif$
$if(apc-ident)$
pdfkeywords={$apc-ident$},
$endif$
}
\usepackage{url}
\usepackage{iftex}
$if(lang)$
\ifLuaTeX
\usepackage[bidi=basic,english,ngerman]{babel}
\else
\usepackage[bidi=default,english,ngerman]{babel}
\fi
\babelprovide[main,import]{$babel-lang$}
$for(babel-otherlangs)$
\babelprovide[import]{$babel-otherlangs$}
$endfor$
% get rid of language-specific shorthands (see #6817):
\let\LanguageShortHands\languageshorthands
\def\languageshorthands#1{}
$endif$
\ifLuaTeX
\usepackage{selnolig} % disable illegal ligatures
\fi
\usepackage[sfdefault]{roboto}
\ifPDFTeX
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
% \usepackage{DejaVuSansMono} % better monofont
\else
% if luatex or xetex
\usepackage{fontspec}
% \setmonofont{DejaVu Sans Mono}
\fi
\renewcommand{\familydefault}{\sfdefault}
\let\oldhref\href
\renewcommand{\href}[2]{\oldhref{#1}{\bfseries#2}}
$if(mathspec)$
\ifXeTeX
\usepackage{mathspec}
\else
\usepackage{unicode-math}
\fi
$else$
\usepackage{unicode-math}
$endif$
%\usepackage[a4paper, bottom=8cm, top=3cm]{geometry} %%% THIS HAD NO EFFECT AT ALL
\usepackage{parskip}% might be useful for pandoc tightlist
\usepackage{graphics}
\usepackage{xcolor}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage[right]{eurosym}
\usepackage{enumitem}
\makeatletter
\setplength{firstheadvpos}{1.8cm}
\setplength{toaddrvpos}{5.5cm}
\setlength{\@tempskipa}{-1.2cm}%
\@addtoplength{toaddrheight}{\@tempskipa}
\makeatother
\setlength{\oddsidemargin}{\useplength{toaddrhpos}}
\addtolength{\oddsidemargin}{-1in}
\setlength{\textwidth}{\useplength{firstheadwidth}}
\usepackage[absolute,quiet,overlay]{textpos}%,showboxes
\setlength{\TPHorizModule}{1mm}
\setlength{\TPVertModule}{1mm}
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\begin{document}%
\setkomavar{fromname}{$author$}%
\renewcommand*{\raggedsignature}{\raggedright}%
\setkomavar{fromaddress}{%
$for(return-address)$%
$return-address$$sep$\\
$endfor$
}
\setkomavar{fromphone}{$phone$}
\setkomavar{fromemail}{$email$}
%if there is a handwritten signature
%\setkomavar{signature}{$author$}
%if there is no handwritten signature
\setkomavar{signature}{}
\setplength{sigbeforevskip}{-\baselineskip}
\setkomavar{date}{$date$}
\setkomavar{place}{$place$}
$if(is-de)$
\setkomavar{subject}{$de-subject$}
$else$
\setkomavar{subject}{$en-subject$}
$endif$
\begin{letter}{%
$for(address)$
$address$$sep$\\
$endfor$
}
$if(apc-ident)$
\begin{textblock}{200}(5,5)%hpos,vpos
\textcolor{white!0}{$apc-ident$}%
\end{textblock}%
$endif$
$if(is-de)$
\opening{$de-opening$}
$else$
\opening{$en-opening$}
$endif$
\begin{textblock}{65}(92,236)%hpos,vpos Werte in mm
\textcolor{black!39}{
\begin{labeling}{Password:}%Achtung! Die Position des Logins muss sprachunabhängig immer an der gleichen Position sein, sonst kannn die Rückmeldung der Druckerei den Ident nicht mehr identifizieren!
$if(is-de)$
\item[Benutzer:] \texttt{$login$}
\item[Passwort:] \texttt{$pin$}
$else$
\item[User:] \texttt{$login$}
\item[Password:] \texttt{$pin$}
$endif$
\end{labeling}
~}
\end{textblock}
$body$
$if(is-de)$
\closing{$de-closing$}
$else$
\closing{$en-closing$}
$endif$
%\ps $postskriptum$
$if(encludes)$
\setkomavar*{enclseparator}{Anlage}
\encl{$encludes$}
$endif$
$if(notice)$
\begin{textblock}{170}(20,262)%hpos,vpos Werte in mm
\scriptsize
\textbf{Hinweise für den Schulungsteilnehmer:}
\newline
$for(notice)$
$notice$
$sep$\newline
$endfor$
\end{textblock}
$endif$
\end{letter}
\end{document}