Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slett logikk fargekategori #1586

Merged
merged 8 commits into from
Jun 11, 2024
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package no.nav.pto.veilarbportefolje.arbeidsliste.v2;

import io.vavr.control.Validation;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.QueryParam;
import lombok.extern.slf4j.Slf4j;
import no.nav.common.types.identer.Fnr;
import no.nav.pto.veilarbportefolje.arbeidsliste.*;
Expand Down Expand Up @@ -120,6 +118,8 @@ public Arbeidsliste deleteArbeidsliste(
@RequestBody ArbeidslisteForBrukerRequest arbeidslisteForBrukerRequest,
@RequestParam(value = "slettFargekategori", required = false, defaultValue = "true") Boolean slettFargekategori
) {
NavKontor enhet = brukerService.hentNavKontor(arbeidslisteForBrukerRequest.fnr()).orElse(null);

validerOppfolgingOgBruker(arbeidslisteForBrukerRequest.fnr().get());
validerErVeilederForBruker(arbeidslisteForBrukerRequest.fnr().get());
Fnr gyldigFnr = Fnr.ofValidFnr(arbeidslisteForBrukerRequest.fnr().get());
Expand All @@ -129,9 +129,7 @@ public Arbeidsliste deleteArbeidsliste(
arbeidslisteService.slettArbeidsliste(gyldigFnr, slettFargekategori);
} catch (SlettArbeidslisteException e) {
VeilederId veilederId = AuthUtils.getInnloggetVeilederIdent();
NavKontor enhet = brukerService.hentNavKontor(gyldigFnr).orElse(null);
secureLog.warn("Kunne ikke slette arbeidsliste for fnr: {}, av veileder: {}, på enhet: {}", gyldigFnr.get(), veilederId.toString(), enhet);

throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Kunne ikke slette. Fant ikke arbeidsliste for bruker");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import io.vavr.control.Validation;
import lombok.RequiredArgsConstructor;
import no.nav.common.types.identer.EnhetId;
import no.nav.common.types.identer.Fnr;
import no.nav.pto.veilarbportefolje.auth.AuthService;
import no.nav.pto.veilarbportefolje.auth.AuthUtils;
Expand All @@ -15,7 +16,11 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static no.nav.pto.veilarbportefolje.util.SecureLog.secureLog;
Expand All @@ -33,14 +38,8 @@ public class FargekategoriController {
public ResponseEntity<FargekategoriEntity> hentFargekategoriForBruker(@RequestBody HentFargekategoriRequest request) {
validerRequest(request.fnr);

Optional<NavKontor> brukerEnhet = brukerServiceV2.hentNavKontor(request.fnr);
if (brukerEnhet.isEmpty()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Bruker med oppgitt fnr er ikke under oppfølging");
}

authService.innloggetVeilederHarTilgangTilOppfolging();
authService.innloggetVeilederHarTilgangTilBruker(request.fnr.get());
authService.innloggetVeilederHarTilgangTilEnhet(brukerEnhet.get().toString());

try {
Optional<FargekategoriEntity> kanskjeFargekategori = fargekategoriService.hentFargekategoriForBruker(request);
Expand All @@ -59,27 +58,23 @@ public ResponseEntity<FargekategoriResponse> oppdaterFargekategoriForBruker(@Req
VeilederId innloggetVeileder = AuthUtils.getInnloggetVeilederIdent();
validerRequest(request.fnr);

Optional<NavKontor> brukerEnhet = brukerServiceV2.hentNavKontor(request.fnr);

if (brukerEnhet.isEmpty()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Bruker med oppgitt fnr er ikke under oppfølging");
}
NavKontor navKontorForBruker = brukerServiceV2.hentNavKontor(request.fnr).orElseThrow(() -> new ResponseStatusException(HttpStatus.FORBIDDEN, "Bruker er ikke tilordnet enhet"));

authService.innloggetVeilederHarTilgangTilOppfolging();
authService.innloggetVeilederHarTilgangTilBruker(request.fnr.get());
authService.innloggetVeilederHarTilgangTilEnhet(brukerEnhet.get().toString());
authService.innloggetVeilederHarTilgangTilEnhet(navKontorForBruker.getValue());
Validation<String, Fnr> erVeilederForBrukerValidation = fargekategoriService.erVeilederForBruker(request.fnr.get());

if (erVeilederForBrukerValidation.isInvalid()) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Bruker er ikke tilordnet veileder");
}

try {
Optional<FargekategoriEntity> fargekategoriEntity = fargekategoriService.oppdaterFargekategoriForBruker(request, innloggetVeileder);
Optional<FargekategoriEntity> fargekategoriEntity = fargekategoriService.oppdaterFargekategoriForBruker(request, innloggetVeileder, EnhetId.of(navKontorForBruker.getValue()));

return fargekategoriEntity
.map(fargekategori -> ResponseEntity.ok(new FargekategoriResponse(fargekategori.fnr(), fargekategori.fargekategoriVerdi())))
.orElseGet(() -> ResponseEntity.ok(new FargekategoriResponse(request.fnr(), FargekategoriVerdi.INGEN_KATEGORI)));
.orElseGet(() -> ResponseEntity.ok(new FargekategoriResponse(request.fnr(), FargekategoriVerdi.INGEN_KATEGORI)));
} catch (Exception e) {
String melding = String.format("Klarte ikke å opprette/oppdatere fargekategori med verdi %s for fnr %s", request.fargekategoriVerdi.name(), request.fnr.get());
secureLog.error(melding, e);
Expand All @@ -100,14 +95,27 @@ public ResponseEntity<BatchUpsertResponse> batchoppdaterFargekategoriForBruker(@

BatchUpsertResponse responseEtterAutoriseringssjekk = sjekkVeilederautorisering(responseEtterValidering.data, request.fargekategoriVerdi);
List<Fnr> feilFraValideringOgAutorisering = Stream.concat(responseEtterValidering.errors.stream(), responseEtterAutoriseringssjekk.errors.stream()).toList();
BatchUpsertResponse resultatFraValideringOgAutorisering = new BatchUpsertResponse(responseEtterAutoriseringssjekk.data, feilFraValideringOgAutorisering, request.fargekategoriVerdi);
BatchUpsertResponse resultatFraValideringOgAutorisering = new BatchUpsertResponse(responseEtterAutoriseringssjekk.data, feilFraValideringOgAutorisering, request.fargekategoriVerdi);

if(responseEtterAutoriseringssjekk.data.isEmpty()) {
if (responseEtterAutoriseringssjekk.data.isEmpty()) {
return ResponseEntity.status(403).body(resultatFraValideringOgAutorisering);
}

Set<NavKontor> brukerEnheter = request.fnr.stream()
.map(brukerServiceV2::hentNavKontor)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());

if (brukerEnheter.size() != 1) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Kan ikke oppdatere fargekategori i flere enheter samtidig.");
}

EnhetId enhetId = EnhetId.of(brukerEnheter.iterator().next().getValue());
authService.innloggetVeilederHarTilgangTilEnhet(enhetId.get());

try {
fargekategoriService.batchoppdaterFargekategoriForBruker(request.fargekategoriVerdi, responseEtterAutoriseringssjekk.data, innloggetVeileder);
fargekategoriService.batchoppdaterFargekategoriForBruker(request.fargekategoriVerdi, responseEtterAutoriseringssjekk.data, innloggetVeileder, enhetId);

return ResponseEntity.ok(resultatFraValideringOgAutorisering);

Expand Down Expand Up @@ -144,19 +152,9 @@ private BatchUpsertResponse sjekkVeilederautorisering(List<Fnr> fodselsnumre, Fa

fodselsnumre.forEach(fnr -> {
try {
Optional<NavKontor> brukerEnhet = brukerServiceV2.hentNavKontor(fnr);

/* Vi sjekkar om bruker er under oppfølging i autorisering i staden for i validering
* for å unngå at feilmeldinga avslører om eit fnr er i systemet. (400 bad request vs 403 forbidden) */
boolean brukerErIkkeUnderOppfølging = brukerEnhet.isEmpty();
if (brukerErIkkeUnderOppfølging) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND,
"Bruker med oppgitt fnr er ikke under oppfølging"
);
}

authService.innloggetVeilederHarTilgangTilEnhet(brukerEnhet.get().getValue());

authService.innloggetVeilederHarTilgangTilBruker(fnr.get());

Expand Down Expand Up @@ -195,11 +193,12 @@ public record OppdaterFargekategoriRequest(
}

public record BatchoppdaterFargekategoriRequest(
@JsonProperty(required = true) List<Fnr> fnr,
@JsonProperty(required = true) FargekategoriVerdi fargekategoriVerdi
@JsonProperty(required = true) List<Fnr> fnr,
@JsonProperty(required = true) FargekategoriVerdi fargekategoriVerdi
) {
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public BatchoppdaterFargekategoriRequest {}
public BatchoppdaterFargekategoriRequest {
}
}

public record BatchUpsertResponse(List<Fnr> data, List<Fnr> errors, FargekategoriVerdi fargekategoriVerdi) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.nav.pto.veilarbportefolje.fargekategori;

import lombok.RequiredArgsConstructor;
import no.nav.common.types.identer.EnhetId;
import no.nav.common.types.identer.Fnr;
import no.nav.pto.veilarbportefolje.domene.value.VeilederId;
import no.nav.pto.veilarbportefolje.fargekategori.FargekategoriController.OppdaterFargekategoriRequest;
Expand Down Expand Up @@ -38,14 +39,14 @@ public Optional<FargekategoriEntity> hentFargekategoriForBruker(Fnr fnr) {
}

@Transactional
public FargekategoriEntity upsertFargekateori(OppdaterFargekategoriRequest request, VeilederId sistEndretAv) {
public FargekategoriEntity upsertFargekateori(OppdaterFargekategoriRequest request, VeilederId sistEndretAv, EnhetId enhetId) {
Timestamp sistEndret = toTimestamp(ZonedDateTime.now());

String upsertSql = """
INSERT INTO fargekategori(id, fnr, verdi, sist_endret, sist_endret_av_veilederident)
VALUES (?, ?, ?, ?, ?)
INSERT INTO fargekategori(id, fnr, verdi, sist_endret, sist_endret_av_veilederident, enhet_id)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT (fnr) DO UPDATE
SET verdi=?, sist_endret=?, sist_endret_av_veilederident=?
SET verdi=excluded.verdi, sist_endret=excluded.sist_endret, sist_endret_av_veilederident=excluded.sist_endret_av_veilederident, enhet_id=excluded.enhet_id
""";

jdbcTemplate.update(upsertSql,
Expand All @@ -54,9 +55,7 @@ ON CONFLICT (fnr) DO UPDATE
request.fargekategoriVerdi().name(),
sistEndret,
sistEndretAv.getValue(),
request.fargekategoriVerdi().name(),
sistEndret,
sistEndretAv.getValue());
enhetId.get());

return jdbcTemplate.queryForObject(
"SELECT * FROM fargekategori WHERE fnr=?",
Expand Down Expand Up @@ -87,12 +86,12 @@ public int getBatchSize() {
});
}

public void batchupsertFargekategori(FargekategoriVerdi fargekategoriVerdi, List<Fnr> fnr, VeilederId sisteEndretAv) {
public void batchupsertFargekategori(FargekategoriVerdi fargekategoriVerdi, List<Fnr> fnr, VeilederId sisteEndretAv, EnhetId enhetId) {
String upsertSql = """
INSERT INTO fargekategori(id, fnr, verdi, sist_endret, sist_endret_av_veilederident)
VALUES (?, ?, ?, ?, ?)
INSERT INTO fargekategori(id, fnr, verdi, sist_endret, sist_endret_av_veilederident, enhet_id)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT (fnr) DO UPDATE
SET verdi=?, sist_endret=?, sist_endret_av_veilederident=?
SET verdi=excluded.verdi, sist_endret=excluded.sist_endret, sist_endret_av_veilederident=excluded.sist_endret_av_veilederident
""";

jdbcTemplate.batchUpdate(upsertSql, new BatchPreparedStatementSetter() {
Expand All @@ -103,9 +102,7 @@ public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setString(3, fargekategoriVerdi.name());
ps.setTimestamp(4, toTimestamp(ZonedDateTime.now()));
ps.setString(5, sisteEndretAv.getValue());
ps.setString(6, fargekategoriVerdi.name());
ps.setTimestamp(7, toTimestamp(ZonedDateTime.now()));
ps.setString(8, sisteEndretAv.getValue());
ps.setString(6, enhetId.get());
}

@Override
Expand All @@ -114,4 +111,15 @@ public int getBatchSize() {
}
});
}

public Optional<String> hentNavkontorPaFargekategori(Fnr fnr) {
String hentSql = "SELECT enhet_id FROM fargekategori WHERE fnr=?";

return Optional.ofNullable(queryForObjectOrNull(() ->
jdbcTemplate.queryForObject(
hentSql,
(resultSet, rowNumber) -> resultSet.getString("enhet_id"),
fnr.get())
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import io.vavr.control.Validation;
import lombok.RequiredArgsConstructor;
import no.nav.common.types.identer.AktorId;
import no.nav.common.types.identer.EnhetId;
import no.nav.common.types.identer.Fnr;
import no.nav.pto.veilarbportefolje.auth.AuthUtils;
import no.nav.pto.veilarbportefolje.domene.AktorClient;
import no.nav.pto.veilarbportefolje.domene.value.NavKontor;
import no.nav.pto.veilarbportefolje.domene.value.VeilederId;
import no.nav.pto.veilarbportefolje.fargekategori.FargekategoriController.OppdaterFargekategoriRequest;
import no.nav.pto.veilarbportefolje.opensearch.OpensearchIndexerV2;
Expand Down Expand Up @@ -37,30 +39,30 @@ public Optional<FargekategoriEntity> hentFargekategoriForBruker(FargekategoriCon
return fargekategoriRepository.hentFargekategoriForBruker(request.fnr());
}

public Optional<FargekategoriEntity> oppdaterFargekategoriForBruker(OppdaterFargekategoriRequest request, VeilederId sistEndretAv) {
public Optional<FargekategoriEntity> oppdaterFargekategoriForBruker(OppdaterFargekategoriRequest request, VeilederId sistEndretAv, EnhetId enhetId) {
if (request.fargekategoriVerdi() == FargekategoriVerdi.INGEN_KATEGORI) {
fargekategoriRepository.deleteFargekategori(request.fnr());

slettIOpensearch(request.fnr());

return Optional.empty();
} else {
FargekategoriEntity oppdatertKategori = fargekategoriRepository.upsertFargekateori(request, sistEndretAv);
FargekategoriEntity oppdatertKategori = fargekategoriRepository.upsertFargekateori(request, sistEndretAv, enhetId);

oppdaterIOpensearch(request.fnr(), request.fargekategoriVerdi());

return Optional.of(oppdatertKategori);
}
}

public void batchoppdaterFargekategoriForBruker(FargekategoriVerdi fargekategoriVerdi, List<Fnr> fnr, VeilederId innloggetVeileder) {
public void batchoppdaterFargekategoriForBruker(FargekategoriVerdi fargekategoriVerdi, List<Fnr> fnr, VeilederId innloggetVeileder, EnhetId enhetId) {
if (fargekategoriVerdi == FargekategoriVerdi.INGEN_KATEGORI) {
fargekategoriRepository.batchdeleteFargekategori(fnr);

fnr.forEach(this::slettIOpensearch);

} else {
fargekategoriRepository.batchupsertFargekategori(fargekategoriVerdi, fnr, innloggetVeileder);
fargekategoriRepository.batchupsertFargekategori(fargekategoriVerdi, fnr, innloggetVeileder, enhetId);

fnr.forEach(f -> oppdaterIOpensearch(f, fargekategoriVerdi));
}
Expand Down Expand Up @@ -120,6 +122,32 @@ public Boolean erVeilederForBruker(AktorId aktoerId, VeilederId veilederId) {
.orElse(false);
}

public boolean brukerHarFargekategoriPaForrigeNavkontor(AktorId aktoerId) {
Fnr fnr = pdlIdentRepository.hentFnrForAktivBruker(aktoerId);
Optional<String> navkontorPaFargekategori = fargekategoriRepository.hentNavkontorPaFargekategori(fnr);

if (navkontorPaFargekategori.isEmpty()) {
secureLog.info("Bruker {} har ikke NAV-kontor på fargekategori", aktoerId.toString());
return false;
}

final Optional<String> navKontorForBruker = brukerServiceV2.hentNavKontor(aktoerId).map(NavKontor::getValue);
if (navKontorForBruker.isEmpty()) {
secureLog.error("Kunne ikke hente NAV-kontor for bruker {}", aktoerId.toString());
return false;
}

boolean navkontorForBrukerUlikNavkontorPaFargekategori = !navKontorForBruker.orElseThrow().equals(navkontorPaFargekategori.orElseThrow());

if (navkontorForBrukerUlikNavkontorPaFargekategori) {
secureLog.info("Bruker {} er på kontor {} mens fargekategori er lagret på et annet kontor {}", aktoerId.toString(), navKontorForBruker.get(), navkontorPaFargekategori.get());
} else {
secureLog.info("Bruker {} er på kontor {} og fargekategori er lagret på samme kontor {}", aktoerId.toString(), navKontorForBruker.get(), navkontorPaFargekategori.get());
}

return navkontorForBrukerUlikNavkontorPaFargekategori;
}

private Try<AktorId> hentAktorId(Fnr fnr) {
return Try.of(() -> aktorClient.hentAktorId(fnr));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import no.nav.pto.veilarbportefolje.persononinfo.PdlIdentRepository;
import no.nav.pto.veilarbportefolje.service.BrukerServiceV2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
Expand All @@ -33,9 +34,10 @@ public class HuskelappService {
private final PdlIdentRepository pdlIdentRepository;


@Transactional
public UUID opprettHuskelapp(HuskelappOpprettRequest huskelappOpprettRequest, VeilederId veilederId) {
try {

huskelappRepository.deaktivereAlleHuskelappRaderPaaBruker(huskelappOpprettRequest.brukerFnr());
UUID huskelappId = huskelappRepository.opprettHuskelapp(huskelappOpprettRequest, veilederId);

AktorId aktorId = hentAktorId(huskelappOpprettRequest.brukerFnr()).orElseThrow(RuntimeException::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import no.nav.common.types.identer.AktorId;
import no.nav.common.types.identer.Fnr;
import no.nav.pto.veilarbportefolje.arbeidsliste.ArbeidslisteService;
import no.nav.pto.veilarbportefolje.domene.AktorClient;
import no.nav.pto.veilarbportefolje.domene.value.VeilederId;
import no.nav.pto.veilarbportefolje.fargekategori.FargekategoriService;
import no.nav.pto.veilarbportefolje.huskelapp.HuskelappService;
import no.nav.pto.veilarbportefolje.kafka.KafkaCommonConsumerService;
import no.nav.pto.veilarbportefolje.opensearch.OpensearchIndexerV2;
Expand All @@ -26,8 +26,8 @@ public class VeilederTilordnetService extends KafkaCommonConsumerService<Veilede
private final OppfolgingRepositoryV2 oppfolgingRepositoryV2;
private final ArbeidslisteService arbeidslisteService;
private final HuskelappService huskelappService;
private final FargekategoriService fargekategoriService;
private final OpensearchIndexerV2 opensearchIndexerV2;
private final AktorClient aktorClient;
private final PdlIdentRepository pdlIdentRepository;


Expand Down Expand Up @@ -56,6 +56,11 @@ public void tilordneVeileder(AktorId aktoerId, VeilederId veilederId) {
if (brukerHarByttetNavkontorHuskelapp) {
huskelappService.deaktivereAlleHuskelapperPaaBruker(aktoerId, maybeFnr);
}

final boolean brukerHarByttetNavkontorFargekategori = fargekategoriService.brukerHarFargekategoriPaForrigeNavkontor(aktoerId);
if (brukerHarByttetNavkontorFargekategori) {
fargekategoriService.slettFargekategoriPaaBruker(aktoerId, maybeFnr);
}
}

private void kastErrorHvisBrukerSkalVaereUnderOppfolging(AktorId aktorId, VeilederId veilederId) {
Expand Down
Loading