registries/identificationFunds

This commit is contained in:
ialbert 2023-09-21 18:56:07 +03:00
parent 69aa7aa047
commit e366b647cc
5 changed files with 210 additions and 14 deletions

View file

@ -26,10 +26,7 @@ import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
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.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.service.validation.*;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
@ -369,6 +366,26 @@ public class ValidationConfig {
};
}
@Bean("identificationFundsValidator")
public Function<IdentificationFundsRequest, IValidator> identificationFundsValidator() {
return identificationFundsRequest -> {
ImdgValidationContext<IdentificationFundsRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(identificationFundsRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
IdentificationFundsValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
IdentificationFundsValidationRule.RegistryCodeCheck,
IdentificationFundsValidationRule.BalanceCheck,
IdentificationFundsValidationRule.TcrCheck,
IdentificationFundsValidationRule.AssetsCheck
);
};
}
@Bean("splitDepositValidator")
public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() {
return refundDateRequest -> {

View file

@ -17,10 +17,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.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImportedRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
@ -159,6 +156,9 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
callback(RegistryChangeStatusExtractRequest.class)
.setFunction(registryService::changeStatusExtract)
.forDestination(Consts.REGISTRY_CHANGE_STATUS_EXTRACT_ACTION, callbacks::put);
callback(IdentificationFundsRequest.class)
.setFunction(registryService::identificationFunds)
.forDestination(Consts.REGISTRY_IDENTIFICATION_FUNDS, callbacks::put);
callback(RegistryChangeRefundDateRequest.class)
.setFunction(registryService::changeRefundDate)
.forDestination(Consts.REGISTRY_CHANGE_REFUND_DATE_ACTION, callbacks::put);

View file

@ -12,10 +12,7 @@ import ru.spcex.clearing.notification.NotificationSender;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
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.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.service.integration.GatewayRequestCreator;
@ -48,6 +45,7 @@ import java.util.function.Function;
import java.util.function.Supplier;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service
public class RegistryService {
@ -59,6 +57,7 @@ public class RegistryService {
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
private final Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal;
private final Function<IdentificationFundsRequest, IValidator> identificationFundsVal;
private final Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal;
private final GatewayRequester gateway;
private final TradingTimeService trdTime;
@ -72,15 +71,22 @@ public class RegistryService {
public RegistryService(ImdgProvider imdgProvider,
@Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal,
@Qualifier("refundDateValidator") Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal,
@Qualifier("identificationFundsValidator") Function<IdentificationFundsRequest, IValidator> identificationFundsVal,
@Qualifier("splitDepositValidator") Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal,
@Qualifier("statusExtractValidator") Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal,
GatewayRequester gateway, TradingTimeService tradingTimeService, NotificationSender notification, IMessageResolver msgResolver,
RequestHelper reqHelp, UserRoleVerification rights, AssetTBFProcessing assets) {
GatewayRequester gateway,
TradingTimeService tradingTimeService,
NotificationSender notification,
IMessageResolver msgResolver,
RequestHelper reqHelp,
UserRoleVerification rights,
AssetTBFProcessing assets) {
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.identificationFundsVal = identificationFundsVal;
this.splitDepositActionVal = splitDepositActionVal;
this.statusExtractVal = statusExtractVal;
this.gateway = gateway;
@ -227,6 +233,36 @@ public class RegistryService {
return reqHelp.success(req.getId());
}
public RequestInfoUpdate identificationFunds(BaseRequest<IdentificationFundsRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
IdentificationFundsRequest payload = req.getRequestPayload();
IValidator validator = identificationFundsVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("IdentificationFundsRequest.id={} validation error: {}",
req.getId(),
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
Registry dmau = validator.getStored(Stored.PresentById);
AssetTrio asts = validator.getStored(ValidationStored.IdentificationFundsAssetTrio);
BigDecimal dmauBalance = safeBD(dmau.getBalance());
BigDecimal reqBalance = payload.getBalance();
BigDecimal am_tBalance = safeBD(asts.a__t().getBalance());
dmau.setBalance(dmauBalance.subtract(reqBalance));
asts.a__t().setBalance(am_tBalance.add(reqBalance));
Instant now = Instant.now();
dmau.setUpdated(now);
asts.a__t().setUpdated(now);
registryImdg.update(dmau);
registryImdg.update(asts.a__t());
assets.process(asts.a__b(), asts.a__t(), asts.a__f(), BigDecimal.ZERO);
return reqHelp.success(req.getId());
}
public RequestInfoUpdate changeRefundDate(BaseRequest<RegistryChangeRefundDateRequest> req) {
RegistryChangeRefundDateRequest requestPayload = req.getRequestPayload();
IValidator validator = refundDateVal.apply(requestPayload);

View file

@ -0,0 +1,141 @@
package ru.spcex.clearing.service.validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.IdentificationFundsRequest;
import ru.spcex.clearing.service.AnltSearcher;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.Stored;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.math.BigDecimal;
import java.util.Optional;
import static ru.spcex.clearing.service.registry.RegistryManager.equalsByCode;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
public enum IdentificationFundsValidationRule implements IValidationRule<ImdgValidationContext<IdentificationFundsRequest>> {
Fields() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<IdentificationFundsRequest> context) {
IdentificationFundsRequest validatedObject = context.getValidatedObject();
if (validatedObject.getId() == null) {
return of(ClearingError.WrongField, "id");
}
if (validatedObject.getTradingClearingRegistryId() == null) {
return of(ClearingError.WrongField, "tradingClearingRegistryId");
}
if (validatedObject.getBalance() == null || validatedObject.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
return of(ClearingError.WrongField, "balance");
}
return empty();
}
},
RegistryCodeCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<IdentificationFundsRequest> context) {
Registry rgs = context.getStoredObject(Stored.PresentById);
if (!equalsByCode(RegistryTradingParams.DMAU, rgs)) {
return of(ClearingError.RgsWrongCode, "%s.id=%d".formatted(
rgs.getRegistryCode(),
rgs.getId()));
}
return empty();
}
},
BalanceCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<IdentificationFundsRequest> context) {
IdentificationFundsRequest validatedObject = context.getValidatedObject();
Registry rgs = context.getStoredObject(Stored.PresentById);
if (safeBD(rgs.getBalance()).compareTo(BigDecimal.ZERO) <= 0) {
return of(ClearingError.BalanceInsufficient);
}
if (safeBD(rgs.getBalance())
.subtract(safeBD(validatedObject.getBalance()))
.compareTo(BigDecimal.ZERO) < 0) {
return of(ClearingError.BalanceInsufficient);
}
return empty();
}
},
TcrCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<IdentificationFundsRequest> context) {
IdentificationFundsRequest validatedObject = context.getValidatedObject();
Registry rgs = context.getStoredObject(Stored.PresentById);
if (rgs == null) {
return of(ClearingError.GeneralError);
}
Imdg<TradingClearingRegistry> tcrImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
TradingClearingRegistry tcr = tcrImdg.getSingleObjectByID(validatedObject.getTradingClearingRegistryId());
if (tcr == null) {
return of(ClearingError.TCRegistryNotFound, validatedObject.getTradingClearingRegistryId());
}
if (!ServiceStatus.Active.equalsByKey(tcr.getStatus())) {
return of(ClearingError.TradingClearingRegistryNotActive, tcr.getCode());
}
if (tcr.getMoneyAccountId() == null) {
return of(ClearingError.AccountNotFoundB, "null"); //mb other error
}
Imdg<Account> accImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account acc = accImdg.getSingleObjectByID(tcr.getMoneyAccountId());
if (acc == null) {
return of(ClearingError.AccountNotFoundB, tcr.getMoneyAccountId());
}
if (!AccountType.Info.equalsByKey(acc.getAccountType())) {
return of(ClearingError.AccountWrongType, acc.getAccountType());
}
Imdg<Company> cmpImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
Company company = cmpImdg.getSingleObjectByID(tcr.getCompanyId());
if (company == null) {
return of(ClearingError.CompanyNotFoundB, tcr.getCompanyId());
}
AnltSearcher.AnltSearch res = new AnltSearcher.AnltSearch(acc, company, tcr);
context.storeObject(ValidationStored.IdentificationFundsTcrSearch, res);
return empty();
}
},
AssetsCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<IdentificationFundsRequest> context) {
AnltSearcher.AnltSearch tcrSearch = context.getStoredObject(ValidationStored.IdentificationFundsTcrSearch);
if (tcrSearch == null) {
return of(ClearingError.RecordNotFound, "AM*T");
}
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
AssetTBFProcessing assets = new AssetTBFProcessing(rgsImdg);
Optional<AssetTrio> assetTrio = assets.searchMoneyByAccAndCompany(tcrSearch.getCompany().getId(), tcrSearch.getAccount().getId());
if (assetTrio.isEmpty()) {
return of(ClearingError.RecordNotFound, "AM*T");
}
context.storeObject(ValidationStored.IdentificationFundsAssetTrio, assetTrio.get());
return Optional.empty();
}
}
;
private final static Logger log = LoggerFactory.getLogger(IdentificationFundsValidationRule.class);
@Override
public String ruleName() {
return "IdentificationFundsValidationRule." + name();
}
}

View file

@ -20,6 +20,8 @@ public enum ValidationStored {
ReturnDepositDmx,
IdentificationFundsTcrSearch, IdentificationFundsAssetTrio,
RefundDateChangeRegistries,
CompanyByTradingCode,