chore(firm): implement several table actions; add supervisor form

This commit is contained in:
Steffen Jost 2023-11-17 18:54:34 +01:00
parent 715b751363
commit 44c4b3b6a8
10 changed files with 212 additions and 51 deletions

View File

@ -11,6 +11,7 @@ FirmAllActResetSupervision: Ansprechpartner für alle Firmenangehörigen zurück
FirmAllActResetSuperKeep: Bisherige Ansprechpartner der Firmenangehörigen zusätzlich beibehalten? FirmAllActResetSuperKeep: Bisherige Ansprechpartner der Firmenangehörigen zusätzlich beibehalten?
FirmAllActResetMutualSupervision: Ansprechpartner beaufsichtigen sich gegenseitig FirmAllActResetMutualSupervision: Ansprechpartner beaufsichtigen sich gegenseitig
FirmUserActNotify: Mitteilung versenden FirmUserActNotify: Mitteilung versenden
FirmUserActResetSupervision: Ansprechpartner auf Firmenstandard zurücksetzen
FirmUserActMkSuper: Zum Firmenansprechpartner ernennen FirmUserActMkSuper: Zum Firmenansprechpartner ernennen
FirmResetSupervision rem@Int64 set@Int64: #{tshow set} Ansprechpartner gesetzt#{bool mempty (", " <> tshow rem <> " zuvor gelöscht") (rem > 0)} FirmResetSupervision rem@Int64 set@Int64: #{tshow set} Ansprechpartner gesetzt#{bool mempty (", " <> tshow rem <> " zuvor gelöscht") (rem > 0)}
FirmSuperActNotify: Mitteilung versenden FirmSuperActNotify: Mitteilung versenden
@ -30,4 +31,9 @@ FirmSupervisorIndependent: Ansprechpartner ohne jegliche Firmenzugehörigkeit
FirmEmployeeOf fsh@CompanyShorthand: Firmenangehörige #{fsh} FirmEmployeeOf fsh@CompanyShorthand: Firmenangehörige #{fsh}
NoCompanySelected: Bitte wählen Sie mindestens eine Firm aus. NoCompanySelected: Bitte wählen Sie mindestens eine Firm aus.
TableIsDefaultSupervisor: Standardansprechpartner TableIsDefaultSupervisor: Standardansprechpartner
TableIsDefaultReroute: Standardumleitung TableIsDefaultReroute: Standardumleitung
ASReqPostal: Benachrichtigungseinstellung
ASReqPostalTip: Gilt für alle Benachrichtigungen an diese Person, nicht nur für Umleitungen an diesen Ansprechpartner
ASReqEmpty: Es konnten keine Ansprechpartner hinzugefügt werden
ASReqSetSupers n@Int64 postal@(Maybe Bool): #{n} Standardansprechpartner eingetragen #{maybeBoolMessage postal "" "und auf Briefversand geschaltet" "und Benachrichtigungen per Email gesetzt"}, aber nicht nicht aktiviert.
RemoveDefaultSupervisors n@Int64: #{n} Standard Ansprechpartner entfernt, aber noch nicht deaktiviert.

View File

@ -11,6 +11,7 @@ FirmAllActResetSupervision: Reset supervisors for all company associates
FirmUserActNotify: Send message FirmUserActNotify: Send message
FirmAllActResetSuperKeep: Additionally keep existing supervisors of company associates? FirmAllActResetSuperKeep: Additionally keep existing supervisors of company associates?
FirmAllActResetMutualSupervision: Supervisors supervise each other FirmAllActResetMutualSupervision: Supervisors supervise each other
FirmUserActResetSupervision: Reset supervisors to company default
FirmResetSupervision rem set: #{tshow set} supervisors set#{bool mempty (", " <> tshow rem <> " deleted before") (rem > 0)} FirmResetSupervision rem set: #{tshow set} supervisors set#{bool mempty (", " <> tshow rem <> " deleted before") (rem > 0)}
FirmUserActMkSuper: Mark as company supervisor FirmUserActMkSuper: Mark as company supervisor
FirmSuperActNotify: Send message FirmSuperActNotify: Send message
@ -30,4 +31,9 @@ FirmSupervisorIndependent: Independent supervisors
FirmEmployeeOf fsh@CompanyShorthand: #{fsh} associated users FirmEmployeeOf fsh@CompanyShorthand: #{fsh} associated users
NoCompanySelected: Select at least one company, please. NoCompanySelected: Select at least one company, please.
TableIsDefaultSupervisor: Default supervisor TableIsDefaultSupervisor: Default supervisor
TableIsDefaultReroute: Default reroute TableIsDefaultReroute: Default reroute
ASReqPostal: Notification type
ASReqPostalTip: Affects all notifications to this person, not just reroutes to this supervisor
ASReqEmpty: No supervisors added
ASReqSetSupers n postal: #{n} default company supervisors set #{maybeBoolMessage postal "" "and switched to postal notifications" "and switched to email notifications"}, but not yet activated.
RemoveDefaultSupervisors n: #{n} default supervisors removed, but not yet deactivated.

View File

@ -18,6 +18,8 @@ CommRecipients: Empfänger:innen
CommRecipientsTip: Sie selbst erhalten immer eine Kopie der Nachricht CommRecipientsTip: Sie selbst erhalten immer eine Kopie der Nachricht
CommRecipientsList: Die an Sie selbst verschickte Kopie der Nachricht wird, zu Archivierungszwecken, eine vollständige Liste aller Empfänger:innen enthalten. Die Empfängerliste wird im CSV-Format an die E-Mail angehängt. Andere Empfänger:innen erhalten die Liste nicht. Bitte entfernen Sie dementsprechend den Anhang bevor Sie die E-Mail weiterleiten oder anderweitig mit Dritten teilen. CommRecipientsList: Die an Sie selbst verschickte Kopie der Nachricht wird, zu Archivierungszwecken, eine vollständige Liste aller Empfänger:innen enthalten. Die Empfängerliste wird im CSV-Format an die E-Mail angehängt. Andere Empfänger:innen erhalten die Liste nicht. Bitte entfernen Sie dementsprechend den Anhang bevor Sie die E-Mail weiterleiten oder anderweitig mit Dritten teilen.
UtilEMail: E-Mail UtilEMail: E-Mail
UtilPostal: Brief
UtilUnchanged: Nicht verändern
UtilMultiEmailFieldTip: Es sind mehrere, Komma-separierte, E-Mail-Adressen möglich UtilMultiEmailFieldTip: Es sind mehrere, Komma-separierte, E-Mail-Adressen möglich
RGTutorialParticipants tutn@TutorialName: Kursteilnehmer:innen (#{tutn}) RGTutorialParticipants tutn@TutorialName: Kursteilnehmer:innen (#{tutn})
RGExamRegistered examn@ExamName: Angemeldet zur Prüfung „#{examn}“ RGExamRegistered examn@ExamName: Angemeldet zur Prüfung „#{examn}“
@ -94,6 +96,7 @@ RoomReferenceLinkLink !ident-ok: Link
RoomReferenceLinkLinkPlaceholder !ident-ok: URL RoomReferenceLinkLinkPlaceholder !ident-ok: URL
RoomReferenceLinkInstructions: Anweisungen RoomReferenceLinkInstructions: Anweisungen
RoomReferenceLinkInstructionsPlaceholder: Anweisungen RoomReferenceLinkInstructionsPlaceholder: Anweisungen
UtilEmptyChoice: Auswahl war leer
#invitation.hs #invitation.hs
InvitationAction: Aktion InvitationAction: Aktion

View File

@ -18,6 +18,8 @@ CommRecipients: Recipients
CommRecipientsTip: You always receive a copy of the message CommRecipientsTip: You always receive a copy of the message
CommRecipientsList: For archival purposes the copy of the message sent to you will contain a complete list of all recipients. The list of recipients will be attached to the email in CSV-format. Other recipients do not receive the list. Thus, please remove the attachment before you forward the email or otherwise share it with third parties. CommRecipientsList: For archival purposes the copy of the message sent to you will contain a complete list of all recipients. The list of recipients will be attached to the email in CSV-format. Other recipients do not receive the list. Thus, please remove the attachment before you forward the email or otherwise share it with third parties.
UtilEMail: Email UtilEMail: Email
UtilPostal: Postal
UtilUnchanged: No change
UtilMultiEmailFieldTip: Multiple emails addresses may be specified (comma-separated) UtilMultiEmailFieldTip: Multiple emails addresses may be specified (comma-separated)
RGTutorialParticipants tutn: Course participants (#{tutn}) RGTutorialParticipants tutn: Course participants (#{tutn})
RGExamRegistered examn: Registered for exam “#{examn}” RGExamRegistered examn: Registered for exam “#{examn}”
@ -94,6 +96,7 @@ RoomReferenceLinkLink: Link
RoomReferenceLinkLinkPlaceholder: URL RoomReferenceLinkLinkPlaceholder: URL
RoomReferenceLinkInstructions: Instructions RoomReferenceLinkInstructions: Instructions
RoomReferenceLinkInstructionsPlaceholder: Instructions RoomReferenceLinkInstructionsPlaceholder: Instructions
UtilEmptyChoice: Empty selection
#invitation.hs #invitation.hs
InvitationAction: Action InvitationAction: Action

View File

@ -203,6 +203,11 @@ maybeToMessage :: ToMessage m => Text -> Maybe m -> Text -> Text
maybeToMessage _ Nothing _ = mempty maybeToMessage _ Nothing _ = mempty
maybeToMessage before (Just x) after = before <> toMessage x <> after maybeToMessage before (Just x) after = before <> toMessage x <> after
maybeBoolMessage :: Maybe Bool -> Text -> Text -> Text -> Text
maybeBoolMessage Nothing n _ _ = n
maybeBoolMessage (Just True) _ t _ = t
maybeBoolMessage (Just False) _ _ f = f
newtype ShortTermIdentifier = ShortTermIdentifier TermIdentifier newtype ShortTermIdentifier = ShortTermIdentifier TermIdentifier
deriving stock (Eq, Ord, Read, Show) deriving stock (Eq, Ord, Read, Show)

View File

@ -21,6 +21,7 @@ import Import
-- import Jobs -- import Jobs
import Handler.Utils import Handler.Utils
import Handler.Utils.Communication import Handler.Utils.Communication
import Handler.Utils.Avs (guessAvsUser)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
@ -28,7 +29,7 @@ import qualified Data.Map as Map
-- import qualified Data.Text as T -- import qualified Data.Text as T
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
-- import qualified Data.Conduit.List as C -- import qualified Data.Conduit.List as C
import Database.Persist.Sql (deleteWhereCount) import Database.Persist.Sql (deleteWhereCount, 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 (from, on) import qualified Database.Esqueleto.Legacy as EL (from, on)
@ -77,16 +78,18 @@ addDefaultSupervisors cid employees = do
) )
(\_old new -> [UserSupervisorRerouteNotifications E.=. new E.^. UserSupervisorRerouteNotifications]) (\_old new -> [UserSupervisorRerouteNotifications E.=. new E.^. UserSupervisorRerouteNotifications])
-- like `addDefaultSupervisors`, but selects all employees from database -- like `addDefaultSupervisors`, but selects all employees of given companies from database
addDefaultSupervisorsAll :: (MonoFoldable mono, CompanyId ~ Element mono) => Bool -> mono -> DB Int64 addDefaultSupervisorsAll :: (CompanyId ~ Element mono, MonoFoldable mono) => Bool -> mono -> DB Int64
addDefaultSupervisorsAll mutualSupervision cids = do addDefaultSupervisorsAll mutualSupervision cids = do
E.insertSelectWithConflictCount UniqueUserSupervisor E.insertSelectWithConflictCount UniqueUserSupervisor
(do (do
(spr :& usr) <- E.from $ E.table @UserCompany `E.innerJoin` E.table @UserCompany `E.on` (\(spr :& usr) -> spr E.^. UserCompanyCompany E.==. usr E.^. UserCompanyCompany) (spr :& usr) <- E.from $ E.table @UserCompany `E.innerJoin` E.table @UserCompany `E.on` (\(spr :& usr) -> spr E.^. UserCompanyCompany E.==. usr E.^. UserCompanyCompany)
E.where_ $ E.and $ guardMonoid (not mutualSupervision) [ E.not_ $ usr E.^. UserCompanySupervisor ] E.where_ $ E.and $ guardMonoid (not mutualSupervision)
<> [ spr E.^. UserCompanyCompany `E.in_` E.vals cids [ E.not_ $ usr E.^. UserCompanySupervisor ]
, spr E.^. UserCompanySupervisor <> [ spr E.^. UserCompanySupervisor
] , spr E.^. UserCompanyCompany `E.in_` E.vals cids
, usr E.^. UserCompanyCompany `E.in_` E.vals cids
]
return $ UserSupervisor return $ UserSupervisor
E.<# (spr E.^. UserCompanyUser) E.<# (spr E.^. UserCompanyUser)
E.<&> (usr E.^. UserCompanyUser) E.<&> (usr E.^. UserCompanyUser)
@ -216,12 +219,12 @@ firmCountUserSupervisorsReroute usrCmp = E.subSelectCount $ do
getFirmR, postFirmR :: CompanyShorthand -> Handler Html getFirmR, postFirmR :: CompanyShorthand -> Handler Html
getFirmR = postFirmR getFirmR = postFirmR
postFirmR fsh = do postFirmR fsh = do
let fshId = CompanyKey fsh let cid = CompanyKey fsh
cusers <- runDB $ do cusers <- runDB $ do
cusers <- selectList [UserCompanyCompany ==. fshId] [] cusers <- selectList [UserCompanyCompany ==. cid] []
selectList [UserId <-. fmap (userCompanyUser . entityVal) cusers] [Asc UserDisplayName] selectList [UserId <-. fmap (userCompanyUser . entityVal) cusers] [Asc UserDisplayName]
csuper <- runDB $ do csuper <- runDB $ do
csuper <- selectList [UserCompanyCompany ==. fshId, UserCompanySupervisor ==. True] [] csuper <- selectList [UserCompanyCompany ==. cid, UserCompanySupervisor ==. True] []
selectList [UserId <-. fmap (userCompanyUser . entityVal) csuper] [Asc UserDisplayName] selectList [UserId <-. fmap (userCompanyUser . entityVal) csuper] [Asc UserDisplayName]
cactSuper <- runDB $ E.select $ do cactSuper <- runDB $ E.select $ do
(usr :& spr :& scmpy) <- E.from $ (usr :& spr :& scmpy) <- E.from $
@ -253,7 +256,7 @@ postFirmR fsh = do
<li>#{nr} Employees supervised by ^{nameWidget dn sn} # <li>#{nr} Employees supervised by ^{nameWidget dn sn} #
#{iconLetterOrEmail prefPost} # #{iconLetterOrEmail prefPost} #
$maybe csh <- mbCsh $maybe csh <- mbCsh
$if csh /= fshId $if csh /= cid
from foreign company #{unCompanyKey csh} from foreign company #{unCompanyKey csh}
$else $else
from this company from this company
@ -478,8 +481,8 @@ postFirmAllR = do
E.where_ $ usr E.^. UserCompanyCompany `E.in_` E.vals fids E.where_ $ usr E.^. UserCompanyCompany `E.in_` E.vals fids
E.&&. usr E.^. UserCompanyUser E.==. spr E.^. UserSupervisorUser E.&&. usr E.^. UserCompanyUser E.==. spr E.^. UserSupervisorUser
else return 0 else return 0
newSupers <- addDefaultSupervisorsAll (firmAllActResetMutualSupervision /= Just False) fids newSupers <- addDefaultSupervisorsAll (firmAllActResetMutualSupervision /= Just False) fids
addMessageI Info $ MsgFirmResetSupervision newSupers delSupers addMessageI Info $ MsgFirmResetSupervision delSupers newSupers
reloadKeepGetParams FirmAllR -- reload to reflect changes reloadKeepGetParams FirmAllR -- reload to reflect changes
(FirmAllActNotifyData , Set.toList -> fids) -> do (FirmAllActNotifyData , Set.toList -> fids) -> do
@ -499,6 +502,7 @@ postFirmAllR = do
-- Firm Users Table -- Firm Users Table
data FirmUserAction = FirmUserActNotify data FirmUserAction = FirmUserActNotify
| FirmUserActResetSupervision
| FirmUserActMkSuper | FirmUserActMkSuper
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic) deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
deriving anyclass (Universe, Finite) deriving anyclass (Universe, Finite)
@ -507,8 +511,14 @@ nullaryPathPiece ''FirmUserAction $ camelToPathPiece' 3
embedRenderMessage ''UniWorX ''FirmUserAction id embedRenderMessage ''UniWorX ''FirmUserAction id
data FirmUserActionData = FirmUserActNotifyData data FirmUserActionData = FirmUserActNotifyData
| FirmUserActResetSupervisionData
{ firmUserActResetKeepOldSupers :: Maybe Bool
-- , firmUserActResetMutualSupervision :: Maybe Bool
}
| FirmUserActMkSuperData | FirmUserActMkSuperData
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic) { firmUserActMkSuperReroute :: Maybe Bool }
deriving (Eq, Ord, Read, Show, Generic)
type UserCompanyTableExpr = E.SqlExpr (Entity User) `E.InnerJoin` E.SqlExpr (Entity UserCompany) type UserCompanyTableExpr = E.SqlExpr (Entity User) `E.InnerJoin` E.SqlExpr (Entity UserCompany)
@ -651,8 +661,12 @@ mkFirmUserTable isAdmin cid = do
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout } dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
acts :: Map FirmUserAction (AForm Handler FirmUserActionData) acts :: Map FirmUserAction (AForm Handler FirmUserActionData)
acts = mconcat acts = mconcat
[ singletonMap FirmUserActNotify $ pure FirmUserActNotifyData [ singletonMap FirmUserActNotify $ pure FirmUserActNotifyData
, singletonMap FirmUserActMkSuper $ pure FirmUserActMkSuperData , singletonMap FirmUserActResetSupervision $ FirmUserActResetSupervisionData
<$> aopt (boolField . Just $ SomeMessage MsgBoolIrrelevant) (fslI MsgFirmAllActResetSuperKeep) (Just $ Just False)
-- <*> aopt checkBoxField (fslI MsgFirmAllActResetMutualSupervision) (Just $ Just True )
, singletonMap FirmUserActMkSuper $ FirmUserActMkSuperData
<$> aopt checkBoxField (fslI MsgTableIsDefaultReroute) (Just $ Just True)
] ]
dbtParams = DBParamsForm dbtParams = DBParamsForm
{ dbParamsFormMethod = POST { dbParamsFormMethod = POST
@ -720,10 +734,23 @@ postFirmUsersR fsh = do
<*> mkFirmUserTable isAdmin cid <*> mkFirmUserTable isAdmin cid
formResult fusrRes $ \case formResult fusrRes $ \case
(FirmUserActMkSuperData, fids) -> addMessage Info $ text2Html $ "Make " <> tshow (length fids) <> " employees to supervisors. TODO" (_, uids) | null uids -> addMessageI Error MsgUtilEmptyChoice
(FirmUserActNotifyData , fids) -> do (FirmUserActMkSuperData{..}, uids) -> do
cuids <- traverse encrypt $ Set.toList fids :: Handler [CryptoUUIDUser] nrMkSuper <- runDB $ updateWhereCount [UserCompanyUser <-. uids, UserCompanyCompany ==. cid] [UserCompanySupervisor =. True, UserCompanySupervisorReroute =. firmUserActMkSuperReroute]
addMessageI Info $ MsgASReqSetSupers nrMkSuper Nothing
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
(FirmUserActNotifyData , uids) -> do
cuids <- traverse encrypt $ Set.toList uids :: Handler [CryptoUUIDUser]
redirect (FirmCommR fsh, [(toPathPiece GetRecipient, toPathPiece cID) | cID <- cuids]) redirect (FirmCommR fsh, [(toPathPiece GetRecipient, toPathPiece cID) | cID <- cuids])
(FirmUserActResetSupervisionData{..}, Set.toList -> uids') -> do
let uids = fromList uids' -- guaranteed to be non-empty due to first case clause
runDB $ do
delSupers <- if firmUserActResetKeepOldSupers == Just False
then deleteSupervisors uids
else return 0
newSupers <- addDefaultSupervisors cid uids
addMessageI Info $ MsgFirmResetSupervision delSupers newSupers
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
siteLayout (citext2widget companyName) $ do siteLayout (citext2widget companyName) $ do
setTitle $ toHtml $ CI.original companyShorthand <> "-" <> tshow companyAvsId setTitle $ toHtml $ CI.original companyShorthand <> "-" <> tshow companyAvsId
@ -745,7 +772,33 @@ embedRenderMessage ''UniWorX ''FirmSuperAction id
data FirmSuperActionData = FirmSuperActNotifyData data FirmSuperActionData = FirmSuperActNotifyData
| FirmSuperActRMSuperDefData | FirmSuperActRMSuperDefData
| FirmSuperActRMSuperAllData | FirmSuperActRMSuperAllData
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic) deriving (Eq, Ord, Read, Show, Generic)
data AddSupervisorRequest = AddSupervisorRequest
{ asReqSupers :: Set Text
, asReqReroute :: Bool
, asReqPostal :: Maybe Bool
} deriving (Eq, Ord, Show, Generic)
instance Default AddSupervisorRequest where
def = AddSupervisorRequest
{ asReqSupers = mempty
, asReqReroute = True
, asReqPostal = Nothing
}
postalEmailField :: (MonadHandler m, HandlerSite m ~ UniWorX) => Field m Bool
postalEmailField = boolFieldCustom (SomeMessage MsgUtilPostal) (SomeMessage MsgUtilEMail) $ Just $ SomeMessage MsgUtilUnchanged
makeAddSupervisorForm :: Maybe AddSupervisorRequest -> Form AddSupervisorRequest
makeAddSupervisorForm template html = do
flip (renderAForm FormStandard) html $ AddSupervisorRequest
<$> areq (textField & cfAnySeparatedSet)
(fslI MsgTableIsDefaultSupervisor & setTooltip MsgCourseParticipantsRegisterUsersFieldTip) (asReqSupers <$> template)
<*> areq checkBoxField (fslI MsgTableIsDefaultReroute ) (asReqReroute <$> template)
<*> aopt postalEmailField (fslI MsgASReqPostal & setTooltip MsgASReqPostalTip) (asReqPostal <$> template)
type SuperCompanyTableExpr = E.SqlExpr (Entity User) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity UserCompany)) type SuperCompanyTableExpr = E.SqlExpr (Entity User) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity UserCompany))
@ -886,41 +939,59 @@ getFirmSupersR, postFirmSupersR :: CompanyShorthand -> Handler Html
getFirmSupersR = postFirmSupersR getFirmSupersR = postFirmSupersR
postFirmSupersR fsh = do postFirmSupersR fsh = do
isAdmin <- hasReadAccessTo AdminR isAdmin <- hasReadAccessTo AdminR
let fshId = CompanyKey fsh let cid = CompanyKey fsh
(Company{..},(fsprRes,fsprTable)) <- runDB $ (,) (Company{..},(fsprRes,fsprTable)) <- runDB $ (,)
<$> get404 fshId <$> get404 cid
<*> mkFirmSuperTable isAdmin fshId <*> mkFirmSuperTable isAdmin cid
formResult fsprRes $ \case formResult fsprRes $ \case
(FirmSuperActRMSuperDefData, fids) -> addMessage Info $ text2Html $ "Remove " <> tshow (length fids) <> " default supervisors. TODO" (_, uids) | null uids -> addMessageI Error MsgUtilEmptyChoice
(FirmSuperActRMSuperAllData, fids) -> addMessage Info $ text2Html $ "Make " <> tshow (length fids) <> " default and active supervisors. TODO" (FirmSuperActRMSuperDefData, uids) -> do
(FirmSuperActNotifyData , fids) -> do nrRmSuper <- runDB $ updateWhereCount [UserCompanyUser <-. uids, UserCompanyCompany ==. cid] [UserCompanySupervisor =. False, UserCompanySupervisorReroute =. False]
cuids <- traverse encrypt $ Set.toList fids :: Handler [CryptoUUIDUser] addMessageI Info $ MsgRemoveDefaultSupervisors nrRmSuper
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
(FirmSuperActRMSuperAllData, uids) -> addMessage Info $ text2Html $ "Make " <> tshow (length uids) <> " default and active supervisors. TODO"
(FirmSuperActNotifyData , uids) -> do
cuids <- traverse encrypt $ Set.toList uids :: Handler [CryptoUUIDUser]
redirect (FirmCommR fsh, [(toPathPiece GetRecipient, toPathPiece cID) | cID <- cuids]) redirect (FirmCommR fsh, [(toPathPiece GetRecipient, toPathPiece cID) | cID <- cuids])
((asReqRes, asReqWgt), asReqEnctype) <- runFormPost . identifyForm FIDAddSupervisor $ makeAddSupervisorForm (Just def)
let addSuperAnchor = "add-supervisors-form" :: Text
routeAddSuperForm = FirmSupersR fsh :#: addSuperAnchor
addSuperForm = wrapForm asReqWgt FormSettings
{ formMethod = POST
, formAction = Just . SomeRoute $ routeAddSuperForm
, formEncoding = asReqEnctype
, formAttrs = []
, formSubmit = FormSubmit
, formAnchor = Just addSuperAnchor
}
formResult asReqRes $ \AddSupervisorRequest{..} -> do
avsUsers :: Map Text (Maybe UserId) <- sequenceA $ Map.fromSet guessAvsUser asReqSupers
let (usersFound', usersNotFound) = partition (is _Just . view _2) $ Map.toList avsUsers
usersFound = mapMaybe snd usersFound'
unless (null usersNotFound) $
let msgContent = [whamlet|
$newline never
<ul>
$forall (usr,_) <- usersNotFound
<li>#{usr}
|]
in addMessageModal Error (i18n . MsgCourseParticipantsRegisterNotFoundInAvs $ length usersNotFound) (Right msgContent)
when (null usersFound) $ do
addMessageI Warning MsgASReqEmpty
redirect routeAddSuperForm
runDB $ do
putMany [UserCompany uid cid True asReqReroute | uid <- usersFound]
whenIsJust asReqPostal $ \prefPostal ->
updateWhere [UserId <-. usersFound] [UserPrefersPostal =. prefPostal]
addMessageI Info $ MsgASReqSetSupers (fromIntegral $ length usersFound) asReqPostal
redirect $ FirmSupersR fsh
siteLayout (citext2widget fsh) $ do siteLayout (citext2widget fsh) $ do
setTitle $ citext2Html $ fsh <> " Supers" setTitle $ citext2Html $ fsh <> " Supers"
-- TODO: factor out company info section hamlet here and from user table $(i18nWidgetFile "firm-supervisors")
[whamlet|
<section>
<h2>!!!STUB!!!TO DO!!!
<section .profile>
<dl .deflist.profile-dl>
$maybe fem <- companyEmail
<dt .deflist__dt>
_{MsgFirmEmail} #{iconLetterOrEmail False}
<dd .deflist__dd .email>
#{mailtoHtml fem}
$maybe addr <- companyPostAddress
<dt .deflist__dt>
_{MsgFirmAddress} #{iconLetterOrEmail True}
<dd .deflist__dd>
#{addr}
<section>
^{fsprTable}
|]
getFirmCommR, postFirmCommR :: CompanyShorthand -> Handler Html getFirmCommR, postFirmCommR :: CompanyShorthand -> Handler Html
getFirmCommR = postFirmCommR getFirmCommR = postFirmCommR

View File

@ -1498,7 +1498,20 @@ boolField mkNone = radioGroupField mkNone $ do
_other -> Nothing _other -> Nothing
} }
-- | like `boolField` but with custom labels
boolFieldCustom :: (MonadHandler m, HandlerSite m ~ UniWorX)
=> SomeMessage UniWorX -> SomeMessage UniWorX -> Maybe (SomeMessage UniWorX) -> Field m Bool
boolFieldCustom mkTrue mkFalse mkNone = radioGroupField mkNone $ do
mr <- getMessageRender
return OptionList
{ olOptions = [ Option (mr mkFalse) False "false"
, Option (mr mkTrue) True "true"
]
, olReadExternal = \case
"false" -> Just False
"true" -> Just True
_other -> Nothing
}
sectionedFuncForm :: forall f k v m sec. sectionedFuncForm :: forall f k v m sec.
( TraversableWithIndex k f ( TraversableWithIndex k f

View File

@ -316,6 +316,7 @@ data FormIdentifier
| FIDBtnAvsImportUnknown | FIDBtnAvsImportUnknown
| FIDBtnAvsRevokeUnknown | FIDBtnAvsRevokeUnknown
| FIDHijackUser | FIDHijackUser
| FIDAddSupervisor
deriving (Eq, Ord, Read, Show) deriving (Eq, Ord, Read, Show)
instance PathPiece FormIdentifier where instance PathPiece FormIdentifier where

View File

@ -0,0 +1,27 @@
$newline never
$# SPDX-FileCopyrightText: 2023 Steffen Jost <s.jost@fraport.de>
$#
$# SPDX-License-Identifier: AGPL-3.0-or-later
<section>
Bitte beachten, dass Ansprechpartner-Beziehung unabhängig von Firmenzugehörigkeit zwischen Einzelpersonen bestehen.
Daraus folgt zum Beispiel, dass wenn <em>x</em> ein Standard-Ansprechpartner für Firma <em>a</em> ist
und wenn <em>y</em> sowohl Firma <em>a</em> als auch <em>b</em> angehört,
dass dann <em>x</em> als firmenfremd in der Liste der Ansprechpartner von Firma <em>b</em> angezeigt wird.
<section .profile>
<dl .deflist.profile-dl>
$maybe fem <- companyEmail
<dt .deflist__dt>
_{MsgFirmEmail} #{iconLetterOrEmail False}
<dd .deflist__dd .email>
#{mailtoHtml fem}
$maybe addr <- companyPostAddress
<dt .deflist__dt>
_{MsgFirmAddress} #{iconLetterOrEmail True}
<dd .deflist__dd>
#{addr}
<section>
^{fsprTable}
<section>
^{addSuperForm}

View File

@ -0,0 +1,26 @@
$newline never
$# SPDX-FileCopyrightText: 2023 Steffen Jost <s.jost@fraport.de>
$#
$# SPDX-License-Identifier: AGPL-3.0-or-later
<section>
Note that supervision is company independent.
For example, if <em>x</em> is a regular supervisor for company <em>a</em> and <em>y</em> belongs to companies <em>a</em> and <em>b</em>,
then <em>x</em> will be listed as a foreign supervisor for company <em>b</em>.
<section .profile>
<dl .deflist.profile-dl>
$maybe fem <- companyEmail
<dt .deflist__dt>
_{MsgFirmEmail} #{iconLetterOrEmail False}
<dd .deflist__dd .email>
#{mailtoHtml fem}
$maybe addr <- companyPostAddress
<dt .deflist__dt>
_{MsgFirmAddress} #{iconLetterOrEmail True}
<dd .deflist__dd>
#{addr}
<section>
^{fsprTable}
<section>
^{addSuperForm}