diff --git a/clearing-parent/account-service/pom.xml b/clearing-parent/account-service/pom.xml index f2bfdaf25..a9fae56b7 100644 --- a/clearing-parent/account-service/pom.xml +++ b/clearing-parent/account-service/pom.xml @@ -65,6 +65,14 @@ spring-boot-test test + + ru.spcex.clearing + security-util + + + ru.spcex.clearing + clearing-validation + diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/BeanConfiguration.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/BeanConfiguration.java new file mode 100644 index 000000000..9a7793082 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/BeanConfiguration.java @@ -0,0 +1,26 @@ +package ru.spcex.clearing.account.config; + +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import ru.spcex.clearing.account.errors.AccountError; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.enumeration.UserRole; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; + +@Configuration +public class BeanConfiguration { + @Bean + public IMessageResolver messageResolver() { + return new SimpleMessageResolver(); + } + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) { + return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, AccountError.UserVerifyDenial); + } +} diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/ErrorResolverConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/ErrorResolverConfig.java deleted file mode 100644 index 7cf2db17a..000000000 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/ErrorResolverConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.spcex.clearing.account.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.spcex.platform.utils.enumeration.IMessageResolver; -import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; - -@Configuration -public class ErrorResolverConfig { - @Bean - public IMessageResolver messageResolver() { - return new SimpleMessageResolver(); - } -} diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java new file mode 100644 index 000000000..9d0995c17 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java @@ -0,0 +1,214 @@ +package ru.spcex.clearing.account.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.BankAccount; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.platform.dictionary.CurrencyCodeDictionary; +import ru.spcex.clearing.account.errors.AccountError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; +import ru.spcex.clearing.validation.common.rules.EnumPresentRule; +import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.CurrencyCode; +import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Collection; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class BankAccountValidationConfig { + + @Bean("bankAccountNewRequestValidator") + public Function bankAccountNewRequestValidator( + Map> imdgForValidation + ) { + return bankAccountNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(bankAccountNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_BankAccount); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + BankAccountNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + AccountError.RequiredFieldEmpty, + AccountError.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive), + FieldRequiredRule.instance("account", + BankAccountNewRequest::getAccount, + AccountError.RequiredFieldEmpty, + accountValue -> { + Imdg accountImdg = context.obtainMap( + IMDGDistributedNames.Map_Account, Account.class + ); + ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); + ImdgPredicate accountValuePredicate = pb.equals("account", accountValue); + ImdgPredicate accountStatusPredicate = pb.equals("accountStatus", Status.Active.getKey()); + ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate); + Collection accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); + if (accounts.isEmpty()) return null; + return AccountError.AccountAlreadyExist; + }), + EnumPresentRule.instance("currency", + BankAccountNewRequest::getCurrency, + CurrencyCode.values(), + AccountError.WrongFieldValue, + AccountError.RequiredFieldEmpty), + DictionaryPresentRule.instance("currency", + BankAccountNewRequest::getCurrency, + IMDGDistributedNames.Map_CurrencyCodeDictionary, + CurrencyCodeDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue), + FieldRequiredRule.instance("bankIdentificationCode", + BankAccountNewRequest::getBankIdentificationCode, + AccountError.RequiredFieldEmpty), + FieldRequiredRule.instance("bankName", + BankAccountNewRequest::getBankName, + AccountError.RequiredFieldEmpty), + FieldRequiredRule.instance("destination", + BankAccountNewRequest::getDestination, + AccountError.RequiredFieldEmpty), + FieldRequiredRule.instance("correspondentAccount", + BankAccountNewRequest::getCorrespondentAccount, + AccountError.RequiredFieldEmpty, + false, + correspondentAccount -> { + String currency = bankAccountNewRequest.getCurrency(); + if (CurrencyCode.RUB.getKey().equalsIgnoreCase(currency) && correspondentAccount == null) + return AccountError.RequiredFieldEmpty; + return null; + }), + FieldRequiredRule.instance("correspondentAccountName", + BankAccountNewRequest::getCorrespondentAccountName, + AccountError.RequiredFieldEmpty, + false, + correspondentAccountName -> { + String currency = bankAccountNewRequest.getCurrency(); + if (CurrencyCode.RUB.getKey().equalsIgnoreCase(currency) && correspondentAccountName == null) + return AccountError.RequiredFieldEmpty; + return null; + }), + FieldRequiredRule.instance("taxpayerIdentificationNumber", + BankAccountNewRequest::getTaxpayerIdentificationNumber, + AccountError.RequiredFieldEmpty, + false, + taxpayerIdentificationNumber -> { + String currency = bankAccountNewRequest.getCurrency(); + if (CurrencyCode.RUB.getKey().equalsIgnoreCase(currency) && taxpayerIdentificationNumber == null) + return AccountError.RequiredFieldEmpty; + return null; + }), + FieldRequiredRule.instance("taxRegistrationReasonCode", + BankAccountNewRequest::getTaxRegistrationReasonCode, + AccountError.RequiredFieldEmpty, + false, + taxRegistrationReasonCode -> { + String currency = bankAccountNewRequest.getCurrency(); + if (CurrencyCode.RUB.getKey().equalsIgnoreCase(currency) && taxRegistrationReasonCode == null) + return AccountError.RequiredFieldEmpty; + return null; + }) + ); + }; + } + + @Bean("bankAccountUpdateRequestValidator") + public Function bankAccountUpdateRequestValidator( + Map> imdgForValidation + ) { + return bankAccountUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(bankAccountUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary); + addImdg.accept(IMDGDistributedNames.Map_BankAccount); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + BankAccountUpdateRequest::getId, + IMDGDistributedNames.Map_BankAccount, + BankAccount.class, + AccountError.RequiredFieldEmpty, + AccountError.BankAccountNotFound, + bankAccount -> { + Long accountId = bankAccount.getAccountId(); + Imdg accountImdg = context.obtainMap( + IMDGDistributedNames.Map_Account, Account.class + ); + Account account = accountImdg.getSingleObjectByID(accountId); + if (account == null) return AccountError.BankAccountNotFound; + if (!WorkflowStatus.Active.getKey().equalsIgnoreCase(account.getAccountStatus())) + return AccountError.AccountNotActive; + return null; + }), + EnumPresentRule.instance("currency", + BankAccountUpdateRequest::getCurrency, + CurrencyCode.values(), + false, + AccountError.WrongFieldValue, + AccountError.RequiredFieldEmpty), + DictionaryPresentRule.instance("currency", + BankAccountUpdateRequest::getCurrency, + IMDGDistributedNames.Map_CurrencyCodeDictionary, + CurrencyCodeDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue, + false) + ); + }; + } + + @Bean("bankAccountUpdateRequestValidator") + public Function bankAccountDeleteRequestValidator( + Map> imdgForValidation + ) { + return bankAccountDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(bankAccountDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_BankAccount); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_BankAccount, + BankAccount.class, + AccountError.RequiredFieldEmpty, + AccountError.BankAccountNotFound, + bankAccount -> { + Long accountId = bankAccount.getAccountId(); + Imdg accountImdg = context.obtainMap( + IMDGDistributedNames.Map_Account, Account.class + ); + Account account = accountImdg.getSingleObjectByID(accountId); + if (account == null) return AccountError.BankAccountNotFound; + if (!WorkflowStatus.Active.getKey().equalsIgnoreCase(account.getAccountStatus())) + return AccountError.AccountNotActive; + return null; + }) + ); + }; + } + +} diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java new file mode 100644 index 000000000..879f5b85c --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java @@ -0,0 +1,43 @@ +package ru.spcex.clearing.account.config.validation; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.BankAccount; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.platform.dictionary.CurrencyCodeDictionary; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +@Configuration +public class ValidationConfig { + + @Bean("imdgForValidation") + public Map> imdgForValidation(ImdgProvider imdgProvider) { + final Map> imdg = new HashMap<>(); + BiConsumer> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass)); + + addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); + addImdg.accept(IMDGDistributedNames.Map_Account, Account.class); + addImdg.accept(IMDGDistributedNames.Map_BankAccount, BankAccount.class); + addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class); + + return imdg; + } + + @Bean("validationHelper") + public ValidationHelper validationHelper(IMessageResolver messageResolver) { + return new ValidationHelper(messageResolver); + } + +} + diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java index 122609131..fef804c81 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java @@ -3,12 +3,16 @@ package ru.spcex.clearing.account.errors; import ru.spcex.platform.utils.enumeration.IErrorEnumId; public enum AccountError implements IErrorEnumId { + UserVerifyDenial(5001L), + RequiredFieldEmpty(5002L), WrongFieldValue(5004L), AccountAlreadyExist(5010L), + BankAccountNotFound(5011L), + AccountNotActive(5012L), CompanyNotFound(5013L), CompanyNotActive(5014L), - ; + private final Long id; AccountError(Long id) { diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java index 36fea1fe3..a3461b62b 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java @@ -43,7 +43,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { init(); } - private void accountNew(BaseRequest userRequest) { + public void accountNew(BaseRequest userRequest) { AccountSdf01Request req = userRequest.getRequestPayload(); log.debug("AccountSdf01Request received"); List accountToStatement = new ArrayList<>(); @@ -60,11 +60,11 @@ public class AccountService extends QueueConsumer implements InitializingBean { log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size()); } - private void accountUpdateWithBrake(BaseRequest userRequest) { + public void accountUpdateWithBrake(BaseRequest userRequest) { } - private AccountSdfToStatementRequestPart responsePart(Long sdf01Id) { + public AccountSdfToStatementRequestPart responsePart(Long sdf01Id) { AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); responsePart.setSdfId(sdf01Id); responsePart.setErrorCode(null); @@ -72,7 +72,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { return responsePart; } - private void sendStatementRequestBack(Long groupingSdf01Id, List results) { + public void sendStatementRequestBack(Long groupingSdf01Id, List results) { StatementRequest request = new StatementRequest(); request.setGroupId(groupingSdf01Id); request.setAccountCreationResults(results);