From 865af17158af468f8daa670f125d13ec59afb3e1 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 6 Jun 2023 17:57:56 +0300 Subject: [PATCH] =?UTF-8?q?company-service=20http://jira.mfd.msk:8088/brow?= =?UTF-8?q?se/CLS-347=20=D0=BE=D0=BA=D0=B0=20=D1=82=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=BA=D0=BE=20new=20=D0=B7=D0=B0=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= =?UTF-8?q?.=20=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20update,?= =?UTF-8?q?=20transaction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AccountNotificationHelper.java | 13 +- .../company/service/CompanyService.java | 98 ++++++++ .../company/service/MultiCompanyService.java | 223 ++++++++++++++++++ .../service/ProfileDocumentService.java | 2 +- 4 files changed, 330 insertions(+), 6 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java index cde306470..c220cf6dd 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java @@ -9,19 +9,15 @@ import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; -import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountTerminationRequest; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; -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.ImdgProvider; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; @Service public class AccountNotificationHelper { @@ -96,4 +92,11 @@ public class AccountNotificationHelper { Long reqId = kafkaSender.sendRequestToQueue(Consts.INFORMATION_ACCOUNT_SYSTEM_NEW, r); log.debug("Send request id={}", reqId); } + + public void clientCodeNew(ClientCodeNewRequest clientCodeNewRequest) { + log.debug("Sending messages to account-service {} for company {}", + Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, clientCodeNewRequest.getCompanyId()); + Long reqId = kafkaSender.sendRequestToQueue(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, clientCodeNewRequest); + log.debug("Send request id={}", reqId); + } } \ No newline at end of file diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java index 3cf059bc6..9840b6db3 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java @@ -379,6 +379,104 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } + public synchronized Company createOrUpdateCompany(BaseRequest companyNewRequestBaseRequest, Long existCompanyId) throws ValidationException { + CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); + log.debug("company new or update, request {}, existCOmpanyId={}", companyNewRequestBaseRequest.getId(), existCompanyId); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyNewRequestBaseRequest); + if (requestInfoUpdate != null) + throw new ValidationException(CompanyErrors.GeneralError, requestInfoUpdate.getMessage()); +// requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); +// if (requestInfoUpdate != null) throw new ValidationException(CompanyErrors.GeneralError, requestInfoUpdate.getMessage()); + } + + Company company = null; + if (existCompanyId != null) { + company = companyIMap.getSingleObjectByID(existCompanyId); + if (company == null) { + throw new ValidationException(CompanyErrors.CompanyNotFound, String.valueOf(existCompanyId)); + } + } + + if (company == null) { + // #createCompany + company = new Company(); + company.setId(idSequence.nextId()); + Instant now = Instant.now(); + company.setCreated(now); + company.setUpdated(now); + log.debug("Create new company {}", company.getId()); + + company.setShortName(req.getShortName()); + company.setFullName(req.getFullName()); + + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + if (req.getCompanySymbol() != null) { + CompanySymbols newSymbol = companySymbolService.createCompanySymbol(transaction, company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue()); + updateCompanyBySymbol(company, newSymbol, false); + } + + company.setWorkflowStatus(req.getWorkflowStatus()); + fillNewCompanyInfo(company, req); + + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companyMap.insert(company); + log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", + companyNewRequestBaseRequest.getId(), company.getId()); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + accountNotification.makeInfoAccount(company.getId()); + } else { + log.debug("Update exist company {}", company.getId()); + company.setUpdated(Instant.now()); + // #updateCompany + + company.setUpdated(Instant.now()); + company.setShortName(req.getShortName()); + company.setFullName(req.getFullName()); + + if (req.getCompanySymbol() != null || req.getCompanySymbolValue() != null) { + log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); + } +// CompanySymbols не обновляем + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + String prevStatus = company.getWorkflowStatus(); + if (req.getWorkflowStatus() != null) { + company.setWorkflowStatus(req.getWorkflowStatus()); + if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + } else { + log.trace("Status was not changed"); + } + } else { + log.trace("Null new WorkflowStatus"); + } + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companyMap.update(company); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + } + + return company; + } + + /** * Блокировка компании после блокировки счетов * diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java new file mode 100644 index 000000000..768bc81ca --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java @@ -0,0 +1,223 @@ +package ru.spcex.clearing.company.service; + +import org.apache.commons.lang3.StringUtils; +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.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +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.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.*; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.RequestHelper; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.enumeration.UserRole; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.log.ExceptionUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +/** + * Обрабатывает MultiCompanyRequest и распределяет сложный объект по... + */ +@Service +public class MultiCompanyService + extends QueueConsumer implements InitializingBean { + + private final Logger log = LoggerFactory.getLogger(getClass()); + private final RequestHelper requestHelper; + + protected UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + + final CompanyService companyService; + final CompanyInfoService companyInfoService; + final ProfileDocumentService profileDocumentService; + final CompanySymbolService companySymbolService; + final ContactService contactService; + final AccountNotificationHelper accountNotification; + final RelationService relationService; + + final ImdgProvider imdgProvider; + final Imdg companyIMap; + final Imdg companySymbolsImdg; + + @Autowired + public MultiCompanyService(Consumer kafkaQueue, Producer kafkaProducer, + ImdgProvider imdgProvider, + RequestHelper requestHelper, + + CompanyService companyService, + CompanyInfoService companyInfoService, + ProfileDocumentService profileDocumentService, + CompanySymbolService companySymbolService, + ContactService contactService, + AccountNotificationHelper accountNotification, + RelationService relationService, + ValidationHelper validationHelper + ) { + super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; + this.requestHelper = requestHelper.setLogger(log); + +// this.idSequence = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification; + userRoleVerification.setRoleForVerification(UserRole.Admin); + this.validationHelper = validationHelper; + this.companyService = companyService; + this.companyInfoService = companyInfoService; + this.profileDocumentService = profileDocumentService; + this.companySymbolService = companySymbolService; + this.contactService = contactService; + this.accountNotification = accountNotification; + this.relationService = relationService; + + companyIMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public void afterPropertiesSet() { + callback(MultiCompanyRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processMultiRequest, request)) + .forDestination(Consts.DESTINATION_COMPANY_MULTIREQUEST, callbacks::put); + init(); + } + + private synchronized RequestInfoUpdate processMultiRequest(BaseRequest baseRequest) { + MultiCompanyRequest req = baseRequest.getRequestPayload(); + log.debug("company-batch-new request received, BaseRequest.id = {}", baseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(baseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + } + /* + todo: + 1) добавить апдейт кейсы + 2) сделать транзакции. + + */ + Long companyId = null; + boolean txOk = false; + synchronized (companyService) { + try { + companyId = getCompanyIdForCompanySymbols(req.getUuid(), req.getCompany()); + log.debug("For request {} (uuid {}) company {}.", baseRequest.getId(), req.getUuid(), companyId == null ? "not found" : ("found, id=" + companyId)); + + RequestInfoUpdate replyI; + Company company = companyService.createOrUpdateCompany(wrapRequest(baseRequest, req.getCompany()), companyId); + companyId = company.getId(); + log.debug("The companyId={}", companyId); + fillCompanyId(req, companyId); + + //todo update case: + replyI = companyInfoService.companyInfoUpdate(wrapRequest(baseRequest, req.getCompanyInfo())); + for (ProfileDocumentNewRequest partRequest : req.getProfileDocuments()) { + replyI = profileDocumentService.profileDocumentNew(wrapRequest(baseRequest, partRequest)); + } + for (CompanySymbolNewRequest partRequest : req.getCompanySymbols()) { + replyI = companySymbolService.companySymbolNew(wrapRequest(baseRequest, partRequest)); + } + for (ContactNewRequest partRequest : req.getContacts()) { + replyI = contactService.contactNew(wrapRequest(baseRequest, partRequest)); + } + txOk = true; + } catch (ValidationException vex) { + log.error("For companyId={} error: {}", companyId, ExceptionUtils.getStackTrace(vex)); + } + } + if (txOk) { + log.debug("Create or update sendNewClientCode for company {}", companyId); + for (ClientCodeNewRequest partRequest : req.getClientCodes()) { + accountNotification.clientCodeNew(partRequest); // Consts.DESTINATION_CLIENT_CODE_NEW Consts.DESTINATION_CLIENT_CODE_UPDATE + } + } + + return null; + } + + + Long getCompanyIdForCompanySymbols(String uuid, CompanyNewRequest cnr) { + CompanySymbols companySymbol = null; + if (StringUtils.isNotEmpty(uuid)) { + log.trace("Search company by companySymbol uuid={}", uuid); + Collection companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues( + Map.of( + "companySymbol", CompanySymbol.UUID.getKey(), + "companySymbolValue", uuid + ) + ); + if (!companySymbolsFromImdg.isEmpty()) { + companySymbol = companySymbolsFromImdg.iterator().next(); + if (companySymbolsFromImdg.size() > 1) { + log.warn("For UUID found > 1 company_symbols, use first (id = {})", companySymbol.getId()); + } + } + } + if (companySymbol == null && StringUtils.isNotEmpty(cnr.getCompanySymbol())) { + log.trace("Search company by companySymbol {}={}", cnr.getCompanySymbol(), cnr.getCompanySymbolValue()); + Collection companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues( + Map.of( + "companySymbol", cnr.getCompanySymbol(), + "companySymbolValue", cnr.getCompanySymbolValue() + ) + ); + if (!companySymbolsFromImdg.isEmpty()) { + companySymbol = companySymbolsFromImdg.iterator().next(); + if (companySymbolsFromImdg.size() > 1) { + log.warn("For {} found > 1 company_symbols, use first (id = {})", cnr.getCompanySymbol(), cnr.getCompanySymbolValue()); + } + } + } + if (companySymbol != null) + return companySymbol.getCompanyId(); + else + return null; + } + + private BaseRequest wrapRequest(BaseRequest template, T payload) { + BaseRequest r = new BaseRequest<>(); + r.setId(template.getId()); + r.setActionType(template.getActionType()); // todo? + r.setUserId(template.getUserId()); + r.setCorrelationId(template.getCorrelationId()); + r.setRequestPayload(payload); + return r; + } + + void fillCompanyId(MultiCompanyRequest req, Long companyId) { + req.getCompany().setId(companyId); + req.getCompanyInfo().setId(companyId); + if (req.getCompanySymbols() == null) req.setCompanySymbols(new ArrayList<>()); + if (req.getClientCodes() == null) req.setClientCodes(new ArrayList<>()); + if (req.getProfileDocuments() == null) req.setProfileDocuments(new ArrayList<>()); + if (req.getContacts() == null) req.setContacts(new ArrayList<>()); + for (CompanySymbolNewRequest cs : req.getCompanySymbols()) { + cs.setCompanyId(companyId); + } + for (ClientCodeNewRequest cc : req.getClientCodes()) { + cc.setCompanyId(companyId); + } + for (ProfileDocumentNewRequest pd : req.getProfileDocuments()) { + pd.setCompanyId(companyId); + } + for (ContactNewRequest c : req.getContacts()) { + c.setCompanyId(companyId); + } + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java index 55b64abe0..af4c24586 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java @@ -94,7 +94,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin } @NonNull - private RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { + protected RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { log.trace("Start processing ProfileDocumentNewRequest!"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentNewRequestBaseRequest);