ialbert 2026-04-29 15:05:20 +03:00
parent ea0a449602
commit 9223d8b391
6 changed files with 375 additions and 2 deletions

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.config;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@ -41,11 +42,14 @@ 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.DmauRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.IdentificationFundsRequest;
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.service.AssetTrio;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.validation.AnltAccLoad;
import ru.spcex.clearing.service.validation.ClrngValidationStored;
import ru.spcex.clearing.service.validation.CompanyByTradingCodeValidationRule;
@ -68,18 +72,27 @@ import ru.spcex.clearing.service.validation.SecurityBySecurityCodeValidationRule
import ru.spcex.clearing.service.validation.SessionTerminationValidationRule;
import ru.spcex.clearing.service.validation.SplitDepositRequestValidationRule;
import ru.spcex.clearing.service.validation.StatusExtractValidationRule;
import ru.spcex.clearing.service.validation.WithdrawalFundsValidationRule;
import ru.spcex.clearing.service.validation.WithdrawalFundsValidationStore;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.enumeration.CompanySymbol;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.LogPrefixId;
import ru.spcex.platform.imdg.validation.rule.CurrencyCodeValidationRule;
import ru.spcex.platform.imdg.validation.rule.PresentById;
import ru.spcex.platform.imdg.validation.rule.PresentByPredicate;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidationRule;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -113,8 +126,9 @@ public class ValidationConfig {
Imdg<PaymentInstruction> pmtImdg;
Imdg<ClearingMemberCategory> ctgrImdg;
ImdgProvider imdgProvider;
AssetTBFProcessing assetsMng;
public ValidationConfig(ImdgProvider imdgProvider) {
public ValidationConfig(ImdgProvider imdgProvider, AssetTBFProcessing assetsMng) {
this.imdgRelation = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
this.imdgCompany = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.imdgCurrency = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
@ -142,6 +156,7 @@ public class ValidationConfig {
this.currencyPairSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairSecurity, CurrencyPairSecurity.class);
this.digitalCertificateSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DigitalCertificateSecurity, DigitalCertificateSecurity.class);
this.imdgProvider = imdgProvider;
this.assetsMng = assetsMng;
}
//@Bean("adminRoleVerification")
@ -399,6 +414,81 @@ public class ValidationConfig {
};
}
@Bean("withdrawalFundsValidator")
public Function<DmauRegistryRequest, IValidator> withdrawalFundsValidator() {
return identificationFundsRequest -> {
ImdgValidationContext<DmauRegistryRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(identificationFundsRequest);
context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
context.addImdg(IMDGDistributedNames.Map_CompanySymbols, imdgCompanySymbols);
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistryList, imdgTradingClearingRegistryList);
context.setLogPrefix(dmauRegistryRequest ->
"[debitCorrAccount:%s]".formatted(dmauRegistryRequest.getDebitCorrAccount()
));
ImdgPredicateBuilder cmpSymbPb = imdgCompanySymbols.predicateBuilder();
var cmpSymbCheck = PresentByPredicate.builder(
(Function<DmauRegistryRequest, ImdgPredicate>) req -> cmpSymbPb.and(
cmpSymbPb.equals("companyId", req.getSenderId()),
cmpSymbPb.equals("companySymbol", CompanySymbol.BIC.getKey())
))
.mapName(IMDGDistributedNames.Map_CompanySymbols)
.errorProvider(req -> new EnumMessage(ClearingError.RecordNotFound, "companySymbol"))
.store(WithdrawalFundsValidationStore.CompanySymbol)
.build()
;
ImdgPredicateBuilder cmpPb = imdgCompany.predicateBuilder();
var cmpCheck = PresentByPredicate.builder(new IdEqualPredicate<>(
cmpPb, DmauRegistryRequest::getSenderId
))
.mapName(IMDGDistributedNames.Map_Company)
.errorProvider(req -> new EnumMessage(ClearingError.RecordNotFound, "company"))
.store(WithdrawalFundsValidationStore.Company)
.build();
ImdgPredicateBuilder accPb = imdgAccount.predicateBuilder();
var accCheck = PresentByPredicate.builder(new IdEqualPredicate<>(
accPb, DmauRegistryRequest::getCreditLegAccountId
))
.mapName(IMDGDistributedNames.Map_Account)
.errorProvider(req -> new EnumMessage(ClearingError.RecordNotFound, "account"))
.store(WithdrawalFundsValidationStore.Account)
.build();
var assetPresent = new IValidationRule<ImdgValidationContext<DmauRegistryRequest>>() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<DmauRegistryRequest> ctx) {
Company cmp = ctx.getStoredObject(WithdrawalFundsValidationStore.Company);
Account acc = ctx.getStoredObject(WithdrawalFundsValidationStore.Account);
Optional<AssetTrio> assetsTrio = assetsMng.searchMoneyByAccAndCompany(cmp.getId(), acc.getId());
if (assetsTrio.isEmpty()) {
return of(ClearingError.RecordNotFound, "AM_F/AM_B/AM_T");
}
ctx.storeObject(WithdrawalFundsValidationStore.AssetTrio, assetsTrio.get());
return empty();
}
@Override
public String ruleName() {
return "assets-present";
}
};
return new ValidatorImpl<>(context,
WithdrawalFundsValidationRule.Fields,
cmpSymbCheck,
cmpCheck,
accCheck,
assetPresent,
WithdrawalFundsValidationRule.TcrPresent
);
};
}
@Bean("splitDepositValidator")
public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() {
return refundDateRequest -> {

View file

@ -23,6 +23,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.DmauRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.IdentificationFundsRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
@ -40,6 +41,7 @@ import ru.spcex.clearing.service.execution.ExecutionFondComponent;
import ru.spcex.clearing.service.executors.Sdf06Executor;
import ru.spcex.clearing.service.executors.Sdf10Executor;
import ru.spcex.clearing.service.payment.PaymentInstructionOutboundService;
import ru.spcex.clearing.service.payment.WithdrawalFundsService;
import ru.spcex.clearing.session.stage.SessionTerminator;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.stage.impl.BalanceRevise;
@ -65,6 +67,7 @@ public class EventsReceiver extends QueueConsumerV2 implements InitializingBean
private final StatementServiceV2 statementService;
private final SessionTerminator sessionTerminator;
private final PaymentInstructionOutboundService pmtOutboundService;
private final WithdrawalFundsService withdrawalFundsService;
private final ExecutionCurrencyComponent execCurrUpload;
private final ExecutionDepositComponent execDepUpload;
private final ExecutionFondComponent execFondUpload;
@ -81,7 +84,7 @@ public class EventsReceiver extends QueueConsumerV2 implements InitializingBean
Sdf05Sender sdf05Sender,
StatementServiceV2 statementService,
SessionTerminator sessionTerminator,
PaymentInstructionOutboundService pmtOutboundService,
PaymentInstructionOutboundService pmtOutboundService, WithdrawalFundsService withdrawalFundsService,
ExecutionCurrencyComponent execCurrUpload,
ExecutionDepositComponent execDepUpload,
ExecutionFondComponent execFondUpload) {
@ -98,6 +101,7 @@ public class EventsReceiver extends QueueConsumerV2 implements InitializingBean
this.statementService = statementService;
this.sessionTerminator = sessionTerminator;
this.pmtOutboundService = pmtOutboundService;
this.withdrawalFundsService = withdrawalFundsService;
this.execCurrUpload = execCurrUpload;
this.execDepUpload = execDepUpload;
this.execFondUpload = execFondUpload;
@ -144,6 +148,9 @@ public class EventsReceiver extends QueueConsumerV2 implements InitializingBean
callback(PIClearingOutbondActionNewRequest.class)
.setFunction(pmtOutboundService::sendOutBoundPayment)
.forDestination(Consts.PAYMENT_INSTRUCTION_CLEARING_OUTBOUND_ACTION, callbacks::put);
callback(DmauRegistryRequest.class)
.setFunction(withdrawalFundsService::withdrawalFunds)
.forDestination(Consts.REGISTRY_DMAU_CREATE_ACTION, callbacks::put);
callback(StatementRequest.class)
.setConsumer(statementService::processReq)
.forDestination(Consts.STATEMENT_PROCESS, callbacks::put);

View file

@ -0,0 +1,192 @@
package ru.spcex.clearing.service.payment;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Optional;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.error.ClearingError;
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.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DmauRegistryRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.Sdf54Creator;
import ru.spcex.clearing.service.SpecifUtil;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.registry.DmiService;
import ru.spcex.clearing.service.validation.WithdrawalFundsValidationStore;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.InOutDirection;
import ru.spcex.platform.enumeration.TransactionStatus;
import ru.spcex.platform.enumeration.UserRole;
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.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.log.ExceptionUtils;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.time.TimeUtil;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class WithdrawalFundsService {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Function<DmauRegistryRequest, IValidator> withdrawalFundsVal;
private final Sdf54Creator sdf54Creator;
private final Imdg<SDf54> sdf54Imdg;
private final Imdg<PaymentInstruction> pmtImdg;
private final KafkaSender kafkaSender;
private final ImdgId idGen;
private final RequestHelper reqHelp;
private final UserRoleVerification rights;
private final IMessageResolver msgResolver;
private final AssetTBFProcessing assetsMng;
private final DmiService dmiService;
public WithdrawalFundsService(Function<DmauRegistryRequest, IValidator> withdrawalFundsVal, Sdf54Creator sdf54Creator, ImdgProvider imdgProvider, KafkaSender kafkaSender, RequestHelper reqHelp, UserRoleVerification rights, IMessageResolver msgResolver, AssetTBFProcessing assetsMng, DmiService dmiService) {
this.withdrawalFundsVal = withdrawalFundsVal;
this.sdf54Creator = sdf54Creator;
this.kafkaSender = kafkaSender;
this.sdf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.idGen = imdgProvider.getImdgIdGenerator();
this.reqHelp = reqHelp;
this.rights = rights;
this.msgResolver = msgResolver;
this.assetsMng = assetsMng;
this.dmiService = dmiService;
}
public RequestInfoUpdate withdrawalFunds(BaseRequest<DmauRegistryRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
DmauRegistryRequest payload = req.getRequestPayload();
IValidator validator = withdrawalFundsVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("DmauRegistryRequest.id={} debitCorrAccount={} validation error: {}",
req.getId(),
payload != null ? payload.getDebitCorrAccount() : null,
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
log.info("DmauRegistryRequest.id={} debitCorrAccount={} validation passed", req.getId(), payload.getDebitCorrAccount());
CompanySymbols cmpSymb = validator.getStored(WithdrawalFundsValidationStore.CompanySymbol);
Company cmp = validator.getStored(WithdrawalFundsValidationStore.Company);
Account acc = validator.getStored(WithdrawalFundsValidationStore.Account);
AssetTrio assets = validator.getStored(WithdrawalFundsValidationStore.AssetTrio);
TradingClearingRegistry tcr = validator.getStored(WithdrawalFundsValidationStore.TCR);
String curr = TextUtil.isEmpty(payload.getSecuritySymbol()) ? CurrencyCode.RUB.getKey() : payload.getSecuritySymbol();
Instant now = Instant.now();
LocalDate nowDate = TimeUtil.toLocalDate(now);
PaymentInstruction pmtIns = new PaymentInstruction();
pmtIns.setSenderId(payload.getSenderId());
pmtIns.setPayeeBic(cmpSymb.getCompanySymbolValue());
pmtIns.setAdresseeBic(payload.getDebitBIC());
pmtIns.setPayeeBankName(cmp.getShortName());
pmtIns.setAddresseeBankName(payload.getDebitBankName());
pmtIns.setPaymentDate(now);
pmtIns.setPaymentPurpose(extractPaymentPurpose(payload));
pmtIns.setSettlementDate(nowDate);
pmtIns.setCreditLeg_amount(payload.getAmount());
pmtIns.setDebitLeg_amount(payload.getAmount());
pmtIns.setCreditLeg_accountId(payload.getCreditLegAccountId());
pmtIns.setCreditLeg_account(acc.getAccount());
pmtIns.setDebit_csAccount(payload.getDebitCorrAccount());
pmtIns.setDebitLeg_account(payload.getDebitLegAccount());
pmtIns.setCreditLeg_direction(InOutDirection.out.getKey());
pmtIns.setDebitLeg_direction(InOutDirection.in.getKey());
pmtIns.setCreditLeg_currencyCode(payload.getSecuritySymbol());
pmtIns.setDebitLeg_currencyCode(payload.getSecuritySymbol());
pmtIns.setCreditLeg_securityId(payload.getSecurityId());
pmtIns.setDebitLeg_securityId(payload.getSecurityId());
pmtIns.setTransactionStatus(TransactionStatus.stld.getKey());
pmtIns.setCreated(now);
pmtIns.setClearingDate(nowDate);
pmtImdg.insert(pmtIns);
log.info("created PaymentInstruction.id={}", pmtIns.getId());
SDf54 sDf54;
try {
sDf54 = sdf54Creator.create(pmtIns);
} catch (IllegalStateException e) {
log.error(ExceptionUtils.getStackTrace(e));
return failedResponse(req, now, pmtIns);
}
sDf54.setId(idGen.nextId());
sDf54.setGenerationId(pmtIns.getId());
sDf54.setRbankcode(pmtIns.getAdresseeBic());
sDf54.setC_acc_cred(pmtIns.getDebit_csAccount());
SpecifUtil.fillSegmentsBy35Symbols(pmtIns.getAddresseeBankName(),
sDf54::setRbanknam1,
sDf54::setRbanknam2,
sDf54::setRbanknam3,
sDf54::setRbanknam4,
sDf54::setRbanknam5);
SpecifUtil.fillSegmentsBy35Symbols(payload.getDebitCompanyName(),
sDf54::setRclientn1,
sDf54::setRclientn2,
sDf54::setRclientn3,
sDf54::setRclientn4
);
sDf54.setInn_cred(payload.getDebitINN());
sDf54.setKpp_cred(payload.getDebitKPP());
sdf54Imdg.insert(sDf54);
log.info("created sdf54.id={}", sDf54.getId());
dmiService.setProcComment(tcr.getId(),
curr,
safeBD(payload.getAmount()).negate(),
sDf54.getDocnm_ref());
log.debug("recalculating assests...");
assetsMng.process(assets.a__b(), assets.a__t(), assets.a__f(), BigDecimal.ZERO);
SdfClearingRequest exp = new SdfClearingRequest();
exp.setGroupId(sDf54.getGenerationId());
kafkaSender.sendRequestToQueue(Consts.SDF54_PROCESS, exp);
return reqHelp.success(req.getId());
}
private RequestInfoUpdate failedResponse(BaseRequest<DmauRegistryRequest> req,
Instant now,
PaymentInstruction pmtIns) {
pmtIns.setTransactionStatus(TransactionStatus.fail.getKey());
pmtIns.setUpdated(now);
pmtImdg.update(pmtIns);
return reqHelp.error(req.getId(), ClearingError.GeneralError);
}
private String extractPaymentPurpose(DmauRegistryRequest payload) {
if (!TextUtil.isEmpty(payload.getPaymentPurpose())) {
return payload.getPaymentPurpose();
}
if (CurrencyCode.RUB.equalsByKey(payload.getSecuritySymbol())) {
return "Вывод средств с регистра невыясненных денежных средств по %s"
.formatted(payload.getSecuritySymbol());
} else {
return "Withdrawal of funds from the register %s of unidentified funds"
.formatted(payload.getSecuritySymbol());
}
}
}

View file

@ -0,0 +1,69 @@
package ru.spcex.clearing.service.validation;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.Optional;
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.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DmauRegistryRequest;
import ru.spcex.clearing.service.AnltSearcher;
import ru.spcex.clearing.service.TcrSearcher;
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.validation.IValidationRule;
public enum WithdrawalFundsValidationRule implements IValidationRule<ImdgValidationContext<DmauRegistryRequest>> {
Fields() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<DmauRegistryRequest> context) {
DmauRegistryRequest validatedObject = context.getValidatedObject();
if (validatedObject.getAmount() == null || validatedObject.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
return of(ClearingError.WrongField, "amount");
}
if (validatedObject.getBalance() == null || validatedObject.getBalance().compareTo(validatedObject.getAmount()) < 0) {
return of(ClearingError.WrongField, "balance");
}
return empty();
}
},
TcrPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<DmauRegistryRequest> context) {
Account accCred = context.getStoredObject(WithdrawalFundsValidationStore.Account);
Company addressee = context.getStoredObject(WithdrawalFundsValidationStore.Company);
Imdg<TradingClearingRegistry> tcrImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
Imdg<TradingClearingRegistryList> tcrListImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
TcrSearcher tcrSearcher = new TcrSearcher(tcrImdg, tcrListImdg, companyImdg, accountImdg);
AnltSearcher.AnltSearch srchRes = tcrSearcher.searchByAccountId(accCred.getId(), accCred.getCurrency());
if (!srchRes.isFound()) {
return Optional.of(srchRes.getError());
}
if (srchRes.getCompany() != null) {
if (!Objects.equals(srchRes.getCompany().getId(), addressee.getId())) {
return of(ClearingError.AccountIsNotMatchedWithCompany, accCred.getId(), addressee.getId());
}
}
TradingClearingRegistry tcr = srchRes.getTcr();
if (tcr == null) {
return of(ClearingError.RecordNotFound, "TCR");
}
context.storeObject(WithdrawalFundsValidationStore.TCR, tcr);
return Optional.empty();
}
};
private final static Logger log = LoggerFactory.getLogger(WithdrawalFundsValidationRule.class);
@Override
public String ruleName() {
return "WithdrawalFundsValidationRule." + name();
}
}

View file

@ -0,0 +1,10 @@
package ru.spcex.clearing.service.validation;
public enum WithdrawalFundsValidationStore {
CompanySymbol,
Company,
Account,
AssetTrio,
TCR,
;
}

View file

@ -2,6 +2,8 @@ package ru.spcex.platform.imdg.validation.rule;
import java.util.Optional;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
@ -10,6 +12,7 @@ import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public class PresentByPredicate<T> implements IValidationRule<ImdgValidationContext<T>> {
private static final Logger log = LoggerFactory.getLogger(PresentByPredicate.class);
private final String mapName;
private final Function<T, EnumMessage> errorProvider;
@ -42,8 +45,10 @@ public class PresentByPredicate<T> implements IValidationRule<ImdgValidationCont
if (obj == null) {
EnumMessage errMsg = errorProvider.apply(validatedObject);
log.debug("object not found by predicate: {}", predicate);
return Optional.of(errMsg);
}
log.debug("object found by predicate [{}]: {}.id={}", predicate, mapName, obj.getId());
if (storeEnabled != null) {
context.storeObject(storeEnabled, obj);