From c3a1a6966f05e9c98d47422b8ba03fd88779aabc Mon Sep 17 00:00:00 2001 From: Petter Ekern <43809623+pekern@users.noreply.github.com> Date: Tue, 21 May 2024 14:40:49 +0200 Subject: [PATCH] Feature/pofim 5 (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * POFIM-5: Tjeneste for å hente inntekt siste 3 mnd før startdato * POFIM-5: Tjeneste for å hente inntekt siste 3 mnd før startdato * Inntektskomponentm klient * POFIM-5 Henter inntekt 3 siste måneder for søker gitt organisasjon og startdato. * POFIM-5 Henter inntekt 3 siste måneder for søker gitt organisasjon og startdato. --------- Co-authored-by: anjaaalerud --- pom.xml | 6 +- .../rest/InntektsmeldingDialogRest.java | 29 +++++- .../rest/M\303\245nedsinntektResponsDto.java" | 7 ++ .../inntektskomponent/FinnInntektRequest.java | 6 ++ .../inntektskomponent/InntektTjeneste.java | 99 +++++++++++++++++++ .../InntektskomponentKlient.java | 60 +++++++++++ 6 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 "src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/M\303\245nedsinntektResponsDto.java" create mode 100644 src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/FinnInntektRequest.java create mode 100644 src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektTjeneste.java create mode 100644 src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektskomponentKlient.java diff --git a/pom.xml b/pom.xml index 085dc9e8..2935c32d 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,11 @@ org.glassfish.jersey.media jersey-media-json-jackson - + + no.nav.tjenester + aordningen-inntektsinformasjon-v1 + 1.7 + no.nav.foreldrepenger.felles felles-db diff --git a/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/InntektsmeldingDialogRest.java b/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/InntektsmeldingDialogRest.java index d97e8da7..348d058a 100644 --- a/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/InntektsmeldingDialogRest.java +++ b/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/InntektsmeldingDialogRest.java @@ -13,6 +13,7 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import no.nav.familie.inntektsmelding.integrasjoner.inntektskomponent.InntektTjeneste; import no.nav.familie.inntektsmelding.integrasjoner.organisasjon.OrganisasjonTjeneste; import no.nav.familie.inntektsmelding.integrasjoner.person.AktørId; import no.nav.familie.inntektsmelding.integrasjoner.person.PersonInfo; @@ -20,6 +21,8 @@ import no.nav.familie.inntektsmelding.koder.Ytelsetype; import no.nav.vedtak.sikkerhet.jaxrs.UtenAutentisering; +import java.time.LocalDate; + @Path(InntektsmeldingDialogRest.BASE_PATH) @ApplicationScoped @Transactional @@ -27,14 +30,17 @@ public class InntektsmeldingDialogRest { public static final String BASE_PATH = "/imdialog"; private static final String HENT_PERSONINFO = "/personinfo"; private static final String HENT_ORGANISASJON = "/organisasjon"; + private static final String HENT_INNTEKT = "/inntekt"; private PersonTjeneste personTjeneste; private OrganisasjonTjeneste organisasjonTjeneste; + private InntektTjeneste inntektTjeneste; @Inject - public InntektsmeldingDialogRest(PersonTjeneste personTjeneste, OrganisasjonTjeneste organisasjonTjeneste) { + public InntektsmeldingDialogRest(PersonTjeneste personTjeneste, OrganisasjonTjeneste organisasjonTjeneste, InntektTjeneste inntektTjeneste) { this.personTjeneste = personTjeneste; this.organisasjonTjeneste = organisasjonTjeneste; + this.inntektTjeneste = inntektTjeneste; } InntektsmeldingDialogRest() { @@ -62,7 +68,26 @@ public Response hentPersoninfo(@NotNull @QueryParam("aktorId") @Valid AktørIdDt public Response hentOrganisasjon(@NotNull @Parameter(description = "Organisasjonsnummer") @QueryParam("organisasjonsnummer") @Valid OrganisasjonsnummerDto organisasjonsnummerDto ){ var organisasjon = organisasjonTjeneste.finnOrganisasjon(organisasjonsnummerDto.organisasjonsnummer()); var organisassjonInfoDto = organisasjon.map( o -> new OrganisasjonInfoDto(o.navn(), o.orgnr())); - return organisassjonInfoDto.map(oi -> Response.ok(organisassjonInfoDto).build()).orElse(Response.noContent().build()); } + + @GET + @UtenAutentisering + @Path(HENT_INNTEKT) + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") + @Operation(description = "Henter inntekt siste tre måneder for en aktør", tags = "imdialog") + public Response hentInntekt(@Parameter(description = "Request for å hente inntekt, hvis startdato er null brukes dagens dato") @NotNull InntektsmeldingDialogRest.HentInntektRequestDto hentInntektRequestDto) { + var startdato = hentInntektRequestDto.startdato == null ? LocalDate.now() : hentInntektRequestDto.startdato; + var aktørId = new AktørId(hentInntektRequestDto.aktorId().aktørId()); + var inntekt = inntektTjeneste.hentInntekt(aktørId, startdato, hentInntektRequestDto.organisasjonsnummer().organisasjonsnummer()); + return Response.ok(inntekt.stream() + .map(i -> new MånedsinntektResponsDto(i.måned().atDay(1), i.måned().atEndOfMonth(), i.beløp(), i.organisasjonsnummer())) + .toList()).build(); + } + + protected record HentInntektRequestDto(@NotNull @QueryParam("aktorId") AktørIdDto aktorId, + @NotNull @QueryParam("ytelse") Ytelsetype ytelse, + @NotNull @QueryParam("organisasjonsnummer") @Valid OrganisasjonsnummerDto organisasjonsnummer, + LocalDate startdato){} + } diff --git "a/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/M\303\245nedsinntektResponsDto.java" "b/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/M\303\245nedsinntektResponsDto.java" new file mode 100644 index 00000000..81dfbc04 --- /dev/null +++ "b/src/main/java/no/nav/familie/inntektsmelding/imdialog/rest/M\303\245nedsinntektResponsDto.java" @@ -0,0 +1,7 @@ +package no.nav.familie.inntektsmelding.imdialog.rest; + +import java.math.BigDecimal; +import java.time.LocalDate; + +public record MånedsinntektResponsDto(LocalDate fom, LocalDate tom, BigDecimal beløp, String organisasjonsnummer) { +} diff --git a/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/FinnInntektRequest.java b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/FinnInntektRequest.java new file mode 100644 index 00000000..67de3fd2 --- /dev/null +++ b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/FinnInntektRequest.java @@ -0,0 +1,6 @@ +package no.nav.familie.inntektsmelding.integrasjoner.inntektskomponent; + +import java.time.YearMonth; + +public record FinnInntektRequest(String aktørId, YearMonth fom, YearMonth tom) {} + diff --git a/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektTjeneste.java b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektTjeneste.java new file mode 100644 index 00000000..1cad94a5 --- /dev/null +++ b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektTjeneste.java @@ -0,0 +1,99 @@ +package no.nav.familie.inntektsmelding.integrasjoner.inntektskomponent; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import no.nav.familie.inntektsmelding.integrasjoner.person.AktørId; +import no.nav.tjenester.aordningen.inntektsinformasjon.ArbeidsInntektIdent; +import no.nav.tjenester.aordningen.inntektsinformasjon.inntekt.Inntekt; +import no.nav.tjenester.aordningen.inntektsinformasjon.inntekt.InntektType; +import no.nav.tjenester.aordningen.inntektsinformasjon.response.HentInntektListeBolkResponse; +import no.nav.vedtak.exception.IntegrasjonException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.YearMonth; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@ApplicationScoped +public class InntektTjeneste { + private InntektskomponentKlient inntektskomponentKlient; + + InntektTjeneste() { + // CDI + } + + @Inject + public InntektTjeneste(InntektskomponentKlient inntektskomponentKlient) { + this.inntektskomponentKlient = inntektskomponentKlient; + } + + public List hentInntekt(AktørId aktørId, LocalDate startdato, String organisasjonsnummer) { + var request = lagRequest(aktørId, startdato); + var respons = inntektskomponentKlient.finnInntekt(request); + return oversettRespons(respons, aktørId, organisasjonsnummer); + } + + private List oversettRespons(HentInntektListeBolkResponse response, + AktørId aktørId, + String organisasjonsnummer) { + if (response.getSikkerhetsavvikListe() != null && !response.getSikkerhetsavvikListe().isEmpty()) { + throw new IntegrasjonException("FP-535194", + String.format("Fikk følgende sikkerhetsavvik ved kall til inntektstjenesten: %s.", byggSikkerhetsavvikString(response))); + } + + List inntektListeRespons = response.getArbeidsInntektIdentListe() == null + ? Collections.emptyList() + : response.getArbeidsInntektIdentListe(); + + var inntektPerMånedForBruker = inntektListeRespons.stream() + .filter(a -> a.getIdent().getIdentifikator().equals(aktørId.getId())) + .findFirst() + .map(ArbeidsInntektIdent::getArbeidsInntektMaaned) + .orElse(List.of()); + + List månedsInntektListe = new ArrayList<>(); + + inntektPerMånedForBruker.forEach( inntektMåned -> inntektMåned.getArbeidsInntektInformasjon().getInntektListe().stream() + .filter(inntekt -> InntektType.LOENNSINNTEKT.equals(inntekt.getInntektType()) && organisasjonsnummer.equals(inntekt.getVirksomhet().getIdentifikator())) + .findFirst() + .map(this::mapMånedsInntekt) + .ifPresent(månedsInntektListe::add)); + + return månedsInntektListe; + } + + private Månedsinntekt mapMånedsInntekt(Inntekt månedsInntekt) { + return new Månedsinntekt(månedsInntekt.getUtbetaltIMaaned(), månedsInntekt.getBeloep(), månedsInntekt.getVirksomhet().getIdentifikator()); + } + + public record Månedsinntekt(YearMonth måned, BigDecimal beløp, String organisasjonsnummer) {} + + private FinnInntektRequest lagRequest(AktørId aktørId, LocalDate startdato) { + var fomDato = startdato.minusMonths(3); + var tomDato = startdato.minusMonths(1); + + var fomÅrMåned = YearMonth.of(fomDato.getYear(), fomDato.getMonth()); + var tomÅrMåned = YearMonth.of(tomDato.getYear(), tomDato.getMonth()); + + return new FinnInntektRequest(aktørId.getId(), fomÅrMåned, tomÅrMåned); + } + + private String byggSikkerhetsavvikString(HentInntektListeBolkResponse response) { + var stringBuilder = new StringBuilder(); + var sikkerhetsavvikListe = response.getSikkerhetsavvikListe(); + if (sikkerhetsavvikListe != null && !sikkerhetsavvikListe.isEmpty()) { + stringBuilder.append(sikkerhetsavvikListe.getFirst().getTekst()); + for (int i = 1; i < sikkerhetsavvikListe.size(); i++) { + stringBuilder.append(", "); + stringBuilder.append(sikkerhetsavvikListe.get(i).getTekst()); + } + } + return stringBuilder.toString(); + } + +} diff --git a/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektskomponentKlient.java b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektskomponentKlient.java new file mode 100644 index 00000000..e3a01669 --- /dev/null +++ b/src/main/java/no/nav/familie/inntektsmelding/integrasjoner/inntektskomponent/InntektskomponentKlient.java @@ -0,0 +1,60 @@ +package no.nav.familie.inntektsmelding.integrasjoner.inntektskomponent; + +import jakarta.enterprise.context.ApplicationScoped; +import no.nav.tjenester.aordningen.inntektsinformasjon.Aktoer; +import no.nav.tjenester.aordningen.inntektsinformasjon.request.HentInntektListeBolkRequest; +import no.nav.tjenester.aordningen.inntektsinformasjon.response.HentInntektListeBolkResponse; +import no.nav.vedtak.exception.IntegrasjonException; +import no.nav.vedtak.felles.integrasjon.rest.RestClient; +import no.nav.vedtak.felles.integrasjon.rest.RestClientConfig; +import no.nav.vedtak.felles.integrasjon.rest.RestConfig; +import no.nav.vedtak.felles.integrasjon.rest.RestRequest; +import no.nav.vedtak.felles.integrasjon.rest.TokenFlow; + +import java.time.YearMonth; +import java.util.Collections; + +@ApplicationScoped +@RestClientConfig(tokenConfig = TokenFlow.AZUREAD_CC, endpointProperty = "hentinntektlistebolk.url", endpointDefault = "https://app.adeo.no/inntektskomponenten-ws/rs/api/v1/hentinntektlistebolk", + scopesProperty = "hentinntektlistebolk.scopes", scopesDefault = "api://prod-fss.team-inntekt.inntektskomponenten/.default") +public class InntektskomponentKlient { + private static final YearMonth INNTK_TIDLIGSTE_DATO = YearMonth.of(2015, 7); + + private final RestClient restClient; + private final RestConfig restConfig; + + public InntektskomponentKlient() { + this(RestClient.client()); + } + + public InntektskomponentKlient(RestClient restClient) { + this.restClient = restClient; + this.restConfig = RestConfig.forClient(this.getClass()); + } + + public HentInntektListeBolkResponse finnInntekt(FinnInntektRequest finnInntektRequest) { + var request = lagRequest(finnInntektRequest); + + HentInntektListeBolkResponse response; + try { + response = restClient.send(request, HentInntektListeBolkResponse.class); + } catch (RuntimeException e) { + throw new IntegrasjonException("FP-824246", + "Feil ved kall til inntektstjenesten. Meld til #team_registre og #produksjonshendelser hvis dette skjer over lengre tidsperiode.", e); + } + return response; + } + + private RestRequest lagRequest(FinnInntektRequest finnInntektRequest) { + var request = new HentInntektListeBolkRequest(); + + request.setIdentListe(Collections.singletonList(Aktoer.newAktoerId(finnInntektRequest.aktørId()))); + request.setAinntektsfilter("8-28"); + request.setFormaal("Foreldrepenger"); // Trenger eget formål for K9 + + request.setMaanedFom(finnInntektRequest.fom().isAfter(INNTK_TIDLIGSTE_DATO) ? finnInntektRequest.fom() : INNTK_TIDLIGSTE_DATO); + request.setMaanedTom(finnInntektRequest.tom().isAfter(INNTK_TIDLIGSTE_DATO) ? finnInntektRequest.tom() : INNTK_TIDLIGSTE_DATO); + return RestRequest.newPOSTJson(request, restConfig.endpoint(), restConfig); + } + +}