module Handler.Utils.ExamOffice.Exam ( resultIsSynced , examOfficeExamResultAuth ) where import Import.NoFoundation import qualified Database.Esqueleto as E resultIsSynced :: E.SqlExpr (E.Value UserId) -- ^ office -> E.SqlExpr (Entity ExamResult) -> E.SqlExpr (E.Value Bool) resultIsSynced authId examResult = (hasSchool E.&&. allSchools) E.||. (E.not_ hasSchool E.&&. anySync) where anySync = E.exists . E.from $ \synced -> E.where_ $ synced E.^. ExamOfficeResultSyncedResult E.==. examResult E.^. ExamResultId E.&&. synced E.^. ExamOfficeResultSyncedTime E.>=. examResult E.^. ExamResultLastChanged hasSchool = E.exists . E.from $ \userFunction -> E.where_ $ userFunction E.^. UserFunctionUser E.==. authId E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice allSchools = E.not_ . E.exists . E.from $ \userFunction -> do E.where_ $ userFunction E.^. UserFunctionUser E.==. authId E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice E.where_ . E.not_ . E.exists . E.from $ \synced -> E.where_ $ synced E.^. ExamOfficeResultSyncedSchool E.==. E.just (userFunction E.^. UserFunctionSchool) E.&&. synced E.^. ExamOfficeResultSyncedResult E.==. examResult E.^. ExamResultId E.&&. synced E.^. ExamOfficeResultSyncedTime E.>=. examResult E.^. ExamResultLastChanged examOfficeExamResultAuth :: E.SqlExpr (E.Value UserId) -- ^ office -> E.SqlExpr (Entity ExamResult) -> E.SqlExpr (E.Value Bool) examOfficeExamResultAuth authId examResult = authByUser E.||. authByField E.||. authBySchool where authByField = E.exists . E.from $ \(examOfficeField `E.InnerJoin` studyFeatures) -> do E.on $ studyFeatures E.^. StudyFeaturesField E.==. examOfficeField E.^. ExamOfficeFieldField E.where_ $ studyFeatures E.^. StudyFeaturesUser E.==. examResult E.^. ExamResultUser E.&&. examOfficeField E.^. ExamOfficeFieldOffice E.==. authId E.&&. examOfficeField E.^. ExamOfficeFieldField E.==. studyFeatures E.^. StudyFeaturesField E.where_ $ examOfficeField E.^. ExamOfficeFieldForced E.||. E.exists (E.from $ \userFunction -> E.where_ $ userFunction E.^. UserFunctionUser E.==. authId E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice E.&&. E.not_ (E.exists . E.from $ \(course `E.InnerJoin` exam `E.InnerJoin` courseUserExamOfficeOptOut) -> do E.on $ courseUserExamOfficeOptOut E.^. CourseUserExamOfficeOptOutCourse E.==. course E.^. CourseId E.on $ exam E.^. ExamCourse E.==. course E.^. CourseId E.where_ $ exam E.^. ExamId E.==. examResult E.^. ExamResultExam E.where_ $ courseUserExamOfficeOptOut E.^. CourseUserExamOfficeOptOutUser E.==. examResult E.^. ExamResultUser E.&&. courseUserExamOfficeOptOut E.^. CourseUserExamOfficeOptOutSchool E.==. userFunction E.^. UserFunctionSchool ) ) authByUser = E.exists . E.from $ \examOfficeUser -> E.where_ $ examOfficeUser E.^. ExamOfficeUserOffice E.==. authId E.&&. examOfficeUser E.^. ExamOfficeUserUser E.==. examResult E.^. ExamResultUser authBySchool = E.exists . E.from $ \(userFunction `E.InnerJoin` course `E.InnerJoin` exam) -> do E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse E.&&. exam E.^. ExamId E.==. examResult E.^. ExamResultExam E.on $ course E.^. CourseSchool E.==. userFunction E.^. UserFunctionSchool E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice E.where_ $ userFunction E.^. UserFunctionUser E.==. authId