From 2829e50e7e003e492e4473dcbd65639e7251cc07 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 14:36:33 +0300 Subject: [PATCH 1/4] =?UTF-8?q?company-service=20http://jira.mfd.msk:8088/?= =?UTF-8?q?browse/CLS-284=20=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20(?= =?UTF-8?q?=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/service/CompanyInfoService.java | 2 +- .../company/service/CompanyService.java | 26 ++++++------ ...lationHelper.java => RelationService.java} | 40 ++++++++++++++++++- .../service/CompanyInfoServiceTest.java | 2 +- .../company/service/CompanyServiceTest.java | 2 +- .../service/CompanySymbolServiceTest.java | 2 +- 6 files changed, 54 insertions(+), 20 deletions(-) rename clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/{RelationHelper.java => RelationService.java} (66%) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java index 0beb21c0a..03d355d49 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java @@ -111,7 +111,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea transaction.beginTransaction(); boolean txOk = false; try { - companyService.relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + companyService.relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); Imdg txCompanyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); txCompanyMap.update(company); log.trace("Company {} updated", company.getId()); 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 3444b1243..542916892 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 @@ -29,13 +29,11 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ClearingBaseException; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; -import java.util.Map; import java.util.Objects; import java.util.function.Function; @@ -56,7 +54,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { protected CompanySymbolService companySymbolService; protected AccountNotificationHelper accountNotification; - protected RelationHelper relationHelper; + protected RelationService relationService; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, @@ -73,7 +71,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { CompanySymbolService companySymbolService, AccountNotificationHelper accountNotification, - RelationHelper relationHelper + RelationService relationService ) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; @@ -89,7 +87,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolService = companySymbolService; companySymbolService.setCompanyService(this); this.accountNotification = accountNotification; - this.relationHelper = relationHelper; + this.relationService = relationService; companyIMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); } @@ -145,9 +143,9 @@ public class CompanyService extends QueueConsumer implements InitializingBean { companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); - relationHelper.createNewRelation(transaction, company); + relationService.createNewRelation(transaction, company); if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block - relationHelper.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); } txOk = true; } finally { @@ -180,10 +178,10 @@ public class CompanyService extends QueueConsumer implements InitializingBean { log.trace("Company {} not found", updateRequest.getId()); return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyNotFound, updateRequest.getId()); } - if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { - log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); - return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyDisabled, updateRequest.getId()); - } +// if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { +// log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); +// return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyDisabled, updateRequest.getId()); +// } company.setUpdated(Instant.now()); company.setShortName(updateRequest.getShortName()); @@ -199,7 +197,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (updateRequest.getWorkflowStatus() != null) { company.setWorkflowStatus(updateRequest.getWorkflowStatus()); if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { - relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); } else { log.trace("Status was not changed"); } @@ -286,7 +284,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { String prevStatus = company.getWorkflowStatus(); company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); log.debug("Update company.id={}", company.getId()); companyMap.update(company); @@ -339,7 +337,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - relationHelper.onChangeWorkflowStatusOnlyRelationChange(transaction, company, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatusOnlyRelationChange(transaction, company, company.getWorkflowStatus()); log.debug("Update company.id={}", company.getId()); companyMap.update(company); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java similarity index 66% rename from clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java rename to clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index c68595767..ca0c4349f 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -1,17 +1,27 @@ package ru.spcex.clearing.company.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.Autowired; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.classes.statics.data.profile.ProfileDocument; 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.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.platform.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; 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.error.ValidationException; @@ -20,15 +30,41 @@ import java.util.Collection; import java.util.Objects; @Service -public class RelationHelper { +public class RelationService extends QueueConsumer implements InitializingBean { protected static final Long SPVB_ID = 1L; // СПВБ protected final Logger log = LoggerFactory.getLogger(getClass()); + protected ImdgProvider imdgProvider; protected AccountNotificationHelper accountNotification; @Autowired - public RelationHelper(AccountNotificationHelper accountNotification) { + public RelationService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + + AccountNotificationHelper accountNotification) { + super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; this.accountNotification = accountNotification; + +// this.requestHelper = requestHelper.setLogger(log); + } + + @Override + public void afterPropertiesSet() { +// this.profileDocumentMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); +// this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); +//todo all CLS-284 +// callback(ProfileDocumentNewRequest.class) +// .setFunction(this::profileDocumentNew) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); +// callback(ProfileDocumentUpdateRequest.class) +// .setFunction(this::profileDocumentUpdate) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); +// callback(CommonDeleteRequest.class) +// .setFunction(this::profileDocumentDelete) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_DELETE, callbacks::put); +// init(); } protected void createNewRelation(ImdgTransaction transaction, Company company) { diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java index d823d4ab6..b521fd7e4 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java @@ -50,7 +50,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv ValidationConfig.class, CompanySymbolService.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, BeanConfiguration.class, KafkaTestConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java index b80446af5..f18f68a84 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java @@ -54,7 +54,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv ValidationConfig.class, CompanySymbolService.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, CompanySymbolService.class, CompanySymbolValidationConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java index 98383d456..39e77828d 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java @@ -50,7 +50,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv CompanyService.class, CompanyValidationConfig.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, KafkaTestConfig.class, ImdgTestConfig.class}) From a37fea506195002d72a9cd049178ee4f91005aa7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 20:17:35 +0300 Subject: [PATCH 2/4] =?UTF-8?q?company-service=20http://jira.mfd.msk:8088/?= =?UTF-8?q?browse/CLS-284=20=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= =?UTF-8?q?=20=D0=BA=D1=80=D0=BE=D0=BC=D0=B5=20=D1=81=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/RelationValidationConfig.java | 134 +++++++++++ .../config/validation/ValidationConfig.java | 2 + .../clearing/company/error/CompanyErrors.java | 1 + .../company/service/RelationService.java | 206 +++++++++++++++-- .../company/service/RelationServiceTest.java | 214 ++++++++++++++++++ .../platform/messaging/domain/Consts.java | 2 + .../cud/company/RelationNewRequest.java | 46 ++++ 7 files changed, 588 insertions(+), 17 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java create mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java new file mode 100644 index 000000000..959f62491 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java @@ -0,0 +1,134 @@ +package ru.spcex.clearing.company.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationUpdateRequest; +import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class RelationValidationConfig { + + @Bean("relationNewRequestValidation") + public Function relationNewRequestValidator( + Map> imdgForValidation + ) { + return relationNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + RelationNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), + DictionaryPresentRule.instance("documentType", + RelationNewRequest::getClearingMemberCategory, + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue), + DictionaryPresentRule.instance("serviceStatus", + RelationNewRequest::getServiceStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } + + @Bean("relationUpdateRequestValidation") + public Function relationUpdateRequestValidator( + Map> imdgForValidation + ) { + return relationUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Relation); + addImdg.accept(IMDGDistributedNames.Map_Company); +// addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + RelationUpdateRequest::getId, + IMDGDistributedNames.Map_Relation, + Relation.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RelationNotFound, + relation -> { + if (relation.getConsumerId() == null) return null; + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(relation.getConsumerId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } else { + return null; + } + }), +// IdPresentRule.instance("companyId", +// RelationUpdateRequest::getCompanyId, +// IMDGDistributedNames.Map_Company, +// Company.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.CompanyNotFound), +// DictionaryPresentRule.instance("documentType", +// RelationUpdateRequest::getClearingMemberCategory, +// IMDGDistributedNames.Map_ClearingCategoryDictionary, +// ClearingCategoryDictionary.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.WrongFieldValue), + DictionaryPresentRule.instance("serviceStatus", + RelationUpdateRequest::getServiceStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } + + @Bean("relationDeleteRequestValidation") + public Function relationDeleteRequestValidator( + Map> imdgForValidation + ) { + return relationDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Relation); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_Relation, + Relation.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RelationNotFound + ) + ); + }; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java index cd6671cf1..c586e2fd7 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java @@ -7,6 +7,7 @@ import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; +import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; @@ -37,6 +38,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary, DocumentTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_Contact, Contact.class); + addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class); addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java index 3979ab8b9..a7e4b232d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -25,6 +25,7 @@ public enum CompanyErrors implements IErrorEnumId { EditContactType(3021L), // Тип контакта компании %s не может быть изменен. TradingClearingRegistryNotFound(3022L), // ТКР с %s не найден AccountNotFound(3023L), // Счет %s не найден + RelationNotFound(3026L), // Запись о договорных отношениях не найдена ; private final Long id; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index ca0c4349f..882abff8c 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -6,28 +6,35 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; -import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.util.RequestHelper; 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.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; +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.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Collection; import java.util.Objects; +import java.util.function.Function; @Service public class RelationService extends QueueConsumer implements InitializingBean { @@ -35,38 +42,203 @@ public class RelationService extends QueueConsumer implements InitializingBean { protected final Logger log = LoggerFactory.getLogger(getClass()); protected ImdgProvider imdgProvider; + protected ImdgId idSequence; + protected Imdg relationMap; + protected Imdg companyMap; protected AccountNotificationHelper accountNotification; + protected UserRoleVerification userRoleVerification; + protected RequestHelper requestHelper; + + protected ValidationHelper validationHelper; + private Function relationNewRequestValidator; + private Function relationUpdateRequestValidator; + private Function relationDeleteRequestValidator; @Autowired public RelationService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, + RequestHelper requestHelper, + + UserRoleVerification userRoleVerification, + ValidationHelper validationHelper, + @Qualifier("relationNewRequestValidation") Function relationNewRequestValidator, + @Qualifier("relationUpdateRequestValidation") Function relationUpdateRequestValidator, + @Qualifier("relationDeleteRequestValidation") Function relationDeleteRequestValidator, AccountNotificationHelper accountNotification) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; + this.idSequence = imdgProvider.getImdgIdGenerator(); this.accountNotification = accountNotification; + this.userRoleVerification = userRoleVerification; -// this.requestHelper = requestHelper.setLogger(log); + this.validationHelper = validationHelper; + this.relationNewRequestValidator = relationNewRequestValidator; + this.relationUpdateRequestValidator = relationUpdateRequestValidator; + this.relationDeleteRequestValidator = relationDeleteRequestValidator; + + relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.requestHelper = requestHelper.setLogger(log); } + // --- external API --- @Override public void afterPropertiesSet() { // this.profileDocumentMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); // this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); -//todo all CLS-284 -// callback(ProfileDocumentNewRequest.class) -// .setFunction(this::profileDocumentNew) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); -// callback(ProfileDocumentUpdateRequest.class) -// .setFunction(this::profileDocumentUpdate) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); -// callback(CommonDeleteRequest.class) -// .setFunction(this::profileDocumentDelete) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_DELETE, callbacks::put); -// init(); + + callback(RelationNewRequest.class) + .setFunction(this::relationNew) + .forDestination(Consts.DESTINATION_RELATION_NEW, callbacks::put); + callback(RelationUpdateRequest.class) + .setFunction(this::relationUpdate) + .forDestination(Consts.DESTINATION_RELATION_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::relationDelete) + .forDestination(Consts.DESTINATION_RELATION_DELETE, callbacks::put); + init(); } + private synchronized RequestInfoUpdate relationNew(BaseRequest relationNewBaseRequest) { + RelationNewRequest req = relationNewBaseRequest.getRequestPayload(); + log.debug("relation-new request received, BaseRequest.id = {}", relationNewBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationNewBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationNewBaseRequest, relationNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + Company company = companyMap.getSingleObjectByID(req.getCompanyId()); + +// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, +// если запись создана и serviceStatus=CLOS, +// изменить запись в relation согласно описанию с тегом При возобнолвении +// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." +// */ +// } +// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, +//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, +// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ +// } + Relation relation = new Relation(); + relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + + relation.setConsumerId(req.getCompanyId()); + relation.setSupplierId(SPVB_ID); // 1 СПВБ + if (req.getServiceStatus() != null) { + relation.setServiceStatus(req.getServiceStatus()); + } else { + log.warn("Request has no status. Set status from company[{}].status={}", company.getId(), company.getWorkflowStatus()); + relation.setServiceStatus(company.getWorkflowStatus()); + } + relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR + relation.setServiceProduct(ServiceProduct.ZERO.getKey()); + relation.setComment(req.getComment()); + + relationMap.insert(relation); + log.debug("New Relation[{}] created.", relation.getId()); + + return null; + } + + + private synchronized RequestInfoUpdate relationUpdate(BaseRequest relationUpdateBaseRequest) { + RelationUpdateRequest req = relationUpdateBaseRequest.getRequestPayload(); + log.debug("relation-update request received, BaseRequest.id = {}", relationUpdateBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationUpdateBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationUpdateBaseRequest, relationUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + //Company company = companyMap.getSingleObjectByID(req.getCompanyId()); +// +// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, +// если запись создана и serviceStatus=CLOS, +// изменить запись в relation согласно описанию с тегом При возобнолвении +// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." +// */ +// } +// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, +//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, +// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ +// } + + Relation relation = relationMap.getSingleObjectByID(req.getId()); + relation.setUpdated(relation.getCreated()); + + if (req.getServiceStatus() != null) { + relation.setServiceStatus(req.getServiceStatus()); + } else { +// relation.setServiceStatus(company.getStatus()); + } + relation.setComment(req.getComment()); + + relationMap.insert(relation); + log.debug("Update Relation[{}] created.", relation.getId()); + + return null; + } + + + private synchronized RequestInfoUpdate relationDelete(BaseRequest relationDeleteBaseRequest) { + CommonDeleteRequest req = relationDeleteBaseRequest.getRequestPayload(); + log.debug("relation-delete request received, BaseRequest.id = {}", relationDeleteBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationDeleteBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationDeleteBaseRequest, relationDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + Relation relation = relationMap.getSingleObjectByID(req.getId()); + if (WorkflowStatus.Blocked.equalsByKey(relation.getServiceStatus())) { + log.warn("Relation {} already blocked.", relation.getId()); + } else { + relation.setUpdated(relation.getCreated()); + relation.setServiceStatus(WorkflowStatus.Blocked.getKey()); + + relationMap.insert(relation); + log.debug("Relation[{}] block.", relation.getId()); + } + return null; + } + + + // --- internal API --- + protected void createNewRelation(ImdgTransaction transaction, Company company) { Relation relation = new Relation(); // relation.setId(idSequence.nextId()); @@ -79,7 +251,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR relation.setServiceProduct(ServiceProduct.ZERO.getKey()); log.debug("New Relation[{}] created.", relation.getId()); - Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); relationMap.insert(relation); } @@ -103,7 +275,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { } } - protected void onChangeWorkflowStatusOnlyRelationChange(ImdgTransaction transaction, Company company, String newStatus) throws ValidationException { + protected synchronized void onChangeWorkflowStatusOnlyRelationChange(ImdgTransaction transaction, Company company, String newStatus) throws ValidationException { assert Objects.equals(newStatus, company.getWorkflowStatus()); String query = String.format("consumerId=%s", company.getId()); Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java new file mode 100644 index 000000000..8bebb24f7 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java @@ -0,0 +1,214 @@ +package ru.spcex.clearing.company.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationUpdateRequest; +import ru.spcex.clearing.test.MatcherFactory; +import ru.spcex.clearing.test.TestUtils; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; +import ru.spcex.platform.enumeration.ClearingCategory; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import javax.annotation.PostConstruct; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; +import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, + RelationService.class, + AccountNotificationHelper.class, + RelationValidationConfig.class, + KafkaTestConfig.class, + ImdgTestConfig.class}) +class RelationServiceTest { + + public static final MatcherFactory.Matcher RELATION_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private static final int PARTITION = 0; + + private static final Long ID = currentID.getAndIncrement(); + @Autowired + RelationService relationService; + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + private Imdg relationMap; + private Imdg companyMap; + + @Captor + private ArgumentCaptor producerRecord; + @SpyBean + private MockProducer mockProducer; + + private long COMPANY_ID; + + private final long RELATION_ID = ID; + + @PostConstruct + private void init() { + waitAvailableImdgProviderAndAddAdminWithDefaultId(); + this.relationMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + Company testCompany = new Company(); + testCompany.setWorkflowStatus(WorkflowStatus.Active.getKey()); + COMPANY_ID = companyMap.insert(testCompany); + + Imdg workflowStatusDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class + ); + WorkflowStatusDictionary workflowStatusDictionary = new WorkflowStatusDictionary(); + workflowStatusDictionary.setId(1L); + workflowStatusDictionary.setCode(WorkflowStatus.Active.getKey()); + workflowStatusDictionary.setName("active"); + workflowStatusDictionaryImdg.insert(workflowStatusDictionary); + workflowStatusDictionary = new WorkflowStatusDictionary(); + workflowStatusDictionary.setId(2L); + workflowStatusDictionary.setCode(WorkflowStatus.Blocked.getKey()); + workflowStatusDictionary.setName("not active"); + workflowStatusDictionaryImdg.insert(workflowStatusDictionary); + + Imdg clearingCategoryDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class + ); + ClearingCategoryDictionary clearingCategoryDictionary = new ClearingCategoryDictionary(); + clearingCategoryDictionary.setId(1L); + clearingCategoryDictionary.setCode(ClearingCategory.I.getKey()); + clearingCategoryDictionary.setName("I"); + clearingCategoryDictionaryImdg.insert(clearingCategoryDictionary); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } + + + @Test + void newRelation() { + //ARRANGE + RelationNewRequest relationNewRequest = new RelationNewRequest(); + relationNewRequest.setCompanyId(COMPANY_ID); + relationNewRequest.setServiceStatus("ACTV"); + relationNewRequest.setClearingMemberCategory("I"); + relationNewRequest.setComment(null); + + Relation predictableRelation = new Relation(); + predictableRelation.setId(RELATION_ID); + predictableRelation.setConsumerId(relationNewRequest.companyId); + predictableRelation.setService("MKR"); + predictableRelation.setServiceProduct("ZERO"); + predictableRelation.setSupplierId(1L); + predictableRelation.setServiceStatus("ACTV"); + + //ACT + String jsonString = getJsonStringForNew(relationNewRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultNew = relationMap.getSingleObjectBySQL("serviceStatus=ACTV"); // String.format("supplierId = %d", COMPANY_ID)); + predictableRelation.setId(resultNew.getId()); + RELATION_MATCHER.assertMatch(resultNew, predictableRelation); + } + + @Test + void updateRelation() { + //ARRANGE + Relation existsRelation = new Relation(); + existsRelation.setId(ID); + existsRelation.setConsumerId(COMPANY_ID); + existsRelation.setSupplierId(1L); + existsRelation.setComment("Test ONE"); + existsRelation.setServiceStatus("ACTV"); + existsRelation.setServiceProduct("PROD"); + existsRelation.setService("MKR"); + relationMap.insert(existsRelation); + + Relation predictableRelation = new Relation(); + predictableRelation.setId(ID); + predictableRelation.setConsumerId(COMPANY_ID); + predictableRelation.setSupplierId(1L); + predictableRelation.setComment("Another Me - ONE"); + predictableRelation.setServiceStatus("ACTV"); + predictableRelation.setServiceProduct("PROD"); + predictableRelation.setService("MKR"); + + RelationUpdateRequest relationUpdateRequest = new RelationUpdateRequest(); + relationUpdateRequest.setId(RELATION_ID); + relationUpdateRequest.setComment("Another Me - ONE"); + relationUpdateRequest.setServiceStatus("ACTV"); + + //ACT + String jsonString = getJsonStringForUpdate(relationUpdateRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_UPDATE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultUpdate = relationMap.getSingleObjectBySQL(String.format("id = %d", RELATION_ID)); +// predictableProfileDocument.setId(resultUpdate.getId()); + RELATION_MATCHER.assertMatch(resultUpdate, predictableRelation); + } + + + @Test + void deleteProfileDocument() { + //ARRANGE + Relation existsRelation = new Relation(); + existsRelation.setId(ID); + existsRelation.setConsumerId(COMPANY_ID); + existsRelation.setSupplierId(1L); + existsRelation.setComment("Test ONE"); + existsRelation.setServiceStatus("ACTV"); + existsRelation.setServiceProduct("PROD"); + existsRelation.setService("MKR"); + relationMap.insert(existsRelation); + + CommonDeleteRequest profileDocumentDeleteRequest = new CommonDeleteRequest(); + profileDocumentDeleteRequest.setId(RELATION_ID); + + //ACT + String jsonString = getJsonStringForUpdate(profileDocumentDeleteRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_DELETE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultUpdate = relationMap.getSingleObjectByID(RELATION_ID); +// Assertions.assertNull(resultUpdate); + assertEquals(WorkflowStatus.Blocked.getKey(), resultUpdate.getServiceStatus()); + } +} \ No newline at end of file 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 c00ea09a8..2d0f0cae6 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 @@ -72,7 +72,9 @@ public interface Consts { @Deprecated String ACCOUNT_NEW_SDF01 = "account-new-sdf01"; + String DESTINATION_RELATION_NEW = "relation-new"; String DESTINATION_RELATION_UPDATE = "relation-update"; + String DESTINATION_RELATION_DELETE = "relation-delete"; String DESTINATION_PROFILE_DOCUMENT_NEW = "profile-document-new"; String DESTINATION_PROFILE_DOCUMENT_UPDATE = "profile-document-update"; String DESTINATION_PROFILE_DOCUMENT_DELETE = "profile-document-delete"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java new file mode 100644 index 000000000..9e630303a --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RelationNewRequest { + @JsonProperty + public Long companyId; + @JsonProperty + private String serviceStatus; + @JsonProperty + private String clearingMemberCategory; + @JsonProperty + private String comment; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getServiceStatus() { + return serviceStatus; + } + + public void setServiceStatus(String serviceStatus) { + this.serviceStatus = serviceStatus; + } + + public String getClearingMemberCategory() { + return clearingMemberCategory; + } + + public void setClearingMemberCategory(String clearingMemberCategory) { + this.clearingMemberCategory = clearingMemberCategory; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} From 84870fb64f5a6dfa52f83998fdffe2cbd61c2960 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 12:16:41 +0300 Subject: [PATCH 3/4] =?UTF-8?q?company-service=20http://jira.mfd.msk:8088/?= =?UTF-8?q?browse/CLS-284=20=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clearing/company/error/CompanyErrors.java | 2 + .../company/service/RelationService.java | 126 +++++++++++------- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java index a7e4b232d..1c5b42c49 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -25,6 +25,8 @@ public enum CompanyErrors implements IErrorEnumId { EditContactType(3021L), // Тип контакта компании %s не может быть изменен. TradingClearingRegistryNotFound(3022L), // ТКР с %s не найден AccountNotFound(3023L), // Счет %s не найден + ClearingMemberCategoryOnMKRAlreadyExist(3024L), // Договорные отношения %s в секции МКР уже созданы. + ClearingMemberCategoryOnFONDAlreadyExist(3025L), // Договорные отношения %s на фондовой секции уже созданы. RelationNotFound(3026L), // Запись о договорных отношениях не найдена ; private final Long id; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index 882abff8c..ab47be9ad 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -21,6 +21,7 @@ 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.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; @@ -33,6 +34,7 @@ import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Collection; +import java.util.Map; import java.util.Objects; import java.util.function.Function; @@ -115,38 +117,48 @@ public class RelationService extends QueueConsumer implements InitializingBean { Company company = companyMap.getSingleObjectByID(req.getCompanyId()); -// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, -// если запись создана и serviceStatus=CLOS, -// изменить запись в relation согласно описанию с тегом При возобнолвении -// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." -// */ -// } -// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, -//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, -// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ -// } - Relation relation = new Relation(); - relation.setId(idSequence.nextId()); - relation.setCreated(Instant.now()); - relation.setUpdated(relation.getCreated()); + Relation existRelation = searchRelation(req.getClearingMemberCategory(), req.getCompanyId()); + if (existRelation != null && !WorkflowStatus.Blocked.equalsByKey(existRelation.getServiceStatus())) { + CompanyErrors errorType; + if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(existRelation.getService())) { + errorType = CompanyErrors.ClearingMemberCategoryOnMKRAlreadyExist; + } else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(existRelation.getService())) { + errorType = CompanyErrors.ClearingMemberCategoryOnFONDAlreadyExist; + } else { + log.warn("Unknown relation[{}] service={}", existRelation.getId(), existRelation.getService()); + errorType = CompanyErrors.GeneralError; + } + return requestHelper.makeErrorResponse(relationNewBaseRequest, errorType); + } + + Relation relation; + if (existRelation == null) { + relation = new Relation(); + relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + } else { + log.info("Found exist relation id={}, it will be update.", existRelation.getId()); + relation = existRelation; + relation.setUpdated(Instant.now()); + } relation.setConsumerId(req.getCompanyId()); relation.setSupplierId(SPVB_ID); // 1 СПВБ if (req.getServiceStatus() != null) { relation.setServiceStatus(req.getServiceStatus()); } else { - log.warn("Request has no status. Set status from company[{}].status={}", company.getId(), company.getWorkflowStatus()); - relation.setServiceStatus(company.getWorkflowStatus()); + if (existRelation != null) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + log.debug("Request has no status. Set status by resume: {}", relation.getServiceStatus()); + } else { + String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + null; + log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}", + company.getId(), company.getWorkflowStatus(), toStatus); + relation.setServiceStatus(toStatus); + } } relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR relation.setServiceProduct(ServiceProduct.ZERO.getKey()); @@ -158,6 +170,27 @@ public class RelationService extends QueueConsumer implements InitializingBean { return null; } + private Relation searchRelation(String clearingMemberCategory, Long consumerId) { + String svc; + if (ClearingCategory.B.equalsByKey(clearingMemberCategory) + || ClearingCategory.I.equalsByKey(clearingMemberCategory) + || ClearingCategory.V.equalsByKey(clearingMemberCategory) + ) { + svc = ru.spcex.platform.enumeration.Service.MKR.getKey(); + } else if (ClearingCategory.C.equalsByKey(clearingMemberCategory) + || ClearingCategory.F.equalsByKey(clearingMemberCategory) + ) { + svc = ru.spcex.platform.enumeration.Service.FOND.getKey(); + } else { + log.warn("Unexpected relation Relation={}", clearingMemberCategory); + return null; + } + Relation existRelation = relationMap.getSingleObjectByFieldValues(Map.of( + "consumerId", consumerId, + "service", svc + )); + return existRelation; + } private synchronized RequestInfoUpdate relationUpdate(BaseRequest relationUpdateBaseRequest) { RelationUpdateRequest req = relationUpdateBaseRequest.getRequestPayload(); @@ -171,37 +204,30 @@ public class RelationService extends QueueConsumer implements InitializingBean { } - //Company company = companyMap.getSingleObjectByID(req.getCompanyId()); -// -// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, -// если запись создана и serviceStatus=CLOS, -// изменить запись в relation согласно описанию с тегом При возобнолвении -// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." -// */ -// } -// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, -//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, -// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ -// } - Relation relation = relationMap.getSingleObjectByID(req.getId()); relation.setUpdated(relation.getCreated()); if (req.getServiceStatus() != null) { + log.debug("To relation {} set serivceStatus=\"{}\" by user request.", relation.getId(), req.getServiceStatus()); relation.setServiceStatus(req.getServiceStatus()); } else { -// relation.setServiceStatus(company.getStatus()); + if (relation.getConsumerId() == null) { + log.warn("Relation[{}]. consumerId was null", relation.getId()); + } + Company company = companyMap.getSingleObjectByID(relation.getConsumerId()); + String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + null; + if (ServiceStatus.Active.equalsByKey(toStatus) && ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + log.debug("Set status by resume: {}", relation.getServiceStatus()); + } else { + relation.setServiceStatus(toStatus); + log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}", + company.getId(), company.getWorkflowStatus(), toStatus, relation.getServiceStatus()); + } } + relation.setComment(req.getComment()); relationMap.insert(relation); From a4d1a618cb1db406dbebfc4796af3c2cfa3dbd4f Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 12:17:20 +0300 Subject: [PATCH 4/4] =?UTF-8?q?RequestHelper=20=D1=82.=D0=BA.=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=87=D0=BD=D0=BE=20=D0=BE=D1=82=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=20=D1=81=D1=80=D0=B0=D0=B7=D1=83=20=D0=B2=D0=BE=D0=B7=D0=B2?= =?UTF-8?q?=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20-=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8C=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D0=B5=D1=82=D0=B0=20=D0=B2=20=D0=BB=D0=BE=D0=B3=20?= =?UTF-8?q?info?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/spcex/clearing/company/util/RequestHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java index f134ec949..ac865b66a 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java @@ -74,6 +74,7 @@ public class RequestHelper { public RequestInfoUpdate makeErrorResponse(BaseRequest request, EnumMessage msg) { String errorMsg = msg == null? "" : messageResolver.resolve(msg); + log.info("{}", errorMsg); return new RequestInfoUpdate() .setId(request.getId()) .setStatus(Status.Error)