ExecutionDeposit заполнение поля CounterPartyTradingClearingRegistryId

SDF10
This commit is contained in:
ialbert 2023-08-15 19:33:03 +03:00
parent 00090857a8
commit eeb8e4dc5f
8 changed files with 284 additions and 195 deletions

View file

@ -202,7 +202,7 @@ public class ValidationConfig {
context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equitySecurityImdg);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
CompanyByDepoCodeValidationRule.instance(SDf21::getDepoCodeCl),
CompanyByTradingCodeValidationRule.instance(SDf21::getDepoCodeCl),
Sdf21ValidationRule.AccountPresent,
SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode)
);
@ -279,9 +279,10 @@ public class ValidationConfig {
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
Sdf10ValidationRule.DepoAccountPresent,
CompanyByDepoCodeValidationRule.instance(SDf10::getDepoCode),
CompanyByTradingCodeValidationRule.instance(SDf10::getDepoCode),
Sdf10ValidationRule.CompanyStatus,
SecurityBySecurityCodeValidationRule.instance(SDf10::getSecurityCode)
SecurityBySecurityCodeValidationRule.instance(SDf10::getSecurityCode),
Sdf10ValidationRule.Balance
);
};
}

View file

@ -25,6 +25,7 @@ import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IEnumKey;
@ -239,6 +240,17 @@ public class ExecutionDepositComponent {
eDeposit.setContract(contract);
eDeposit.setCounterPartyId(counterCompany.getId());
eDeposit.setSecurityCode(sTrades.getSecCode());
{
ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder();
STrades counterSTrades = sTradeImdg.getFirstObjectByPredicate(strPb.and(
strPb.equals("tradeNum", sTrades.getTradeNum()),
strPb.equals("section", sTrades.getSection()),
strPb.not(strPb.equals("section", sTrades.getSection()))));
if (counterSTrades != null) {
searchTcrByStrades(counterSTrades)
.ifPresent(tcr -> eDeposit.setCounterPartyTradingClearingRegistryId(tcr.getId()));
}
}
return eDeposit;
}
@ -265,4 +277,14 @@ public class ExecutionDepositComponent {
private void logError(Long sTradeId, EnumMessage msg) {
log.warn("sTrade id={} {}", sTradeId, msgResolver.resolve(msg));
}
private Optional<TradingClearingRegistry> searchTcrByStrades(STrades sTrades) {
IValidator counterValidator = stradesValidator.apply(sTrades);
Optional<EnumMessage> err = counterValidator.tillFirstError();
if (err.isPresent()) {
log.error("couldn't extract setCounterPartyTradingClearingRegistryId from strades.id={}", sTrades.getId());
return Optional.empty();
}
return counterValidator.getStored(ValidationStored.STradesTradingClearingRegistry);
}
}

View file

@ -12,22 +12,26 @@ import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf06;
import ru.clearing.classes.statics.data.sdf.SDf07;
import ru.clearing.classes.statics.data.sdf.SDf10;
import ru.clearing.classes.statics.data.sdf.SDf11;
import ru.clearing.classes.statics.data.statement.Statement;
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.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse;
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.platform.enumeration.*;
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.number.BigDecimalUtil;
import ru.spcex.platform.utils.validation.IValidator;
@ -35,8 +39,10 @@ import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@Service
@ -51,11 +57,11 @@ public class Sdf10Executor {
private final Imdg<DepoAccount> depoAccountImdg;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Company> companyImdg;
private final Imdg<SDf06> sdf06Imdg;
private final Imdg<SDf07> sdf07Imdg;
private final Imdg<SDf10> sdf10Imdg;
private final Imdg<SDf11> sdf11Imdg;
private final ImdgId idGenerator;
private final IMessageResolver messageResolver;
private final Function<SDf06, IValidator> sDf06Validator;
private final Function<SDf10, IValidator> sDf10Validator;
private final KafkaSender kafkaSender;
private final static BigDecimal successResult = BigDecimal.ZERO;
@ -65,14 +71,15 @@ public class Sdf10Executor {
private final static BigDecimal errorResult1 = new BigDecimal("1");
//отказ от gateway
private final static BigDecimal errorResult3 = new BigDecimal("3");
private final static String DEFAULT_11_RES = "result";
private Long sdf10GroupId;
private Long sdf07GroupId;
private Long sdf11GroupId;
@Autowired
public Sdf10Executor(ImdgProvider imdgProvider,
IMessageResolver messageResolver,
@Qualifier("sdf06ValidatorNew") Function<SDf06, IValidator> sDf06Validator,
@Qualifier("sdf10Validator") Function<SDf10, IValidator> sDf10Validator,
KafkaSender kafkaSender) {
this.imdgProvider = imdgProvider;
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
@ -84,15 +91,14 @@ public class Sdf10Executor {
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.messageResolver = messageResolver;
this.sDf06Validator = sDf06Validator;
this.sDf10Validator = sDf10Validator;
this.kafkaSender = kafkaSender;
this.sdf06Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf06, SDf06.class);
this.sdf07Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf07, SDf07.class);
this.sdf10Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class);
this.sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class);
}
public void execute(BaseRequest<StatementRequest> systemRequest) {
Imdg<SDf10> sdf10Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class);
Imdg<SDf11> sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class);
Long groupId = systemRequest.getRequestPayload().getGroupId();
Collection<SDf10> sdfs = sdf10Imdg.getCollectionObjectsByFieldValues(Map.of(
"generationId", groupId
@ -100,157 +106,142 @@ public class Sdf10Executor {
Instant now = Instant.now();
Long sdf11GroupId = idGenerator.nextId();
log.info("processing SDF10 groupId: {} sdf10s: {}", groupId, sdfs.size());
for (SDf10 sdf10 : sdfs) {
SDf11 sdf11 = createSdf11(sdf10, now);
sdf11.setGenerationId(sdf11GroupId);
sdf11.setResult(SdfResult.OK.getKey());
sdf11Imdg.insert(sdf11);
log.debug("sdf10.id={} created sdf11.id={}", sdf10.getId(), sdf11.getId());
if (sdf10GroupId != null) {
log.warn("currently awaiting gateway response for groupId: {}. skipping groupId {}", sdf10GroupId, groupId);
sdfs.forEach(sdf10 -> {
SDf11 errorSdf11 = createSdf11(sdf10, now, DEFAULT_11_RES);
errorSdf11.setGenerationId(sdf11GroupId);
this.sdf11Imdg.insert(errorSdf11);
});
sendToExporter(sdf11GroupId);
return;
}
Collection<AssetOperationRequest> requests = new ArrayList<>();
boolean sdf11WasCreated = false;
for (SDf10 sDf10 : sdfs) {
IValidator validator = sDf10Validator.apply(sDf10);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.debug("sdf10.id={} validation error: {}", sDf10.getId(), messageResolver.resolve(err.get()));
SDf11 errorSdf11;
String errorResult;
Statement stmt = null;
if (needToCreateStatement(err.get())) {
errorResult = DEFAULT_11_RES;
stmt = createStatementBySdf10(sDf10,
((Company) validator.getStored(ValidationStored.CompanyByTradingCode)).getId(),
validator.getStored(ValidationStored.Sdf10Account));
} else {
errorResult = DEFAULT_11_RES;
}
errorSdf11 = createSdf11(sDf10, now, errorResult);
errorSdf11.setGenerationId(sdf11GroupId);
this.sdf11Imdg.insert(errorSdf11);
sdf11WasCreated = true;
if (stmt != null) {
stmt.setOutSDfId(errorSdf11.getId());
statementImdg.insert(stmt);
log.debug("Statement created: {}", stmt.getId());
}
continue;
}
Company company = validator.getStored(ValidationStored.CompanyByTradingCode);
Account account = validator.getStored(ValidationStored.Sdf10Account);
TradingClearingRegistry tcr = validator.getStored(ValidationStored.Sdf10Tcr);
Statement stmt = createStatementBySdf10(sDf10, company.getId(), account);
statementImdg.insert(stmt);
log.debug("Statement created: {}", stmt.getId());
if (InOutDirection.in.getKey().equals(stmt.getInOutDirection())) {
processedApproved(stmt, sDf10, now, sdf11GroupId);
sdf11WasCreated = true;
} else {
requests.add(requestFromStatement(stmt, company.getTradingCode(), tcr.getCode()));
}
}
if (requests.size() > 0) {
this.sdf10GroupId = groupId;
this.sdf11GroupId = sdf11GroupId;
AssetOperationListRequest assetOperationListRequest = new AssetOperationListRequest();
assetOperationListRequest.setAssetOperationRequests(requests);
kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, assetOperationListRequest);
} else if (sdf11WasCreated) {
sendToExporter(sdf11GroupId);
}
sendToExporter(sdf11GroupId);
// if (sdf10GroupId != null) {
// log.warn("currently awaiting gateway response for groupId: {}. skipping groupId {}", sdf10GroupId, groupId);
// sdfs.forEach(sdf10 -> {
// SDf11 errorSdf11 = createSdf11(sdf10, now, errorResult2);
// errorSdf11.setGenerationId(sdf11GroupId);
// sdf07Imdg.insert(errorSdf11);
// });
// sendToExporter(sdf11GroupId);
// return;
// }
// Collection<AssetOperationRequest> requests = new ArrayList<>();
// boolean sdf07WasCreated = false;
// for (SDf06 sDf06 : sdfs) {
// IValidator validator = sDf06Validator.apply(sDf06);
// Optional<EnumMessage> err = validator.tillFirstError();
// if (err.isPresent()) {
// log.debug("sdf06.id={} validation error: {}", sDf06.getId(), messageResolver.resolve(err.get()));
// SDf07 errorSdf07;
// BigDecimal errorResult;
// Statement stmt = null;
// if (needToCreateStatement(err.get())) {
// errorResult = errorResult1;
// stmt = createStatementBySdf06(sDf06,
// ((Company) validator.getStored(ValidationStored.Sdf06Company)).getId(),
// validator.getStored(ValidationStored.Sdf06Account));
// } else {
// errorResult = errorResult2;
// }
// errorSdf07 = createSdf11(sDf06, now, errorResult);
// errorSdf07.setGenerationId(sdf11GroupId);
// sdf07Imdg.insert(errorSdf07);
// sdf07WasCreated = true;
// if (stmt != null) {
// stmt.setOutSDfId(errorSdf07.getId());
// statementImdg.insert(stmt);
// log.debug("Statement created: {}", stmt.getId());
// }
// continue;
// }
// Company company = validator.getStored(ValidationStored.Sdf06Company);
// Account account = validator.getStored(ValidationStored.Sdf06Account);
// TradingClearingRegistry tcr = tradingClearingRegistryImdg.getFirstObjectByFieldValues(
// Map.of("moneyAccountId", account.getId())
// );
// //проверка существует ли statement пока убрал
// Statement stmt = createStatementBySdf06(sDf06, company.getId(), account);
// statementImdg.insert(stmt);
// log.debug("Statement created: {}", stmt.getId());
// if (InOutDirection.in.getKey().equals(stmt.getInOutDirection())) {
// processedApproved(stmt, sDf06, now, sdf11GroupId);
// sdf07WasCreated = true;
// } else {
// requests.add(requestFromStatement(stmt, company.getTradingCode(), tcr.getCode()));
// }
// }
// if (requests.size() > 0) {
// this.sdf10GroupId = groupId;
// this.sdf07GroupId = sdf11GroupId;
// AssetOperationListRequest assetOperationListRequest = new AssetOperationListRequest();
// assetOperationListRequest.setAssetOperationRequests(requests);
// kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, assetOperationListRequest);
// } else if (sdf07WasCreated) {
// sendToExporter(sdf11GroupId);
// }
}
// private void processedApproved(Statement stmt, SDf06 sDf06, Instant time) {
// processedApproved(stmt, sDf06, time, sdf07GroupId);
// }
//
// private void processedApproved(Statement stmt, SDf06 sDf06, Instant time, Long sdf07GenerationId) {
// log.trace("statement.id={}, sdf07.id={}, sdf06.id={} executed",
// stmt.getId(),
// sDf06.getGenerationId(),
// sDf06.getId());
// SDf07 sdf07 = createSdf11(sDf06, time, successResult);
// sdf07.setGenerationId(sdf07GenerationId);
// sdf07Imdg.insert(sdf07);
// stmt.setOperationStatus(OperationStatus.Executed.getKey());
// stmt.setUpdated(time);
// stmt.setOutSDfId(sdf07.getId());
// statementImdg.update(stmt);
// }
private void processedApproved(Statement stmt, SDf10 sDf10, Instant time) {
processedApproved(stmt, sDf10, time, sdf11GroupId);
}
// private boolean needToCreateStatement(EnumMessage err) {
// return ClearingError.ActiveSessionIsPresent.equals(err.getSubject()) || ClearingError.BalanceInsufficient.equals(err.getSubject());
// }
//
// public void processGatewayResponse(BaseRequest<AssetOperationApprovalRequest> req) {
// Instant now = Instant.now();
// for (SingleAssetResponse gatewayMsg : req.getRequestPayload().getApprovals()) {
// //получаем запрос для текущей группы sdf06
// //находим группу
// Long statementId = gatewayMsg.getStatementId();
// Statement stmt = statementImdg.getSingleObjectByID(statementId);
// if (stmt == null) {
// log.error("Statement.id {} not found", statementId);
// return;
// }
//
// Long sdf06Id = stmt.getInSDfId();
// SDf06 sdf06 = sdf06Imdg.getSingleObjectByID(sdf06Id);
// if (sdf06 == null) {
// log.error("Sdf06.id {} not found by statement.id {}", sdf06Id, statementId);
// return;
// }
//
// Long groupId = sdf06.getGenerationId();
// //сверяем группу SDF06 пришедшего запроса с ожидаемой
// if (sdf10GroupId == null || !sdf10GroupId.equals(groupId)) {
// log.error("do not currently waiting for gateway response for statement.id {} sdf06 groupId {}; waiting for {}",
// statementId,
// groupId,
// sdf06Id);
// return;
// }
//
// Instant updatedTime = Instant.now();
// if (gatewayMsg.isApproved()) {
// processedApproved(stmt, sdf06, updatedTime);
// } else {
// log.trace("statement.id={}, sdf07.id={}, sdf06.id={} rejected (by gateway answer)",
// statementId,
// sdf06.getGenerationId(),
// sdf06.getId());
// SDf07 sdf07 = createSdf11(sdf06, now, errorResult3);
// sdf07.setGenerationId(sdf07GroupId);
// sdf07Imdg.insert(sdf07);
// stmt.setOperationStatus(OperationStatus.Rejected.getKey());
// stmt.setUpdated(updatedTime);
// stmt.setOutSDfId(sdf07.getId());
// statementImdg.update(stmt);
// }
// }
// sendToExporter(sdf07GroupId);
// log.debug("All gateway responses received for SDF06 groupId {}. SDF07 groupId {}", sdf10GroupId, sdf07GroupId);
// clearContext();
// }
//
// private void clearContext() {
// this.sdf10GroupId = null;
// this.sdf07GroupId = null;
// }
private void processedApproved(Statement stmt, SDf10 sDf10, Instant time, Long sdf11GenerationId) {
log.trace("statement.id={}, sdf11.id={}, sdf10.id={} executed",
stmt.getId(),
sDf10.getGenerationId(),
sDf10.getId());
SDf11 sdf11 = createSdf11(sDf10, time, DEFAULT_11_RES);
sdf11.setGenerationId(sdf11GenerationId);
sdf11Imdg.insert(sdf11);
stmt.setOperationStatus(OperationStatus.Executed.getKey());
stmt.setUpdated(time);
stmt.setOutSDfId(sdf11.getId());
statementImdg.update(stmt);
}
public void processGatewayResponse(BaseRequest<AssetOperationApprovalRequest> req) {
Instant now = Instant.now();
for (SingleAssetResponse gatewayMsg : req.getRequestPayload().getApprovals()) {
//получаем запрос для текущей группы sdf10
//находим группу
Long statementId = gatewayMsg.getStatementId();
Statement stmt = statementImdg.getSingleObjectByID(statementId);
if (stmt == null) {
log.error("Statement.id {} not found", statementId);
return;
}
Long sdf10Id = stmt.getInSDfId();
SDf10 sdf10 = sdf10Imdg.getSingleObjectByID(sdf10Id);
if (sdf10 == null) {
log.error("Sdf10.id {} not found by statement.id {}", sdf10Id, statementId);
return;
}
Long groupId = sdf10.getGenerationId();
//сверяем группу SDF10 пришедшего запроса с ожидаемой
if (sdf10GroupId == null || !sdf10GroupId.equals(groupId)) {
log.error("do not currently waiting for gateway response for statement.id {} sdf10 groupId {}; waiting for {}",
statementId,
groupId,
sdf10Id);
return;
}
Instant updatedTime = Instant.now();
if (gatewayMsg.isApproved()) {
processedApproved(stmt, sdf10, updatedTime);
} else {
log.trace("statement.id={}, sdf11.id={}, sdf10.id={} rejected (by gateway answer)",
statementId,
sdf10.getGenerationId(),
sdf10.getId());
SDf11 sdf11 = createSdf11(sdf10, now, DEFAULT_11_RES);
sdf11.setGenerationId(sdf11GroupId);
sdf11Imdg.insert(sdf11);
stmt.setOperationStatus(OperationStatus.Rejected.getKey());
stmt.setUpdated(updatedTime);
stmt.setOutSDfId(sdf11.getId());
statementImdg.update(stmt);
}
}
sendToExporter(sdf11GroupId);
log.debug("All gateway responses received for SDF10 groupId {}. SDF11 groupId {}", sdf10GroupId, sdf11GroupId);
clearContext();
}
private void clearContext() {
this.sdf10GroupId = null;
this.sdf11GroupId = null;
}
private void sendToExporter(Long generationId) {
SwtExporterRequest swtReq = new SwtExporterRequest();
@ -259,42 +250,28 @@ public class Sdf10Executor {
kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtReq);
}
private SDf11 createSdf11(SDf10 sdf10, Instant time) {
// SDf11 sDf07 = new SDf11();
// sDf07.setInSDfId(sdf06.getId());
// sDf07.setGenerationTime(time);
// sDf07.setAccount(sdf06.getAccount());
// sDf07.setSum(sdf06.getSum());
// sDf07.setMarket(sdf06.getMarket());
// sDf07.setType(sdf06.getType());
// sDf07.setDeal(sdf06.getDeal());
// sDf07.setClientN(sdf06.getClientN());
// sDf07.setInn(sdf06.getInn());
// sDf07.setBic(sdf06.getBic());
// sDf07.setNumber(sdf06.getNumber());
// sDf07.setSpec(sdf06.getSpec());
// sDf07.setResult(result);
// return sDf07;
private SDf11 createSdf11(SDf10 sdf10, Instant time, String result) {
SDf11 sdf11 = new SDf11();
sdf11.setOutDocument(sdf10.getOutDocument());
// sdf11.setInDocument();
sdf11.setDepoCode(sdf10.getDepoCode());
sdf11.setQuantity(sdf10.getQuantity());
sdf11.setSecurityCode(sdf10.getSecurityCode());
sdf11.setClientName(sdf10.getClientName());
sdf11.setGenerationTime(time);
// sdf11.setGenerationId(sdf10.getGenerationId());
sdf11.setResult(result);
return sdf11;
}
private Statement createStatementBySdf06(SDf06 sdf06, Long companyId, Account account) {
private Statement createStatementBySdf10(SDf10 sdf10, Long companyId, Account account) {
Statement stmt = new Statement();
stmt.setAddresseeId(companyId);
stmt.setSenderId(Sender.Prc.getId());
stmt.setStatementType(StatementType.incr.getKey());
stmt.setComment(sdf06.getSpec());
//fixme stmt.setComment(sdf10.());
stmt.setAccountId(account.getId());
stmt.setAccount(account.getAccount());
BigDecimal amount = BigDecimalUtil.safeBD(sdf06.getSum());
BigDecimal amount = BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())); //fixme safe new BigDecimal
if (amount.compareTo(BigDecimal.ZERO) >= 0) {
stmt.setInOutDirection(InOutDirection.in.getKey());
} else {
@ -302,7 +279,7 @@ public class Sdf10Executor {
}
stmt.setAmount(amount.abs());
stmt.setOperationStatus(OperationStatus.Pending.getKey());
stmt.setInSDfId(sdf06.getId());
stmt.setInSDfId(sdf10.getId());
stmt.setInOutSDfType(InOutSDfType.type6.getKey());
stmt.setClearingDate(LocalDate.now());
stmt.setCreated(Instant.now());
@ -319,4 +296,9 @@ public class Sdf10Executor {
req.setDirection(stmt.getInOutDirection());
return req;
}
private boolean needToCreateStatement(EnumMessage err) {
return ClearingError.ActiveSessionIsPresent.equals(err.getSubject()) || ClearingError.BalanceInsufficient.equals(err.getSubject())
|| ClearingError.TCRegistryNotFound.equals(err.getSubject());
}
}

View file

@ -145,7 +145,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
log.error("error while validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get()));
continue;
}
Company company = validator.getStored(ValidationStored.CompanyByDepoCode);
Company company = validator.getStored(ValidationStored.CompanyByTradingCode);
Account account = validator.getStored(ValidationStored.Sdf21Account);
log.debug("company.id={}, account.id={}", company.getId(), account.getId());
//адресат CREDIT / владелец DEBIT

View file

@ -14,24 +14,24 @@ import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
public class CompanyByDepoCodeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> {
public class CompanyByTradingCodeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> {
private final Function<T, String> depoCodeExtractor;
private final Function<T, String> tradingCodeExtractor;
private CompanyByDepoCodeValidationRule(Function<T, String> depoCodeExtractor) {
Objects.requireNonNull(depoCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null");
this.depoCodeExtractor = depoCodeExtractor;
private CompanyByTradingCodeValidationRule(Function<T, String> tradingCodeExtractor) {
Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null");
this.tradingCodeExtractor = tradingCodeExtractor;
}
public static <C> CompanyByDepoCodeValidationRule<C> instance(Function<C, String> depoCodeExtractor) {
return new CompanyByDepoCodeValidationRule<>(depoCodeExtractor);
public static <C> CompanyByTradingCodeValidationRule<C> instance(Function<C, String> depoCodeExtractor) {
return new CompanyByTradingCodeValidationRule<>(depoCodeExtractor);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
T validatedObject = context.getValidatedObject();
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
String depoCode = depoCodeExtractor.apply(validatedObject);
String depoCode = tradingCodeExtractor.apply(validatedObject);
if (TextUtil.isEmpty(depoCode) || depoCode.length() < 4) {
return of(ClearingError.CompanyNotFoundB, depoCode);
}
@ -41,7 +41,7 @@ public class CompanyByDepoCodeValidationRule<T> implements IValidationRule<ImdgV
if (companies.size() != 1) {
return of(ClearingError.CompanyNotFoundB, tradingCode);
}
context.storeObject(ValidationStored.CompanyByDepoCode, companies.iterator().next());
context.storeObject(ValidationStored.CompanyByTradingCode, companies.iterator().next());
return empty();
}
}

View file

@ -5,18 +5,28 @@ import org.slf4j.LoggerFactory;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.DepoAccount;
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.clearing.classes.statics.data.sdf.SDf10;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.enumeration.WorkflowStatus;
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.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.number.BigDecimalUtil;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
public enum Sdf10ValidationRule implements IValidationRule<ImdgValidationContext<SDf10>> {
DepoAccountPresent() {
@ -37,13 +47,15 @@ public enum Sdf10ValidationRule implements IValidationRule<ImdgValidationContext
if (depoAccount == null) {
return of(ClearingError.DepoAccNotFound, sdf10.getDepoCode());
}
context.storeObject(ValidationStored.Sdf10DepoAccount, depoAccount);
context.storeObject(ValidationStored.Sdf10Account, acc);
return empty();
}
},
CompanyStatus() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf10> context) {
Company company = context.getStoredObject(ValidationStored.CompanyByDepoCode);
Company company = context.getStoredObject(ValidationStored.CompanyByTradingCode);
if (company == null) {
return of(ClearingError.CompanyNotActive, "null");
}
@ -53,6 +65,73 @@ public enum Sdf10ValidationRule implements IValidationRule<ImdgValidationContext
return empty();
}
},
TcrPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf10> context) {
DepoAccount account = context.getStoredObject(ValidationStored.Sdf10Account);
if (account == null) {
return of(ClearingError.TCRegistryNotFound, "<no account to search for>");
}
Imdg<TradingClearingRegistry> tcrImdg;
tcrImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
// if (AccountType.Anlt.getKey().equals(account.getAccountType())) {
// log.debug("account.id={} is ANLT", account.getId());
// if (TextUtil.isEmpty(sdf10.getSpec())) {
// return of(ClearingError.TCRegistryNotFound, "<spec empty>");
// }
// Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
// Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
// AnltSearcher anltSearcher = new AnltSearcher(tcrImdg, companyImdg, accountImdg);
// AnltSearcher.AnltSearch anltSrch = anltSearcher.loadByAnlt(sdf10.getSpec());
// if (!anltSrch.isFound()) {
// log.debug("account.id={} ANLT couldn't find account by spec {}", account.getId(), sdf10.getSpec());
// return of(ClearingError.TCRegistryNotFound, sdf10.getSpec());
// } else {
// account = anltSrch.getAccount();
// log.debug("account.id={} ANLT found account.id={} by spec {}", account.getId(), account.getId(), sdf10.getSpec());
// }
// }
TradingClearingRegistry tcr = tcrImdg.getFirstObjectByFieldValues(
Map.of("moneyAccountId", account.getId())
);
if (tcr == null) {
return of(ClearingError.TCRegistryNotFound, "<moneyAccountId = " + account.getId() + ">");
}
context.storeObject(ValidationStored.Sdf10Tcr, tcr);
return empty();
}
},
Balance() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf10> context) {
SDf10 sdf10 = context.getValidatedObject();
if (BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())).compareTo(BigDecimal.ZERO) >= 0) { //fixme safe new BigDecimal
return empty();
}
Company company = context.getStoredObject(ValidationStored.CompanyByTradingCode);
Account account = context.getStoredObject(ValidationStored.Sdf10Account);
Imdg<Registry> registryImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
ImdgPredicateBuilder prdctBldr = registryImdg.predicateBuilder();
Function<RegistryTradingParams, ImdgPredicate> prdctByRegistryCode = code -> prdctBldr.and(
prdctBldr.equals("account", account.getAccount()),
prdctBldr.equals("companyId", company.getId()),
prdctBldr.sql(RegistryCodeSqlBuilder.getInstance(code).build()));
Registry rgsAsf = registryImdg.getSingleObjectByPredicate(prdctByRegistryCode.apply(RegistryTradingParams.AS_F));
Registry rgsDst = registryImdg.getSingleObjectByPredicate(prdctByRegistryCode.apply(RegistryTradingParams.DS_T));
log.trace("validating sdf10 id={} account={} companyId={} found registries: AS*F.id={} DS*T.id={}",
sdf10.getId(), account.getAccount(), company.getId(),
rgsAsf == null ? null : rgsAsf.getId(),
rgsDst == null ? null : rgsDst.getId()
);
BigDecimal asfBalance = rgsAsf == null ? BigDecimal.ZERO : BigDecimalUtil.safeBD(rgsAsf.getBalance());
BigDecimal dstBalance = rgsDst == null ? BigDecimal.ZERO : BigDecimalUtil.safeBD(rgsDst.getBalance());
BigDecimal stmtAmount = BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())); //fixme safe new BigDecimal
if (asfBalance.subtract(dstBalance).compareTo(stmtAmount.abs()) < 0) {
return of(ClearingError.BalanceInsufficient);
}
return empty();
}
}
;
private final static Logger log = LoggerFactory.getLogger(Sdf10ValidationRule.class);
@Override

View file

@ -10,7 +10,7 @@ public enum ValidationStored {
Sdf08Company, Sdf08Account,
Sdf10Company, Sdf10Account,
Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr,
Sdf21Account,
@ -18,5 +18,5 @@ public enum ValidationStored {
ReturnDepositDmx,
CompanyByDepoCode
CompanyByTradingCode
}

View file

@ -24,6 +24,7 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation,
public final static RegistryTradingParams AM_T;
public final static RegistryTradingParams AM_B;
public final static RegistryTradingParams AS_T;
public final static RegistryTradingParams DS_T;
public final static RegistryTradingParams AS_B;
public final static RegistryTradingParams AS_F;
public final static RegistryTradingParams CM_T;
@ -132,6 +133,10 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation,
RegistryInstrumentType.M,
RegistryCapacity.A,
RegistryUnit.U);
DS_T = new RegistryTradingParams(RegistryDesignation.D,
RegistryInstrumentType.S,
null,
RegistryUnit.T);
}
}