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

K1J-449: Use limited statistics when large number of commissions #1141

Merged
merged 8 commits into from
Oct 29, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class CertificateServiceStatisticService {
private final CSIntegrationService csIntegrationService;
private final CSIntegrationRequestFactory csIntegrationRequestFactory;

public void add(UserStatisticsDTO statisticsFromWC, List<String> unitIds, WebCertUser user) {
public void add(UserStatisticsDTO statisticsFromWC, List<String> unitIds, WebCertUser user, boolean maxCommissionsExceeded) {
if (!certificateServiceProfile.active()) {
return;
}
Expand All @@ -59,9 +59,11 @@ public void add(UserStatisticsDTO statisticsFromWC, List<String> unitIds, WebCer
);
}

final var careUnitsWithRelatedSubUnits = getAvailableCareUnitsWithSubUnits(user);
final var unitStatisticsDTO = buildUnitStatisticsFromCS(statisticsFromCS, careUnitsWithRelatedSubUnits);
statisticsFromWC.mergeUnitStatistics(unitStatisticsDTO);
if (!maxCommissionsExceeded) {
final var careUnitsWithRelatedSubUnits = getAvailableCareUnitsWithSubUnits(user.getVardgivare());
final var unitStatisticsDTO = buildUnitStatisticsFromCS(statisticsFromCS, careUnitsWithRelatedSubUnits);
statisticsFromWC.mergeUnitStatistics(unitStatisticsDTO);
}
}

private static Map<String, UnitStatisticsDTO> buildUnitStatisticsFromCS(Map<String, StatisticsForUnitDTO> statisticsFromCS,
Expand Down Expand Up @@ -89,8 +91,8 @@ private static Map<String, UnitStatisticsDTO> buildUnitStatisticsFromCS(Map<Stri
));
}

private static Map<String, List<String>> getAvailableCareUnitsWithSubUnits(WebCertUser user) {
return user.getVardgivare().stream()
private static Map<String, List<String>> getAvailableCareUnitsWithSubUnits(List<Vardgivare> careProviders) {
return careProviders.stream()
.map(Vardgivare::getVardenheter)
.flatMap(List::stream)
.collect(Collectors.toMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,31 @@
*/
package se.inera.intyg.webcert.web.service.facade.list.config;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import se.inera.intyg.infra.integration.hsatk.model.legacy.AbstractVardenhet;
import se.inera.intyg.infra.integration.hsatk.services.legacy.HsaOrganizationsService;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.*;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.CertificateListItemValueType;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.ListColumnType;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.ListConfig;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.ListFilterConfig;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.ListFilterConfigValue;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.ListFilterSelectConfig;
import se.inera.intyg.webcert.web.service.facade.list.config.dto.TableHeading;
import se.inera.intyg.webcert.web.service.facade.list.config.factory.ListFilterConfigFactory;
import se.inera.intyg.webcert.web.service.facade.list.config.factory.TableHeadingFactory;
import se.inera.intyg.webcert.web.service.facade.user.UnitStatisticsDTO;
import se.inera.intyg.webcert.web.service.facade.user.UserStatisticsDTO;
import se.inera.intyg.webcert.web.service.facade.user.UserStatisticsService;
import se.inera.intyg.webcert.web.service.user.WebCertUserService;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ListQuestionsConfigFacadeServiceImpl implements ListVariableConfigFacadeService {

Expand Down Expand Up @@ -210,6 +220,9 @@ private List<ListFilterConfigValue> getUnitList() {

private String getShowAllText(String unitId, UserStatisticsDTO statistics) {
final var unitStatistic = statistics.getUnitStatistics().get(unitId);
if (unitStatistic == null) {
return "Visa alla";
}
final var totalQuestions = unitStatistic.getQuestionsOnUnit() + unitStatistic.getQuestionsOnSubUnits();
return "Visa alla (" + totalQuestions + ")";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class UserStatisticsDTO {

private long totalDraftsAndUnhandledQuestionsOnOtherUnits;

private Map<String, UnitStatisticsDTO> unitStatistics;
private Map<String, UnitStatisticsDTO> unitStatistics = new HashMap<>();

public UserStatisticsDTO() {
}
Expand Down Expand Up @@ -63,10 +63,6 @@ public Map<String, UnitStatisticsDTO> getUnitStatistics() {
}

public void addUnitStatistics(String unitId, UnitStatisticsDTO statistics) {
if (unitStatistics == null) {
unitStatistics = new HashMap<>();
}

unitStatistics.put(unitId, statistics);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import se.inera.intyg.infra.integration.hsatk.model.legacy.Vardenhet;
import se.inera.intyg.infra.integration.hsatk.model.legacy.Vardgivare;
Expand All @@ -40,8 +42,12 @@
import se.inera.intyg.webcert.web.service.utkast.UtkastService;

@Service
@Slf4j
public class UserStatisticsServiceImpl implements UserStatisticsService {

@Value("${max.number.of.commissions.for.statistics:15}")
private Integer maxCommissionsForStatistics;

private static final Logger LOG = LoggerFactory.getLogger(UserStatisticsServiceImpl.class);

private final WebCertUserService webCertUserService;
Expand Down Expand Up @@ -71,12 +77,27 @@ public UserStatisticsDTO getUserStatistics() {
return null;
}

final var unitIds = getUnitIds(user);
final var careUnitIds = getCareUnitIds(user);

if (unitIds == null) {
if (careUnitIds.isEmpty()) {
return null;
}

final var maxCommissionsExceeded = careUnitIds.size() > maxCommissionsForStatistics;

if (maxCommissionsExceeded && user.getValdVardenhet() == null) {
log.info("Number of commissions ({}) exceeds maxCommissionsForStatistics ({}) without selected unit. No statistics will "
+ "be collected.", careUnitIds.size(), maxCommissionsForStatistics);
return null;
}

final var unitIds = maxCommissionsExceeded ? user.getValdVardenhet().getHsaIds() : getUnitIds(user);

if (maxCommissionsExceeded) {
log.info("Number of commissions ({}) exceeds maxCommissionsForStatistics ({}) with selected unit. Statistics will be collected "
+ "for selected care unit only.", careUnitIds.size(), maxCommissionsForStatistics);
}

final var statistics = new UserStatisticsDTO();
final var certificateTypes = getCertificateTypesAllowedForUser(user);
final var questionsMap = getMergedMapOfQuestions(unitIds, certificateTypes);
Expand All @@ -94,8 +115,11 @@ public UserStatisticsDTO getUserStatistics() {
);
}

addCareProviderStatistics(statistics, user.getVardgivare(), draftsMap, questionsMap);
certificateServiceStatisticService.add(statistics, unitIds, user);
if (!maxCommissionsExceeded) {
addCareProviderStatistics(statistics, user.getVardgivare(), draftsMap, questionsMap);
}

certificateServiceStatisticService.add(statistics, unitIds, user, maxCommissionsExceeded);
return statistics;
}

Expand Down Expand Up @@ -193,6 +217,16 @@ private List<String> getUnitIds(WebCertUser user) {
return units;
}

private List<String> getCareUnitIds(WebCertUser user) {
List<String> allIds = new ArrayList<>();
for (Vardgivare v : user.getVardgivare()) {
for (Vardenhet ve : v.getVardenheter()) {
allIds.add(ve.getId());
}
}
return allIds;
}

private Map<String, Long> getMergedMapOfQuestions(List<String> unitIds, Set<String> certificateTypes) {
final var fragaSvarStatsMap = fragaSvarService.getNbrOfUnhandledFragaSvarForCareUnits(unitIds, certificateTypes);
final var arendeStatsMap = arendeService.getNbrOfUnhandledArendenForCareUnits(unitIds, certificateTypes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.doReturn;

import java.util.Collections;
Expand Down Expand Up @@ -69,12 +69,12 @@ class CertificateServiceStatisticServiceTest {
void shallNotAddAnythingIfCertificateServiceProfileIsNotActive() {
final var userStatisticsDTO = new UserStatisticsDTO();
doReturn(false).when(certificateServiceProfile).active();
certificateServiceStatisticService.add(userStatisticsDTO, Collections.emptyList(), user);
certificateServiceStatisticService.add(userStatisticsDTO, Collections.emptyList(), user, false);
assertAll(
() -> assertEquals(0, userStatisticsDTO.getNbrOfDraftsOnSelectedUnit()),
() -> assertEquals(0, userStatisticsDTO.getTotalDraftsAndUnhandledQuestionsOnOtherUnits()),
() -> assertEquals(0, userStatisticsDTO.getNbrOfUnhandledQuestionsOnSelectedUnit()),
() -> assertNull(userStatisticsDTO.getUnitStatistics())
() -> assertTrue(userStatisticsDTO.getUnitStatistics().isEmpty())
);
}

Expand All @@ -98,21 +98,21 @@ void setUp() {
@Test
void shallIncrementNbrOfDraftsOnSelectedUnit() {
final var userStatisticsDTO = buildUserStatisticsDTO();
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user);
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user, false);
assertEquals(2, userStatisticsDTO.getNbrOfDraftsOnSelectedUnit());
}

@Test
void shallIncrementNbrOfUnhandledQuestionsOnSelectedUnit() {
final var userStatisticsDTO = buildUserStatisticsDTO();
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user);
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user, false);
assertEquals(2, userStatisticsDTO.getNbrOfUnhandledQuestionsOnSelectedUnit());
}

@Test
void shallIncrementTotalDraftsAndUnhandledQuestionsOnOtherUnits() {
final var userStatisticsDTO = buildUserStatisticsDTO();
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user);
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user, false);
assertEquals(5, userStatisticsDTO.getTotalDraftsAndUnhandledQuestionsOnOtherUnits());
}
}
Expand All @@ -136,7 +136,7 @@ void shallNotIncrementSubUnitStatisticsIfNoSubUnitIsPresent() {
doReturn(SELECTED_UNIT_IDS).when(user).getIdsOfSelectedVardenhet();

final var userStatisticsDTO = buildUserStatisticsDTO();
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user);
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user, false);
assertAll(
() -> assertEquals(2, userStatisticsDTO.getUnitStatistics().get(UNIT_ID).getDraftsOnUnit()),
() -> assertEquals(1, userStatisticsDTO.getUnitStatistics().get(UNIT_ID).getDraftsOnSubUnits()),
Expand Down Expand Up @@ -166,7 +166,7 @@ void shallMergeUnitStatistics() {
doReturn(SELECTED_UNIT_IDS).when(user).getIdsOfSelectedVardenhet();

final var userStatisticsDTO = buildUserStatisticsDTO();
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user);
certificateServiceStatisticService.add(userStatisticsDTO, UNIT_IDS, user, false);
assertAll(
() -> assertEquals(2, userStatisticsDTO.getUnitStatistics().get(UNIT_ID).getDraftsOnUnit()),
() -> assertEquals(2, userStatisticsDTO.getUnitStatistics().get(UNIT_ID).getDraftsOnSubUnits()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import se.inera.intyg.infra.integration.hsatk.model.legacy.Mottagning;
import se.inera.intyg.infra.integration.hsatk.model.legacy.Vardenhet;
import se.inera.intyg.infra.integration.hsatk.model.legacy.Vardgivare;
Expand All @@ -55,9 +56,10 @@
@ExtendWith(MockitoExtension.class)
class UserStatisticsServiceImplTest {

final static String SELECTED_UNIT_ID = "UNITID";
final static String NOT_SELECTED_UNIT_ID = "NOT_SELECTED_UNIT_ID";
final static String SUB_UNIT_TO_SELECTED = "SUB_UNIT_ID";
static final String SELECTED_UNIT_ID = "UNITID";
static final String NOT_SELECTED_UNIT_ID = "NOT_SELECTED_UNIT_ID";
static final String SUB_UNIT_TO_SELECTED = "SUB_UNIT_ID";

@Mock
private CertificateServiceStatisticService certificateServiceStatisticService;

Expand Down Expand Up @@ -90,10 +92,12 @@ void setUpUser() {
}

void setUpUnit() {
final var unit = new Vardenhet();
unit.setId(SELECTED_UNIT_ID);
final var careProvider = getCareProvider();

doReturn(List.of(careProvider))
.when(user).getVardgivare();

doReturn(unit)
doReturn(careProvider.getVardenheter().get(1))
.when(user)
.getValdVardenhet();

Expand Down Expand Up @@ -176,17 +180,18 @@ class ValuesForSelectedUnit {
@BeforeEach
void setup() {
setUpUser();
setUpUnit();

doReturn(new HashSet<String>())
.when(authoritiesHelper)
.getIntygstyperForPrivilege(any(), any());

map.put(SELECTED_UNIT_ID, expectedValue);
ReflectionTestUtils.setField(userStatisticsService, "maxCommissionsForStatistics", 15);
}

@Test
void shouldReturnNbrOfDraftsForSelectedUnit() {
setUpUnit();
doReturn(map).when(utkastService).getNbrOfUnsignedDraftsByCareUnits(any());

final var result = userStatisticsService.getUserStatistics().getNbrOfDraftsOnSelectedUnit();
Expand All @@ -196,6 +201,7 @@ void shouldReturnNbrOfDraftsForSelectedUnit() {

@Test
void shouldReturnNbrOfQuestionsForSelectedUnit() {
setUpUnit();
doReturn(map).when(arendeService).getNbrOfUnhandledArendenForCareUnits(any(), any());
doReturn(map).when(fragaSvarService).getNbrOfUnhandledFragaSvarForCareUnits(any(), any());

Expand All @@ -205,7 +211,7 @@ void shouldReturnNbrOfQuestionsForSelectedUnit() {
}

@Nested
class CareProviderStatistics {
class CareProviderStatisticsUnlimited {

final Map<String, Long> draftsMap = new HashMap<String, Long>();
final Map<String, Long> questionsMap = new HashMap<String, Long>();
Expand All @@ -229,7 +235,6 @@ void setup() {

doReturn(questionsMap).when(arendeService).getNbrOfUnhandledArendenForCareUnits(any(), any());
doReturn(draftsMap).when(utkastService).getNbrOfUnsignedDraftsByCareUnits(any());

}

@Test
Expand Down Expand Up @@ -339,7 +344,12 @@ void shouldExcludeSubUnitsWithoutUnitId() {
}

@Nested
class totalDraftsAndUnhandledQuestionsOnOtherUnits {
class TotalDraftsAndUnhandledQuestionsOnOtherUnits {

@BeforeEach
void setup() {
setUpUnit();
}

@Test
void shouldReturn0IfOnlySelectedUnitStatisticsInMap() {
Expand Down Expand Up @@ -388,9 +398,10 @@ void shouldReturnNbrOfQuestionsPlusDrafts() {

@Test
void shouldAddStatisticsFromCertificateService() {
setUpUnit();
userStatisticsService.getUserStatistics();
verify(certificateServiceStatisticService).add(any(UserStatisticsDTO.class),
eq(List.of(SELECTED_UNIT_ID, NOT_SELECTED_UNIT_ID, SUB_UNIT_TO_SELECTED)), eq(user));
eq(List.of(SELECTED_UNIT_ID, NOT_SELECTED_UNIT_ID, SUB_UNIT_TO_SELECTED)), eq(user), eq(false));
}
}
}
Loading