Merge branch 'fradrive/company' into test
This commit is contained in:
commit
1797d4eb9b
@ -20,6 +20,8 @@ UnauthorizedTokenInvalidAuthorityValue: Ihr Authorisierungs-Token basiert auf Re
|
|||||||
UnauthorizedTokenInvalidImpersonation: Ihr Authorisierungs-Token enthält die Anweisung sich als ein Nutzer:in auszugeben, dies ist jedoch nicht allen Benutzer:innen, auf deren Rechten ihr Authorisierungs-Token basiert, erlaubt.
|
UnauthorizedTokenInvalidImpersonation: Ihr Authorisierungs-Token enthält die Anweisung sich als ein Nutzer:in auszugeben, dies ist jedoch nicht allen Benutzer:innen, auf deren Rechten ihr Authorisierungs-Token basiert, erlaubt.
|
||||||
UnauthorizedToken404: Authorisierungs-Tokens können nicht auf Fehlerseiten ausgewertet werden.
|
UnauthorizedToken404: Authorisierungs-Tokens können nicht auf Fehlerseiten ausgewertet werden.
|
||||||
UnauthorizedSupervisor: Sie sind kein Ansprechpartner:in für diesen Benutzer:in.
|
UnauthorizedSupervisor: Sie sind kein Ansprechpartner:in für diesen Benutzer:in.
|
||||||
|
UnauthorizedAnySupervisor: Sie sind kein Ansprechpartner:in.
|
||||||
|
UnauthorizedCompanySupervisor fsh@CompanyShorthand: Sie sind kein Standard Ansprechpartner:in für Firma #{fsh}.
|
||||||
UnauthorizedSiteAdmin: Sie sind nicht System-weiter Administrator:in.
|
UnauthorizedSiteAdmin: Sie sind nicht System-weiter Administrator:in.
|
||||||
UnauthorizedSchoolAdmin: Sie sind nicht als Administrator:in für diesen Bereich eingetragen.
|
UnauthorizedSchoolAdmin: Sie sind nicht als Administrator:in für diesen Bereich eingetragen.
|
||||||
UnauthorizedAdminEscalation: Sie sind nicht Administrator:in für alle Bereiche, für die dieser Nutzer/diese Nutzerin Administrator:in oder Veranstalter:in ist.
|
UnauthorizedAdminEscalation: Sie sind nicht Administrator:in für alle Bereiche, für die dieser Nutzer/diese Nutzerin Administrator:in oder Veranstalter:in ist.
|
||||||
|
|||||||
@ -20,6 +20,8 @@ UnauthorizedTokenInvalidAuthorityValue: The specification of the rights in which
|
|||||||
UnauthorizedTokenInvalidImpersonation: Your authorisation-token contains an instruction to impersonate an user. Not all users on whose rights your token is based however are permitted to do so.
|
UnauthorizedTokenInvalidImpersonation: Your authorisation-token contains an instruction to impersonate an user. Not all users on whose rights your token is based however are permitted to do so.
|
||||||
UnauthorizedToken404: Authorisation-tokens cannot be processed on error pages.
|
UnauthorizedToken404: Authorisation-tokens cannot be processed on error pages.
|
||||||
UnauthorizedSupervisor: You are not a supervisor for the requested user.
|
UnauthorizedSupervisor: You are not a supervisor for the requested user.
|
||||||
|
UnauthorizedAnySupervisor: You are not a supervisor.
|
||||||
|
UnauthorizedCompanySupervisor fsh: You are not a default supervisor for company #{fsh}.
|
||||||
UnauthorizedSiteAdmin: You are no system-wide administrator.
|
UnauthorizedSiteAdmin: You are no system-wide administrator.
|
||||||
UnauthorizedSchoolAdmin: You are no administrator for this department.
|
UnauthorizedSchoolAdmin: You are no administrator for this department.
|
||||||
UnauthorizedAdminEscalation: You aren't an administrator for all departments for which this user is an administrator.
|
UnauthorizedAdminEscalation: You aren't an administrator for all departments for which this user is an administrator.
|
||||||
|
|||||||
@ -5,4 +5,6 @@
|
|||||||
FirmAllActNotify: Mitteilung versenden
|
FirmAllActNotify: Mitteilung versenden
|
||||||
FirmAllActResetSupervision: Ansprechpartner für alle Firmenangehörigen zurücksetzen
|
FirmAllActResetSupervision: Ansprechpartner für alle Firmenangehörigen zurücksetzen
|
||||||
FirmUserActNotify: Mitteilung versenden
|
FirmUserActNotify: Mitteilung versenden
|
||||||
FirmUserActMkSuper: Zum Firmenansprechparnter ernennen
|
FirmUserActMkSuper: Zum Firmenansprechpartner ernennen
|
||||||
|
FilterSupervisor: Hat aktiven Ansprechpartner
|
||||||
|
FilterSupervisorCompany fsh@CompanyShorthand: Hat aktiven Ansprechpartner, der #{fsh} angehört
|
||||||
|
|||||||
@ -5,4 +5,6 @@
|
|||||||
FirmAllActNotify: Send message
|
FirmAllActNotify: Send message
|
||||||
FirmAllActResetSupervision: Reset supervisors for all company associates
|
FirmAllActResetSupervision: Reset supervisors for all company associates
|
||||||
FirmUserActNotify: Send message
|
FirmUserActNotify: Send message
|
||||||
FirmUserActMkSuper: Mark as company supervisor
|
FirmUserActMkSuper: Mark as company supervisor
|
||||||
|
FilterSupervisor: Has active supervisor
|
||||||
|
FilterSupervisorCompany fsh: Has active company supervisor belonging to #{fsh}
|
||||||
@ -37,7 +37,8 @@ PDFPassword: Passwort zur Verschlüsselung von PDF Anhängen an Email Benachrich
|
|||||||
PDFPasswordTip: Achtung, dieses Passwort ist für FRADrive Administratoren einsehbar und wird unverschlüsselt gespeichert!
|
PDFPasswordTip: Achtung, dieses Passwort ist für FRADrive Administratoren einsehbar und wird unverschlüsselt gespeichert!
|
||||||
PDFPasswordInvalid c@Char: Bitte ein nicht-triviales Passwort für PDF Email Anhänge eintragen! Ungültiges Zeichen: #{char2Text c}
|
PDFPasswordInvalid c@Char: Bitte ein nicht-triviales Passwort für PDF Email Anhänge eintragen! Ungültiges Zeichen: #{char2Text c}
|
||||||
PDFPasswordTooShort n@Int: Bitte ein PDF Passwort mit mindestens #{show n} Zeichen wählen oder Post-Versand aktivieren
|
PDFPasswordTooShort n@Int: Bitte ein PDF Passwort mit mindestens #{show n} Zeichen wählen oder Post-Versand aktivieren
|
||||||
PrefersPostal: Sollen Benachrichtigung möglichst per Post versendet werden anstatt per Email?
|
PrefersPostal: Bevorzugte Benachrichtigung
|
||||||
|
PrefersPostalExp: Sollen Benachrichtigung möglichst per Post versendet werden anstatt per Email?
|
||||||
PostalTip: Postversand kann in Rechnung gestellt werden und ist derzeit nur für Benachrichtigungen über Erneuerung und Ablauf von Qualifikation, wie z.B. Führerscheine, verfügbar.
|
PostalTip: Postversand kann in Rechnung gestellt werden und ist derzeit nur für Benachrichtigungen über Erneuerung und Ablauf von Qualifikation, wie z.B. Führerscheine, verfügbar.
|
||||||
PostAddress: Postalische Adresse
|
PostAddress: Postalische Adresse
|
||||||
PostAddressTip: Mindestens eine Zeile mit Straße und Hausnummer und eine Zeile mit Postleitzahl und Ort. Kein Empfängername, denn dieser wird später automatisch hinzugefügt.
|
PostAddressTip: Mindestens eine Zeile mit Straße und Hausnummer und eine Zeile mit Postleitzahl und Ort. Kein Empfängername, denn dieser wird später automatisch hinzugefügt.
|
||||||
|
|||||||
@ -37,7 +37,8 @@ PDFPassword: Password to lock PDF email attachments
|
|||||||
PDFPasswordTip: Please note that this password is displayed to FRADrive admins and is saved unencrypted
|
PDFPasswordTip: Please note that this password is displayed to FRADrive admins and is saved unencrypted
|
||||||
PDFPasswordInvalid c: Please supply a sensible password for encrypting PDF email attachments! Invalid character #{char2Text c}
|
PDFPasswordInvalid c: Please supply a sensible password for encrypting PDF email attachments! Invalid character #{char2Text c}
|
||||||
PDFPasswordTooShort n: Please provide a password with at least #{show n} characters or choose postal mail
|
PDFPasswordTooShort n: Please provide a password with at least #{show n} characters or choose postal mail
|
||||||
PrefersPostal: Should notifications preferably send by post instead of email?
|
PrefersPostal: Notification preference
|
||||||
|
PrefersPostalExp: Should notifications preferably send by post instead of email?
|
||||||
PostalTip: Mailing may incur a fee and is currently only avaulable for qualification expiry notifications, such as driving lincence renewal.
|
PostalTip: Mailing may incur a fee and is currently only avaulable for qualification expiry notifications, such as driving lincence renewal.
|
||||||
PostAddress: Postal address
|
PostAddress: Postal address
|
||||||
PostAddressTip: Should contain at least one line with street and house number and another line featuring zip code and town. Omit a recipient name, since it will be added later.
|
PostAddressTip: Should contain at least one line with street and house number and another line featuring zip code and town. Omit a recipient name, since it will be added later.
|
||||||
|
|||||||
@ -80,6 +80,7 @@ TableCompanyShort: Firmenkürzel
|
|||||||
TableCompanies: Firmen
|
TableCompanies: Firmen
|
||||||
TableCompanyNo: Firmennummer
|
TableCompanyNo: Firmennummer
|
||||||
TableCompanyNos: Firmennummern
|
TableCompanyNos: Firmennummern
|
||||||
|
TableCompanyUser: Firmenangehöriger
|
||||||
TableCompanyNrUsers: Firmenangehörige
|
TableCompanyNrUsers: Firmenangehörige
|
||||||
TableCompanyNrSupers: Ansprechpartner
|
TableCompanyNrSupers: Ansprechpartner
|
||||||
TableCompanyNrEmpSupervised: Firmenangehörige mit Ansprechpartner
|
TableCompanyNrEmpSupervised: Firmenangehörige mit Ansprechpartner
|
||||||
@ -90,6 +91,7 @@ TableCompanyNrSupersDefault: Standard Ansprechpartner
|
|||||||
TableCompanyNrForeignSupers: Firmenfremde Ansprechpartner
|
TableCompanyNrForeignSupers: Firmenfremde Ansprechpartner
|
||||||
TableCompanyNrRerouteDefault: Standard Umleitungen
|
TableCompanyNrRerouteDefault: Standard Umleitungen
|
||||||
TableCompanyNrRerouteActive: Aktive Umleitungen
|
TableCompanyNrRerouteActive: Aktive Umleitungen
|
||||||
|
TableCompanyPostalPreference: Benachrichtigungspräferenz neue Firmenangehörige
|
||||||
TableSupervisor: Ansprechpartner
|
TableSupervisor: Ansprechpartner
|
||||||
TableCreationTime: Erstellungszeit
|
TableCreationTime: Erstellungszeit
|
||||||
TableJob !ident-ok: Job
|
TableJob !ident-ok: Job
|
||||||
@ -100,4 +102,5 @@ TableJobCreationInstance: Ersteller
|
|||||||
ActJobDelete: Job entfernen
|
ActJobDelete: Job entfernen
|
||||||
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} Jobs entfernt
|
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} Jobs entfernt
|
||||||
TableFilterComma: Es können mehrere alternative Suchkriterien mit Komma getrennt angegeben werden, wovon mindestens eines erfüllt werden muss.
|
TableFilterComma: Es können mehrere alternative Suchkriterien mit Komma getrennt angegeben werden, wovon mindestens eines erfüllt werden muss.
|
||||||
TableFilterCommaPlus: Mehrere alternative Suchkriterien mit Komma trennen. Mindestens ein Suchkriterium muss erfüllt werden, zusätzlich zu allen Suchkriterien mit vorangestelltem Plus-Symbol.
|
TableFilterCommaPlus: Mehrere alternative Suchkriterien mit Komma trennen. Mindestens ein Suchkriterium muss erfüllt werden, zusätzlich zu allen Suchkriterien mit vorangestelltem Plus-Symbol.
|
||||||
|
TableFilterCommaNameNr: Mehrere Namen oder Nummern mit Komma trennen. Nummern werden nur exakt gesucht.
|
||||||
@ -80,6 +80,7 @@ TableCompanyShort: Company shorthand
|
|||||||
TableCompanies: Companies
|
TableCompanies: Companies
|
||||||
TableCompanyNo: Company number
|
TableCompanyNo: Company number
|
||||||
TableCompanyNos: Company numbers
|
TableCompanyNos: Company numbers
|
||||||
|
TableCompanyUser: Associate
|
||||||
TableCompanyNrUsers: Associates
|
TableCompanyNrUsers: Associates
|
||||||
TableCompanyNrSupers: Supervisors
|
TableCompanyNrSupers: Supervisors
|
||||||
TableCompanyNrEmpSupervised: Supervsied employees
|
TableCompanyNrEmpSupervised: Supervsied employees
|
||||||
@ -90,6 +91,7 @@ TableCompanyNrSupersDefault: Default supervisors
|
|||||||
TableCompanyNrForeignSupers: External Supervisors
|
TableCompanyNrForeignSupers: External Supervisors
|
||||||
TableCompanyNrRerouteDefault: Default reroutes
|
TableCompanyNrRerouteDefault: Default reroutes
|
||||||
TableCompanyNrRerouteActive: Active reroutes
|
TableCompanyNrRerouteActive: Active reroutes
|
||||||
|
TableCompanyPostalPreference: Default notification preference
|
||||||
TableSupervisor: Supervisor
|
TableSupervisor: Supervisor
|
||||||
TableCreationTime: Creation
|
TableCreationTime: Creation
|
||||||
TableJob !ident-ok: Job
|
TableJob !ident-ok: Job
|
||||||
@ -100,4 +102,5 @@ TableJobCreationInstance: Creator
|
|||||||
ActJobDelete: Delete job
|
ActJobDelete: Delete job
|
||||||
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} queued jobs deleted
|
TableJobActDeleteFeedback n@Int m@Int: #{n}/#{m} queued jobs deleted
|
||||||
TableFilterComma: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled.
|
TableFilterComma: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled.
|
||||||
TableFilterCommaPlus: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled in addition to all criteria preceded by a plus symbol.
|
TableFilterCommaPlus: Separate multiple alternative filter criteria by comma, at least one of which must be fulfilled in addition to all criteria preceded by a plus symbol.
|
||||||
|
TableFilterCommaNameNr: Separate names and numbers by comma. Numbers have to match exact.
|
||||||
6
routes
6
routes
@ -113,10 +113,10 @@
|
|||||||
/for/#CryptoUUIDUser/user ForProfileR GET POST !supervisor !self
|
/for/#CryptoUUIDUser/user ForProfileR GET POST !supervisor !self
|
||||||
/for/#CryptoUUIDUser/user/profile ForProfileDataR GET !supervisor !self
|
/for/#CryptoUUIDUser/user/profile ForProfileDataR GET !supervisor !self
|
||||||
|
|
||||||
/firm FirmAllR GET POST
|
/firm FirmAllR GET POST !supervisor
|
||||||
/firm/#CompanyShorthand FirmR GET POST
|
/firm/#CompanyShorthand FirmR GET POST
|
||||||
/firm/#CompanyShorthand/users FirmUsersR GET POST
|
/firm/#CompanyShorthand/users FirmUsersR GET POST !supervisor
|
||||||
/firm/#CompanyShorthand/supers FirmSupersR GET POST
|
/firm/#CompanyShorthand/supers FirmSupersR GET POST !supervisor
|
||||||
|
|
||||||
/exam-office ExamOfficeR !exam-office:
|
/exam-office ExamOfficeR !exam-office:
|
||||||
/ EOExamsR GET POST !system-exam-office
|
/ EOExamsR GET POST !system-exam-office
|
||||||
|
|||||||
@ -18,7 +18,7 @@ module Database.Esqueleto.Utils
|
|||||||
, or, and
|
, or, and
|
||||||
, any, all
|
, any, all
|
||||||
, subSelectAnd, subSelectOr
|
, subSelectAnd, subSelectOr
|
||||||
, mkExactFilter, mkExactFilterWith
|
, mkExactFilter, mkExactFilterWith, mkExactFilterWithComma
|
||||||
, mkExactFilterLast, mkExactFilterLastWith
|
, mkExactFilterLast, mkExactFilterLastWith
|
||||||
, mkExactFilterMaybeLast, mkExactFilterMaybeLast'
|
, mkExactFilterMaybeLast, mkExactFilterMaybeLast'
|
||||||
, mkContainsFilter, mkContainsFilterWith
|
, mkContainsFilter, mkContainsFilterWith
|
||||||
@ -285,6 +285,17 @@ mkExactFilterWith cast lenslike row criterias
|
|||||||
| Set.null criterias = true
|
| Set.null criterias = true
|
||||||
| otherwise = lenslike row `E.in_` E.valList (cast <$> Set.toList criterias)
|
| otherwise = lenslike row `E.in_` E.valList (cast <$> Set.toList criterias)
|
||||||
|
|
||||||
|
-- | like `mkExactFilterWith` but splits comma separared Texts into multiple criteria
|
||||||
|
mkExactFilterWithComma :: (PersistField b)
|
||||||
|
=> (Text -> b) -- ^ type conversion
|
||||||
|
-> (t -> E.SqlExpr (E.Value b)) -- ^ getter from query to searched element
|
||||||
|
-> t -- ^ query row
|
||||||
|
-> Set.Set Text -- ^ needle collection
|
||||||
|
-> E.SqlExpr (E.Value Bool)
|
||||||
|
mkExactFilterWithComma cast lenslike row (foldMap commaSeparatedText -> criterias)
|
||||||
|
| Set.null criterias = true
|
||||||
|
| otherwise = lenslike row `E.in_` E.valList (cast <$> Set.toList criterias)
|
||||||
|
|
||||||
-- | generic filter creation for dbTable
|
-- | generic filter creation for dbTable
|
||||||
-- Given a lens-like function, make filter for exact matches against last element of a collection
|
-- Given a lens-like function, make filter for exact matches against last element of a collection
|
||||||
mkExactFilterLast :: (PersistField a)
|
mkExactFilterLast :: (PersistField a)
|
||||||
|
|||||||
@ -539,8 +539,11 @@ tagAccessPredicate AuthAdmin = cacheAPSchoolFunction SchoolAdmin (Just $ Right d
|
|||||||
return Authorized
|
return Authorized
|
||||||
|
|
||||||
tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
||||||
ForProfileR cID -> checkSupervisor (mAuthId, cID)
|
ForProfileR cID -> checkSupervisor (mAuthId, cID)
|
||||||
ForProfileDataR cID -> checkSupervisor (mAuthId, cID)
|
ForProfileDataR cID -> checkSupervisor (mAuthId, cID)
|
||||||
|
FirmAllR -> checkAnySupervisor mAuthId
|
||||||
|
FirmUsersR fsh -> checkCompanySupervisor (mAuthId, fsh)
|
||||||
|
FirmSupersR fsh -> checkCompanySupervisor (mAuthId, fsh)
|
||||||
r -> $unsupportedAuthPredicate AuthSupervisor r
|
r -> $unsupportedAuthPredicate AuthSupervisor r
|
||||||
where
|
where
|
||||||
checkSupervisor sup@(mAuthId, cID) = $cachedHereBinary sup . exceptT return return $ do
|
checkSupervisor sup@(mAuthId, cID) = $cachedHereBinary sup . exceptT return return $ do
|
||||||
@ -549,6 +552,16 @@ tagAccessPredicate AuthSupervisor = APDB $ \_ _ mAuthId route _ -> case route of
|
|||||||
isSupervisor <- lift . existsBy $ UniqueUserSupervisor authId uid
|
isSupervisor <- lift . existsBy $ UniqueUserSupervisor authId uid
|
||||||
guardMExceptT isSupervisor (unauthorizedI MsgUnauthorizedSupervisor)
|
guardMExceptT isSupervisor (unauthorizedI MsgUnauthorizedSupervisor)
|
||||||
return Authorized
|
return Authorized
|
||||||
|
checkCompanySupervisor sup@(mAuthId, fsh) = $cachedHereBinary sup . exceptT return return $ do
|
||||||
|
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||||
|
isSupervisor <- lift . existsBy $ UniqueUserCompany authId $ CompanyKey fsh
|
||||||
|
guardMExceptT isSupervisor (unauthorizedI $ MsgUnauthorizedCompanySupervisor fsh)
|
||||||
|
return Authorized
|
||||||
|
checkAnySupervisor mAuthId = $cachedHereBinary mAuthId . exceptT return return $ do
|
||||||
|
authId <- maybeExceptT AuthenticationRequired $ return mAuthId
|
||||||
|
isSupervisor <- lift $ exists [UserSupervisorSupervisor ==. authId]
|
||||||
|
guardMExceptT isSupervisor (unauthorizedI MsgUnauthorizedAnySupervisor)
|
||||||
|
return Authorized
|
||||||
|
|
||||||
tagAccessPredicate AuthSystemExamOffice = cacheAPSystemFunction SystemExamOffice (Just $ Right diffHour) $ \mAuthId' _ _ examOfficeList -> if
|
tagAccessPredicate AuthSystemExamOffice = cacheAPSystemFunction SystemExamOffice (Just $ Right diffHour) $ \mAuthId' _ _ examOfficeList -> if
|
||||||
| maybe True (`Set.notMember` examOfficeList) mAuthId' -> Right $ if
|
| maybe True (`Set.notMember` examOfficeList) mAuthId' -> Right $ if
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import qualified Data.CaseInsensitive as CI
|
|||||||
-- import Database.Persist.Sql (updateWhereCount)
|
-- import Database.Persist.Sql (updateWhereCount)
|
||||||
import Database.Esqueleto.Experimental ((:&)(..))
|
import Database.Esqueleto.Experimental ((:&)(..))
|
||||||
import qualified Database.Esqueleto.Experimental as E -- needs TypeApplications Lang-Pragma
|
import qualified Database.Esqueleto.Experimental as E -- needs TypeApplications Lang-Pragma
|
||||||
-- import qualified Database.Esqueleto.Legacy as EL
|
import qualified Database.Esqueleto.Legacy as EL (from, on)
|
||||||
-- import qualified Database.Esqueleto.PostgreSQL as E
|
-- import qualified Database.Esqueleto.PostgreSQL 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
|
||||||
@ -77,7 +77,7 @@ postFirmR fsh = do
|
|||||||
<ul>
|
<ul>
|
||||||
$forall (E.Value _, E.Value dn, E.Value sn, E.Value mbCsh, E.Value nr, E.Value prefPost) <- cactSuper
|
$forall (E.Value _, E.Value dn, E.Value sn, E.Value mbCsh, E.Value nr, E.Value prefPost) <- cactSuper
|
||||||
<li>#{nr} Employees supervised by ^{nameWidget dn sn} #
|
<li>#{nr} Employees supervised by ^{nameWidget dn sn} #
|
||||||
#{icon (bool IconAt IconLetter prefPost)} #
|
#{iconLetterOrEmail prefPost} #
|
||||||
$maybe csh <- mbCsh
|
$maybe csh <- mbCsh
|
||||||
$if csh /= fshId
|
$if csh /= fshId
|
||||||
from foreign company #{unCompanyKey csh}
|
from foreign company #{unCompanyKey csh}
|
||||||
@ -112,8 +112,8 @@ data FirmAllActionData = FirmAllActNotifyData
|
|||||||
|
|
||||||
-- just in case for future extensions
|
-- just in case for future extensions
|
||||||
type AllCompanyTableExpr = E.SqlExpr (Entity Company)
|
type AllCompanyTableExpr = E.SqlExpr (Entity Company)
|
||||||
queryCompany :: AllCompanyTableExpr -> E.SqlExpr (Entity Company)
|
queryAllCompany :: AllCompanyTableExpr -> E.SqlExpr (Entity Company)
|
||||||
queryCompany = id
|
queryAllCompany = id
|
||||||
|
|
||||||
type AllCompanyTableData = DBRow (Entity Company, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64)
|
type AllCompanyTableData = DBRow (Entity Company, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64, E.Value Word64)
|
||||||
resultAllCompanyEntity :: Lens' AllCompanyTableData (Entity Company)
|
resultAllCompanyEntity :: Lens' AllCompanyTableData (Entity Company)
|
||||||
@ -255,10 +255,8 @@ mkFirmAllTable isAdmin uid = do
|
|||||||
)
|
)
|
||||||
dbtRowKey = (E.^. CompanyId)
|
dbtRowKey = (E.^. CompanyId)
|
||||||
dbtProj = dbtProjId
|
dbtProj = dbtProjId
|
||||||
dbtColonnade = formColonnade $
|
dbtColonnade = formColonnade $ mconcat
|
||||||
mconcat
|
[ guardMonoid isAdmin $ dbSelect (applying _2) id (return . view (resultAllCompanyEntity . _entityKey))
|
||||||
[ if not isAdmin then mempty else -- guardOnM idAdmin $
|
|
||||||
dbSelect (applying _2) id (return . view (resultAllCompanyEntity . _entityKey))
|
|
||||||
, sortable (Just "name") (i18nCell MsgTableCompany) $ \(view resultAllCompany -> firm) ->
|
, sortable (Just "name") (i18nCell MsgTableCompany) $ \(view resultAllCompany -> firm) ->
|
||||||
anchorCell (FirmUsersR $ companyShorthand firm) . toWgt $ companyName firm
|
anchorCell (FirmUsersR $ companyShorthand firm) . toWgt $ companyName firm
|
||||||
, sortable (Just "short") (i18nCell MsgTableCompanyShort) $ \(view resultAllCompany -> firm) ->
|
, sortable (Just "short") (i18nCell MsgTableCompanyShort) $ \(view resultAllCompany -> firm) ->
|
||||||
@ -276,11 +274,13 @@ mkFirmAllTable isAdmin uid = do
|
|||||||
, sortable (Just "foreigners") (i18nCell MsgTableCompanyNrForeignSupers) $ \(view resultAllCompanyForeignSupers -> nr) -> wgtCell $ word2widget nr
|
, sortable (Just "foreigners") (i18nCell MsgTableCompanyNrForeignSupers) $ \(view resultAllCompanyForeignSupers -> nr) -> wgtCell $ word2widget nr
|
||||||
, sortable (Just "reroute-act") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultAllCompanyActiveReroutes -> nr) -> wgtCell $ word2widget nr
|
, sortable (Just "reroute-act") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultAllCompanyActiveReroutes -> nr) -> wgtCell $ word2widget nr
|
||||||
, sortable (Just "reroute-all") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultAllCompanyActiveReroutes' -> nr) -> wgtCell $ word2widget nr
|
, sortable (Just "reroute-all") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultAllCompanyActiveReroutes' -> nr) -> wgtCell $ word2widget nr
|
||||||
|
, sortable (Just "postal-pref") (i18nCell MsgTableCompanyPostalPreference) $ \(view $ resultAllCompany . _companyPrefersPostal -> b) -> iconFixedCell $ iconLetterOrEmail b
|
||||||
]
|
]
|
||||||
dbtSorting = mconcat
|
dbtSorting = mconcat
|
||||||
[ singletonMap "name" $ SortColumn (E.^. CompanyName)
|
[ singletonMap "name" $ SortColumn (E.^. CompanyName)
|
||||||
, singletonMap "short" $ SortColumn (E.^. CompanyShorthand)
|
, singletonMap "short" $ SortColumn (E.^. CompanyShorthand)
|
||||||
, singletonMap "avsnr" $ SortColumn (E.^. CompanyAvsId)
|
, singletonMap "avsnr" $ SortColumn (E.^. CompanyAvsId)
|
||||||
|
, singletonMap "postal-pref" $ SortColumn (E.^. CompanyPrefersPostal)
|
||||||
, singletonMap "users" $ SortColumn firmCountUsers
|
, singletonMap "users" $ SortColumn firmCountUsers
|
||||||
, singletonMap "supervisors" $ SortColumn firmCountSupervisors
|
, singletonMap "supervisors" $ SortColumn firmCountSupervisors
|
||||||
, singletonMap "emp-supervised" $ SortColumn firmCountEmployeeSupervised
|
, singletonMap "emp-supervised" $ SortColumn firmCountEmployeeSupervised
|
||||||
@ -292,12 +292,12 @@ mkFirmAllTable isAdmin uid = do
|
|||||||
, singletonMap "reroute-all" $ SortColumn firmCountActiveReroutes'
|
, singletonMap "reroute-all" $ SortColumn firmCountActiveReroutes'
|
||||||
]
|
]
|
||||||
dbtFilter = mconcat
|
dbtFilter = mconcat
|
||||||
[ single $ fltrCompanyNameNr queryCompany
|
[ single $ fltrCompanyNameNr queryAllCompany
|
||||||
, single ("is-supervisor", FilterColumn . E.mkExistsFilter $ \row (criterion :: Text) -> do
|
, single ("is-supervisor", FilterColumn . E.mkExistsFilter $ \row (criterion :: Text) -> do
|
||||||
(usr :& usrCmp) <- E.from $ E.table @User
|
(usr :& usrCmp) <- E.from $ E.table @User
|
||||||
`E.innerJoin` E.table @UserCompany
|
`E.innerJoin` E.table @UserCompany
|
||||||
`E.on` (\(usr :& usrCmp) -> usr E.^. UserId E.==. usrCmp E.^. UserCompanyUser)
|
`E.on` (\(usr :& usrCmp) -> usr E.^. UserId E.==. usrCmp E.^. UserCompanyUser)
|
||||||
E.where_ $ usrCmp E.^. UserCompanyCompany E.==. queryCompany row E.^. CompanyId
|
E.where_ $ usrCmp E.^. UserCompanyCompany E.==. queryAllCompany row E.^. CompanyId
|
||||||
E.&&. ( (usr E.^. UserDisplayName `E.hasInfix` E.val criterion)
|
E.&&. ( (usr E.^. UserDisplayName `E.hasInfix` E.val criterion)
|
||||||
E.||. (usr E.^. UserDisplayEmail `E.hasInfix` E.val (CI.mk criterion))
|
E.||. (usr E.^. UserDisplayEmail `E.hasInfix` E.val (CI.mk criterion))
|
||||||
E.||. (usr E.^. UserSurname `E.hasInfix` E.val criterion)
|
E.||. (usr E.^. UserSurname `E.hasInfix` E.val criterion)
|
||||||
@ -374,31 +374,171 @@ data FirmUserActionData = FirmUserActNotifyData
|
|||||||
| FirmUserActMkSuperData
|
| FirmUserActMkSuperData
|
||||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
||||||
|
|
||||||
|
type UserCompanyTableExpr = E.SqlExpr (Entity User) `E.InnerJoin` E.SqlExpr (Entity UserCompany)
|
||||||
|
|
||||||
|
queryUserUser :: UserCompanyTableExpr -> E.SqlExpr (Entity User)
|
||||||
|
queryUserUser = $(sqlIJproj 2 1)
|
||||||
|
|
||||||
|
queryUserUserCompany :: UserCompanyTableExpr -> E.SqlExpr (Entity UserCompany)
|
||||||
|
queryUserUserCompany = $(sqlIJproj 2 2)
|
||||||
|
|
||||||
|
type UserCompanyTableData = DBRow (Entity User, Entity UserCompany, E.Value Word64, E.Value Word64)
|
||||||
|
|
||||||
|
resultUserUser :: Lens' UserCompanyTableData (Entity User)
|
||||||
|
resultUserUser = _dbrOutput . _1
|
||||||
|
|
||||||
|
resultUserUserCompany :: Lens' UserCompanyTableData (Entity UserCompany)
|
||||||
|
resultUserUserCompany = _dbrOutput . _2
|
||||||
|
|
||||||
|
resultUserCompanySupervisors :: Lens' UserCompanyTableData Word64
|
||||||
|
resultUserCompanySupervisors = _dbrOutput . _3 . _unValue
|
||||||
|
|
||||||
|
resultUserCompanyReroutes :: Lens' UserCompanyTableData Word64
|
||||||
|
resultUserCompanyReroutes = _dbrOutput . _4 . _unValue
|
||||||
|
|
||||||
|
instance HasEntity UserCompanyTableData User where
|
||||||
|
hasEntity = resultUserUser
|
||||||
|
|
||||||
|
instance HasUser UserCompanyTableData where
|
||||||
|
hasUser = resultUserUser . _entityVal
|
||||||
|
|
||||||
|
|
||||||
|
firmCountUserSupervisors :: E.SqlExpr (Entity UserCompany) -> E.SqlExpr (E.Value Word64)
|
||||||
|
firmCountUserSupervisors usrCmp = E.subSelectCount $ do
|
||||||
|
usrSpr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ usrSpr E.^. UserSupervisorUser E.==. usrCmp E.^. UserCompanyUser
|
||||||
|
|
||||||
|
firmCountUserSupervisorsReroute :: E.SqlExpr (Entity UserCompany) -> E.SqlExpr (E.Value Word64)
|
||||||
|
firmCountUserSupervisorsReroute usrCmp = E.subSelectCount $ do
|
||||||
|
usrSpr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ usrSpr E.^. UserSupervisorUser E.==. usrCmp E.^. UserCompanyUser
|
||||||
|
E.&&. usrSpr E.^. UserSupervisorRerouteNotifications
|
||||||
|
|
||||||
|
mkFirmUserTable :: Bool -> CompanyId -> DB (FormResult (FirmUserActionData, Set UserId), Widget)
|
||||||
|
mkFirmUserTable isAdmin cid = do
|
||||||
|
let
|
||||||
|
fsh = unCompanyKey cid
|
||||||
|
resultDBTable = DBTable{..}
|
||||||
|
where
|
||||||
|
dbtSQLQuery = \(usr `E.InnerJoin` usrCmp) -> do
|
||||||
|
EL.on $ usr E.^. UserId E.==. usrCmp E.^. UserCompanyUser
|
||||||
|
E.where_ $ usrCmp E.^. UserCompanyCompany E.==. E.val cid
|
||||||
|
return (usr, usrCmp, firmCountUserSupervisors usrCmp, firmCountUserSupervisorsReroute usrCmp)
|
||||||
|
dbtRowKey = queryUserUser >>> (E.^. UserId)
|
||||||
|
dbtProj = dbtProjId
|
||||||
|
dbtColonnade = formColonnade $ mconcat
|
||||||
|
[ guardMonoid isAdmin $ dbSelect (applying _2) id (return . view (resultUserUser . _entityKey))
|
||||||
|
, colUserNameModalHdr MsgTableCompanyUser ForProfileDataR
|
||||||
|
, sortable (Just "matriculation") (i18nCell MsgTableMatrikelNr) $ \(view resultUserUser -> entUsr ) -> cellHasMatrikelnummerLinked entUsr
|
||||||
|
, sortable (Just "personal-number") (i18nCell MsgCompanyPersonalNumber) $ \(view $ resultUserUser . _userCompanyPersonalNumber -> t) -> foldMap textCell t
|
||||||
|
, sortable (Just "supervisors") (i18nCell MsgTableCompanyNrSupers ) $ \(view resultUserCompanySupervisors -> nr) -> wgtCell $ word2widget nr
|
||||||
|
, sortable (Just "reroutes") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultUserCompanyReroutes -> nr) -> wgtCell $ word2widget nr
|
||||||
|
, sortable (Just "postal-pref") (i18nCell MsgPrefersPostal) $ \(view $ resultUserUser . _userPrefersPostal -> b) -> iconFixedCell $ iconLetterOrEmail b
|
||||||
|
, colUserEmail
|
||||||
|
]
|
||||||
|
dbtSorting = mconcat
|
||||||
|
[ single $ sortUserNameLink queryUserUser
|
||||||
|
, single $ sortUserEmail queryUserUser
|
||||||
|
, singletonMap "postal-pref" $ SortColumn $ queryUserUser >>> (E.^. UserPrefersPostal)
|
||||||
|
, singletonMap "matriculation" $ SortColumn $ queryUserUser >>> (E.^. UserMatrikelnummer)
|
||||||
|
, singletonMap "personal-number" $ SortColumn $ queryUserUser >>> (E.^. UserCompanyPersonalNumber)
|
||||||
|
, singletonMap "supervisors" $ SortColumn $ queryUserUserCompany >>> firmCountUserSupervisors
|
||||||
|
, singletonMap "reroutes" $ SortColumn $ queryUserUserCompany >>> firmCountUserSupervisorsReroute
|
||||||
|
]
|
||||||
|
dbtFilter = mconcat
|
||||||
|
[ single $ fltrUserNameEmail queryUserUser
|
||||||
|
, singletonMap "has-supervisor" $ FilterColumn $ \row (getLast -> criterion) ->
|
||||||
|
let checkSuper = do
|
||||||
|
usrSpr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ usrSpr E.^. UserSupervisorUser E.==. queryUserUser row E.^. UserId
|
||||||
|
in case criterion of
|
||||||
|
Nothing -> E.true
|
||||||
|
Just True -> E.exists checkSuper
|
||||||
|
Just False -> E.notExists checkSuper
|
||||||
|
, singletonMap "has-company-supervisor" $ FilterColumn $ \row (getLast -> criterion) ->
|
||||||
|
let checkSuper = do
|
||||||
|
usrSpr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ usrSpr E.^. UserSupervisorUser E.==. queryUserUser row E.^. UserId
|
||||||
|
E.&&. E.exists (do
|
||||||
|
spr <- E.from $ E.table @UserCompany
|
||||||
|
E.where_ $ spr E.^. UserCompanyCompany E.==. E.val cid
|
||||||
|
E.&&. spr E.^. UserCompanyUser E.==. usrSpr E.^. UserSupervisorSupervisor
|
||||||
|
)
|
||||||
|
in case criterion of
|
||||||
|
Nothing -> E.true
|
||||||
|
Just True -> E.exists checkSuper
|
||||||
|
Just False -> E.notExists checkSuper
|
||||||
|
]
|
||||||
|
dbtFilterUI mPrev = mconcat
|
||||||
|
[ fltrUserNameEmailHdrUI MsgTableCompanyUser mPrev
|
||||||
|
, prismAForm (singletonFilter "has-supervisor" . maybePrism _PathPiece) mPrev $ aopt (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgFilterSupervisor)
|
||||||
|
, prismAForm (singletonFilter "has-company-supervisor" . maybePrism _PathPiece) mPrev $ aopt (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI $ MsgFilterSupervisorCompany fsh)
|
||||||
|
]
|
||||||
|
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
||||||
|
acts :: Map FirmUserAction (AForm Handler FirmUserActionData)
|
||||||
|
acts = mconcat
|
||||||
|
[ singletonMap FirmUserActNotify $ pure FirmUserActNotifyData
|
||||||
|
, singletonMap FirmUserActMkSuper $ pure FirmUserActMkSuperData
|
||||||
|
]
|
||||||
|
dbtParams = DBParamsForm
|
||||||
|
{ dbParamsFormMethod = POST
|
||||||
|
, dbParamsFormAction = Nothing
|
||||||
|
, dbParamsFormAttrs = []
|
||||||
|
, dbParamsFormSubmit = FormSubmit
|
||||||
|
, dbParamsFormAdditional
|
||||||
|
= renderAForm FormStandard $ (, mempty) . First . Just
|
||||||
|
<$> multiActionA acts (fslI MsgTableAction) Nothing
|
||||||
|
, dbParamsFormEvaluate = liftHandler . runFormPost
|
||||||
|
, dbParamsFormResult = id
|
||||||
|
, dbParamsFormIdent = def
|
||||||
|
}
|
||||||
|
dbtIdent :: Text
|
||||||
|
dbtIdent = "firm-users"
|
||||||
|
dbtCsvEncode = noCsvEncode
|
||||||
|
dbtCsvDecode = Nothing
|
||||||
|
dbtExtraReps = []
|
||||||
|
|
||||||
|
postprocess :: FormResult (First FirmUserActionData, DBFormResult UserId Bool UserCompanyTableData)
|
||||||
|
-> FormResult ( FirmUserActionData, Set UserId)
|
||||||
|
postprocess inp = do
|
||||||
|
(First (Just act), m) <- inp
|
||||||
|
let s = Map.keysSet . Map.filter id $ getDBFormResult (const False) m
|
||||||
|
return (act, s)
|
||||||
|
|
||||||
|
-- resultDBTableValidator :: PSValidator (MForm Handler) (FormResult (First FirmAllActionData, DBFormResult CompanyId Bool FirmAllActionData))
|
||||||
|
resultDBTableValidator = def
|
||||||
|
& defaultSorting [SortAscBy "user-name"]
|
||||||
|
over _1 postprocess <$> dbTable resultDBTableValidator resultDBTable
|
||||||
|
|
||||||
|
|
||||||
getFirmUsersR, postFirmUsersR :: CompanyShorthand -> Handler Html
|
getFirmUsersR, postFirmUsersR :: CompanyShorthand -> Handler Html
|
||||||
getFirmUsersR = postFirmUsersR
|
getFirmUsersR = postFirmUsersR
|
||||||
postFirmUsersR fsh = do
|
postFirmUsersR fsh = do
|
||||||
|
isAdmin <- hasReadAccessTo AdminR
|
||||||
let fshId = CompanyKey fsh
|
let fshId = CompanyKey fsh
|
||||||
Company{..} <- runDB $ get404 fshId
|
(Company{..}, (fusrRes, fusrTable)) <- runDB $ (,)
|
||||||
|
<$> get404 fshId
|
||||||
|
<*> mkFirmUserTable isAdmin fshId
|
||||||
|
formResult fusrRes $ \case
|
||||||
|
(FirmUserActNotifyData , fids) -> addMessage Info $ text2Html $ "Notify " <> tshow (length fids) <> " employees. TODO"
|
||||||
|
(FirmUserActMkSuperData, fids) -> addMessage Info $ text2Html $ "Make " <> tshow (length fids) <> " employees to supervisors. TODO"
|
||||||
siteLayout (citext2widget companyName) $ do
|
siteLayout (citext2widget companyName) $ do
|
||||||
setTitle $ citext2Html companyShorthand
|
setTitle $ toHtml $ CI.original companyShorthand <> " (" <> tshow companyAvsId <> ")"
|
||||||
[whamlet|
|
[whamlet|
|
||||||
<p>
|
<section>
|
||||||
#{companyPostAddress}
|
<p>
|
||||||
<p>
|
#{companyPostAddress}
|
||||||
Für neue Firmangehörige ist Benachrichtigungs-Voreinstellung:
|
<p>
|
||||||
$if companyPrefersPostal
|
Benachrichtigungs-Voreinstellung für neue Firmangehörige: #
|
||||||
#{icon IconLetter} Briefversand
|
$if companyPrefersPostal
|
||||||
$else
|
#{icon IconLetter} Briefversand
|
||||||
#{icon IconAt} Email
|
$else
|
||||||
<p>
|
#{icon IconAt} Email
|
||||||
AVS Nummer #{companyAvsId}
|
<section>
|
||||||
|
<h4>
|
||||||
<h1>
|
Company associated users, excluding foreign supervisors
|
||||||
!!!STUB!!!TO DO!!!
|
<p>
|
||||||
<p>
|
^{fusrTable}
|
||||||
Table showing all company associated users
|
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
|
||||||
@ -412,513 +552,3 @@ postFirmSupersR fsh = do
|
|||||||
siteLayout (citext2widget fsh) $ do
|
siteLayout (citext2widget fsh) $ do
|
||||||
setTitle $ citext2Html fsh
|
setTitle $ citext2Html fsh
|
||||||
[whamlet|!!!STUB!!!TO DO!!!|]
|
[whamlet|!!!STUB!!!TO DO!!!|]
|
||||||
|
|
||||||
|
|
||||||
-- data QualificationTableCsv = QualificationTableCsv -- Q..T..C.. -> qtc..
|
|
||||||
-- { qtcDisplayName :: UserDisplayName
|
|
||||||
-- , qtcEmail :: UserEmail
|
|
||||||
-- , qtcCompany :: Maybe Text
|
|
||||||
-- , qtcCompanyNumbers :: CsvSemicolonList Int
|
|
||||||
-- , qtcValidUntil :: Day
|
|
||||||
-- , qtcLastRefresh :: Day
|
|
||||||
-- , qtcBlockStatus :: Maybe Bool
|
|
||||||
-- , qtcBlockFrom :: Maybe UTCTime
|
|
||||||
-- , qtcScheduleRenewal:: Bool
|
|
||||||
-- , qtcLmsStatusTxt :: Maybe Text
|
|
||||||
-- , qtcLmsStatusDay :: Maybe UTCTime
|
|
||||||
-- }
|
|
||||||
-- deriving Generic
|
|
||||||
-- makeLenses_ ''QualificationTableCsv
|
|
||||||
|
|
||||||
-- qtcExample :: QualificationTableCsv
|
|
||||||
-- qtcExample = QualificationTableCsv
|
|
||||||
-- { qtcDisplayName = "Max Mustermann"
|
|
||||||
-- , qtcEmail = "m.mustermann@example.com"
|
|
||||||
-- , qtcCompany = Just "Example Brothers LLC, SecondaryJobs Inc"
|
|
||||||
-- , qtcCompanyNumbers = CsvSemicolonList [27,69]
|
|
||||||
-- , qtcValidUntil = compDay
|
|
||||||
-- , qtcLastRefresh = compDay
|
|
||||||
-- , qtcBlockStatus = Nothing
|
|
||||||
-- , qtcBlockFrom = Nothing
|
|
||||||
-- , qtcScheduleRenewal= True
|
|
||||||
-- , qtcLmsStatusTxt = Just "Success"
|
|
||||||
-- , qtcLmsStatusDay = Just compTime
|
|
||||||
-- }
|
|
||||||
-- where
|
|
||||||
-- compTime :: UTCTime
|
|
||||||
-- compTime = $compileTime
|
|
||||||
-- compDay :: Day
|
|
||||||
-- compDay = utctDay compTime
|
|
||||||
|
|
||||||
-- qtcOptions :: Csv.Options
|
|
||||||
-- qtcOptions = Csv.defaultOptions { Csv.fieldLabelModifier = renameLtc }
|
|
||||||
-- where
|
|
||||||
-- renameLtc "qtcDisplayName" = "licensee"
|
|
||||||
-- renameLtc other = replaceLtc $ camelToPathPiece' 1 other
|
|
||||||
-- replaceLtc ('l':'m':'s':'-':t) = prefixLms t
|
|
||||||
-- replaceLtc other = other
|
|
||||||
-- prefixLms = ("elearn-" <>)
|
|
||||||
|
|
||||||
-- instance Csv.ToNamedRecord QualificationTableCsv where
|
|
||||||
-- toNamedRecord = Csv.genericToNamedRecord qtcOptions
|
|
||||||
|
|
||||||
-- instance Csv.DefaultOrdered QualificationTableCsv where
|
|
||||||
-- headerOrder = Csv.genericHeaderOrder qtcOptions
|
|
||||||
|
|
||||||
-- instance CsvColumnsExplained QualificationTableCsv where
|
|
||||||
-- csvColumnsExplanations = genericCsvColumnsExplanations qtcOptions $ Map.fromList
|
|
||||||
-- [ ('qtcDisplayName , SomeMessage MsgLmsUser)
|
|
||||||
-- , ('qtcEmail , SomeMessage MsgTableLmsEmail)
|
|
||||||
-- , ('qtcCompany , SomeMessage MsgTableCompanies)
|
|
||||||
-- , ('qtcCompanyNumbers , SomeMessage MsgTableCompanyNos)
|
|
||||||
-- , ('qtcValidUntil , SomeMessage MsgLmsQualificationValidUntil)
|
|
||||||
-- , ('qtcLastRefresh , SomeMessage MsgTableQualificationLastRefresh)
|
|
||||||
-- , ('qtcBlockStatus , SomeMessage MsgInfoQualificationBlockStatus)
|
|
||||||
-- , ('qtcBlockFrom , SomeMessage MsgInfoQualificationBlockFrom)
|
|
||||||
-- , ('qtcScheduleRenewal, SomeMessage MsgQualificationScheduleRenewalTooltip)
|
|
||||||
-- , ('qtcLmsStatusTxt , SomeMessage MsgTableLmsStatus)
|
|
||||||
-- , ('qtcLmsStatusDay , SomeMessage MsgTableLmsStatusDay)
|
|
||||||
-- ]
|
|
||||||
|
|
||||||
|
|
||||||
-- type QualificationTableExpr = ( E.SqlExpr (Entity QualificationUser)
|
|
||||||
-- `E.InnerJoin` E.SqlExpr (Entity User)
|
|
||||||
-- ) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity LmsUser))
|
|
||||||
-- `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity QualificationUserBlock))
|
|
||||||
|
|
||||||
-- queryQualUser :: QualificationTableExpr -> E.SqlExpr (Entity QualificationUser)
|
|
||||||
-- queryQualUser = $(sqlIJproj 2 1) . $(sqlLOJproj 3 1)
|
|
||||||
|
|
||||||
-- queryUser :: QualificationTableExpr -> E.SqlExpr (Entity User)
|
|
||||||
-- queryUser = $(sqlIJproj 2 2) . $(sqlLOJproj 3 1)
|
|
||||||
|
|
||||||
-- queryLmsUser :: QualificationTableExpr -> E.SqlExpr (Maybe (Entity LmsUser))
|
|
||||||
-- queryLmsUser = $(sqlLOJproj 3 2)
|
|
||||||
|
|
||||||
-- queryQualBlock :: QualificationTableExpr -> E.SqlExpr (Maybe (Entity QualificationUserBlock))
|
|
||||||
-- queryQualBlock = $(sqlLOJproj 3 3)
|
|
||||||
|
|
||||||
-- type QualificationTableData = DBRow (Entity QualificationUser, Entity User, Maybe (Entity LmsUser), Maybe (Entity QualificationUserBlock), [Entity UserCompany])
|
|
||||||
|
|
||||||
-- resultQualUser :: Lens' QualificationTableData (Entity QualificationUser)
|
|
||||||
-- resultQualUser = _dbrOutput . _1
|
|
||||||
|
|
||||||
-- resultUser :: Lens' QualificationTableData (Entity User)
|
|
||||||
-- resultUser = _dbrOutput . _2
|
|
||||||
|
|
||||||
-- resultLmsUser :: Traversal' QualificationTableData (Entity LmsUser)
|
|
||||||
-- resultLmsUser = _dbrOutput . _3 . _Just
|
|
||||||
|
|
||||||
-- resultQualBlock :: Traversal' QualificationTableData (Entity QualificationUserBlock)
|
|
||||||
-- resultQualBlock = _dbrOutput . _4 . _Just
|
|
||||||
|
|
||||||
-- resultCompanyUser :: Lens' QualificationTableData [Entity UserCompany]
|
|
||||||
-- resultCompanyUser = _dbrOutput . _5
|
|
||||||
|
|
||||||
|
|
||||||
-- instance HasEntity QualificationTableData User where
|
|
||||||
-- hasEntity = resultUser
|
|
||||||
|
|
||||||
-- instance HasUser QualificationTableData where
|
|
||||||
-- hasUser = resultUser . _entityVal
|
|
||||||
|
|
||||||
-- instance HasEntity QualificationTableData QualificationUser where
|
|
||||||
-- hasEntity = resultQualUser
|
|
||||||
|
|
||||||
-- instance HasQualificationUser QualificationTableData where
|
|
||||||
-- hasQualificationUser = resultQualUser . _entityVal
|
|
||||||
|
|
||||||
-- -- instance HasEntity QualificationUserBlock where
|
|
||||||
-- -- hasQualificationUserBlock = resultQualBlock
|
|
||||||
|
|
||||||
|
|
||||||
-- data QualificationTableAction
|
|
||||||
-- = QualificationActExpire
|
|
||||||
-- | QualificationActUnexpire
|
|
||||||
-- | QualificationActBlockSupervisor
|
|
||||||
-- | QualificationActBlock
|
|
||||||
-- | QualificationActUnblock
|
|
||||||
-- | QualificationActRenew
|
|
||||||
-- | QualificationActGrant
|
|
||||||
-- deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
|
||||||
|
|
||||||
-- instance Universe QualificationTableAction
|
|
||||||
-- instance Finite QualificationTableAction
|
|
||||||
-- nullaryPathPiece ''QualificationTableAction $ camelToPathPiece' 2
|
|
||||||
-- embedRenderMessage ''UniWorX ''QualificationTableAction id
|
|
||||||
|
|
||||||
-- {-
|
|
||||||
-- isAdminAct :: QualificationTableAction -> Bool
|
|
||||||
-- isAdminAct QualificationActExpire = False
|
|
||||||
-- isAdminAct QualificationActUnexpire = False
|
|
||||||
-- isAdminAct QualificationActBlockSupervisor = False
|
|
||||||
-- isAdminAct _ = True
|
|
||||||
-- -}
|
|
||||||
|
|
||||||
-- data QualificationTableActionData
|
|
||||||
-- = QualificationActExpireData
|
|
||||||
-- | QualificationActUnexpireData
|
|
||||||
-- | QualificationActBlockSupervisorData
|
|
||||||
-- | QualificationActBlockData { qualTableActBlockReason :: Text, qualTableActNotify :: Bool, qualTableActRemoveSupervisors :: Bool }
|
|
||||||
-- | QualificationActUnblockData { qualTableActBlockReason :: Text, qualTableActNotify :: Bool}
|
|
||||||
-- | QualificationActRenewData
|
|
||||||
-- | QualificationActGrantData { qualTableActGrantUntil :: Day }
|
|
||||||
-- deriving (Eq, Ord, Show, Generic)
|
|
||||||
|
|
||||||
-- isExpiryAct :: QualificationTableActionData -> Bool
|
|
||||||
-- isExpiryAct QualificationActExpireData = True
|
|
||||||
-- isExpiryAct QualificationActUnexpireData = True
|
|
||||||
-- isExpiryAct _ = False
|
|
||||||
|
|
||||||
-- isBlockAct :: QualificationTableActionData -> Bool
|
|
||||||
-- isBlockAct QualificationActBlockSupervisorData = True
|
|
||||||
-- isBlockAct QualificationActBlockData{} = True
|
|
||||||
-- isBlockAct QualificationActUnblockData{} = True
|
|
||||||
-- isBlockAct _ = False
|
|
||||||
|
|
||||||
-- blockActRemoveSupervisors :: QualificationTableActionData -> Bool
|
|
||||||
-- blockActRemoveSupervisors QualificationActBlockSupervisorData = True
|
|
||||||
-- blockActRemoveSupervisors QualificationActBlockData{qualTableActRemoveSupervisors=res} = res
|
|
||||||
-- blockActRemoveSupervisors _ = False
|
|
||||||
|
|
||||||
-- -- qualificationTableQuery :: QualificationId -> (_ -> E.SqlExpr (E.Value Bool)) -> QualificationTableExpr
|
|
||||||
-- -- -> E.SqlQuery ( E.SqlExpr (Entity QualificationUser)
|
|
||||||
-- -- , E.SqlExpr (Entity User)
|
|
||||||
-- -- , E.SqlExpr (Maybe (Entity LmsUser))
|
|
||||||
-- -- )
|
|
||||||
-- -- qualificationTableQuery qid fltr (qualUser `E.InnerJoin` user `E.LeftOuterJoin` lmsUse) = do
|
|
||||||
-- -- E.on $ user E.^. UserId E.=?. lmsUser E.?. LmsUserUser
|
|
||||||
-- -- E.&&. E.val qid E.=?. lmsUser E.?. LmsUserQualification -- NOTE: condition was once erroneously placed in where-clause, which does not work
|
|
||||||
-- -- E.on $ user E.^. UserId E.==. qualUser E.^. QualificationUserUser
|
|
||||||
-- -- E.where_ $ fltr qualUser E.&&. (E.val qid E.==. qualUser E.^. QualificationUserQualification)
|
|
||||||
-- -- return (qualUser, user, lmsUser)
|
|
||||||
|
|
||||||
-- qualificationTableQuery :: UTCTime -> QualificationId -> (_ -> E.SqlExpr (E.Value Bool)) -> QualificationTableExpr
|
|
||||||
-- -> E.SqlQuery ( E.SqlExpr (Entity QualificationUser)
|
|
||||||
-- , E.SqlExpr (Entity User)
|
|
||||||
-- , E.SqlExpr (Maybe (Entity LmsUser))
|
|
||||||
-- , E.SqlExpr (Maybe (Entity QualificationUserBlock))
|
|
||||||
-- )
|
|
||||||
-- qualificationTableQuery now qid fltr (qualUser `E.InnerJoin` user `E.LeftOuterJoin` lmsUser `E.LeftOuterJoin` qualBlock) = do
|
|
||||||
-- -- E.distinctOnOrderBy will not work: sorting with dbTable should work, except that columns contained in distinctOnOrderBy cannot be sorted inversely by user; but PostgreSQL leftJoin with distinct filters too many results, see SQL Example lead/lag under jost/misc DevOps
|
|
||||||
-- --
|
|
||||||
-- E.on $ qualBlock E.?. QualificationUserBlockQualificationUser E.?=. qualUser E.^. QualificationUserId
|
|
||||||
-- E.&&. qualBlock `isLatestBlockBefore` E.val now
|
|
||||||
-- E.on $ user E.^. UserId E.=?. lmsUser E.?. LmsUserUser
|
|
||||||
-- E.&&. E.val qid E.=?. lmsUser E.?. LmsUserQualification -- NOTE: condition was once erroneously placed in where-clause, which does not work
|
|
||||||
-- E.on $ user E.^. UserId E.==. qualUser E.^. QualificationUserUser
|
|
||||||
-- E.where_ $ fltr qualUser
|
|
||||||
-- E.&&. (E.val qid E.==. qualUser E.^. QualificationUserQualification)
|
|
||||||
-- return (qualUser, user, lmsUser, qualBlock)
|
|
||||||
|
|
||||||
|
|
||||||
-- mkQualificationTable ::
|
|
||||||
-- ( Functor h, ToSortable h
|
|
||||||
-- , AsCornice h p QualificationTableData (DBCell (MForm Handler) (FormResult (First QualificationTableActionData, DBFormResult UserId Bool QualificationTableData))) cols
|
|
||||||
-- )
|
|
||||||
-- => Bool
|
|
||||||
-- -> Entity Qualification
|
|
||||||
-- -> Map QualificationTableAction (AForm Handler QualificationTableActionData)
|
|
||||||
-- -> (Map CompanyId Company -> cols)
|
|
||||||
-- -> PSValidator (MForm Handler) (FormResult (First QualificationTableActionData, DBFormResult UserId Bool QualificationTableData))
|
|
||||||
-- -> DB (FormResult (QualificationTableActionData, Set UserId), Widget)
|
|
||||||
-- mkQualificationTable isAdmin (Entity qid quali) acts cols psValidator = do
|
|
||||||
-- svs <- getSupervisees
|
|
||||||
-- now <- liftIO getCurrentTime
|
|
||||||
-- -- lookup all companies
|
|
||||||
-- cmpMap <- memcachedBy (Just . Right $ 5 * diffMinute) ("CompanyDictionary"::Text) $ do
|
|
||||||
-- cmps <- selectList [] [] -- [Asc CompanyShorthand]
|
|
||||||
-- return $ Map.fromList $ fmap (\Entity{..} -> (entityKey, entityVal)) cmps
|
|
||||||
-- let
|
|
||||||
-- nowaday = utctDay now
|
|
||||||
-- mbRenewal = addGregorianDurationClip <$> qualificationRefreshWithin quali <*> Just nowaday
|
|
||||||
-- csvName = T.replace " " "-" $ CI.original (quali ^. _qualificationName)
|
|
||||||
-- dbtIdent :: Text
|
|
||||||
-- dbtIdent = "qualification"
|
|
||||||
-- fltrSvs = if isAdmin then const E.true else \quser -> quser E.^. QualificationUserUser `E.in_` E.vals svs
|
|
||||||
-- dbtSQLQuery = qualificationTableQuery now qid fltrSvs
|
|
||||||
-- dbtRowKey = queryUser >>> (E.^. UserId)
|
|
||||||
-- dbtProj = dbtProjSimple $ \(qualUsr, usr, lmsUsr, qUsrBlock) -> do
|
|
||||||
-- -- cmps <- E.select . E.from $ \(usrComp `E.InnerJoin` comp) -> do
|
|
||||||
-- -- E.on $ usrComp E.^. UserCompanyCompany E.==. comp E.^. CompanyId
|
|
||||||
-- -- E.where_ $ usrComp E.^. UserCompanyUser E.==. E.val (entityKey usr)
|
|
||||||
-- -- E.orderBy [E.asc (comp E.^. CompanyName)]
|
|
||||||
-- -- return (comp E.^. CompanyName, comp E.^. CompanyAvsId, usrComp E.^. UserCompanySupervisor)
|
|
||||||
-- cmpUsr <- selectList [UserCompanyUser ==. entityKey usr] [Asc UserCompanyCompany]
|
|
||||||
-- return (qualUsr, usr, lmsUsr, qUsrBlock, cmpUsr)
|
|
||||||
-- dbtColonnade = cols cmpMap
|
|
||||||
-- dbtSorting = mconcat
|
|
||||||
-- [ single $ sortUserNameLink queryUser
|
|
||||||
-- , single $ sortUserEmail queryUser
|
|
||||||
-- , single $ sortUserMatriclenr queryUser
|
|
||||||
-- , single ("first-held" , SortColumn $ queryQualUser >>> (E.^. QualificationUserFirstHeld))
|
|
||||||
-- , single ("last-refresh" , SortColumn $ queryQualUser >>> (E.^. QualificationUserLastRefresh))
|
|
||||||
-- , single ("last-notified" , SortColumn $ queryQualUser >>> (E.^. QualificationUserLastNotified))
|
|
||||||
-- , single ("valid-until" , SortColumn $ queryQualUser >>> (E.^. QualificationUserValidUntil))
|
|
||||||
-- , single ("blocked" , SortColumnNeverNull $ queryQualBlock >>> (E.?. QualificationUserBlockFrom))
|
|
||||||
-- , single ("lms-status-plus",SortColumnNeverNull $ \row -> E.coalesce [ E.joinV (queryLmsUser row E.?. LmsUserStatusDay)
|
|
||||||
-- , E.joinV (queryLmsUser row E.?. LmsUserNotified)
|
|
||||||
-- , queryLmsUser row E.?. LmsUserStarted])
|
|
||||||
-- , single ("schedule-renew", SortColumnNullsInv $ queryQualUser >>> (E.^. QualificationUserScheduleRenewal))
|
|
||||||
-- , single ("user-company" , SortColumn $ \row -> E.subSelect $ E.from $ \(usrComp `E.InnerJoin` comp) -> do
|
|
||||||
-- E.on $ usrComp E.^. UserCompanyCompany E.==. comp E.^. CompanyId
|
|
||||||
-- E.where_ $ usrComp E.^. UserCompanyUser E.==. queryUser row E.^. UserId
|
|
||||||
-- E.orderBy [E.asc (comp E.^. CompanyName)]
|
|
||||||
-- return (comp E.^. CompanyName)
|
|
||||||
-- )
|
|
||||||
-- -- , single ("validity", SortColumn $ queryQualUser >>> validQualification now)
|
|
||||||
-- ]
|
|
||||||
-- dbtFilter = mconcat
|
|
||||||
-- [ single $ fltrUserNameEmail queryUser
|
|
||||||
-- , single ("avs-number" , FilterColumn . E.mkExistsFilter $ \row criterion ->
|
|
||||||
-- E.from $ \usrAvs -> -- do
|
|
||||||
-- E.where_ $ usrAvs E.^. UserAvsUser E.==. queryUser row E.^. UserId
|
|
||||||
-- E.&&. ((E.val criterion :: E.SqlExpr (E.Value (CI Text))) E.==.
|
|
||||||
-- (E.explicitUnsafeCoerceSqlExprValue "citext" (usrAvs E.^. UserAvsNoPerson) :: E.SqlExpr (E.Value (CI Text))) ))
|
|
||||||
-- , single ("avs-card" , FilterColumn $ \(queryUser -> user) (criterion :: Set.Set Text) -> case readAvsFullCardNo =<< Set.lookupMin criterion of
|
|
||||||
-- Nothing -> E.false
|
|
||||||
-- Just cardNo -> E.exists $ E.from $ \(avsCard `E.InnerJoin` usrAvs) -> do
|
|
||||||
-- E.on $ usrAvs E.^. UserAvsPersonId E.==. avsCard E.^. UserAvsCardPersonId
|
|
||||||
-- E.where_ $ usrAvs E.^. UserAvsUser E.==. user E.^. UserId
|
|
||||||
-- E.&&. (avsCard E.^. UserAvsCardCardNo E.==. E.val cardNo)
|
|
||||||
-- )
|
|
||||||
-- , single ("personal-number", FilterColumn $ \(queryUser -> user) (criteria :: Set.Set Text) -> if
|
|
||||||
-- | Set.null criteria -> E.true
|
|
||||||
-- | otherwise -> E.any (\c -> user E.^. UserCompanyPersonalNumber `E.hasInfix` E.val c) criteria
|
|
||||||
-- )
|
|
||||||
-- , single ("user-company", FilterColumn . E.mkExistsFilter $ \row criterion ->
|
|
||||||
-- E.from $ \(usrComp `E.InnerJoin` comp) -> do
|
|
||||||
-- let testname = (E.val criterion :: E.SqlExpr (E.Value (CI Text))) `E.isInfixOf`
|
|
||||||
-- (E.explicitUnsafeCoerceSqlExprValue "citext" (comp E.^. CompanyName) :: E.SqlExpr (E.Value (CI Text)))
|
|
||||||
-- testnumber nr = E.val nr E.==. comp E.^. CompanyAvsId
|
|
||||||
-- testcrit = maybe testname testnumber $ readMay $ CI.original criterion
|
|
||||||
-- E.on $ usrComp E.^. UserCompanyCompany E.==. comp E.^. CompanyId
|
|
||||||
-- E.where_ $ usrComp E.^. UserCompanyUser E.==. queryUser row E.^. UserId E.&&. testcrit
|
|
||||||
-- )
|
|
||||||
-- , single ("validity" , FilterColumn . E.mkExactFilterLast $ views (to queryQualUser) (validQualification now))
|
|
||||||
-- , single ("renewal-due" , FilterColumn $ \(queryQualUser -> quser) criterion ->
|
|
||||||
-- if | Just renewal <- mbRenewal
|
|
||||||
-- , Just True <- getLast criterion -> quser E.^. QualificationUserValidUntil E.<=. E.val renewal
|
|
||||||
-- E.&&. quser E.^. QualificationUserValidUntil E.>=. E.val nowaday
|
|
||||||
-- | otherwise -> E.true
|
|
||||||
-- )
|
|
||||||
-- , single ("tobe-notified", FilterColumn $ \row criterion ->
|
|
||||||
-- if | Just True <- getLast criterion -> quserToNotify now (queryQualUser row) (queryQualBlock row)
|
|
||||||
-- | otherwise -> E.true
|
|
||||||
-- )
|
|
||||||
-- , single ("status" , FilterColumn . E.mkExactFilterMaybeLast' (views (to queryLmsUser) (E.?. LmsUserId)) $ views (to queryLmsUser) (E.?. LmsUserStatus))
|
|
||||||
-- ]
|
|
||||||
-- dbtFilterUI mPrev = mconcat
|
|
||||||
-- [ fltrUserNameEmailHdrUI MsgLmsUser mPrev
|
|
||||||
-- , prismAForm (singletonFilter "user-company") mPrev $ aopt textField (fslI MsgTableCompany)
|
|
||||||
-- , prismAForm (singletonFilter "personal-number" ) mPrev $ aopt textField (fslI MsgCompanyPersonalNumber)
|
|
||||||
-- , prismAForm (singletonFilter "avs-card" ) mPrev $ aopt textField (fslI MsgAvsCardNo)
|
|
||||||
-- , prismAForm (singletonFilter "avs-number" ) mPrev $ aopt textField (fslI MsgAvsPersonNo)
|
|
||||||
-- , prismAForm (singletonFilter "validity" . maybePrism _PathPiece) mPrev $ aopt (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgFilterLmsValid)
|
|
||||||
-- , if isNothing mbRenewal then mempty
|
|
||||||
-- else prismAForm (singletonFilter "renewal-due" . maybePrism _PathPiece) mPrev $ aopt checkBoxField (fslI MsgFilterLmsRenewal)
|
|
||||||
-- , prismAForm (singletonFilter "tobe-notified" . maybePrism _PathPiece) mPrev $ aopt checkBoxField (fslI MsgFilterLmsNotificationDue)
|
|
||||||
-- , prismAForm (singletonFilter "status" . maybePrism _PathPiece) mPrev $ aopt (hoistField liftHandler (selectField optionsFinite) :: (Field _ (Maybe LmsStatus))) (fslI MsgTableLmsStatus)
|
|
||||||
-- ]
|
|
||||||
-- dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
|
||||||
-- dbtCsvEncode = Just DBTCsvEncode
|
|
||||||
-- { dbtCsvExportForm = pure ()
|
|
||||||
-- , dbtCsvDoEncode = \() -> C.map (doEncode' . view _2)
|
|
||||||
-- , dbtCsvName = csvName
|
|
||||||
-- , dbtCsvSheetName = csvName
|
|
||||||
-- , dbtCsvNoExportData = Just id
|
|
||||||
-- , dbtCsvHeader = const $ return $ Csv.headerOrder qtcExample
|
|
||||||
-- , dbtCsvExampleData = Just [qtcExample]
|
|
||||||
-- }
|
|
||||||
-- where
|
|
||||||
-- doEncode' :: QualificationTableData -> QualificationTableCsv
|
|
||||||
-- doEncode' = QualificationTableCsv
|
|
||||||
-- <$> view (resultUser . _entityVal . _userDisplayName)
|
|
||||||
-- <*> view (resultUser . _entityVal . _userDisplayEmail)
|
|
||||||
-- <*> (view resultCompanyUser >>= getCompanies)
|
|
||||||
-- <*> (view resultCompanyUser >>= getCompanyNos)
|
|
||||||
-- <*> view (resultQualUser . _entityVal . _qualificationUserValidUntil)
|
|
||||||
-- <*> view (resultQualUser . _entityVal . _qualificationUserLastRefresh)
|
|
||||||
-- <*> preview (resultQualBlock. _entityVal . _qualificationUserBlockUnblock . _not)
|
|
||||||
-- <*> preview (resultQualBlock. _entityVal . _qualificationUserBlockFrom)
|
|
||||||
-- <*> view (resultQualUser . _entityVal . _qualificationUserScheduleRenewal)
|
|
||||||
-- <*> getStatusPlusTxt
|
|
||||||
-- <*> getStatusPlusDay
|
|
||||||
-- getCompanies cmps = case mapMaybe (flip Map.lookup cmpMap . view (_entityVal . _userCompanyCompany)) cmps of
|
|
||||||
-- [] -> pure Nothing
|
|
||||||
-- somecmps -> pure $ Just $ intercalate ", " $ fmap (view (_companyName . _CI)) somecmps
|
|
||||||
-- getCompanyNos = pure . CsvSemicolonList . mapMaybe (preview (_Just . _companyAvsId) . flip Map.lookup cmpMap . view (_entityVal . _userCompanyCompany))
|
|
||||||
|
|
||||||
-- getStatusPlusTxt =
|
|
||||||
-- (join . preview (resultLmsUser . _entityVal . _lmsUserStatus)) >>= \case
|
|
||||||
-- Just LmsBlocked{} -> return $ Just "Failed"
|
|
||||||
-- Just LmsExpired{} -> return $ Just "Expired"
|
|
||||||
-- Just LmsSuccess{} -> return $ Just "Success"
|
|
||||||
-- Nothing -> maybeM (return Nothing) (const $ return $ Just "Open") $
|
|
||||||
-- preview (resultLmsUser . _entityVal . _lmsUserStarted)
|
|
||||||
-- getStatusPlusDay =
|
|
||||||
-- (join . preview (resultLmsUser . _entityVal . _lmsUserStatusDay)) >>= \case
|
|
||||||
-- lsd@(Just _) -> return lsd
|
|
||||||
-- Nothing -> preview (resultLmsUser . _entityVal . _lmsUserStarted)
|
|
||||||
|
|
||||||
-- dbtCsvDecode = Nothing
|
|
||||||
-- dbtExtraReps = []
|
|
||||||
-- dbtParams = DBParamsForm
|
|
||||||
-- { dbParamsFormMethod = POST
|
|
||||||
-- , dbParamsFormAction = Nothing
|
|
||||||
-- , dbParamsFormAttrs = []
|
|
||||||
-- , dbParamsFormSubmit = FormSubmit
|
|
||||||
-- , dbParamsFormAdditional
|
|
||||||
-- = renderAForm FormStandard
|
|
||||||
-- $ (, mempty) . First . Just
|
|
||||||
-- <$> multiActionA acts (fslI MsgTableAction) Nothing
|
|
||||||
-- , dbParamsFormEvaluate = liftHandler . runFormPost
|
|
||||||
-- , dbParamsFormResult = id
|
|
||||||
-- , dbParamsFormIdent = def
|
|
||||||
-- }
|
|
||||||
|
|
||||||
-- postprocess :: FormResult (First QualificationTableActionData, DBFormResult UserId Bool QualificationTableData)
|
|
||||||
-- -> FormResult ( QualificationTableActionData, Set UserId)
|
|
||||||
-- postprocess inp = do
|
|
||||||
-- (First (Just act), usrMap) <- inp
|
|
||||||
-- let usrSet = Map.keysSet . Map.filter id $ getDBFormResult (const False) usrMap
|
|
||||||
-- return (act, usrSet)
|
|
||||||
|
|
||||||
-- -- resultDBTableValidator :: PSValidator (MForm Handler) (FormResult (First QualificationTableActionData, DBFormResult UserId Bool QualificationTableActionData))
|
|
||||||
-- -- resultDBTableValidator = def
|
|
||||||
-- -- & defaultSorting [SortAscBy csvLmsIdent]
|
|
||||||
-- over _1 postprocess <$> dbTable psValidator DBTable{..}
|
|
||||||
|
|
||||||
-- getQualificationR, postQualificationR :: SchoolId -> QualificationShorthand -> Handler Html
|
|
||||||
-- getQualificationR = postQualificationR
|
|
||||||
-- postQualificationR sid qsh = do
|
|
||||||
-- isAdmin <- hasReadAccessTo AdminR
|
|
||||||
-- msgGrantWarning <- messageIconI Warning IconWarning MsgQualificationActGrantWarning
|
|
||||||
-- msgUnexpire <- messageIconI Info IconWarning MsgQualificationActUnexpireWarning
|
|
||||||
-- now <- liftIO getCurrentTime
|
|
||||||
-- let nowaday = utctDay now
|
|
||||||
-- ((lmsRes, qualificationTable), Entity qid quali) <- runDB $ do
|
|
||||||
-- qent@Entity{
|
|
||||||
-- entityKey=qid
|
|
||||||
-- , entityVal=Qualification{
|
|
||||||
-- qualificationAuditDuration=auditMonths
|
|
||||||
-- , qualificationValidDuration=validMonths
|
|
||||||
-- }} <- getBy404 $ SchoolQualificationShort sid qsh
|
|
||||||
|
|
||||||
-- -- Block copied to Handler/Qualifications TODO: refactor
|
|
||||||
-- let getBlockReasons unblk = E.select $ do
|
|
||||||
-- (quser :& qblock) <- E.from $ E.table @QualificationUser
|
|
||||||
-- `E.innerJoin` E.table @QualificationUserBlock
|
|
||||||
-- `E.on` (\(quser :& qblock) -> quser E.^. QualificationUserId E.==. qblock E.^. QualificationUserBlockQualificationUser)
|
|
||||||
-- E.where_ $ quser E.^. QualificationUserQualification E.==. E.val qid
|
|
||||||
-- E.&&. unblk (qblock E.^. QualificationUserBlockUnblock)
|
|
||||||
-- E.groupBy (qblock E.^. QualificationUserBlockReason)
|
|
||||||
-- let countRows' :: E.SqlExpr (E.Value Int64) = E.countRows
|
|
||||||
-- E.orderBy [E.desc countRows']
|
|
||||||
-- E.limit 7
|
|
||||||
-- pure (qblock E.^. QualificationUserBlockReason)
|
|
||||||
-- mkOption :: E.Value Text -> Option Text
|
|
||||||
-- mkOption (E.unValue -> t) = Option{ optionDisplay = t, optionInternalValue = t, optionExternalValue = toPathPiece t }
|
|
||||||
-- suggestionsBlock :: HandlerFor UniWorX (OptionList Text)
|
|
||||||
-- suggestionsBlock = mkOptionList . fmap mkOption <$> runDB (getBlockReasons E.not_)
|
|
||||||
-- suggestionsUnblock = mkOptionList . fmap mkOption <$> runDB (getBlockReasons id)
|
|
||||||
-- dayExpiry = flip addGregorianDurationClip nowaday . fromMonths <$> validMonths
|
|
||||||
-- acts :: Map QualificationTableAction (AForm Handler QualificationTableActionData)
|
|
||||||
-- acts = mconcat $
|
|
||||||
-- [ singletonMap QualificationActExpire $ pure QualificationActExpireData
|
|
||||||
-- , singletonMap QualificationActUnexpire $ QualificationActUnexpireData
|
|
||||||
-- <$ aformMessage msgUnexpire
|
|
||||||
-- ] ++ bool
|
|
||||||
-- -- nonAdmin actions, ie. Supervisor
|
|
||||||
-- [ singletonMap QualificationActBlockSupervisor $ pure QualificationActBlockSupervisorData ]
|
|
||||||
-- -- Admin-only actions
|
|
||||||
-- [ singletonMap QualificationActUnblock $ QualificationActUnblockData
|
|
||||||
-- <$> apreq (textField & cfStrip & addDatalist suggestionsUnblock) (fslI MsgQualificationGrantReason) Nothing
|
|
||||||
-- <*> areq (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgQualificationBlockNotify) (Just False)
|
|
||||||
-- , singletonMap QualificationActBlock $ QualificationActBlockData
|
|
||||||
-- <$> apreq (textField & cfStrip & addDatalist suggestionsBlock) (fslI MsgQualificationBlockReason) Nothing
|
|
||||||
-- <*> areq (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgQualificationBlockNotify) (Just False)
|
|
||||||
-- <*> areq (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgQualificationBlockRemoveSupervisor) (Just False)
|
|
||||||
-- , singletonMap QualificationActRenew $ pure QualificationActRenewData
|
|
||||||
-- , singletonMap QualificationActGrant $ QualificationActGrantData
|
|
||||||
-- <$> apopt dayField (fslI MsgLmsQualificationValidUntil) dayExpiry
|
|
||||||
-- <* aformMessage msgGrantWarning
|
|
||||||
-- ] isAdmin
|
|
||||||
-- linkLmsUser = toMaybe isAdmin (LmsUserR sid qsh)
|
|
||||||
-- linkUserName = bool ForProfileR ForProfileDataR isAdmin
|
|
||||||
-- colChoices cmpMap = mconcat
|
|
||||||
-- [ dbSelect (applying _2) id (return . view (hasEntity . _entityKey))
|
|
||||||
-- , colUserNameModalHdr MsgLmsUser linkUserName
|
|
||||||
-- , colUserEmail
|
|
||||||
-- , sortable (Just "user-company") (i18nCell MsgTableCompanies) $ \( view resultCompanyUser -> cmps) ->
|
|
||||||
-- let icnSuper = text2markup " " <> icon IconSupervisor
|
|
||||||
-- cs = [ (cmpName, cmpSpr)
|
|
||||||
-- | Entity _ UserCompany{userCompanyCompany=cmpId, userCompanySupervisor=cmpSpr} <- cmps
|
|
||||||
-- , let cmpName = maybe (unCompanyKey cmpId) companyName $ Map.lookup cmpId cmpMap
|
|
||||||
-- ]
|
|
||||||
-- companies = intercalate (text2markup ", ") $
|
|
||||||
-- (\(cmpName, cmpSpr) -> text2markup (CI.original cmpName) <> bool mempty icnSuper cmpSpr) <$> cs
|
|
||||||
-- in wgtCell companies
|
|
||||||
-- , guardMonoid isAdmin colUserMatriclenr
|
|
||||||
-- -- , sortable (Just "validity") (i18nCell MsgQualificationValidIndicator) (qualificationValidIconCell nowaday . view resultQualUser)
|
|
||||||
-- , sortable (Just "first-held") (i18nCell MsgTableQualificationFirstHeld) $ \( view $ resultQualUser . _entityVal . _qualificationUserFirstHeld -> d) -> dayCell d
|
|
||||||
-- , sortable (Just "last-refresh") (i18nCell MsgTableQualificationLastRefresh)$ \( view $ resultQualUser . _entityVal . _qualificationUserLastRefresh -> d) -> dayCell d
|
|
||||||
-- , sortable (Just "valid-until") (i18nCell MsgLmsQualificationValidUntil) (dayCell . view ( resultQualUser . _entityVal . _qualificationUserValidUntil))
|
|
||||||
-- , sortable (Just "blocked") (i18nCell MsgQualificationValidIndicator & cellTooltip MsgTableQualificationBlockedTooltipSimple) $ \row ->
|
|
||||||
-- qualificationValidReasonCell' (Just $ LmsUserR sid qsh) isAdmin nowaday (row ^? resultQualBlock) row
|
|
||||||
-- , sortable (Just "schedule-renew")(i18nCell MsgTableQualificationNoRenewal & cellTooltip MsgTableQualificationNoRenewalTooltip
|
|
||||||
-- ) $ \( view $ resultQualUser . _entityVal . _qualificationUserScheduleRenewal -> b) -> ifIconCell (not b) IconNoNotification
|
|
||||||
-- , sortable (Just "lms-status-plus")(i18nCell MsgTableLmsStatus & cellTooltipWgt Nothing (lmsStatusInfoCell isAdmin auditMonths))
|
|
||||||
-- $ \(preview $ resultLmsUser . _entityVal -> lu) -> foldMap (lmsStatusCell isAdmin linkLmsUser) lu
|
|
||||||
-- , sortable (Just "last-notified") (i18nCell MsgTableQualificationLastNotified) $ \( view $ resultQualUser . _entityVal . _qualificationUserLastNotified -> d) -> dateTimeCell d
|
|
||||||
-- ]
|
|
||||||
-- psValidator = def & defaultSorting [SortDescBy "last-refresh"]
|
|
||||||
-- tbl <- mkQualificationTable isAdmin qent acts colChoices psValidator
|
|
||||||
-- return (tbl, qent)
|
|
||||||
|
|
||||||
-- formResult lmsRes $ \case
|
|
||||||
-- (QualificationActRenewData, selectedUsers) | isAdmin -> do
|
|
||||||
-- noks <- runDB $ renewValidQualificationUsers qid Nothing $ Set.toList selectedUsers
|
|
||||||
-- addMessageI (if noks > 0 && noks == Set.size selectedUsers then Success else Warning) $ MsgTutorialUserRenewedQualification noks
|
|
||||||
-- reloadKeepGetParams $ QualificationR sid qsh
|
|
||||||
-- (QualificationActGrantData grantValidday, selectedUsers) | isAdmin -> do
|
|
||||||
-- runDB . forM_ selectedUsers $ upsertQualificationUser qid nowaday grantValidday Nothing
|
|
||||||
-- addMessageI (if 0 < Set.size selectedUsers then Success else Warning) . MsgTutorialUserGrantedQualification $ Set.size selectedUsers
|
|
||||||
-- reloadKeepGetParams $ QualificationR sid qsh
|
|
||||||
-- (action, selectedUsers) | isExpiryAct action -> do
|
|
||||||
-- let isUnexpire = action == QualificationActUnexpireData
|
|
||||||
-- upd <- runDB $ updateWhereCount
|
|
||||||
-- [QualificationUserQualification ==. qid, QualificationUserUser <-. Set.toList selectedUsers]
|
|
||||||
-- [QualificationUserScheduleRenewal =. isUnexpire]
|
|
||||||
-- let msgKind = if upd > 0 then Success else Warning
|
|
||||||
-- msgVal = upd & if isUnexpire then MsgQualificationSetUnexpire else MsgQualificationSetExpire
|
|
||||||
-- addMessageI msgKind msgVal
|
|
||||||
-- reloadKeepGetParams $ QualificationR sid qsh
|
|
||||||
-- (action, selectedUsers) | isBlockAct action && (isAdmin || action == QualificationActBlockSupervisorData) -> do
|
|
||||||
-- let selUserIds = Set.toList selectedUsers
|
|
||||||
-- (unblock, reason) = case action of
|
|
||||||
-- QualificationActBlockSupervisorData -> (False, Right QualificationBlockReturnedByCompany)
|
|
||||||
-- QualificationActBlockData{..} -> (False, Left qualTableActBlockReason)
|
|
||||||
-- QualificationActUnblockData{..} -> (True , Left qualTableActBlockReason)
|
|
||||||
-- _ -> error "Handle.Qualification.isBlockAct returned non-block action" -- cannot occur due to earlier checks
|
|
||||||
-- notify = case action of
|
|
||||||
-- QualificationActBlockData{qualTableActNotify} -> qualTableActNotify
|
|
||||||
-- _ -> False
|
|
||||||
|
|
||||||
-- oks <- runDB $ do
|
|
||||||
-- when (blockActRemoveSupervisors action) $ deleteWhere [UserSupervisorUser <-. selUserIds]
|
|
||||||
-- qualificationUserBlocking qid selUserIds unblock Nothing reason notify
|
|
||||||
-- let nrq = length selectedUsers
|
|
||||||
-- warnLevel = if
|
|
||||||
-- | oks < 0 -> Error
|
|
||||||
-- | oks == nrq -> Success
|
|
||||||
-- | otherwise -> Warning
|
|
||||||
-- fbmsg = if unblock then MsgQualificationStatusUnblock else MsgQualificationStatusBlock
|
|
||||||
-- addMessageI warnLevel $ fbmsg qsh oks nrq
|
|
||||||
-- reloadKeepGetParams $ QualificationR sid qsh
|
|
||||||
-- _ -> addMessageI Error MsgInvalidFormAction
|
|
||||||
|
|
||||||
-- let heading = citext2widget $ qualificationName quali
|
|
||||||
-- siteLayout heading $ do
|
|
||||||
-- setTitle $ toHtml $ unSchoolKey sid <> "-" <> qsh
|
|
||||||
-- $(widgetFile "qualification")
|
|
||||||
|
|||||||
@ -631,7 +631,7 @@ postLmsR sid qsh = do
|
|||||||
<* aformMessage msgRestartWarning
|
<* aformMessage msgRestartWarning
|
||||||
]
|
]
|
||||||
colChoices cmpMap = mconcat
|
colChoices cmpMap = mconcat
|
||||||
[ if not isAdmin then mempty else dbSelect (applying _2) id (return . view (resultUser . _entityKey))
|
[ guardMonoid isAdmin $ dbSelect (applying _2) id (return . view (resultUser . _entityKey))
|
||||||
, colUserNameModalHdr MsgLmsUser AdminUserR
|
, colUserNameModalHdr MsgLmsUser AdminUserR
|
||||||
, colUserEmail
|
, colUserEmail
|
||||||
, sortable (Just "user-company") (i18nCell MsgTableCompanies) $ \( view resultCompanyUser -> cmps) ->
|
, sortable (Just "user-company") (i18nCell MsgTableCompanies) $ \( view resultCompanyUser -> cmps) ->
|
||||||
|
|||||||
@ -130,7 +130,7 @@ makeSettingForm template html = do
|
|||||||
|
|
||||||
<* aformSection MsgFormNotifications
|
<* aformSection MsgFormNotifications
|
||||||
<*> aopt (textField & cfStrip) (fslI MsgPDFPassword & setTooltip MsgPDFPasswordTip) (stgPinPassword <$> template)
|
<*> aopt (textField & cfStrip) (fslI MsgPDFPassword & setTooltip MsgPDFPasswordTip) (stgPinPassword <$> template)
|
||||||
<*> apopt checkBoxField (fslI MsgPrefersPostal & setTooltip MsgPostalTip) (stgPrefersPostal <$> template)
|
<*> apopt checkBoxField (fslI MsgPrefersPostalExp & setTooltip MsgPostalTip) (stgPrefersPostal <$> template)
|
||||||
<*> aopt htmlField (fslI MsgPostAddress & setTooltip MsgPostAddressTip) (stgPostAddress <$> template)
|
<*> aopt htmlField (fslI MsgPostAddress & setTooltip MsgPostAddressTip) (stgPostAddress <$> template)
|
||||||
|
|
||||||
<*> examOfficeForm (stgExamOfficeSettings <$> template)
|
<*> examOfficeForm (stgExamOfficeSettings <$> template)
|
||||||
|
|||||||
@ -111,10 +111,11 @@ postUsersR = do
|
|||||||
companies =
|
companies =
|
||||||
(\(E.Value cmpSh, E.Value cmpName, E.Value cmpSpr) -> simpleLink (citext2widget cmpName) (FirmR cmpSh) <> bool mempty icnSuper cmpSpr) <$> companies'
|
(\(E.Value cmpSh, E.Value cmpName, E.Value cmpSpr) -> simpleLink (citext2widget cmpName) (FirmR cmpSh) <> bool mempty icnSuper cmpSpr) <$> companies'
|
||||||
pure $ intercalate (text2widget "; ") companies
|
pure $ intercalate (text2widget "; ") companies
|
||||||
, sortable (Just "personal-number") (i18nCell MsgCompanyPersonalNumber) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
-- , sortable (Just "personal-number") (i18nCell MsgCompanyPersonalNumber) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
||||||
(AdminUserR <$> encrypt uid)
|
-- (AdminUserR <$> encrypt uid)
|
||||||
(toWgt userCompanyPersonalNumber)
|
-- (toWgt userCompanyPersonalNumber)
|
||||||
, sortable (Just "company-department") (i18nCell MsgCompanyDepartment) $ \DBRow{ dbrOutput = Entity _uid User{..} } -> cellMaybe textCell userCompanyDepartment
|
, sortable (Just "personal-number") (i18nCell MsgCompanyPersonalNumber) $ \DBRow{ dbrOutput = Entity _uid User{..} } -> cellMaybe textCell userCompanyPersonalNumber
|
||||||
|
, sortable (Just "company-department") (i18nCell MsgCompanyDepartment) $ \DBRow{ dbrOutput = Entity _uid User{..} } -> cellMaybe textCell userCompanyDepartment
|
||||||
-- , sortable (Just "last-name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
-- , sortable (Just "last-name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
||||||
-- (AdminUserR <$> encrypt uid)
|
-- (AdminUserR <$> encrypt uid)
|
||||||
-- (toWidget . display $ last $ impureNonNull $ words $ userDisplayName)
|
-- (toWidget . display $ last $ impureNonNull $ words $ userDisplayName)
|
||||||
|
|||||||
@ -91,6 +91,7 @@ guardAuthCell mkParams = over cellContents $ \act -> do
|
|||||||
---------------------
|
---------------------
|
||||||
-- Icon cells
|
-- Icon cells
|
||||||
|
|
||||||
|
-- to be used with icons directly, for results of `icon`, use either `wgtCell` or `iconFixedCell`
|
||||||
iconCell :: IsDBTable m a => Icon -> DBCell m a
|
iconCell :: IsDBTable m a => Icon -> DBCell m a
|
||||||
iconCell = cell . toWidget . icon
|
iconCell = cell . toWidget . icon
|
||||||
|
|
||||||
|
|||||||
@ -754,23 +754,38 @@ sortUserCompany queryUser = ( "user-company"
|
|||||||
))
|
))
|
||||||
|
|
||||||
-- | Search companies by name, shorthand oder AVS nr
|
-- | Search companies by name, shorthand oder AVS nr
|
||||||
|
-- fltrCompanyNameNr :: (IsFilterColumn t (a -> Set Text -> E.SqlExpr (E.Value Bool)), IsString d)
|
||||||
|
-- => (a -> E.SqlExpr (Entity Company))
|
||||||
|
-- -> (d, FilterColumn t fs)
|
||||||
|
-- fltrCompanyNameNr query = ( "company-name-number", FilterColumn $ anyFilter
|
||||||
|
-- [ mkContainsFilterWithComma CI.mk $ query >>> (E.^. CompanyName)
|
||||||
|
-- , mkContainsFilterWithComma CI.mk $ query >>> (E.^. CompanyShorthand)
|
||||||
|
-- , mkExactFilterWithComma id $ query >>> (E.num2text . (E.^. CompanyAvsId))
|
||||||
|
-- ]
|
||||||
|
-- )
|
||||||
|
|
||||||
fltrCompanyNameNr :: (IsFilterColumn t (a -> Set Text -> E.SqlExpr (E.Value Bool)), IsString d)
|
fltrCompanyNameNr :: (IsFilterColumn t (a -> Set Text -> E.SqlExpr (E.Value Bool)), IsString d)
|
||||||
=> (a -> E.SqlExpr (Entity Company))
|
=> (a -> E.SqlExpr (Entity Company))
|
||||||
-> (d, FilterColumn t fs)
|
-> (d, FilterColumn t fs)
|
||||||
fltrCompanyNameNr query = ( "company-name-number", FilterColumn $ anyFilter
|
fltrCompanyNameNr query = ("company-name-number", FilterColumn $ \needle (setFoldMap commaSeparatedText -> criterias) ->
|
||||||
[ mkContainsFilterWithCommaPlus CI.mk $ query >>> (E.^. CompanyName)
|
let numCrits = setMapMaybe readMay criterias
|
||||||
, mkContainsFilterWithCommaPlus CI.mk $ query >>> (E.^. CompanyShorthand)
|
fltrCName = mkContainsFilterWith CI.mk (query >>> (E.^. CompanyName)) needle criterias
|
||||||
, mkContainsFilterWithCommaPlus id $ query >>> (E.num2text . (E.^. CompanyAvsId))
|
fltrCShort = mkContainsFilterWith CI.mk (query >>> (E.^. CompanyShorthand)) needle criterias
|
||||||
]
|
fltrCno = mkExactFilter (query >>> (E.^. CompanyAvsId)) needle numCrits
|
||||||
)
|
in if null numCrits
|
||||||
|
then fltrCName E.||. fltrCShort
|
||||||
|
else fltrCName E.||. fltrCShort E.||. fltrCno
|
||||||
|
)
|
||||||
|
where
|
||||||
|
setFoldMap :: (Text -> Set.Set Text) -> Set.Set Text -> Set.Set Text
|
||||||
|
setFoldMap = foldMap
|
||||||
|
|
||||||
fltrCompanyNameNrUI :: Maybe (Map FilterKey [Text]) -> AForm (YesodDB UniWorX) (Map FilterKey [Text])
|
fltrCompanyNameNrUI :: Maybe (Map FilterKey [Text]) -> AForm (YesodDB UniWorX) (Map FilterKey [Text])
|
||||||
fltrCompanyNameNrUI = fltrCompanyNameNrHdrUI MsgTableCompanyFilter
|
fltrCompanyNameNrUI = fltrCompanyNameNrHdrUI MsgTableCompanyFilter
|
||||||
|
|
||||||
fltrCompanyNameNrHdrUI :: (RenderMessage UniWorX msg) => msg -> Maybe (Map FilterKey [Text]) -> AForm (YesodDB UniWorX) (Map FilterKey [Text])
|
fltrCompanyNameNrHdrUI :: (RenderMessage UniWorX msg) => msg -> Maybe (Map FilterKey [Text]) -> AForm (YesodDB UniWorX) (Map FilterKey [Text])
|
||||||
fltrCompanyNameNrHdrUI msg mPrev =
|
fltrCompanyNameNrHdrUI msg mPrev =
|
||||||
prismAForm (singletonFilter "company-name-number") mPrev $ aopt textField (fslI msg & setTooltip MsgTableFilterCommaPlus)
|
prismAForm (singletonFilter "company-name-number") mPrev $ aopt textField (fslI msg & setTooltip MsgTableFilterCommaNameNr)
|
||||||
|
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|||||||
@ -846,8 +846,8 @@ _MapUnit = iso Map.keysSet $ Map.fromSet (const ())
|
|||||||
|
|
||||||
-- | Just @flip (.)@ for convenient formatting in some cases,
|
-- | Just @flip (.)@ for convenient formatting in some cases,
|
||||||
-- Deprecated in favor of Control.Arrow.(>>>)
|
-- Deprecated in favor of Control.Arrow.(>>>)
|
||||||
compose :: (a -> b) -> (b -> c) -> (a -> c)
|
-- compose :: (a -> b) -> (b -> c) -> (a -> c)
|
||||||
compose = flip (.)
|
-- compose = flip (.)
|
||||||
|
|
||||||
|
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>
|
-- SPDX-FileCopyrightText: 2022-23 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
|||||||
@ -32,11 +32,12 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
Ob ein Ansprechpartner Email oder Briefpost wünscht ist eine individuelle Einstellung des Ansprechpartners und gilt für alle Benachrichtigungen an diesen Ansprechpartner.
|
Ob ein Ansprechpartner Email oder Briefpost wünscht ist eine individuelle Einstellung des Ansprechpartners und gilt für alle Benachrichtigungen an diesen Ansprechpartner.
|
||||||
<li> Anzahl der firmenfremden Ansprechpartner, welche mindestens einen Firmenangehörigen betreuen. Bei manchen Firmen ist es normal, dass die Ansprechpartner einer anderen Firma angehören, aber oft ist nur ein Fehler durch Firmenwechsel.
|
<li> Anzahl der firmenfremden Ansprechpartner, welche mindestens einen Firmenangehörigen betreuen. Bei manchen Firmen ist es normal, dass die Ansprechpartner einer anderen Firma angehören, aber oft ist nur ein Fehler durch Firmenwechsel.
|
||||||
<li> Anzahl der Ansprechpartner mit derzeit aktiver Benachrichtigungsumleitung, egal ob Brief oder Email.
|
<li> Anzahl der Ansprechpartner mit derzeit aktiver Benachrichtigungsumleitung, egal ob Brief oder Email.
|
||||||
<li> Gesamtzahl der Brief und Emails, welche bei Benachrichtigung aller Firmenangehörigen derzeit verschickt würden.
|
<li> Gesamtzahl der Brief und Emails, welche bei Benachrichtigung aller Firmenangehörigen derzeit verschickt würden.
|
||||||
<p>
|
<p>
|
||||||
Dies ist also die Gesamtzahl aller derzeit aktiven Benachrichtigungsumleitungen.
|
Dies ist also die Gesamtzahl aller derzeit aktiven Benachrichtigungsumleitungen.
|
||||||
<p>
|
<p>
|
||||||
<em>
|
<em>
|
||||||
Beispiel: Für eine Firma mit 2 Angehörigen, für die ein Mitarbeiter 1 Ansprechpartner mit aktiver Umleitung und einen Mitarbeiter mit 3 Ansprechpartnern mit aktiver Umleitung hätte, #
|
Beispiel: Für eine Firma mit 2 Angehörigen, für die ein Mitarbeiter 1 Ansprechpartner mit aktiver Umleitung und einen Mitarbeiter mit 3 Ansprechpartnern mit aktiver Umleitung hätte, #
|
||||||
würde hier die Zahl 4 stehen, da bei einer Benachrichtigung an beide Mitarbeiter insgesamt 4 Briefe oder Emails versendet würden.
|
würde hier die Zahl 4 stehen, da bei einer Benachrichtigung an beide Mitarbeiter insgesamt 4 Briefe oder Emails versendet würden.
|
||||||
|
<li> Voreinstellung der persönlichen Benachrichtigungspreferenz für Firmenangehörige welche neu aus dem AVS importiert werden (erst mit Umsetzung CR3 effektiv).
|
||||||
|
|
||||||
|
|||||||
@ -40,4 +40,5 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
<em>
|
<em>
|
||||||
Beispiel: Für eine Firma mit 2 Angehörigen, für die ein Mitarbeiter 1 Ansprechpartner mit aktiver Umleitung und einen Mitarbeiter mit 3 Ansprechpartnern mit aktiver Umleitung hätte, #
|
Beispiel: Für eine Firma mit 2 Angehörigen, für die ein Mitarbeiter 1 Ansprechpartner mit aktiver Umleitung und einen Mitarbeiter mit 3 Ansprechpartnern mit aktiver Umleitung hätte, #
|
||||||
würde hier die Zahl 4 stehen, da bei einer Benachrichtigung an beide Mitarbeiter insgesamt 4 Briefe oder Emails versendet würden.
|
würde hier die Zahl 4 stehen, da bei einer Benachrichtigung an beide Mitarbeiter insgesamt 4 Briefe oder Emails versendet würden.
|
||||||
|
<li> Voreinstellung der persönlichen Benachrichtigungspreferenz für Firmenangehörige welche neu aus dem AVS importiert werden (erst mit Umsetzung CR3 effektiv).
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
^{formatTimeW SelFormatDate bday}
|
^{formatTimeW SelFormatDate bday}
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
_{MsgPrefersPostal}
|
_{MsgPrefersPostalExp}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
#{iconLetterOrEmail userPrefersPostal}
|
#{iconLetterOrEmail userPrefersPostal}
|
||||||
$maybe addr <- userPostAddress
|
$maybe addr <- userPostAddress
|
||||||
|
|||||||
Reference in New Issue
Block a user