97 lines
4.4 KiB
Haskell
97 lines
4.4 KiB
Haskell
module Handler.Allocation.Prios
|
|
( getAPriosR, postAPriosR
|
|
) where
|
|
|
|
import Import
|
|
|
|
import Handler.Utils
|
|
import Handler.Utils.Csv
|
|
import Handler.Utils.Allocation
|
|
|
|
import qualified Database.Esqueleto as E
|
|
import qualified Database.Esqueleto.Utils as E
|
|
|
|
import qualified Data.Conduit.List as C
|
|
|
|
import qualified Data.Csv as Csv
|
|
|
|
|
|
data AllocationPrioritiesMode
|
|
= AllocationPrioritiesNumeric
|
|
| AllocationPrioritiesOrdinal
|
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
|
instance Universe AllocationPrioritiesMode
|
|
instance Finite AllocationPrioritiesMode
|
|
|
|
nullaryPathPiece ''AllocationPrioritiesMode $ camelToPathPiece' 2
|
|
|
|
embedRenderMessage ''UniWorX ''AllocationPrioritiesMode id
|
|
|
|
|
|
getAPriosR, postAPriosR :: TermId -> SchoolId -> AllocationShorthand -> Handler Html
|
|
getAPriosR = postAPriosR
|
|
postAPriosR tid ssh ash = do
|
|
doNumericPrios <- runDB $ do
|
|
Entity aId _ <- getBy404 $ TermSchoolAllocationShort tid ssh ash
|
|
|
|
numericPrios <- E.selectCountRows . E.from $ \allocationUser -> do
|
|
E.where_ $ allocationUser E.^. AllocationUserAllocation E.==. E.val aId
|
|
E.where_ . E.maybe E.false sqlAllocationPriorityNumeric $ allocationUser E.^. AllocationUserPriority
|
|
|
|
ordinalPrios <- E.selectCountRows . E.from $ \allocationUser -> do
|
|
E.where_ $ allocationUser E.^. AllocationUserAllocation E.==. E.val aId
|
|
E.where_ . E.maybe E.false (E.not_ . sqlAllocationPriorityNumeric) $ allocationUser E.^. AllocationUserPriority
|
|
let doNumericPrios = ((>=) :: Int64 -> Int64 -> Bool) numericPrios ordinalPrios
|
|
|
|
return doNumericPrios
|
|
|
|
let explainAllocationPrioMode = \case
|
|
AllocationPrioritiesNumeric -> return $(i18nWidgetFile "allocation-priority-explanation/numeric")
|
|
AllocationPrioritiesOrdinal -> return $(i18nWidgetFile "allocation-priority-explanation/ordinal")
|
|
|
|
ignoreWarningMsg <- messageIconI Warning IconMissingAllocationPriority MsgAllocationMissingPrioritiesIgnored
|
|
((priosRes, priosView), priosEnctype) <- runFormPost . renderAForm FormStandard $ (,)
|
|
<$> apopt (explainedSelectionField Nothing (explainOptionList optionsFinite explainAllocationPrioMode)) (fslI MsgAllocationPrioritiesMode) (Just $ bool AllocationPrioritiesOrdinal AllocationPrioritiesNumeric doNumericPrios)
|
|
<* aformMessage ignoreWarningMsg
|
|
<*> areq fileField (fslI MsgAllocationPrioritiesFile) Nothing
|
|
|
|
formResult priosRes $ \(mode, fInfo) -> do
|
|
let sourcePrios = case mode of
|
|
AllocationPrioritiesNumeric -> transPipe liftHandler fInfo .| fileSourceCsvPositional Csv.NoHeader
|
|
AllocationPrioritiesOrdinal -> transPipe liftHandler fInfo .| fileSourceCsvPositional Csv.NoHeader .| C.map Csv.fromOnly .| ordinalPriorities
|
|
|
|
(matrSunk, matrMissing) <- runDB $ do
|
|
Entity aId _ <- getBy404 $ TermSchoolAllocationShort tid ssh ash
|
|
updateWhere
|
|
[ AllocationUserAllocation ==. aId ]
|
|
[ AllocationUserPriority =. Nothing ]
|
|
matrSunk <- runConduit $ sourcePrios .| sinkAllocationPriorities aId
|
|
matrMissing <- E.selectCountRows . E.from $ \allocationUser -> do
|
|
E.where_ $ allocationUser E.^. AllocationUserAllocation E.==. E.val aId
|
|
E.&&. E.isNothing (allocationUser E.^. AllocationUserPriority)
|
|
|
|
E.where_ . E.exists . E.from $ \(courseApplication `E.InnerJoin` allocationCourse) -> do
|
|
E.on $ allocationCourse E.^. AllocationCourseCourse E.==. courseApplication E.^. CourseApplicationCourse
|
|
E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.just (allocationCourse E.^. AllocationCourseAllocation)
|
|
E.where_ $ courseApplication E.^. CourseApplicationUser E.==. allocationUser E.^. AllocationUserUser
|
|
E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.just (E.val aId)
|
|
return (matrSunk, matrMissing)
|
|
|
|
when (matrSunk > 0) $
|
|
addMessageI Success $ MsgAllocationPrioritiesSunk matrSunk
|
|
when (matrMissing > 0) $
|
|
addMessageI Error $ MsgAllocationPrioritiesMissing matrMissing
|
|
redirect $ AllocationR tid ssh ash AUsersR
|
|
|
|
siteLayoutMsg MsgMenuAllocationPriorities $ do
|
|
setTitleI $ MsgAllocationPrioritiesTitle tid ssh ash
|
|
|
|
let priosForm = wrapForm priosView def
|
|
{ formEncoding = priosEnctype
|
|
, formAction = Just . SomeRoute $ AllocationR tid ssh ash APriosR
|
|
}
|
|
gradeScale <- getsYesod $ view _appAllocationGradeScale
|
|
gradeOrdinalProportion <- getsYesod $ view _appAllocationGradeOrdinalProportion
|
|
|
|
$(i18nWidgetFile "allocation-priorities")
|