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 9883ce49a..35cf92ea5 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 @@ -23,6 +23,7 @@ import ru.clearing.platform.dictionary.SectionDictionary; import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest; import ru.spcex.clearing.service.validation.*; import ru.spcex.clearing.util.security.UserRoleVerification; @@ -321,6 +322,20 @@ public class ValidationConfig { }; } + @Bean("refundDateValidator") + public Function refundDateValidator() { + return refundDateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(refundDateRequest); + context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry); + context.setLogPrefix(r -> "groupId=%d refundDate=%s".formatted(r.getGroupId(), r.getRefundDate())); + return new ValidatorImpl<>(context, + RefundDateValidationRule.Fields, + RefundDateValidationRule.RegistriesPresent + ); + }; + } + @Bean public Function piOutboundValidation() { return pmtOut -> { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index 52f735c9b..2bcac2b3d 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -15,6 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SessionContinueE import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest; import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest; import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImportedRequest; @@ -131,6 +132,9 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { callback(RegistryReturnDepositRequest.class) .setFunction(registryService::returnDeposit) .forDestination(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, callbacks::put); + callback(RegistryChangeRefundDateRequest.class) + .setFunction(registryService::changeRefundDate) + .forDestination(Consts.REGISTRY_CHANGE_REFUND_DATE_ACTION, callbacks::put); callback(LauncherCommandRequest.class) .setConsumer(event -> registryService.resetBalances()) .forDestination(Task.createRegistry_GRYT.topic(), callbacks::put); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java index 945ef3c34..1dba37a2e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java @@ -9,6 +9,7 @@ import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; @@ -41,15 +42,18 @@ public class RegistryService { private final Imdg tradingClearingRegistryImdg; private final Imdg registryImdg; private final Function returnDepositVal; + private final Function refundDateVal; private final IMessageResolver msgResolver; public RegistryService(ImdgProvider imdgProvider, @Qualifier("returnDepositValidator") Function returnDepositVal, + @Qualifier("refundDateValidator") Function refundDateVal, IMessageResolver msgResolver) { this.imdgProvider = imdgProvider; this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.returnDepositVal = returnDepositVal; + this.refundDateVal = refundDateVal; this.msgResolver = msgResolver; } @@ -141,6 +145,34 @@ public class RegistryService { return new RequestInfoUpdate(req.getId(), Status.Success, null); } + public RequestInfoUpdate changeRefundDate(BaseRequest req) { + RegistryChangeRefundDateRequest requestPayload = req.getRequestPayload(); + IValidator validator = refundDateVal.apply(requestPayload); + Optional err = validator.tillFirstError(); + if (err.isPresent()) { + log.error("RegistryChangeRefundDateRequest.id={} groupId={}, refundDate={} validation error: {}", + req.getId(), + requestPayload.getGroupId(), + requestPayload.getRefundDate(), + msgResolver.resolve(err.get())); + return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get())); + } + Collection registries = validator.getStored(ValidationStored.RefundDateChangeRegistries); + log.debug("RegistryChangeRefundDateRequest.id={} groupId={}, refundDate={} updating {} registries", + req.getId(), + requestPayload.getGroupId(), + requestPayload.getRefundDate(), + registries.size()); + Instant now = Instant.now(); + for (Registry rgs : registries) { + rgs.setSettlementDate(requestPayload.getRefundDate()); + rgs.setRefundDate(requestPayload.getRefundDate()); + rgs.setUpdated(now); + registryImdg.update(rgs); + } + return new RequestInfoUpdate(req.getId(), Status.Success, null); + } + /** * находим все регистры AM__/AS__ по пришедшему ТКР */ diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RefundDateValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RefundDateValidationRule.java new file mode 100644 index 000000000..a2ce53e70 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RefundDateValidationRule.java @@ -0,0 +1,65 @@ +package ru.spcex.clearing.service.validation; + +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +public enum RefundDateValidationRule implements IValidationRule> { + Fields() { + @Override + public Optional validate(ImdgValidationContext context) { + RegistryChangeRefundDateRequest validatedObject = context.getValidatedObject(); + if (validatedObject.getRefundDate() == null) { + return of(ClearingError.WrongField, "refundDate"); + } + if (validatedObject.getGroupId() == null) { + return of(ClearingError.WrongField, "groupId"); + } + return empty(); + } + }, + RegistriesPresent() { + @Override + public Optional validate(ImdgValidationContext context) { + RegistryChangeRefundDateRequest validatedObject = context.getValidatedObject(); + Imdg rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class); + ImdgPredicateBuilder pb = rgsImdg.predicateBuilder(); + ImdgPredicate prdct = pb.and( + pb.equals("groupId", validatedObject.getGroupId()), + pb.or( + pb.equals("registryStatus", RegistryStatus.PROC.getKey()), + pb.equals("registryStatus", RegistryStatus.MNG.getKey()) + ) + ); + Collection rgss = rgsImdg.getCollectionObjectsByPredicate(prdct).stream() + .filter(rgs -> Objects.nonNull(rgs.getSettlementDate())) + .filter(rgs -> Objects.nonNull(rgs.getValueDate())) + .filter(rgs -> rgs.getValueDate().isBefore(rgs.getSettlementDate())) + .collect(Collectors.toList()); + + if (rgss.size() < 1) { + return of(ClearingError.RecordNotFound, "groupId=" + validatedObject.getGroupId()); + } + context.storeObject(ValidationStored.RefundDateChangeRegistries, rgss); + return empty(); + } + }; + + @Override + public String ruleName() { + return "RefundDateValidationRule." + name(); + } +} \ No newline at end of file diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java index 79938a220..c5a0efe7c 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java @@ -20,6 +20,8 @@ public enum ValidationStored { ReturnDepositDmx, + RefundDateChangeRegistries, + CompanyByTradingCode, Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security,