diff --git a/domene/src/main/java/no/nav/foreldrepenger/los/avdelingsleder/AvdelingslederSaksbehandlerTjeneste.java b/domene/src/main/java/no/nav/foreldrepenger/los/avdelingsleder/AvdelingslederSaksbehandlerTjeneste.java index 906027e12..ec58717b7 100644 --- a/domene/src/main/java/no/nav/foreldrepenger/los/avdelingsleder/AvdelingslederSaksbehandlerTjeneste.java +++ b/domene/src/main/java/no/nav/foreldrepenger/los/avdelingsleder/AvdelingslederSaksbehandlerTjeneste.java @@ -10,6 +10,7 @@ import no.nav.foreldrepenger.los.organisasjon.Avdeling; import no.nav.foreldrepenger.los.organisasjon.OrganisasjonRepository; import no.nav.foreldrepenger.los.organisasjon.Saksbehandler; +import no.nav.foreldrepenger.los.organisasjon.SaksbehandlerGruppe; import no.nav.vedtak.exception.TekniskException; @ApplicationScoped @@ -37,7 +38,7 @@ public void leggSaksbehandlerTilAvdeling(String saksbehandlerIdent, String avdel .orElseGet(() -> opprettSaksbehandler(saksbehandlerIdent)); var avdeling = hentAvdeling(avdelingEnhet); saksbehandler.leggTilAvdeling(avdeling); - organisasjonRepository.lagre(saksbehandler); + organisasjonRepository.persistFlush(saksbehandler); organisasjonRepository.refresh(avdeling); } @@ -45,7 +46,7 @@ public void fjernSaksbehandlerFraAvdeling(String saksbehandlerIdent, String avde var saksbehandler = organisasjonRepository.hentSaksbehandlerHvisEksisterer(saksbehandlerIdent) .orElseThrow(() -> AvdelingSaksbehandlerTjenesteFeil.finnerIkkeSaksbehandler(saksbehandlerIdent)); saksbehandler.fjernAvdeling(organisasjonRepository.hentAvdelingFraEnhet(avdelingEnhet).orElseThrow()); - organisasjonRepository.lagre(saksbehandler); + organisasjonRepository.persistFlush(saksbehandler); var avdeling = hentAvdeling(avdelingEnhet); var oppgaveFiltreringList = avdeling.getOppgaveFiltrering(); @@ -62,11 +63,40 @@ private Avdeling hentAvdeling(String avdelingEnhet) { private Saksbehandler opprettSaksbehandler(String ident) { var saksbehandler = new Saksbehandler(ident.toUpperCase()); - organisasjonRepository.lagre(saksbehandler); + organisasjonRepository.persistFlush(saksbehandler); return organisasjonRepository.hentSaksbehandlerHvisEksisterer(ident) .orElseThrow(() -> AvdelingSaksbehandlerTjenesteFeil.finnerIkkeSaksbehandler(ident)); } + public List hentAvdelingensSaksbehandlereOgGrupper(String avdelingEnhet) { + return organisasjonRepository.hentSaksbehandlerGrupper(avdelingEnhet); + } + + public void leggSaksbehandlerTilGruppe(String saksbehandlerId, int gruppeId, String avdelingEnhet) { + organisasjonRepository.leggSaksbehandlerTilGruppe(saksbehandlerId, gruppeId, avdelingEnhet); + } + + public void fjernSaksbehandlerFraGruppe(String saksbehandlerId, int gruppeId) { + organisasjonRepository.fjernSaksbehandlerFraGruppe(saksbehandlerId, gruppeId); + } + + public SaksbehandlerGruppe opprettSaksbehandlerGruppe(String avdelingEnhet) { + var gruppe = new SaksbehandlerGruppe(); + var avdeling = hentAvdeling(avdelingEnhet); + gruppe.setGruppeNavn("Ny saksbehandlergruppe"); + gruppe.setAvdeling(avdeling); + organisasjonRepository.persistFlush(gruppe); + return gruppe; + } + + public void endreSaksbehandlerGruppeNavn(long gruppeId, String gruppeNavn) { + organisasjonRepository.updateSaksbehandlerGruppeNavn(gruppeId, gruppeNavn); + } + + public void slettSaksbehandlerGruppe(long gruppeId, String avdelingEnhet) { + organisasjonRepository.slettSaksbehandlerGruppe(gruppeId, avdelingEnhet); + } + private static final class AvdelingSaksbehandlerTjenesteFeil { private static TekniskException finnerIkkeSaksbehandler(String ident) { return new TekniskException("Finner ikke saksbehandler med ident {}", ident); diff --git a/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/OrganisasjonRepository.java b/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/OrganisasjonRepository.java index b30a027dc..bb5853fe2 100644 --- a/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/OrganisasjonRepository.java +++ b/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/OrganisasjonRepository.java @@ -10,6 +10,8 @@ import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; +import no.nav.foreldrepenger.los.felles.BaseEntitet; +import no.nav.vedtak.exception.FunksjonellException; @ApplicationScoped @@ -25,7 +27,7 @@ public OrganisasjonRepository(EntityManager entityManager) { OrganisasjonRepository() { } - public void lagre(Saksbehandler saksbehandler) { + public void persistFlush(T saksbehandler) { entityManager.persist(saksbehandler); entityManager.flush(); } @@ -59,4 +61,56 @@ public List hentAvdelinger() { var listeTypedQuery = entityManager.createQuery("FROM avdeling ", Avdeling.class); return listeTypedQuery.getResultList(); } + + public List hentSaksbehandlerGrupper(String avdelingEnhet) { + return entityManager.createQuery("FROM saksbehandlerGruppe g where g.avdeling.avdelingEnhet = :avdelingEnhet", SaksbehandlerGruppe.class) + .setParameter("avdelingEnhet", avdelingEnhet) + .getResultList(); + } + + public void leggSaksbehandlerTilGruppe(String saksbehandlerId, int gruppeId, String avdelingEnhet) { + var gruppe = entityManager.find(SaksbehandlerGruppe.class, gruppeId); + if (gruppe == null || !gruppe.getAvdeling().getAvdelingEnhet().equals(avdelingEnhet)) { + throw new FunksjonellException("FP-164687", String.format("Fant ikke gruppe %s for avdeling %s", gruppeId, avdelingEnhet), + "Kontroller logisk sammenheng mellom gruppe og enhet"); + } + var saksbehandler = hentSaksbehandlerHvisEksisterer(saksbehandlerId).filter(sb -> sb.getAvdelinger().contains(gruppe.getAvdeling())); + saksbehandler.ifPresentOrElse(sb -> { + gruppe.getSaksbehandlere().add(sb); + entityManager.persist(gruppe); + }, () -> { + throw new FunksjonellException("FP-164687", + String.format("Fant ikke saksbehandler %s tilknyttet avdeling %s", saksbehandlerId, avdelingEnhet), + "Kontroller logisk sammenheng mellom saksbehandler, gruppe og enhet"); + }); + } + + public void fjernSaksbehandlerFraGruppe(String saksbehandlerIdent, int gruppeId) { + var gruppe = entityManager.find(SaksbehandlerGruppe.class, gruppeId); + if (gruppe == null) { + throw new IllegalArgumentException("Fant ikke gruppe"); + } + gruppe.getSaksbehandlere().removeIf(s -> s.getSaksbehandlerIdent().equals(saksbehandlerIdent)); + entityManager.persist(gruppe); + } + + public void updateSaksbehandlerGruppeNavn(long gruppeId, String gruppeNavn) { + entityManager.createQuery("UPDATE saksbehandlerGruppe g SET g.gruppeNavn = :gruppeNavn WHERE g.id = :gruppeId") + .setParameter("gruppeNavn", gruppeNavn) + .setParameter("gruppeId", gruppeId) + .executeUpdate(); + } + + public void slettSaksbehandlerGruppe(long gruppeId, String avdelingEnhet) { + var gruppe = entityManager.find(SaksbehandlerGruppe.class, gruppeId); + if (gruppe == null || !gruppe.getAvdeling().getAvdelingEnhet().equals(avdelingEnhet)) { + throw new FunksjonellException("FP-164687", String.format("Fant ikke gruppe %s for avdeling %s", gruppeId, avdelingEnhet), + "Kontroller logisk sammenheng mellom gruppe og enhet"); + } + gruppe.getSaksbehandlere().clear(); + entityManager.persist(gruppe); + entityManager.createQuery("DELETE FROM saksbehandlerGruppe g WHERE g.id = :gruppeId") + .setParameter("gruppeId", gruppeId) + .executeUpdate(); + } } diff --git a/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/SaksbehandlerGruppe.java b/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/SaksbehandlerGruppe.java new file mode 100644 index 000000000..ff9a68169 --- /dev/null +++ b/domene/src/main/java/no/nav/foreldrepenger/los/organisasjon/SaksbehandlerGruppe.java @@ -0,0 +1,65 @@ +package no.nav.foreldrepenger.los.organisasjon; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import no.nav.foreldrepenger.los.felles.BaseEntitet; + +import java.util.HashSet; +import java.util.Set; + +@Entity(name = "saksbehandlerGruppe") +@Table(name = "SAKSBEHANDLER_GRUPPE") +public class SaksbehandlerGruppe extends BaseEntitet { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GRUPPE") + private Long id; + + @Column(name = "GRUPPE_NAVN") + private String gruppeNavn; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "AVDELING_ID", updatable = false) + private Avdeling avdeling; + + @ManyToMany + @JoinTable(name = "gruppe_tilknytning", joinColumns = @JoinColumn(name = "gruppe_id"), inverseJoinColumns = @JoinColumn(name = "saksbehandler_id")) + private Set saksbehandlere = new HashSet<>(); + + public SaksbehandlerGruppe() { + + } + + public Long getId() { + return id; + } + + public Set getSaksbehandlere() { + return saksbehandlere; + } + + public Avdeling getAvdeling() { + return avdeling; + } + + public void setGruppeNavn(String gruppeNavn) { + this.gruppeNavn = gruppeNavn; + } + + public String getGruppeNavn() { + return gruppeNavn; + } + + public void setAvdeling(Avdeling avdeling) { + this.avdeling = avdeling; + } +} diff --git a/migreringer/src/main/resources/db/migration/defaultDS/2.2/V2.2_05__saksbehandlergrupper.sql b/migreringer/src/main/resources/db/migration/defaultDS/2.2/V2.2_05__saksbehandlergrupper.sql new file mode 100644 index 000000000..d05adde27 --- /dev/null +++ b/migreringer/src/main/resources/db/migration/defaultDS/2.2/V2.2_05__saksbehandlergrupper.sql @@ -0,0 +1,48 @@ +CREATE TABLE SAKSBEHANDLER_GRUPPE +( + ID NUMBER(19) NOT NULL + CONSTRAINT PK_SAKSBEHANDLER_GRUPPE PRIMARY KEY, + GRUPPE_NAVN VARCHAR2(255 char) NOT NULL, + AVDELING_ID NUMBER(19) NOT NULL + CONSTRAINT FK_SAKSBEHANDLER_GRUPPE_AVDELING_01 REFERENCES AVDELING (ID), + VERSJON NUMBER(19) default 0 not null, + OPPRETTET_AV VARCHAR2(20 char) default 'VL' not null, + OPPRETTET_TID TIMESTAMP(3) default systimestamp not null, + ENDRET_AV VARCHAR2(20 char), + ENDRET_TID TIMESTAMP(3) +); + +CREATE INDEX IDX_SAKSBEHANDLER_GRUPPE_1 + on SAKSBEHANDLER_GRUPPE (AVDELING_ID); + +COMMENT ON TABLE SAKSBEHANDLER_GRUPPE IS 'Tabell som holder informasjon om grupper'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.ID IS 'Gruppe ID'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.GRUPPE_NAVN IS 'Gruppenavn'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.AVDELING_ID IS 'Referanse til avdeling som gruppen tilhører'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.VERSJON IS 'angir versjon for optimistisk låsing hvor aktuelt'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.OPPRETTET_AV IS 'Bruker som opprettet raden'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.OPPRETTET_TID IS 'Tidspunkt for opprettelse'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.ENDRET_AV IS 'Endret av'; +COMMENT ON column SAKSBEHANDLER_GRUPPE.ENDRET_TID IS 'Timestamp endring'; + + +CREATE TABLE GRUPPE_TILKNYTNING +( + SAKSBEHANDLER_ID NUMBER(19) NOT NULL + CONSTRAINT FK_GRUPPE_TILKNYTNING_SAKSBEHANDLER_01 REFERENCES SAKSBEHANDLER (ID), + GRUPPE_ID NUMBER(19) NOT NULL + CONSTRAINT FK_GRUPPE_TILKNYTNING_SAKSBEHANDLER_GRUPPE_01 REFERENCES SAKSBEHANDLER_GRUPPE (ID), + CONSTRAINT PK_GRUPPE_TILKNYTNING PRIMARY KEY (SAKSBEHANDLER_ID, GRUPPE_ID) +); + +CREATE SEQUENCE SEQ_GRUPPE START WITH 1000 INCREMENT BY 50 NOCACHE; + +CREATE INDEX IDX_GRUPPE_TILKNYTNING_1 + on GRUPPE_TILKNYTNING (SAKSBEHANDLER_ID); + +CREATE INDEX IDX_GRUPPE_TILKNYTNING_2 + on GRUPPE_TILKNYTNING (GRUPPE_ID); + +COMMENT ON TABLE GRUPPE_TILKNYTNING IS 'Jointabell som holder koblinger mellom saksbehandlere og gruppe'; +COMMENT ON column GRUPPE_TILKNYTNING.SAKSBEHANDLER_ID IS 'Saksbehandler ID'; +COMMENT ON column GRUPPE_TILKNYTNING.GRUPPE_ID IS 'Gruppe ID'; diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/dto/SaksbehandlerOgGruppeDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/dto/SaksbehandlerOgGruppeDto.java new file mode 100644 index 000000000..9106d73e5 --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/dto/SaksbehandlerOgGruppeDto.java @@ -0,0 +1,20 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksliste.FplosAbacAttributtType; +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerBrukerIdentDto; +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.AbacDto; + +public record SaksbehandlerOgGruppeDto(@NotNull @Valid SaksbehandlerBrukerIdentDto brukerIdent, + @NotNull @Valid AvdelingEnhetDto avdelingEnhet, + @Min(1) @Max(Integer.MAX_VALUE) int gruppeId) implements AbacDto { + + @Override + public AbacDataAttributter abacAttributter() { + return AbacDataAttributter.opprett().leggTil(FplosAbacAttributtType.OPPGAVESTYRING_ENHET, avdelingEnhet.getAvdelingEnhet()); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjeneste.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjeneste.java index d1ae165b0..0f6678eeb 100644 --- a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjeneste.java +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjeneste.java @@ -20,6 +20,7 @@ import no.nav.foreldrepenger.los.avdelingsleder.AvdelingslederSaksbehandlerTjeneste; import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.AvdelingEnhetDto; import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.SaksbehandlerOgAvdelingDto; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.SaksbehandlerOgGruppeDto; import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerBrukerIdentDto; import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerDtoTjeneste; import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerMedAvdelingerDto; @@ -58,6 +59,64 @@ public List hentAvdelingensSaksbehandlere(@NotNul .toList(); } + @GET + @Path("/grupper") + @Operation(description = "Avdelingsliste saksbehandlere og grupper") + @BeskyttetRessurs(actionType = ActionType.READ, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET, sporingslogg = false) + public SaksbehandlereOgSaksbehandlerGrupper hentSaksbehandlerGrupper(@NotNull @QueryParam("avdelingEnhet") @Valid AvdelingEnhetDto avdelingEnhetDto) { + var avdelingensSaksbehandlere = avdelingslederSaksbehandlerTjeneste.hentAvdelingensSaksbehandlere(avdelingEnhetDto.getAvdelingEnhet()) + .stream() + .map(saksbehandlerDtoTjeneste::lagKjentOgUkjentSaksbehandlerMedAvdelingerDto) + .toList(); + // Litt dobbeltarbeid her i overgangsfase - vi henter saksbehandlere og mapper som før i tillegg til å gjøre samme med gruppene + var saksbehandlereGruppe = avdelingslederSaksbehandlerTjeneste.hentAvdelingensSaksbehandlereOgGrupper(avdelingEnhetDto.getAvdelingEnhet()) + .stream().map(g -> new SaksbehandlerGruppeDto(g.getId(), g.getGruppeNavn(), g.getSaksbehandlere().stream().map(saksbehandlerDtoTjeneste::lagKjentOgUkjentSaksbehandlerMedAvdelingerDto).toList())).toList(); + return new SaksbehandlereOgSaksbehandlerGrupper(avdelingensSaksbehandlere, saksbehandlereGruppe); + } + + @POST + @Path("/grupper/opprett-gruppe") + @Operation(description = "Oppretter gruppe") + @BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET) + public SaksbehandlerGruppeDto opprettSaksbehandlerGruppe(@Valid AvdelingEnhetDto dto) { + var sbg = avdelingslederSaksbehandlerTjeneste.opprettSaksbehandlerGruppe(dto.getAvdelingEnhet()); + var sb = sbg.getSaksbehandlere().stream() + .map(saksbehandlerDtoTjeneste::lagKjentOgUkjentSaksbehandlerMedAvdelingerDto).toList(); + return new SaksbehandlerGruppeDto(sbg.getId(), sbg.getGruppeNavn(), sb); + } + + @POST + @Path("/grupper/endre-gruppe") + @Operation(description = "Gir nytt navn til gruppe") + @BeskyttetRessurs(actionType = ActionType.UPDATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET) + public void endreSaksbehandlerGruppe(@Valid SaksbehandlerGruppeNavneEndringDto dto) { + avdelingslederSaksbehandlerTjeneste.endreSaksbehandlerGruppeNavn(dto.gruppeId(), dto.gruppeNavn()); + } + + @POST + @Path("/grupper/legg-til-saksbehandler") + @Operation(description = " legger saksbehandler til gruppe") + @BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET) + public void leggSaksbehandlerTilGruppe(@Valid SaksbehandlerOgGruppeDto dto) { + avdelingslederSaksbehandlerTjeneste.leggSaksbehandlerTilGruppe(dto.brukerIdent().getVerdi(), dto.gruppeId(), dto.avdelingEnhet().getAvdelingEnhet()); + } + + @POST + @Path("/grupper/fjern-saksbehandler") + @Operation(description = " fjerner saksbehandler fra gruppe") + @BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET) + public void fjernSaksbehandlerFraGruppe(@Valid SaksbehandlerOgGruppeDto dto) { + avdelingslederSaksbehandlerTjeneste.fjernSaksbehandlerFraGruppe(dto.brukerIdent().getVerdi(), dto.gruppeId()); + } + + @POST + @Path("/grupper/slett-saksbehandlergruppe") + @Operation(description = "sletter saksbehandlergruppe") + @BeskyttetRessurs(actionType = ActionType.DELETE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET) + public void slettSaksbehandlerGruppe(@Valid SaksbehandlerGruppeSletteRequestDto dto) { + avdelingslederSaksbehandlerTjeneste.slettSaksbehandlerGruppe(dto.gruppeId(), dto.avdelingEnhet().getAvdelingEnhet()); + } + @POST @Path("/søk") @Operation(description = "Søk etter saksbehandler", tags = "AvdelingslederSaksbehandlere") diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeDto.java new file mode 100644 index 000000000..2e1fe681c --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeDto.java @@ -0,0 +1,7 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksbehandler; + +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerMedAvdelingerDto; +import java.util.List; + +public record SaksbehandlerGruppeDto(long gruppeId, String gruppeNavn, List saksbehandlere) { +} diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeNavneEndringDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeNavneEndringDto.java new file mode 100644 index 000000000..4e0e51ee4 --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeNavneEndringDto.java @@ -0,0 +1,23 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksbehandler; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.AvdelingEnhetDto; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksliste.FplosAbacAttributtType; +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.AbacDto; +import no.nav.vedtak.util.InputValideringRegex; + +public record SaksbehandlerGruppeNavneEndringDto(@Min(1) @Max(Integer.MAX_VALUE) long gruppeId, + @NotNull @Size(max = 500) @Pattern(regexp = InputValideringRegex.FRITEKST) String gruppeNavn, + @Valid AvdelingEnhetDto avdelingEnhet) implements AbacDto { + + @Override + public AbacDataAttributter abacAttributter() { + return AbacDataAttributter.opprett().leggTil(FplosAbacAttributtType.OPPGAVESTYRING_ENHET, avdelingEnhet.getAvdelingEnhet()); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeSletteRequestDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeSletteRequestDto.java new file mode 100644 index 000000000..1a0ea7dd1 --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlerGruppeSletteRequestDto.java @@ -0,0 +1,18 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksbehandler; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.AvdelingEnhetDto; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksliste.FplosAbacAttributtType; +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.AbacDto; + +public record SaksbehandlerGruppeSletteRequestDto(@Min(1) @Max(Integer.MAX_VALUE) long gruppeId, + @Valid AvdelingEnhetDto avdelingEnhet) implements AbacDto { + + @Override + public AbacDataAttributter abacAttributter() { + return AbacDataAttributter.opprett().leggTil(FplosAbacAttributtType.OPPGAVESTYRING_ENHET, avdelingEnhet.getAvdelingEnhet()); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlereOgSaksbehandlerGrupper.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlereOgSaksbehandlerGrupper.java new file mode 100644 index 000000000..9bc1409df --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/SaksbehandlereOgSaksbehandlerGrupper.java @@ -0,0 +1,8 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksbehandler; + +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerMedAvdelingerDto; + +import java.util.List; + +public record SaksbehandlereOgSaksbehandlerGrupper(List saksbehandlere, List saksbehandlerGrupper) { +} diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerBrukerIdentDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerBrukerIdentDto.java index bd259191b..f70efe5e2 100644 --- a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerBrukerIdentDto.java +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerBrukerIdentDto.java @@ -19,10 +19,9 @@ public class SaksbehandlerBrukerIdentDto implements AbacDto { @NotNull @Size(max = 100) @Pattern(regexp = InputValideringRegex.FRITEKST) - private final String brukerIdent; + private String brukerIdent; public SaksbehandlerBrukerIdentDto() { - brukerIdent = null; // NOSONAR } public SaksbehandlerBrukerIdentDto(String brukerIdent) { diff --git a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerMedAvdelingerDto.java b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerMedAvdelingerDto.java index d4f5091cd..857f08b8f 100644 --- a/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerMedAvdelingerDto.java +++ b/web/src/main/java/no/nav/foreldrepenger/los/web/app/tjenester/felles/dto/SaksbehandlerMedAvdelingerDto.java @@ -9,7 +9,7 @@ public class SaksbehandlerMedAvdelingerDto { private SaksbehandlerDto saksbehandlerDto; private List avdelingsnavn; - SaksbehandlerMedAvdelingerDto(SaksbehandlerDto saksbehandlerDto, List avdelingsnavn) { + public SaksbehandlerMedAvdelingerDto(SaksbehandlerDto saksbehandlerDto, List avdelingsnavn) { this.saksbehandlerDto = saksbehandlerDto; this.avdelingsnavn = avdelingsnavn; } diff --git a/web/src/test/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjenesteTest.java b/web/src/test/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjenesteTest.java new file mode 100644 index 000000000..f516b76fd --- /dev/null +++ b/web/src/test/java/no/nav/foreldrepenger/los/web/app/tjenester/avdelingsleder/saksbehandler/AvdelingslederSaksbehandlerRestTjenesteTest.java @@ -0,0 +1,117 @@ +package no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.saksbehandler; + +import jakarta.persistence.EntityManager; +import no.nav.foreldrepenger.extensions.JpaExtension; + +import no.nav.foreldrepenger.los.avdelingsleder.AvdelingslederSaksbehandlerTjeneste; +import no.nav.foreldrepenger.los.oppgave.OppgaveRepository; +import no.nav.foreldrepenger.los.organisasjon.OrganisasjonRepository; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.AvdelingEnhetDto; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.SaksbehandlerOgAvdelingDto; +import no.nav.foreldrepenger.los.web.app.tjenester.avdelingsleder.dto.SaksbehandlerOgGruppeDto; +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerBrukerIdentDto; +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerDto; +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerDtoTjeneste; + +import no.nav.foreldrepenger.los.web.app.tjenester.felles.dto.SaksbehandlerMedAvdelingerDto; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@ExtendWith(JpaExtension.class) +class AvdelingslederSaksbehandlerRestTjenesteTest { + + private static final AvdelingEnhetDto avdelingDto = new AvdelingEnhetDto("4817"); + private static final SaksbehandlerBrukerIdentDto brukerIdentDto = new SaksbehandlerBrukerIdentDto("Z999999"); + private static final SaksbehandlerDto saksbehandlerDto = new SaksbehandlerDto(brukerIdentDto, "Navn Navnesen"); + private AvdelingslederSaksbehandlerTjeneste avdelingslederSaksbehandlerTjeneste; + @Mock + private SaksbehandlerDtoTjeneste saksbehandlerDtoTjeneste; + + private AvdelingslederSaksbehandlerRestTjeneste restTjeneste; + + @Mock + private OppgaveRepository oppgaveRepository; + private EntityManager entityManager; + + @BeforeEach + public void setUp(EntityManager entityManager) { + this.entityManager = entityManager; + var organisasjonRepository = new OrganisasjonRepository(entityManager); + avdelingslederSaksbehandlerTjeneste = new AvdelingslederSaksbehandlerTjeneste(oppgaveRepository, organisasjonRepository); + restTjeneste = new AvdelingslederSaksbehandlerRestTjeneste(avdelingslederSaksbehandlerTjeneste, saksbehandlerDtoTjeneste); + } + + @Test + void kan_hente_lagrede_grupper() { + var nyGruppe = restTjeneste.opprettSaksbehandlerGruppe(avdelingDto); + var hentetGruppe = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + assertThat(nyGruppe).isNotNull().isInstanceOf(SaksbehandlerGruppeDto.class); + assertThat(hentetGruppe.saksbehandlerGrupper().get(0)).isEqualTo(nyGruppe); + } + + @Test + void kan_slette_gruppe() { + var gruppe = restTjeneste.opprettSaksbehandlerGruppe(avdelingDto); + restTjeneste.slettSaksbehandlerGruppe(new SaksbehandlerGruppeSletteRequestDto((int) gruppe.gruppeId(), avdelingDto)); + var etterSletting = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + assertThat(etterSletting.saksbehandlerGrupper()).hasSize(0); + } + + @Test + void kan_legge_saksbehandlere_til_gruppe() { + setupMockForMappingAvSaksbehandlerDto(); + + var gruppe = restTjeneste.opprettSaksbehandlerGruppe(avdelingDto); + restTjeneste.leggTilNySaksbehandler(new SaksbehandlerOgAvdelingDto(brukerIdentDto, avdelingDto)); + restTjeneste.leggSaksbehandlerTilGruppe(new SaksbehandlerOgGruppeDto(brukerIdentDto, avdelingDto, (int) gruppe.gruppeId())); + var hentetGrupper = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + + assertThat(hentetGrupper.saksbehandlerGrupper()).hasSize(1); + var saksbehandlere = hentetGrupper.saksbehandlerGrupper().get(0).saksbehandlere(); + assertThat(saksbehandlere).hasSize(1); + assertThat(saksbehandlere.get(0).getBrukerIdent()).isEqualTo("Z999999"); + } + + @Test + void kan_fjerne_saksbehandlere_fra_gruppe() { + setupMockForMappingAvSaksbehandlerDto(); + var gruppe = restTjeneste.opprettSaksbehandlerGruppe(avdelingDto); + restTjeneste.leggTilNySaksbehandler(new SaksbehandlerOgAvdelingDto(brukerIdentDto, avdelingDto)); + restTjeneste.leggSaksbehandlerTilGruppe(new SaksbehandlerOgGruppeDto(brukerIdentDto, avdelingDto, (int) gruppe.gruppeId())); + var hentetGrupper = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + assertThat(hentetGrupper.saksbehandlerGrupper().get(0).saksbehandlere()).hasSize(1); + + restTjeneste.fjernSaksbehandlerFraGruppe(new SaksbehandlerOgGruppeDto(brukerIdentDto, avdelingDto, (int) gruppe.gruppeId())); + var etterSletting = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + assertThat(etterSletting.saksbehandlerGrupper().get(0).saksbehandlere()).hasSize(0); + } + + @Test + void kan_gi_grupper_nytt_navn() { + var gruppe = restTjeneste.opprettSaksbehandlerGruppe(avdelingDto); + assertThat(gruppe.gruppeNavn()).isNotEqualTo("Nytt navn"); + restTjeneste.endreSaksbehandlerGruppe(new SaksbehandlerGruppeNavneEndringDto((int) gruppe.gruppeId(), "Nytt navn", avdelingDto)); + entityManager.clear(); // simulerer ny transaksjon + var hentetGrupper = restTjeneste.hentSaksbehandlerGrupper(avdelingDto); + var oppdatertGruppe = hentetGrupper.saksbehandlerGrupper().get(0); + assertThat(oppdatertGruppe.gruppeNavn()).isEqualTo("Nytt navn"); + } + + private void setupMockForMappingAvSaksbehandlerDto() { + when(saksbehandlerDtoTjeneste.lagKjentOgUkjentSaksbehandlerMedAvdelingerDto(argThat(sb -> sb.getSaksbehandlerIdent().equals("Z999999")))) + .thenReturn(new SaksbehandlerMedAvdelingerDto(saksbehandlerDto, singletonList(avdelingDto.getAvdelingEnhet()))); + } + + + +}