Skip to content

Commit

Permalink
Legger til mulighet for å opprette grupper av saksbehandlere (#2027)
Browse files Browse the repository at this point in the history
  • Loading branch information
dijjal authored Nov 13, 2023
1 parent 74e8bd0 commit cfe9c81
Show file tree
Hide file tree
Showing 14 changed files with 509 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -37,15 +38,15 @@ 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);
}

public void fjernSaksbehandlerFraAvdeling(String saksbehandlerIdent, String avdelingEnhet) {
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();
Expand All @@ -62,11 +63,39 @@ 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<SaksbehandlerGruppe> hentAvdelingensSaksbehandlereOgGrupper(String avdelingEnhet) {
return organisasjonRepository.hentSaksbehandlerGrupper(avdelingEnhet);
}

public void leggSaksbehandlerTilGruppe(String saksbehandlerId, long gruppeId, String avdelingEnhet) {
organisasjonRepository.leggSaksbehandlerTilGruppe(saksbehandlerId, gruppeId, avdelingEnhet);
}

public void fjernSaksbehandlerFraGruppe(String saksbehandlerId, long gruppeId, String avdelingEnhet) {
organisasjonRepository.fjernSaksbehandlerFraGruppe(saksbehandlerId, gruppeId, avdelingEnhet);
}

public SaksbehandlerGruppe opprettSaksbehandlerGruppe(String avdelingEnhet) {
var gruppe = new SaksbehandlerGruppe("Ny saksbehandlergruppe");
var avdeling = hentAvdeling(avdelingEnhet);
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.felles.jpa.TomtResultatException;


@ApplicationScoped
Expand All @@ -25,7 +27,7 @@ public OrganisasjonRepository(EntityManager entityManager) {
OrganisasjonRepository() {
}

public void lagre(Saksbehandler saksbehandler) {
public <T extends BaseEntitet> void persistFlush(T saksbehandler) {
entityManager.persist(saksbehandler);
entityManager.flush();
}
Expand Down Expand Up @@ -59,4 +61,62 @@ public List<Avdeling> hentAvdelinger() {
var listeTypedQuery = entityManager.createQuery("FROM avdeling ", Avdeling.class);
return listeTypedQuery.getResultList();
}

public List<SaksbehandlerGruppe> 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, long gruppeId, String avdelingEnhet) {
var gruppe = entityManager.find(SaksbehandlerGruppe.class, gruppeId);
sjekkGruppeEnhetTilknytning(gruppeId, avdelingEnhet, gruppe);
var saksbehandler = hentSaksbehandlerHvisEksisterer(saksbehandlerId).filter(sb -> sb.getAvdelinger().contains(gruppe.getAvdeling()));
saksbehandler.ifPresentOrElse(sb -> {
gruppe.getSaksbehandlere().add(sb);
entityManager.persist(gruppe);
}, () -> {
throw fantIkkeSaksbehandlerException(saksbehandlerId, avdelingEnhet);
});
}

public void fjernSaksbehandlerFraGruppe(String saksbehandlerIdent, long gruppeId, String avdelingEnhet) {
var gruppe = entityManager.find(SaksbehandlerGruppe.class, gruppeId);
sjekkGruppeEnhetTilknytning(gruppeId, avdelingEnhet, 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);
sjekkGruppeEnhetTilknytning(gruppeId, avdelingEnhet, gruppe);
gruppe.getSaksbehandlere().clear();
entityManager.merge(gruppe);
entityManager.remove(gruppe);
entityManager.flush();
}

private static void sjekkGruppeEnhetTilknytning(long gruppeId, String avdelingEnhet, SaksbehandlerGruppe gruppe) {
if (gruppe == null || !gruppe.getAvdeling().getAvdelingEnhet().equals(avdelingEnhet)) {
throw fantIkkeGruppeException(gruppeId, avdelingEnhet);
}
}

private static TomtResultatException fantIkkeGruppeException(long gruppeId, String avdelingEnhet) {
return new TomtResultatException("FP-164688", String.format("Fant ikke gruppe %s for avdeling %s", gruppeId, avdelingEnhet));
}

private static TomtResultatException fantIkkeSaksbehandlerException(String saksbehandlerIdent, String avdelingEnhet) {
return new TomtResultatException("FP-164689",
String.format("Fant ikke saksbehandler %s tilknyttet avdeling %s", saksbehandlerIdent, avdelingEnhet));
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
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<Saksbehandler> saksbehandlere = new HashSet<>();

SaksbehandlerGruppe() {
// hibernate
}

public SaksbehandlerGruppe(String gruppeNavn) {
this.gruppeNavn = gruppeNavn;
}

public Long getId() {
return id;
}

public Set<Saksbehandler> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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) long gruppeId) implements AbacDto {

@Override
public AbacDataAttributter abacAttributter() {
return AbacDataAttributter.opprett().leggTil(FplosAbacAttributtType.OPPGAVESTYRING_ENHET, avdelingEnhet.getAvdelingEnhet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -82,4 +83,60 @@ public void slettSaksbehandler(@NotNull @Parameter(description = "Brukeridentifi
avdelingslederSaksbehandlerTjeneste.fjernSaksbehandlerFraAvdeling(saksbehandlerOgAvdeling.getBrukerIdent().getVerdi(),
saksbehandlerOgAvdeling.getAvdelingEnhet().getAvdelingEnhet());
}

@GET
@Path("/grupper")
@Operation(description = "Avdelingsliste saksbehandlere og grupper", tags = "AvdelingslederSaksbehandlergrupper")
@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", tags = "AvdelingslederSaksbehandlergrupper")
@BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET)
public SaksbehandlerGruppeDto opprettSaksbehandlerGruppe(@Valid AvdelingEnhetDto dto) {
var sbg = avdelingslederSaksbehandlerTjeneste.opprettSaksbehandlerGruppe(dto.getAvdelingEnhet());
return new SaksbehandlerGruppeDto(sbg.getId(), sbg.getGruppeNavn(), List.of());
}

@POST
@Path("/grupper/endre-gruppe")
@Operation(description = "Gir nytt navn til gruppe", tags = "AvdelingslederSaksbehandlergrupper")
@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", tags = "AvdelingslederSaksbehandlergrupper")
@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", tags = "AvdelingslederSaksbehandlergrupper")
@BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET)
public void fjernSaksbehandlerFraGruppe(@Valid SaksbehandlerOgGruppeDto dto) {
avdelingslederSaksbehandlerTjeneste.fjernSaksbehandlerFraGruppe(dto.brukerIdent().getVerdi(), dto.gruppeId(), dto.avdelingEnhet().getAvdelingEnhet());
}

@POST
@Path("/grupper/slett-saksbehandlergruppe")
@Operation(description = "Sletter saksbehandlergruppe", tags = "AvdelingslederSaksbehandlergrupper")
@BeskyttetRessurs(actionType = ActionType.DELETE, resourceType = ResourceType.OPPGAVESTYRING_AVDELINGENHET)
public void slettSaksbehandlerGruppe(@Valid SaksbehandlerGruppeSletteRequestDto dto) {
avdelingslederSaksbehandlerTjeneste.slettSaksbehandlerGruppe(dto.gruppeId(), dto.avdelingEnhet().getAvdelingEnhet());
}
}
Original file line number Diff line number Diff line change
@@ -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<SaksbehandlerMedAvdelingerDto> saksbehandlere) {
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Loading

0 comments on commit cfe9c81

Please sign in to comment.