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 a4d163256..e345077d9 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.22", + "version": "3.5.0.23", "enums": { @@ -1726,7 +1726,7 @@ } , {"code": "corporationSoleType", - "type": 12,"dbname": "Код единоличного исполнительного органа","name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","searchable": true,"sortable": true,"visible": true,"link": "corporationSoleType" + "type": 12,"dbname": "Код единоличного исполнительного органа","name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","searchable": true,"sortable": true,"visible": true,"link": "corporationSoleType","ignore": true } , {"code": "countryCode", @@ -1734,7 +1734,7 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "professionalSign", @@ -1812,7 +1812,7 @@ } , {"code": "corporationSoleType", - "type": 12,"name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","link": "corporationSoleType" + "type": 12,"name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","link": "corporationSoleType","visible": false } , {"code": "legalKind", @@ -1840,7 +1840,7 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание компании" + "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание компании","visible": false } , {"code": "workflowStatus", @@ -2025,7 +2025,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "issuer", @@ -2033,11 +2033,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "number", @@ -2045,11 +2045,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Место","shortname": "Место","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало","searchable": true,"sortable": true + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","searchable": true,"sortable": true,"ignore": true } , {"code": "validToDate", @@ -2085,7 +2085,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","required": true + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","visible": false } , {"code": "issuer", @@ -2093,11 +2093,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","required": true + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","visible": false } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","required": true + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","visible": false } , {"code": "number", @@ -2105,11 +2105,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место","required": true + "type": 2,"length": 255,"name": "Место","shortname": "Место","visible": false } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало","required": true + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","visible": false } , {"code": "validToDate", @@ -2146,7 +2146,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи" + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","visible": false } , {"code": "issuer", @@ -2154,11 +2154,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган" + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","visible": false } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ" + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","visible": false } , {"code": "number", @@ -2166,11 +2166,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место" + "type": 2,"length": 255,"name": "Место","shortname": "Место","visible": false } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало" + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","visible": false } , {"code": "validToDate", @@ -2391,7 +2391,7 @@ "fields": [ {"code": "countryCode", - "type": 12,"dbname": "Код страны","name": "Наименование страны","shortname": "Страна","searchable": true,"sortable": true,"visible": true,"link": "countryCode" + "type": 12,"dbname": "Код страны","name": "Наименование страны","shortname": "Страна","searchable": true,"sortable": true,"visible": true,"link": "countryCode","ignore": true } , {"code": "currencyCode", @@ -2423,15 +2423,15 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание","searchable": true,"sortable": false + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","searchable": true,"sortable": false,"ignore": true } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","searchable": true,"sortable": true + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","searchable": true,"sortable": true,"ignore": true } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","searchable": true,"sortable": true + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","searchable": true,"sortable": true,"ignore": true } , {"code": "nominalValue", @@ -2463,7 +2463,7 @@ } , {"code": "termType", - "type": 12,"dbname": "Код вида инструмента","name": "Наименование вида инструмента","shortname": "Вид инструмента","searchable": true,"sortable": true,"visible": false,"link": "termType" + "type": 12,"dbname": "Код вида инструмента","name": "Наименование вида инструмента","shortname": "Вид инструмента","searchable": true,"sortable": true,"visible": false,"link": "termType","ignore": true } , {"code": "lotSize", @@ -2499,7 +2499,7 @@ "name": "Добавление инструмента Денежного рынка", - "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency,startDate,endDate,termType", + "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", "fields": [ {"code": "securitySymbol", @@ -2531,19 +2531,19 @@ } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","required": true + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","visible": false } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","required": true + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","visible": false } , {"code": "termType", - "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","required": true + "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","visible": false } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание" + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","visible": false } , {"code": "issuerId", @@ -2576,7 +2576,7 @@ "name": "Изменение инструмента Денежного рынка", - "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency,startDate,endDate,termType", + "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", "fields": [ {"code": "id", @@ -2612,19 +2612,19 @@ } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","enabled": false + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","enabled": false,"visible": false } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания" + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","visible": false } , {"code": "termType", - "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType" + "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","visible": false } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание" + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","visible": false } , {"code": "issuerId", @@ -3531,7 +3531,7 @@ } , {"code": "code", - "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "Код ТКР","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "ТКР","searchable": true,"sortable": true,"visible": true } , {"code": "moneyAccountId", @@ -3596,15 +3596,31 @@ "name": "Изменение ТКР", - "confirmation": "companyId,moneyAccountId,depoAccountId,status", + "confirmation": "companyId,code,moneyAccountId,depoAccountId,status", "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true } + , + {"code": "companyId", + "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","enabled": false + } + , + {"code": "code", + "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "ТКР","enabled": false + } + , + {"code": "moneyAccountId", + "type": 1,"name": "Номер денежного счета","shortname": "Денежный счет","link": "account","linkCode": "account","enabled": false + } + , + {"code": "depoAccountId", + "type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account","enabled": false + } , {"code": "status", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "workflowStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true } ] } @@ -4439,11 +4455,11 @@ } , {"code": "task", - "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task" + "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true } , {"code": "taskTime", - "type": 5,"name": "Время задачи","shortname": "Время задачи" + "type": 5,"name": "Время задачи","shortname": "Время задачи","required": true } , {"code": "section", @@ -4455,7 +4471,7 @@ } , {"code": "taskStatus", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus","required": true } , {"code": "companyId", @@ -4548,11 +4564,11 @@ } , {"code": "clearingDate", - "type": 6,"name": "Дата","shortname": "Дата" + "type": 6,"name": "Дата","shortname": "Дата","required": true } , {"code": "dayStatus", - "type": 12,"name": "Статус","shortname": "Статус","link": "dayStatus" + "type": 12,"name": "Статус","shortname": "Статус","link": "dayStatus","required": true } , {"code": "companyId", @@ -4685,15 +4701,15 @@ } , {"code": "task", - "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task" - } - , - {"code": "taskTime", - "type": 5,"name": "Время задачи","shortname": "Время задачи" + "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true } , {"code": "clearingDate", - "type": 6,"name": "Дата задачи","shortname": "Дата задачи" + "type": 6,"name": "Дата задачи","shortname": "Дата задачи","required": true + } + , + {"code": "taskTime", + "type": 5,"name": "Время задачи","shortname": "Время задачи","required": true } , {"code": "section", @@ -4705,7 +4721,7 @@ } , {"code": "taskStatus", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus","required": true } , {"code": "companyId", 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 6273184e6..7527dd5e0 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 @@ - + @@ -388,9 +388,9 @@ - + - + @@ -410,14 +410,14 @@ - + - + @@ -465,13 +465,13 @@ - + - - + + - - + + @@ -480,13 +480,13 @@ - + - - + + - - + + @@ -495,13 +495,13 @@ - + - - + + - - + + @@ -553,15 +553,15 @@ - + - - - + + + @@ -569,7 +569,7 @@ - + @@ -578,7 +578,7 @@ - + @@ -586,10 +586,10 @@ - - - - + + + + @@ -597,7 +597,7 @@ - + @@ -606,10 +606,10 @@ - - - - + + + + @@ -823,7 +823,7 @@ - + @@ -839,9 +839,13 @@ - + - + + + + + @@ -1042,11 +1046,11 @@ - - + +
- + @@ -1070,8 +1074,8 @@ - - + + @@ -1105,12 +1109,12 @@ - - - + + +
- + diff --git a/clearing-parent/backend-api/src/test/resources/meta.json b/clearing-parent/backend-api/src/test/resources/meta.json index a4d163256..e345077d9 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.22", + "version": "3.5.0.23", "enums": { @@ -1726,7 +1726,7 @@ } , {"code": "corporationSoleType", - "type": 12,"dbname": "Код единоличного исполнительного органа","name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","searchable": true,"sortable": true,"visible": true,"link": "corporationSoleType" + "type": 12,"dbname": "Код единоличного исполнительного органа","name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","searchable": true,"sortable": true,"visible": true,"link": "corporationSoleType","ignore": true } , {"code": "countryCode", @@ -1734,7 +1734,7 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "professionalSign", @@ -1812,7 +1812,7 @@ } , {"code": "corporationSoleType", - "type": 12,"name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","link": "corporationSoleType" + "type": 12,"name": "Единоличный исполнительный орган","shortname": "Исполнительный орган","link": "corporationSoleType","visible": false } , {"code": "legalKind", @@ -1840,7 +1840,7 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание компании" + "type": 2,"length": 255,"name": "Описание компании","shortname": "Описание компании","visible": false } , {"code": "workflowStatus", @@ -2025,7 +2025,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "issuer", @@ -2033,11 +2033,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "number", @@ -2045,11 +2045,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Место","shortname": "Место","searchable": true,"sortable": true,"visible": true,"ignore": true } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало","searchable": true,"sortable": true + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","searchable": true,"sortable": true,"ignore": true } , {"code": "validToDate", @@ -2085,7 +2085,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","required": true + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","visible": false } , {"code": "issuer", @@ -2093,11 +2093,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","required": true + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","visible": false } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","required": true + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","visible": false } , {"code": "number", @@ -2105,11 +2105,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место","required": true + "type": 2,"length": 255,"name": "Место","shortname": "Место","visible": false } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало","required": true + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","visible": false } , {"code": "validToDate", @@ -2146,7 +2146,7 @@ } , {"code": "issuePlace", - "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи" + "type": 2,"length": 255,"name": "Место выдачи","shortname": "Место выдачи","visible": false } , {"code": "issuer", @@ -2154,11 +2154,11 @@ } , {"code": "issuerCode", - "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган" + "type": 2,"length": 255,"name": "Код выдавшего органа","shortname": "Выдавший орган","visible": false } , {"code": "name", - "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ" + "type": 2,"length": 255,"name": "Наименование документа","shortname": "Документ","visible": false } , {"code": "number", @@ -2166,11 +2166,11 @@ } , {"code": "place", - "type": 2,"length": 255,"name": "Место","shortname": "Место" + "type": 2,"length": 255,"name": "Место","shortname": "Место","visible": false } , {"code": "validFromDate", - "type": 6,"name": "Дата начала срока действия","shortname": "Начало" + "type": 6,"name": "Дата начала срока действия","shortname": "Начало","visible": false } , {"code": "validToDate", @@ -2391,7 +2391,7 @@ "fields": [ {"code": "countryCode", - "type": 12,"dbname": "Код страны","name": "Наименование страны","shortname": "Страна","searchable": true,"sortable": true,"visible": true,"link": "countryCode" + "type": 12,"dbname": "Код страны","name": "Наименование страны","shortname": "Страна","searchable": true,"sortable": true,"visible": true,"link": "countryCode","ignore": true } , {"code": "currencyCode", @@ -2423,15 +2423,15 @@ } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание","searchable": true,"sortable": false + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","searchable": true,"sortable": false,"ignore": true } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","searchable": true,"sortable": true + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","searchable": true,"sortable": true,"ignore": true } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","searchable": true,"sortable": true + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","searchable": true,"sortable": true,"ignore": true } , {"code": "nominalValue", @@ -2463,7 +2463,7 @@ } , {"code": "termType", - "type": 12,"dbname": "Код вида инструмента","name": "Наименование вида инструмента","shortname": "Вид инструмента","searchable": true,"sortable": true,"visible": false,"link": "termType" + "type": 12,"dbname": "Код вида инструмента","name": "Наименование вида инструмента","shortname": "Вид инструмента","searchable": true,"sortable": true,"visible": false,"link": "termType","ignore": true } , {"code": "lotSize", @@ -2499,7 +2499,7 @@ "name": "Добавление инструмента Денежного рынка", - "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency,startDate,endDate,termType", + "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", "fields": [ {"code": "securitySymbol", @@ -2531,19 +2531,19 @@ } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","required": true + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","visible": false } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","required": true + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","visible": false } , {"code": "termType", - "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","required": true + "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","visible": false } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание" + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","visible": false } , {"code": "issuerId", @@ -2576,7 +2576,7 @@ "name": "Изменение инструмента Денежного рынка", - "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency,startDate,endDate,termType", + "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", "fields": [ {"code": "id", @@ -2612,19 +2612,19 @@ } , {"code": "startDate", - "type": 6,"name": "Дата начала действия","shortname": "Дата начала","enabled": false + "type": 6,"name": "Дата начала действия","shortname": "Дата начала","enabled": false,"visible": false } , {"code": "endDate", - "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания" + "type": 6,"name": "Дата окончания действия","shortname": "Дата окончания","visible": false } , {"code": "termType", - "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType" + "type": 12,"name": "Наименование вида инструмента","shortname": "Вид инструмента","link": "termType","visible": false } , {"code": "description", - "type": 2,"length": 255,"name": "Описание","shortname": "Описание" + "type": 2,"length": 255,"name": "Описание","shortname": "Описание","visible": false } , {"code": "issuerId", @@ -3531,7 +3531,7 @@ } , {"code": "code", - "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "Код ТКР","searchable": true,"sortable": true,"visible": true + "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "ТКР","searchable": true,"sortable": true,"visible": true } , {"code": "moneyAccountId", @@ -3596,15 +3596,31 @@ "name": "Изменение ТКР", - "confirmation": "companyId,moneyAccountId,depoAccountId,status", + "confirmation": "companyId,code,moneyAccountId,depoAccountId,status", "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true } + , + {"code": "companyId", + "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","enabled": false + } + , + {"code": "code", + "type": 2,"length": 255,"name": "Код торгово-клирингового регистра","shortname": "ТКР","enabled": false + } + , + {"code": "moneyAccountId", + "type": 1,"name": "Номер денежного счета","shortname": "Денежный счет","link": "account","linkCode": "account","enabled": false + } + , + {"code": "depoAccountId", + "type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account","enabled": false + } , {"code": "status", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "workflowStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true } ] } @@ -4439,11 +4455,11 @@ } , {"code": "task", - "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task" + "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true } , {"code": "taskTime", - "type": 5,"name": "Время задачи","shortname": "Время задачи" + "type": 5,"name": "Время задачи","shortname": "Время задачи","required": true } , {"code": "section", @@ -4455,7 +4471,7 @@ } , {"code": "taskStatus", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus","required": true } , {"code": "companyId", @@ -4548,11 +4564,11 @@ } , {"code": "clearingDate", - "type": 6,"name": "Дата","shortname": "Дата" + "type": 6,"name": "Дата","shortname": "Дата","required": true } , {"code": "dayStatus", - "type": 12,"name": "Статус","shortname": "Статус","link": "dayStatus" + "type": 12,"name": "Статус","shortname": "Статус","link": "dayStatus","required": true } , {"code": "companyId", @@ -4685,15 +4701,15 @@ } , {"code": "task", - "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task" - } - , - {"code": "taskTime", - "type": 5,"name": "Время задачи","shortname": "Время задачи" + "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true } , {"code": "clearingDate", - "type": 6,"name": "Дата задачи","shortname": "Дата задачи" + "type": 6,"name": "Дата задачи","shortname": "Дата задачи","required": true + } + , + {"code": "taskTime", + "type": 5,"name": "Время задачи","shortname": "Время задачи","required": true } , {"code": "section", @@ -4705,7 +4721,7 @@ } , {"code": "taskStatus", - "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus" + "type": 12,"name": "Наименование статуса","shortname": "Статус","link": "taskStatus","required": true } , {"code": "companyId", diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingRegistersOnOS.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingRegistersOnOS.java index 5204abe62..54b16f861 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingRegistersOnOS.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingRegistersOnOS.java @@ -9,7 +9,7 @@ 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.RegistryOnObligationsAndSettlementRequirementsPayload; +import ru.spcex.clearing.session.stage.task.FormingRegistersOnOSPayload; import ru.spcex.clearing.session.stage.util.RegistryUtil; import ru.spcex.platform.enumeration.RegistryDesignation; import ru.spcex.platform.enumeration.RegistryInstrumentType; @@ -39,10 +39,10 @@ public class FormingRegistersOnOS implements ISessionStage { @Override public StageResult submit(Task task) { - RegistryOnObligationsAndSettlementRequirementsPayload payload = (RegistryOnObligationsAndSettlementRequirementsPayload) task.getData(); + FormingRegistersOnOSPayload payload = (FormingRegistersOnOSPayload) task.getData(); switch (task.getTaskType()) { case FormingRegistersOnOS -> { - return createRegistryOnObligationsAndSettlementRequirements(payload.getSessionId()); + return createRegistryOnObligationsAndSettlementRequirements(); } default -> { throw new IllegalStateException("Unknown task type: " + task.getTaskType()); @@ -53,12 +53,10 @@ public class FormingRegistersOnOS implements ISessionStage { /** * Select Registry by: registryCode = [O/T][S/M][*][T] & registryStatus=OK * - * @param sessionId * @return */ - protected Collection selectRegistry(Long sessionId) { - String registrySQL = "sessionId = " + sessionId; - registrySQL += " and (registryDesignation=" + RegistryDesignation.O.getKey() + " or registryDesignation=" + RegistryDesignation.T.getKey() + ")"; + protected Collection selectRegistry() { + String registrySQL = "(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() + ")"; @@ -67,8 +65,8 @@ public class FormingRegistersOnOS implements ISessionStage { return result; } - protected StageResult createRegistryOnObligationsAndSettlementRequirements(Long sessionId) { - Collection forRegistries = selectRegistry(sessionId); + protected StageResult createRegistryOnObligationsAndSettlementRequirements() { + Collection forRegistries = selectRegistry(); ArrayList newRegistries = new ArrayList<>(); //todo oreder by обрабатываться группами по полю registry.groupId diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java new file mode 100644 index 000000000..29e40efae --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java @@ -0,0 +1,151 @@ +package ru.spcex.clearing.session.stage.impl; + +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionDeposit; +import ru.clearing.classes.statics.data.execution.ExecutionFond; +import ru.clearing.classes.statics.data.misc.Market; +import ru.clearing.classes.statics.data.misc.Session; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.session.stage.util.RegistryUtil; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class RegistryBuilder { + private Imdg companyImdg; + private Imdg tradingClearingRegistryImdg; + private Imdg accountImdg; + private Imdg marketImdg; + private Imdg sessionImdg; + private ExecutionCommon exec; + private RegistryDesignation regDsgn; + + private RegistryBuilder() { + } + + public static RegistryBuilder builder() { + return new RegistryBuilder(); + } + + public RegistryBuilder imdg(ImdgProvider imdgProvider) { + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); + this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); + return this; + } + + public RegistryBuilder exec(ExecutionCommon exec) { + this.exec = exec; + return this; + } + + public RegistryBuilder registryDesignation(RegistryDesignation registryDesignation) { + this.regDsgn = registryDesignation; + return this; + } + + public Registry build() { + ISide side = getSide(exec); + Registry reg = new Registry(); + reg.setCompanyId(exec.getCompanyId()); + Company company = searchCompany(); + reg.setTradingCode(company.getTradingCode()); + reg.setClearingCode(company.getClearingCode()); + reg.setShortName(company.getShortName()); + reg.setFullName(company.getFullName()); + TradingClearingRegistry tcr = searchTradingClearingRegistry(); + if ((regDsgn.equals(RegistryDesignation.O) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && side.isSell())) { + reg.setAccountId(tcr.getMoneyAccountId()); + reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + reg.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme add second leg code branch + } else if ((regDsgn.equals(RegistryDesignation.T) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && side.isSell())) { + reg.setAccountId(tcr.getDepoAccountId()); + reg.setRegistryInstrumentType(RegistryInstrumentType.S.getKey()); + reg.setBalanceDimension(BalanceDimension.PICS.getKey()); //fixme add second leg code branch + } + Account account = accountImdg.getSingleObjectByID(reg.getAccountId()); + reg.setAccountType(account.getAccountType()); + reg.setAccount(account.getAccount()); + reg.setRegistryDesignation(regDsgn.getKey()); + reg.setRegistryCapacity(account.getAccountType()); + reg.setRegistryUnit(RegistryUnit.T.getKey()); + reg.setRegistryCode(RegistryUtil.clearingCode(reg)); + reg.setTradingClearingRegistryId(exec.getTradingClearingRegistryId()); + reg.setTradingClearingRegistry(tcr.getCode()); + reg.setRegistryStatus(RegistryStatus.PROC.getKey()); + reg.setSecurityId(exec.getSecurityId()); + reg.setSecuritySymbol(exec.getSecuritySymbol()); + switch (exec.type()) { + case ExecutionDeposit -> { + ExecutionDeposit execDep = (ExecutionDeposit) this.exec; + reg.setBalance((execDep).getFirstLegAmount()); + if (regDsgn.equals(RegistryDesignation.T)) { + reg.setSettledCredit((execDep).getFirstLegAmount()); + } else if (regDsgn.equals(RegistryDesignation.O)) { + reg.setSettledDebit((execDep).getFirstLegAmount()); + } + reg.setSettlementDate(execDep.getFirstLegSettlementDate()); //fixme add second leg code branch + reg.setSettlementCode(execDep.getFirstLegSettlementCode()); //fixme add second leg code branch + reg.setRefundDate(execDep.getSecondLegSettlementDate()); //fixme add second leg code branch?? + reg.setValueDate(execDep.getFirstLegSettlementDate()); + reg.setContract(execDep.getContract()); + } + case ExecutionFond -> { + ExecutionFond execFond = (ExecutionFond) this.exec; + reg.setBalance(execFond.getSettlementAmount()); + reg.setSettlementDate(execFond.getSettlementDate()); + reg.setSettlementCode(execFond.getSettlementCode()); + } + } + reg.setTradingDate(exec.getTradingDate()); + reg.setClearingDate(LocalDate.now()); + reg.setPrice(exec.getPrice()); + reg.setCounterPartyId(exec.getCounterPartyId()); + reg.setGroupId(groupId()); + reg.setSessionId(exec.getSessionId()); + reg.setSessionType(sessionType()); + return reg; + } + + private static DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyyMMdd"); + + private Long groupId() { + LocalDate now = LocalDate.now(); + Market market = marketImdg.getSingleObjectBySQL("code = '" + exec.getMarket() + "'"); + return Long.valueOf(now.format(yyyyMMdd) + exec.getExchangeExecutionId() + market.getId()); + } + + //можно передать из стейджа + private String sessionType() { + Session session = sessionImdg.getSingleObjectByID(exec.getSessionId()); + return session.getSessionType(); + } + + private Company searchCompany() { + return companyImdg.getSingleObjectBySQL("id = " + exec.getCompanyId()); + } + + private TradingClearingRegistry searchTradingClearingRegistry() { + return tradingClearingRegistryImdg.getSingleObjectBySQL("tradingClearingRegistryId = " + exec.getTradingClearingRegistryId()); + } + + private static ISide getSide(ExecutionCommon exec) { + if (exec.type().equals(ExecutionType.ExecutionDeposit)) { + return ISide.parse(MoneyFlowSide.class, exec.getSide()); + } else if (exec.type().equals(ExecutionType.ExecutionFond)) { + return ISide.parse(Side.class, exec.getSide()); + } else { + throw new RuntimeException("Unknown Execution type: " + exec.type()); + } + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryUpdater.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryUpdater.java new file mode 100644 index 000000000..98bc78a6d --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryUpdater.java @@ -0,0 +1,66 @@ +package ru.spcex.clearing.session.stage.impl; + +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +public class RegistryUpdater { + public static RegistryUpdater updater() { + return new RegistryUpdater(); + } + + private RegistryUpdater() { + } + + private Imdg registryImdg; + private Imdg companyImdg; + private Imdg tradingClearingRegistryImdg; + private ExecutionCommon exec; + private Registry rgs; + + public RegistryUpdater imdg(ImdgProvider imdgProvider) { + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + return this; + } + + public RegistryUpdater registry(Registry rgs) { + this.rgs = rgs; + return this; + } + + public RegistryUpdater exec(ExecutionCommon exec) { + this.exec = exec; + return this; + } + + public Registry update() { + Registry reg = new Registry(); + reg.setCompanyId(exec.getCompanyId()); + Company company = searchCompany(); + reg.setTradingCode(company.getTradingCode()); + reg.setClearingCode(company.getClearingCode()); + reg.setShortName(company.getShortName()); + reg.setFullName(company.getFullName()); + TradingClearingRegistry tcr = searchTradingClearingRegistry(); + return null; + } + + private Company searchCompany() { + return companyImdg.getSingleObjectBySQL("id = " + exec.getCompanyId()); + } + + private TradingClearingRegistry searchTradingClearingRegistry() { + return tradingClearingRegistryImdg.getSingleObjectBySQL("tradingClearingRegistryId = " + exec.getTradingClearingRegistryId()); + } + + + + +// public +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java new file mode 100644 index 000000000..894b0f197 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RequirmentsAndObligationCreation.java @@ -0,0 +1,180 @@ +package ru.spcex.clearing.session.stage.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionDeposit; +import ru.clearing.classes.statics.data.execution.ExecutionFond; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.models.RegistryTradingParams; +import ru.spcex.clearing.service.builder.sql.RegistryCodeSqlBuilder; +import ru.spcex.clearing.session.stage.ISessionStage; +import ru.spcex.clearing.session.stage.StageResult; +import ru.spcex.clearing.session.stage.Task; +import ru.spcex.clearing.session.stage.TaskType; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.utils.collection.Pair; + +import java.time.LocalDate; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; + +@Service +public class RequirmentsAndObligationCreation implements ISessionStage { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg registryImdg; + private final ImdgProvider imdgProvider; + + + @Autowired + public RequirmentsAndObligationCreation(ImdgProvider imdgProvider) { + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.imdgProvider = imdgProvider; + } + + @SuppressWarnings("unchecked") + @Override + public StageResult submit(Task task) { + if (task.getTaskType() == TaskType.RequirementsAndObligationsCreate) { + return createRegisters((List) task.getData()); + } + throw new IllegalStateException("Unknown task type: " + task.getTaskType()); + } + + private StageResult createRegisters(List data) { + if (data.size() % 2 != 0) { + throw new IllegalStateException("Data size must be even (executions must match)"); + } + //см. описание к #matchExecutions + for (int i = 0; i < data.size(); ) { + Pair matched = matchExecutions(data, i); + if (matched == null) { + log.error("couldn't find match execution for id = {}", data.get(i).getId()); + i += 1; + continue; + } + i += 2; + ExecutionCommon partyExec = matched.getFirst(); + ExecutionCommon counterExec = matched.getSecond(); + + BiConsumer findAndUpdateOrCreate = (exec, regDsgn) -> + findReg(exec, regDsgn).ifPresentOrElse(registry -> { + RegistryUpdater.updater() + .imdg(imdgProvider) + .exec(partyExec) + .registry(registry) + .update(); + registryImdg.update(registry); + }, () -> { + Registry newRegister = RegistryBuilder.builder() + .imdg(imdgProvider) + .exec(partyExec) + .registryDesignation(regDsgn) + .build(); + registryImdg.insert(newRegister); + }); + findAndUpdateOrCreate.accept(partyExec, RegistryDesignation.O); + findAndUpdateOrCreate.accept(partyExec, RegistryDesignation.T); + findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.O); + findAndUpdateOrCreate.accept(counterExec, RegistryDesignation.T); + } + return new StageResult<>(null, true); + } + + + private Optional findReg(ExecutionCommon exec, RegistryDesignation des) { + ISide side = getSide(exec); + RegistryTradingParams p; + if (side.isBuy() && des.equals(RegistryDesignation.O)) { + p = new RegistryTradingParams( + RegistryDesignation.O, RegistryInstrumentType.M, null, RegistryUnit.T + ); + } else if (side.isBuy() && des.equals(RegistryDesignation.T)) { + p = new RegistryTradingParams( + RegistryDesignation.T, RegistryInstrumentType.S, null, RegistryUnit.T + ); + } else if (side.isSell() && des.equals(RegistryDesignation.O)) { + p = new RegistryTradingParams( + RegistryDesignation.O, RegistryInstrumentType.S, null, RegistryUnit.T + ); + } else if (side.isSell() && des.equals(RegistryDesignation.T)) { + p = new RegistryTradingParams( + RegistryDesignation.T, RegistryInstrumentType.M, null, RegistryUnit.T + ); + } else { + throw new IllegalStateException("cannot construct for " + des + " " + side); + } + String sql = RegistryCodeSqlBuilder.getInstance(p).build(); + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate rgstrPredicate = pb.and(pb.sql(sql), + pb.equals("tradingClearingRegistryId", exec.getTradingClearingRegistryId()), + pb.equals("companyId", exec.getCompanyId()), + pb.equals("settlementDate", settlementDt(exec)) + ); + return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(rgstrPredicate)); + } + + private LocalDate settlementDt(ExecutionCommon exec) { + if (exec.type().equals(ExecutionType.ExecutionDeposit)) { + return ((ExecutionDeposit) exec).getFirstLegSettlementDate(); + } else if (exec.type().equals(ExecutionType.ExecutionFond)) { + return ((ExecutionFond) exec).getSettlementDate(); + } else { + throw new RuntimeException("Unknown Execution type: " + exec.type()); + } + } + + + /** + * входные данные отсортированы по exchangeExecutionId. + * сортировка выполнена на предыдущем шаге. (такое описание шагов в ТЗ) + * по идее, Execution с одинаковым exchangeExecutionId должно быть всего два. + * если это не так, передалать на коллекцию Long executionId в правильном порядке + * и для каждого искать мэтч отдельно в Imdg, с сохранением уже обработанных для избежания дублирования + */ + private Pair matchExecutions(List data, int i) { + //if the last execution, then no match + if (i >= data.size() - 1) { + return null; + } + ExecutionCommon exec1 = data.get(i); + ExecutionCommon exec2 = data.get(i + 1); + //Встречная сделка контрагента выбирается из executionDeposit/Fond по условию: + //exchangeExecutionId=currentExecutionDeposit/Fond.exchangeExecutionId + //и [side=SELL (если currentExecutionDeposit/Fond.side=BUY) или side=BUY (если currentExecutionDeposit/Fond.side=SELL) по справочнику moneyFlowSide или справочнику side в зависимости от секции обрабатываемой сделки] + //и companyId=currentExecutionDeposit/Fond.counterPartyId + boolean valid = true; + if (!Objects.equals(exec1.getExchangeExecutionId(), exec2.getExchangeExecutionId())) { + valid = false; + } else if (Objects.equals(getSide(exec1), getSide(exec2))) { + valid = false; + } else if (!Objects.equals(exec1.getCounterPartyId(), exec2.getCounterPartyId())) { + valid = false; + } + if (!valid) { + log.error("FATAL skipping ExchangeExecutionId: {}", exec1.getId()); + } + return new Pair<>(exec1, exec2); + } + + private static ISide getSide(ExecutionCommon exec) { + if (exec.type().equals(ExecutionType.ExecutionDeposit)) { + return ISide.parse(MoneyFlowSide.class, exec.getSide()); + } else if (exec.type().equals(ExecutionType.ExecutionFond)) { + return ISide.parse(Side.class, exec.getSide()); + } else { + throw new RuntimeException("Unknown Execution type: " + exec.type()); + } + } + +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java index c563c84b5..91c0a60f2 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java @@ -15,6 +15,7 @@ import ru.spcex.platform.enumeration.RegistryInstrumentType; import ru.spcex.platform.enumeration.RegistryUnit; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; @@ -26,10 +27,12 @@ import java.util.Collection; public class UnlockResources implements ISessionStage { private final Logger log = LoggerFactory.getLogger(getClass()); + protected final ImdgProvider imdgProvider; private final Imdg registryImdg; @Autowired public UnlockResources(ImdgProvider imdgProvider) { + this.imdgProvider = imdgProvider; this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); } @@ -39,7 +42,7 @@ public class UnlockResources implements ISessionStage { switch (task.getTaskType()) { case UnlockResources -> { UnlockResourcesPayload payload = (UnlockResourcesPayload) task.getData(); - return unlockResources(payload.getSdfMode(), payload.getSessionId(), + return unlockResources(payload.getSdfMode(), payload.getAccount(), payload.getSecurityId(), payload.getFullNames(), @@ -52,26 +55,18 @@ public class UnlockResources implements ISessionStage { } } - /** - * Select Registry by: account; fullName* / securityId - */ - protected Collection selectRegistry(Long sessionId, String account, Long securityId, Collection fullNames) { + protected Collection selectRegistryForSDF04(String account, Collection fullNames) { ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); - ImdgPredicate queryPart; - if (securityId != null) { - queryPart = pb.in("securityId", securityId); - } else if (fullNames != null && !fullNames.isEmpty()) { - queryPart = pb.in("fullName", fullNames.toArray(new String[fullNames.size()])); - } else { - throw new IllegalArgumentException("Required securityId or fullNames"); - } ImdgPredicate query = pb.and( pb.and( - pb.equals("sessionId", sessionId), - pb.equals("registryDesignation", RegistryDesignation.A.getKey()) // не все нужны, только с этим кодом отфильтруем. + pb.equals("registryDesignation", RegistryDesignation.A.getKey()), + pb.equals("registryInstrumentType", RegistryInstrumentType.M.getKey()), + // pb.equals("registryCapacity", *), + pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()), + pb.equals("registryUnit", RegistryUnit.B.getKey())) ), pb.equals("account", account), - queryPart + pb.in("fullName", fullNames.toArray(new String[fullNames.size()])) ); Collection result = registryImdg.getCollectionObjectsByPredicate(query); @@ -79,50 +74,74 @@ public class UnlockResources implements ISessionStage { return result; } + /** + * Select Registry by: account; fullName* / securityId + */ + protected Collection selectRegistryForSDF12(String account, Long securityId) { + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate query = pb.and( + pb.and( + pb.equals("registryDesignation", RegistryDesignation.A.getKey()), + pb.equals("registryInstrumentType", RegistryInstrumentType.S.getKey()), + // pb.equals("registryCapacity", *), + pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()), + pb.equals("registryUnit", RegistryUnit.B.getKey())) + ), + pb.equals("account", account), + pb.in("securityId", securityId) + ); + + Collection result = registryImdg.getCollectionObjectsByPredicate(query); + log.trace("Selected {} registry's by sql: {}", result.size(), query); + return result; + } + + /** * @param sdfMode UnlockResourcesPayload.sdfMode - * @param sessionId * @param account * @param securityId * @param fullNames * @return */ - protected StageResult unlockResources(String sdfMode, Long sessionId, String account, Long securityId, Collection fullNames, BigDecimal value) { - Collection forRegistries = selectRegistry(sessionId, account, securityId, fullNames); + protected StageResult unlockResources(String sdfMode, String account, Long securityId, Collection fullNames, BigDecimal value) { + Collection forRegistries; - //todo при перезапуске после незапланированного завершения стадии: надо ли проверять уже созданные регистры и не создавать дубликаты? if (UnlockResourcesPayload.MODE_SDF04.equals(sdfMode)) { - forRegistries = forRegistries.stream().filter( - (Registry r) -> - RegistryDesignation.A.equalsByKey(r.getRegistryDesignation()) - && - RegistryInstrumentType.M.equalsByKey(r.getRegistryInstrumentType()) - && - (RegistryUnit.F.equalsByKey(r.getRegistryUnit()) || RegistryUnit.B.equalsByKey(r.getRegistryUnit())) - ).toList(); + forRegistries = selectRegistryForSDF04(account, fullNames); } else if (UnlockResourcesPayload.MODE_SDF12.equals(sdfMode)) { - forRegistries = forRegistries.stream().filter( - (Registry r) -> - RegistryDesignation.A.equalsByKey(r.getRegistryDesignation()) - && - RegistryInstrumentType.S.equalsByKey(r.getRegistryInstrumentType()) - && - (RegistryUnit.F.equalsByKey(r.getRegistryUnit()) || RegistryUnit.B.equalsByKey(r.getRegistryUnit())) - ).toList(); + forRegistries = selectRegistryForSDF12(account, securityId); } else { throw new IllegalArgumentException("Mode not support: " + sdfMode); } - for (Registry registry : forRegistries) { - boolean modified = unlockRegistry(registry, value); - if (modified) { - registry.setUpdated(Instant.now()); - registryImdg.update(registry); - log.trace("Registry {} changed; value +- registry", - registry.getId(), registry.getRegistryCode(), value); + ImdgTransaction tx = imdgProvider.newTransaction(); + boolean txOk = false; + try { + log.debug("Processing transaction {}, input {} registers.", tx, forRegistries.size()); + Imdg registryTxImdg = tx.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + int nUpdates = 0; + for (Registry registry : forRegistries) { + boolean modified = unlockRegistry(registry, value); + if (modified) { + registry.setUpdated(Instant.now()); + registryTxImdg.update(registry); + nUpdates++; + log.trace("Registry {} (registryCode={}) changed; value +- {}", + registry.getId(), registry.getRegistryCode(), value); + } + } + log.info("Updated {} registry's (under transaction {}", nUpdates, tx); + txOk = true; + } finally { + if (txOk) { + log.debug("Commit transaction {}.", tx); + tx.commitTransaction(); + } else { + log.info("Rollback transaction {}", tx); + tx.rollbackTransaction(); } } - //todo рекомендуется делать транзакцией. StageResult> res = new StageResult<>(null, true); res.setStageResult(forRegistries); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingRegistersOnOSPayload.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingRegistersOnOSPayload.java new file mode 100644 index 000000000..c09807ebb --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingRegistersOnOSPayload.java @@ -0,0 +1,5 @@ +package ru.spcex.clearing.session.stage.task; + +public class FormingRegistersOnOSPayload { + +} 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 deleted file mode 100644 index e0ddc15da..000000000 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/RegistryOnObligationsAndSettlementRequirementsPayload.java +++ /dev/null @@ -1,31 +0,0 @@ -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/task/UnlockResourcesPayload.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/UnlockResourcesPayload.java index 1b9525f23..fc16b5d2b 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/UnlockResourcesPayload.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/UnlockResourcesPayload.java @@ -12,8 +12,6 @@ public class UnlockResourcesPayload { */ private String sdfMode; - private Long sessionId; - /** * sDf04.c_acc_cred * sDf12.depoCodeSender @@ -46,13 +44,6 @@ public class UnlockResourcesPayload { } - public Long getSessionId() { - return sessionId; - } - - public void setSessionId(Long sessionId) { - this.sessionId = sessionId; - } public String getAccount() { return account; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/BalanceDimension.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/BalanceDimension.java new file mode 100644 index 000000000..8251c48a4 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/BalanceDimension.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum BalanceDimension implements IEnumKey { + MONY("MONY"), + PICS("PICS"), + ; + + private final String key; + + BalanceDimension(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ISide.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ISide.java new file mode 100644 index 000000000..4a5256b8b --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ISide.java @@ -0,0 +1,15 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public interface ISide { + boolean isBuy(); + boolean isSell(); + default boolean isOpposite(ISide other) { + return (isBuy() && other.isSell()) || (isSell() && other.isBuy()); + } + + static & IEnumKey & ISide> ISide parse(Class clazz, String key) { + return IEnumKey.getEnumByKey(clazz, key); + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MoneyFlowSide.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MoneyFlowSide.java index 1b1111295..b275279de 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MoneyFlowSide.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MoneyFlowSide.java @@ -2,7 +2,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; -public enum MoneyFlowSide implements IEnumKey { +public enum MoneyFlowSide implements IEnumKey, ISide { BUY("BUY"), SELL("SELL"), ; @@ -17,4 +17,15 @@ public enum MoneyFlowSide implements IEnumKey { public String getKey() { return key; } + + + @Override + public boolean isBuy() { + return equals(BUY); + } + + @Override + public boolean isSell() { + return equals(SELL); + } } 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 index dd948e3b9..451a06ef8 100644 --- 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 @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum RegistryStatus implements IEnumKey { - OK("OK"), + OK("OK"), PROC("PROC"), ; private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java index d33888a93..2efb0196d 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Side.java @@ -2,7 +2,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; -public enum Side implements IEnumKey { +public enum Side implements IEnumKey, ISide { BUY("B"), SELL("S"), ; @@ -17,4 +17,15 @@ public enum Side implements IEnumKey { public String getKey() { return key; } + + + @Override + public boolean isBuy() { + return equals(BUY); + } + + @Override + public boolean isSell() { + return equals(SELL); + } } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java index a544c3a45..4cbde8b72 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java @@ -251,6 +251,15 @@ public class ImdgHazelcast implements Imdg { return searchResult; } + @Override + public T getSingleObjectByPredicate(ImdgPredicate predicate) { + Collection els = getCollectionObjectsByPredicate(predicate); + if (els.size() > 1) { + throw new RuntimeException("More than one element found by predicate - " + els.size()); + } + return els.iterator().next(); + } + @Override public ImdgPredicateBuilder predicateBuilder() { return ImdgPredicateBuilderHazelcast.instance(); diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java index 34e9ea3b1..e9d1d0380 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java @@ -68,4 +68,9 @@ public class ImdgTransactionProviderHazelcast implements ImdgTransaction { public void setHz(HazelcastInstance hz) { this.hz = hz; } + + @Override + public String toString() { + return "ImdgTransaction{" + (ctx == null ? null : ctx.getTxnId()) + "}"; + } } diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java index 68007e757..091dc44fa 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java @@ -101,6 +101,11 @@ public interface Imdg { throw new UnsupportedOperationException("not implemented getCollectionObjectsByPredicate"); } + // Predicate API + default T getSingleObjectByPredicate(ImdgPredicate predicate) { + throw new UnsupportedOperationException("not implemented getSingleObjectByPredicate"); + } + default ImdgPredicateBuilder predicateBuilder() { throw new UnsupportedOperationException("not implemented predicateBuilder API"); }