Skip to content

Commit fd9acea

Browse files
modify POST users/{userId}/onboarding
1 parent 6dc4301 commit fd9acea

File tree

9 files changed

+164
-78
lines changed

9 files changed

+164
-78
lines changed

apps/user-ms/src/main/docs/openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@
15591559
},
15601560
"responses" : {
15611561
"200" : {
1562-
"description" : "The user is already a manager for the specified product.",
1562+
"description" : "The user is already onboarded for the specified product.",
15631563
"content" : {
15641564
"application/json" : { }
15651565
}

apps/user-ms/src/main/docs/openapi.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ paths:
11111111
$ref: "#/components/schemas/AddUserRoleDto"
11121112
responses:
11131113
"200":
1114-
description: The user is already a manager for the specified product.
1114+
description: The user is already onboarded for the specified product.
11151115
content:
11161116
application/json: {}
11171117
"201":

apps/user-ms/src/main/java/it/pagopa/selfcare/user/controller/UserController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public Uni<Response> createOrUpdateByUserId(@PathParam("userId") String userId,
314314
@Valid AddUserRoleDto userDto,
315315
@Context SecurityContext ctx) {
316316
return readUserIdFromToken(ctx)
317-
.onItem().transformToUni(loggedUser -> userService.createOrUpdateUserByUserId(userDto, userId, loggedUser))
317+
.onItem().transformToUni(loggedUser -> userService.createOrUpdateUserByUserId(userDto, userId, loggedUser, OnboardedProductState.ACTIVE))
318318
.onItem().ifNotNull().transform(ignore -> Response.status(HttpStatus.SC_CREATED).build())
319319
.onItem().ifNull().continueWith(Response.status(HttpStatus.SC_OK).build());
320320

@@ -327,7 +327,7 @@ public Uni<Response> createOrUpdateByUserId(@PathParam("userId") String userId,
327327
*/
328328
@Operation(description = "Checks if the user is already a manager for the specified product and, if not, creates or updates the user with a new role.", summary = "Check if the user is manager or Update/create a user by userId with a new role")
329329
@APIResponses({
330-
@APIResponse(responseCode = "200", description = "The user is already a manager for the specified product."),
330+
@APIResponse(responseCode = "200", description = "The user is already onboarded for the specified product."),
331331
@APIResponse(responseCode = "201", description = "The user has been created or updated with a new role."),
332332
})
333333
@POST

apps/user-ms/src/main/java/it/pagopa/selfcare/user/mapper/OnboardedProductMapper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import it.pagopa.selfcare.user.controller.request.CreateUserDto;
55
import it.pagopa.selfcare.user.controller.response.OnboardedProductResponse;
66
import it.pagopa.selfcare.user.model.OnboardedProduct;
7+
import it.pagopa.selfcare.user.model.constants.OnboardedProductState;
78
import org.mapstruct.Mapper;
89
import org.mapstruct.Mapping;
910

@@ -23,10 +24,11 @@ public interface OnboardedProductMapper {
2324
@Mapping(target = "productRole", source = "productRole")
2425
OnboardedProduct toNewOnboardedProduct(CreateUserDto.Product product, String productRole);
2526

26-
@Mapping(target = "status", expression = "java(it.pagopa.selfcare.user.model.constants.OnboardedProductState.ACTIVE)")
27+
@Mapping(target = "status", source = "status")
2728
@Mapping(target = "env", expression = "java(it.pagopa.selfcare.onboarding.common.Env.ROOT)")
2829
@Mapping(target = "createdAt", expression = "java(java.time.OffsetDateTime.now())")
2930
@Mapping(target = "updatedAt", expression = "java(java.time.OffsetDateTime.now())")
3031
@Mapping(target = "productRole", source = "productRole")
31-
OnboardedProduct toNewOnboardedProduct(AddUserRoleDto.Product product, String productRole);
32+
OnboardedProduct toNewOnboardedProduct(AddUserRoleDto.Product product, String productRole, OnboardedProductState status);
33+
3234
}

apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public interface UserService {
5050

5151
Uni<CreateOrUpdateUserByFiscalCodeResponse> createOrUpdateUserByFiscalCode(CreateUserDto userDto, LoggedUser loggedUser);
5252

53-
Uni<String> createOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser);
53+
Uni<String> createOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser, OnboardedProductState status);
5454

5555
Uni<String> createUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser);
5656

apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserServiceImpl.java

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -452,28 +452,29 @@ private Uni<CreateOrUpdateUserByFiscalCodeResponse> createUserOnUserRegistryAndU
452452
* Finally, if any operation fails, it logs an error message and returns a Uni that emits a failure.
453453
*/
454454
@Override
455-
public Uni<String> createOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser) {
455+
public Uni<String> createOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser, OnboardedProductState status) {
456456
return userRegistryService.findByIdUsingGET(USERS_FIELD_LIST_WITHOUT_FISCAL_CODE, userId)
457457
.onFailure(UserUtils::isUserNotFoundExceptionOnUserRegistry).retry().atMost(2)
458458
.onFailure(UserUtils::isUserNotFoundExceptionOnUserRegistry).recoverWithUni(throwable -> Uni.createFrom().failure(new ResourceNotFoundException(throwable.getMessage())))
459-
.onItem().transformToUni(userResource -> updateUserInstitutionByUserId(userResource, userDto, loggedUser))
459+
.onItem().transformToUni(userResource -> updateUserInstitutionByUserId(userResource, userDto, loggedUser, status))
460460
.onFailure().invoke(exception -> log.error("Error during retrieve user from userRegistry: {} ", exception.getMessage(), exception));
461461
}
462462

463463
public Uni<String> createUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser) {
464464
var userInstitutionFilters = UserInstitutionFilter.builder().userId(userId).institutionId(userDto.getInstitutionId()).build().constructMap();
465-
var productFilters = OnboardedProductFilter.builder().productId(userDto.getProduct().getProductId()).status(List.of(ACTIVE)).build().constructMap();
465+
var productFilters = OnboardedProductFilter.builder().productId(userDto.getProduct().getProductId()).status(List.of(ACTIVE, SUSPENDED)).build().constructMap();
466466
Map<String, Object> queryParameter = userUtils.retrieveMapForFilter(userInstitutionFilters, productFilters);
467467
return userInstitutionService.retrieveFirstFilteredUserInstitution(queryParameter)
468468
.onItem().transformToUni(userInstitution -> {
469469
if (Optional.ofNullable(userInstitution).isPresent()) {
470470
log.info("User with userId: {} has already onboarded for product {}. Proceeding with check role", userId, userDto.getProduct().getProductId());
471471
PartyRole roleOnProduct = retrieveUserRoleOnProduct(userInstitution, userDto.getProduct().getProductId());
472+
OnboardedProductState currentStatus = retrieveUserStatusOnProduct(userInstitution, userDto.getProduct().getProductId());
472473
return checkAndUpdateUserMail(userInstitution, userDto.getUserMailUuid())
473-
.onItem().transformToUni(ignore -> evaluateRoleAndCreateOrUpdateUserByUserId(userDto, userId, loggedUser, roleOnProduct));
474+
.onItem().transformToUni(ignore -> evaluateRoleAndCreateOrUpdateUserByUserId(userDto, userId, loggedUser, roleOnProduct, currentStatus));
474475
} else {
475476
log.info("User with userId: {} has not onboarded for product {}. Proceeding with create", userId, userDto.getProduct().getProductId());
476-
return createOrUpdateUserByUserId(userDto, userId, loggedUser);
477+
return createOrUpdateUserByUserId(userDto, userId, loggedUser, ACTIVE);
477478
}
478479
})
479480
.onFailure().invoke(exception -> log.error("Error during createOrUpdateManagerByUserId for userId: {}, institutionId: {}: {}", userId, userDto.getInstitutionId(), exception.getMessage(), exception));
@@ -502,23 +503,33 @@ private Uni<UserInstitution> checkAndUpdateUserMail(UserInstitution userInstitut
502503
* we have to delete the old role, and subsequently we create new role for the user on selected product.
503504
* If the new role is equals or higher than the existing role, throw a UserRoleAlreadyPresentException to indicate that we need to keep the old role.
504505
*/
505-
private Uni<String> evaluateRoleAndCreateOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser, PartyRole roleOnProduct) {
506+
private Uni<String> evaluateRoleAndCreateOrUpdateUserByUserId(AddUserRoleDto userDto, String userId, LoggedUser loggedUser, PartyRole roleOnProduct, OnboardedProductState currentStatus) {
506507
PartyRole newRole;
507508
try {
508509
newRole = PartyRole.valueOf(userDto.getProduct().getRole());
509510
} catch (IllegalArgumentException e) {
510511
throw new InvalidRequestException("Invalid role: " + userDto.getProduct().getRole() + ". Allowed value are: " + Arrays.toString(PartyRole.values()));
511512
}
512513
if (Objects.isNull(roleOnProduct)) {
513-
return createOrUpdateUserByUserId(userDto, userId, loggedUser);
514-
} else if (newRole.compareTo(roleOnProduct) < 0) {
515-
log.info("User {}, for product {}, has role {}, which is lower than {}. The old role will be deleted, and the new role will be created.", userId, userDto.getProduct().getProductId(), roleOnProduct, userDto.getProduct().getRole());
516-
return userInstitutionService.updateUserStatusWithOptionalFilterByInstitutionAndProduct(userId, userDto.getInstitutionId(), userDto.getProduct().getProductId(), null, null, DELETED)
517-
.onItem().transformToUni(longValue -> createOrUpdateUserByUserId(userDto, userId, loggedUser));
514+
return createOrUpdateUserByUserId(userDto, userId, loggedUser, ACTIVE);
515+
}
516+
517+
if (newRole == PartyRole.MANAGER) {
518+
if (PartyRole.MANAGER.equals(roleOnProduct)) {
519+
log.info("User {} already has MANAGER role with status {}. No changes needed.", userId, currentStatus);
520+
return Uni.createFrom().failure(new UserRoleAlreadyPresentException(
521+
String.format("User already has MANAGER role with status %s for product [%s].", currentStatus, userDto.getProduct().getProductId())));
522+
} else {
523+
log.info("User {} has role {} with status {}. Replacing with MANAGER role keeping same status.", userId, roleOnProduct, currentStatus);
524+
return userInstitutionService.updateUserStatusWithOptionalFilterByInstitutionAndProduct(
525+
userId, userDto.getInstitutionId(), userDto.getProduct().getProductId(), null, null, DELETED)
526+
.onItem().transformToUni(ignore -> createOrUpdateUserByUserId(userDto, userId, loggedUser, currentStatus));
527+
}
518528
} else {
519-
log.info("User {}, for product {}, has role {}, which is equals or biggest than {}. The old role is kept.", userId, userDto.getProduct().getProductId(), roleOnProduct, userDto.getProduct().getRole());
520-
return Uni.createFrom().failure(new UserRoleAlreadyPresentException(String.format("User already has a role equals or bigger than %s for the product [%s] we cannot create %s role",
521-
roleOnProduct, userDto.getProduct().getProductId(), userDto.getProduct().getRole())));
529+
log.info("User {} already has status {} for product {}. Cannot assign {} role.", userId, currentStatus, userDto.getProduct().getProductId(), newRole);
530+
return Uni.createFrom().failure(new UserRoleAlreadyPresentException(
531+
String.format("User already has status %s for product [%s]. Cannot assign %s role.",
532+
currentStatus, userDto.getProduct().getProductId(), newRole)));
522533
}
523534
}
524535

@@ -529,14 +540,27 @@ private PartyRole retrieveUserRoleOnProduct(UserInstitution userInstitution, Str
529540
if (Objects.nonNull(userInstitution.getProducts()) && !userInstitution.getProducts().isEmpty()) {
530541
return userInstitution.getProducts().stream()
531542
.filter(onboardedProduct -> productId.equalsIgnoreCase(onboardedProduct.getProductId()))
532-
.filter(onboardedProduct -> ACTIVE.equals(onboardedProduct.getStatus()))
543+
.filter(onboardedProduct -> List.of(ACTIVE, SUSPENDED).contains(onboardedProduct.getStatus()))
533544
.findFirst()
534545
.map(OnboardedProduct::getRole)
535546
.orElse(null);
536547
}
537548
return null;
538549
}
539550

551+
private OnboardedProductState retrieveUserStatusOnProduct(UserInstitution userInstitution, String productId) {
552+
if (Objects.nonNull(userInstitution.getProducts()) && !userInstitution.getProducts().isEmpty()) {
553+
return userInstitution.getProducts().stream()
554+
.filter(onboardedProduct -> productId.equalsIgnoreCase(onboardedProduct.getProductId()))
555+
.filter(onboardedProduct -> List.of(ACTIVE, SUSPENDED).contains(onboardedProduct.getStatus()))
556+
.findFirst()
557+
.map(OnboardedProduct::getStatus)
558+
.orElse(null);
559+
}
560+
return null;
561+
}
562+
563+
540564
/**
541565
* Updates or creates a UserInstitution by userId and institutionId, persists the changes,
542566
* and sends notifications if needed. If the productRole already exists return nullItem.
@@ -546,9 +570,9 @@ private PartyRole retrieveUserRoleOnProduct(UserInstitution userInstitution, Str
546570
* @param loggedUser The currently logged-in user.
547571
* @return A Uni containing the userId as a string.
548572
*/
549-
private Uni<String> updateUserInstitutionByUserId(UserResource userResource, AddUserRoleDto userDto, LoggedUser loggedUser) {
573+
private Uni<String> updateUserInstitutionByUserId(UserResource userResource, AddUserRoleDto userDto, LoggedUser loggedUser, OnboardedProductState status) {
550574
return userInstitutionService.findByUserIdAndInstitutionId(userResource.getId().toString(), userDto.getInstitutionId())
551-
.onItem().transformToUni(userInstitution -> updateOrCreateUserInstitution(userDto, userInstitution, userResource.getId().toString()))
575+
.onItem().transformToUni(userInstitution -> updateOrCreateUserInstitution(userDto, userInstitution, userResource.getId().toString(), status))
552576
.onItem().ifNotNull().transformToUni(userInstitutionService::persistOrUpdate)
553577
.onItem().ifNotNull().invoke(userInstitution -> log.info("UserInstitution with userId: {}, institutionId: {} persisted", userInstitution.getUserId(), userInstitution.getInstitutionId()))
554578
.onFailure().invoke(exception -> log.error("Error during persist user on UserInstitution: {} ", exception.getMessage(), exception))
@@ -557,7 +581,7 @@ private Uni<String> updateUserInstitutionByUserId(UserResource userResource, Add
557581

558582
}
559583

560-
private Uni<UserInstitution> updateOrCreateUserInstitution(AddUserRoleDto userDto, UserInstitution userInstitution, String userId) {
584+
private Uni<UserInstitution> updateOrCreateUserInstitution(AddUserRoleDto userDto, UserInstitution userInstitution, String userId, OnboardedProductState status) {
561585
if (userInstitution == null) {
562586
log.info(USER_INSTITUTION_NOT_FOUND, userId, userDto.getInstitutionId());
563587
return Uni.createFrom().item(userInstitutionMapper.toNewEntity(userDto, userId));
@@ -572,7 +596,7 @@ private Uni<UserInstitution> updateOrCreateUserInstitution(AddUserRoleDto userDt
572596
List<String> productRoleToAdd = checkAlreadyOnboardedProductRole(userDto.getProduct().getProductId(), userDto.getProduct().getProductRoles(), userInstitution);
573597
userDto.getProduct().setProductRoles(productRoleToAdd);
574598

575-
productRoleToAdd.forEach(productRole -> userInstitution.getProducts().add(onboardedProductMapper.toNewOnboardedProduct(userDto.getProduct(), productRole)));
599+
productRoleToAdd.forEach(productRole -> userInstitution.getProducts().add(onboardedProductMapper.toNewOnboardedProduct(userDto.getProduct(), productRole, status)));
576600
return Uni.createFrom().item(userInstitution);
577601
}
578602

apps/user-ms/src/test/java/it/pagopa/selfcare/user/controller/UserControllerTest.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@
2828
import org.apache.http.HttpStatus;
2929
import org.junit.jupiter.api.Test;
3030
import org.mockito.Mockito;
31-
import org.openapi.quarkus.user_registry_json.model.EmailCertifiableSchema;
32-
import org.openapi.quarkus.user_registry_json.model.FamilyNameCertifiableSchema;
33-
import org.openapi.quarkus.user_registry_json.model.MobilePhoneCertifiableSchema;
34-
import org.openapi.quarkus.user_registry_json.model.NameCertifiableSchema;
35-
import org.openapi.quarkus.user_registry_json.model.UserResource;
36-
import org.openapi.quarkus.user_registry_json.model.WorkContactResource;
31+
import org.openapi.quarkus.user_registry_json.model.*;
3732

3833
import java.util.*;
3934

@@ -655,7 +650,7 @@ void testCreateOrUpdateUserByUserId() {
655650

656651

657652
// Mock the userService.createOrUpdateUser method
658-
when(userService.createOrUpdateUserByUserId(any(AddUserRoleDto.class), anyString(), any()))
653+
when(userService.createOrUpdateUserByUserId(any(AddUserRoleDto.class), anyString(), any(), any()))
659654
.thenReturn(Uni.createFrom().item("example"));
660655

661656
// Perform the API call
@@ -676,7 +671,7 @@ void testCreateOrUpdateUserWithInvalidBodyByUserId() {
676671
// Set userDto properties
677672

678673
// Mock the userService.createOrUpdateUser method
679-
when(userService.createOrUpdateUserByUserId(any(AddUserRoleDto.class), anyString(), any(LoggedUser.class)))
674+
when(userService.createOrUpdateUserByUserId(any(AddUserRoleDto.class), anyString(), any(LoggedUser.class), any()))
680675
.thenReturn(Uni.createFrom().nullItem());
681676

682677
// Perform the API call

0 commit comments

Comments
 (0)