From a42f767698d7e3504f921b103572319e858fddbc Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 2 May 2023 14:57:15 +0300 Subject: [PATCH] DepoAccountNewRequest, new depo account --- .../DepoAccountValidationConfig.java | 75 ++++++++++++ .../account/service/DepoAccountService.java | 111 ++++++++++++++++++ .../platform/enumeration/AccountType.java | 2 +- .../platform/messaging/domain/Consts.java | 2 + .../cud/account/DepoAccountNewRequest.java | 39 ++++++ 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java create mode 100644 clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/DepoAccountNewRequest.java diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java new file mode 100644 index 000000000..9f41be340 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java @@ -0,0 +1,75 @@ +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.company.Company; +import ru.spcex.clearing.account.errors.AccountError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewRequest; +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.AccountStatus; +import ru.spcex.platform.enumeration.AccountType; +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 DepoAccountValidationConfig { + + @Bean("depoAccountNewRequestValidator") + public Function depoAccountNewRequestValidator( + Map> imdgForValidation + ) { + return depoAccountNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(depoAccountNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_DepoAccount); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + DepoAccountNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + AccountError.RequiredFieldEmpty, + AccountError.CompanyNotFound, + company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null), + FieldRequiredRule.instance("account", + DepoAccountNewRequest::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("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey()); + ImdgPredicate finalPredicate = pb.and(accountValuePredicate, + accountStatusPredicate, + accountTypePredicate); + Collection accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); + if (!accounts.isEmpty()) return null; + return AccountError.AccountAlreadyExist; + }), + FieldRequiredRule.instance("depoAccountType", + DepoAccountNewRequest::getDepoAccountType, + AccountError.RequiredFieldEmpty) + ); + }; + } + + +} diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java new file mode 100644 index 000000000..dcffe05f9 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java @@ -0,0 +1,111 @@ +package ru.spcex.clearing.account.service; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.DepoAccount; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.AccountStatus; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.function.Function; + +@Service +public class DepoAccountService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final ValidationHelper validationHelper; + private final ImdgProvider imdgProvider; + private final AccountService accountService; + private final Function depoAccountNewRequestValidator; + private final Imdg accountImdg; + private final Imdg depoAccountImdg; + + public DepoAccountService(Consumer kafkaQueue, + Producer kafkaProducer, + ValidationHelper validationHelper, + ImdgProvider imdgProvider, + AccountService accountService, + @Qualifier("depoAccountNewRequestValidator") + Function depoAccountNewRequestValidator) { + super(kafkaQueue, kafkaProducer); + this.validationHelper = validationHelper; + this.imdgProvider = imdgProvider; + this.accountService = accountService; + this.depoAccountNewRequestValidator = depoAccountNewRequestValidator; + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); + } + + @Override + public void afterPropertiesSet() throws Exception { + callback(DepoAccountNewRequest.class) + .setConsumer(this::depoAccountNew) + .forDestination(Consts.DESTINATION_DEPO_ACCOUNT_NEW, callbacks::put); + init(); + } + + public RequestInfoUpdate depoAccountNew(BaseRequest userRequest) { + log.debug("DepoAccountNewRequest received"); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + userRequest, depoAccountNewRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + DepoAccountNewRequest req = userRequest.getRequestPayload(); + + Instant now = Instant.now(); + Account account = new Account(); + account.setAccount(req.getAccount()); + account.setAccountType(AccountType.Depo.getKey()); + account.setStatus(AccountStatus.ACTIVE.getKey()); + account.setCompanyId(req.getCompanyId()); + account.setCreated(now); + account.setUpdated(now); + requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + Long depoAccountId = -1L; + Long accountId = -1L; + ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); + boolean txOk = false; + imdgTransaction.beginTransaction(); + try { + accountId = accountImdg.insert(account); + + DepoAccount depoAccount = new DepoAccount(); + depoAccount.setCompanyId(req.getCompanyId()); + depoAccount.setAccountId(accountId); + depoAccountId = depoAccountImdg.insert(depoAccount); + txOk = true; + } finally { + if (txOk) { + imdgTransaction.commitTransaction(); + log.debug("successfully processed, new depo account id {}, account id {}", depoAccountId, accountId); + } else { + // todo выяснить, что возвращать из метода в этой ситуации + log.debug("failed insert, new depo account id {}, new account id {} (if id = -1 then insert is failed)", + depoAccountId, + accountId); + imdgTransaction.rollbackTransaction(); + } + } + return null; + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java index 51184296e..8f8ad6fdb 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum AccountType implements IEnumKey { - Clrn("CLRN"), Bank("BANK"), Info("INFO"), Tran("TRAN"), Corr("CORR"), Anlt("ANLT"); + Clrn("CLRN"), Bank("BANK"), Info("INFO"), Tran("TRAN"), Corr("CORR"), Anlt("ANLT"), Depo("DEPO"); private final String key; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index 91d2551b6..9842d71ef 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -54,6 +54,8 @@ public interface Consts { String DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE = "clearing-member-category-update"; String DESTINATION_CLEARING_MEMBER_CATEGORY_DELETE = "clearing-member-category-delete"; + String DESTINATION_DEPO_ACCOUNT_NEW = "depo-account-new"; + String DESTINATION_CLEARING_ACCOUNT_NEW = "clearing-account-new"; String DESTINATION_CLEARING_ACCOUNT_UPDATE = "clearing-account-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/DepoAccountNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/DepoAccountNewRequest.java new file mode 100644 index 000000000..efc416b62 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/DepoAccountNewRequest.java @@ -0,0 +1,39 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.account; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class DepoAccountNewRequest { + @JsonProperty + public String account; + + @JsonProperty + public String depoAccountType; + + @JsonProperty + public Long companyId; + + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDepoAccountType() { + return depoAccountType; + } + + public void setDepoAccountType(String depoAccountType) { + this.depoAccountType = depoAccountType; + } + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } +}