Merge branch 'plan_balance_dmx_dmt' into dev_try_merge

# Conflicts:
#	clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java
This commit is contained in:
ialbert 2023-09-28 18:12:25 +03:00
commit 7fa35d108d
11 changed files with 307 additions and 89 deletions

View file

@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.company.relation.Relation;
@ -69,6 +70,7 @@ public class ValidationConfig {
Imdg<SDf55> sDf55Imdg;
Imdg<SDf54> sDf54Imdg;
Imdg<PaymentInstruction> pmtImdg;
Imdg<ClearingMemberCategory> ctgrImdg;
ImdgProvider imdgProvider;
public ValidationConfig(ImdgProvider imdgProvider) {
@ -91,6 +93,7 @@ public class ValidationConfig {
this.sDf55Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf55, SDf55.class);
this.sDf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.ctgrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.imdgProvider = imdgProvider;
}
@ -326,12 +329,14 @@ public class ValidationConfig {
ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(returnDepositRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ctgrImdg);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
ReturnDepositValidationRule.RegistryCodeCheck,
ReturnDepositValidationRule.RgsWronCodeCheck,
ReturnDepositValidationRule.CategoryCheck,
ReturnDepositValidationRule.BalanceCheck,
ReturnDepositValidationRule.DmxCheck
ReturnDepositValidationRule.Dm_Check
);
};
}

View file

@ -23,6 +23,7 @@ public enum ClearingError implements IErrorEnumId {
SuchRecordAlreadyExists(5405L),
TradingClearingRegistryNotFound(5418L),
TradingClearingRegistryNotActive(5419L),
CategoryNotFound(5420L),
ClearingUnavailableForCompany(5421L),
InsecurityObligation(5422L),
NewDealsNotFound(5423L),

View file

@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
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.misc.Currency;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
@ -23,6 +25,7 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
import ru.spcex.clearing.service.integration.GatewayRequestCreator;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.registry.RegistryManager;
import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
@ -49,6 +52,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@ -59,6 +64,9 @@ public class RegistryService {
private final ImdgProvider imdgProvider;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Registry> registryImdg;
private final Imdg<Account> accImdg;
private final Imdg<Currency> currImdg;
private final Imdg<Company> cmpImdg;
private final Imdg<PaymentInstruction> pmtImdg;
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
@ -92,6 +100,9 @@ public class RegistryService {
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.accImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
this.cmpImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.returnDepositVal = returnDepositVal;
this.refundDateVal = refundDateVal;
this.identificationFundsVal = identificationFundsVal;
@ -158,6 +169,52 @@ public class RegistryService {
registryImdg.update(rgs);
log.trace("TCR#id={} registry#id={} updated", tcr.getId(), rgs.getId());
});
if (registries.size() > 0) {
log.info("assets size {} updated by TCR#id={}, will not create new assets",
registries.size(), tcr.getId());
return;
}
Account acc = accImdg.getSingleObjectByID(tcr.getMoneyAccountId());
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
Company cmp = cmpImdg.getSingleObjectByID(tcr.getCompanyId());
if (acc == null) {
log.warn("TCR#id={} account {} not found", tcr.getId(), tcr.getMoneyAccountId());
return;
}
if (currency == null) {
log.warn("TCR#id={} currency {} not found", tcr.getId(), CurrencyCode.RUB.getKey());
return;
}
if (cmp == null) {
log.warn("TCR#id={} company {} not found", tcr.getId(), tcr.getCompanyId());
return;
}
log.debug("TCR#id={} account#id={} company#id={}, creating assets", tcr.getId(), acc.getId(), cmp.getId());
AssetTrio assets = this.assets.createMAssets(acc,
CurrencyCode.RUB.getKey(),
currency.getId(),
tcr.getTradingClearingRegistryType(),
tcr.getId(),
tcr.getCode(),
cmp);
Stream.of(assets.a__t(), assets.a__b(), assets.a__f())
.forEach(a -> {
a.setRegistryStatus(RegistryStatus.PROC.getKey());
registryImdg.insert(a);
});
log.debug("TCR#id={} created {}#id={} {}#id={} {}#id={}",
tcr.getId(),
assets.a__f().getRegistryCode(), assets.a__f().getId(),
assets.a__t().getRegistryCode(), assets.a__t().getId(),
assets.a__b().getRegistryCode(), assets.a__b().getId());
}
public RequestInfoUpdate returnDeposit(BaseRequest<RegistryReturnDepositRequest> req) {
@ -170,28 +227,37 @@ public class RegistryService {
msgResolver.resolve(err.get()));
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
}
Registry tm_t = validator.getStored(Stored.PresentById);
Registry dm_x = validator.getStored(ValidationStored.ReturnDepositDmx);
if (dm_x != null) {
dm_x.setSessionId(null);
dm_x.setSessionType(null);
dm_x.setBalance(requestPayload.getBalance());
dm_x.setUpdated(Instant.now());
registryImdg.update(dm_x);
log.debug("updated dm*x.id={} by RegistryReturnDepositRequest.id={}",
dm_x.getId(),
Registry _m_t = validator.getStored(ValidationStored.ReturnDepositOm_t);
if (_m_t == null) _m_t = validator.getStored(Stored.PresentById);
Registry dm__ = validator.getStored(ValidationStored.ReturnDepositDm__);
if (dm__ != null) {
dm__.setSessionId(null);
dm__.setSessionType(null);
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
dm__.setUpdated(Instant.now());
registryImdg.update(dm__);
log.debug("updated {}.id={} by RegistryReturnDepositRequest.id={}",
dm__.getRegistryCode(),
dm__.getId(),
req.getId());
} else {
dm_x = tm_t.clone();
dm_x.setRegistryDesignation(RegistryDesignation.D.getKey());
dm_x.setRegistryUnit(RegistryUnit.X.getKey());
dm_x.setRegistryCode(RegistryUtil.clearingCode(dm_x));
dm_x.setBalance(requestPayload.getBalance());
dm_x.setSessionId(null);
dm_x.setSessionType(null);
registryImdg.insert(dm_x);
log.debug("created dm*x.id={} by RegistryReturnDepositRequest.id={}",
dm_x.getId(),
dm__ = _m_t.clone();
dm__.setRegistryDesignation(RegistryDesignation.D.getKey());
RegistryManager.zeroState(dm__);
if (RegistryDesignation.T.equalsByKey(_m_t.getRegistryDesignation())) {
dm__.setRegistryUnit(RegistryUnit.X.getKey());
} else {
dm__.setRegistryUnit(RegistryUnit.T.getKey());
}
dm__.setRegistryCode(RegistryUtil.clearingCode(dm__));
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
dm__.setSessionId(null);
dm__.setSessionType(null);
registryImdg.insert(dm__);
log.debug("created {}.id={} by RegistryReturnDepositRequest.id={}",
dm__.getRegistryCode(),
dm__.getId(),
req.getId());
}
return new RequestInfoUpdate(req.getId(), Status.Success, null);

View file

@ -162,6 +162,46 @@ public class AssetTBFProcessing {
return new AssetTrio(asf, asb, ast);
}
public AssetTrio createMAssets(Account acc,
String securitySymbol,
Long securityId,
String tcrType,
Long tcrId,
String tcr,
Company company) {
Registry ast = new Registry();
ast.setCreated(Instant.now());
ast.setSecuritySymbol(securitySymbol);
ast.setSecurityId(securityId);
ast.setAccountId(acc.getId());
ast.setAccount(acc.getAccount());
ast.setAccountType(acc.getAccountType());
ast.setRegistryDesignation(RegistryDesignation.A.getKey());
ast.setRegistryInstrumentType(RegistryInstrumentType.M.getKey());
ast.setRegistryCapacity(tcrType);
ast.setRegistryUnit(RegistryUnit.T.getKey());
ast.setRegistryCode(RegistryUtil.clearingCode(ast));
ast.setClearingCode(company.getClearingCode());
ast.setTradingCode(company.getClearingCode());
ast.setCompanyId(company.getId());
ast.setShortName(company.getShortName());
ast.setFullName(company.getFullName());
ast.setTradingClearingRegistryId(tcrId);
ast.setTradingClearingRegistry(tcr);
ast.setRegistryStatus(RegistryStatus.OK.getKey());
ast.setBalanceDimension(BalanceDimension.MONY.getKey());
RegistryManager.zeroState(ast);
Registry asf = ast.clone();
asf.setRegistryUnit(RegistryUnit.F.getKey());
asf.setRegistryCode(RegistryUtil.clearingCode(asf));
RegistryManager.zeroState(asf);
Registry asb = ast.clone();
asb.setRegistryUnit(RegistryUnit.B.getKey());
asb.setRegistryCode(RegistryUtil.clearingCode(asb));
RegistryManager.zeroState(asb);
return new AssetTrio(asf, asb, ast);
}
public Optional<Registry> searchByTcrCompanyAccount(Registry rgs,
RegistryTradingParams params) {
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();

View file

@ -183,6 +183,8 @@ public class RegistryManager {
//балансы
rgs.setBalance(BigDecimal.ZERO);
rgs.setDebit(BigDecimal.ZERO);
rgs.setSettledDebit(BigDecimal.ZERO);
rgs.setSettledCredit(BigDecimal.ZERO);
rgs.setCredit(BigDecimal.ZERO);
rgs.setDiffBalance(BigDecimal.ZERO);
rgs.setCheckBalance(BigDecimal.ZERO);

View file

@ -1,56 +1,122 @@
package ru.spcex.clearing.service.validation;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
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.RegistryReturnDepositRequest;
import ru.spcex.clearing.service.registry.RegistryManager;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
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.enumeration.IEnumKey;
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.Optional;
import static ru.spcex.clearing.service.registry.RegistryManager.equalsByCode;
//1. Проверки
//1.1 Проверить, в запросе у регистра код:
// 1.1.1 Если регистр TM-T:
// Проверить, что у registry.companyId существует категория I, иначе ошибка: 5420 - "Доступ к клирингу на «%s» не найден для компании %s."/> Где %s = категории И
// Проверить, что найденного регистра DM*X: registry.status!=OK, иначе ошибка: 5425 - "Запрещена идентификация средства по рассчитанным обязательствам".
// Создать/добавить в баланс DM-X на базе TM-T
// 1.1.2 Если регистр OM-T:
// Проверить, что у registry.companyId существует категория V, иначе ошибка: 5420 - "Доступ к клирингу на «%s» не найден для компании %s."/> Где %s = категории В
// Проверить, что найденного регистра DM*T: registry.status!=OK, иначе ошибка: 5425 - "Запрещена идентификация средства по рассчитанным обязательствам".
// Создать/добавить в баланс DM-T на базе OM-T
//1.2 Проверить, баланс в запросе
// Баланс должен быть положительный
public enum ReturnDepositValidationRule implements IValidationRule<ImdgValidationContext<RegistryReturnDepositRequest>> {
RegistryCodeCheck() {
RgsWronCodeCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
Registry rgs = context.getStoredObject(Stored.PresentById);
if (!RegistryDesignation.T.equalsByKey(rgs.getRegistryDesignation())
|| !RegistryInstrumentType.M.equalsByKey(rgs.getRegistryInstrumentType())
|| !RegistryUnit.T.equalsByKey(rgs.getRegistryUnit())) {
return of(ClearingError.RecordNotFoundInDictionary, "TM*T", "Registry");
if (!equalsByCode(RegistryTradingParams.TM_T, rgs)) { //!equalsByCode(RegistryTradingParams.OM_T, rgs)
return of(ClearingError.RgsWrongCode, "{}.id={}", rgs.getRegistryCode(), rgs.getId());
}
return empty();
}
}, BalanceCheck() {
},
CategoryCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
Registry rgs = context.getStoredObject(Stored.PresentById);
Imdg<ClearingMemberCategory> ctgImdg = context.obtainMap(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
Collection<ClearingMemberCategory> category = ctgImdg.getCollectionObjectsBySQL(
"companyId = %d".formatted(rgs.getCompanyId()));
Optional<ClearingCategory> ctgr = category.stream()
.map(c -> IEnumKey.getEnumByKey(ClearingCategory.class, c.getClearingMemberCategory()))
.filter(c -> ClearingCategory.V.equals(c) || ClearingCategory.I.equals(c))
.findFirst();
if (ctgr.isEmpty()) {
return of(ClearingError.CategoryNotFound, "I/V", rgs.getCompanyId());
}
if (ctgr.get().equals(ClearingCategory.V)) {
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
Collection<Registry> group = rgsImdg.getCollectionObjectsBySQL("groupId = %d".formatted(rgs.getGroupId()));
Optional<Registry> om_t = group.stream()
.filter(r -> r.getSettlementDate() != null)
.filter(r -> r.getValueDate() != null)
.filter(r -> r.getSettlementDate().isAfter(r.getValueDate()))
.filter(r -> equalsByCode(RegistryTradingParams.OM_T, r))
.findFirst();
if (om_t.isEmpty()) return of(ClearingError.RecordNotFound, "OM*T.groupId=%d".formatted(rgs.getGroupId()));
context.storeObject(ValidationStored.ReturnDepositOm_t, om_t.get());
}
return empty();
}
},
BalanceCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
Registry rgs = context.getStoredObject(Stored.PresentById);
RegistryReturnDepositRequest request = context.getValidatedObject();
if (request.getBalance() == null || request.getBalance().compareTo(rgs.getBalance()) > 0) {
if (request.getBalance() == null || request.getBalance().compareTo(BigDecimal.ZERO) < 0) {
return of(ClearingError.WrongField, "balance");
}
if (request.getBalance().compareTo(rgs.getBalance()) > 0) {
return of(ClearingError.IdentifiedFundsExceedObligations);
}
return Optional.empty();
}
}, DmxCheck() {
}, Dm_Check() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
Registry rgs = context.getStoredObject(Stored.PresentById);
Registry rgs = context.getStoredObject(ValidationStored.ReturnDepositOm_t);
if (rgs == null) rgs = context.getStoredObject(Stored.PresentById);
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
RegistryManager rgsMng = new RegistryManager(rgsImdg);
Optional<Registry> dmx = rgsMng.searchDmxByCompanyId(rgs);
if (dmx.isPresent() && RegistryStatus.OK.equalsByKey(dmx.get().getRegistryStatus()) ) {
if (TextUtil.isEmpty(rgs.getContract())) {
return empty();
}
RegistryTradingParams rgsCode;
if (equalsByCode(RegistryTradingParams.TM_T, rgs)) {
rgsCode = RegistryTradingParams.DM_X;
} else {
rgsCode = RegistryTradingParams.DM_T;
}
String sqlCondition = String.format("(%s) and companyId = %d and contract = '%s'",
RegistryCodeSqlBuilder.getInstance(rgsCode).build(),
rgs.getCompanyId(),
rgs.getContract());
Registry dm__ = rgsImdg.getFirstObjectBySQL(sqlCondition);
if (dm__ != null && RegistryStatus.OK.equalsByKey(dm__.getRegistryStatus()) ) {
return of(ClearingError.ObligationsAlreadyCalculated);
}
dmx.ifPresent(dmxRgs -> context.storeObject(ValidationStored.ReturnDepositDmx, dmxRgs));
return Optional.empty();
if (dm__ != null) {
context.storeObject(ValidationStored.ReturnDepositDm__, dm__);
}
return empty();
}
};

View file

@ -18,7 +18,7 @@ public enum ValidationStored {
Sdf06Company, Sdf06Account, Sdf06Tcr,
ReturnDepositDmx,
ReturnDepositDm__, ReturnDepositOm_t,
IdentificationFundsTcrSearch, IdentificationFundsAssetTrio,

View file

@ -160,6 +160,7 @@ public class ReturnDepositSession extends AbstractSession implements Initializin
{
InspectionPoolPayload companyIdPayload = new InspectionPoolPayload();
companyIdPayload.setProcessedCompanyId(currSession.getCompanyId());
companyIdPayload.setSessionId(currSession.getId());
runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligationsDepositReturn);
}

View file

@ -1,7 +1,5 @@
package ru.spcex.clearing.session.stage.impl;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -55,16 +53,18 @@ public class InspectionObligations implements ISessionStage {
private final AssetTBFProcessing assets;
private final GatewayRequester gateway;
private final TradingTimeService tradingTimeService;
private final PlanBalanceCalc planBalanceCalc;
@Autowired
public InspectionObligations(ImdgProvider imdgProvider,
RegistryManager registryManager,
AssetTBFProcessing assets,
GatewayRequester gateway) {
GatewayRequester gateway, PlanBalanceCalc planBalanceCalc) {
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.registryManager = registryManager;
this.assets = assets;
this.gateway = gateway;
this.planBalanceCalc = planBalanceCalc;
this.gateway.setName("InspectionObligations|OM*T");
this.tradingTimeService = new TradingTimeService(imdgProvider);
}
@ -204,52 +204,11 @@ public class InspectionObligations implements ISessionStage {
}
}
stageRevision2(sessionId);
planBalanceCalc.stageRevision2(sessionId);
return new StageResult(null, true);
}
protected void stageRevision2(Long sessionId) {
/* todo logic
Collection rgsAT = findRegistryATBySession // registry_disignation=A and registry_unit=T
Collection rgsAB = findRegistryATBySession // registry_disignation=A and registry_unit=B and sessionId = current
foreach( at: rgsAT)
foreach (ab: rgsAB)
if (at.companyId=ab.companyId and at.accountId=ab.accountId and at.securityId=ab.securityId)
at.plannecBallance -= ab.balance
*/
String sqlAT = RegistryCodeSqlBuilder.getInstance(A__T).build();
String sqlAB = String.format("(%s) and sessionId = %d",
RegistryCodeSqlBuilder.getInstance(A__B).build(),
sessionId
);
Collection<Registry> registriesAT = registryImdg.getCollectionObjectsBySQL(sqlAT);
Collection<Registry> registriesAB = registryImdg.getCollectionObjectsBySQL(sqlAB);
log.debug("Select {} registers by \"{}\", {} registers by \"{}\" for revision step 2",
registriesAT.size(), sqlAT, registriesAB.size(), sqlAB);
Map<Triple<Long, Long, Long>, List<Registry>> regABIndex = registriesAB.stream().collect(Collectors.groupingBy(
(Registry reg) -> new MutableTriple(reg.getCompanyId(), reg.getAccountId(), reg.getSecurityId())
));
int updateCount = 0;
Instant now = Instant.now();
for (Registry regT : registriesAT) {
Triple<Long, Long, Long> key = new MutableTriple(regT.getCompanyId(), regT.getAccountId(), regT.getSecurityId());
List<Registry> regsB = regABIndex.get(key);
if (regsB == null) {
log.debug("Registry A__B for registry[{}] (A__T key {}) not found", regT, key);
} else {
for (Registry regB : regsB) {
regT.setPlanBalance(safeBD(regT.getPlanBalance()).subtract(safeBD(regB.getBalance())));
}
regT.setUpdated(now);
registryImdg.update(regT);
updateCount++;
}
}
log.debug("Updated {} registers A__T with planBalance at {}", updateCount, now);
}
private String searchAssetsByObligationSql(Registry obligation) {
RegistryTradingParams counterRegistryTradingParams = null;
if (IEnumKey.getEnumByKey(RegistryInstrumentType.class, obligation.getRegistryInstrumentType()) == RegistryInstrumentType.S) {

View file

@ -16,6 +16,7 @@ import ru.spcex.clearing.service.schedule.TradingTimeService;
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.task.InspectionPoolPayload;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -44,23 +45,26 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
private final AssetTBFProcessing assets;
private final TradingTimeService tradingTimeService;
private final GatewayRequester gateway;
private final PlanBalanceCalc planBalanceCalc;
@Autowired
public InspectionObligationsDepositReturn(ImdgProvider imdgProvider, RegistryManager rgsMng, AssetTBFProcessing assets, TradingTimeService tradingTimeService, GatewayRequester gateway) {
public InspectionObligationsDepositReturn(ImdgProvider imdgProvider, RegistryManager rgsMng, AssetTBFProcessing assets, TradingTimeService tradingTimeService, GatewayRequester gateway, PlanBalanceCalc planBalanceCalc) {
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.categoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.rgsMng = rgsMng;
this.assets = assets;
this.tradingTimeService = tradingTimeService;
this.gateway = gateway;
this.planBalanceCalc = planBalanceCalc;
this.gateway.setName("InspectionObligationsDepositReturn|OM*T");
}
@Override
public StageResult<?> submit(Task<?> task) {
InspectionPoolPayload payload = (InspectionPoolPayload) task.getData();
switch (task.getTaskType()) {
case InspectionObligations -> {
return inspectionObligations();
return inspectionObligations(payload.getSessionId());
}
default -> throw new IllegalStateException("Unknown task type: " + task.getTaskType());
}
@ -81,7 +85,7 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
}
}
private StageResult<?> inspectionObligations() {
private StageResult<?> inspectionObligations(Long sessionId) {
String sqlCondition = String.format("(%s) and registryStatus = '%s'",
RegistryCodeSqlBuilder.getInstance(OS_T, OM_T, TS_T, TM_T).build(),
RegistryStatus.POOL.getKey());
@ -196,6 +200,7 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
group.forEach(rgs -> updateStatus(rgs, registryStatusFailed(rgs)));
}
}
planBalanceCalc.stageRevision2(sessionId);
return new StageResult<>(null, true);
}

View file

@ -0,0 +1,73 @@
package ru.spcex.clearing.session.stage.impl;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static ru.spcex.platform.enumeration.RegistryTradingParams.A__B;
import static ru.spcex.platform.enumeration.RegistryTradingParams.A__T;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Component
public class PlanBalanceCalc {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<Registry> rgsImdg;
public PlanBalanceCalc(ImdgProvider imdgProvider) {
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
}
public void stageRevision2(Long sessionId) {
/* todo logic
Collection rgsAT = findRegistryATBySession // registry_disignation=A and registry_unit=T
Collection rgsAB = findRegistryATBySession // registry_disignation=A and registry_unit=B and sessionId = current
foreach( at: rgsAT)
foreach (ab: rgsAB)
if (at.companyId=ab.companyId and at.accountId=ab.accountId and at.securityId=ab.securityId)
at.plannecBallance -= ab.balance
*/
String sqlAT = RegistryCodeSqlBuilder.getInstance(A__T).build();
String sqlAB = String.format("(%s) and sessionId = %d",
RegistryCodeSqlBuilder.getInstance(A__B).build(),
sessionId
);
Collection<Registry> registriesAT = rgsImdg.getCollectionObjectsBySQL(sqlAT);
Collection<Registry> registriesAB = rgsImdg.getCollectionObjectsBySQL(sqlAB);
log.debug("Select {} registers by \"{}\", {} registers by \"{}\" for revision step 2",
registriesAT.size(), sqlAT, registriesAB.size(), sqlAB);
Map<Triple<Long, Long, Long>, List<Registry>> regABIndex = registriesAB.stream().collect(Collectors.groupingBy(
(Registry reg) -> new MutableTriple(reg.getCompanyId(), reg.getAccountId(), reg.getSecurityId())
));
int updateCount = 0;
Instant now = Instant.now();
for (Registry regT : registriesAT) {
Triple<Long, Long, Long> key = new MutableTriple(regT.getCompanyId(), regT.getAccountId(), regT.getSecurityId());
List<Registry> regsB = regABIndex.get(key);
if (regsB == null) {
log.debug("Registry A__B for registry[{}] (A__T key {}) not found", regT, key);
} else {
for (Registry regB : regsB) {
regT.setPlanBalance(safeBD(regT.getPlanBalance()).subtract(safeBD(regB.getBalance())));
}
regT.setUpdated(now);
rgsImdg.update(regT);
updateCount++;
}
}
log.debug("Updated {} registers A__T with planBalance at {}", updateCount, now);
}
}