SDF21
SDF10
This commit is contained in:
ialbert 2023-08-21 17:20:42 +03:00
parent bd65726668
commit ae3abdb638
14 changed files with 255 additions and 47 deletions

View file

@ -207,11 +207,13 @@ public class ValidationConfig {
context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, imdgMoneyMarketSecurity);
context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeSecurityImdg);
context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equitySecurityImdg);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
CompanyByTradingCodeValidationRule.instance(SDf21::getDepoCodeCl),
Sdf21ValidationRule.AccountPresent,
SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode)
SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode),
Sdf21ValidationRule.TransactionNumberProcessed
);
};
}
@ -352,12 +354,15 @@ public class ValidationConfig {
ctx.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
ctx.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
ctx.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
ctx.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity , fixedIncomeSecurityImdg);
ctx.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity , imdgMoneyMarketSecurity);
ctx.addImdg(IMDGDistributedNames.Map_EquitySecurity , equitySecurityImdg);
return new ValidatorImpl<>(ctx,
Sdf20ValidationRule.AccountPresent,
Sdf20ValidationRule.CompanyPresent,
Sdf20ValidationRule.SecurityPresent,
Sdf20ValidationRule.TCRPresent,
Sdf20ValidationRule.DS_TFound,
Sdf20ValidationRule.AS_TFound);
Sdf20ValidationRule.AssetsPresent);
};
}

View file

@ -20,6 +20,7 @@ public enum ClearingError implements IErrorEnumId {
AccountNotActive(5415L),
SecurityNotFound(5416L),
AccountNotPresent(5417L),
SuchRecordAlreadyExists(5405L),
TradingClearingRegistryNotFound(5418L),
TradingClearingRegistryNotActive(5419L),
ClearingUnavailableForCompany(5421L),

View file

@ -3,11 +3,12 @@ package ru.spcex.clearing.service;
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.registry.Registry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
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.ImdgPredicate;
@ -50,6 +51,18 @@ public class AssetTBFProcessing {
rgsImdg.update(am_f);
}
public void processWithoutChangingB(Registry am_b, Registry am_t, Registry am_f, BigDecimal sum) {
safeWrapField(am_t::getBalance, am_t::setBalance);
safeWrapField(am_b::getBalance, am_b::setBalance);
safeWrapField(am_f::getBalance, am_f::setBalance);
Instant now = Instant.now();
am_f.setBalance(am_t.getBalance().subtract(am_b.getBalance()));
am_f.setUpdated(now);
rgsImdg.update(am_f);
}
public void processByAm_b(Registry am_b, BigDecimal sum) {
Optional<Registry> am_f = rgsMng.findRegByUnit(am_b.getCompanyId(),
am_b.getAccountId(),
@ -66,6 +79,46 @@ public class AssetTBFProcessing {
}
}
public AssetTrio createSAssets(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.S.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.PICS.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<AssetTrio> searchMoneyByAccAndCompany(Long companyId, Long accountId) {
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
Function<RegistryTradingParams, ImdgPredicate> prdct = rgsCode -> pb.and(

View file

@ -2,5 +2,5 @@ package ru.spcex.clearing.service;
import ru.clearing.classes.statics.data.registry.Registry;
public record AssetTrio(Registry am_f, Registry am_b, Registry am_t) {
public record AssetTrio(Registry a__f, Registry a__b, Registry a__t) {
}

View file

@ -15,6 +15,7 @@ import ru.spcex.platform.imdg.api.predicate.specific.RegistryDm_tClrnPredicate;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.text.TextUtil;
import java.math.BigDecimal;
import java.util.Optional;
import static ru.spcex.platform.enumeration.RegistryTradingParams.DM_T;
@ -108,6 +109,23 @@ public class RegistryManager {
);
}
public Optional<Registry> searchByAccSec(Long accountId, String securitySymbol, RegistryTradingParams rgsCde) {
if (TextUtil.isEmpty(securitySymbol)
|| accountId == null
|| rgsCde == null)
return Optional.empty();
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
return Optional.ofNullable(
rgsImdg.getSingleObjectByPredicate(
pb.and(
pb.sql(RegistryCodeSqlBuilder.getInstance(rgsCde).build()),
pb.equals("accountId", accountId),
pb.equals("securitySymbol", securitySymbol)
)
)
);
}
public Optional<Registry> searchDmtClrn(Registry rgs) {
ImdgPredicate dmtClrnPrdct = RegistryDm_tClrnPredicate
.instance(rgs.getCompanyId(), rgs.getCounterPartyId())
@ -144,6 +162,14 @@ public class RegistryManager {
return Optional.ofNullable(rgsImdg.getSingleObjectByPredicate(prdct));
}
public static void zeroState(Registry rgs) {
rgs.setBalance(BigDecimal.ZERO);
rgs.setDebit(BigDecimal.ZERO);
rgs.setCredit(BigDecimal.ZERO);
rgs.setDiffBalance(BigDecimal.ZERO);
rgs.setCheckBalance(BigDecimal.ZERO);
}
public static boolean equalsByCode(RegistryTradingParams code, Registry rgs) {
return code.equalByRegistry(

View file

@ -206,8 +206,7 @@ public class Sdf10Executor {
Function<Task, Optional<PlannerAllToday>> plannerByTask = task -> {
ImdgPredicate plannerPrdct = pb.and(
pb.equals("task", task.getKey()),
pb.equals("taskStatus", TaskStatus.Active.getKey()),
pb.equals("clearingDate", LocalDate.now())
pb.equals("taskStatus", TaskStatus.Active.getKey())
);
return Optional.ofNullable(plannerAllTodayImdg.getFirstObjectByPredicate(plannerPrdct));
};

View file

@ -5,10 +5,13 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf20;
import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -16,10 +19,12 @@ 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.service.sender.KafkaSender;
import ru.spcex.clearing.service.AssetTBFProcessing;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.RegistryManager;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.platform.enumeration.InOutDirection;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -29,31 +34,38 @@ 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.Optional;
import java.util.function.Function;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service
public class Sdf20Executor {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<SDf20> sDf20Imdg;
private final Imdg<Registry> rgsImdg;
private final Imdg<Statement> stmtImdg;
private final Function<SDf20, IValidator> validation;
private final IMessageResolver msgRslv;
private final KafkaSender kafka;
private final AssetTBFProcessing assetsMng;
@Autowired
public Sdf20Executor(ImdgProvider imdgProvider,
Function<SDf20, IValidator> validation,
IMessageResolver msgRslv,
RegistryManager rgsMng,
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka) {
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assetsMng) {
this.sDf20Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf20, SDf20.class);
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.stmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.validation = validation;
this.msgRslv = msgRslv;
this.kafka = kafka;
this.assetsMng = assetsMng;
}
public void execute(BaseRequest<StatementRequest> systemRequest) {
@ -71,36 +83,71 @@ public class Sdf20Executor {
log.error("sdf20.id={} error {}", sDf20.getId(), msgRslv.resolve(err.get()));
return;
}
BigDecimal quantity = safeBD(BigDecimalUtil.parseLeadingZeroes(sDf20.getQuantity()));
if ("ADDFREE".equalsIgnoreCase(sDf20.getOperationCode())) {
quantity = quantity;
} else if ("DELFREE".equals(sDf20.getOperationCode())) {
quantity = quantity.negate();
}
Registry ds_t = validator.getStored(ValidationStored.Sdf20Dst);
Registry as_t = validator.getStored(ValidationStored.Sdf20Ast);
Company company = validator.getStored(ValidationStored.Sdf20Company);
AssetTrio assets = validator.getStored(ValidationStored.Sdf20Ast);
Company cmp = validator.getStored(ValidationStored.Sdf20Company);
Account acc = validator.getStored(ValidationStored.Sdf20Account);
Security security = validator.getStored(ValidationStored.Sdf20Security);
TradingClearingRegistry tcr = validator.getStored(ValidationStored.Sdf20Tcr);
log.debug("sdf20.id={}, found as_t.id={}, ds_t.id={}", sDf20.getId(), as_t.getId(), ds_t.getId());
if (assets == null) {
log.debug("assets were not found for sdf20.id={} creating", sDf20.getId());
assets = assetsMng.createSAssets(
acc,
sDf20.getSecurity(),
security.getId(),
tcr.getTradingClearingRegistryType(),
tcr.getId(),
tcr.getCode(),
cmp
);
rgsImdg.insert(assets.a__t());
rgsImdg.insert(assets.a__f());
rgsImdg.insert(assets.a__b());
}
if (ds_t == null) {
log.debug("DS*T were not found for sdf20.id={} creating", sDf20.getId());
ds_t = assets.a__t().clone();
ds_t.setRegistryDesignation(RegistryDesignation.D.getKey());
ds_t.setRegistryCode(RegistryUtil.clearingCode(ds_t));
rgsImdg.insert(ds_t);
}
Registry as_t = assets.a__t();
ds_t.setComment(sDf20.getTransactionNumber());
ds_t.setContract(sDf20.getInDocument());
ds_t.setRegistryStatus(RegistryStatus.OK.getKey());
ds_t.setUpdated(now);
BigDecimal quantity = BigDecimalUtil.parseLeadingZeroes(sDf20.getQuantity());
BigDecimal balance = BigDecimalUtil.safeBD(as_t.getBalance());
if ("ADDFREE".equalsIgnoreCase(sDf20.getOperationCode())) {
as_t.setBalance(balance.add(quantity));
} else if ("DELFREE".equals(sDf20.getOperationCode())) {
as_t.setBalance(balance.subtract(quantity));
}
ds_t.setBalance(safeBD(ds_t.getBalance()).add(quantity));
as_t.setBalance(safeBD(as_t.getBalance()).add(quantity));
as_t.setCheckBalance(BigDecimalUtil.parseLeadingZeroes(sDf20.getCloseBalance()));
as_t.setUpdated(now);
rgsImdg.update(ds_t);
rgsImdg.update(as_t);
rgsImdg.update(ds_t);
assetsMng.process(assets.a__b(), assets.a__t(), assets.a__f(), BigDecimal.ZERO);
//statement recfree in
//statement delfree out
Statement statement = createStatement(cmp.getId(), acc, quantity, sDf20.getId(), sDf20.getTransactionNumber(), security.getId());
stmtImdg.insert(statement);
log.debug("sdf20.id={}, processing as_t.id={}, as_f.id={}, as_b.id={}, ds_t.id={}. statement.id={}",
sDf20.getId(),
assets.a__t().getId(), assets.a__f().getId(), assets.a__b().getId(),
ds_t.getId(),
statement.getId());
//send gateway
{
Collection<AssetOperationRequest> requests = new ArrayList<>();
AssetOperationRequest req = requestFromStatement(
quantity,
BigDecimalUtil.parseLeadingZeroes(sDf20.getQuantity()),
sDf20.getSecurity(),
company.getTradingCode(),
cmp.getTradingCode(),
tcr.getCode()
);
requests.add(req);
@ -125,4 +172,33 @@ public class Sdf20Executor {
req.setDirection(InOutDirection.in.getKey());
return req;
}
private Statement createStatement(Long companyId,
Account account,
BigDecimal quantity,
Long sdf20Id,
String transactionNumber,
Long securityId) {
Statement stmt = new Statement();
stmt.setAddresseeId(companyId);
stmt.setSenderId(Sender.Prc.getId());
stmt.setStatementType(StatementType.incr.getKey());
//fixme stmt.setComment(sdf10.());
stmt.setAccountId(account.getId());
stmt.setAccount(account.getAccount());
stmt.setSecurityId(securityId);
if (quantity.compareTo(BigDecimal.ZERO) >= 0) {
stmt.setInOutDirection(InOutDirection.in.getKey());
} else {
stmt.setInOutDirection(InOutDirection.out.getKey());
}
stmt.setAmount(quantity.abs());
stmt.setOperationStatus(OperationStatus.Executed.getKey());
stmt.setInSDfId(sdf20Id);
stmt.setInOutSDfType(InOutSDfType.type20.getKey());
stmt.setClearingDate(LocalDate.now());
stmt.setComment(transactionNumber);
stmt.setCreated(Instant.now());
return stmt;
}
}

View file

@ -142,7 +142,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
IValidator validator = sDf21Validator.apply(sdf21);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
log.error("error while validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get()));
log.info("skipping after validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get()));
continue;
}
Company company = validator.getStored(ValidationStored.CompanyByTradingCode);

View file

@ -136,17 +136,17 @@ public class PaymentInstructionOutboundService {
pmtImdg.insert(pmt);
log.debug("new PaymentInstruction.id: {}", pmt.getId());
Optional<AssetTrio> assets = assetsMng.searchMoneyByAccAndCompany(addressee.getId(), accCred.getId());
if (assets.isEmpty() || assetsMng.insufficientBalance(assets.get().am_f(), amount)) {
if (assets.isEmpty() || assetsMng.insufficientBalance(assets.get().a__f(), amount)) {
pmt.setTransactionStatus(TransactionStatus.cher.getKey());
pmt.setUpdated(now);
pmtImdg.update(pmt);
log.debug("insufficient balance, pmt.id: {}, am*f.balance={}",
pmt.getId(), assets.map(AssetTrio::am_f).map(Registry::getBalance).orElse(null));
pmt.getId(), assets.map(AssetTrio::a__f).map(Registry::getBalance).orElse(null));
return error(req.getId(), ClearingError.BalanceInsufficient);
}
log.debug("assets found and balance is ok. am*b.id={}, am*t.id={}, am*f.id={}",
assets.get().am_b().getId(), assets.get().am_t().getId(), assets.get().am_f().getId());
assetsMng.process(assets.get().am_b(), assets.get().am_t(), assets.get().am_f(), amount.negate());
assets.get().a__b().getId(), assets.get().a__t().getId(), assets.get().a__f().getId());
assetsMng.process(assets.get().a__b(), assets.get().a__t(), assets.get().a__f(), amount.negate());
SDf54 sDf54 = sdf54Creator.create(pmt);
sDf54.setId(idGenerator.nextId());
sDf54.setGenerationId(pmt.getId());

View file

@ -7,11 +7,14 @@ 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.SDf20;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.RegistryManager;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.text.TextUtil;
@ -20,8 +23,7 @@ import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Map;
import java.util.Optional;
import static ru.spcex.platform.enumeration.RegistryTradingParams.AS_T;
import static ru.spcex.platform.enumeration.RegistryTradingParams.DS_T;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext<SDf20>> {
AccountPresent() {
@ -34,7 +36,7 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
}
Imdg<Account> accImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account acc = accImdg.getFirstObjectBySQL("account = '%s' and accountType = '%s'"
.formatted(depoCodeCl, AccountType.Clrn.getKey()));
.formatted(depoCodeCl, AccountType.Depo.getKey()));
if (acc == null) {
return of(ClearingError.AccountNotFoundB, depoCodeCl);
}
@ -60,6 +62,26 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
context.storeObject(ValidationStored.Sdf20Company, company);
return empty();
}
}, SecurityPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf20> context) {
SDf20 sDf20 = context.getValidatedObject();
String security = sDf20.getSecurity();
if (TextUtil.isEmpty(security)) {
return of(ClearingError.SecurityNotFound, security);
}
SecuritySelector<Security> slctr = new SecuritySelector<>(
context.obtainMap(IMDGDistributedNames.Map_FixedIncomeSecurity, Security.class),
context.obtainMap(IMDGDistributedNames.Map_MoneyMarketSecurity, Security.class),
context.obtainMap(IMDGDistributedNames.Map_EquitySecurity, Security.class)
);
Security securityFound = slctr.selectSecurityBySymbol(security);
if (securityFound == null) {
return of(ClearingError.SecurityNotFound, security);
}
context.storeObject(ValidationStored.Sdf20Security, securityFound);
return empty();
}
},
TCRPresent() {
@Override
@ -79,7 +101,7 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
return empty();
}
},
DS_TFound() {
DS_TPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf20> context) {
SDf20 sDf20 = context.getValidatedObject();
@ -92,14 +114,11 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
RegistryManager rgsMng = new RegistryManager(rgsImdg);
Optional<Registry> ds_t = rgsMng.searchByAccSecContract(acc.getId(), security, inDocument, DS_T);
if (ds_t.isEmpty()) {
return of(ClearingError.RecordNotFound, "DS*T");
}
context.storeObject(ValidationStored.Sdf20Dst, ds_t.get());
ds_t.ifPresent(registry -> context.storeObject(ValidationStored.Sdf20Dst, registry));
return empty();
}
},
AS_TFound() {
AssetsPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf20> context) {
SDf20 sDf20 = context.getValidatedObject();
@ -107,15 +126,20 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
String security = sDf20.getSecurity();
Account acc = context.getStoredObject(ValidationStored.Sdf20Account);
if (TextUtil.isEmpty(inDocument) || TextUtil.isEmpty(security) || acc == null) {
return of(ClearingError.RecordNotFound, "AS*T");
return of(ClearingError.RecordNotFound, "AS*T/AS*F/AS*B");
}
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
RegistryManager rgsMng = new RegistryManager(rgsImdg);
Optional<Registry> as_t = rgsMng.searchByAccSecContract(acc.getId(), security, inDocument, AS_T);
if (as_t.isEmpty()) {
return of(ClearingError.RecordNotFound, "AS*T");
Optional<Registry> as_t = rgsMng.searchByAccSec(acc.getId(), security, AS_T);
Optional<Registry> as_f = rgsMng.searchByAccSec(acc.getId(), security, AS_F);
Optional<Registry> as_b = rgsMng.searchByAccSec(acc.getId(), security, AS_B);
if (as_t.isPresent() && as_f.isPresent() && as_b.isPresent()) {
context.storeObject(ValidationStored.Sdf20Ast, new AssetTrio(as_f.get(), as_b.get(), as_t.get()));
return empty();
}
if (as_t.isPresent() || as_f.isPresent() || as_b.isPresent()) {
return of(ClearingError.RecordNotFound, "AS*T/AS*F/AS*B");
}
context.storeObject(ValidationStored.Sdf20Ast, as_t.get());
return empty();
}
}

View file

@ -1,11 +1,15 @@
package ru.spcex.clearing.service.validation;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.sdf.SDf21;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.imdg.api.Imdg;
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.text.TextUtil;
@ -33,6 +37,24 @@ public enum Sdf21ValidationRule implements IValidationRule<ImdgValidationContext
context.storeObject(ValidationStored.Sdf21Account, account.iterator().next());
return empty();
}
},
TransactionNumberProcessed() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {
SDf21 sdf21 = context.getValidatedObject();
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
Registry ds_t = rgsImdg.getFirstObjectByPredicate(
pb.and(
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.DS_T).build()),
pb.equals("comment", sdf21.getTransactionNumber())
)
);
if (ds_t != null) {
return of(ClearingError.SuchRecordAlreadyExists);
}
return empty();
}
};
@Override

View file

@ -22,7 +22,7 @@ public enum ValidationStored {
CompanyByTradingCode,
Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast,
Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security,
SecurityBySecurityCode
}

View file

@ -30,6 +30,7 @@ public class SDf20Table extends AbstractTable<SDf20> {
result.setDepoCodeCorr(record.getValFor87DTag());
result.setOperationDate(record.getValFor30Tag());
result.setCloseBalance(record.getValFor62ATag());
result.setTransactionNumber(record.getValFor23Tag());
result.setFileName(filename);
result.setGenerationTime(Instant.now());
result.setGenerationId(fileId);

View file

@ -10,6 +10,7 @@ public enum InOutSDfType implements IEnumKey {
type57("57"),
type08("0809"),
type10("1011"),
type20("20"),
type21("21"),
;