149 lines
6.4 KiB
Haskell
149 lines
6.4 KiB
Haskell
module Handler.Allocation.EditUser
|
|
( getAEditUserR, postAEditUserR
|
|
, getADelUserR, postADelUserR
|
|
) where
|
|
|
|
import Import
|
|
import Handler.Allocation.Application
|
|
import Handler.Allocation.UserForm
|
|
|
|
import Handler.Utils
|
|
|
|
import qualified Data.Map.Strict as Map
|
|
import qualified Data.Set as Set
|
|
|
|
import qualified Data.Conduit.Combinators as C
|
|
|
|
import Handler.Utils.Delete
|
|
|
|
import qualified Database.Esqueleto as E
|
|
|
|
|
|
getAEditUserR, postAEditUserR :: TermId -> SchoolId -> AllocationShorthand -> CryptoUUIDUser -> Handler Html
|
|
getAEditUserR = postAEditUserR
|
|
postAEditUserR tid ssh ash cID = do
|
|
(Entity _ Allocation{..}, User{..}, (editUserAct, editUserForm, editUserEnctype)) <- runDB $ do
|
|
uid <- decrypt cID
|
|
user <- get404 uid
|
|
alloc@(Entity aId _) <- getBy404 $ TermSchoolAllocationShort tid ssh ash
|
|
Entity auId AllocationUser{..} <- getBy404 $ UniqueAllocationUser aId uid
|
|
|
|
((editUserRes, editUserForm), editUserEnctype) <- runFormPost . renderAForm FormStandard $
|
|
allocationUserForm aId $ Just AllocationUserForm
|
|
{ aauUser = uid
|
|
, aauTotalCourses = allocationUserTotalCourses
|
|
, aauPriority = allocationUserPriority
|
|
, aauApplications = Map.empty -- form collects existing applications itself
|
|
}
|
|
|
|
editUserAct <- formResultMaybe editUserRes $ \AllocationUserForm{..} -> Just <$> do
|
|
now <- liftIO getCurrentTime
|
|
|
|
replace auId AllocationUser
|
|
{ allocationUserAllocation = aId
|
|
, allocationUserUser = aauUser
|
|
, allocationUserTotalCourses = aauTotalCourses
|
|
, allocationUserPriority = aauPriority
|
|
}
|
|
audit $ TransactionAllocationUserEdited aauUser aId
|
|
|
|
oldApps <- selectList [CourseApplicationUser ==. aauUser, CourseApplicationAllocation ==. Just aId] []
|
|
forM_ oldApps $ \(Entity appId CourseApplication{..}) -> do
|
|
deleteWhere [ CourseApplicationFileApplication ==. appId ]
|
|
delete appId
|
|
unless (courseApplicationCourse `Map.member` aauApplications) $
|
|
audit $ TransactionCourseApplicationDeleted courseApplicationCourse courseApplicationUser appId
|
|
|
|
iforM_ aauApplications $ \cId ApplicationForm{..} -> maybeT_ $ do
|
|
prio <- hoistMaybe afPriority
|
|
let rated = afRatingVeto || is _Just afRatingPoints
|
|
appId <- lift $ insert CourseApplication
|
|
{ courseApplicationCourse = cId
|
|
, courseApplicationUser = aauUser
|
|
, courseApplicationText = afText
|
|
, courseApplicationRatingVeto = afRatingVeto
|
|
, courseApplicationRatingPoints = afRatingPoints
|
|
, courseApplicationRatingComment = afRatingComment
|
|
, courseApplicationAllocation = Just aId
|
|
, courseApplicationAllocationPriority = Just prio
|
|
, courseApplicationTime = now
|
|
, courseApplicationRatingTime = guardOn rated now
|
|
}
|
|
lift . runConduit $ transPipe liftHandler (sequence_ afFiles) .| C.mapM_ (insert_ . review _FileReference . (, CourseApplicationFileResidual appId))
|
|
lift . audit $ TransactionCourseApplicationEdit cId aauUser appId
|
|
|
|
return $ do
|
|
addMessageI Success MsgAllocationEditUserUserEdited
|
|
redirect $ AllocationR tid ssh ash AUsersR
|
|
|
|
return (alloc, user, (editUserAct, editUserForm, editUserEnctype))
|
|
|
|
sequence_ editUserAct
|
|
|
|
MsgRenderer mr <- getMsgRenderer
|
|
let title = MsgAllocationEditUserTitle (mr . ShortTermIdentifier $ unTermKey allocationTerm) (unSchoolKey allocationSchool) allocationShorthand userDisplayName
|
|
shortTitle = MsgAllocationEditUserShortTitle allocationTerm allocationSchool allocationShorthand userDisplayName
|
|
|
|
siteLayoutMsg title $ do
|
|
setTitleI shortTitle
|
|
wrapForm editUserForm FormSettings
|
|
{ formMethod = POST
|
|
, formAction = Just . SomeRoute . AllocationR tid ssh ash $ AEditUserR cID
|
|
, formEncoding = editUserEnctype
|
|
, formAttrs = []
|
|
, formSubmit = FormSubmit
|
|
, formAnchor = Nothing :: Maybe Text
|
|
}
|
|
|
|
getADelUserR, postADelUserR :: TermId -> SchoolId -> AllocationShorthand -> CryptoUUIDUser -> Handler Html
|
|
getADelUserR = postADelUserR
|
|
postADelUserR tid ssh ash cID = do
|
|
uid <- decrypt cID
|
|
(aId, auId) <- runDB . maybeT notFound $ do
|
|
aId <- MaybeT . getKeyBy $ TermSchoolAllocationShort tid ssh ash
|
|
auId <- MaybeT . getKeyBy $ UniqueAllocationUser aId uid
|
|
return (aId, auId)
|
|
|
|
deleteR DeleteRoute
|
|
{ drRecords = Set.singleton auId
|
|
, drGetInfo = \(allocationUser `E.InnerJoin` user) -> do
|
|
E.on $ allocationUser E.^. AllocationUserUser E.==. user E.^. UserId
|
|
|
|
let appsCount = E.subSelectCount . E.from $ \courseApplication ->
|
|
E.where_ $ courseApplication E.^. CourseApplicationUser E.==. allocationUser E.^. AllocationUserUser
|
|
E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.just (allocationUser E.^. AllocationUserAllocation)
|
|
allocsCount = E.subSelectCount . E.from $ \courseParticipant ->
|
|
E.where_ $ courseParticipant E.^. CourseParticipantUser E.==. allocationUser E.^. AllocationUserUser
|
|
E.&&. courseParticipant E.^. CourseParticipantAllocated E.==. E.just (allocationUser E.^. AllocationUserAllocation)
|
|
|
|
return ( ( user E.^. UserDisplayName, user E.^. UserSurname )
|
|
, appsCount :: E.SqlExpr (E.Value Word64)
|
|
, allocsCount :: E.SqlExpr (E.Value Word64)
|
|
)
|
|
, drUnjoin = \(allocationUser `E.InnerJoin` _user) -> allocationUser
|
|
, drRenderRecord = \((E.Value dName, E.Value sName), E.Value (assertM' (> 0) -> appsCount), E.Value (assertM' (> 0) -> allocsCount)) -> return
|
|
[whamlet|
|
|
$newline never
|
|
^{nameWidget dName sName}
|
|
$if is _Just appsCount || is _Just allocsCount
|
|
\ (
|
|
$maybe c <- appsCount
|
|
_{MsgAllocationApplicationsCount c}
|
|
$if is _Just appsCount || is _Just allocsCount
|
|
, #
|
|
$maybe c <- appsCount
|
|
_{MsgAllocationAllocationsCount c}
|
|
)
|
|
|]
|
|
, drRecordConfirmString = \((E.Value dName, _), _, _) -> return [st|#{dName}|]
|
|
, drFormMessage = \_ -> return Nothing
|
|
, drCaption = SomeMessage MsgAllocationUserDeleteQuestion
|
|
, drSuccessMessage = SomeMessage MsgAllocationUserDeleted
|
|
, drAbort = SomeRoute . AllocationR tid ssh ash $ AEditUserR cID
|
|
, drSuccess = SomeRoute $ AllocationR tid ssh ash AUsersR
|
|
, drDelete = \_k doDelete -> do
|
|
res <- doDelete
|
|
audit $ TransactionAllocationUserDeleted uid aId
|
|
return res
|
|
}
|