etreschenkov 2026-03-30 12:01:31 +03:00
parent a122186b56
commit 46afedede1
10 changed files with 247 additions and 8 deletions

View file

@ -1439,6 +1439,8 @@
<!-- </post>-->
<post destination="GVTF" group="Общее" name="Проведение сверки по регистрам AMAT и AMAF">
</post>
<post destination="LORT" group="Обмен с интеграционными модулями" name="Загрузка курсов валют">
</post>
</actions>
</launcher>
<session name="Клиринговые сессии" destination="sessions" historyDestination="history" class="ru.clearing.classes.statics.data.misc.Session" logUpdates="true" table="session">

View file

@ -265,14 +265,6 @@ INSERT INTO COUNTRY_CODE_DICTIONARY(ID, CODE, NAME) values (897, 'DNR', 'ДНР'
INSERT INTO COUNTRY_CODE_DICTIONARY(ID, CODE, NAME) values (898, 'LNR', 'ЛНР') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO COUNTRY_CODE_DICTIONARY(ID, CODE, NAME) values (998, '998', 'МЕЖДУНАРОДНАЯ ОРГАНИЗАЦИЯ') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (1, 'MKR', 'Секция Денежного рынка МКР') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (2, 'FOND', 'Фондовая секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (3, 'CURR', 'Валютная секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (4, 'MULT', 'Единая') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO USER_ROLE_DICTIONARY(ID, CODE, NAME) values (1, 'ADMN', 'Администратор Клиринга МКР') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO USER_ROLE_DICTIONARY(ID, CODE, NAME) values (2, 'SPVS', 'Супервайзер Клиринга МКР') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
@ -750,6 +742,7 @@ INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (33, 'GREC', 'Формиро
INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (34, 'CX84', 'Формирование отчета CCX84') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (35, 'GVTF', 'Проведение сверки по регистрам AMAT и AMAF') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (36, 'LORT', 'Загрузка курсов валют') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO TASK_STATUS_DICTIONARY(ID, CODE, NAME) values (1, 'ACTV', 'Активна') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;

View file

@ -0,0 +1,16 @@
-- DB version: 3.22
-- SECTION_DICTIONARY LCC version: 3.22.0.0
/* Dictionaries */
/* Business objects */
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (1, 'MKR', 'Секция Валютного рынка') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (2, 'FOND', 'Фондовая секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (3, 'CURR', 'Валютная секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (4, 'MULT', 'Единая') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;

View file

@ -0,0 +1,16 @@
-- DB version: 3.22
-- SECTION_DICTIONARY LCC version: 3.22.0.0
/* Dictionaries */
/* Business objects */
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (1, 'MKR', 'Секция Денежного и Валютного рынков') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (2, 'FOND', 'Фондовая секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (3, 'CURR', 'Валютная секция') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO SECTION_DICTIONARY(ID, CODE, NAME) values (4, 'MULT', 'Единая') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;

View file

@ -12,6 +12,7 @@ public enum OutboundRequestType implements IEnumKey {
REPORT_KS_TMP("REPORT_KS_TMP"),
REPORT_KS_FINAL("REPORT_KS_FINAL"),
MEMBER_RESPONSE_TKR("MEMBER_RESPONSE_TKR"),
CURRENCY_RATE("CURRENCY_RATE"),
;
private final String key;

View file

@ -32,6 +32,7 @@ import ru.spcex.clearing.gatewayapi.controller.inbound.request.operations.SentAs
import ru.spcex.clearing.gatewayapi.controller.outbound.request.OutboundRequest;
import ru.spcex.clearing.gatewayapi.controller.outbound.response.SuccessResponse;
import ru.spcex.clearing.gatewayapi.enums.OutboundRequestType;
import ru.spcex.clearing.gatewayapi.service.builders.ContentBuilder;
import ru.spcex.clearing.gatewayapi.service.builders.GatewayResultBuilder;
import ru.spcex.clearing.gatewayapi.service.builders.OutboundRequestBuilder;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -97,6 +98,9 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
callback(GatewayTaskRequest.class)
.setConsumer(this::requestOnDemandSecurity)
.forDestination(Task.loadIssue_LOSC.topic(), callbacks::put);
callback(GatewayTaskRequest.class)
.setConsumer(this::requestOn)
.forDestination(Task.LORT.topic(), callbacks::put);
callback(LimExportedRequest.class)
.setConsumer(this::requestOnLimit)
.forDestination(Consts.LIM_EXPORTED, callbacks::put);
@ -191,6 +195,27 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
log.debug("LOSC task 4/4 complete (CURR section)");
}
public void requestOn(BaseRequest<GatewayTaskRequest> userRequest) {
OutboundRequest settleRateReq = OutboundRequestBuilder.builder()
.type(OutboundRequestType.CURRENCY_RATE.getKey())
.content(ContentBuilder.builder().settleRateBuild())
.clearingSystem(clearingSystemValue)
.build();
OutboundRequest cbRateReq = OutboundRequestBuilder.builder()
.type(OutboundRequestType.CURRENCY_RATE.getKey())
.content(ContentBuilder.builder().cbRateBuild())
.clearingSystem(clearingSystemValue)
.build();
outboundRequestByUuid.put(settleRateReq.getId(), settleRateReq);
outboundRequestByUuid.put(cbRateReq.getId(), cbRateReq);
log.debug("LORT task 1/2 complete (SETTLE_RATE)");
sendRequest(settleRateReq);
log.debug("LORT task 2/2 complete (CB_RATE)");
sendRequest(cbRateReq);
}
public void requestOnAsset(BaseRequest<AssetOperationListRequest> request) {
Long requestId = request.getId();
Collection<AssetOperationRequest> assetOperations = request.getRequestPayload().getAssetOperationRequests();

View file

@ -0,0 +1,33 @@
package ru.spcex.clearing.gatewayapi.service.builders;
import java.util.HashMap;
import java.util.Map;
public class ContentBuilder {
private ContentBuilder(){}
public static ContentBuilder builder(){
return new ContentBuilder();
}
public Map<String, Object> settleRateBuild() {
return new HashMap<>() {{
put("sender_organization_code", "SPVB");
put("sender_subsystem_code", "KS");
put("recipient_organization_code", "SPVB");
put("sender_rate_type_code", "SETTLE_RATE");
put("recipient_rate_type_code", "NCC_RATE");
}};
}
public Map<String, Object> cbRateBuild() {
return new HashMap<>() {{
put("sender_organization_code", "SPVB");
put("sender_subsystem_code", "KS");
put("recipient_organization_code", "SPVB");
put("sender_rate_type_code", "CB_RATE");
put("recipient_rate_type_code", "CBR_RATE");
}};
}
}

View file

@ -0,0 +1,43 @@
package ru.spcex.clearing.securities.service.facade;
import java.math.BigDecimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.misc.SCrossRate;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateRequest;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
@Service
public class SCrossRateFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final SecuritySelector<Security> securitySelector;
private final ImdgProvider imdgProvider;
private final ImdgId idGenerator;
private final Imdg<SCrossRate> sCrossRateImdg;
public SCrossRateFacade(SecuritySelector<Security> securitySelector, ImdgProvider imdgProvider) {
this.securitySelector = securitySelector;
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.sCrossRateImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SCrossRate, SCrossRate.class);
}
public Listing newSCrossRate(SCrossRateRequest req) {
SCrossRate sCrossRate = new SCrossRate();
sCrossRate.setDate(req.getDate());
sCrossRate.setCurrency(req.getBaseCurrencyLetterCode());
sCrossRate.setUnitRate(req.getRate());
sCrossRate.setFaceValue(new BigDecimal(req.getBaseCurrencyUnit()));
sCrossRate.setRate(req.getPrice());
return null;
}
}

View file

@ -62,6 +62,7 @@ public enum Task implements IEnumKey {
makeFiles_MTCR("MTCR"), // Формирование файлов с МТКР
CX84("CX84"), // Формирование отчета CCX84
GVTF("GVTF"), // Проведение сверки по регистрам AMAT и AMAF
LORT("LORT"), // Загрузка курсов валют
;
private final String key;

View file

@ -0,0 +1,109 @@
package ru.spcex.clearing.platform.messaging.domain.cud.securitites;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class SCrossRateRequest {
@JsonProperty
private String type;
@JsonProperty
private LocalDate date;
@JsonProperty
private String baseCurrencyLetterCode;
@JsonProperty
private String associatedCurrencyLetterCode;
@JsonProperty
private BigDecimal rate;
@JsonProperty
private Integer priceAccuracy;
@JsonProperty
private Integer baseCurrencyUnit;
@JsonProperty
private BigDecimal price;
@JsonProperty
private LocalDateTime updateDateTime;
@JsonProperty
private LocalDateTime sourceDateTime;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public String getBaseCurrencyLetterCode() {
return baseCurrencyLetterCode;
}
public void setBaseCurrencyLetterCode(String baseCurrencyLetterCode) {
this.baseCurrencyLetterCode = baseCurrencyLetterCode;
}
public String getAssociatedCurrencyLetterCode() {
return associatedCurrencyLetterCode;
}
public void setAssociatedCurrencyLetterCode(String associatedCurrencyLetterCode) {
this.associatedCurrencyLetterCode = associatedCurrencyLetterCode;
}
public BigDecimal getRate() {
return rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
public Integer getPriceAccuracy() {
return priceAccuracy;
}
public void setPriceAccuracy(Integer priceAccuracy) {
this.priceAccuracy = priceAccuracy;
}
public Integer getBaseCurrencyUnit() {
return baseCurrencyUnit;
}
public void setBaseCurrencyUnit(Integer baseCurrencyUnit) {
this.baseCurrencyUnit = baseCurrencyUnit;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public LocalDateTime getUpdateDateTime() {
return updateDateTime;
}
public void setUpdateDateTime(LocalDateTime updateDateTime) {
this.updateDateTime = updateDateTime;
}
public LocalDateTime getSourceDateTime() {
return sourceDateTime;
}
public void setSourceDateTime(LocalDateTime sourceDateTime) {
this.sourceDateTime = sourceDateTime;
}
}