From 6fdfcb041fb441e45db6556f0a82e3153e7e2163 Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Wed, 17 May 2023 12:05:26 +0300 Subject: [PATCH 1/3] http://jira.mfd.msk:8088/browse/CLS-290 stage 4 --- .../clearing/session/stage/TaskType.java | 4 + .../stage/impl/InclusionObligations.java | 80 +++++++++++++++++++ .../stage/task/InclusionToPoolPayload.java | 22 +++++ 3 files changed, 106 insertions(+) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InclusionObligations.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/InclusionToPoolPayload.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java index 86b6b740d..c1fb4a584 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java @@ -11,5 +11,9 @@ public enum TaskType { * step 1 */ DealsPrepare, + /** + * step 4 + */ + InclusionToPool, } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InclusionObligations.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InclusionObligations.java new file mode 100644 index 000000000..4a61cf6c9 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InclusionObligations.java @@ -0,0 +1,80 @@ +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.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +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.task.InclusionToPoolPayload; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Service +public class InclusionObligations implements ISessionStage { + private final Logger log = LoggerFactory.getLogger(getClass()); + //todo remove (set all in single method setImdg(provider -> setImdg1();setIdGenerator();...) + private ImdgProvider imdgProvider; + private ImdgId idGenerator; + private Imdg registryImdg; + private KafkaSender kafkaSender; + + @Autowired + public InclusionObligations(ImdgProvider imdgProvider) { + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + } + + @Override + public StageResult submit(Task task) { + InclusionToPoolPayload payload = (InclusionToPoolPayload) task.getData(); + switch (task.getTaskType()) { + case InclusionToPool -> { + return inclusionToPool(payload.getSessionType(), payload.getCounterPartyId()); + } + default -> { + throw new IllegalStateException("Unknown task type: " + task.getTaskType()); + } + } + } + + + private StageResult inclusionToPool(String sessionType, Long counterPartyId) { + String sqlCondition = String.format("registryCode like '%s' and " + + "registryStatus = '%s' and " + + "settlementDate = '%s' and " + + "sessionType = '%s'", + "[O/T][S/M][*][T]", + "PROC", + LocalDate.now(), + sessionType); + + Collection obligations = registryImdg.getCollectionObjectsBySQL(sqlCondition); + Map> registryByGroupId = obligations.stream(). + filter(registry -> registry.getCompanyId().equals(counterPartyId)). + collect(Collectors.groupingBy(Registry::getGroupId)); + + for (Map.Entry> entrySet : registryByGroupId.entrySet()) { + log.debug("Processing set of registry with groupId: {}", entrySet.getKey()); + for (Registry registry : entrySet.getValue()){ + registry.setRegistryStatus("POOL"); + registryImdg.update(registry); + } + } + + return new StageResult(null, true); + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/InclusionToPoolPayload.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/InclusionToPoolPayload.java new file mode 100644 index 000000000..41bba14c6 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/InclusionToPoolPayload.java @@ -0,0 +1,22 @@ +package ru.spcex.clearing.session.stage.task; + +public class InclusionToPoolPayload { + private String sessionType; + private Long counterPartyId; + + public String getSessionType() { + return sessionType; + } + + public void setSessionType(String sessionType) { + this.sessionType = sessionType; + } + + public Long getCounterPartyId() { + return counterPartyId; + } + + public void setCounterPartyId(Long counterPartyId) { + this.counterPartyId = counterPartyId; + } +} From 4e37cf7757680c11aa5a6d63ac5556c5a6efc335 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 17 May 2023 14:45:34 +0300 Subject: [PATCH 2/3] http://jira.mfd.msk:8088/browse/CLS-293 DDL meta 4.2 --- .../MoneyMarketSecurityController.java | 2 +- .../src/main/resources/meta/meta.json | 130 ++++++++++++++++-- .../src/main/resources/meta/meta.xml | 38 ++++- .../MoneyMarketSecurityControllerTest.java | 2 +- .../backend-api/src/test/resources/meta.json | 130 ++++++++++++++++-- .../MoneyMarketSecurity.java | 15 +- .../MoneyMarketSecurityHistory.java | 2 +- .../security/TradedMoneyMarketSecurity.java | 42 ++++++ .../db-scripts/src/main/resources/db/DDL.sql | 21 ++- .../AccountBalanceHistoryMapStore.java | 75 ---------- .../MoneyMarketSecurityHistoryMapStore.java | 14 +- .../MoneyMarketSecurityMapStore.java | 12 +- .../TradedMoneyMarketSecurityMapStore.java | 57 ++++++++ .../imdg/services/UpdateMapService.java | 9 +- .../structure/RunnableMapNamesForTesting.java | 2 + .../securities/component/ListingBuilder.java | 2 +- .../cud/MoneyMarketSecurityService.java | 2 +- .../rule/MmsDeleteValidationRule.java | 2 +- .../rule/MmsUpdateValidationRule.java | 2 +- .../service/AbstractServiceTest.java | 2 +- .../service/MoneyMarketSecurityFactory.java | 2 +- .../MoneyMarketSecurityServiceTest.java | 2 +- .../clearing/imdg/IMDGDistributedNames.java | 3 +- 23 files changed, 433 insertions(+), 135 deletions(-) rename clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/{misc => security}/MoneyMarketSecurity.java (85%) rename clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/{misc => security}/MoneyMarketSecurityHistory.java (88%) create mode 100644 clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/TradedMoneyMarketSecurity.java delete mode 100644 clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/AccountBalanceHistoryMapStore.java create mode 100644 clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/TradedMoneyMarketSecurityMapStore.java diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityController.java index 98c321858..64a26b49a 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityController.java @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController; import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityNewAction; diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.json b/clearing-parent/backend-api/src/main/resources/meta/meta.json index b3bf979e0..a4d163256 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.json +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.json @@ -1,6 +1,6 @@ { - "version": "3.5.0.21", + "version": "3.5.0.22", "enums": { @@ -2411,7 +2411,7 @@ "destination": "securities/money-securities", - "class": "ru.clearing.classes.statics.data.misc.MoneyMarketSecurity", + "class": "ru.clearing.classes.statics.data.security.MoneyMarketSecurity", "logUpdates": "true", @@ -2453,6 +2453,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование","searchable": true,"sortable": true,"visible": true,"extends": "security" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска","visible": true + } , {"code": "securitySymbol", "type": 2,"length": 255,"name": "Код инструмента","shortname": "Код","searchable": true,"sortable": true,"visible": true,"extends": "security" @@ -2509,6 +2513,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска" + } , {"code": "lotSize", "type": 11,"name": "Размер лота","shortname": "Лот","required": true @@ -2586,6 +2594,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска" + } , {"code": "lotSize", "type": 11,"name": "Размер лота","shortname": "Лот" @@ -2654,6 +2666,36 @@ ] } ] + } + , + "tradedMoneyMarketSecurity": { + + "name": "Инструменты денежного рынка, учавствующие в сделках", + + "destination": "securities/traded-money-securities", + + "class": "ru.clearing.classes.statics.data.misc.TradedMoneyMarketSecurity", + + "table": "traded_money_market_security", + + "fields": [ + {"code": "securityId", + "type": 1,"dbname": "Идентификатор инструмента","name": "Наименование инструмента","shortname": "Инструмент","searchable": true,"sortable": true,"link": "security","linkCode": "shortName" + } + , + {"code": "shortName", + "type": 2,"length": 255,"name": "Краткое наименование инструмента","shortname": "Краткое наименование","searchable": true,"sortable": true,"visible": true,"extends": "security" + } + , + {"code": "securityCode", + "type": 2,"length": 255,"name": "Полный код инструмента со сроком","shortname": "Код инструмента","searchable": true,"sortable": true,"visible": true + } + , + {"code": "id", + "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true + } + ] + } , "equitySecurity": { @@ -3783,7 +3825,38 @@ "field": "updated","type": 4,"name": "Дата и время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true } ] - + ,"actions":[ + {"method":"post", + + "name": "Досрочное изъятие части денежных средств по депозиту МКР", + + "destination": "registries/splitDeposit", + + "confirmation": "contract,outboundAmount,refundDate", + + "fields": [ + {"code": "contract", + "type": 2,"length": 255,"name": "Договор","shortname": "Договор","required": true + } + , + {"code": "outboundAmount", + "type": 10,"name": "Сумма изъятия","shortname": "Сумма","required": true + } + , + {"code": "refundDate", + "type": 6,"name": "Дата возврата","shortname": "Дата","required": true + } + , + {"code": "comment", + "type": 2,"length": 255,"name": "Основание для вывода","shortname": "Основание" + } + , + {"code": "direction", + "type": 1,"name": "Направление","shortname": "Направление","link": "inOutDirection" + } + ] + } + ] } , "account": { @@ -4046,6 +4119,10 @@ {"code": "companyId", "type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName" } + , + {"code": "status", + "type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "serviceStatus","extends": "account" + } , {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true @@ -4966,7 +5043,11 @@ "name": "Формирование отчетности", - "fields": [] + "fields": [ + {"code": "sessionId", + "type": 1,"name": "Клиринговая сессия","shortname": "Сессия","link": "session" + } + ] } , {"method":"post", @@ -4975,18 +5056,18 @@ "group": "Обмен с Торговой системой", - "name": "Выгрузка в торговую систему остатков секции МКР", + "name": "Выгрузка в торговую систему остатков по деньгам", "fields": [] } , {"method":"post", - "destination": "LIMF", + "destination": "LIMS", "group": "Обмен с Торговой системой", - "name": "Выгрузка в торговую систему остатков Фондовой секции", + "name": "Выгрузка в торговую систему остатков по бумагам", "fields": [] } @@ -6465,7 +6546,40 @@ "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session" } ] - + ,"actions":[ + {"method":"post", + + "name": "Вывод денежных средств c регистра инициатора", + + "destination": "payment-instructions/clearing-outbound", + + "fields": [ + {"code": "senderId", + "type": 1,"name": "Участник отправитель","shortname": "Отправитель","link": "company","required": true + } + , + {"code": "addresseeId", + "type": 1,"name": "Участник получатель","shortname": "Получатель","link": "company","required": true + } + , + {"code": "paymentPurpose", + "type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение","searchable": true,"sortable": true,"visible": true + } + , + {"code": "creditLeg_amount", + "type": 10,"name": "Сумма отправителя","shortname": "Сумма отправителя","searchable": true,"sortable": true,"visible": true + } + , + {"code": "creditLeg_accountId", + "type": 1,"name": "Наименование счета отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true + } + , + {"code": "debitLeg_accountId", + "type": 1,"name": "Наименование счета получателя","shortname": "Счет получателя","searchable": true,"sortable": true,"link": "account","ignore": true + } + ] + } + ] } , "notification": { diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index a3cf956b4..6273184e6 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -1,6 +1,6 @@ - + @@ -557,7 +557,7 @@ - + @@ -567,6 +567,7 @@ + @@ -581,6 +582,7 @@ + @@ -600,6 +602,7 @@ + @@ -619,6 +622,12 @@ + + + + + + @@ -887,6 +896,15 @@ + + + + + + + + + @@ -950,6 +968,7 @@ + @@ -1160,10 +1179,11 @@ + - + - + @@ -1505,6 +1525,16 @@ + + + + + + + + + + diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityControllerTest.java index c06d659e1..f79f0469e 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/MoneyMarketSecurityControllerTest.java @@ -1,7 +1,7 @@ package ru.spcex.clearing.backendapi.controller.queue.securities; import org.junit.jupiter.api.Test; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest; import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityNewAction; diff --git a/clearing-parent/backend-api/src/test/resources/meta.json b/clearing-parent/backend-api/src/test/resources/meta.json index b3bf979e0..a4d163256 100644 --- a/clearing-parent/backend-api/src/test/resources/meta.json +++ b/clearing-parent/backend-api/src/test/resources/meta.json @@ -1,6 +1,6 @@ { - "version": "3.5.0.21", + "version": "3.5.0.22", "enums": { @@ -2411,7 +2411,7 @@ "destination": "securities/money-securities", - "class": "ru.clearing.classes.statics.data.misc.MoneyMarketSecurity", + "class": "ru.clearing.classes.statics.data.security.MoneyMarketSecurity", "logUpdates": "true", @@ -2453,6 +2453,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование","searchable": true,"sortable": true,"visible": true,"extends": "security" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска","visible": true + } , {"code": "securitySymbol", "type": 2,"length": 255,"name": "Код инструмента","shortname": "Код","searchable": true,"sortable": true,"visible": true,"extends": "security" @@ -2509,6 +2513,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска" + } , {"code": "lotSize", "type": 11,"name": "Размер лота","shortname": "Лот","required": true @@ -2586,6 +2594,10 @@ {"code": "fullName", "type": 2,"length": 255,"name": "Полное наименование инструмента","shortname": "Наименование" } + , + {"code": "convention", + "type": 2,"length": 255,"name": "Нотация наименования инструмента","shortname": "Маска" + } , {"code": "lotSize", "type": 11,"name": "Размер лота","shortname": "Лот" @@ -2654,6 +2666,36 @@ ] } ] + } + , + "tradedMoneyMarketSecurity": { + + "name": "Инструменты денежного рынка, учавствующие в сделках", + + "destination": "securities/traded-money-securities", + + "class": "ru.clearing.classes.statics.data.misc.TradedMoneyMarketSecurity", + + "table": "traded_money_market_security", + + "fields": [ + {"code": "securityId", + "type": 1,"dbname": "Идентификатор инструмента","name": "Наименование инструмента","shortname": "Инструмент","searchable": true,"sortable": true,"link": "security","linkCode": "shortName" + } + , + {"code": "shortName", + "type": 2,"length": 255,"name": "Краткое наименование инструмента","shortname": "Краткое наименование","searchable": true,"sortable": true,"visible": true,"extends": "security" + } + , + {"code": "securityCode", + "type": 2,"length": 255,"name": "Полный код инструмента со сроком","shortname": "Код инструмента","searchable": true,"sortable": true,"visible": true + } + , + {"code": "id", + "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true + } + ] + } , "equitySecurity": { @@ -3783,7 +3825,38 @@ "field": "updated","type": 4,"name": "Дата и время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true } ] - + ,"actions":[ + {"method":"post", + + "name": "Досрочное изъятие части денежных средств по депозиту МКР", + + "destination": "registries/splitDeposit", + + "confirmation": "contract,outboundAmount,refundDate", + + "fields": [ + {"code": "contract", + "type": 2,"length": 255,"name": "Договор","shortname": "Договор","required": true + } + , + {"code": "outboundAmount", + "type": 10,"name": "Сумма изъятия","shortname": "Сумма","required": true + } + , + {"code": "refundDate", + "type": 6,"name": "Дата возврата","shortname": "Дата","required": true + } + , + {"code": "comment", + "type": 2,"length": 255,"name": "Основание для вывода","shortname": "Основание" + } + , + {"code": "direction", + "type": 1,"name": "Направление","shortname": "Направление","link": "inOutDirection" + } + ] + } + ] } , "account": { @@ -4046,6 +4119,10 @@ {"code": "companyId", "type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName" } + , + {"code": "status", + "type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "serviceStatus","extends": "account" + } , {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true @@ -4966,7 +5043,11 @@ "name": "Формирование отчетности", - "fields": [] + "fields": [ + {"code": "sessionId", + "type": 1,"name": "Клиринговая сессия","shortname": "Сессия","link": "session" + } + ] } , {"method":"post", @@ -4975,18 +5056,18 @@ "group": "Обмен с Торговой системой", - "name": "Выгрузка в торговую систему остатков секции МКР", + "name": "Выгрузка в торговую систему остатков по деньгам", "fields": [] } , {"method":"post", - "destination": "LIMF", + "destination": "LIMS", "group": "Обмен с Торговой системой", - "name": "Выгрузка в торговую систему остатков Фондовой секции", + "name": "Выгрузка в торговую систему остатков по бумагам", "fields": [] } @@ -6465,7 +6546,40 @@ "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session" } ] - + ,"actions":[ + {"method":"post", + + "name": "Вывод денежных средств c регистра инициатора", + + "destination": "payment-instructions/clearing-outbound", + + "fields": [ + {"code": "senderId", + "type": 1,"name": "Участник отправитель","shortname": "Отправитель","link": "company","required": true + } + , + {"code": "addresseeId", + "type": 1,"name": "Участник получатель","shortname": "Получатель","link": "company","required": true + } + , + {"code": "paymentPurpose", + "type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение","searchable": true,"sortable": true,"visible": true + } + , + {"code": "creditLeg_amount", + "type": 10,"name": "Сумма отправителя","shortname": "Сумма отправителя","searchable": true,"sortable": true,"visible": true + } + , + {"code": "creditLeg_accountId", + "type": 1,"name": "Наименование счета отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true + } + , + {"code": "debitLeg_accountId", + "type": 1,"name": "Наименование счета получателя","shortname": "Счет получателя","searchable": true,"sortable": true,"link": "account","ignore": true + } + ] + } + ] } , "notification": { diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurity.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurity.java similarity index 85% rename from clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurity.java rename to clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurity.java index d4e5741ef..7e91af78f 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurity.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurity.java @@ -1,4 +1,4 @@ -package ru.clearing.classes.statics.data.misc; +package ru.clearing.classes.statics.data.security; import ru.clearing.classes.statics.data.security.Security; @@ -11,12 +11,13 @@ import java.time.LocalDate; * DB table: MONEY_MARKET_SECURITY **/ public class MoneyMarketSecurity extends Security { - private Long securityId;// (linked to security) + private Long securityId; private String description; private LocalDate startDate; private LocalDate endDate; private BigDecimal nominalValue; - private String nominalCurrency; // (linked to currencyCode) + private String nominalCurrency; + private String convention; private String termType; private BigDecimal lotSize; @@ -68,6 +69,14 @@ public class MoneyMarketSecurity extends Security { this.nominalCurrency = nominalCurrency; } + public String getConvention() { + return convention; + } + + public void setConvention(String convention) { + this.convention = convention; + } + public String getTermType() { return termType; } diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurityHistory.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurityHistory.java similarity index 88% rename from clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurityHistory.java rename to clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurityHistory.java index f24b02f70..98474ad7c 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/misc/MoneyMarketSecurityHistory.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/MoneyMarketSecurityHistory.java @@ -1,4 +1,4 @@ -package ru.clearing.classes.statics.data.misc; +package ru.clearing.classes.statics.data.security; import ru.clearing.classes.ConstSerializable; import ru.clearing.classes.objects.BusinessEvent; diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/TradedMoneyMarketSecurity.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/TradedMoneyMarketSecurity.java new file mode 100644 index 000000000..e412e01c8 --- /dev/null +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/TradedMoneyMarketSecurity.java @@ -0,0 +1,42 @@ +package ru.clearing.classes.statics.data.security; + +import ru.clearing.classes.ConstSerializable; +import ru.spcex.platform.classes.base.SpcexObjectBase; + +/** + * Инструменты денежного рынка, учавствующие в сделках + *

+ * DB table: TRADED_MONEY_MARKET_SECURITY + **/ +public class TradedMoneyMarketSecurity extends SpcexObjectBase { + private static final long serialVersionUID = ConstSerializable.serialVersionUID; + + private Long securityId; + private String shortName; + private String securityCode; + + public Long getSecurityId() { + return securityId; + } + + public void setSecurityId(Long value) { + this.securityId = value; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String value) { + this.shortName = value; + } + + public String getSecurityCode() { + return securityCode; + } + + public void setSecurityCode(String value) { + this.securityCode = value; + } + +} \ No newline at end of file diff --git a/clearing-parent/db-scripts/src/main/resources/db/DDL.sql b/clearing-parent/db-scripts/src/main/resources/db/DDL.sql index fc80f1e1c..cb3537967 100644 --- a/clearing-parent/db-scripts/src/main/resources/db/DDL.sql +++ b/clearing-parent/db-scripts/src/main/resources/db/DDL.sql @@ -1,4 +1,4 @@ --- DB version: 3.5.0.21 +-- DB version: 3.5.0.22 /* Dictionaries */ -- allowed - Справочник признаков допустимости использования объектов @@ -1164,7 +1164,7 @@ COMMENT ON COLUMN CURRENCY_HISTORY.ID IS 'Идентификатор запис -- moneyMarketSecurity - Инструменты Денежного рынка DROP TABLE IF EXISTS MONEY_MARKET_SECURITY; -CREATE TABLE MONEY_MARKET_SECURITY(SECURITY_ID bigint, DESCRIPTION varchar(255), START_DATE date, END_DATE date, NOMINAL_VALUE numeric(72,18), NOMINAL_CURRENCY varchar(4), TERM_TYPE varchar(4), ID bigint PRIMARY KEY); +CREATE TABLE MONEY_MARKET_SECURITY(SECURITY_ID bigint, DESCRIPTION varchar(255), START_DATE date, END_DATE date, NOMINAL_VALUE numeric(72,18), NOMINAL_CURRENCY varchar(4), CONVENTION varchar(255), TERM_TYPE varchar(4), ID bigint PRIMARY KEY); COMMENT ON TABLE MONEY_MARKET_SECURITY IS 'Инструменты Денежного рынка'; COMMENT ON COLUMN MONEY_MARKET_SECURITY.SECURITY_ID IS 'Идентификатор инструмента (linked to security)'; @@ -1179,6 +1179,8 @@ COMMENT ON COLUMN MONEY_MARKET_SECURITY.NOMINAL_VALUE IS 'Номинал'; COMMENT ON COLUMN MONEY_MARKET_SECURITY.NOMINAL_CURRENCY IS 'Код валюты номинала (linked to currencyCode)'; +COMMENT ON COLUMN MONEY_MARKET_SECURITY.CONVENTION IS 'Нотация наименования инструмента'; + COMMENT ON COLUMN MONEY_MARKET_SECURITY.TERM_TYPE IS 'Код вида инструмента (linked to termType)'; COMMENT ON COLUMN MONEY_MARKET_SECURITY.ID IS 'Идентификатор записи'; @@ -1186,7 +1188,7 @@ COMMENT ON COLUMN MONEY_MARKET_SECURITY.ID IS 'Идентификатор зап -- History log of moneyMarketSecurity - Инструменты Денежного рынка DROP TABLE IF EXISTS MONEY_MARKET_SECURITY_HISTORY; -CREATE TABLE MONEY_MARKET_SECURITY_HISTORY(MONEY_MARKET_SECURITY_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), SECURITY_ID bigint, DESCRIPTION varchar(255), START_DATE date, END_DATE date, NOMINAL_VALUE numeric(72,18), NOMINAL_CURRENCY varchar(4), TERM_TYPE varchar(4), ID bigint PRIMARY KEY); +CREATE TABLE MONEY_MARKET_SECURITY_HISTORY(MONEY_MARKET_SECURITY_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), SECURITY_ID bigint, DESCRIPTION varchar(255), START_DATE date, END_DATE date, NOMINAL_VALUE numeric(72,18), NOMINAL_CURRENCY varchar(4), CONVENTION varchar(255), TERM_TYPE varchar(4), ID bigint PRIMARY KEY); COMMENT ON TABLE MONEY_MARKET_SECURITY_HISTORY IS 'История изменений таблицы moneyMarketSecurity'; COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.MONEY_MARKET_SECURITY_ID IS 'Идентификатор записи в таблице MONEY_MARKET_SECURITY'; COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.EVENT_TIME IS 'Дата и время изменения'; @@ -1205,10 +1207,23 @@ COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.NOMINAL_VALUE IS 'Номинал COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.NOMINAL_CURRENCY IS 'Код валюты номинала (linked to currencyCode)'; +COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.CONVENTION IS 'Нотация наименования инструмента'; + COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.TERM_TYPE IS 'Код вида инструмента (linked to termType)'; COMMENT ON COLUMN MONEY_MARKET_SECURITY_HISTORY.ID IS 'Идентификатор записи'; +-- tradedMoneyMarketSecurity - Инструменты денежного рынка, учавствующие в сделках +DROP TABLE IF EXISTS TRADED_MONEY_MARKET_SECURITY; +CREATE TABLE TRADED_MONEY_MARKET_SECURITY(SECURITY_ID bigint, SECURITY_CODE varchar(255), ID bigint PRIMARY KEY); +COMMENT ON TABLE TRADED_MONEY_MARKET_SECURITY IS 'Инструменты денежного рынка, учавствующие в сделках'; + +COMMENT ON COLUMN TRADED_MONEY_MARKET_SECURITY.SECURITY_ID IS 'Идентификатор инструмента (linked to security)'; + +COMMENT ON COLUMN TRADED_MONEY_MARKET_SECURITY.SECURITY_CODE IS 'Полный код инструмента со сроком'; + +COMMENT ON COLUMN TRADED_MONEY_MARKET_SECURITY.ID IS 'Идентификатор записи'; + -- equitySecurity - Акции DROP TABLE IF EXISTS EQUITY_SECURITY; CREATE TABLE EQUITY_SECURITY(SECURITY_ID bigint, SHARE_TYPE varchar(4), ID bigint PRIMARY KEY); diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/AccountBalanceHistoryMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/AccountBalanceHistoryMapStore.java deleted file mode 100644 index f120be004..000000000 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/AccountBalanceHistoryMapStore.java +++ /dev/null @@ -1,75 +0,0 @@ -package ru.spcex.clearing.imdg.businessevent; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Component; -import ru.clearing.classes.statics.data.account.AccountBalance; -import ru.clearing.classes.statics.data.account.AccountBalanceHistory; -import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.imdg.base.TemplateEventMapStore; -import ru.spcex.platform.utils.time.TimeUtil; - -@Deprecated -//@Component -public class AccountBalanceHistoryMapStore extends TemplateEventMapStore { - - public AccountBalanceHistoryMapStore(JdbcTemplate jdbcTemplate) { - super(jdbcTemplate); - } - - @Override - public String getMapName() { - return IMDGDistributedNames.Map_AccountBalanceHistory; - } - - @Override - public String getTableName() { - return "ACCOUNT_BALANCE_HISTORY"; - } - - @Override - public String[] getFields() { - return new String[]{"ID", "EVENT_TIME", "EVENT_TYPE", "EVENT_USER_ID", - "ACCOUNT_BALANCE_ID", "COMPANY_ID", "CREATED_AT", "UPDATED_AT", "ACCOUNT_ID", "ACCOUNT_TYPE", - "ACCOUNT", "OPEN_BALANCE_AMOUNT", "START_BALANCE_AMOUNT", "CLOSE_BALANCE_AMOUNT", - "TRADE_BALANCE_AMOUNT", "FREE_BALANCE_AMOUNT", "CHANGE_BALANCE_AMOUNT", - "CREDIT_AMOUNT", "DEBIT_AMOUNT", "BALANCE_AMOUNT", "BALANCE_ACCOUNT_TYPE", - "CLEARING_DATE", "CURRENCY_CODE", "TRADING_CODE", "SHORT_NAME", "FULL_NAME" - }; - } - - @Override - public Object[] objectToField(AccountBalanceHistory updateLog) { - AccountBalance object = updateLog.getObject(); - Object[] args = new Object[]{ - updateLog.getId(), - TimeUtil.toDateFromInstant(updateLog.getEventTime()), - updateLog.getEventType(), - updateLog.getUserId(), - - object.getId(), - object.getCompanyId(), - TimeUtil.toDateFromInstant(object.getCreated()), - TimeUtil.toDateFromInstant(object.getUpdated()), - object.getAccountId(), - object.getAccountType(), - object.getAccount(), - object.getOpenBalanceAmount(), - object.getStartBalanceAmount(), - object.getCloseBalanceAmount(), - object.getTradeBalanceAmount(), - object.getFreeBalanceAmount(), - object.getChangeBalanceAmount(), - object.getCreditAmount(), - object.getDebitAmount(), - object.getBalanceAmount(), - object.getBalanceAccountType(), - TimeUtil.toDateFromLocalDate(object.getClearingDate()), - object.getCurrencyCode(), - object.getTradingCode(), - object.getShortName(), - object.getFullName() - }; - return args; - } - -} diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/MoneyMarketSecurityHistoryMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/MoneyMarketSecurityHistoryMapStore.java index 9d2cae9ad..bcba1991d 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/MoneyMarketSecurityHistoryMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessevent/MoneyMarketSecurityHistoryMapStore.java @@ -3,15 +3,10 @@ package ru.spcex.clearing.imdg.businessevent; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurityHistory; -import ru.spcex.clearing.imdg.base.TemplateEventMapStore; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurityHistory; import ru.spcex.platform.utils.time.TimeUtil; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - @Component public class MoneyMarketSecurityHistoryMapStore extends ASecurityHistoryMapStore { @@ -34,7 +29,7 @@ public class MoneyMarketSecurityHistoryMapStore extends ASecurityHistoryMapStore public String[] getFields() { return new String[]{ "ID", "EVENT_TIME", "EVENT_USER_ID", "EVENT_TYPE", - "MONEY_MARKET_SECURITY_ID", "SECURITY_ID", "DESCRIPTION", "START_DATE", "END_DATE", "NOMINAL_VALUE", "NOMINAL_CURRENCY", "TERM_TYPE"}; + "MONEY_MARKET_SECURITY_ID", "SECURITY_ID", "DESCRIPTION", "START_DATE", "END_DATE", "NOMINAL_VALUE", "NOMINAL_CURRENCY", "TERM_TYPE", "CONVENTION"}; } @@ -54,7 +49,8 @@ public class MoneyMarketSecurityHistoryMapStore extends ASecurityHistoryMapStore TimeUtil.toDateFromLocalDate(moneyMarketSecurity.getEndDate()), moneyMarketSecurity.getNominalValue(), moneyMarketSecurity.getNominalCurrency(), - moneyMarketSecurity.getTermType() + moneyMarketSecurity.getTermType(), + moneyMarketSecurity.getConvention() }; return args; } diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/MoneyMarketSecurityMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/MoneyMarketSecurityMapStore.java index 75651a2c5..d642126f6 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/MoneyMarketSecurityMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/MoneyMarketSecurityMapStore.java @@ -2,17 +2,13 @@ package ru.spcex.clearing.imdg.businessobject; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.imdg.base.TemplateMapStore; import ru.spcex.platform.utils.time.TimeUtil; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; @Component public class MoneyMarketSecurityMapStore extends ASecurityMapStore { @@ -41,7 +37,7 @@ public class MoneyMarketSecurityMapStore extends ASecurityMapStore { + + public TradedMoneyMarketSecurityMapStore(JdbcTemplate jdbcTemplate) { + super(jdbcTemplate); + } + + @Override + public String getMapName() { + return IMDGDistributedNames.Map_TradedMoneyMarketSecurity; + } + + @Override + public String getTableName() { + return "TRADED_MONEY_MARKET_SECURITY"; + } + + @Override + public String[] getFields() { + return new String[]{ + "SECURITY_ID", "SHORT_NAME", "SECURITY_CODE", "ID" + }; + } + + @Override + public TradedMoneyMarketSecurity objectReader(ResultSet resultSet) throws SQLException { + TradedMoneyMarketSecurity object = new TradedMoneyMarketSecurity(); + object.setSecurityId(resultSet.getObject("SECURITY_ID", Long.class)); + object.setShortName(resultSet.getObject("SHORT_NAME", String.class)); + object.setSecurityCode(resultSet.getObject("SECURITY_CODE", String.class)); + object.setId(resultSet.getObject("ID", Long.class)); + return object; + } + + @Override + public Object[] objectToField(TradedMoneyMarketSecurity object) { + Object[] args = new Object[]{ + object.getSecurityId(), + object.getShortName(), + object.getSecurityCode(), + object.getId() + }; + return args; + } + +} \ No newline at end of file diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/UpdateMapService.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/UpdateMapService.java index 6b3590754..19d300c15 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/UpdateMapService.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/UpdateMapService.java @@ -15,6 +15,8 @@ import ru.clearing.classes.statics.data.instrument.issue.*; import ru.clearing.classes.statics.data.misc.*; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.classes.statics.data.profile.ProfileDocumentHistory; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurityHistory; import ru.clearing.classes.statics.data.security.Security; import ru.clearing.classes.statics.data.security.SecurityHistory; import ru.clearing.classes.statics.data.user.User; @@ -61,12 +63,7 @@ public class UpdateMapService extends AbstractUpdateMapService { protected void entryModified(EntryEvent event, String eventType) { log.debug("{} {}", event, eventType); Object value = (EVENT_DELETE.equals(eventType) ? event.getOldValue() : event.getValue()); - if (value instanceof AccountBalance) { - AccountBalanceHistory accountBalanceHistory = new AccountBalanceHistory(); - createBusinessEvent(accountBalanceHistory, eventType); - accountBalanceHistory.setObject((AccountBalance) value); - hazelcastServerInstance.getMap(IMDGDistributedNames.Map_AccountBalanceHistory).put(accountBalanceHistory.getId(), accountBalanceHistory); - } else if (value instanceof Account) { + if (value instanceof Account) { AccountHistory accountHistory = new AccountHistory(); createBusinessEvent(accountHistory, eventType); accountHistory.setObject((Account) value); diff --git a/clearing-parent/imdg/src/test/java/ru/spcex/clearing/imdg/structure/RunnableMapNamesForTesting.java b/clearing-parent/imdg/src/test/java/ru/spcex/clearing/imdg/structure/RunnableMapNamesForTesting.java index 55572a080..5f02f1d24 100644 --- a/clearing-parent/imdg/src/test/java/ru/spcex/clearing/imdg/structure/RunnableMapNamesForTesting.java +++ b/clearing-parent/imdg/src/test/java/ru/spcex/clearing/imdg/structure/RunnableMapNamesForTesting.java @@ -23,6 +23,8 @@ import ru.clearing.classes.statics.data.profile.ProfileDocumentHistory; import ru.clearing.classes.statics.data.register.*; import ru.clearing.classes.statics.data.scheduler.*; import ru.clearing.classes.statics.data.sdf.*; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurityHistory; import ru.clearing.classes.statics.data.statement.Statement; import ru.clearing.classes.statics.data.user.*; import ru.clearing.platform.dictionary.*; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java index dba5c2768..cffaa31e3 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java @@ -3,7 +3,7 @@ package ru.spcex.clearing.securities.component; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index 285e0d3d4..3b37d72a7 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -8,7 +8,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsDeleteValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsDeleteValidationRule.java index bbf126857..71ca83735 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsDeleteValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsDeleteValidationRule.java @@ -1,6 +1,6 @@ package ru.spcex.clearing.securities.validation.rule; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.platform.enumeration.Status; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java index c2b681924..be9a064d0 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java @@ -1,6 +1,6 @@ package ru.spcex.clearing.securities.validation.rule; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.platform.enumeration.Status; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index 7de280a46..b7f895ea1 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -12,7 +12,7 @@ import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.securities.config.ErrorResolverConfig; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java index d90f48819..780630784 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java @@ -1,6 +1,6 @@ package ru.spcex.clearing.securities.service; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java index c9709e640..80f5141d0 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -4,7 +4,7 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java index 176213160..4e656358b 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java @@ -14,7 +14,6 @@ public final class IMDGDistributedNames { @Deprecated public static final String Map_AccountBalance = "Map_AccountBalance"; public static final String Map_AccountHistory = "Map_AccountHistory"; - public static final String Map_AccountBalanceHistory = "Map_AccountBalanceHistory"; public static final String Map_Relation = "Map_Relation"; public static final String Map_ClearingAccount = "Map_ClearingAccount"; public static final String Map_ClearingAccountHistory = "Map_ClearingAccountHistory"; @@ -32,7 +31,6 @@ public final class IMDGDistributedNames { public static final String Map_RelationHistory = "Map_RelationHistory"; public static final String Map_ErrorText = "Map_ErrorText"; public static final String Map_Statement = "Map_Statement"; - public static final String Map_MarketAccess = "Map_MarketAccess"; // todo unused? public static final String Map_MarketTypeDictionary = "Map_MarketTypeDictionary"; public static final String Map_MarketDataLiquidation = "Map_MarketDataLiquidation"; public static final String Map_UserConnect = "Map_UserConnect"; @@ -109,6 +107,7 @@ public final class IMDGDistributedNames { public static final String Map_StatementTypeDictionary = "Map_StatementTypeDictionary"; public static final String Map_TermTypeDictionary = "Map_TermTypeDictionary"; public static final String Map_TransactionStatusDictionary = "Map_TransactionStatusDictionary"; + public static final String Map_TradedMoneyMarketSecurity = "Map_TradedMoneyMarketSecurity"; public static final String Map_CourierTypeDictionary = "Map_CourierTypeDictionary"; public static final String Map_TaskDictionary = "Map_TaskDictionary"; public static final String Map_TaskStatusDictionary = "Map_TaskStatusDictionary"; From 35a7a41091f5afaa79bc65da04729244bd68a072 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 17 May 2023 17:51:05 +0300 Subject: [PATCH 3/3] =?UTF-8?q?clearing-service=20http://jira.mfd.msk:8088?= =?UTF-8?q?/browse/CLS-290=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D1=87=D0=B8=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D1=88=D0=B0=D0=B3?= =?UTF-8?q?=D0=B0=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statics/data/registry/Registry.java | 11 +- .../clearing/session/stage/TaskType.java | 5 + ...nObligationsAndSettlementRequirements.java | 118 ++++++++++++++++++ ...tionsAndSettlementRequirementsPayload.java | 31 +++++ .../session/stage/util/RegistryUtil.java | 43 +++++++ .../session/stage/util/RegistryUtilTest.java | 25 ++++ .../enumeration/RegistryDesignation.java | 6 +- .../platform/enumeration/RegistryStatus.java | 19 +++ 8 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/CreateRegistryOnObligationsAndSettlementRequirements.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/RegistryOnObligationsAndSettlementRequirementsPayload.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/util/RegistryUtil.java create mode 100644 clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java index 7aed98446..93836225e 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java @@ -13,7 +13,7 @@ import java.time.LocalDate; *

* DB table: REGISTRY **/ -public class Registry extends BusinessObject { +public class Registry extends BusinessObject implements Cloneable { private static final long serialVersionUID = ConstSerializable.serialVersionUID; private Long companyId; @@ -412,4 +412,13 @@ public class Registry extends BusinessObject { public void setPaymentId(Long paymentId) { this.paymentId = paymentId; } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException("never", e); // it is Cloneable + } + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java index c1fb4a584..6e60b79c5 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/TaskType.java @@ -16,4 +16,9 @@ public enum TaskType { */ InclusionToPool, + /** + * Step 6 + */ + CreateRegistryOnObligationsAndSettlementRequirements, + } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/CreateRegistryOnObligationsAndSettlementRequirements.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/CreateRegistryOnObligationsAndSettlementRequirements.java new file mode 100644 index 000000000..061c367cd --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/CreateRegistryOnObligationsAndSettlementRequirements.java @@ -0,0 +1,118 @@ +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.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.session.stage.ISessionStage; +import ru.spcex.clearing.session.stage.StageResult; +import ru.spcex.clearing.session.stage.Task; +import ru.spcex.clearing.session.stage.task.DealsPreparePayload; +import ru.spcex.clearing.session.stage.task.RegistryOnObligationsAndSettlementRequirementsPayload; +import ru.spcex.clearing.session.stage.util.RegistryUtil; +import ru.spcex.platform.classes.base.interfaces.IExecution; +import ru.spcex.platform.classes.base.interfaces.WithExchangeExecutionId; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; + +@Service +public class CreateRegistryOnObligationsAndSettlementRequirements implements ISessionStage { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final ImdgId idSequence; + private final Imdg registryImdg; + + @Autowired + public CreateRegistryOnObligationsAndSettlementRequirements(ImdgProvider imdgProvider) { + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.idSequence = imdgProvider.getImdgIdGenerator(); + + } + + @Override + public StageResult submit(Task task) { + RegistryOnObligationsAndSettlementRequirementsPayload payload = (RegistryOnObligationsAndSettlementRequirementsPayload) task.getData(); + switch (task.getTaskType()) { + case CreateRegistryOnObligationsAndSettlementRequirements -> { + return createRegistryOnObligationsAndSettlementRequirements(payload.getSessionId()); + } + default -> { + throw new IllegalStateException("Unknown task type: " + task.getTaskType()); + } + } + } + + private Collection selectRegistry(Long sessionId) { + String registrySQL = "sessionId = " + sessionId; + registrySQL += " and (registryDesignation=" + RegistryDesignation.O.getKey() + " or registryDesignation=" + RegistryDesignation.T.getKey() + ")"; + registrySQL += " and (registryInstrumentType=" + RegistryInstrumentType.S.getKey() + " or registryInstrumentType=" + RegistryInstrumentType.M.getKey() + ")"; + registrySQL += " and (registryUnit=" + RegistryUnit.T.getKey() + ")"; + registrySQL += " and registryStatus=" + RegistryStatus.OK.getKey() + ")"; + // registryCode = [O/T][S/M][*][T] & registryStatus=OK + Collection result = registryImdg.getCollectionObjectsBySQL(registrySQL); + log.trace("Selected {} registry's by sql: {}", result.size(), registrySQL); + return result; + } + + private StageResult createRegistryOnObligationsAndSettlementRequirements(Long sessionId) { + Collection forRegistries = selectRegistry(sessionId); + ArrayList newRegistries = new ArrayList<>(); + + //todo oreder by обрабатываться группами по полю registry.groupId + + for (Registry registry : forRegistries) { + Registry newRegistry = createRegistryFor(registry); + newRegistries.add(newRegistry); + registryImdg.insert(newRegistry); + log.trace("For registry {} (registryCode={}) make new registry {} (registryCode={})", + registry.getId(), registry.getRegistryCode(), newRegistry.getId(), newRegistry.getRegistryCode()); + } + + StageResult> res = new StageResult<>(null, true); + res.setStageResult(newRegistries); + return res; + } + + Registry createRegistryFor(Registry forRegistry) { + Registry newRegistry = (Registry) forRegistry.clone();// cloneable + newRegistry.setId(idSequence.nextId()); + newRegistry.setCreated(Instant.now()); + newRegistry.setUpdated(newRegistry.getCreated()); + + String newRegDestination; + if (RegistryDesignation.O.equalsByKey(forRegistry.getRegistryDesignation())) { + newRegDestination = RegistryDesignation.L.getKey(); + } else if (RegistryDesignation.T.equalsByKey(forRegistry.getRegistryDesignation())) { + newRegDestination = RegistryDesignation.C.getKey(); + } else { + throw new IllegalArgumentException("RegistryDesignation=" + forRegistry.getRegistryDesignation()); + } + newRegistry.setRegistryDesignation(newRegDestination); + + String newRegistryInstrumentType; // по ТЗ не меняется + if (RegistryInstrumentType.S.equalsByKey(forRegistry.getRegistryInstrumentType())) { + newRegistryInstrumentType = RegistryInstrumentType.S.getKey(); + } else if (RegistryInstrumentType.M.equalsByKey(forRegistry.getRegistryInstrumentType())) { + newRegistryInstrumentType = RegistryInstrumentType.M.getKey(); + } else { + throw new IllegalArgumentException("RegistryInstrumentType=" + forRegistry.getRegistryInstrumentType()); + } + newRegistry.setRegistryInstrumentType(newRegistryInstrumentType); + + newRegistry.setRegistryCode(RegistryUtil.clearingCode(newRegistry)); + return newRegistry; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/RegistryOnObligationsAndSettlementRequirementsPayload.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/RegistryOnObligationsAndSettlementRequirementsPayload.java new file mode 100644 index 000000000..e0ddc15da --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/RegistryOnObligationsAndSettlementRequirementsPayload.java @@ -0,0 +1,31 @@ +package ru.spcex.clearing.session.stage.task; + +public class RegistryOnObligationsAndSettlementRequirementsPayload { + private Long sessionId; +// private Long companyId; +// private Long securityId; + + public Long getSessionId() { + return sessionId; + } + + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + +// public Long getCompanyId() { +// return companyId; +// } +// +// public void setCompanyId(Long companyId) { +// this.companyId = companyId; +// } +// +// public Long getSecurityId() { +// return securityId; +// } +// +// public void setSecurityId(Long securityId) { +// this.securityId = securityId; +// } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/util/RegistryUtil.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/util/RegistryUtil.java new file mode 100644 index 000000000..4361b6d4b --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/util/RegistryUtil.java @@ -0,0 +1,43 @@ +package ru.spcex.clearing.session.stage.util; + +import org.apache.commons.lang3.StringUtils; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.platform.enumeration.RegistryCapacity; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryUnit; + +import java.util.*; + +public class RegistryUtil { + + + public static String clearingCode(Registry ofRegistry) { + return clearingCode(ofRegistry.getRegistryDesignation(), ofRegistry.getRegistryInstrumentType(), ofRegistry.getRegistryCapacity(), ofRegistry.getRegistryUnit()); + } + + public static String clearingCode(String registryDesignation, String registryInstrumentType, String registryCapacity, String registryUnit) { + if (StringUtils.isEmpty(registryDesignation)) registryDesignation = "-"; + if (StringUtils.isEmpty(registryInstrumentType)) registryInstrumentType = "-"; + if (StringUtils.isEmpty(registryCapacity)) registryCapacity = "-"; + if (StringUtils.isEmpty(registryUnit)) registryUnit = "-"; + return registryDesignation + registryInstrumentType + registryCapacity + registryUnit; + } + + public static String clearingCode(RegistryDesignation registryDesignation, RegistryInstrumentType registryInstrumentType, RegistryCapacity registryCapacity, RegistryUnit registryUnit) { + return registryDesignation.getKey() + registryInstrumentType.getKey() + registryCapacity.getKey() + registryUnit.getKey(); + } + + public static Map> groupByGroupId(Collection registries) { + HashMap> groups = new HashMap<>(); + for (Registry reg : registries) { + List lst = groups.get(reg.getGroupId()); + if (lst == null) { + lst = new ArrayList<>(); + groups.put(reg.getGroupId(), lst); + } + lst.add(reg); + } + return groups; + } +} diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java new file mode 100644 index 000000000..d423313bd --- /dev/null +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java @@ -0,0 +1,25 @@ +package ru.spcex.clearing.session.stage.util; + +import org.junit.jupiter.api.Test; +import ru.clearing.classes.statics.data.registry.Registry; + +import static org.junit.jupiter.api.Assertions.*; + +class RegistryUtilTest { + + @Test + void clearingCode1() { + assertEquals("OMAT", RegistryUtil.clearingCode("O", "M", "A", "T")); + assertEquals("O-A-", RegistryUtil.clearingCode("O", "", "A", null)); + } + + @Test + void clearingCode2() { + Registry reg = new Registry(); + reg.setRegistryDesignation("O"); + reg.setRegistryInstrumentType("M"); + reg.setRegistryCapacity("A"); + reg.setRegistryUnit("T"); + assertEquals("OMAT", RegistryUtil.clearingCode(reg)); + } +} \ No newline at end of file diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryDesignation.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryDesignation.java index 0d9420516..896e326af 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryDesignation.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryDesignation.java @@ -3,7 +3,11 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum RegistryDesignation implements IEnumKey { - A("A") + A("A"), + O("O"), + T("T"), + L("L"), + C("C") ; private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java new file mode 100644 index 000000000..dd948e3b9 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java @@ -0,0 +1,19 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum RegistryStatus implements IEnumKey { + OK("OK"), + ; + + private final String key; + + RegistryStatus(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +}