ialbert 2026-04-13 18:53:16 +03:00
parent 8c4f3f4769
commit db2079821c
13 changed files with 374 additions and 20 deletions

View file

@ -0,0 +1,39 @@
package ru.spcex.clearing.dflt.management.component.validation;
import java.util.Collection;
import java.util.Optional;
import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public class OrderCurrencyByCompanyAndTcrAlreadyPresent implements IValidationRule<ImdgValidationContext<OrderCompanyNewRequest>> {
public static final OrderCurrencyByCompanyAndTcrAlreadyPresent INSTANCE = new OrderCurrencyByCompanyAndTcrAlreadyPresent();
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<OrderCompanyNewRequest> ctx) {
OrderCompanyNewRequest validatedObject = ctx.getValidatedObject();
Imdg<OrderCurrency> imdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
ImdgPredicateBuilder pb = imdg.predicateBuilder();
Collection<OrderCurrency> orders = imdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("tradingClearingRegistryId", validatedObject.getTradingClearingRegistryId()),
pb.equals("companyId", validatedObject.getCompanyId())
)
);
if (!orders.isEmpty()) {
return of(DefaultManagementErrors.RecordAlreadyPresent);
}
return empty();
}
@Override
public String ruleName() {
return "OrderCurrencyByCompanyAndTcrAlreadyPresent";
}
}

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.dflt.management.component.validation;
import java.util.Optional;
import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors;
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCompanyNewRequest;
import ru.spcex.platform.enumeration.OrderAffil;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public class OrderCurrencyPLBLCheck implements IValidationRule<ImdgValidationContext<OrderCompanyNewRequest>> {
public static final OrderCurrencyPLBLCheck INSTANCE = new OrderCurrencyPLBLCheck();
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<OrderCompanyNewRequest> ctx) {
OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
if (!OrderAffil.PLBL.equalsByKey(order.getType())) {
return of(DefaultManagementErrors.OnlyBalancingOrdersAllowed);
}
return empty();
}
@Override
public String ruleName() {
return "OrderCurrencyPLBLCheck";
}
}

View file

@ -1,5 +1,5 @@
package ru.spcex.clearing.dflt.management.component.validation; package ru.spcex.clearing.dflt.management.component.validation;
public enum OrderCurrencyValidationStored { public enum OrderCurrencyValidationStored {
OrderCurrency, Company, TCR OrderCurrency, OrderCurrencySpotPair, Registry, Company, TCR
} }

View file

@ -0,0 +1,32 @@
package ru.spcex.clearing.dflt.management.component.validation;
import java.util.Optional;
import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors;
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public class OvernightTypeChanged implements IValidationRule<ImdgValidationContext<OrderCurrencyUpdateRequest>> {
public static final OvernightTypeChanged INSTANCE = new OvernightTypeChanged();
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<OrderCurrencyUpdateRequest> ctx) {
OrderCurrencyUpdateRequest validatedObject = ctx.getValidatedObject();
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
if (oc.getOvernightType() == null) {
return of(DefaultManagementErrors.GeneralError); //не понятно че с ним делать...
}
if (oc.getOvernightType().equalsIgnoreCase(validatedObject.getOvernightType())) {
return of(DefaultManagementErrors.GeneralError); //todo нормальную ошибку
}
return empty();
}
@Override
public String ruleName() {
return "QuantityLotGreaterThanZero";
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.dflt.management.component.validation;
import java.util.Optional;
import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.order.OrderCurrencyUpdateRequest;
import ru.spcex.platform.enumeration.OvernightType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public class SpotPairPresent implements IValidationRule<ImdgValidationContext<OrderCurrencyUpdateRequest>> {
public static final SpotPairPresent INSTANCE = new SpotPairPresent();
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<OrderCurrencyUpdateRequest> ctx) {
OrderCurrency oc = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
if (!OvernightType.SPOT.equalsByKey(oc.getOvernightType())) {
return empty();
}
Imdg<OrderCurrency> ocImdg = ctx.obtainMap(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
ImdgPredicateBuilder pb = ocImdg.predicateBuilder();
OrderCurrency pairOc = ocImdg.getSingleObjectByPredicate(
pb.and(
pb.equals("overnightType", oc.getOvernightType()),
pb.equals("registryId", oc.getRegistryId()),
pb.equals("companyId", oc.getCompanyId()),
pb.equals("tradingClearingRegistryId", oc.getTradingClearingRegistryId()),
pb.equals("counterPartyId", oc.getCounterPartyId()),
pb.not(
pb.equals("id", oc.getId())
)
)
);
if (pairOc == null) {
return of(DefaultManagementErrors.GeneralError); //todo нормальная ошибка
}
ctx.storeObject(OrderCurrencyValidationStored.OrderCurrencySpotPair, pairOc);
return empty();
}
@Override
public String ruleName() {
return "SpotPairPresent";
}
}

View file

@ -8,10 +8,15 @@ import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.misc.Market; import ru.clearing.classes.statics.data.misc.Market;
import ru.clearing.classes.statics.data.misc.OrderCurrency; import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.clearing.classes.statics.data.misc.OvernightSettings; import ru.clearing.classes.statics.data.misc.OvernightSettings;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.OvernightTypeDictionary; import ru.clearing.platform.dictionary.OvernightTypeDictionary;
import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyByCompanyAndTcrAlreadyPresent;
import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyPLBLCheck;
import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored; import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored;
import ru.spcex.clearing.dflt.management.component.validation.OvernightTypeChanged;
import ru.spcex.clearing.dflt.management.component.validation.QuantityLotGreaterThanZero; import ru.spcex.clearing.dflt.management.component.validation.QuantityLotGreaterThanZero;
import ru.spcex.clearing.dflt.management.component.validation.SpotPairPresent;
import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors; import ru.spcex.clearing.dflt.management.error.DefaultManagementErrors;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.misc.OvernightSettingsNewRequest;
@ -23,7 +28,9 @@ import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule; import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate; import ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate;
import static ru.spcex.platform.imdg.api.predicate.specific.IdEqualPredicate.byId;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.LogPrefixId; import ru.spcex.platform.imdg.validation.LogPrefixId;
import ru.spcex.platform.imdg.validation.rule.PresentById; import ru.spcex.platform.imdg.validation.rule.PresentById;
@ -41,6 +48,7 @@ public class ValidationConfig {
private final Imdg<Market> marketImdg; private final Imdg<Market> marketImdg;
private final Imdg<OvernightTypeDictionary> osTypeDictionaryImdg; private final Imdg<OvernightTypeDictionary> osTypeDictionaryImdg;
private final Imdg<OrderCurrency> orderCurrencyImdg; private final Imdg<OrderCurrency> orderCurrencyImdg;
private final Imdg<Registry> rgsImdg;
@Autowired @Autowired
public ValidationConfig(ImdgProvider imdgProvider) { public ValidationConfig(ImdgProvider imdgProvider) {
@ -50,6 +58,7 @@ public class ValidationConfig {
this.osTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightTypeDictionary, OvernightTypeDictionary.class); this.osTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightTypeDictionary, OvernightTypeDictionary.class);
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
this.tcrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); this.tcrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
} }
public enum OvernightSettingsValidationStorage { public enum OvernightSettingsValidationStorage {
@ -76,7 +85,7 @@ public class ValidationConfig {
SpecialIdPresentRule.instance("market", SpecialIdPresentRule.instance("market",
OvernightSettingsNewRequest::getMarket, "code", OvernightSettingsNewRequest::getMarket, "code",
IMDGDistributedNames.Map_Market, IMDGDistributedNames.Map_Market,
ru.clearing.classes.statics.data.misc.Market.class, Market.class,
DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.RequiredFieldIsEmpty,
DefaultManagementErrors.DictionaryNotFound, DefaultManagementErrors.DictionaryNotFound,
true true
@ -107,7 +116,7 @@ public class ValidationConfig {
SpecialIdPresentRule.instance("market", SpecialIdPresentRule.instance("market",
OvernightSettingsUpdateRequest::getMarket, "code", OvernightSettingsUpdateRequest::getMarket, "code",
IMDGDistributedNames.Map_Market, IMDGDistributedNames.Map_Market,
ru.clearing.classes.statics.data.misc.Market.class, Market.class,
DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.RequiredFieldIsEmpty,
DefaultManagementErrors.DictionaryNotFound, DefaultManagementErrors.DictionaryNotFound,
true true
@ -125,8 +134,34 @@ public class ValidationConfig {
ctx.setValidatedObject(req); ctx.setValidatedObject(req);
ctx.setLogPrefix(LogPrefixId.INSTANCE); ctx.setLogPrefix(LogPrefixId.INSTANCE);
ctx.addImdg(IMDGDistributedNames.Map_OrderCurrency, orderCurrencyImdg); ctx.addImdg(IMDGDistributedNames.Map_OrderCurrency, orderCurrencyImdg);
ctx.addImdg(IMDGDistributedNames.Map_Registry, rgsImdg);
ctx.addImdg(IMDGDistributedNames.Map_OvernightTypeDictionary, osTypeDictionaryImdg);
var orderCurrencyPresentById = PresentByPredicate
.builder(byId(orderCurrencyImdg.predicateBuilder(), req))
.mapName(IMDGDistributedNames.Map_OrderCurrency)
.errorProvider(r -> recordNotFound(r.getId()))
.store(OrderCurrencyValidationStored.OrderCurrency)
.build();
ImdgPredicateBuilder rgsPb = rgsImdg.predicateBuilder();
var registryPresent = PresentByPredicate
.builder(r -> {
OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
return rgsPb.equals("id", order.getRegistryId());
})
.mapName(IMDGDistributedNames.Map_Registry)
.errorProvider(r -> {
OrderCurrency order = ctx.getStoredObject(OrderCurrencyValidationStored.OrderCurrency);
return recordNotFound("registry.id=" + order.getRegistryId());
})
.store(OrderCurrencyValidationStored.Registry)
.build();
return new ValidatorImpl<>(ctx, return new ValidatorImpl<>(ctx,
new PresentById(IMDGDistributedNames.Map_OrderCurrency, DefaultManagementErrors.DictionaryNotFound, true), orderCurrencyPresentById,
OvernightTypeChanged.INSTANCE,
DictionaryPresentRule.instance( DictionaryPresentRule.instance(
"overnightType", "overnightType",
OvernightSettingsNewRequest::getOvernightType, OvernightSettingsNewRequest::getOvernightType,
@ -134,7 +169,9 @@ public class ValidationConfig {
OvernightTypeDictionary.class, OvernightTypeDictionary.class,
DefaultManagementErrors.RequiredFieldIsEmpty, DefaultManagementErrors.RequiredFieldIsEmpty,
DefaultManagementErrors.DictionaryNotFound, DefaultManagementErrors.DictionaryNotFound,
true) true),
SpotPairPresent.INSTANCE,
registryPresent
); );
}; };
} }
@ -194,7 +231,9 @@ public class ValidationConfig {
orderCurrencyPresent, orderCurrencyPresent,
companyPresentRule, companyPresentRule,
tcrPresent, tcrPresent,
QuantityLotGreaterThanZero.INSTANCE); QuantityLotGreaterThanZero.INSTANCE,
OrderCurrencyByCompanyAndTcrAlreadyPresent.INSTANCE,
OrderCurrencyPLBLCheck.INSTANCE);
}; };
} }

View file

@ -10,6 +10,8 @@ public enum DefaultManagementErrors implements IErrorEnumId {
RequiredFieldIsEmpty(3002L), RequiredFieldIsEmpty(3002L),
DictionaryNotFound(3003L), DictionaryNotFound(3003L),
RecordNotFound(3006L), RecordNotFound(3006L),
RecordAlreadyPresent(11002L),
OnlyBalancingOrdersAllowed(11003L),
; ;
private final Long id; private final Long id;

View file

@ -1,6 +1,8 @@
package ru.spcex.clearing.dflt.management.listener; package ru.spcex.clearing.dflt.management.listener;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.Consumer;
@ -10,11 +12,15 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.misc.Market;
import ru.clearing.classes.statics.data.misc.OrderCurrency; import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.clearing.classes.statics.data.misc.OvernightSettings; import ru.clearing.classes.statics.data.misc.OvernightSettings;
import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.security.Rates;
import ru.clearing.platform.dictionary.CurrencyPairDictionary;
import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored; import ru.spcex.clearing.dflt.management.component.validation.OrderCurrencyValidationStored;
import ru.spcex.clearing.dflt.management.service.OrderCurrencyService; import ru.spcex.clearing.dflt.management.service.ImdgQueryService;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -24,11 +30,17 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.MarketType;
import ru.spcex.platform.enumeration.OvernightType;
import ru.spcex.platform.enumeration.SettleCode;
import ru.spcex.platform.enumeration.Side;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.Stored; import ru.spcex.platform.utils.collection.Pair;
import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.number.BigDecimalUtil;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
@Service @Service
@ -39,6 +51,7 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
private final Imdg<OrderCurrency> orderCurrencyImdg; private final Imdg<OrderCurrency> orderCurrencyImdg;
private final Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator; private final Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator;
private final Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator; private final Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator;
private final ImdgQueryService imdgQueryService;
private final IMessageResolver msgResolver; private final IMessageResolver msgResolver;
@Autowired @Autowired
@ -46,15 +59,15 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
Producer<String, Object> kafkaProducer, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider, ImdgProvider imdgProvider,
UserRoleVerification userRoleVerification, UserRoleVerification userRoleVerification,
OrderCurrencyService orderCurrencyService,
Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator, Function<OrderCurrencyUpdateRequest, IValidator> overnightTypeUpdateValidator,
Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator, Function<OrderCompanyNewRequest, IValidator> orderCompanyNewValidator, ImdgQueryService imdgQueryService,
IMessageResolver msgResolver) { IMessageResolver msgResolver) {
super(kafkaQueue, kafkaProducer); super(kafkaQueue, kafkaProducer);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class); this.overnightSettingsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OvernightSettings, OvernightSettings.class);
this.overnightTypeUpdateValidator = overnightTypeUpdateValidator; this.overnightTypeUpdateValidator = overnightTypeUpdateValidator;
this.orderCompanyNewValidator = orderCompanyNewValidator; this.orderCompanyNewValidator = orderCompanyNewValidator;
this.imdgQueryService = imdgQueryService;
this.msgResolver = msgResolver; this.msgResolver = msgResolver;
this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class); this.orderCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_OrderCurrency, OrderCurrency.class);
} }
@ -77,15 +90,122 @@ public class OrderCurrencyListener extends QueueConsumer implements Initializing
if (error.isPresent()) { if (error.isPresent()) {
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(error.get())); return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(error.get()));
} }
OrderCurrency orderCurrency = validator.getStored(Stored.PresentById); OrderCurrency order = validator.getStored(OrderCurrencyValidationStored.OrderCurrency);
orderCurrency.setOvernightType(payload.getOvernightType()); Registry rgs = validator.getStored(OrderCurrencyValidationStored.Registry);
log.info("Updating overnight type for orderCurrency.id={} to {}", if (OvernightType.SWAP.equalsByKey(order.getOvernightType())) {
orderCurrency.getId(), Pair<OrderCurrency, OrderCurrency> newSpotPair = swapToSpotSplit(order, rgs);
orderCurrency.getOvernightType()); log.info("deleting old OrderCurrency.id={}", order.getId());
orderCurrencyImdg.update(orderCurrency); orderCurrencyImdg.delete(order);
orderCurrencyImdg.insert(newSpotPair.getFirst());
orderCurrencyImdg.insert(newSpotPair.getSecond());
log.info("created OrderCurrency[{}, {}]",
newSpotPair.getFirst().getId(), newSpotPair.getSecond().getId());
} else if (OvernightType.SPOT.equalsByKey(order.getOvernightType())) {
OrderCurrency pairOrder = validator.getStored(OrderCurrencyValidationStored.OrderCurrencySpotPair);
OrderCurrency newSwapOrder = spotToSwap(order, pairOrder, rgs);
log.info("deleting old records OrderCurrency[{}, {}]", order.getId(), pairOrder.getId());
orderCurrencyImdg.delete(order);
orderCurrencyImdg.delete(pairOrder);
orderCurrencyImdg.insert(newSwapOrder);
log.info("created OrderCurrency.id={}", newSwapOrder.getId());
}
return null; return null;
} }
private Pair<OrderCurrency, OrderCurrency> swapToSpotSplit(OrderCurrency swap, Registry rgs) {
OrderCurrency orderT0 = new OrderCurrency();
OrderCurrency orderT1 = new OrderCurrency();
orderT0.setSettleCode(SettleCode.T0.getKey());
orderT1.setSettleCode(SettleCode.T1.getKey());
if (Side.SELL.equalsByKey(swap.getSide())) {
orderT0.setSide(Side.BUY.getKey());
orderT1.setSide(Side.SELL.getKey());
} else {
orderT0.setSide(Side.SELL.getKey());
orderT1.setSide(Side.BUY.getKey());
}
Market market = imdgQueryService.getSpotMarket();
Listing listing = imdgQueryService.findListing(rgs, market.getCode());
//мб возвращать вместе с листингом?
CurrencyPairDictionary currPair = imdgQueryService.getCurrencyPairDictionaryByListing(listing);
Rates rate = imdgQueryService.getRate(currPair.getBaseCurrency(), LocalDate.now());
var pair = new Pair<>(orderT0, orderT1);
Pair.forEach(pair, o -> {
o.setSecurityId(listing.getSecurityId());
o.setSecuritySymbol(listing.getSymbolCode());
o.setAccount(swap.getAccount());
o.setTradingClearingRegistryId(swap.getTradingClearingRegistryId());
o.setCompanyId(swap.getCompanyId());
o.setTradingCode(swap.getTradingCode());
o.setCounterPartyId(swap.getCounterPartyId());
o.setCounterTradingCode(swap.getCounterTradingCode());
o.setType(swap.getType());
o.setOvernightType(OvernightType.SPOT.getKey());
o.setListingId(listing.getId());
o.setMarket(MarketType.SCSP.getKey());
o.setRate(swap.getRate());
o.setQuantityLot(swap.getQuantityLot());
o.setLotSize(swap.getLotSize());
o.setStatus(swap.getStatus());
o.setComment(swap.getComment());
o.setRegistryId(swap.getRegistryId());
o.setCreated(Instant.now());
});
orderT0.setPrice(rate.getValue());
orderT1.setPrice(BigDecimalUtil.safeSumBD(swap.getPrice(), rate.getValue()));
return pair;
}
private OrderCurrency spotToSwap(OrderCurrency order1, OrderCurrency order2, Registry rgs) {
OrderCurrency spotT0;
OrderCurrency spotT1;
if (SettleCode.T0.getKey().equals(order1.getSettleCode())) {
spotT0 = order1;
spotT1 = order2;
} else {
spotT0 = order2;
spotT1 = order1;
}
OrderCurrency swap = new OrderCurrency();
swap.setSettleCode(SettleCode.T1.getKey());
if (Side.SELL.equalsByKey(spotT0.getSide())) {
swap.setSide(Side.BUY.getKey());
} else {
swap.setSide(Side.SELL.getKey());
}
Market market = imdgQueryService.getSwapMarket();
Listing listing = imdgQueryService.findListing(rgs, market.getCode());
swap.setSecurityId(listing.getSecurityId());
swap.setSecuritySymbol(listing.getSymbolCode());
swap.setAccount(order1.getAccount());
swap.setTradingClearingRegistryId(order1.getTradingClearingRegistryId());
swap.setCompanyId(order1.getCompanyId());
swap.setTradingCode(order1.getTradingCode());
swap.setCounterPartyId(order1.getCounterPartyId());
swap.setCounterTradingCode(order1.getCounterTradingCode());
swap.setType(order1.getType());
swap.setOvernightType(OvernightType.SWAP.getKey());
swap.setListingId(listing.getId());
swap.setMarket(MarketType.SCSW.getKey());
swap.setPrice(safeBD(spotT1.getPrice()).subtract(safeBD(spotT0.getPrice())));
swap.setRate(order1.getRate());
swap.setQuantityLot(order1.getQuantityLot());
swap.setLotSize(order1.getLotSize());
swap.setStatus(order1.getStatus());
swap.setComment(order1.getComment());
swap.setRegistryId(order1.getRegistryId());
swap.setCreated(Instant.now());
return swap;
}
private RequestInfoUpdate updateCompany(BaseRequest<OrderCompanyNewRequest> req) { private RequestInfoUpdate updateCompany(BaseRequest<OrderCompanyNewRequest> req) {
OrderCompanyNewRequest payload = req.getRequestPayload(); OrderCompanyNewRequest payload = req.getRequestPayload();
IValidator validator = orderCompanyNewValidator.apply(payload); IValidator validator = orderCompanyNewValidator.apply(payload);

View file

@ -129,7 +129,12 @@ public class ImdgQueryService {
return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSW)); return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSW));
} }
public Listing findSwapListing(Registry registry, String marketCode) { public Market getSpotMarket() {
ImdgPredicateBuilder pb = marketImdg.predicateBuilder();
return marketImdg.getSingleObjectByPredicate(pb.equals("marketType", MarketType.SCSP));
}
public Listing findListing(Registry registry, String marketCode) {
return "RUB".equals(registry.getSecuritySymbol()) return "RUB".equals(registry.getSecuritySymbol())
? findListingForRub(registry, marketCode) ? findListingForRub(registry, marketCode)
: findListingForOtherCurrency(registry, marketCode); : findListingForOtherCurrency(registry, marketCode);

View file

@ -37,8 +37,8 @@ public class SpotOvernightOrderService {
public void process(Registry registry) { public void process(Registry registry) {
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
Market market = imdgQueryService.getSwapMarket(); Market market = imdgQueryService.getSpotMarket();
Listing listing = imdgQueryService.findSwapListing(registry, market.getCode()); Listing listing = imdgQueryService.findListing(registry, market.getCode());
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);

View file

@ -38,7 +38,7 @@ public class SwapOvernightOrderService {
String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId()); String orderCategory = imdgQueryService.resolveOrderCategory(registry.getCompanyId());
Market market = imdgQueryService.getSwapMarket(); Market market = imdgQueryService.getSwapMarket();
Listing listing = imdgQueryService.findSwapListing(registry, market.getCode()); Listing listing = imdgQueryService.findListing(registry, market.getCode());
RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry); RiskParameter riskParameter = imdgQueryService.findRiskParameter(registry);
CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P"); CounterpartyInfo categoryP = imdgQueryService.getCompanyByClearingCategory("P");
CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC); CounterpartyInfo clcc = imdgQueryService.getCompanyByRole(CompanyRole.CLCC);

View file

@ -0,0 +1,20 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum OrderAffil implements IEnumKey {
PLBL("PLBL"),
;
private final String key;
OrderAffil(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}

View file

@ -0,0 +1,20 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum SettleCode implements IEnumKey {
T0("T0"),
T1("T1")
;
private final String key;
SettleCode(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}