diff --git a/models/users.model b/models/users.model index 657669910..740de8186 100644 --- a/models/users.model +++ b/models/users.model @@ -58,8 +58,9 @@ StudyFeatures -- multiple entries possible for students pursuing several degree superField StudyTermsId Maybe type StudyFieldType -- Major or minor, i.e. Haupt-/Nebenfach semester Int - updated UTCTime default=now() -- last update from LDAP - valid Bool default=true -- marked as active in LDAP (students may switch, but LDAP never forgets) + firstObserved UTCTime Maybe + lastObserved UTCTime default=now() -- last update from LDAP + valid Bool default=true UniqueStudyFeatures user degree field type semester deriving Eq Show -- UniqueUserSubject ubuser degree field -- There exists a counterexample diff --git a/src/Foundation/Yesod/Auth.hs b/src/Foundation/Yesod/Auth.hs index 66941c9f6..8be3e80b9 100644 --- a/src/Foundation/Yesod/Auth.hs +++ b/src/Foundation/Yesod/Auth.hs @@ -321,7 +321,7 @@ upsertCampusUser plugin ldapData = do , Just defType <- studyTermsDefaultType -> do $logDebugS "Campus" [st|Applying default for standalone study term “#{tshow subterm}”|] - (:) (StudyFeatures userId defDegree subterm Nothing defType subSemester now True) <$> assimilateSubTerms subterms unusedFeats + (:) (StudyFeatures userId defDegree subterm Nothing defType subSemester (Just now) now True) <$> assimilateSubTerms subterms unusedFeats Nothing | [] <- unusedFeats -> do $logDebugS "Campus" [st|Saw subterm “#{tshow subterm}” when no fos-terms remain|] @@ -389,26 +389,11 @@ upsertCampusUser plugin ldapData = do forM_ fs $ \f@StudyFeatures{..} -> do insertMaybe studyFeaturesDegree $ StudyDegree (unStudyDegreeKey studyFeaturesDegree) Nothing Nothing insertMaybe studyFeaturesField $ StudyTerms (unStudyTermsKey studyFeaturesField) Nothing Nothing Nothing Nothing - oldFs <- selectKeysList - [ StudyFeaturesUser ==. studyFeaturesUser - , StudyFeaturesDegree ==. studyFeaturesDegree - , StudyFeaturesField ==. studyFeaturesField - , StudyFeaturesType ==. studyFeaturesType - , StudyFeaturesSemester ==. studyFeaturesSemester - ] - [] - case oldFs of - [oldF] -> update oldF - [ StudyFeaturesUpdated =. now - , StudyFeaturesValid =. True - , StudyFeaturesField =. studyFeaturesField - , StudyFeaturesSuperField =. studyFeaturesSuperField - ] - _other -> void $ upsert f - [ StudyFeaturesUpdated =. now - , StudyFeaturesValid =. True - , StudyFeaturesSuperField =. studyFeaturesSuperField - ] + void $ upsert f + [ StudyFeaturesLastObserved =. now + , StudyFeaturesValid =. True + , StudyFeaturesSuperField =. studyFeaturesSuperField + ] associateUserSchoolsByTerms userId let diff --git a/src/Handler/Utils/StudyFeatures.hs b/src/Handler/Utils/StudyFeatures.hs index 52d59082f..80d7d1681 100644 --- a/src/Handler/Utils/StudyFeatures.hs +++ b/src/Handler/Utils/StudyFeatures.hs @@ -24,7 +24,7 @@ parseSubTermsSemester = parse (pLMUTermsSemester <* eof) (unpack key) pStudyFeatures :: UserId -> UTCTime -> Parser [StudyFeatures] -pStudyFeatures studyFeaturesUser studyFeaturesUpdated = do +pStudyFeatures studyFeaturesUser now = do studyFeaturesDegree <- StudyDegreeKey' <$> pKey void $ string "$$" @@ -41,6 +41,8 @@ pStudyFeatures studyFeaturesUser studyFeaturesUpdated = do studyFeaturesSemester <- decimal let studyFeaturesValid = True studyFeaturesSuperField = Nothing + studyFeaturesFirstObserved = Just now + studyFeaturesLastObserved = now return StudyFeatures{..} pStudyFeature `sepBy1` char '#' diff --git a/src/Model/Migration.hs b/src/Model/Migration.hs index 5ebd46b6f..6b74de437 100644 --- a/src/Model/Migration.hs +++ b/src/Model/Migration.hs @@ -913,6 +913,14 @@ customMigrations = Map.fromListWith (>>) insert_ CronLastExec{ cronLastExecJob = toJSON $ JobQueueNotification NotificationAllocationUnratedApplications{..}, .. } ) + , ( AppliedMigrationKey [migrationVersion|39.0.0|] [version|40.0.0|] + , whenM (tableExists "study_features") $ do + [executeQQ| + ALTER TABLE study_features RENAME updated TO last_observed; + ALTER TABLE study_features ADD COLUMN first_observed timestamp with time zone; + UPDATE study_features SET first_observed = (SELECT MAX(last_observed) FROM study_features as other WHERE other."user" = study_features."user" AND other.degree = study_features.degree AND other.field = study_features.field AND other.type = study_features.type AND other.semester = study_features.semester - 1); + |] + ) ] diff --git a/templates/course/user/profile.hamlet b/templates/course/user/profile.hamlet index 20b3417e0..2b375a22d 100644 --- a/templates/course/user/profile.hamlet +++ b/templates/course/user/profile.hamlet @@ -44,14 +44,18 @@ $newline never _{MsgStudyFeatureAge} _{MsgStudyFeatureValid} _{MsgStudyFeatureUpdate} - $forall ((Entity _ StudyFeatures{studyFeaturesType, studyFeaturesSemester, studyFeaturesValid, studyFeaturesUpdated}), (Entity _ degree), (Entity _ field)) <- studies + $forall ((Entity _ StudyFeatures{studyFeaturesType, studyFeaturesSemester, studyFeaturesValid, studyFeaturesFirstObserved, studyFeaturesLastObserved}), (Entity _ degree), (Entity _ field)) <- studies _{field} _{degree} _{studyFeaturesType} #{studyFeaturesSemester} #{hasTickmark studyFeaturesValid} - ^{formatTimeW SelFormatDate studyFeaturesUpdated} + + $maybe fObs <- studyFeaturesFirstObserved + ^{formatTimeRangeW SelFormatDate fObs $ Just studyFeaturesLastObserved} + $nothing + ^{formatTimeW SelFormatDate studyFeaturesLastObserved} $maybe _ <- mRegistration
_{MsgCourseStudyFeature}
^{regFieldWidget} diff --git a/templates/profileData.hamlet b/templates/profileData.hamlet index fe327abe3..231082dbc 100644 --- a/templates/profileData.hamlet +++ b/templates/profileData.hamlet @@ -43,14 +43,18 @@ $newline never _{MsgStudyFeatureValid} _{MsgStudyFeatureUpdate} - $forall ((Entity _ StudyFeatures{studyFeaturesType, studyFeaturesSemester, studyFeaturesValid, studyFeaturesUpdated}), (Entity _ degree), (Entity _ field)) <- studies + $forall ((Entity _ StudyFeatures{studyFeaturesType, studyFeaturesSemester, studyFeaturesValid, studyFeaturesFirstObserved, studyFeaturesLastObserved}), (Entity _ degree), (Entity _ field)) <- studies _{field} _{degree} _{studyFeaturesType} #{studyFeaturesSemester} #{hasTickmark studyFeaturesValid} - ^{formatTimeW SelFormatDateTime studyFeaturesUpdated} + + $maybe fObs <- studyFeaturesFirstObserved + ^{formatTimeRangeW SelFormatDateTime fObs $ Just studyFeaturesLastObserved} + $nothing + ^{formatTimeW SelFormatDateTime studyFeaturesLastObserved}
$if hasRows