diff --git a/messages/uniworx/categories/settings/de-de-formal.msg b/messages/uniworx/categories/settings/de-de-formal.msg index 5d5886061..721b8b4ab 100644 --- a/messages/uniworx/categories/settings/de-de-formal.msg +++ b/messages/uniworx/categories/settings/de-de-formal.msg @@ -94,6 +94,7 @@ ProfileNever: Nie ProfileLdapPrimaryKey: LDAP-Primärschlüssel ProfileLastLdapSynchronisation: Letzte LDAP-Synchronisation ProfileLastAvsSynchronisation: Letzte AVS-Synchronisation +ProfileLastAvsSynchError: Letzte AVS-Fehlermeldung NotificationSettingsUpdate: Benachrichtigungs-Einstellungen erfolgreich gespeichert NotificationSettingsHeading displayName@Text: Benachrichtigungs-Einstellungen für #{displayName} diff --git a/messages/uniworx/categories/settings/en-eu.msg b/messages/uniworx/categories/settings/en-eu.msg index ec30510e6..723bba82b 100644 --- a/messages/uniworx/categories/settings/en-eu.msg +++ b/messages/uniworx/categories/settings/en-eu.msg @@ -94,6 +94,7 @@ ProfileNever: Never ProfileLdapPrimaryKey: LDAP primary key ProfileLastLdapSynchronisation: Last LDAP synchronisation ProfileLastAvsSynchronisation: Last AVS synchronisation +ProfileLastAvsSynchError: Last AVS Error NotificationSettingsUpdate: Successfully updated notification settings NotificationSettingsHeading displayName: Notification settings for #{displayName} diff --git a/models/avs.model b/models/avs.model index b9f77cdd7..be0eb89db 100644 --- a/models/avs.model +++ b/models/avs.model @@ -18,6 +18,7 @@ UserAvs user UserId noPerson Int default=0 -- only needed for manual communication with personnel from Ausweisverwaltungsstelle lastSynch UTCTime default=now() + lastSynchError Text Maybe UniqueUserAvsUser user UniqueUserAvsId personId deriving Generic Show diff --git a/src/Handler/Utils/Avs.hs b/src/Handler/Utils/Avs.hs index 6afc21150..386b63a71 100644 --- a/src/Handler/Utils/Avs.hs +++ b/src/Handler/Utils/Avs.hs @@ -418,19 +418,19 @@ upsertAvsUserById api = do $logInfoS "AVS" $ "Creating new user with avsInternalPersonalNo " <> tshow persNo candidates <- selectKeysList [UserCompanyPersonalNumber ==. Just persNo] [] case candidates of - [uid] -> $logInfoS "AVS" "Matching user found, linking." >> insertUniqueEntity (UserAvs api uid avsPersonPersonNo now) + [uid] -> $logInfoS "AVS" "Matching user found, linking." >> insertUniqueEntity (UserAvs api uid avsPersonPersonNo now Nothing) (_:_) -> throwM $ AvsUserAmbiguous api [] -> do upsRes :: Either SomeException (Entity User) <- try $ ldapLookupAndUpsert persNo $logInfoS "AVS" $ "No matching existing user found. Attempted LDAP upsert returned: " <> tshow upsRes case upsRes of - Right Entity{entityKey=uid} -> insertUniqueEntity $ UserAvs api uid avsPersonPersonNo now -- pin/addr are updated in next step anyway + Right Entity{entityKey=uid} -> insertUniqueEntity $ UserAvs api uid avsPersonPersonNo now Nothing -- pin/addr are updated in next step anyway Left err -> do $logWarnS "AVS" $ "AVS user with avsInternalPersonalNo " <> tshow persNo <> " not found in LDAP: " <> tshow err return mbuid -- == Nothing -- user could not be created somehow (Just Entity{ entityKey = uaid }, _) -> do - update uaid [ UserAvsLastSynch =. now ] -- mark as updated early, to prevent failed users to clog the synch + update uaid [ UserAvsLastSynch =. now, UserAvsLastSynchError =. Nothing ] -- mark as updated early, to prevent failed users to clog the synch return mbuid _other -> return mbuid $logInfoS "AVS" $ "upsert prestep result: " <> tshow mbuid <> " --- " <> tshow mbapd @@ -465,7 +465,7 @@ upsertAvsUserById api = do } mbUid <- addNewUser newUsr -- triggers JobSynchroniseLdapUser, JobSendPasswordReset and NotificationUserAutoModeUpdate -- TODO: check if these are failsafe whenIsJust mbUid $ \uid -> runDB $ do - insert_ $ UserAvs avsPersonPersonID uid avsPersonPersonNo now + insert_ $ UserAvs avsPersonPersonID uid avsPersonPersonNo now Nothing forM_ avsPersonPersonCards $ -- save all cards for later comparisons whether an update occurred -- let cs :: Set AvsDataPersonCard = Set.fromList $ catMaybes [pinCard, addrCard] -- forM_ cs $ -- only save used cards for the postal address update detection diff --git a/src/Jobs/Handler/SynchroniseAvs.hs b/src/Jobs/Handler/SynchroniseAvs.hs index 04f698c30..9bb3cd687 100644 --- a/src/Jobs/Handler/SynchroniseAvs.hs +++ b/src/Jobs/Handler/SynchroniseAvs.hs @@ -37,17 +37,23 @@ dispatchJobSynchroniseAvs numIterations epoch iteration pause workJobSynchroniseAvs :: Either AvsPersonId UserId -> Maybe UTCTime -> JobHandler UniWorX workJobSynchroniseAvs eauid pause = JobHandlerException $ do - let uniqKey = either UniqueUserAvsId UniqueUserAvsUser eauid - runDB (getBy uniqKey) >>= \case - Nothing -> return () -- do not create new newers in this background job, only update existing - Just Entity{entityVal=UserAvs{..}} - | maybe False (userAvsLastSynch >=) pause -> return () -- we just updated this one within the given limit - | otherwise -> catch (void $ upsertAvsUserById userAvsPersonId) -- updates UserAvsLastSynch - (\case - AvsInterfaceUnavailable -> return () -- ignore and retry later - AvsUserUnknownByAvs _ -> return () -- ignore for users no longer listed in AVS - otherExc -> throwM otherExc - ) + let uniqKey = either UniqueUserAvsId UniqueUserAvsUser eauid + runDB (getBy uniqKey) >>= \case + Nothing -> return () -- do not create new newers in this background job, only update existing + Just Entity{entityKey=avsKey, entityVal=UserAvs{..} } + | maybe False (userAvsLastSynch >=) pause -> return () -- we just updated this one within the given limit + | otherwise -> catch (void $ upsertAvsUserById userAvsPersonId) -- already updates UserAvsLastSynch + (\exc -> do + now <- liftIO getCurrentTime + let excMsg = tshow exc <> " at " <> tshow now + runDB (update avsKey [UserAvsLastSynchError =. Just excMsg]) + case exc of + AvsInterfaceUnavailable -> return () -- ignore and retry later + AvsUserUnknownByAvs _ -> return () -- ignore for users no longer listed in AVS + otherExc -> throwM otherExc + ) + + dispatchJobSynchroniseAvsId :: AvsPersonId -> Maybe UTCTime -> JobHandler UniWorX dispatchJobSynchroniseAvsId = workJobSynchroniseAvs . Left diff --git a/templates/profileData.hamlet b/templates/profileData.hamlet index 0e0ae1825..b943c9591 100644 --- a/templates/profileData.hamlet +++ b/templates/profileData.hamlet @@ -20,6 +20,11 @@ $# SPDX-License-Identifier: AGPL-3.0-or-later ^{messageTooltip tooltipAvsPersNo}
#{view _userAvsNoPerson avs} + $maybe avsError <- view _userAvsLastSynchError avs +
+ _{MsgProfileLastAvsSynchError} +
+ #{avsError}
_{MsgProfileLastAvsSynchronisation}
diff --git a/test/Database/Fill.hs b/test/Database/Fill.hs index 67780ec37..ab162ea60 100644 --- a/test/Database/Fill.hs +++ b/test/Database/Fill.hs @@ -575,7 +575,7 @@ fillDb = do matrikel <- toMatrikel <$> getRandomRs (0 :: Int, 9 :: Int) manyUsers <- insertMany . getZipList $ manyUser <$> ZipList ((,,) <$> firstNames <*> middlenames <*> surnames) <*> ZipList matrikel matUsers <- selectList [UserMatrikelnummer !=. Nothing] [] - insertMany_ [UserAvs (AvsPersonId n) uid n now | Entity uid User{userMatrikelnummer = fmap readMay -> Just (Just n)} <- matUsers] + insertMany_ [UserAvs (AvsPersonId n) uid n now Nothing | Entity uid User{userMatrikelnummer = fmap readMay -> Just (Just n)} <- matUsers] let tmin = -1 tmax = 2 @@ -681,12 +681,12 @@ fillDb = do void . insert' $ UserSchool uid mi False for_ [jost] $ \uid -> void . insert' $ UserSchool uid avn False - void . insert' $ UserAvs (AvsPersonId 12345678) jost 87654321 (n_day' $ -12) - void . insert' $ UserAvs (AvsPersonId 2) svaupel 2 (n_day' $ -22) - void . insert' $ UserAvs (AvsPersonId 3) gkleen 3 (n_day' $ -32) - void . insert' $ UserAvs (AvsPersonId 4) sbarth 4 now - void . insert' $ UserAvs (AvsPersonId 5) fhamann 5 now - void . insert' $ UserAvs (AvsPersonId 77) tinaTester 77 now + void . insert' $ UserAvs (AvsPersonId 12345678) jost 87654321 (n_day' $ -12) (Just "Some Message here") + void . insert' $ UserAvs (AvsPersonId 2) svaupel 2 (n_day' $ -22) Nothing + void . insert' $ UserAvs (AvsPersonId 3) gkleen 3 (n_day' $ -32) Nothing + void . insert' $ UserAvs (AvsPersonId 4) sbarth 4 now Nothing + void . insert' $ UserAvs (AvsPersonId 5) fhamann 5 now (Just "another message from avs synch") + void . insert' $ UserAvs (AvsPersonId 77) tinaTester 77 now Nothing insert_ $ UserAvsCard (AvsPersonId 12345678) (AvsFullCardNo (AvsCardNo "1234") "4") (AvsDataPersonCard True Nothing Nothing AvsCardColorGelb (Set.fromList ['F']) Nothing Nothing Nothing Nothing (AvsCardNo "1234") "4") now insert_ $ UserAvsCard (AvsPersonId 2) (AvsFullCardNo (AvsCardNo "3344") "1") (AvsDataPersonCard True Nothing Nothing AvsCardColorRot (Set.fromList ['F','R']) Nothing Nothing Nothing Nothing (AvsCardNo "3344") "1") now insert_ $ UserAvsCard (AvsPersonId 3) (AvsFullCardNo (AvsCardNo "7788") "1") (AvsDataPersonCard False Nothing Nothing AvsCardColorRot (Set.fromList ['F','R']) Nothing Nothing Nothing Nothing (AvsCardNo "7788") "1") now