From bea0c96d643ba1d6be0e023c587bd355a9073ffe Mon Sep 17 00:00:00 2001 From: ialbert Date: Mon, 22 May 2023 17:48:27 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-290 --- .../clearing/config/ValidationConfig.java | 21 ++++ .../spcex/clearing/error/ClearingError.java | 3 + .../RegistryStep3ValidationRule.java | 104 ++++++++++++++++++ .../validation/RegistryValidationStored.java | 5 + .../clearing/session/stage/TaskType.java | 4 + .../stage/impl/ObligationAdmission.java | 79 +++++++++++++ ...=> RequirementsAndObligationCreation.java} | 4 +- .../platform/enumeration/RegistryStatus.java | 2 +- 8 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryValidationStored.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/ObligationAdmission.java rename clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/{RequirmentsAndObligationCreation.java => RequirementsAndObligationCreation.java} (98%) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java index f4677be37..95f979e72 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java @@ -8,11 +8,13 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.execution.ExecutionDeposit; import ru.clearing.classes.statics.data.misc.STrades; +import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.security.Security; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.service.validation.ClrngValidationStored; import ru.spcex.clearing.service.validation.ExecutionDepositValidationRule; +import ru.spcex.clearing.service.validation.RegistryStep3ValidationRule; import ru.spcex.clearing.service.validation.STradesValidationRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.ClearingCategory; @@ -86,4 +88,23 @@ public class ValidationConfig { STradesValidationRule.TradingClearingRegistryPresent); }; } + + @Bean("obligationAndRequirementsAdmissionValidator") + public Function registryValidator() { + return rgs -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(rgs); + addImdg.accept(context, IMDGDistributedNames.Map_Relation); + addImdg.accept(context, IMDGDistributedNames.Map_Session); + addImdg.accept(context, IMDGDistributedNames.Map_SectionDictionary); + addImdg.accept(context, IMDGDistributedNames.Map_Account); + addImdg.accept(context, IMDGDistributedNames.Map_Company); + addImdg.accept(context, IMDGDistributedNames.Map_TradingClearingRegistry); + return new ValidatorImpl<>(context, + RegistryStep3ValidationRule.ClearingAvailable, + RegistryStep3ValidationRule.AccountActive, + RegistryStep3ValidationRule.CompanyActive, + RegistryStep3ValidationRule.TradingClearingRegistryActive); + }; + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java index 7b8cb5e01..9dd2a2595 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java @@ -5,12 +5,15 @@ import ru.spcex.platform.utils.enumeration.IErrorEnumId; public enum ClearingError implements IErrorEnumId { GeneralError(5400L), RecordNotFound(5406L), + CompanyNotActive(5411L), CompanyCreditCheck(5412L), CompanyDebitCheck(5413L), CompanyNotFound(5410L), + AccountNotActive(5415L), SecurityNotFound(5416L), TradingClearingRegistryNotFound(5418L), TradingClearingRegistryNotActive(5419L), + ClearingUnavailableForCompany(5421L), InsecurityObligation(5422L), NewDealsNotFound(5423L), ; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java new file mode 100644 index 000000000..495574f9e --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java @@ -0,0 +1,104 @@ +package ru.spcex.clearing.service.validation; + +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.classes.statics.data.misc.Session; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.platform.dictionary.SectionDictionary; +import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.ServiceStatus; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; + +public enum RegistryStep3ValidationRule implements IValidationRule> { + ClearingAvailable() { + @Override + public Optional validate(ImdgValidationContext context) { + Registry validatedObject = context.getValidatedObject(); + Supplier sectionFind = () -> { + Imdg sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class); + Imdg sectionDictionaryImdg = context.obtainMap(IMDGDistributedNames.Map_SectionDictionary, SectionDictionary.class); + Session session = sessionImdg.getSingleObjectByID(validatedObject.getSessionId()); + if (session == null) { + return "null"; + } else { + SectionDictionary section = sectionDictionaryImdg.getSingleObjectBySQL("code ='" + session.getSection() + "'"); + if (section == null) { + return "null"; + } else { + return section.getName(); + } + } + }; + if (validatedObject.getCompanyId() == null) { + return of(ClearingError.ClearingUnavailableForCompany, sectionFind.get()); + } + Imdg relationImdg = context.obtainMap(IMDGDistributedNames.Map_Relation, Relation.class); + Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", validatedObject.getCompanyId())); + if (relation == null || (!ServiceStatus.Active.equalsByKey(relation.getServiceStatus()) && !ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus()))) { + return of(ClearingError.ClearingUnavailableForCompany, sectionFind.get(), validatedObject.getCompanyId()); + } + context.storeObject(RegistryValidationStored.Relation, relation); + return empty(); + } + }, + AccountActive() { + @Override + public Optional validate(ImdgValidationContext context) { + Registry validatedObject = context.getValidatedObject(); + Relation relation = context.getStoredObject(RegistryValidationStored.Relation); + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectBySQL("id = %d and relationId = %d".formatted(validatedObject.getAccountId(), relation.getId())); + if (account == null || (!IEnumKey.contains(account.getStatus(), ServiceStatus.Active, ServiceStatus.Reopened))) { + return of(ClearingError.AccountNotActive, validatedObject.getAccountId()); + } + return empty(); + } + }, + CompanyActive() { + @Override + public Optional validate(ImdgValidationContext context) { + Registry validatedObject = context.getValidatedObject(); + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + if (validatedObject.getCompanyId() == null) { + return of(ClearingError.CompanyNotActive, validatedObject.getCompanyId()); + } + Company company = companyImdg.getSingleObjectBySQL("id = %d".formatted(validatedObject.getCompanyId())); + if (company == null || !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { + return of(ClearingError.CompanyNotActive, validatedObject.getCompanyId()); + } + return empty(); + } + }, + TradingClearingRegistryActive() { + @Override + public Optional validate(ImdgValidationContext context) { + Registry validatedObject = context.getValidatedObject(); + if (validatedObject.getTradingClearingRegistryId() == null) { + return of(ClearingError.TradingClearingRegistryNotActive, validatedObject.getTradingClearingRegistryId()); + } + Imdg tradingClearingRegistryImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectBySQL("id = " + validatedObject.getTradingClearingRegistryId()); + if (tcr == null || (ServiceStatus.Active.equalsByKey(tcr.getStatus()) || ServiceStatus.Reopened.equalsByKey(tcr.getStatus()))) + return of(ClearingError.TradingClearingRegistryNotActive, validatedObject.getTradingClearingRegistryId()); + return empty(); + } + }, + ; + + @Override + public String ruleName() { + return "STradesValidationRule." + name(); + } +} \ No newline at end of file diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryValidationStored.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryValidationStored.java new file mode 100644 index 000000000..0d7bba6b7 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryValidationStored.java @@ -0,0 +1,5 @@ +package ru.spcex.clearing.service.validation; + +public enum RegistryValidationStored { + Relation +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java index 47d060511..d30d4c7d8 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java @@ -15,6 +15,10 @@ public enum TaskType { * step 2 */ RequirementsAndObligationsCreate, + /** + * step 3 + */ + ObligationsAdmission, /** * step 4 */ diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/ObligationAdmission.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/ObligationAdmission.java new file mode 100644 index 000000000..f62cdd211 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/ObligationAdmission.java @@ -0,0 +1,79 @@ +package ru.spcex.clearing.session.stage.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.session.stage.ISessionStage; +import ru.spcex.clearing.session.stage.StageResult; +import ru.spcex.clearing.session.stage.Task; +import ru.spcex.clearing.session.stage.TaskType; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class ObligationAdmission implements ISessionStage { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg registryImdg; + private final ImdgProvider imdgProvider; + private final Function validatorFactory; + private final IMessageResolver messageResolver; + + @Autowired + public ObligationAdmission(ImdgProvider imdgProvider, + @Qualifier("obligationAndRequirementsAdmissionValidator") Function validatorFactory, + IMessageResolver messageResolver) { + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.imdgProvider = imdgProvider; + this.validatorFactory = validatorFactory; + this.messageResolver = messageResolver; + } + + @SuppressWarnings("unchecked") + @Override + public StageResult submit(Task task) { + if (task.getTaskType() == TaskType.ObligationsAdmission) { + return obligationAdmission((Long) task.getData()); + } + throw new IllegalStateException("Unknown task type: " + task.getTaskType()); + } + + private StageResult obligationAdmission(Long sessionId) { + Collection registries = registryImdg.getCollectionObjectsBySQL("sessionId = " + sessionId); + Map> byGroups = registries.stream().collect(Collectors.groupingBy(Registry::getGroupId)); + for (Map.Entry> grpEntry : byGroups.entrySet()) { + EnumMessage groupError = null; + List rgsGroup = grpEntry.getValue(); + for (Registry rgs : rgsGroup) { + IValidator validator = validatorFactory.apply(rgs); + Optional error = validator.tillFirstError(); + if (error.isPresent()) { + groupError = error.get(); + break; + } + } + if (groupError != null) { + log.warn("error {} for registries groupId = {}", messageResolver.resolve(groupError), grpEntry.getKey()); + for (Registry rgs : rgsGroup) { + rgs.setRegistryStatus(RegistryStatus.NACK.getKey()); + registryImdg.update(rgs); + } + } + } + return new StageResult<>(null, true); + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java similarity index 98% rename from clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java rename to clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java index c10e29938..eaecae3f8 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirementsAndObligationCreation.java @@ -32,14 +32,14 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; @Service -public class RequirmentsAndObligationCreation implements ISessionStage { +public class RequirementsAndObligationCreation implements ISessionStage { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg registryImdg; private final ImdgProvider imdgProvider; @Autowired - public RequirmentsAndObligationCreation(ImdgProvider imdgProvider) { + public RequirementsAndObligationCreation(ImdgProvider imdgProvider) { this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.imdgProvider = imdgProvider; } diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java index 451a06ef8..ec4f38aa2 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum RegistryStatus implements IEnumKey { - OK("OK"), PROC("PROC"), + OK("OK"), PROC("PROC"), NACK("NACK"), ; private final String key;