ResourceUnitsResponse.java

  1. package no.nav.data.team.resource.dto;

  2. import com.fasterxml.jackson.annotation.JsonInclude;
  3. import com.fasterxml.jackson.annotation.JsonInclude.Include;
  4. import lombok.AllArgsConstructor;
  5. import lombok.Builder;
  6. import lombok.Data;
  7. import lombok.NoArgsConstructor;
  8. import lombok.Singular;
  9. import no.nav.data.common.utils.DateUtil;
  10. import no.nav.data.team.org.OrgUrlId;
  11. import no.nav.data.team.resource.NomClient;
  12. import no.nav.data.team.resource.domain.Resource;
  13. import no.nav.nom.graphql.model.*;
  14. import no.nav.nom.graphql.model.OrgEnhetDto;
  15. import no.nav.nom.graphql.model.OrgEnhetsLederDto;
  16. import no.nav.nom.graphql.model.RessursOrgTilknytningDto;

  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.Optional;
  20. import java.util.function.Function;

  21. import static no.nav.data.common.utils.StreamUtils.convert;
  22. import static no.nav.data.common.utils.StreamUtils.distinctByKey;
  23. import static no.nav.data.common.utils.StreamUtils.safeStream;

  24. @Data
  25. @AllArgsConstructor
  26. @NoArgsConstructor
  27. public class ResourceUnitsResponse {

  28.     private static final String TOP_LEVEL_ID = "0_NAV";
  29.     private static final String IT_AVD_ID = "2_854";

  30.     @Singular
  31.     List<Unit> units;
  32.     @Singular
  33.     List<ResourceResponse> members;

  34.     @Data
  35.     @Builder
  36.     @AllArgsConstructor
  37.     @NoArgsConstructor
  38.     public static class Unit {

  39.         String id;
  40.         String nomid;
  41.         String name;
  42.         String niva;

  43.         @JsonInclude(Include.NON_EMPTY)
  44.         ResourceResponse leader;
  45.         @JsonInclude(Include.NON_EMPTY)
  46.         Unit parentUnit;
  47.     }

  48.     public static ResourceUnitsResponse from(RessursDto nomRessurs, List<String> memberIdents, Function<String, Optional<OrgEnhetDto>> hentOrgEnhet) {
  49.         var units = new ArrayList<Unit>();

  50.         nomRessurs.getOrgTilknytning()
  51.                 .stream()
  52.                 .filter(dto -> DateUtil.isNow(dto.getGyldigFom(), dto.getGyldigTom()))
  53.                 .map(RessursOrgTilknytningDto::getOrgEnhet)
  54.                 .filter(distinctByKey(k -> k.getOrgNiv() + "_" + k.getAgressoId()))
  55.                 .forEach(org -> {
  56.                     var unitBuilder = Unit.builder()
  57.                             .id(org.getAgressoId())
  58.                             .nomid(org.getId())
  59.                             .name(org.getNavn())
  60.                             .niva(org.getOrgNiv());

  61.                     findParentUnit(org.getAgressoId(), org.getOrgNiv(), hentOrgEnhet)
  62.                             .ifPresent(parentUnit ->
  63.                                     unitBuilder.parentUnit(Unit.builder()
  64.                                             .id(parentUnit.id())
  65.                                             .nomid(parentUnit.nomId())
  66.                                             .name(parentUnit.navn())
  67.                                             .niva(parentUnit.niva).build()));

  68.                     org.getLeder().stream().findFirst()
  69.                             .map(OrgEnhetsLederDto::getRessurs)
  70.                             .map(RessursDto::getNavident)
  71.                             .filter(id -> !id.equals(nomRessurs.getNavident()))
  72.                             .or(() -> nomRessurs.getLedere().stream()
  73.                                     .map(RessursLederDto::getRessurs)
  74.                                     .map(RessursDto::getNavident)
  75.                                     .findFirst()
  76.                             )
  77.                             .ifPresent(ident -> unitBuilder.leader(NomClient.getInstance()
  78.                                     .getByNavIdent(ident)
  79.                                     .map(Resource::convertToResponse)
  80.                                     .orElse(null))
  81.                             );

  82.                     units.add(unitBuilder.build());
  83.                 });
  84.         var members = convert(memberIdents, ident -> NomClient.getInstance().getByNavIdent(ident).map(Resource::convertToResponse).orElse(null));
  85.         return new ResourceUnitsResponse(units, members);
  86.     }

  87.     private static Optional<UnitId> findParentUnit(String agressoId, String orgNiv, Function<String, Optional<OrgEnhetDto>> hentOrgEnhet) {

  88.         var tmpIdUrl = new OrgUrlId(orgNiv, agressoId).asUrlIdStr();
  89.         var org = hentOrgEnhet.apply(tmpIdUrl).orElseThrow();
  90.         var trace = new ArrayList<OrgEnhetDto>();
  91.         trace.add(org);

  92.         var parent = firstValid(org.getOrganiseringer(), hentOrgEnhet);
  93.         while (parent != null && !parent.getAgressoId().equals(trace.get(0).getAgressoId()) && !TOP_LEVEL_ID.equals(trace.get(0).getAgressoId())) {
  94.             trace.add(0, parent);
  95.             parent = firstValid(parent.getOrganiseringer(), hentOrgEnhet);
  96.         }
  97.         if (new OrgUrlId(trace.get(0)).asUrlIdStr().equals(TOP_LEVEL_ID)) {
  98.             return Optional.of(switch (trace.size()) {
  99.                 case 1 -> new UnitId(trace.get(0));
  100.                 case 2 -> new UnitId(trace.get(1));
  101.                 default -> {
  102.                     var itAvd = trace.stream().filter(o -> new OrgUrlId(o).asUrlIdStr().equals(IT_AVD_ID)).findFirst();
  103.                     if (itAvd.isPresent()) {
  104.                         // IT should be level=2, and IT-sub level=3, but we can be safe
  105.                         var itAvdIdx = trace.indexOf(itAvd.get());
  106.                         int itAvdSubIdx = itAvdIdx + 1;
  107.                         if (itAvdSubIdx < trace.size()) {
  108.                             yield new UnitId(trace.get(itAvdSubIdx).getAgressoId(), trace.get(itAvdIdx).getNavn() + " - " + trace.get(itAvdSubIdx).getNavn(), trace.get(itAvdSubIdx).getOrgNiv(), trace.get(itAvdSubIdx).getId());
  109.                         }
  110.                     }
  111.                     yield new UnitId(trace.get(2));
  112.                 }
  113.             });
  114.         }
  115.         return Optional.empty();
  116.     }

  117.     private static OrgEnhetDto firstValid(List<OrganiseringDto> organiseringer, Function<String, Optional<OrgEnhetDto>> hentOrgEnhet) {
  118.         return safeStream(organiseringer)
  119.                 .filter(o -> o.getRetning() == RetningDto.over)
  120.                 .filter(dto -> DateUtil.isNow(dto.getGyldigFom(), dto.getGyldigTom()))
  121.                 .findFirst()
  122.                 .map(OrganiseringDto::getOrgEnhet)
  123.                 .map(OrgUrlId::new)
  124.                 .map(OrgUrlId::asUrlIdStr)
  125.                 .flatMap(hentOrgEnhet)
  126.                 .orElse(null);
  127.     }

  128.     private record UnitId(String id, String navn, String niva, String nomId) {

  129.         private UnitId(OrgEnhetDto org) {
  130.             this(org.getAgressoId(), org.getNavn(), org.getOrgNiv(), org.getId());
  131.         }
  132.     }
  133. }