diff --git a/CHANGELOG.md b/CHANGELOG.md index ce583c535..21a9732bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog All notable changes to this project will be documented in this file. +## [4.1.10](https://github.com/Backbase/stream-services/compare/4.1.9...4.1.10) +### Changed +- Enhance Legal Entity level Limit Object to set Limit based on Privilege, Business Function and User. ## [4.1.9](https://github.com/Backbase/stream-services/compare/4.1.9...4.1.9) ### Changed. diff --git a/e2e-tests/stubs/mappings/mapping-service-api-v2-legal-entity.json b/e2e-tests/stubs/mappings/mapping-service-api-v2-legal-entity.json index 73b9366f0..c8674f641 100644 --- a/e2e-tests/stubs/mappings/mapping-service-api-v2-legal-entity.json +++ b/e2e-tests/stubs/mappings/mapping-service-api-v2-legal-entity.json @@ -23,7 +23,30 @@ "number": "+31611193399" }, "fullName": "TESS JACKQUELINE SHOOK", - "identityLinkStrategy": "CREATE_IN_IDENTITY" + "identityLinkStrategy": "CREATE_IN_IDENTITY", + "limit": { + "businessFunctionLimits": [{ + "functionId": "2000", + "privileges": [ + { + "privilege": "create", + "limit": { + "currencyCode": "USD", + "transactional": "100", + "daily": "100" + } + }, + { + "privilege": "approve", + "limit": { + "currencyCode": "USD", + "transactional": "100", + "daily": "100" + } + } + ] + }] + } }, "referenceJobRoleNames": [ "Retail User - USA" diff --git a/stream-legal-entity/legal-entity-core/src/main/java/com/backbase/stream/LegalEntitySaga.java b/stream-legal-entity/legal-entity-core/src/main/java/com/backbase/stream/LegalEntitySaga.java index 8c3311f4d..8e785385b 100644 --- a/stream-legal-entity/legal-entity-core/src/main/java/com/backbase/stream/LegalEntitySaga.java +++ b/stream-legal-entity/legal-entity-core/src/main/java/com/backbase/stream/LegalEntitySaga.java @@ -89,6 +89,7 @@ import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.mapstruct.factory.Mappers; +import org.springframework.data.util.Pair; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -1030,7 +1031,8 @@ private Flux setSubsidiaryParentLegalEntityId(LegalEntity parentLeg private Mono setupLimits(LegalEntityTask streamTask) { return Mono.just(streamTask) .flatMap(this::setupLegalEntityLimits) - .flatMap(this::setupLegalEntityLevelBusinessFunctionLimits) + .flatMap(this::setupLegalEntityLevelBusinessFunctionLimits) // Create Limit with combination of LE, BF AND PRV + .flatMap(this::setupUserLevelBusinessFunctionLimits) // Create Limit with combination of USER, BF AND PRV .flatMap(this::setupServiceAgreementLimits) .flatMap(this::setupServiceAgreementParticipantLimits) .flatMap(this::retrieveUsersInternalIds) @@ -1060,6 +1062,43 @@ private boolean validateLimit(Limit limit) { nonNull(limit.getYearly())); } + private Mono setupUserLevelBusinessFunctionLimits(LegalEntityTask streamTask) { + LegalEntity legalEntity = streamTask.getData(); + var result = ofNullable(legalEntity.getUsers()).stream() + .flatMap(List::stream) + .map(JobProfileUser::getUser) + .filter(Objects::nonNull) + .map(User::getLimit) + .filter(Objects::nonNull) + .allMatch(user -> isEmpty(user.getBusinessFunctionLimits())); + if (isEmpty(legalEntity.getUsers()) || result) { + streamTask.info(LEGAL_ENTITY, PROCESS_LIMITS, FAILED, legalEntity.getInternalId(), + legalEntity.getExternalId(), "Legal Entity : %s does not have any User level limits defined", + legalEntity.getExternalId()); + return Mono.just(streamTask); + } + return Flux.fromStream(legalEntity.getUsers().stream()) + .map(JobProfileUser::getUser) + .filter(user -> nonNull(user) && nonNull(user.getLimit()) && !isEmpty(user.getLimit().getBusinessFunctionLimits())) + .map(user -> user.getLimit().getBusinessFunctionLimits().stream().map(bf -> Pair.of(user.getInternalId(), bf))) + .flatMap(Flux::fromStream) + .map(pair -> createLimitsTask(streamTask,null, pair.getFirst(), + pair.getSecond())) + .flatMap(Flux::fromStream) + .concatMap(limitsSaga::executeTask) + .map(limitsTask -> streamTask.addHistory(limitsTask.getHistory())) + .collectList() + .map(tasks -> { + boolean failed = tasks.stream().anyMatch(StreamTask::isFailed); + if (failed) { + streamTask.setState(StreamTask.State.FAILED); + } else { + streamTask.setState(StreamTask.State.COMPLETED); + } + return streamTask; + }); + } + private Mono setupLegalEntityLevelBusinessFunctionLimits(LegalEntityTask streamTask) { LegalEntity legalEntity = streamTask.getData(); if (isNull(legalEntity.getLimit()) || isEmpty(legalEntity.getLimit().getBusinessFunctionLimits())) { @@ -1070,7 +1109,7 @@ private Mono setupLegalEntityLevelBusinessFunctionLimits(LegalE .stream() .filter(businessFunctionLimit -> nonNull(businessFunctionLimit) && !CollectionUtils.isEmpty(businessFunctionLimit.getPrivileges())) - .flatMap(businessFunctionLimit -> createLimitsTask(streamTask, legalEntity.getInternalId(), businessFunctionLimit))) + .flatMap(businessFunctionLimit -> createLimitsTask(streamTask, legalEntity.getInternalId(), null, businessFunctionLimit))) .concatMap(limitsSaga::executeTask) .map(limitsTask -> streamTask.addHistory(limitsTask.getHistory())) .collectList() @@ -1097,7 +1136,7 @@ private Mono setupServiceAgreementLimits(LegalEntityTask stream .then(Mono.just(streamTask)); } - private Stream createLimitsTask(LegalEntityTask streamTask, String legalEntityId, BusinessFunctionLimit businessFunctionLimit) { + private Stream createLimitsTask(LegalEntityTask streamTask, String legalEntityId, String userInternalId, BusinessFunctionLimit businessFunctionLimit) { if(isNull(businessFunctionLimit) || CollectionUtils.isEmpty(businessFunctionLimit.getPrivileges())){ return Stream.of(); @@ -1108,7 +1147,9 @@ private Stream createLimitsTask(LegalEntityTask streamTask, String l .map(privilege -> { var limitData = new CreateLimitRequestBody(); var entities = new ArrayList(); - ofNullable(legalEntityId).ifPresent(le -> entities.add(new Entity().etype(LEGAL_ENTITY_E_TYPE).eref(le))); + ofNullable(legalEntityId) + .ifPresentOrElse(le -> entities.add(new Entity().etype(LEGAL_ENTITY_E_TYPE).eref(le)), + () -> limitData.setUserBBID(userInternalId)); ofNullable(businessFunctionLimit.getFunctionId()) .ifPresent(functionId -> entities.add(new Entity().etype(FUNCTION_E_TYPE).eref(functionId))); ofNullable(privilege.getPrivilege()) diff --git a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java index c529d4712..3bbf02306 100644 --- a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java +++ b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java @@ -64,7 +64,7 @@ private static LegalEntityTask defaultLegalEntityTask() { .parentExternalId("parent-100000") .legalEntityType(LegalEntityType.CUSTOMER) .realmName("customer-bank") - .limit(legalEntityLimit()) + .limit(limitWithBussinessFunctionAndPrivileges()) .productGroups(Arrays.asList( (ProductGroup) new ProductGroup() .productGroupType(BaseProductGroup.ProductGroupTypeEnum.ARRANGEMENTS) @@ -114,12 +114,14 @@ private static LegalEntityTask defaultLegalEntityTask() { new JobProfileUser() .user( new User() + .internalId("internal-id") .externalId("john.doe") .fullName("John Doe") .identityLinkStrategy(IdentityUserLinkStrategy.CREATE_IN_IDENTITY) .locked(false) .emailAddress(new EmailAddress().address("test@example.com")) .mobileNumber(new PhoneNumber().number("+12345")) + .limit(limitWithBussinessFunctionAndPrivileges()) ) .referenceJobRoleNames(Arrays.asList( "Private - Read only", "Private - Full access" @@ -144,13 +146,11 @@ private static LegalEntityTask defaultLegalEntityTask() { ); } - private static Limit legalEntityLimit(){ + private static Limit limitWithBussinessFunctionAndPrivileges(){ return new Limit() - .addBusinessFunctionLimitsItem(new BusinessFunctionLimit() - .functionId("1001") - .shadow(true) - .addPrivilegesItem(new Privilege().privilege("create").limit(new Limit().daily(BigDecimal.valueOf(2500d)))) - .addPrivilegesItem(new Privilege().privilege("execute").limit(new Limit().daily(BigDecimal.valueOf(2500d)))) + .addBusinessFunctionLimitsItem(new BusinessFunctionLimit("1001", false) + .addPrivilegesItem(new Privilege("create").limit(new Limit().transactional(BigDecimal.valueOf(2500d)).daily(BigDecimal.valueOf(2500d)))) + .addPrivilegesItem(new Privilege("approve").limit(new Limit().transactional(BigDecimal.valueOf(2500d)).daily(BigDecimal.valueOf(2500d)))) ); }