Merge branch 'fradrive/cr3'
This commit is contained in:
commit
b77e9e1d1c
@ -25,7 +25,8 @@ import qualified Database.Esqueleto.Legacy as E
|
||||
import qualified Database.Esqueleto.Utils as E
|
||||
import Database.Esqueleto.Utils.TH
|
||||
|
||||
import Utils.Print
|
||||
import Utils.Print hiding (LetterRenewQualificationF)
|
||||
import Utils.Print.RenewQualification
|
||||
|
||||
import qualified Data.Aeson as Aeson
|
||||
-- import qualified Data.Text as Text
|
||||
@ -82,7 +83,7 @@ lrqf2letter LRQF{..}
|
||||
usr <- getUser lrqfUser
|
||||
rcvr <- mapM getUser lrqfSuper
|
||||
now <- liftIO getCurrentTime
|
||||
let letter = LetterRenewQualificationF
|
||||
let letter = LetterRenewQualification
|
||||
{ lmsLogin = lrqfIdent
|
||||
, lmsPin = lrqfPin
|
||||
, qualHolderID = usr ^. _entityKey
|
||||
|
||||
@ -565,16 +565,16 @@ getAvsCompany afi =
|
||||
in firstJustM $
|
||||
bcons (compAvsId > 0)
|
||||
( getBy $ UniqueCompanyAvsId compAvsId )
|
||||
[ getEntity $ CompanyKey compShorthand
|
||||
, getBy $ UniqueCompanyName compName
|
||||
[ getBy $ UniqueCompanyName compName
|
||||
, getEntity $ CompanyKey compShorthand
|
||||
]
|
||||
|
||||
-- | insert a company from AVS firm info or update an existing one based on previous values
|
||||
upsertAvsCompany :: AvsFirmInfo -> Maybe AvsFirmInfo -> DB (Entity Company)
|
||||
upsertAvsCompany newAvsFirmInfo mbOldAvsFirmInfo = do
|
||||
mbFirmEnt <- getAvsCompany newAvsFirmInfo
|
||||
mbFirmEnt <- getAvsCompany newAvsFirmInfo -- primarily by AvsId, then Shorthand, then name
|
||||
case (mbFirmEnt, mbOldAvsFirmInfo) of
|
||||
(Nothing, _) -> do -- insert new company
|
||||
(Nothing, _) -> do -- insert new company, neither AvsId, Shorthand or Name are known to exist
|
||||
let upd = flip updateRecord newAvsFirmInfo
|
||||
dmy = Company -- mostly dummy, values are actually prodcued through firmInfo2company below for consistency
|
||||
{ companyName = newAvsFirmInfo ^. _avsFirmFirm . from _CI
|
||||
@ -583,32 +583,36 @@ upsertAvsCompany newAvsFirmInfo mbOldAvsFirmInfo = do
|
||||
, companyPrefersPostal = True
|
||||
, companyPostAddress = newAvsFirmInfo ^. _avsFirmPostAddress
|
||||
, companyEmail = newAvsFirmInfo ^? _avsFirmPrimaryEmail . _Just . from _CI
|
||||
}
|
||||
newCmp <- insertEntity $ foldl' upd dmy $ firmInfo2key : firmInfo2company
|
||||
}
|
||||
newCmp <- insertEntity $ foldl' upd dmy $ firmInfo2key : firmInfo2companyUniques <> firmInfo2company
|
||||
reportAdminProblem $ AdminProblemNewCompany $ entityKey newCmp
|
||||
return newCmp
|
||||
|
||||
(Just Entity{entityKey=firmid, entityVal=firm}, oldAvsFirmInfo) -> do -- possibly update existing company, if isJust oldAvsFirmInfo and changed occurred
|
||||
let cmp_ups = mapMaybe (mkUpdate' firm newAvsFirmInfo oldAvsFirmInfo) firmInfo2company
|
||||
key_ups = mkUpdate' firm newAvsFirmInfo oldAvsFirmInfo firmInfo2key
|
||||
res_cmp <- updateGetEntity firmid cmp_ups
|
||||
let cmp_ups = mapMaybe (mkUpdate' firm newAvsFirmInfo oldAvsFirmInfo) firmInfo2company
|
||||
key_ups = mkUpdate' firm newAvsFirmInfo oldAvsFirmInfo firmInfo2key
|
||||
uniq_ups <- maybeMapM (mkUpdateCheckUnique' firm newAvsFirmInfo oldAvsFirmInfo) firmInfo2companyUniques
|
||||
res_cmp <- updateGetEntity firmid $ cmp_ups <> uniq_ups
|
||||
case key_ups of
|
||||
Nothing -> return res_cmp
|
||||
Just key_up -> do
|
||||
let uniq_cmp = UniqueCompanyAvsId $ res_cmp ^. _entityVal . _companyAvsId
|
||||
let compId = res_cmp ^. _entityVal . _companyAvsId
|
||||
uniq_cmp = if compId > 0 then UniqueCompanyAvsId compId
|
||||
else UniqueCompanyName $ res_cmp ^. _entityVal . _companyName
|
||||
updateBy uniq_cmp [key_up] -- this is ok, since we have OnUpdateCascade on all CompanyId entries
|
||||
maybeM (return res_cmp) return $ getBy uniq_cmp
|
||||
|
||||
|
||||
where
|
||||
firmInfo2key =
|
||||
firmInfo2key =
|
||||
CheckUpdate CompanyShorthand $ _avsFirmAbbreviation . from _CI -- Updating primary key works in principle thanks to OnUpdateCascade, but fails due to update get
|
||||
firmInfo2companyUniques =
|
||||
[ CheckUpdate CompanyName $ _avsFirmFirm . from _CI -- Updating unique turned out to be problematic, who would have thought!
|
||||
, CheckUpdate CompanyAvsId _avsFirmFirmNo -- Updating unique turned out to be problematic, who would have thought!
|
||||
]
|
||||
firmInfo2company =
|
||||
[ CheckUpdate CompanyName $ _avsFirmFirm . from _CI
|
||||
, CheckUpdate CompanyAvsId _avsFirmFirmNo -- Updating unique might be problematic
|
||||
-- , CheckUpdate CompanyPrefersPostal _avsFirmPrefersPostal -- Guessing here is not useful, since postal preference is ignored anyway when there is only one option available
|
||||
, CheckUpdate CompanyPostAddress _avsFirmPostAddress
|
||||
[ CheckUpdate CompanyPostAddress _avsFirmPostAddress
|
||||
, CheckUpdate CompanyEmail $ _avsFirmPrimaryEmail . _Just . from _CI . re _Just
|
||||
-- , CheckUpdate CompanyPrefersPostal _avsFirmPrefersPostal -- Guessing here is not useful, since postal preference is ignored anyway when there is only one option available
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -364,4 +364,28 @@ updateRecord :: PersistEntity record => record -> iraw -> CheckUpdate record ira
|
||||
updateRecord ent new (CheckUpdate up l) =
|
||||
let newval = new ^. l
|
||||
lensRec = fieldLensVal up
|
||||
in ent & lensRec .~ newval
|
||||
in ent & lensRec .~ newval
|
||||
|
||||
-- | like mkUpdate' but only returns the update if the new value would be unique
|
||||
-- mkUpdateCheckUnique' :: PersistEntity record => record -> iraw -> Maybe iraw -> CheckUpdate record iraw -> DB (Maybe (Update record))
|
||||
|
||||
mkUpdateCheckUnique' :: (MonadIO m, PersistQueryRead backend, PersistEntity record, PersistEntityBackend record ~ BaseBackend backend)
|
||||
=> record -> a -> Maybe a -> CheckUpdate record a -> ReaderT backend m (Maybe (Update record))
|
||||
|
||||
mkUpdateCheckUnique' ent new Nothing (CheckUpdate up l)
|
||||
| let newval = new ^. l
|
||||
, let entval = ent ^. fieldLensVal up
|
||||
, newval /= entval
|
||||
= do
|
||||
newval_exists <- exists [up ==. newval]
|
||||
return $ toMaybe (not newval_exists) (up =. newval)
|
||||
mkUpdateCheckUnique' ent new (Just old) (CheckUpdate up l)
|
||||
| let newval = new ^. l
|
||||
, let oldval = old ^. l
|
||||
, let entval = ent ^. fieldLensVal up
|
||||
, newval /= entval
|
||||
, oldval == entval
|
||||
= do
|
||||
newval_exists <- exists [up ==. newval]
|
||||
return $ toMaybe (not newval_exists) (up =. newval)
|
||||
mkUpdateCheckUnique' _ _ _ _ = return Nothing
|
||||
|
||||
@ -23,6 +23,7 @@ module Utils.Print
|
||||
-- , MDLetter
|
||||
, SomeLetter(..)
|
||||
, LetterRenewQualificationF(..)
|
||||
-- , LetterRenewQualification(..)
|
||||
, LetterExpireQualification(..)
|
||||
-- , LetterCourseCertificate()
|
||||
, makeCourseCertificates
|
||||
@ -59,7 +60,8 @@ import Jobs.Handler.SendNotification.Utils
|
||||
import Utils.Print.Instances ()
|
||||
import Utils.Print.Letters
|
||||
import Utils.Print.SomeLetter
|
||||
import Utils.Print.RenewQualification
|
||||
import Utils.Print.RenewQualificationF
|
||||
import Utils.Print.RenewQualification()
|
||||
import Utils.Print.ExpireQualification
|
||||
import Utils.Print.CourseCertificate
|
||||
|
||||
|
||||
@ -129,6 +129,7 @@ defWriterOpts t = def { P.writerExtensions = P.pandocExtensions, P.writerTemplat
|
||||
|
||||
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
|
||||
| PinNew -- New Variant for Pin Letters for R. TODO: Remove/rename/replace PinLetter
|
||||
| Plain -- scrartcl: Empty, expects empty paper with no preprints
|
||||
| PlainLogo -- Like plain, but expects to be printed on paper with Logo
|
||||
-- | Logo -- Like plain, but prints Fraport Logo in the upper right corner
|
||||
@ -139,15 +140,18 @@ templateLatex =
|
||||
let
|
||||
tDin5008 = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008.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")
|
||||
in \case
|
||||
PinLetter -> tPinLetter
|
||||
PinNew -> tPinNew
|
||||
Din5008 -> tDin5008
|
||||
PlainLogo -> tPlain
|
||||
Plain -> tPlain
|
||||
|
||||
paperKind :: LetterKind -> Text -- Muss genau 5 Zeichen haben!
|
||||
paperKind PinLetter = "a4pin" -- Pin-Brief
|
||||
paperKind PinNew = "a4pin" -- Pin-Brief
|
||||
paperKind Plain = "a4wht" -- Ohne Logo
|
||||
paperKind Din5008 = "a4log" -- Mit Logo
|
||||
paperKind PlainLogo = "a4log"
|
||||
|
||||
@ -19,7 +19,7 @@ import Utils.Print.Letters
|
||||
import Handler.Utils.Widgets (nameHtml) -- , nameHtml')
|
||||
|
||||
|
||||
data LetterRenewQualificationF = LetterRenewQualificationF
|
||||
data LetterRenewQualification = LetterRenewQualification
|
||||
{ lmsLogin :: LmsIdent
|
||||
, lmsPin :: Text
|
||||
, qualHolderID :: UserId
|
||||
@ -37,30 +37,31 @@ data LetterRenewQualificationF = LetterRenewQualificationF
|
||||
|
||||
|
||||
-- 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 }
|
||||
data LetterRenewQualificationData = LetterRenewQualificationData { lmsUrl, lmsUrlLogin, lmsIdent :: Text }
|
||||
deriving (Eq, Show)
|
||||
|
||||
letterRenewalQualificationFData :: LetterRenewQualificationF -> LetterRenewQualificationFData
|
||||
letterRenewalQualificationFData LetterRenewQualificationF{lmsLogin} = LetterRenewQualificationFData{..}
|
||||
letterRenewalQualificationFData :: LetterRenewQualification -> LetterRenewQualificationData
|
||||
letterRenewalQualificationFData LetterRenewQualification{lmsLogin} = LetterRenewQualificationData{..}
|
||||
where
|
||||
lmsUrl = "https://drive.fraport.de"
|
||||
lmsUrlLogin = lmsUrl <> "/?login=" <> lmsIdent
|
||||
lmsUrl = "drive.fraport.de"
|
||||
lmsUrlLogin = "https://" <> lmsUrl <> "/?login=" <> lmsIdent
|
||||
lmsIdent = getLmsIdent lmsLogin
|
||||
|
||||
|
||||
instance MDLetter LetterRenewQualificationF where
|
||||
instance MDLetter LetterRenewQualification where
|
||||
encryptPDFfor _ = PasswordUnderling
|
||||
getLetterKind _ = PinLetter
|
||||
getLetterKind _ = PinNew
|
||||
getLetterEnvelope _ = 'f' -- maybe 'q' (Char.toLower . fst) $ Text.uncons (qualShort l)
|
||||
getTemplate _ = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal.md")
|
||||
getTemplate _ = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal_new.md")
|
||||
getMailSubject l = SomeMessage $ MsgMailSubjectQualificationRenewal $ qualShort l
|
||||
getMailBody l@LetterRenewQualificationF{..} = Just $ \DateTimeFormatter{ format } ->
|
||||
let LetterRenewQualificationFData{..} = letterRenewalQualificationFData l
|
||||
getMailBody l@LetterRenewQualification{..} = Just $ \DateTimeFormatter{ format } ->
|
||||
let LetterRenewQualificationData{..} = 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
|
||||
letterMeta l@LetterRenewQualification{..} DateTimeFormatter{ format } lang Entity{entityKey=rcvrId, entityVal=User{userDisplayName}} =
|
||||
let LetterRenewQualificationData{..} = letterRenewalQualificationFData l
|
||||
isSupervised = rcvrId /= qualHolderID
|
||||
newExpire = addDays (fromIntegral $ fromMaybe 0 qualDuration) qualExpiry
|
||||
in mkMeta $
|
||||
guardMonoid isSupervised
|
||||
[ toMeta "supervisor" userDisplayName
|
||||
@ -79,10 +80,15 @@ instance MDLetter LetterRenewQualificationF where
|
||||
, mbMeta "validduration" (show <$> qualDuration)
|
||||
, toMeta "url-text" lmsUrl
|
||||
, toMeta "url" lmsUrlLogin
|
||||
, toMeta "notice" [ [st|Ein Zertifikat für Ihre Unterlagen kann nur direkt nach dem erfolgreichen Test erstellt werden. Das Zertifikat wird auf die Benutzerkennung ausgestellt. Zusammen mit diesem Schreiben können Sie Ihrem Arbeitgeber zeigen, dass Sie bestanden haben. Bei erfolgreichem Abschluss der Schulung verlängert sich das Ablaufdatum automatisch auf den #{format SelFormatDate newExpire}. Wir empfehlen die Schulung zeitnah durchzuführen. Sollte bis zum Ablaufdatum das E-Learning nicht erfolgreich abgeschlossen sein oder der Test nach 5 Versuchen nicht bestanden werden, muss zur Wiedererlangung der Fahrberechtigung „#{qualShort}“ ein Grundkurs #{qualName} bei der Fahrerausbildung absolviert werden.|]
|
||||
, "Benötigen Sie die Fahrberechtigung nicht mehr, informieren Sie bitte die Fahrerausbildung."::Text
|
||||
, "(Please contact us if you prefer letters in English.)"
|
||||
]
|
||||
, toMeta "de-subject" [st|Verlängerung Fahrberechtigung „#{qualShort}“ (#{qualName})|]
|
||||
, toMeta "en-subject" [st|Renewal of driving licence „#{qualShort}“ (#{qualName})|]
|
||||
] -- TODO use [st|some simple text with interpolation|]
|
||||
|
||||
]
|
||||
|
||||
getPJId LetterRenewQualificationF{..} =
|
||||
getPJId LetterRenewQualification{..} =
|
||||
PrintJobIdentification
|
||||
{ pjiName = bool "Renewal" "Renewal Reminder" isReminder
|
||||
, pjiApcAcknowledge = "lms-" <> getLmsIdent lmsLogin
|
||||
|
||||
100
src/Utils/Print/RenewQualificationF.hs
Normal file
100
src/Utils/Print/RenewQualificationF.hs
Normal file
@ -0,0 +1,100 @@
|
||||
-- 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])
|
||||
}
|
||||
206
templates/letter/din5008with_pin_new.latex
Normal file
206
templates/letter/din5008with_pin_new.latex
Normal file
@ -0,0 +1,206 @@
|
||||
%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}
|
||||
\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}
|
||||
|
||||
%\usepackage[ngerman]{babel}
|
||||
$if(lang)$
|
||||
\ifLuaTeX
|
||||
\usepackage[bidi=basic]{babel}
|
||||
\else
|
||||
\usepackage[bidi=default]{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}
|
||||
|
||||
$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}(84,232)%hpos,vpos
|
||||
\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,258)%hpos,vpos
|
||||
\scriptsize
|
||||
\textbf{Hinweise für den Schulungsteilnehmer:}
|
||||
\newline
|
||||
$for(notice)$
|
||||
$notice$
|
||||
$sep$\newline
|
||||
$endfor$
|
||||
\end{textblock}
|
||||
$endif$
|
||||
\end{letter}
|
||||
\end{document}
|
||||
@ -86,6 +86,8 @@ $else$
|
||||
$endif$
|
||||
Die Durchführung des Lernprogramms und des Abschlusstests dauert etwa 2,5h.
|
||||
|
||||
This is the new version
|
||||
|
||||
Fahrberechtigungsinhaber
|
||||
|
||||
: $examinee$
|
||||
|
||||
130
templates/letter/fraport_renewal_new.md
Normal file
130
templates/letter/fraport_renewal_new.md
Normal file
@ -0,0 +1,130 @@
|
||||
---
|
||||
### Metadaten, welche hier eingestellt werden:
|
||||
# Absender
|
||||
de-subject: 'Verlängerung Fahrberechtigung "F" (Vorfeldführerschein)'
|
||||
en-subject: Renewal of apron driving license
|
||||
author: Fraport AG - Fahrerausbildung (AVN-AR)
|
||||
phone: +49 69 690-30306
|
||||
email: fahrerausbildung@fraport.de
|
||||
place: Frankfurt am Main
|
||||
return-address:
|
||||
- 60547 Frankfurt
|
||||
de-opening: Liebe Fahrberechtigungsinhaber,
|
||||
en-opening: Dear driver,
|
||||
de-closing: |
|
||||
Mit freundlichen Grüßen,
|
||||
Ihre Fraport Fahrerausbildung
|
||||
en-closing: |
|
||||
With kind regards,
|
||||
Your Fraport Driver Training
|
||||
encludes:
|
||||
hyperrefoptions: hidelinks
|
||||
|
||||
### Metadaten, welche automatisch ersetzt werden:
|
||||
url-text: 'drive.fraport.de'
|
||||
url: 'https://drive.fraport.de'
|
||||
date: 11.11.1111
|
||||
expiry: 00.00.0000
|
||||
lang: de-de
|
||||
is-de: true
|
||||
login: 123456
|
||||
pin: abcdef
|
||||
paper: pin
|
||||
# Emfpänger
|
||||
examinee: P. Rüfling
|
||||
address:
|
||||
- E. M. Pfänger
|
||||
- Musterfirma GmbH
|
||||
- Musterstraße 11
|
||||
- 12345 Musterstadt
|
||||
...
|
||||
$if(titleblock)$
|
||||
$titleblock$
|
||||
|
||||
$endif$
|
||||
$for(header-includes)$
|
||||
$header-includes$
|
||||
|
||||
$endfor$
|
||||
$for(include-before)$
|
||||
$include-before$
|
||||
|
||||
$endfor$
|
||||
|
||||
$if(is-de)$
|
||||
|
||||
<!-- deutsche Version des Briefes -->
|
||||
|
||||
um die Rollfeldfahrberechtigung von \textbf{$examinee$} zu erhalten, benötigen wir bis zum $date$ den Nachweis, dass die theoretische und praktische flughafenspezifische Rollfeld Recurrent Schulung der Fraport AG gemäß Verordnung der Europäische Union Nr. 139/2014 absolviert wurde.
|
||||
|
||||
Die Online-Schulung der Fraport AG ist erreichbar unter folgendem Link:
|
||||
[$url-text$]($url$)
|
||||
|
||||
Der erforderliche Benutzername und das Passwort für die Fraport Online-Schulung finden Sie untenstehend. Die Weitergabe der persönlichen Benutzerdaten an Dritte ist untersagt. Ausschließlich Sie sind berechtigt, die Benutzerdaten an den Schulungsteilnehmer auszuhändigen.
|
||||
|
||||
Für die Absolvierung der Schulungsmaßnahme werden 1-2 Stunden benötigt. Der Abschluss der Schulung wird automatisch an das System der Fahrerausbildung übermittelt.
|
||||
|
||||
Nach erfolgreichem Abschluss der Online-Schulung muss \textbf{$examinee$} sich von Ihrer Firma zum praktischen Teil der Schulung einplanen lassen. Im Rahmen der 3--4-stündigen praktischen Auffrischung erfolgen Funkübungen sowie die Durchführung einer Übungsfahrt mit Prüfungscharakter im Start-/Landebahnsystem.
|
||||
|
||||
$else$
|
||||
|
||||
<!-- englische Version des Briefes -->
|
||||
$if(reminder)$
|
||||
this is a last **reminder**: as of $date$,
|
||||
$if(supervisor)$
|
||||
$examinee$ has
|
||||
$else$
|
||||
you have
|
||||
$endif$
|
||||
not yet completed the below detailed e‑learning.
|
||||
The qualification will expire automatically,
|
||||
if the e‑learning is not concluded in time!
|
||||
$else$
|
||||
$if(supervisor)$
|
||||
the apron diving license of $examinee$
|
||||
$else$
|
||||
your apron diving license
|
||||
$endif$
|
||||
is about to expire soon.
|
||||
$endif$
|
||||
The validity will be extended
|
||||
$if(validduration)$
|
||||
by $validduration$ months
|
||||
$endif$
|
||||
by successfully participating in
|
||||
an e‑learning.
|
||||
$if(supervisor)$
|
||||
Supervisors are kindly requested to forward the login data
|
||||
below confidentially to the examinee.
|
||||
$else$
|
||||
Please use the login data from the protected area below.
|
||||
$endif$
|
||||
Reserve 2.5h for the entire e-learning, including the exam.
|
||||
|
||||
Examinee
|
||||
|
||||
: $examinee$
|
||||
|
||||
Expiry
|
||||
|
||||
: $expiry$
|
||||
|
||||
E-learning website
|
||||
|
||||
: [$url-text$]($url$)
|
||||
|
||||
|
||||
If the apron driving license expires before completing this e-learning,
|
||||
$if(supervisor)$
|
||||
the examinee has to participate in a basic training course again to regain
|
||||
to regain the apron driving licence.
|
||||
$else$
|
||||
you have to participate in a basic training course again to regain
|
||||
your apron driving licence.
|
||||
$endif$
|
||||
|
||||
|
||||
Please contact the Fraport driving school team, if you need any assistance.
|
||||
(Kontaktieren Sie uns bitte, wenn Sie zukünftige Briefe in deutscher Sprache bevorzugen.)
|
||||
|
||||
$endif$
|
||||
2137
uniworx.cabal.bak
2137
uniworx.cabal.bak
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user