This commit is contained in:
parent
df63b37e3c
commit
6bdfb36c52
10 changed files with 473 additions and 3 deletions
|
|
@ -0,0 +1,153 @@
|
|||
package ru.spcex.clearing.session.stage.impl;
|
||||
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.misc.Market;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.session.stage.util.RegistryUtil;
|
||||
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class RegistryBuilder {
|
||||
public static RegistryBuilder builder() {
|
||||
return new RegistryBuilder();
|
||||
}
|
||||
|
||||
private RegistryBuilder() {
|
||||
}
|
||||
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Market> marketImdg;
|
||||
private Imdg<Session> sessionImdg;
|
||||
private ExecutionCommon exec;
|
||||
private RegistryDesignation regDsgn;
|
||||
|
||||
public RegistryBuilder imdg(ImdgProvider imdgProvider) {
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class);
|
||||
this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegistryBuilder exec(ExecutionCommon exec) {
|
||||
this.exec = exec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegistryBuilder registryDesignation(RegistryDesignation registryDesignation) {
|
||||
this.regDsgn = registryDesignation;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Registry build() {
|
||||
ISide side = getSide(exec);
|
||||
Registry reg = new Registry();
|
||||
reg.setCompanyId(exec.getCompanyId());
|
||||
Company company = searchCompany();
|
||||
reg.setTradingCode(company.getTradingCode());
|
||||
reg.setClearingCode(company.getClearingCode());
|
||||
reg.setShortName(company.getShortName());
|
||||
reg.setFullName(company.getFullName());
|
||||
TradingClearingRegistry tcr = searchTradingClearingRegistry();
|
||||
if ((regDsgn.equals(RegistryDesignation.O) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && side.isSell())) {
|
||||
reg.setAccountId(tcr.getMoneyAccountId());
|
||||
reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey());
|
||||
reg.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme add second leg code branch
|
||||
} else if ((regDsgn.equals(RegistryDesignation.T) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && side.isSell())) {
|
||||
reg.setAccountId(tcr.getDepoAccountId());
|
||||
reg.setRegistryInstrumentType(RegistryInstrumentType.S.getKey());
|
||||
reg.setBalanceDimension(BalanceDimension.PICS.getKey()); //fixme add second leg code branch
|
||||
}
|
||||
Account account = accountImdg.getSingleObjectByID(reg.getAccountId());
|
||||
reg.setAccountType(account.getAccountType());
|
||||
reg.setAccount(account.getAccount());
|
||||
reg.setRegistryDesignation(regDsgn.getKey());
|
||||
reg.setRegistryCapacity(account.getAccountType());
|
||||
reg.setRegistryUnit(RegistryUnit.T.getKey());
|
||||
reg.setRegistryCode(RegistryUtil.clearingCode(reg));
|
||||
reg.setTradingClearingRegistryId(exec.getTradingClearingRegistryId());
|
||||
reg.setTradingClearingRegistry(tcr.getCode());
|
||||
reg.setRegistryStatus(RegistryStatus.PROC.getKey());
|
||||
reg.setSecurityId(exec.getSecurityId());
|
||||
reg.setSecuritySymbol(exec.getSecuritySymbol());
|
||||
switch (exec.type()) {
|
||||
case ExecutionDeposit -> {
|
||||
ExecutionDeposit execDep = (ExecutionDeposit) this.exec;
|
||||
reg.setBalance((execDep).getFirstLegAmount());
|
||||
if (regDsgn.equals(RegistryDesignation.T)) {
|
||||
reg.setSettledCredit((execDep).getFirstLegAmount());
|
||||
} else if (regDsgn.equals(RegistryDesignation.O)) {
|
||||
reg.setSettledDebit((execDep).getFirstLegAmount());
|
||||
}
|
||||
reg.setSettlementDate(execDep.getFirstLegSettlementDate()); //fixme add second leg code branch
|
||||
reg.setSettlementCode(execDep.getFirstLegSettlementCode()); //fixme add second leg code branch
|
||||
reg.setRefundDate(execDep.getSecondLegSettlementDate()); //fixme add second leg code branch??
|
||||
reg.setValueDate(execDep.getFirstLegSettlementDate());
|
||||
reg.setContract(execDep.getContract());
|
||||
}
|
||||
case ExecutionFond -> {
|
||||
ExecutionFond execFond = (ExecutionFond) this.exec;
|
||||
reg.setBalance(execFond.getSettlementAmount());
|
||||
reg.setSettlementDate(execFond.getSettlementDate());
|
||||
reg.setSettlementCode(execFond.getSettlementCode());
|
||||
}
|
||||
}
|
||||
reg.setTradingDate(exec.getTradingDate());
|
||||
reg.setClearingDate(LocalDate.now());
|
||||
reg.setPrice(exec.getPrice());
|
||||
reg.setCounterPartyId(exec.getCounterPartyId());
|
||||
reg.setGroupId(groupId());
|
||||
reg.setSessionId(exec.getSessionId());
|
||||
reg.setSessionType(sessionType());
|
||||
return reg;
|
||||
}
|
||||
|
||||
private static DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
|
||||
private Long groupId() {
|
||||
LocalDate now = LocalDate.now();
|
||||
Market market = marketImdg.getSingleObjectBySQL("code = '" + exec.getMarket() + "'");
|
||||
return Long.valueOf(now.format(yyyyMMdd) + exec.getExchangeExecutionId() + market.getId());
|
||||
}
|
||||
|
||||
//можно передать из стейджа
|
||||
private String sessionType() {
|
||||
Session session = sessionImdg.getSingleObjectByID(exec.getSessionId());
|
||||
return session.getSessionType();
|
||||
}
|
||||
|
||||
private Company searchCompany() {
|
||||
return companyImdg.getSingleObjectBySQL("id = " + exec.getCompanyId());
|
||||
}
|
||||
|
||||
private TradingClearingRegistry searchTradingClearingRegistry() {
|
||||
return tradingClearingRegistryImdg.getSingleObjectBySQL("tradingClearingRegistryId = " + exec.getTradingClearingRegistryId());
|
||||
}
|
||||
|
||||
private static ISide getSide(ExecutionCommon exec) {
|
||||
if (exec.type().equals(ExecutionType.ExecutionDeposit)) {
|
||||
return ISide.parse(MoneyFlowSide.class, exec.getSide());
|
||||
} else if (exec.type().equals(ExecutionType.ExecutionFond)) {
|
||||
return ISide.parse(Side.class, exec.getSide());
|
||||
} else {
|
||||
throw new RuntimeException("Unknown Execution type: " + exec.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package ru.spcex.clearing.session.stage.impl;
|
||||
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
public class RegistryUpdater {
|
||||
public static RegistryUpdater updater() {
|
||||
return new RegistryUpdater();
|
||||
}
|
||||
|
||||
private RegistryUpdater() {
|
||||
}
|
||||
|
||||
private Imdg<Registry> registryImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private ExecutionCommon exec;
|
||||
private Registry rgs;
|
||||
|
||||
public RegistryUpdater imdg(ImdgProvider imdgProvider) {
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegistryUpdater registry(Registry rgs) {
|
||||
this.rgs = rgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegistryUpdater exec(ExecutionCommon exec) {
|
||||
this.exec = exec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Registry update() {
|
||||
Registry reg = new Registry();
|
||||
reg.setCompanyId(exec.getCompanyId());
|
||||
Company company = searchCompany();
|
||||
reg.setTradingCode(company.getTradingCode());
|
||||
reg.setClearingCode(company.getClearingCode());
|
||||
reg.setShortName(company.getShortName());
|
||||
reg.setFullName(company.getFullName());
|
||||
TradingClearingRegistry tcr = searchTradingClearingRegistry();
|
||||
return null;
|
||||
}
|
||||
|
||||
private Company searchCompany() {
|
||||
return companyImdg.getSingleObjectBySQL("id = " + exec.getCompanyId());
|
||||
}
|
||||
|
||||
private TradingClearingRegistry searchTradingClearingRegistry() {
|
||||
return tradingClearingRegistryImdg.getSingleObjectBySQL("tradingClearingRegistryId = " + exec.getTradingClearingRegistryId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// public
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
package ru.spcex.clearing.session.stage.impl;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.models.RegistryTradingParams;
|
||||
import ru.spcex.clearing.service.builder.sql.RegistryCodeSqlBuilder;
|
||||
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.TaskType;
|
||||
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
|
||||
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;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.utils.collection.Pair;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@Service
|
||||
public class RequirmentsAndObligationCreation implements ISessionStage {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final ImdgProvider imdgProvider;
|
||||
|
||||
|
||||
@Autowired
|
||||
public RequirmentsAndObligationCreation(ImdgProvider imdgProvider) {
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.imdgProvider = imdgProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public StageResult<?> submit(Task<?> task) {
|
||||
if (task.getTaskType() == TaskType.RequirementsAndObligationsCreate) {
|
||||
return createRegisters((List<ExecutionCommon>) task.getData());
|
||||
}
|
||||
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
|
||||
}
|
||||
|
||||
private StageResult<?> createRegisters(List<ExecutionCommon> data) {
|
||||
if (data.size() % 2 != 0) {
|
||||
throw new IllegalStateException("Data size must be even (executions must match)");
|
||||
}
|
||||
//см. описание к #matchExecutions
|
||||
for (int i = 0; i < data.size(); ) {
|
||||
Pair<ExecutionCommon, ExecutionCommon> matched = matchExecutions(data, i);
|
||||
if (matched == null) {
|
||||
log.error("couldn't find match execution for id = {}", data.get(i).getId());
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
i += 2;
|
||||
ExecutionCommon partyExec = matched.getFirst();
|
||||
ExecutionCommon counterExec = matched.getSecond();
|
||||
|
||||
BiConsumer<ExecutionCommon, RegistryDesignation> findAndUpdateOrCreate = (exec, regDsgn) ->
|
||||
findReg(exec, regDsgn).ifPresentOrElse(registry -> {
|
||||
RegistryUpdater.updater()
|
||||
.imdg(imdgProvider)
|
||||
.exec(partyExec)
|
||||
.registry(registry)
|
||||
.update();
|
||||
registryImdg.update(registry);
|
||||
}, () -> {
|
||||
Registry newRegister = RegistryBuilder.builder()
|
||||
.imdg(imdgProvider)
|
||||
.exec(partyExec)
|
||||
.registryDesignation(regDsgn)
|
||||
.build();
|
||||
registryImdg.insert(newRegister);
|
||||
});
|
||||
findAndUpdateOrCreate.accept(partyExec, RegistryDesignation.O);
|
||||
findAndUpdateOrCreate.accept(partyExec, RegistryDesignation.T);
|
||||
findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.O);
|
||||
findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.T);
|
||||
}
|
||||
return new StageResult<>(null, true);
|
||||
}
|
||||
|
||||
|
||||
private Optional<Registry> findReg(ExecutionCommon exec, RegistryDesignation des) {
|
||||
ISide side = getSide(exec);
|
||||
RegistryTradingParams p;
|
||||
if (side.isBuy() && des.equals(RegistryDesignation.O)) {
|
||||
p = new RegistryTradingParams(
|
||||
RegistryDesignation.O, RegistryInstrumentType.M, null, RegistryUnit.T
|
||||
);
|
||||
} else if (side.isBuy() && des.equals(RegistryDesignation.T)) {
|
||||
p = new RegistryTradingParams(
|
||||
RegistryDesignation.T, RegistryInstrumentType.S, null, RegistryUnit.T
|
||||
);
|
||||
} else if (side.isSell() && des.equals(RegistryDesignation.O)) {
|
||||
p = new RegistryTradingParams(
|
||||
RegistryDesignation.O, RegistryInstrumentType.S, null, RegistryUnit.T
|
||||
);
|
||||
} else if (side.isSell() && des.equals(RegistryDesignation.T)) {
|
||||
p = new RegistryTradingParams(
|
||||
RegistryDesignation.T, RegistryInstrumentType.M, null, RegistryUnit.T
|
||||
);
|
||||
} else {
|
||||
throw new IllegalStateException("cannot construct for " + des + " " + side);
|
||||
}
|
||||
String sql = RegistryCodeSqlBuilder.getInstance(p).build();
|
||||
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
|
||||
ImdgPredicate rgstrPredicate = pb.and(pb.sql(sql),
|
||||
pb.equals("tradingClearingRegistryId", exec.getTradingClearingRegistryId()),
|
||||
pb.equals("companyId", exec.getCompanyId()),
|
||||
pb.equals("settlementDate", settlementDt(exec))
|
||||
);
|
||||
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(rgstrPredicate));
|
||||
}
|
||||
|
||||
private LocalDate settlementDt(ExecutionCommon exec) {
|
||||
if (exec.type().equals(ExecutionType.ExecutionDeposit)) {
|
||||
return ((ExecutionDeposit) exec).getFirstLegSettlementDate();
|
||||
} else if (exec.type().equals(ExecutionType.ExecutionFond)) {
|
||||
return ((ExecutionFond) exec).getSettlementDate();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown Execution type: " + exec.type());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* входные данные отсортированы по exchangeExecutionId.
|
||||
* сортировка выполнена на предыдущем шаге. (такое описание шагов в ТЗ)
|
||||
* по идее, Execution с одинаковым exchangeExecutionId должно быть всего два.
|
||||
* если это не так, передалать на коллекцию Long executionId в правильном порядке
|
||||
* и для каждого искать мэтч отдельно в Imdg, с сохранением уже обработанных для избежания дублирования
|
||||
*/
|
||||
private Pair<ExecutionCommon, ExecutionCommon> matchExecutions(List<ExecutionCommon> data, int i) {
|
||||
//if the last execution, then no match
|
||||
if (i >= data.size() - 1) {
|
||||
return null;
|
||||
}
|
||||
ExecutionCommon exec1 = data.get(i);
|
||||
ExecutionCommon exec2 = data.get(i + 1);
|
||||
//Встречная сделка контрагента выбирается из executionDeposit/Fond по условию:
|
||||
//exchangeExecutionId=currentExecutionDeposit/Fond.exchangeExecutionId
|
||||
//и [side=SELL (если currentExecutionDeposit/Fond.side=BUY) или side=BUY (если currentExecutionDeposit/Fond.side=SELL) по справочнику moneyFlowSide или справочнику side в зависимости от секции обрабатываемой сделки]
|
||||
//и companyId=currentExecutionDeposit/Fond.counterPartyId
|
||||
boolean valid = true;
|
||||
if (!Objects.equals(exec1.getExchangeExecutionId(), exec2.getExchangeExecutionId())) {
|
||||
valid = false;
|
||||
} else if (Objects.equals(getSide(exec1), getSide(exec2))) {
|
||||
valid = false;
|
||||
} else if (!Objects.equals(exec1.getCounterPartyId(), exec2.getCounterPartyId())) {
|
||||
valid = false;
|
||||
}
|
||||
if (!valid) {
|
||||
log.error("FATAL skipping ExchangeExecutionId: {}", exec1.getId());
|
||||
}
|
||||
return new Pair<>(exec1, exec2);
|
||||
}
|
||||
|
||||
private static ISide getSide(ExecutionCommon exec) {
|
||||
if (exec.type().equals(ExecutionType.ExecutionDeposit)) {
|
||||
return ISide.parse(MoneyFlowSide.class, exec.getSide());
|
||||
} else if (exec.type().equals(ExecutionType.ExecutionFond)) {
|
||||
return ISide.parse(Side.class, exec.getSide());
|
||||
} else {
|
||||
throw new RuntimeException("Unknown Execution type: " + exec.type());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum BalanceDimension implements IEnumKey {
|
||||
MONY("MONY"),
|
||||
PICS("PICS"),
|
||||
;
|
||||
|
||||
private final String key;
|
||||
|
||||
BalanceDimension(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public interface ISide {
|
||||
boolean isBuy();
|
||||
boolean isSell();
|
||||
default boolean isOpposite(ISide other) {
|
||||
return (isBuy() && other.isSell()) || (isSell() && other.isBuy());
|
||||
}
|
||||
|
||||
static <T extends Enum<T> & IEnumKey & ISide> ISide parse(Class<T> clazz, String key) {
|
||||
return IEnumKey.getEnumByKey(clazz, key);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package ru.spcex.platform.enumeration;
|
|||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum MoneyFlowSide implements IEnumKey {
|
||||
public enum MoneyFlowSide implements IEnumKey, ISide {
|
||||
BUY("BUY"),
|
||||
SELL("SELL"),
|
||||
;
|
||||
|
|
@ -17,4 +17,15 @@ public enum MoneyFlowSide implements IEnumKey {
|
|||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBuy() {
|
||||
return equals(BUY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSell() {
|
||||
return equals(SELL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum RegistryStatus implements IEnumKey {
|
||||
OK("OK"),
|
||||
OK("OK"), PROC("PROC"),
|
||||
;
|
||||
|
||||
private final String key;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package ru.spcex.platform.enumeration;
|
|||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum Side implements IEnumKey {
|
||||
public enum Side implements IEnumKey, ISide {
|
||||
BUY("B"),
|
||||
SELL("S"),
|
||||
;
|
||||
|
|
@ -17,4 +17,15 @@ public enum Side implements IEnumKey {
|
|||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBuy() {
|
||||
return equals(BUY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSell() {
|
||||
return equals(SELL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,15 @@ public class ImdgHazelcast<T extends SpcexObjectBase> implements Imdg<T> {
|
|||
return searchResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getSingleObjectByPredicate(ImdgPredicate predicate) {
|
||||
Collection<T> els = getCollectionObjectsByPredicate(predicate);
|
||||
if (els.size() > 1) {
|
||||
throw new RuntimeException("More than one element found by predicate - " + els.size());
|
||||
}
|
||||
return els.iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImdgPredicateBuilder predicateBuilder() {
|
||||
return ImdgPredicateBuilderHazelcast.instance();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,11 @@ public interface Imdg<T extends SpcexObjectBase> {
|
|||
throw new UnsupportedOperationException("not implemented getCollectionObjectsByPredicate");
|
||||
}
|
||||
|
||||
// Predicate API
|
||||
default T getSingleObjectByPredicate(ImdgPredicate predicate) {
|
||||
throw new UnsupportedOperationException("not implemented getSingleObjectByPredicate");
|
||||
}
|
||||
|
||||
default ImdgPredicateBuilder predicateBuilder() {
|
||||
throw new UnsupportedOperationException("not implemented predicateBuilder API");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue