Merge branch 'fradrive/company' into 'master'
Fradrive/company Closes #67 See merge request fradrive/fradrive!23
This commit is contained in:
commit
60fc5f8b63
@ -16,7 +16,7 @@ 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
|
||||||
FirmSuperActRMSuperDef: Standard Firmenansprechpartner entfernen
|
FirmSuperActRMSuperDef: Standard Firmenansprechpartner entfernen
|
||||||
FirmSuperActRMSuperAll: Als aktiven Ansprechpartner komplett entfernen
|
FirmSuperActRMSuperActive: Auch aktive Ansprechpartnerbeziehungen innerhalb dieser Firma beenden
|
||||||
FirmsNotification: Firmen Benachrichtigung versenden
|
FirmsNotification: Firmen Benachrichtigung versenden
|
||||||
FirmNotification fsh@CompanyShorthand: Benachrichtigung an #{fsh} versenden
|
FirmNotification fsh@CompanyShorthand: Benachrichtigung an #{fsh} versenden
|
||||||
FirmsNotificationTitle: Firmen benachrichtigen
|
FirmsNotificationTitle: Firmen benachrichtigen
|
||||||
@ -32,8 +32,9 @@ 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
|
FormReqPostal: Benachrichtigungseinstellung
|
||||||
ASReqPostalTip: Gilt für alle Benachrichtigungen an diese Person, nicht nur für Umleitungen an diesen Ansprechpartner
|
FormReqPostalTip: Gilt für alle Benachrichtigungen an diese Person, nicht nur für Umleitungen an diesen Ansprechpartner
|
||||||
ASReqEmpty: Es konnten keine Ansprechpartner hinzugefügt werden
|
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.
|
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.
|
RemoveSupervisors ndef@Int64 nact@Int64: #{ndef} Standard Ansprechpartner entfernt#{bool ", aber noch nicht deaktiviert" (", " <> tshow nact <> " aktive Ansprechpartnerbeziehungen gelöscht") (nact > 0)}
|
||||||
|
FirmUserChanges n@Int64: Benachrichtigungseinstellung für #{n} Firmenangehörige wurden geändert
|
||||||
@ -16,7 +16,7 @@ FirmResetSupervision rem set: #{tshow set} supervisors set#{bool mempty (", " <>
|
|||||||
FirmUserActMkSuper: Mark as company supervisor
|
FirmUserActMkSuper: Mark as company supervisor
|
||||||
FirmSuperActNotify: Send message
|
FirmSuperActNotify: Send message
|
||||||
FirmSuperActRMSuperDef: Remove as default supervisor
|
FirmSuperActRMSuperDef: Remove as default supervisor
|
||||||
FirmSuperActRMSuperAll: Remove all active supervisions for this company
|
FirmSuperActRMSuperActive: Also remove active supervisions within this company
|
||||||
FirmsNotification: Send company notification
|
FirmsNotification: Send company notification
|
||||||
FirmNotification fsh: Send notification to company #{fsh}
|
FirmNotification fsh: Send notification to company #{fsh}
|
||||||
FirmsNotificationTitle: Company notification
|
FirmsNotificationTitle: Company notification
|
||||||
@ -32,8 +32,9 @@ 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
|
FormReqPostal: Notification type
|
||||||
ASReqPostalTip: Affects all notifications to this person, not just reroutes to this supervisor
|
FormReqPostalTip: Affects all notifications to this person, not just reroutes to this supervisor
|
||||||
ASReqEmpty: No supervisors added
|
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.
|
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.
|
RemoveSupervisors ndef nact: #{ndef} default supervisors removed#{bool ", but not yet deactivated" (" and " <> tshow nact <> " active supervisons terminated") (nact > 0)}
|
||||||
|
FirmUserChanges n: Notification settings changed for #{n} company associates
|
||||||
@ -104,4 +104,5 @@ 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.
|
||||||
TableFilterCommaName: Mehrere Namen mit Komma trennen.
|
TableFilterCommaName: Mehrere Namen mit Komma trennen.
|
||||||
TableFilterCommaNameNr: Mehrere Namen oder Nummern mit Komma trennen. Nummern werden nur exakt gesucht.
|
TableFilterCommaNameNr: Mehrere Namen oder Nummern mit Komma trennen. Nummern werden nur exakt gesucht.
|
||||||
|
TableUserEdit: Benutzer bearbeiten
|
||||||
@ -104,4 +104,5 @@ 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.
|
||||||
TableFilterCommaName: Separate names by comma.
|
TableFilterCommaName: Separate names by comma.
|
||||||
TableFilterCommaNameNr: Separate names and numbers by comma. Numbers have to match exact.
|
TableFilterCommaNameNr: Separate names and numbers by comma. Numbers have to match exact.
|
||||||
|
TableUserEdit: Edit user
|
||||||
@ -50,7 +50,10 @@ encryptUser = encrypt
|
|||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
-- Firm specific utilities
|
-- Firm specific utilities
|
||||||
-- for filters and counts see before FirmAllR Handlers
|
-- for filters and counts also see before FirmAllR Handlers
|
||||||
|
|
||||||
|
postalEmailField :: (MonadHandler m, HandlerSite m ~ UniWorX) => Field m Bool
|
||||||
|
postalEmailField = boolFieldCustom (SomeMessage MsgUtilPostal) (SomeMessage MsgUtilEMail) $ Just $ SomeMessage MsgUtilUnchanged
|
||||||
|
|
||||||
-- remove supervisors:
|
-- remove supervisors:
|
||||||
deleteSupervisors :: NonEmpty UserId -> DB Int64
|
deleteSupervisors :: NonEmpty UserId -> DB Int64
|
||||||
@ -501,6 +504,25 @@ postFirmAllR = do
|
|||||||
-----------------------
|
-----------------------
|
||||||
-- Firm Users Table
|
-- Firm Users Table
|
||||||
|
|
||||||
|
data FirmUserChangeRequest = FirmUserChangeRequest
|
||||||
|
{ fucrPostalPref :: Maybe Bool
|
||||||
|
, fucrPostalAddr :: Maybe StoredMarkup
|
||||||
|
}
|
||||||
|
deriving (Eq, Ord, Show, Generic)
|
||||||
|
|
||||||
|
instance Default FirmUserChangeRequest where
|
||||||
|
def = FirmUserChangeRequest
|
||||||
|
{ fucrPostalPref = Nothing
|
||||||
|
, fucrPostalAddr = Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
makeFirmUserChangeRequestForm :: Maybe FirmUserChangeRequest -> Form FirmUserChangeRequest
|
||||||
|
makeFirmUserChangeRequestForm template html = do
|
||||||
|
flip (renderAForm FormStandard) html $ FirmUserChangeRequest
|
||||||
|
<$> aopt postalEmailField (fslI MsgFormReqPostal & setTooltip MsgFormReqPostalTip) (fucrPostalPref <$> template)
|
||||||
|
<*> aopt htmlField (fslI MsgPostAddress & setTooltip MsgPostAddressTip) (fucrPostalAddr <$> template)
|
||||||
|
|
||||||
|
|
||||||
data FirmUserAction = FirmUserActNotify
|
data FirmUserAction = FirmUserActNotify
|
||||||
| FirmUserActResetSupervision
|
| FirmUserActResetSupervision
|
||||||
| FirmUserActMkSuper
|
| FirmUserActMkSuper
|
||||||
@ -518,7 +540,7 @@ data FirmUserActionData = FirmUserActNotifyData
|
|||||||
| FirmUserActMkSuperData
|
| FirmUserActMkSuperData
|
||||||
{ firmUserActMkSuperReroute :: Maybe Bool }
|
{ firmUserActMkSuperReroute :: Maybe Bool }
|
||||||
|
|
||||||
deriving (Eq, Ord, Read, Show, Generic)
|
deriving (Eq, Ord, 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)
|
||||||
|
|
||||||
@ -584,6 +606,7 @@ mkFirmUserTable isAdmin cid = do
|
|||||||
, sortable (Just "reroutes") (i18nCell MsgTableCompanyNrRerouteActive) $ \(view resultUserCompanyReroutes -> 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
|
, sortable (Just "postal-pref") (i18nCell MsgPrefersPostal) $ \(view $ resultUserUser . _userPrefersPostal -> b) -> iconFixedCell $ iconLetterOrEmail b
|
||||||
, colUserEmail
|
, colUserEmail
|
||||||
|
, sortable Nothing (i18nCell MsgTableUserEdit) $ \(view resultUserUser -> entUsr) -> cellEditUserModal entUsr
|
||||||
]
|
]
|
||||||
dbtSorting = mconcat
|
dbtSorting = mconcat
|
||||||
[ single $ sortUserNameLink queryUserUser
|
[ single $ sortUserNameLink queryUserUser
|
||||||
@ -750,6 +773,29 @@ postFirmUsersR fsh = do
|
|||||||
newSupers <- addDefaultSupervisors cid uids
|
newSupers <- addDefaultSupervisors cid uids
|
||||||
addMessageI Info $ MsgFirmResetSupervision delSupers newSupers
|
addMessageI Info $ MsgFirmResetSupervision delSupers newSupers
|
||||||
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
|
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
|
||||||
|
|
||||||
|
((fucrRes, fucrWgt), fucrEnctype) <- runFormPost . identifyForm FIDFirmUserChangeRequest $ makeFirmUserChangeRequestForm (Just def)
|
||||||
|
let addFormAnchor = "firm-user-change-form" :: Text
|
||||||
|
routeForm = FirmUsersR fsh :#: addFormAnchor
|
||||||
|
fucrForm = wrapForm fucrWgt FormSettings
|
||||||
|
{ formMethod = POST
|
||||||
|
, formAction = Just . SomeRoute $ routeForm
|
||||||
|
, formEncoding = fucrEnctype
|
||||||
|
, formAttrs = []
|
||||||
|
, formSubmit = FormSubmit
|
||||||
|
, formAnchor = Just addFormAnchor
|
||||||
|
}
|
||||||
|
formResult fucrRes $ \FirmUserChangeRequest{..} -> when (isJust fucrPostalPref || isJust fucrPostalAddr) $ do
|
||||||
|
let changes = foldMap (\pp -> [UserPrefersPostal E.=. E.val pp]) fucrPostalPref <>
|
||||||
|
foldMap (\pa -> [UserPostAddress E.=. E.justVal pa]) fucrPostalAddr -- seems weird, but: Nothing means no change, and not delete address!
|
||||||
|
nrChanged <- runDB $ E.updateCount $ \usr -> do
|
||||||
|
E.set usr changes
|
||||||
|
E.where_ $ E.exists $ do
|
||||||
|
usrCmpy <- E.from $ E.table @UserCompany
|
||||||
|
E.where_ $ usrCmpy E.^. UserCompanyCompany E.==. E.val cid
|
||||||
|
E.&&. usrCmpy E.^. UserCompanyUser E.==. usr E.^. UserId
|
||||||
|
addMessageI Info $ MsgFirmUserChanges nrChanged
|
||||||
|
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
|
||||||
@ -761,7 +807,7 @@ postFirmUsersR fsh = do
|
|||||||
|
|
||||||
data FirmSuperAction = FirmSuperActNotify
|
data FirmSuperAction = FirmSuperActNotify
|
||||||
| FirmSuperActRMSuperDef
|
| FirmSuperActRMSuperDef
|
||||||
| FirmSuperActRMSuperAll
|
|
||||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic)
|
||||||
deriving anyclass (Universe, Finite)
|
deriving anyclass (Universe, Finite)
|
||||||
|
|
||||||
@ -770,8 +816,9 @@ embedRenderMessage ''UniWorX ''FirmSuperAction id
|
|||||||
|
|
||||||
data FirmSuperActionData = FirmSuperActNotifyData
|
data FirmSuperActionData = FirmSuperActNotifyData
|
||||||
| FirmSuperActRMSuperDefData
|
| FirmSuperActRMSuperDefData
|
||||||
| FirmSuperActRMSuperAllData
|
{ firmSuperActRMSuperActive :: Maybe Bool }
|
||||||
deriving (Eq, Ord, Read, Show, Generic)
|
|
||||||
|
deriving (Eq, Ord, Show, Generic)
|
||||||
|
|
||||||
|
|
||||||
data AddSupervisorRequest = AddSupervisorRequest
|
data AddSupervisorRequest = AddSupervisorRequest
|
||||||
@ -787,16 +834,13 @@ instance Default AddSupervisorRequest where
|
|||||||
, asReqPostal = Nothing
|
, 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 :: Maybe AddSupervisorRequest -> Form AddSupervisorRequest
|
||||||
makeAddSupervisorForm template html = do
|
makeAddSupervisorForm template html = do
|
||||||
flip (renderAForm FormStandard) html $ AddSupervisorRequest
|
flip (renderAForm FormStandard) html $ AddSupervisorRequest
|
||||||
<$> areq (textField & cfAnySeparatedSet)
|
<$> areq (textField & cfAnySeparatedSet)
|
||||||
(fslI MsgTableIsDefaultSupervisor & setTooltip MsgCourseParticipantsRegisterUsersFieldTip) (asReqSupers <$> template)
|
(fslI MsgTableIsDefaultSupervisor & setTooltip MsgCourseParticipantsRegisterUsersFieldTip) (asReqSupers <$> template)
|
||||||
<*> areq checkBoxField (fslI MsgTableIsDefaultReroute ) (asReqReroute <$> template)
|
<*> areq checkBoxField (fslI MsgTableIsDefaultReroute ) (asReqReroute <$> template)
|
||||||
<*> aopt postalEmailField (fslI MsgASReqPostal & setTooltip MsgASReqPostalTip) (asReqPostal <$> template)
|
<*> aopt postalEmailField (fslI MsgFormReqPostal & setTooltip MsgFormReqPostalTip) (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))
|
||||||
@ -845,7 +889,8 @@ mkFirmSuperTable isAdmin cid = do
|
|||||||
where
|
where
|
||||||
dbtSQLQuery = \(usr `E.LeftOuterJoin` usrCmp) -> do
|
dbtSQLQuery = \(usr `E.LeftOuterJoin` usrCmp) -> do
|
||||||
EL.on $ usr E.^. UserId E.=?. usrCmp E.?. UserCompanyUser E.&&. usrCmp E.?. UserCompanyCompany E.?=. E.val cid
|
EL.on $ usr E.^. UserId E.=?. usrCmp E.?. UserCompanyUser E.&&. usrCmp E.?. UserCompanyCompany E.?=. E.val cid
|
||||||
E.where_ $ E.exists $ firmQuerySupervisedBy cid Nothing usr
|
E.where_ $ E.isTrue (usrCmp E.?. UserCompanySupervisor)
|
||||||
|
E.||. E.exists (firmQuerySupervisedBy cid Nothing usr)
|
||||||
return ( usr
|
return ( usr
|
||||||
, usr & firmCountForSupervisor cid Nothing
|
, usr & firmCountForSupervisor cid Nothing
|
||||||
, usr & firmCountForSupervisor cid (Just (E.^. UserSupervisorRerouteNotifications))
|
, usr & firmCountForSupervisor cid (Just (E.^. UserSupervisorRerouteNotifications))
|
||||||
@ -873,6 +918,7 @@ mkFirmSuperTable isAdmin cid = do
|
|||||||
, sortable (Just "rerouted") (i18nCell MsgTableCompanyNrEmpRerouted ) $ \(view resultSuperCompanyReroutes -> nr) -> wgtCell $ word2widget nr
|
, sortable (Just "rerouted") (i18nCell MsgTableCompanyNrEmpRerouted ) $ \(view resultSuperCompanyReroutes -> nr) -> wgtCell $ word2widget nr
|
||||||
, sortable (Just "def-super") (i18nCell MsgTableIsDefaultSupervisor) $ \(view resultSuperCompanyDefaultSuper -> mb) -> case mb of { Nothing -> iconCell IconSupervisorForeign; Just True -> iconCell IconSupervisor; Just False -> iconSpacerCell }
|
, sortable (Just "def-super") (i18nCell MsgTableIsDefaultSupervisor) $ \(view resultSuperCompanyDefaultSuper -> mb) -> case mb of { Nothing -> iconCell IconSupervisorForeign; Just True -> iconCell IconSupervisor; Just False -> iconSpacerCell }
|
||||||
, sortable (Just "def-reroute") (i18nCell MsgTableIsDefaultReroute) $ \(view resultSuperCompanyDefaultReroute -> mb) -> tickmarkCell (mb == Just True)
|
, sortable (Just "def-reroute") (i18nCell MsgTableIsDefaultReroute) $ \(view resultSuperCompanyDefaultReroute -> mb) -> tickmarkCell (mb == Just True)
|
||||||
|
, sortable Nothing (i18nCell MsgTableUserEdit) $ \(view resultSuperUser -> entUsr) -> cellEditUserModal entUsr
|
||||||
]
|
]
|
||||||
dbtSorting = mconcat
|
dbtSorting = mconcat
|
||||||
[ single $ sortUserNameLink querySuperUser
|
[ single $ sortUserNameLink querySuperUser
|
||||||
@ -901,8 +947,8 @@ mkFirmSuperTable isAdmin cid = do
|
|||||||
acts :: Map FirmSuperAction (AForm Handler FirmSuperActionData)
|
acts :: Map FirmSuperAction (AForm Handler FirmSuperActionData)
|
||||||
acts = mconcat
|
acts = mconcat
|
||||||
[ singletonMap FirmSuperActNotify $ pure FirmSuperActNotifyData
|
[ singletonMap FirmSuperActNotify $ pure FirmSuperActNotifyData
|
||||||
, singletonMap FirmSuperActRMSuperDef $ pure FirmSuperActRMSuperDefData
|
, singletonMap FirmSuperActRMSuperDef $ FirmSuperActRMSuperDefData
|
||||||
, singletonMap FirmSuperActRMSuperAll $ pure FirmSuperActRMSuperAllData
|
<$> aopt checkBoxField (fslI MsgFirmSuperActRMSuperActive) (Just $ Just True)
|
||||||
]
|
]
|
||||||
dbtParams = DBParamsForm
|
dbtParams = DBParamsForm
|
||||||
{ dbParamsFormMethod = POST
|
{ dbParamsFormMethod = POST
|
||||||
@ -945,11 +991,22 @@ postFirmSupersR fsh = do
|
|||||||
|
|
||||||
formResult fsprRes $ \case
|
formResult fsprRes $ \case
|
||||||
(_, uids) | null uids -> addMessageI Error MsgUtilEmptyChoice
|
(_, uids) | null uids -> addMessageI Error MsgUtilEmptyChoice
|
||||||
(FirmSuperActRMSuperDefData, Set.toList -> uids) -> do
|
(FirmSuperActRMSuperDefData{..}, Set.toList -> uids) -> do
|
||||||
nrRmSuper <- runDB $ updateWhereCount [UserCompanyUser <-. uids, UserCompanyCompany ==. cid] [UserCompanySupervisor =. False, UserCompanySupervisorReroute =. False]
|
(nrRmSuper,nrRmActual) <- runDB $ (,)
|
||||||
addMessageI Info $ MsgRemoveDefaultSupervisors nrRmSuper
|
<$> updateWhereCount [UserCompanyUser <-. uids, UserCompanyCompany ==. cid] [UserCompanySupervisor =. False, UserCompanySupervisorReroute =. False]
|
||||||
|
<*> if firmSuperActRMSuperActive /= Just True
|
||||||
|
then return 0
|
||||||
|
else E.deleteCount $ do
|
||||||
|
spr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ spr E.^. UserSupervisorSupervisor `E.in_` E.vals uids
|
||||||
|
E.&&. E.exists (do
|
||||||
|
usr <- E.from $ E.table @UserCompany
|
||||||
|
E.where_ $ usr E.^. UserCompanyCompany E.==. E.val cid
|
||||||
|
E.&&. usr E.^. UserCompanyUser E.==. spr E.^. UserSupervisorUser
|
||||||
|
)
|
||||||
|
addMessageI Info $ MsgRemoveSupervisors nrRmSuper nrRmActual
|
||||||
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
|
reloadKeepGetParams $ FirmUsersR fsh -- reload to reflect changes
|
||||||
(FirmSuperActRMSuperAllData, uids) -> addMessage Warning $ text2Html $ "TODO Make " <> tshow (length uids) <> " default and active supervisors. TODO"
|
|
||||||
(FirmSuperActNotifyData , uids) -> do
|
(FirmSuperActNotifyData , uids) -> do
|
||||||
cuids <- traverse encrypt $ Set.toList uids :: Handler [CryptoUUIDUser]
|
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])
|
||||||
@ -1005,56 +1062,38 @@ postFirmsCommR = handleFirmCommR (SomeRoute FirmAllR)
|
|||||||
handleFirmCommR :: SomeRoute UniWorX -> Companies -> Handler Html
|
handleFirmCommR :: SomeRoute UniWorX -> Companies -> Handler Html
|
||||||
handleFirmCommR _ [] = invalidArgs ["At least one company name must be provided."]
|
handleFirmCommR _ [] = invalidArgs ["At least one company name must be provided."]
|
||||||
handleFirmCommR ultDest cs = do
|
handleFirmCommR ultDest cs = do
|
||||||
let csKey = CompanyKey <$> cs
|
|
||||||
-- get employees of chosen companies
|
|
||||||
empys <- E.unValue <<$>> runDB (E.select $ do
|
|
||||||
(emp :& uc) <- E.from $ E.table @User `E.innerJoin` E.table @UserCompany `E.on` (\(emp :& uc) -> emp E.^. UserId E.==. uc E.^. UserCompanyUser)
|
|
||||||
E.where_ $ uc E.^. UserCompanyCompany `E.in_` E.valList csKey
|
|
||||||
return $ emp E.^. UserId
|
|
||||||
)
|
|
||||||
-- get supervisors of employees
|
|
||||||
sprs <- E.unValue <<$>> runDB (E.select $ do
|
|
||||||
spr <- E.from $ E.table @User
|
|
||||||
E.where_ $ E.exists $ do
|
|
||||||
usrSpr <- E.from $ E.table @UserSupervisor
|
|
||||||
E.where_ $ usrSpr E.^. UserSupervisorSupervisor E.==. spr E.^. UserId
|
|
||||||
E.&&. usrSpr E.^. UserSupervisorUser `E.in_` E.valList empys
|
|
||||||
return $ spr E.^. UserId
|
|
||||||
)
|
|
||||||
-- get companies of all supervisors
|
|
||||||
sprCmpys <- E.unValue <<$>> runDB (E.select $ do
|
|
||||||
cmpy <- E.from $ E.table @Company
|
|
||||||
E.where_ $ E.exists $ do
|
|
||||||
usrCmpy <- E.from $ E.table @UserCompany
|
|
||||||
E.where_ $ usrCmpy E.^. UserCompanyCompany E.==. cmpy E.^. CompanyId
|
|
||||||
E.&&. usrCmpy E.^. UserCompanyUser `E.in_` E.valList sprs
|
|
||||||
return $ cmpy E.^.CompanyId
|
|
||||||
)
|
|
||||||
let
|
let
|
||||||
queryLoners :: E.SqlQuery (E.SqlExpr (Entity User)) -- get supervisors without any company affiliation
|
queryGiven :: [UserId] -> E.SqlQuery (E.SqlExpr (Entity User)) -- get users from a list of UserIds
|
||||||
queryLoners = do
|
queryGiven usrs = do
|
||||||
spr <- E.from $ E.table @User
|
usr <- E.from $ E.table @User
|
||||||
E.where_ $ spr E.^. UserId `E.in_` E.valList empys
|
E.where_ $ usr E.^. UserId `E.in_` E.valList usrs
|
||||||
E.&&. E.notExists (do
|
|
||||||
sprCmp <- E.from $ E.table @UserCompany
|
|
||||||
E.where_ $ sprCmp E.^. UserCompanyUser E.==. spr E.^. UserId
|
|
||||||
)
|
|
||||||
return spr
|
|
||||||
|
|
||||||
queryCmpy :: Bool -> CompanyId -> E.SqlQuery (E.SqlExpr (Entity User))
|
|
||||||
queryCmpy sORe acid = do
|
|
||||||
(usr :& uc) <- E.from $ E.table @User `E.innerJoin` E.table @UserCompany `E.on` (\(emp :& uc) -> emp E.^. UserId E.==. uc E.^. UserCompanyUser)
|
|
||||||
E.where_ $ uc E.^. UserCompanyCompany E.==. E.val acid
|
|
||||||
E.&&. (if sORe
|
|
||||||
then -- supervisors only
|
|
||||||
E.exists $ do
|
|
||||||
usrSpr <- E.from $ E.table @UserSupervisor
|
|
||||||
E.where_ $ usrSpr E.^. UserSupervisorSupervisor E.==. usr E.^. UserId
|
|
||||||
E.&&. usrSpr E.^. UserSupervisorUser `E.in_` E.valList empys
|
|
||||||
else E.true
|
|
||||||
)
|
|
||||||
return usr
|
return usr
|
||||||
|
mkCompanyUsrList :: [(E.Value (Maybe CompanyId), E.Value UserId)] -> Map.Map (Maybe CompanyId) [UserId]
|
||||||
|
mkCompanyUsrList l = Map.fromAscListWith (++) [(c,[u]) | (E.Value c, E.Value u) <- l]
|
||||||
|
toGrp = maybe RGFirmIndependent (RGFirmSupervisor . unCompanyKey)
|
||||||
|
csKeys = CompanyKey <$> cs
|
||||||
|
mbUser <- maybeAuthId
|
||||||
|
-- get employees of chosen companies
|
||||||
|
empys <- mkCompanyUsrList <$> runDB (E.select $ do
|
||||||
|
(emp :& cmp) <- E.from $ E.table @User `E.innerJoin` E.table @UserCompany `E.on` (\(emp :& cmp) -> emp E.^. UserId E.==. cmp E.^. UserCompanyUser)
|
||||||
|
E.where_ $ cmp E.^. UserCompanyCompany `E.in_` E.valList csKeys
|
||||||
|
E.orderBy [E.ascNullsFirst $ cmp E.^. UserCompanyCompany]
|
||||||
|
return (E.just $ cmp E.^. UserCompanyCompany, emp E.^. UserId)
|
||||||
|
)
|
||||||
|
-- get supervisors of employees
|
||||||
|
sprs <- mkCompanyUsrList <$> runDB (E.select $ do
|
||||||
|
(spr :& cmp) <- E.from $ E.table @User `E.leftJoin` E.table @UserCompany `E.on` (\(spr :& cmp) -> spr E.^. UserId E.=?. cmp E.?. UserCompanyUser)
|
||||||
|
E.where_ $ (E.isTrue (cmp E.?. UserCompanySupervisor) E.&&. cmp E.?. UserCompanyCompany `E.in_` E.justValList csKeys)
|
||||||
|
E.||. (spr E.^. UserId E.=?. E.val mbUser)
|
||||||
|
E.||. E.exists (do
|
||||||
|
usrSpr <- E.from $ E.table @UserSupervisor
|
||||||
|
E.where_ $ usrSpr E.^. UserSupervisorSupervisor E.==. spr E.^. UserId
|
||||||
|
E.&&. usrSpr E.^. UserSupervisorUser `E.in_` E.valList (concat $ Map.elems empys)
|
||||||
|
)
|
||||||
|
E.orderBy [E.ascNullsFirst $ cmp E.?. UserCompanyCompany]
|
||||||
|
return (cmp E.?. UserCompanyCompany, spr E.^. UserId)
|
||||||
|
)
|
||||||
|
|
||||||
commR CommunicationRoute
|
commR CommunicationRoute
|
||||||
{ crHeading = SomeMessage $ case cs of { [c] -> MsgFirmNotification c ; _ -> MsgFirmsNotification }
|
{ crHeading = SomeMessage $ case cs of { [c] -> MsgFirmNotification c ; _ -> MsgFirmsNotification }
|
||||||
, crTitle = SomeMessage $ case cs of { [c] -> MsgFirmNotificationTitle c ; _ -> MsgFirmsNotificationTitle }
|
, crTitle = SomeMessage $ case cs of { [c] -> MsgFirmNotificationTitle c ; _ -> MsgFirmsNotificationTitle }
|
||||||
@ -1062,10 +1101,9 @@ handleFirmCommR ultDest cs = do
|
|||||||
, crJobs = crJobsFirmCommunication cs -- :: Communication -> ConduitT () Job (YesodDB UniWorX) ()
|
, crJobs = crJobsFirmCommunication cs -- :: Communication -> ConduitT () Job (YesodDB UniWorX) ()
|
||||||
, crTestJobs = crTestFirmCommunication cs -- :: Communication -> ConduitT () Job (YesodDB UniWorX) ()
|
, crTestJobs = crTestFirmCommunication cs -- :: Communication -> ConduitT () Job (YesodDB UniWorX) ()
|
||||||
, crRecipientAuth = Nothing -- :: Maybe (UserId -> DB AuthResult) -- an optional filter passed to guardAuthResult
|
, crRecipientAuth = Nothing -- :: Maybe (UserId -> DB AuthResult) -- an optional filter passed to guardAuthResult
|
||||||
, crRecipients = -- :: [(RecipientGroup, SqlQuery (SqlExpr (Entity User)))]
|
, crRecipients = -- :: [(RecipientGroup, SqlQuery (SqlExpr (Entity User)))]
|
||||||
[(RGFirmSupervisor $ unCompanyKey acid, queryCmpy True acid) | acid <- sprCmpys ] ++
|
[(toGrp acid, queryGiven usrs) | (acid, usrs) <- Map.toAscList sprs ] ++
|
||||||
(RGFirmIndependent, queryLoners) :
|
[(RGFirmEmployees $ unCompanyKey acid, queryGiven usrs) | (Just acid, usrs) <- Map.toAscList empys ]
|
||||||
[(RGFirmEmployees $ unCompanyKey acid, queryCmpy False acid) | acid <- csKey ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{- Auswahlbox für Mitteilung:
|
{- Auswahlbox für Mitteilung:
|
||||||
|
|||||||
@ -139,7 +139,7 @@ commR CommunicationRoute{..} = do
|
|||||||
decrypt' cID = do
|
decrypt' cID = do
|
||||||
uid <- decrypt cID
|
uid <- decrypt cID
|
||||||
whenIsJust crRecipientAuth $ guardAuthResult <=< ($ uid)
|
whenIsJust crRecipientAuth $ guardAuthResult <=< ($ uid)
|
||||||
getEntity uid
|
getEntity uid
|
||||||
cUser <- maybeAuth
|
cUser <- maybeAuth
|
||||||
(chosenRecipients, suggestedRecipients) <- runDB $ (,)
|
(chosenRecipients, suggestedRecipients) <- runDB $ (,)
|
||||||
<$> (maybe id cons cUser . catMaybes <$> (mapM decrypt' =<< lookupGlobalGetParams GetRecipient))
|
<$> (maybe id cons cUser . catMaybes <$> (mapM decrypt' =<< lookupGlobalGetParams GetRecipient))
|
||||||
@ -148,7 +148,8 @@ commR CommunicationRoute{..} = do
|
|||||||
|
|
||||||
MsgRenderer mr <- getMsgRenderer
|
MsgRenderer mr <- getMsgRenderer
|
||||||
mbCurrentRoute <- getCurrentRoute
|
mbCurrentRoute <- getCurrentRoute
|
||||||
|
globalCC <- getsYesod $ view _appCommunicationGlobalCC
|
||||||
|
|
||||||
let
|
let
|
||||||
lookupUser :: UserId -> (UserDisplayName,UserSurname)
|
lookupUser :: UserId -> (UserDisplayName,UserSurname)
|
||||||
lookupUser =
|
lookupUser =
|
||||||
@ -156,7 +157,7 @@ commR CommunicationRoute{..} = do
|
|||||||
usrNames Nothing = ("???","???") -- this case only happens during runFormPost when POST Data is present and no form is display
|
usrNames Nothing = ("???","???") -- this case only happens during runFormPost when POST Data is present and no form is display
|
||||||
usrNames (Just User{userDisplayName, userSurname}) = (userDisplayName, userSurname)
|
usrNames (Just User{userDisplayName, userSurname}) = (userDisplayName, userSurname)
|
||||||
in usrNames . flip Map.lookup usrMap
|
in usrNames . flip Map.lookup usrMap
|
||||||
|
|
||||||
chosenRecipients' = Map.fromList $
|
chosenRecipients' = Map.fromList $
|
||||||
[ ( (BoundedPosition $ RecipientGroup g, pos)
|
[ ( (BoundedPosition $ RecipientGroup g, pos)
|
||||||
, (Right recp, recp `elem` map entityKey chosenRecipients)
|
, (Right recp, recp `elem` map entityKey chosenRecipients)
|
||||||
@ -165,9 +166,12 @@ commR CommunicationRoute{..} = do
|
|||||||
, (pos, recp) <- zip [0..] $ map entityKey recps
|
, (pos, recp) <- zip [0..] $ map entityKey recps
|
||||||
] ++
|
] ++
|
||||||
[ ( (BoundedPosition RecipientCustom, pos)
|
[ ( (BoundedPosition RecipientCustom, pos)
|
||||||
, (Right recp, True)
|
, (recp, True)
|
||||||
)
|
)
|
||||||
| (pos, recp) <- zip [0..] . Set.toList $ Set.fromList (map entityKey chosenRecipients) \\ Set.fromList (concatMap (map entityKey) $ view _2 <$> suggestedRecipients)
|
| (pos, recp) <- zip [0..]
|
||||||
|
( mcons (Left <$> globalCC)
|
||||||
|
(Right <$> Set.toList (Set.fromList (map entityKey chosenRecipients) \\ Set.fromList (concatMap (map entityKey) $ view _2 <$> suggestedRecipients)))
|
||||||
|
)
|
||||||
]
|
]
|
||||||
activeCategories = map RecipientGroup (view _1 <$> suggestedRecipients) `snoc` RecipientCustom
|
activeCategories = map RecipientGroup (view _1 <$> suggestedRecipients) `snoc` RecipientCustom
|
||||||
|
|
||||||
|
|||||||
@ -229,6 +229,16 @@ cellHasUserModal toLink user =
|
|||||||
modal nWdgt (Left $ SomeRoute $ toLink uuid)
|
modal nWdgt (Left $ SomeRoute $ toLink uuid)
|
||||||
in cell lWdgt
|
in cell lWdgt
|
||||||
|
|
||||||
|
-- | like `cellHasUserModal` but with fixed route and showing an edit icon instead
|
||||||
|
cellEditUserModal :: (IsDBTable m c, HasEntity u User) => u -> DBCell m c
|
||||||
|
cellEditUserModal user =
|
||||||
|
let userEntity = user ^. hasEntityUser
|
||||||
|
uid = userEntity ^. _entityKey
|
||||||
|
nWdgt = toWidget $ icon IconUserEdit
|
||||||
|
lWdgt = do
|
||||||
|
uuid <- liftHandler $ encrypt uid
|
||||||
|
modal nWdgt (Left $ SomeRoute $ ForProfileR uuid)
|
||||||
|
in cell lWdgt
|
||||||
cellHasMatrikelnummer :: (IsDBTable m a, HasUser u) => u -> DBCell m a
|
cellHasMatrikelnummer :: (IsDBTable m a, HasUser u) => u -> DBCell m a
|
||||||
cellHasMatrikelnummer = maybe mempty textCell . view _userMatrikelnummer
|
cellHasMatrikelnummer = maybe mempty textCell . view _userMatrikelnummer
|
||||||
|
|
||||||
|
|||||||
@ -245,6 +245,7 @@ data AppSettings = AppSettings
|
|||||||
, appJobMaxFlush :: Maybe Natural
|
, appJobMaxFlush :: Maybe Natural
|
||||||
|
|
||||||
, appCommunicationAttachmentsMaxSize :: Maybe Natural
|
, appCommunicationAttachmentsMaxSize :: Maybe Natural
|
||||||
|
, appCommunicationGlobalCC :: Maybe UserEmail
|
||||||
|
|
||||||
, appFileChunkingParams :: FastCDCParameters
|
, appFileChunkingParams :: FastCDCParameters
|
||||||
|
|
||||||
@ -804,6 +805,7 @@ instance FromJSON AppSettings where
|
|||||||
appJobMaxFlush <- o .:? "job-max-flush"
|
appJobMaxFlush <- o .:? "job-max-flush"
|
||||||
|
|
||||||
appCommunicationAttachmentsMaxSize <- o .:? "communication-attachments-max-size"
|
appCommunicationAttachmentsMaxSize <- o .:? "communication-attachments-max-size"
|
||||||
|
appCommunicationGlobalCC <- o .:? "communication-global-cc"
|
||||||
|
|
||||||
appLegalExternal <- o .: "legal-external"
|
appLegalExternal <- o .: "legal-external"
|
||||||
|
|
||||||
|
|||||||
@ -771,6 +771,9 @@ pattern NonEmpty :: forall a. a -> [a] -> NonEmpty a
|
|||||||
pattern NonEmpty x xs = x :| xs
|
pattern NonEmpty x xs = x :| xs
|
||||||
{-# COMPLETE NonEmpty #-}
|
{-# COMPLETE NonEmpty #-}
|
||||||
|
|
||||||
|
checkAsc :: Ord a => [a] -> Bool
|
||||||
|
checkAsc (x:r@(y:_)) = x<=y && checkAsc r
|
||||||
|
checkAsc _ = True
|
||||||
|
|
||||||
----------
|
----------
|
||||||
-- Sets --
|
-- Sets --
|
||||||
|
|||||||
@ -317,6 +317,7 @@ data FormIdentifier
|
|||||||
| FIDBtnAvsRevokeUnknown
|
| FIDBtnAvsRevokeUnknown
|
||||||
| FIDHijackUser
|
| FIDHijackUser
|
||||||
| FIDAddSupervisor
|
| FIDAddSupervisor
|
||||||
|
| FIDFirmUserChangeRequest
|
||||||
deriving (Eq, Ord, Read, Show)
|
deriving (Eq, Ord, Read, Show)
|
||||||
|
|
||||||
instance PathPiece FormIdentifier where
|
instance PathPiece FormIdentifier where
|
||||||
|
|||||||
@ -116,6 +116,7 @@ data Icon
|
|||||||
| IconUnlocked
|
| IconUnlocked
|
||||||
| IconResetTries -- also see IconReset
|
| IconResetTries -- also see IconReset
|
||||||
| IconCompany
|
| IconCompany
|
||||||
|
| IconUserEdit
|
||||||
|
|
||||||
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic)
|
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic)
|
||||||
deriving anyclass (Universe, Finite, NFData)
|
deriving anyclass (Universe, Finite, NFData)
|
||||||
@ -209,7 +210,8 @@ iconText = \case
|
|||||||
IconLocked -> "lock"
|
IconLocked -> "lock"
|
||||||
IconUnlocked -> "lock-open-alt"
|
IconUnlocked -> "lock-open-alt"
|
||||||
IconResetTries -> "trash-undo"
|
IconResetTries -> "trash-undo"
|
||||||
IconCompany -> "building"
|
IconCompany -> "building"
|
||||||
|
IconUserEdit -> "user-edit"
|
||||||
|
|
||||||
nullaryPathPiece ''Icon $ camelToPathPiece' 1
|
nullaryPathPiece ''Icon $ camelToPathPiece' 1
|
||||||
deriveLift ''Icon
|
deriveLift ''Icon
|
||||||
|
|||||||
@ -65,4 +65,7 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later
|
|||||||
<h2>
|
<h2>
|
||||||
_{MsgFirmAssociates}
|
_{MsgFirmAssociates}
|
||||||
<p>
|
<p>
|
||||||
^{fusrTable}
|
^{fusrTable}
|
||||||
|
|
||||||
|
<section>
|
||||||
|
^{fucrForm}
|
||||||
Reference in New Issue
Block a user