This commit is contained in:
parent
8c4f3f4769
commit
db2079821c
13 changed files with 374 additions and 20 deletions
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue