Compare commits

..

374 commits

Author SHA1 Message Date
ialbert
7c2ce48bd1 DM_X search: statuses PROC/MNG 2024-01-29 13:54:12 +03:00
ialbert
0fd9208e41 clearing-service changeStatusExtract => gateway without timeout
optional max-poll-interval-ms setting
2024-01-17 13:22:13 +03:00
ialbert
ab80d194a5 SDF57 cs_blocked to gateway DM_V 2024-01-12 13:12:53 +03:00
ialbert
6590d63026 cs_blocked при создании PaymentInstruction: для категории I ИЛИ V 2024-01-12 11:20:41 +03:00
ialbert
b96fcaae7d http://jira.mfd.msk:8088/browse/CLS-311 2024-01-11 15:33:27 +03:00
ialbert
517dc8669a http://jira.mfd.msk:8088/browse/CLS-311 2024-01-11 14:29:59 +03:00
ialbert
8df2442aa6 SDF06 DM*T.status condition OK/MNG => PROC/MNG 2024-01-10 17:24:38 +03:00
ialbert
c959023094 A**T openBalance null => 0 2023-12-20 11:58:23 +03:00
ialbert
54c3d7c235 >> SDF57 D**I -> OK && session present => AxxT.planned += DxxI.balance 2023-12-19 14:47:04 +03:00
AKurakin
892bdcb769 http://jira.mfd.msk:8088/browse/CLS-600 meta 2023-12-18 14:02:40 +03:00
ialbert
66ead14acb lim-exporter money DM*T settlement_date condition removed [2] 2023-12-18 12:34:18 +03:00
ialbert
072a5dbcd9 lim-exporter money DM*T settlement_date condition removed 2023-12-18 11:26:07 +03:00
ialbert
730ae2aba4 imdg application.properties 2023-12-15 17:29:54 +03:00
ialbert
5ad1b0d569 imdg settings: imdg.hazelcast.instance-name/imdg.hazelcast.db-sync-seconds/imdg.database.min-pool-size/imdg.database.max-pool-size 2023-12-15 17:12:59 +03:00
AKurakin
2a400e1a8a Merge branch 'tmpCLS-585' into dev 2023-12-15 16:29:44 +03:00
AKurakin
c8336ce8a4 http://jira.mfd.msk:8088/browse/CLS-585 уточнение получено 2023-12-15 16:29:11 +03:00
ialbert
08867e3cb9 http://jira.mfd.msk:8088/browse/CLS-603 2023-12-15 13:12:35 +03:00
akulikov
999b0999de http://jira.mfd.msk:8088/browse/CLS-602 (fix date format) 2023-12-15 10:06:00 +03:00
akulikov
038f676eef http://jira.mfd.msk:8088/browse/CLS-602 2023-12-14 12:17:12 +03:00
ialbert
c5a62a0bd4 removed mm2-prefixless-policy.jar 2023-12-13 15:25:56 +03:00
ialbert
ab34364a22 lim-exporter OPEN-BALANCE fix 2023-12-12 13:38:27 +03:00
akulikov
91b6f9efbc http://jira.mfd.msk:8088/browse/CLS-601 fixes 2023-12-12 10:45:33 +03:00
akulikov
9a279eead8 http://jira.mfd.msk:8088/browse/CLS-601 remove DM_X registry sessionId condition 2023-12-08 15:29:11 +03:00
akulikov
c5f79afb50 http://jira.mfd.msk:8088/browse/CLS-601 fix report test 2023-12-08 14:00:56 +03:00
akulikov
de9619376b registry-service fix, ImdgPredicateBuilder fix, RegistryCodeSqlBuilder fix dot 2023-12-08 13:53:12 +03:00
akulikov
0dd5cec12e http://jira.mfd.msk:8088/browse/CLS-601 2023-12-08 13:31:30 +03:00
etreschenkov
cd488b19d8 revert dot 2023-12-08 13:11:23 +03:00
etreschenkov
1ec2b25714 http://jira.mfd.msk:8088/browse/CLS-523 2023-12-08 13:07:24 +03:00
akulikov
8fe43dee98 http://jira.mfd.msk:8088/browse/CLS-599 2023-12-07 19:13:06 +03:00
akulikov
49b3191a63 http://jira.mfd.msk:8088/browse/CLS-599 2023-12-07 18:52:46 +03:00
akulikov
2a81e33b78 http://jira.mfd.msk:8088/browse/CLS-599 2023-12-07 17:27:56 +03:00
akulikov
313ff28cbd http://jira.mfd.msk:8088/browse/CLS-599 2023-12-07 13:19:11 +03:00
AKurakin
2656d6a78c db-scripts DATA_INITIAL.sql поправлен TRADING_CODE для СПВБ=001, транзитный счёт для бумаг SPCEX 2023-12-07 12:19:04 +03:00
ialbert
dc21de68f2 http://jira.mfd.msk:8088/browse/CLS-328 fix 2023-12-01 19:31:52 +03:00
ialbert
2c2cc64595 http://jira.mfd.msk:8088/browse/CLS-328 2023-12-01 19:27:45 +03:00
ialbert
17910bd224 http://jira.mfd.msk:8088/browse/CLS-328 2023-12-01 19:04:18 +03:00
ialbert
02e2b3a3f2 indexes for Registry map 2023-11-30 20:13:32 +03:00
ialbert
fe48b00464 ExecutionFond from s_trade log, clearing-service log pattern 2023-11-30 13:39:03 +03:00
ialbert
3f5fa0433f ExecutionFond#Quantity 2023-11-29 19:59:57 +03:00
ialbert
4e78439e54 ExecutionFond settlementAmount valuation for EQTY 2023-11-29 15:42:27 +03:00
ialbert
673bb48938 запросе сделок из тс, статус запроса (не отвисает кнопка на вебе) 2023-11-29 11:51:29 +03:00
ialbert
0dc90cf828 ExecutionFondComponent valuation flag added to logs 2023-11-28 12:43:28 +03:00
ialbert
afbe819255 changeStatusExtract gateway request 2023-11-28 11:56:51 +03:00
ialbert
9b8e68a94c Merge branch 'dev' into execution_and_deals_status
# Conflicts:
#	clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderV2.java
#	clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionAssets.java
2023-11-27 15:39:16 +03:00
etreshenkov
d5e764131d fix PlannerAllTodayMaker 2023-11-27 12:33:25 +03:00
AKurakin
793171b3da security-util UserRoleVerification поправил логи 2023-11-24 19:04:55 +03:00
AKurakin
4bcc725c26 meta 3.9.0.70 текст для couponPeriod 2023-11-24 17:57:35 +03:00
akulikov
2da0ac042c http://jira.mfd.msk:8088/browse/CLS-598 2023-11-24 17:12:48 +03:00
akulikov
99f4dbe292 http://jira.mfd.msk:8088/browse/CLS-597 fix 2023-11-23 18:58:01 +03:00
akulikov
4bd6dab4b1 http://jira.mfd.msk:8088/browse/CLS-597 fix 2023-11-23 18:11:13 +03:00
akulikov
e028aee516 http://jira.mfd.msk:8088/browse/CLS-597 2023-11-23 14:21:35 +03:00
ialbert
7641b2691c CS_BLKD 2023-11-22 19:07:06 +03:00
akulikov
970da463fc http://jira.mfd.msk:8088/browse/CLS-596 fixes 2023-11-22 15:28:18 +03:00
akulikov
5639f9ff8b http://jira.mfd.msk:8088/browse/CLS-596 fix after review 2023-11-22 15:19:41 +03:00
akulikov
8e948bc27a http://jira.mfd.msk:8088/browse/CLS-596 fix 2023-11-22 14:48:18 +03:00
akulikov
0b2bef797e http://jira.mfd.msk:8088/browse/CLS-596 2023-11-22 14:22:35 +03:00
ialbert
e04460b194 http://jira.mfd.msk:8088/browse/CLS-536 2023-11-21 17:21:16 +03:00
ialbert
0c00c7fdb3 PaymentInstruction grouping for securities 2023-11-21 17:09:08 +03:00
ialbert
494bafbe18 http://jira.mfd.msk:8088/browse/CLS-536 2023-11-21 16:25:31 +03:00
ialbert
4b1b6113f4 http://jira.mfd.msk:8088/browse/CLS-536 2023-11-21 16:25:10 +03:00
ialbert
53198ca9f5 Merge branch 'dev' into execution_and_deals_status 2023-11-20 14:08:05 +03:00
ialbert
3e6b8911c9 http://jira.mfd.msk:8088/browse/CLS-536 2023-11-20 14:07:45 +03:00
ialbert
1d4d831ea7 http://jira.mfd.msk:8088/browse/CLS-590 2023-11-20 13:07:52 +03:00
akulikov
085b0cf4ce http://jira.mfd.msk:8088/browse/CLS-497 KSRepTradesReportBuilder 2023-11-20 12:02:16 +03:00
akulikov
632bdf9e09 http://jira.mfd.msk:8088/browse/CLS-497 KSRepCashNettoReportBuilder 2023-11-20 11:17:53 +03:00
ialbert
866c063b0d http://jira.mfd.msk:8088/browse/CLS-590 2023-11-17 13:29:26 +03:00
ialbert
911c90bc45 Merge branch 'dev' into execution_and_deals_status 2023-11-16 18:08:10 +03:00
ialbert
8ae41b9d16 DS*I fix полей 2023-11-16 18:07:36 +03:00
ialbert
37a741e866 D**I fix полей open_balance/close_balance/plan_balance/created_at(new) 2023-11-16 18:07:36 +03:00
AKurakin
4a0df9bb48 dbf-importer swt-importer Забирать и обрабатывать файлы в порядке времени изменения на sftp (2)) 2023-11-16 16:29:53 +03:00
akulikov
939ea451a1 http://jira.mfd.msk:8088/browse/CLS-497 KSRepTrades 2023-11-16 16:16:35 +03:00
ialbert
ee0f95fcde http://jira.mfd.msk:8088/browse/CLS-591 2023-11-16 16:12:22 +03:00
akulikov
4581592380 http://jira.mfd.msk:8088/browse/CLS-497 KSRepCashNettoReport 2023-11-16 13:22:07 +03:00
akulikov
4e431ee798 http://jira.mfd.msk:8088/browse/CLS-497 KSRepTrades 2023-11-16 13:08:04 +03:00
AKurakin
10d8803651 dbf-importer swt-importer Забирать и обрабатывать файлы в порядке времени изменения на sftp 2023-11-16 12:43:44 +03:00
akulikov
fac5dca462 replace SUM and AGREEMENT_SETTLEMENT_DATE (KSCommissionTradesReport) 2023-11-16 11:58:30 +03:00
ialbert
06b38cc61f Merge branch 'dev' into execution_and_deals_status 2023-11-16 11:34:58 +03:00
AKurakin
4dfb642e1b platform-storage-api поправил RegistryCodeSqlBuilder для случая с множеством or параметров 2023-11-15 18:15:55 +03:00
ialbert
740c138ead http://jira.mfd.msk:8088/browse/CLS-536 DM*V создается для settlementDate == valueDate 2023-11-15 17:58:17 +03:00
akulikov
0d134db9c6 http://jira.mfd.msk:8088/browse/CLS-497 2023-11-15 17:26:30 +03:00
ialbert
deaa77a05c http://jira.mfd.msk:8088/browse/CLS-592 2023-11-15 16:47:16 +03:00
ialbert
c86f1e907a http://jira.mfd.msk:8088/browse/CLS-590
http://jira.mfd.msk:8088/browse/CLS-591
2023-11-15 16:46:36 +03:00
AKurakin
04bc8e9edf db-scripts http://jira.mfd.msk:8088/browse/CLS-594 разделение data.xml 2023-11-15 16:31:10 +03:00
ialbert
e8cba0467a http://jira.mfd.msk:8088/browse/CLS-592 2023-11-15 15:56:43 +03:00
AKurakin
9f988d34c0 swt-importer тест на RDC_KS_DF-20 2023-11-15 15:49:29 +03:00
AKurakin
3fbb5931df http://jira.mfd.msk:8088/browse/CLS-593 SDF02 в порядке SDF01 2023-11-15 11:53:09 +03:00
akulikov
15242a0a75 http://jira.mfd.msk:8088/browse/CLS-497 2023-11-14 14:40:17 +03:00
AKurakin
5cd8608584 meta fix 2023-11-13 16:58:50 +03:00
AKurakin
943ec5f762 http://jira.mfd.msk:8088/browse/CLS-585 todo уточнить задание 2023-11-13 16:51:36 +03:00
ialbert
20f6c6a939 mm2-prefixless-policy.jar настройка для репликации кафки 2023-11-13 16:29:00 +03:00
AKurakin
9e9a801bde http://jira.mfd.msk:8088/browse/CLS-497 2023-11-13 15:50:38 +03:00
akulikov
a8386a9ed9 http://jira.mfd.msk:8088/browse/CLS-497 2023-11-10 19:13:26 +03:00
akulikov
fd25105fe8 http://jira.mfd.msk:8088/browse/CLS-497 2023-11-09 17:12:59 +03:00
AKurakin
858e02084b http://jira.mfd.msk:8088/browse/CLS-586 meta / data 3.9.0.68 2023-11-09 16:27:53 +03:00
ialbert
eb3bed4a1d http://jira.mfd.msk:8088/browse/CLS-479 2023-11-09 15:03:25 +03:00
ialbert
8079ec1fb3 http://jira.mfd.msk:8088/browse/CLS-388 2023-11-09 15:03:25 +03:00
ialbert
cc2f20de3c http://jira.mfd.msk:8088/browse/CLS-584 2023-11-09 15:03:25 +03:00
ialbert
145d3f4c74 kill session command 2023-11-09 15:03:25 +03:00
akulikov
e6ede79021 http://jira.mfd.msk:8088/browse/CLS-497 2023-11-09 14:59:21 +03:00
AKurakin
a2ebfd945b backend-api update meta 3.9.0.67 2023-11-09 11:30:53 +03:00
akulikov
c7ad0a181c http://jira.mfd.msk:8088/browse/CLS-497 2023-11-08 15:47:30 +03:00
etreschenkov
12ff85188f http://jira.mfd.msk:8088/browse/CLS-582 2023-11-04 16:22:33 +03:00
etreschenkov
9c827763de http://jira.mfd.msk:8088/browse/CLS-523 2023-11-06 17:13:38 +03:00
etreschenkov
59d0b000d1 http://jira.mfd.msk:8088/browse/CLS-481 2023-11-06 16:26:27 +03:00
etreshenkov
60e7c6ac39 http://jira.mfd.msk:8088/browse/CLS-522 2023-11-03 13:16:28 +03:00
AKurakin
9b26fb2290 backend-api update meta 3.9.0.65 (fix shortname) 2023-11-02 12:53:44 +03:00
AKurakin
81c4c9fa99 db-scripts обавлен GRANT ALL PRIVILEGES ON TABLE * TO clearing; теперь так в апдейтах также надо писать 2023-11-02 12:03:41 +03:00
AKurakin
9ac71532f7 backend-api update meta 3.9.0.65 2023-11-02 11:44:45 +03:00
AKurakin
79eaffbda6 db-scripts http://jira.mfd.msk:8088/browse/CLS-581 2023-11-01 17:33:51 +03:00
akulikov
8deebfafbb http://jira.mfd.msk:8088/browse/CLS-497 2023-11-01 16:02:44 +03:00
AKurakin
31de64e5bb account-service http://jira.mfd.msk:8088/browse/CLS-577 улучшил текст валидации 2023-11-01 13:57:02 +03:00
AKurakin
afeede8baa backend-api http://jira.mfd.msk:8088/browse/CLS-576 meta 2023-11-01 12:39:48 +03:00
AKurakin
286b3ace2c account-service http://jira.mfd.msk:8088/browse/CLS-577 DATA.sql добавил ошибку 5025 2023-11-01 12:30:50 +03:00
akulikov
2f54dcaccf http://jira.mfd.msk:8088/browse/CLS-497 2023-11-01 12:08:42 +03:00
AKurakin
bcb4307acd account-service http://jira.mfd.msk:8088/browse/CLS-576 улучшил валидацию 2023-11-01 10:31:48 +03:00
AKurakin
0bc0f9461f backend-api http://jira.mfd.msk:8088/browse/CLS-576 добавил тест 2023-10-31 19:01:49 +03:00
AKurakin
681e612bbd backend-api http://jira.mfd.msk:8088/browse/CLS-580 добавил log-warning при отсутствии настроек 2023-10-31 19:01:49 +03:00
akulikov
b5b204bf5f http://jira.mfd.msk:8088/browse/CLS-497 2023-10-31 18:56:12 +03:00
AKurakin
a2dcd21867 account-service http://jira.mfd.msk:8088/browse/CLS-577, imdg http://jira.mfd.msk:8088/browse/CLS-575 добавил AccountSymbolsUpdate в UpdateMapService.java 2023-10-31 17:30:15 +03:00
akulikov
9eff119ff2 http://jira.mfd.msk:8088/browse/CLS-497 part 2 2023-10-31 16:45:14 +03:00
etreshenkov
2a61062eb9 http://jira.mfd.msk:8088/browse/CLS-523 2023-10-31 15:39:41 +03:00
AKurakin
fba4a07513 backend-api http://jira.mfd.msk:8088/browse/CLS-577 AccountSymbols 2023-10-31 14:43:37 +03:00
AKurakin
7b24b1d6ab IMDG DDL http://jira.mfd.msk:8088/browse/CLS-575 DDL 3.9 2023-10-31 14:39:25 +03:00
akulikov
e7c48f17e6 http://jira.mfd.msk:8088/browse/CLS-497 part 1 2023-10-31 10:55:48 +03:00
psemenkov
520233356b add logs 2023-10-30 15:44:06 +03:00
etreschenkov
68a1a4d9d9 http://jira.mfd.msk:8088/browse/CLS-523 2023-10-25 17:26:38 +03:00
psemenkov
3437106728 Поправил тесты. Скопировал реализацию недостающих методов для транзакционного ImdgTransactionalHazelcast из ImdgHazelcast. 2023-10-25 10:54:46 +03:00
AKurakin
a3d2726b23 IMDG http://jira.mfd.msk:8088/browse/CLS-572 добавил настройку backup-count 2023-10-24 11:41:57 +03:00
AKurakin
269a74960b test-api-clearing http://git.mfd.msk/mfd/clearing/-/issues/31 Перенёс в отдельный git-репо 2023-10-21 16:58:37 +03:00
AKurakin
0befdfab92 imdg log info чтобы знать состояние кластера: Initialized new cluster connection between... Members {size:2, ver:2} ... 2023-10-19 17:23:41 +03:00
etreschenkov
90aba79ded http://jira.mfd.msk:8088/browse/CLS-562 2023-10-18 15:07:31 +03:00
etreschenkov
02c768d273 Merge branch 'imdg_hist' into dev 2023-10-18 13:39:41 +03:00
etreschenkov
657a3e79eb http://jira.mfd.msk:8088/browse/CLS-522 2023-10-18 13:37:43 +03:00
etreschenkov
41ce70416c http://jira.mfd.msk:8088/browse/CLS-522 2023-10-18 12:04:27 +03:00
ialbert
63d0a12f55 http://jira.mfd.msk:8088/browse/CLS-523 conditions fix 2023-10-17 16:04:00 +03:00
ialbert
488f7f999b http://jira.mfd.msk:8088/browse/CLS-523 2023-10-17 15:13:09 +03:00
ialbert
d0a359a97e http://jira.mfd.msk:8088/browse/CLS-523 removed unnecessary methods 2023-10-17 15:09:17 +03:00
ialbert
5023e922cf http://jira.mfd.msk:8088/browse/CLS-523 2023-10-17 13:48:37 +03:00
ialbert
205386d78a http://jira.mfd.msk:8088/browse/CLS-523 imdg-hist 2023-10-17 11:43:33 +03:00
etreshenkov
a048a46bf6 add search mapstores 2023-10-16 18:22:02 +03:00
AKurakin
55c8486507 registry-service http://jira.mfd.msk:8088/browse/CLS-280 2023-10-16 10:34:54 +03:00
ialbert
6887b627c7 imdg-hist example 2 2023-10-13 19:30:04 +03:00
etreschenkov
1d36a64dd5 add history mapstores 2023-10-13 16:57:56 +03:00
ialbert
86a76a4488 history example controller 2023-10-13 16:44:28 +03:00
ialbert
039f1f8510 imdg-hist example 2023-10-13 16:35:11 +03:00
AKurakin
e8895ebd84 registry-service http://jira.mfd.msk:8088/browse/CLS-280 2023-10-13 15:05:51 +03:00
AKurakin
39b1b25c80 registry-service http://jira.mfd.msk:8088/browse/CLS-280 2023-10-13 13:41:13 +03:00
AKurakin
e7ac9a8784 registry-service http://jira.mfd.msk:8088/browse/CLS-280 2023-10-12 17:42:49 +03:00
AKurakin
f4f313a1ce data fix tradingClearingRegistryType 2023-10-12 15:15:23 +03:00
aalehin
e4c362db00 http://jira.mfd.msk:8088/browse/CLS-280
---
ExecutionRegisterServiceTest fix up related to new technical requirement
2023-10-12 13:19:35 +03:00
aalehin
846a364164 http://jira.mfd.msk:8088/browse/CLS-280
---
MoneyPaymentInstructionRegisterServiceTest fix up related to new technical requirement
2023-10-12 12:00:38 +03:00
aalehin
6dece4c19f http://jira.mfd.msk:8088/browse/CLS-280
---
DepoPaymentInstructionRegisterServiceTest fix up related to new technical requirement
2023-10-12 11:54:32 +03:00
aalehin
113d0e0d65 http://jira.mfd.msk:8088/browse/CLS-280
---
registry service unit tests
2023-10-12 11:46:31 +03:00
AKurakin
03eb67f82e company-service http://jira.mfd.msk:8088/browse/CLS-538 2023-10-12 10:38:00 +03:00
etreschenkov
7b422acc4a add history mapstores 2023-10-11 21:44:02 +03:00
ialbert
4006c1f233 registry update by created TCR 2023-10-11 18:52:51 +03:00
akulikov
789f18181a fix KSRepCashRegistersReportBuilder, KSRepDepoRegistersReportBuilder 2023-10-11 16:19:41 +03:00
AKurakin
50ebdbacb9 registry-service http://jira.mfd.msk:8088/browse/CLS-280, поправил unit-тест 2023-10-11 13:23:55 +03:00
etreschenkov
ba438187e5 add history mapstores 2023-10-11 12:48:54 +03:00
AKurakin
894408354b test-api-clearing http://10.200.200.183:8701/ последние улучшение тестового модуля 2023-10-11 11:22:39 +03:00
AKurakin
3eaa2a9ac6 account-service, db-scripts http://jira.mfd.msk:8088/browse/CLS-569 2023-10-10 20:00:58 +03:00
ialbert
dc3ea5d48a http://jira.mfd.msk:8088/browse/CLS-311 2023-10-10 16:03:20 +03:00
akulikov
391384fab2 http://jira.mfd.msk:8088/browse/CLS-497 ksRepCashRegisters and ksRepDepoRegisters remove condition updatedAt == currentDay 2023-10-10 13:49:53 +03:00
ialbert
0b4c277ea0 http://jira.mfd.msk:8088/browse/CLS-568 2023-10-10 12:52:42 +03:00
AKurakin
98a2cf46d2 lim-exporter CLS-262 поправил 2 из 3 тестов 2023-10-09 16:28:08 +03:00
AKurakin
38dab80e99 lim-exporter http://jira.mfd.msk:8088/browse/CLS-262 2023-10-09 15:23:35 +03:00
AKurakin
aa1e5f7ac1 test-api-clearing issues/31 поправил перезагрузку данных с битыми MapStore 2023-10-09 13:07:31 +03:00
etreschenkov
6f04b15527 http://jira.mfd.msk:8088/browse/CLS-262 2023-10-06 17:57:12 +03:00
etreschenkov
0522b3a562 http://jira.mfd.msk:8088/browse/CLS-262 2023-10-06 14:26:50 +03:00
aalehin
76a1b74c4b http://jira.mfd.msk:8088/browse/CLS-280
---
1 and 2 bullet points
2023-10-06 11:31:07 +03:00
etreschenkov
53810fd4f1 http://jira.mfd.msk:8088/browse/CLS-280 [5] 2023-10-06 11:27:37 +03:00
etreshenkov
723f177c25 http://jira.mfd.msk:8088/browse/CLS-562 2023-10-05 19:31:54 +03:00
etreshenkov
5fd85852bb http://jira.mfd.msk:8088/browse/CLS-565 2023-10-05 18:26:23 +03:00
etreshenkov
1af852e09c http://jira.mfd.msk:8088/browse/CLS-566 2023-10-05 18:26:22 +03:00
ialbert
7e2e9dcd51 NotificationSender objectType
Sdf57/Sdf01 revise notification comment & objectType
PaymentStateMarkService valueDate/settlementDate conditions
AnltSearcher comment TCR 12 symbols
planBalance revise notification comment
session step 7 fix
session step 5 gateway request only for OK groups
session step 5 deposit return A**B change on receiver side
clearingDate today on POOL
PaymentInstruction paymentPurpose fix
2023-10-05 17:40:26 +03:00
ialbert
7a359c1d98 Merge branch 'dev_release_04_10_2023' into dev 2023-10-05 17:33:19 +03:00
ialbert
ffe2134dfd return deposit contract condition
SettlementDate/ValueDate/RefundDate clone
2023-10-05 17:32:44 +03:00
ialbert
f905772251 execution fond status denied 2023-10-05 17:32:44 +03:00
ialbert
93951a3bf5 return deposit contract condition
SettlementDate/ValueDate/RefundDate clone
2023-10-05 14:41:35 +03:00
etreshenkov
0744364924 http://jira.mfd.msk:8088/browse/CLS-561 2023-10-05 12:12:13 +03:00
etreshenkov
64c174e806 http://jira.mfd.msk:8088/browse/CLS-566 2023-10-05 12:09:13 +03:00
etreshenkov
a4c4fe8c71 http://jira.mfd.msk:8088/browse/CLS-563 [2] 2023-10-05 11:55:43 +03:00
etreshenkov
98922dac8c http://jira.mfd.msk:8088/browse/CLS-559 // http://jira.mfd.msk:8088/browse/CLS-563 [1] 2023-10-05 11:54:57 +03:00
ialbert
815631d5d2 execution fond status denied 2023-10-04 19:16:04 +03:00
akulikov
98523cf528 http://jira.mfd.msk:8088/browse/CLS-497 rename property 2023-10-04 18:37:41 +03:00
akulikov
a9ef98f4da http://jira.mfd.msk:8088/browse/CLS-497 2023-10-04 18:11:48 +03:00
akulikov
c10e41b29e http://jira.mfd.msk:8088/browse/CLS-497 rename package 2023-10-04 18:11:47 +03:00
etreschenkov
1da3af6b7a http://jira.mfd.msk:8088/browse/CLS-559 2023-10-04 10:35:02 +03:00
ialbert
9e009307f4 SDF57 xdep time check -> restriction only for auto launch
сессия шаг 7 по возврату депозитов
2023-10-03 18:57:04 +03:00
akulikov
934b9babd3 http://jira.mfd.msk:8088/browse/CLS-497 2023-10-03 17:28:05 +03:00
AKurakin
b15334d8ac Merge branch 'dev' into tmp_testutil 2023-10-02 20:39:22 +03:00
AKurakin
d78105c3b7 test-api-clearing issues/31 интеграция тестового модуля к hazelcast как клиента (были ограничения), тестирование тестового модуля 2023-10-02 20:38:54 +03:00
akurakin
2b3571ec85 issues/31 подключил тестовые контроллеры к простому http api 2023-10-02 19:08:54 +03:00
akulikov
afdfa0d6d6 http://jira.mfd.msk:8088/browse/CLS-280 npe possible fix 2023-10-02 18:44:34 +03:00
ialbert
6d5e5fd00e split deposit contract index and parentId 2023-10-02 18:10:41 +03:00
akulikov
d2cf49b7c8 http://jira.mfd.msk:8088/browse/CLS-497 2023-10-02 17:09:48 +03:00
akulikov
e99311b582 http://jira.mfd.msk:8088/browse/CLS-497 2023-10-02 15:11:00 +03:00
ialbert
4da67d145d Merge branch 'dev_release' into dev 2023-10-02 14:11:13 +03:00
ialbert
5aca4dc82f SDF57 gateway request only when A**T.TradingClearingRegistry not empty 2023-10-02 12:56:17 +03:00
ialbert
49119bcabd IdentificationFundsValidationRule TCR search status 2023-10-02 11:22:05 +03:00
ialbert
e8bb442588 when account is ANLT TCR search fix status condition 2023-10-02 11:22:05 +03:00
ialbert
93080c76c9 IdentificationFundsValidationRule TCR search status 2023-10-02 11:17:24 +03:00
ialbert
553d829b4f when account is ANLT TCR search fix status condition 2023-10-02 11:13:31 +03:00
AKurakin
f36286e14b account-service http://jira.mfd.msk:8088/browse/CLS-553 account с типом INFO 2023-09-29 20:02:44 +03:00
ialbert
4f2daf06d8 Merge branch 'dev_release' into dev 2023-09-29 18:55:14 +03:00
ialbert
afc8fb0b54 session step 2 sort execution 2023-09-29 18:46:26 +03:00
ialbert
9382c6bb2c Merge remote-tracking branch 'origin/dev' into dev 2023-09-29 18:26:54 +03:00
ialbert
dd4cd2a314 AssetTBFProcessing verbose log
session 5 step return removed gateway request
2023-09-29 18:26:32 +03:00
akulikov
40978a0017 http://jira.mfd.msk:8088/browse/CLS-280 2023-09-29 18:18:16 +03:00
akulikov
9ed6a75fe5 http://jira.mfd.msk:8088/browse/CLS-280 2023-09-29 16:59:12 +03:00
ialbert
ef317a07a5 Merge branch 'dev_release' into dev 2023-09-29 16:23:07 +03:00
ialbert
6ec042bd30 фикс с обновлением dm*x
фикс с поиском ассетов и инструментом
и ipob отключение проверки planbalance
2023-09-29 16:22:41 +03:00
AKurakin
646c8c7e77 backend-api http://jira.mfd.msk:8088/browse/CLS-553 meta и обновление DATA.sql 2023-09-29 16:15:33 +03:00
AKurakin
ef972a593d registry-service http://jira.mfd.msk:8088/browse/CLS-280 сверка с ТЗ 2023-09-29 16:05:05 +03:00
AKurakin
e278bc1bb8 registry-service http://jira.mfd.msk:8088/browse/CLS-280 предварительная очистка мап перед вставкой; улучшил логи 2023-09-29 12:25:27 +03:00
AKurakin
36b0381294 registry-service todo описание 2023-09-28 19:11:41 +03:00
ialbert
5adeeec3f7 Merge remote-tracking branch 'origin/dev' into dev 2023-09-28 18:46:50 +03:00
AKurakin
a743de0dd1 company-service http://jira.mfd.msk:8088/browse/CLS-347 поправил валидацию 2023-09-28 18:45:20 +03:00
ialbert
7fa35d108d Merge branch 'plan_balance_dmx_dmt' into dev_try_merge
# Conflicts:
#	clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java
2023-09-28 18:12:25 +03:00
ialbert
11f6ea0b84 После зачисления с DMAU должно быть обращение в ТС
При DM_V поменять направление, затем закоментировать отправку в ТС.
2023-09-28 17:59:05 +03:00
ialbert
bd7f6ad460 Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-28 17:26:38 +03:00
ialbert
caeece00f3 SDF06 active session error 4 -> 1 2023-09-28 17:26:17 +03:00
ialbert
43911cbb58 TCR registry update, AM*F/AM*T/AM*B creation 2023-09-28 17:25:04 +03:00
AKurakin
252b89652d registry-service правки заполнения регистров 2023-09-28 17:04:36 +03:00
akulikov
4b089a91ae http://jira.mfd.msk:8088/browse/CLS-497 fix 2023-09-28 16:55:32 +03:00
AKurakin
c66df265d9 company-service http://jira.mfd.msk:8088/browse/CLS-347 bug fix, правки поиска 2023-09-28 16:05:04 +03:00
ialbert
90a2b858bb Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-28 15:17:14 +03:00
ialbert
c93e59c814 XDEP time interval
RequirementsAndObligationCreation execution match bugfix
2023-09-28 15:16:46 +03:00
mfd
1be10820a3 Added task SDEP - EDEP and errorCode for cancel XDEP 2023-09-28 14:36:51 +03:00
AKurakin
2ee26a3d68 company-service gateway-api http://jira.mfd.msk:8088/browse/CLS-347 bug fix, правки поиска 2023-09-28 14:22:32 +03:00
etreschenkov
fae7a37424 http://jira.mfd.msk:8088/browse/CLS-522 2023-09-28 14:19:26 +03:00
ialbert
96b5e90ebf Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-28 13:37:57 +03:00
AKurakin
8a2855e32b platform-messaging http://jira.mfd.msk:8088/browse/CLS-280 переделки, временно отключил проверку на дубликаты, т.к. надо добавить новое поле. 2023-09-28 13:21:29 +03:00
AKurakin
03aa29413c http://jira.mfd.msk:8088/browse/CLS-550 обратная совместимость 2023-09-28 11:41:49 +03:00
AKurakin
83ff343c92 http://jira.mfd.msk:8088/browse/CLS-550 улучшил лог. 2023-09-28 11:29:32 +03:00
akurakin
bf3ba4e6aa issues/31 перенос тестовых контроллеров в отдельный модуль (т.к. опасные функции) 2023-09-28 11:02:32 +03:00
AKurakin
4951559891 http://jira.mfd.msk:8088/browse/CLS-550 не доверять пользователю указывать свой userId, проставляется на бэкенде. 2023-09-28 10:28:09 +03:00
ialbert
4df7131630 DM*V creation for MEDM session 2023-09-27 18:39:35 +03:00
ialbert
e16767c15a Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-27 15:15:06 +03:00
AKurakin
1c9de78f5e http://jira.mfd.msk:8088/browse/CLS-500 изменена ошибка 5426 2023-09-27 15:13:22 +03:00
AKurakin
60cff01fe2 backend-api utility-service http://jira.mfd.msk:8088/browse/CLS-550 2023-09-27 13:14:05 +03:00
AKurakin
81456f3d2e dbf-exporter оставлять временные файлы (в папке export-dbf-service.store.local-temp-dir) 2023-09-27 11:06:52 +03:00
ialbert
f467b1062b PaymentInstructionOutboundService + search for anlt by contract
sdf57 session continue event fix
2023-09-26 19:13:24 +03:00
AKurakin
b9b3013b2d clearing-validation http://git.mfd.msk/mfd/clearing/-/issues/12 IMDGMessageResolver поправил при работе с некорректными текстами ошибок (когда кол-во аргументов не совпадает, выдаёт более человекочитаемый текст + warn 2023-09-26 16:00:09 +03:00
ialbert
b749839963 return deposit dm*x/dm*t 2023-09-26 15:06:22 +03:00
akulikov
0761de4b7e http://jira.mfd.msk:8088/browse/CLS-497 fix test 2023-09-26 13:57:35 +03:00
akulikov
f9c09aa792 http://jira.mfd.msk:8088/browse/CLS-497 fix 2023-09-26 13:54:24 +03:00
ialbert
9a074addcf Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-26 13:34:03 +03:00
ialbert
c201e850ce FINL/XDEP removed planned balance checked 2023-09-26 13:33:31 +03:00
ialbert
0961748a2a sdf57 session autostart fix awaiting sdfs
sdf57 dmau logic only for InOutDirection.in
identificationFunds dmau.debit/am_t.credit
2023-09-26 13:21:47 +03:00
ialbert
c940316494 RegistryService#returnDeposit validator imdg bugfix 2023-09-26 13:15:18 +03:00
ialbert
a80742af7d Merge branch 'dev' into plan_balance_dmx_dmt 2023-09-26 11:45:47 +03:00
ialbert
1a0601ba56 sdf57 bugfix contract not empty check 2023-09-26 11:45:00 +03:00
AKurakin
5cf9f6476e db-scripts обновил справочник sessionType id = 3 (code = XDEP) 2023-09-26 10:59:40 +03:00
AKurakin
0000a31942 db-scripts обновил справочник MARKET id = 82 (code = BBVC) 2023-09-25 17:54:43 +03:00
ialbert
fa45f6335b bugfix обновление регистров при создании ТКР
SDF57 specif -> contractr учитываются регистры со статусом MNG
2023-09-25 17:45:17 +03:00
ialbert
e40a8dc724 1. planBalance проставляется для 5 шага возврата депозитов
2. проверки, создание(обновление) dm_x -> dm_x/dm_t
2023-09-25 17:43:43 +03:00
AKurakin
155b899e5d account-service backend-api http://jira.mfd.msk:8088/browse/CLS-548 information-account-new теперь не нужен, вместо него используется account-new 2023-09-25 16:16:07 +03:00
akulikov
80fcb32abe http://jira.mfd.msk:8088/browse/CLS-497 2023-09-25 15:48:26 +03:00
AKurakin
db00bb906f account-service http://jira.mfd.msk:8088/browse/CLS-548 2023-09-25 12:15:48 +03:00
akulikov
f595f0f251 http://jira.mfd.msk:8088/browse/CLS-497 2023-09-25 12:04:39 +03:00
AKurakin
be311962cb imdg http://git.mfd.msk/mfd/clearing/-/issues/22 debug reload 2023-09-23 20:21:42 +03:00
AKurakin
91cc82f154 data добавил значение в словарь 2023-09-22 19:29:25 +03:00
AKurakin
5a4a1cbf56 imdg http://git.mfd.msk/mfd/clearing/-/issues/22 debug reload 2023-09-22 19:20:49 +03:00
AKurakin
248156c45d reports-service http://jira.mfd.msk:8088/browse/CLS-497 KSCommissionTradesReportBuilder 2023-09-22 19:09:09 +03:00
ialbert
0f5feb3c7e identification funds
refund date
sessions error after revision
2023-09-22 19:04:22 +03:00
AKurakin
633f34ee51 reports-service http://jira.mfd.msk:8088/browse/CLS-497 правки 2023-09-22 17:54:32 +03:00
AKurakin
ea0b8a74dd reports-service http://jira.mfd.msk:8088/browse/CLS-497 правки 2023-09-22 17:26:40 +03:00
AKurakin
53b71431ea reports-service http://jira.mfd.msk:8088/browse/CLS-497 KSRepCashRegisterSumsReportBuilder поправил парсинг человекочитаемого формата данных 2023-09-22 15:45:54 +03:00
AKurakin
57bbce07da reports-service http://jira.mfd.msk:8088/browse/CLS-497 улучшил логирование 2023-09-22 15:19:30 +03:00
AKurakin
bef57e096b reports-service http://jira.mfd.msk:8088/browse/CLS-497 ksCommisonTrades, ещё логов trace 2023-09-22 14:22:02 +03:00
AKurakin
0db32aac36 reports-service http://jira.mfd.msk:8088/browse/CLS-497 ksRepCashRegisterSums fix 2023-09-22 13:54:29 +03:00
mfd
2d7a1f452e Added error code to stop session when planningBalance do not equals balance 2023-09-22 13:50:32 +03:00
mfd
fa0b95ba5a Added error code to deny refund date changement 2023-09-22 13:34:30 +03:00
AKurakin
5b85844e5e reports-service http://jira.mfd.msk:8088/browse/CLS-497 ksRepCashRegisterSums 2023-09-22 12:39:56 +03:00
ialbert
334e01d02d SDF57 statement.contract 2023-09-21 18:57:35 +03:00
ialbert
e366b647cc registries/identificationFunds 2023-09-21 18:56:07 +03:00
AKurakin
69aa7aa047 platform-imdg-api-hazelcast-impl рефакторинг ожидания дожидания http://git.mfd.msk/mfd/clearing/-/issues/29 небольшое улучшение 2023-09-21 13:53:44 +03:00
AKurakin
565eb70988 platform-imdg-api-hazelcast-impl рефакторинг ожидания дожидания http://git.mfd.msk/mfd/clearing/-/issues/29 и в backend-api дожидание готовности перед работой RequestInfoAccepter 2023-09-21 13:31:17 +03:00
AKurakin
8c7c88c84f backend-api meta self-validation исключения без стектрейса & warning->info 2023-09-21 13:08:40 +03:00
AKurakin
06efab761d account-service company-service securities-service поправил валидацию словарей DictionaryPresentRule 2023-09-21 12:22:13 +03:00
AKurakin
3ba0611852 backend-api http://jira.mfd.msk:8088/browse/CLS-544 2023-09-21 10:57:40 +03:00
akulikov
488adfa605 http://jira.mfd.msk:8088/browse/CLS-497 2023-09-20 18:05:59 +03:00
ialbert
d9e2796185 SDF57 DM*T/DM*X запускают сессию по возвратам депозитов
перерасчет ассетов при проставлении ОК DM*V
2023-09-20 16:39:47 +03:00
ialbert
091dc2dc1d RegistryService#changeStatusExtract 2023-09-20 15:11:57 +03:00
mfd
7fe717be2b Added ERRORCODES 2023-09-20 13:20:45 +03:00
AKurakin
3756b73c34 z-distr поправил путь к meta.json 2023-09-20 13:03:05 +03:00
AKurakin
2a82fcc4ae account-service http://jira.mfd.msk:8088/browse/CLS-527 добавил логов 2023-09-20 12:50:34 +03:00
AKurakin
6a9867f477 account-service http://jira.mfd.msk:8088/browse/CLS-527 правки 2023-09-20 11:39:45 +03:00
AKurakin
6b7c41705c data, meta 3.8.0.54 2023-09-20 11:06:13 +03:00
ialbert
93ffe36ea6 SDF54/SDF55/SDF57 - D**I регистры 2023-09-19 18:17:31 +03:00
AKurakin
b19912f430 account-service http://jira.mfd.msk:8088/browse/CLS-527 обработка SDF52 2023-09-19 17:52:59 +03:00
AKurakin
a16fe442fa company-service http://jira.mfd.msk:8088/browse/CLS-538 CompanyRoleSet 2023-09-19 15:24:00 +03:00
AKurakin
e19cb6876e account-service http://jira.mfd.msk:8088/browse/CLS-527 2023-09-19 13:28:50 +03:00
AKurakin
f09b02b693 backend-api http://jira.mfd.msk:8088/browse/CLS-537 2023-09-19 11:26:03 +03:00
AKurakin
70e0c499ed backend-api http://jira.mfd.msk:8088/browse/CLS-540 up meta 3.8.0.52 2023-09-18 18:38:53 +03:00
AKurakin
195d6ac55b account-service http://jira.mfd.msk:8088/browse/CLS-509 поправил опечатки в валидаторе 2023-09-18 18:20:14 +03:00
AKurakin
9a97006dcb account-service utility-service http://jira.mfd.msk:8088/browse/CLS-527 DF52 ожидание акцепта пользователя через notification'sы 2023-09-18 17:45:56 +03:00
ialbert
eef8e8499a SDF55/PaymentInstructionOutboundService 2023-09-18 17:41:29 +03:00
ialbert
1deb4337cb InspectionObligations 5й шаг 2023-09-18 17:41:29 +03:00
ialbert
5b82083596 http://jira.mfd.msk:8088/browse/CLS-536 + InspectionObligations assets 2023-09-18 17:41:28 +03:00
akulikov
2db5bbc7c0 http://jira.mfd.msk:8088/browse/CLS-497?focusedCommentId=56715&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-56715 2023-09-18 14:43:14 +03:00
AKurakin
45008556ab account-service http://jira.mfd.msk:8088/browse/CLS-509 http://jira.mfd.msk:8088/browse/CLS-542 имя счетов уникальное между всеми типами (поправил для создания по sdf01-sdf08) 2023-09-18 12:46:04 +03:00
AKurakin
561ddd3b2d account-service http://jira.mfd.msk:8088/browse/CLS-509 http://jira.mfd.msk:8088/browse/CLS-542 валидация счетов 2023-09-18 12:23:22 +03:00
AKurakin
89b6567beb company-service http://jira.mfd.msk:8088/browse/CLS-541 зменил лог trace 2023-09-15 11:54:42 +03:00
AKurakin
bb0f836d3c company-service http://jira.mfd.msk:8088/browse/CLS-541 с пробелами тоже не пускать 2023-09-15 11:12:32 +03:00
AKurakin
29ecbb8956 company-service http://jira.mfd.msk:8088/browse/CLS-541 (bug fix 9dc45f2165) 2023-09-15 10:22:34 +03:00
etreschenkov
4d4e536154 fix gateway-api 2023-09-14 18:01:26 +03:00
AKurakin
425d5c4e13 imdg добавил индекс на Account 2023-09-14 17:00:13 +03:00
AKurakin
38333d5b95 account-service http://jira.mfd.msk:8088/browse/CLS-509 InformationAccount - их может быть много 2023-09-14 16:59:51 +03:00
AKurakin
4c287bfed8 backend-api http://jira.mfd.msk:8088/browse/CLS-534 meta 2023-09-14 16:19:21 +03:00
AKurakin
da22a11afe company-service http://jira.mfd.msk:8088/browse/CLS-509 редактирование CompanySymbol (частично rollback и исправил) 2023-09-14 13:51:26 +03:00
AKurakin
8b35c7d6c5 company-service http://jira.mfd.msk:8088/browse/CLS-509 редактирование CompanySymbol 2023-09-14 13:18:18 +03:00
AKurakin
9fb5303754 account-service http://jira.mfd.msk:8088/browse/CLS-509 validator bug fix 2023-09-14 13:02:30 +03:00
AKurakin
eccfb27efe account-service CLS-533 разрешение редактировать все счета (потому что только статус меняется) 2023-09-14 12:52:24 +03:00
AKurakin
9dc45f2165 company-service http://jira.mfd.msk:8088/browse/CLS-259 companyInfo реквест редактирует shortName/fullName 2023-09-14 10:46:30 +03:00
AKurakin
b7c7e8b358 backend-api http://jira.mfd.msk:8088/browse/CLS-534 2023-09-13 19:28:23 +03:00
etreschenkov
161d16e749 fix gateway-api 2023-09-13 18:35:56 +03:00
AKurakin
8fb0dd63f6 backend-api http://jira.mfd.msk:8088/browse/CLS-531 http://jira.mfd.msk:8088/browse/CLS-534 meta 2023-09-13 18:34:30 +03:00
ialbert
9c559b5c80 D**V registries 2023-09-13 17:35:55 +03:00
AKurakin
41d66b9e96 company-service securities-service http://jira.mfd.msk:8088/browse/CLS-454 поправил выдачу ошибок 2023-09-13 15:27:05 +03:00
AKurakin
2d08c7d589 dbf-exporter http://jira.mfd.msk:8088/browse/CLS-529 S_DF54 формат 2023-09-13 14:03:35 +03:00
ialbert
e2740347ba http://jira.mfd.msk:8088/browse/CLS-530 2023-09-13 13:46:23 +03:00
AKurakin
c5398c7a1d securities-service http://jira.mfd.msk:8088/browse/CLS-516 уникальность FixedIncomeCashFlow 2023-09-12 17:47:59 +03:00
AKurakin
9f32cd93a4 swt-importer fix test 2023-09-12 17:46:34 +03:00
AKurakin
9507dc10be swt-importer улучшил логи, добавил юнит тест 2023-09-12 17:32:21 +03:00
ialbert
21ec74df69 session not launched notification 2023-09-12 15:22:39 +03:00
ialbert
08271d7e36 GatewayRequester 5 шаг сессий 2023-09-12 14:01:52 +03:00
AKurakin
8cd1bda1ed backend-api http://jira.mfd.msk:8088/browse/CLS-512 meta порядок... снова... 2023-09-12 13:34:10 +03:00
AKurakin
d6e462f84f gateway-api securities-service http://jira.mfd.msk:8088/browse/CLS-516 2023-09-12 13:15:17 +03:00
AKurakin
a3ac454cb3 scheduler-service LauncherSender поправил передачу дополнительных параметров CLS-293 2023-09-12 11:20:06 +03:00
ialbert
b2d0d0c742 GatewayRequester 2023-09-11 20:04:28 +03:00
ialbert
6aa252f801 GatewayRequester 2023-09-11 20:04:28 +03:00
ialbert
71cb78b72c Sdf10Executor опечатка в логе
GatewayRequester исключение
2023-09-11 20:04:28 +03:00
ialbert
c4c2afe72c InspectionObligations GatewayRequester 2023-09-11 20:04:28 +03:00
AKurakin
66ab0cad31 backend-api http://jira.mfd.msk:8088/browse/CLS-525 meta счета... 2023-09-11 19:29:16 +03:00
AKurakin
2da6edd976 Revert "backend-api http://jira.mfd.msk:8088/browse/CLS-525 выдача некоторых Account по meta (составное поле)"
This reverts commit 8e73a2eced.
2023-09-11 19:04:01 +03:00
AKurakin
d4b9ee6ec5 backend-api http://jira.mfd.msk:8088/browse/CLS-525 meta fix GALB 2023-09-11 18:55:42 +03:00
etreshenkov
26f6c081f4 asset operation fields [gateway] 2023-09-11 17:04:27 +03:00
AKurakin
d95f22662d account-service http://jira.mfd.msk:8088/browse/CLS-489 SDF52 переделал поиск счетов 2023-09-11 16:58:34 +03:00
ialbert
4226df3e5c asset operation fields 2023-09-11 16:49:52 +03:00
AKurakin
14f6d5656b account-service http://jira.mfd.msk:8088/browse/CLS-509 InformationAccount 2023-09-11 16:11:55 +03:00
AKurakin
4ee335efd5 backend-api http://jira.mfd.msk:8088/browse/CLS-519 meta fix 2023-09-11 14:27:57 +03:00
AKurakin
44880a2b4b backend-api http://jira.mfd.msk:8088/browse/CLS-519 meta fix (поправил регистр атрибута shortname) 2023-09-11 13:30:26 +03:00
AKurakin
f0a090b00c gateway-api securities-service http://jira.mfd.msk:8088/browse/CLS-516 2023-09-11 12:55:57 +03:00
AKurakin
8e73a2eced backend-api http://jira.mfd.msk:8088/browse/CLS-525 выдача некоторых Account по meta (составное поле) 2023-09-08 19:12:20 +03:00
ialbert
d1b368d0b5 SDF20 inDocument NONREF fix, registries copying clearing_date/trading_date/created fix 2023-09-08 19:07:39 +03:00
AKurakin
174ee519d3 backend-api http://jira.mfd.msk:8088/browse/CLS-525 meta 2023-09-08 17:31:01 +03:00
AKurakin
c6df499058 backend-api http://jira.mfd.msk:8088/browse/CLS-510 meta InformationAccountNewRequest 2023-09-08 17:20:22 +03:00
ialbert
7a7468b9f2 SDF13 assets fix, SDF06 DM*T search status conditions 2023-09-08 17:14:16 +03:00
AKurakin
d06be93bc0 gateway-api и др. http://jira.mfd.msk:8088/browse/CLS-506 (отменчет правку по CLS-496) 2023-09-08 15:52:24 +03:00
etreschenkov
5c0c900f6b http://jira.mfd.msk:8088/browse/CLS-521 2023-09-08 15:39:25 +03:00
AKurakin
773e7133f3 backend-api http://jira.mfd.msk:8088/browse/CLS-524 http://jira.mfd.msk:8088/browse/CLS-519 поправил meta 3.8.0.48 2023-09-08 14:41:32 +03:00
AKurakin
065a1179ef account-service http://jira.mfd.msk:8088/browse/CLS-489 sdf52 2023-09-08 13:13:14 +03:00
AKurakin
ccdd38ad1a imdg http://jira.mfd.msk:8088/browse/CLS-520 RegistryMapStore 2023-09-08 12:14:52 +03:00
akulikov
5135ddcd99 http://jira.mfd.msk:8088/browse/CLS-497 2023-09-08 12:08:19 +03:00
ialbert
2a1dfad01b финальная МКР сессия фикс по блокировкам и проверке обязательств 2023-09-08 12:02:47 +03:00
ialbert
285f9b5188 sessions fix 2023-09-07 20:19:10 +03:00
ialbert
99e98f6a28 IPO0, FINL, MEDM 2023-09-07 19:36:23 +03:00
AKurakin
0e19218728 imdg http://jira.mfd.msk:8088/browse/CLS-517 ExecutionDepositMapStore 2023-09-07 18:06:29 +03:00
AKurakin
db06a05eda reports-service UnfulfilledDealReport поправил securityId (поправил тест) 2023-09-07 16:52:29 +03:00
AKurakin
b0dc6e6aa9 imdg http://jira.mfd.msk:8088/browse/CLS-517 ExecutionDepositMapStore 2023-09-07 16:49:26 +03:00
AKurakin
75233d560f reports-service UnfulfilledDealReport поправил securityId 2023-09-07 16:42:08 +03:00
AKurakin
13a45ff83a securities-service http://jira.mfd.msk:8088/browse/CLS-516 api-gateway 2023-09-07 16:06:11 +03:00
AKurakin
6ebc2dc2c6 gateway-api http://jira.mfd.msk:8088/browse/CLS-464 игнор без обязательных полей, вывод в log debug проигноренных 2023-09-07 16:05:05 +03:00
akulikov
54d2183b45 http://jira.mfd.msk:8088/browse/CLS-497 zone id fix 2023-09-07 13:57:13 +03:00
AKurakin
37885e9879 reports-service http://jira.mfd.msk:8088/browse/CLS-497 поправил временные зоны 2023-09-07 13:28:18 +03:00
akulikov
796f247fec http://jira.mfd.msk:8088/browse/CLS-497 time fixes, rename session_date, executionDealReport fixes 2023-09-07 12:22:28 +03:00
ialbert
1ee7c5a985 D**I 2023-09-07 11:12:51 +03:00
AKurakin
bb4fe2abe5 account-service http://jira.mfd.msk:8088/browse/CLS-489 sdf53 заполнение date 2023-09-07 10:06:52 +03:00
akulikov
f86accfa44 http://jira.mfd.msk:8088/browse/CLS-497 fix 2023-09-06 22:40:25 +03:00
akulikov
e93baadd04 http://jira.mfd.msk:8088/browse/CLS-497 fix log 2023-09-06 22:00:19 +03:00
akulikov
3ce2db798c http://jira.mfd.msk:8088/browse/CLS-497 some fixes 2023-09-06 21:22:14 +03:00
AKurakin
e1df8110a7 account-service http://jira.mfd.msk:8088/browse/CLS-489 sdf53 заполнение result 2023-09-06 19:44:56 +03:00
466 changed files with 16713 additions and 4755 deletions

View file

@ -0,0 +1,101 @@
package ru.spcex.clearing.account.config.validation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountSymbols;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
@Configuration
public class AccountSymbolsValidationConfig {
@Bean("accountSymbolsDepoNewRequest")
public Function<AccountSymbolsNewRequest, IValidator> accountSymbolsDepoNewRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return accountSymbolsNewRequest -> {
ImdgValidationContext<AccountSymbolsNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(accountSymbolsNewRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols);
return new ValidatorImpl<>(context,
IdPresentRule.instance("accountId",
AccountSymbolsNewRequest::getAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
true,
(Account account) -> {
if (AccountType.Depo.equalsByKey(account.getAccountType())) {
return null;
} else {
return AccountError.AccountDepoTypeRequired;
}
}
),
FieldNotBlankRequiredRule.instance("accountSymbolValue",
AccountSymbolsNewRequest::getAccountSymbolValue,
AccountError.RequiredFieldEmpty, true),
new DuplicateAccountSymbolsRule()
);
};
}
static class DuplicateAccountSymbolsRule implements IValidationRule<ImdgValidationContext<AccountSymbolsNewRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<AccountSymbolsNewRequest> context) {
AccountSymbolsNewRequest validatedObject = context.getValidatedObject();
Imdg<AccountSymbols> accountSymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
ImdgPredicateBuilder pb = accountSymbolsImdg.predicateBuilder();
ImdgPredicate query = pb.or(
pb.equals("accountId", validatedObject.getAccountId()),
pb.equals("accountSymbolValue", validatedObject.getAccountSymbolValue())
);
Collection<AccountSymbols> existAccSymbols = accountSymbolsImdg.getCollectionObjectsByPredicate(query);
if (existAccSymbols.isEmpty()) {
return empty();
} else {
AccountSymbols existAS = existAccSymbols.iterator().next();
String duplicateMsg = "";
if (validatedObject.getAccountId() != null && validatedObject.getAccountId().equals(existAS.getAccountId())) {
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account linkedAccount = accountImdg.getSingleObjectByID(existAS.getAccountId());
if (linkedAccount != null) {
duplicateMsg = linkedAccount.getAccount();
} else {
duplicateMsg = "" + existAS.getAccountId();
}
}
if (validatedObject.getAccountSymbolValue() != null &&
validatedObject.getAccountSymbolValue().equals(existAS.getAccountSymbolValue())) {
if (!duplicateMsg.isEmpty())
duplicateMsg += ", ";
duplicateMsg += existAS.getAccountSymbolValue();
}
return of(AccountError.AccountAlreadyExist, duplicateMsg);
}
}
}
}

View file

@ -18,12 +18,12 @@ import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -59,8 +59,14 @@ public class AccountValidationConfig {
),
FieldRequiredSpecificRule.instance("account",
CorrespondentAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty,
AccountError.AccountFieldNotSet,
false,
accountValue -> {
if ((accountValue == null || accountValue.isBlank()) && AccountType.Info.equalsByKey(context.getValidatedObject().getAccountType())) {
return null;
}
if (accountValue == null || accountValue.isBlank())
return new EnumMessage(AccountError.AccountFieldNotSet, "account");
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);
@ -77,22 +83,30 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
false,
statusValue -> {
if (ServiceStatus.Active.equalsByKey(statusValue.getCode())) return null;
return AccountError.WrongFieldValue;
}),
AccountError.DictionaryNotFound,
false
// , statusValue -> {
// if (ServiceStatus.Active.equalsByKey(statusValue.getCode())) return null;
// return AccountError.WrongFieldValue;
// }
),
DictionaryPresentRule.instance("accountType",
CorrespondentAccountNewRequest::getAccountType,
IMDGDistributedNames.Map_AccountTypeDictionary,
AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
accountType -> {
if (AccountType.Corr.equalsByKey(accountType.getCode())) return null;
if (IEnumKey.contains(accountType.getCode(), AccountType.Corr, AccountType.Info)) return null;
return AccountError.WrongFieldValue;
})
}).withMessageDecorator((causeEmpty, errorCode, fieldName, fieldValue) -> {
if (errorCode == AccountError.WrongFieldValue)
return DictionaryPresentRule.FIELD_NOT_FOUND_DECORATOR_1.decorator(causeEmpty, errorCode, fieldName, fieldValue);
else
return DictionaryPresentRule.DICTIONARY_NOT_FOUND_DECORATOR_2.decorator(causeEmpty, errorCode, fieldName, fieldValue);
}
),
new SameAccountValidationRule<>(AccountType.Corr, CorrespondentAccountNewRequest::getAccount)
);
};
}
@ -133,18 +147,20 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false),
DictionaryPresentRule.instance("accountType",
CorrespondentAccountUpdateRequest::getAccountType,
IMDGDistributedNames.Map_AccountTypeDictionary,
AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
accountType -> {
if (AccountType.Corr.equalsByKey(accountType.getCode())) return null;
return AccountError.WrongFieldValue;
})
AccountError.DictionaryNotFound,
false
// accountType -> {
// if (AccountType.Corr.equalsByKey(accountType.getCode())) return null;
// return AccountError.WrongFieldValue;
// }
)
);
};
}

View file

@ -13,6 +13,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewReq
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
@ -20,10 +21,7 @@ import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
@ -58,30 +56,17 @@ public class BankAccountValidationConfig {
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound,
false),
FieldRequiredSpecificRule.instance("account",
FieldNotBlankRequiredRule.instance("account",
BankAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty,
accountValue -> {
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate accountValuePredicate = pb.equals("account", accountValue);
ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey());
ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Bank.getKey());
ImdgPredicate finalPredicate = pb.and(accountValuePredicate,
accountStatusPredicate,
accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null;
return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}),
AccountError.RequiredFieldEmpty
),
new SameAccountValidationRule<>(AccountType.Bank, BankAccountNewRequest::getAccount),
DictionaryPresentRule.instance("currency",
BankAccountNewRequest::getCurrency,
IMDGDistributedNames.Map_CurrencyCodeDictionary,
CurrencyCodeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue),
AccountError.DictionaryNotFound),
FieldRequiredRule.instance("bankIdentificationCode",
BankAccountNewRequest::getBankIdentificationCode,
AccountError.RequiredFieldEmpty),
@ -93,7 +78,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};
@ -133,7 +118,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_CurrencyCodeDictionary,
CurrencyCodeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -11,6 +11,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
@ -21,7 +22,6 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -55,36 +55,22 @@ public class ClearingAccountValidationConfig {
AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
),
FieldRequiredSpecificRule.instance("account",
FieldNotBlankRequiredRule.instance("account",
ClearingAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty,
accountValue -> {
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate accountValuePredicate = pb.equals("account", accountValue);
ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey());
ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey());
ImdgPredicate finalPredicate = pb.and(accountValuePredicate,
accountStatusPredicate,
accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null;
return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}),
AccountError.RequiredFieldEmpty),
new SameAccountValidationRule<>(AccountType.Clrn, ClearingAccountNewRequest::getAccount),
DictionaryPresentRule.instance("clearingAccountType",
ClearingAccountNewRequest::getClearingAccountType,
IMDGDistributedNames.Map_ClearingAccountTypeDictionary,
ClearingAccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue),
AccountError.DictionaryNotFound),
DictionaryPresentRule.instance("status",
ClearingAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};
@ -108,6 +94,8 @@ public class ClearingAccountValidationConfig {
ClearingAccountUpdateRequest::getAccount,
AccountError.RequiredFieldEmpty,
accountValue -> {
if (accountValue.isBlank())
return AccountError.RequiredFieldEmpty;
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);

View file

@ -9,17 +9,14 @@ import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -52,24 +49,10 @@ public class DepoAccountValidationConfig {
AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
),
FieldRequiredSpecificRule.instance("account",
FieldNotBlankRequiredRule.instance("account",
DepoAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty,
accountValue -> {
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate accountValuePredicate = pb.equals("account", accountValue);
ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey());
ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey());
ImdgPredicate finalPredicate = pb.and(accountValuePredicate,
accountStatusPredicate,
accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null;
return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}),
AccountError.RequiredFieldEmpty),
new SameAccountValidationRule<>(AccountType.Depo, DepoAccountNewRequest::getAccount),
FieldRequiredRule.instance("depoAccountType",
DepoAccountNewRequest::getDepoAccountType,
AccountError.RequiredFieldEmpty),
@ -78,7 +61,7 @@ public class DepoAccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -2,20 +2,23 @@ package ru.spcex.clearing.account.config.validation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
@ -33,6 +36,9 @@ public class InformationAccountValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_InformationAccount);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_AccountTypeDictionary);
addImdg.accept(IMDGDistributedNames.Map_Account);
return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId",
InformationAccountNewRequest::getCompanyId,
@ -43,16 +49,17 @@ public class InformationAccountValidationConfig {
company -> {
if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))
return AccountError.CompanyNotActive;
Long companyId = company.getId();
Imdg<InformationAccount> informationAccountImdg = context.obtainMap(
IMDGDistributedNames.Map_InformationAccount, InformationAccount.class
);
Collection<InformationAccount> infoAccounts = informationAccountImdg.getCollectionObjectsByFieldValues(
Map.of("companyId", companyId)
);
if (infoAccounts.isEmpty()) return null;
return AccountError.InfoAccountAlreadyExist;
})
return null;
}),
FieldNotBlankRequiredRule.instance("account", InformationAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty),
DictionaryPresentRule.instance("status", InformationAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false),
DictionaryPresentRule.instance("accountType", InformationAccountNewRequest::getAccountType,
IMDGDistributedNames.Map_AccountTypeDictionary, AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false),
new SameAccountValidationRule<>(AccountType.Info, InformationAccountNewRequest::getAccount)
);
};
}

View file

@ -0,0 +1,46 @@
package ru.spcex.clearing.account.config.validation;
import ru.clearing.classes.statics.data.account.Account;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
class SameAccountValidationRule<R> implements IValidationRule<ImdgValidationContext<R>> {
final String accountType;
final Function<R, String> accountGetter;
public SameAccountValidationRule(AccountType accountType, Function<R, String> accountGetter) {
this.accountType = accountType.getKey(); // or req.getAccountType()
this.accountGetter = accountGetter;
Objects.requireNonNull(accountGetter);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R req = context.getValidatedObject();
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate query = pb.and(
pb.equals("account", accountGetter.apply(req)), // req.getAccount()
// pb.equals("accountType", accountType), имена всех счетов уникальны, вне зависимости от типа
pb.in("status", ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey(), ServiceStatus.Appl.getKey())
);
Account existAccount = accountImdg.getFirstObjectByPredicate(query);
if (existAccount != null) {
return of(AccountError.AccountAlreadyExist, existAccount.getAccount());
}
return empty();
}
}

View file

@ -124,7 +124,7 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false),
new newTCRDuplicateCheck()
);
@ -189,7 +189,7 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -41,6 +41,7 @@ public class ValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
//for ClientCodeValidationConfig
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);

View file

@ -21,6 +21,8 @@ public enum AccountError implements IErrorEnumId {
ClearingCategoryNotFound(5019L),
ClearingCompanySymbolNotFound(5022L), // Для компании %s отсутствует клиринговый код».
AccountForTradingClearingRegistryAlreadyUsed(5023L),
AccountFieldNotSet(5024L),
AccountDepoTypeRequired(5025L),
TradingClearingRegistryNotFound(3022L),
;

View file

@ -0,0 +1,106 @@
package ru.spcex.clearing.account.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
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.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import java.util.Collection;
@Service
public class AccountHelper {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<ClearingMemberCategory> clearingMemberCategoryMap;
private final Imdg<Relation> relationMap;
private final IMessageResolver messageResolver;
@Autowired
public AccountHelper(ImdgProvider imdgProvider,
IMessageResolver messageResolver) {
this.clearingMemberCategoryMap = imdgProvider.getImdg(
IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class
);
this.relationMap = imdgProvider.getImdg(
IMDGDistributedNames.Map_Relation, Relation.class
);
this.messageResolver = messageResolver;
}
/**
* Заполняет поля relationId и companyId из соответствующей записи Relation
*
* @param requestId Идентификатор запроса для вывода лога
*/
public RequestInfoUpdate fillAccountFromRelation(Account account, Long requestId, boolean checkClearingMemberCategory) {
Long companyId = account.getCompanyId();
Collection<Relation> relations;
ImdgPredicateBuilder relationPredicateBuilder = relationMap.predicateBuilder();
ImdgPredicate finalRelationPredicate;
if (checkClearingMemberCategory) {
ImdgPredicateBuilder clearingMemberCategoryPredicateBuilder = clearingMemberCategoryMap.predicateBuilder();
ImdgPredicate companyIdEquals = clearingMemberCategoryPredicateBuilder.equals("companyId", companyId);
Collection<ClearingMemberCategory> clearingMemberCategories = clearingMemberCategoryMap.getCollectionObjectsByPredicate(companyIdEquals);
if (clearingMemberCategories.isEmpty())
return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, "(any)");
if (clearingMemberCategories.size() > 1)
log.warn("ClearingMemberCategory for companyId {} contains multiply elements, use first", companyId);
ClearingMemberCategory clearingMemberCategory = clearingMemberCategories.iterator().next();
ImdgPredicate consumerIdPredicate = relationPredicateBuilder.equals("consumerId", companyId);
ImdgPredicate servicePredicate;
String clearingCategoryValue = clearingMemberCategory.getClearingMemberCategory();
if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.B, ClearingCategory.I, ClearingCategory.V)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.MKR.getKey());
} else if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.F, ClearingCategory.C)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.FOND.getKey());
} else {
log.info("ClearingCategoryNotFound with clearingCategoryValue={} not implemented. Do not search Relation.", clearingCategoryValue);
return null;
//return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, clearingCategoryValue + " (case not implemented)");
}
finalRelationPredicate = relationPredicateBuilder.and(consumerIdPredicate, servicePredicate);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
} else {
finalRelationPredicate = relationPredicateBuilder.equals("consumerId", companyId);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
}
if (relations.isEmpty()) {
//return makeError(requestId, AccountError.WrongFieldValue, "companyId", finalRelationPredicate.toString());
log.info("Relation not found: {}", finalRelationPredicate.toString());
return null;
}
if (relations.size() > 1)
log.warn("Relation for consumerId {} contains multiply elements, use first", companyId);
Relation relation = relations.iterator().next();
account.setRelationId(relation.getId());
return null;
}
public RequestInfoUpdate makeError(Long reqId, AccountError accountError, Object... args) {
String errMsg = messageResolver.resolve(new EnumMessage(accountError, args));
return new RequestInfoUpdate()
.setId(reqId)
.setStatus(Status.Error)
.setMessage(errMsg);
}
}

View file

@ -9,6 +9,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.spcex.clearing.account.errors.AccountError;
@ -17,22 +20,15 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountTerminationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
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.ImdgTransaction;
@ -44,9 +40,8 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@Service
@ -60,6 +55,8 @@ public class AccountService extends QueueConsumer implements InitializingBean {
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final AccountHelper accountHelper;
private final InformationAccountService informationAccountService;
private final Function<CorrespondentAccountNewRequest, IValidator> accountNewRequestValidator;
private final Function<CorrespondentAccountUpdateRequest, IValidator> accountUpdateRequestValidator;
private final Function<CommonIdRequest, IValidator> accountBlockRequestValidator;
@ -72,6 +69,8 @@ public class AccountService extends QueueConsumer implements InitializingBean {
IMessageResolver messageResolver,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
AccountHelper accountHelper,
InformationAccountService informationAccountService,
@Qualifier("correspondentAccountNewRequestValidator")
Function<CorrespondentAccountNewRequest, IValidator> accountNewRequestValidator,
@Qualifier("correspondentAccountUpdateRequestValidator")
@ -79,6 +78,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
@Qualifier("correspondentAccountBlockRequestValidator")
Function<CommonIdRequest, IValidator> accountBlockRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.accountHelper = accountHelper;
this.imdgProvider = imdgProvider;
this.accountMap = imdgProvider.getImdg(
IMDGDistributedNames.Map_Account, Account.class
@ -93,6 +93,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
this.messageResolver = messageResolver;
this.userRoleVerification = userRoleVerification;
this.validationHelper = validationHelper;
this.informationAccountService = informationAccountService;
this.accountNewRequestValidator = accountNewRequestValidator;
this.accountUpdateRequestValidator = accountUpdateRequestValidator;
this.accountBlockRequestValidator = accountBlockRequestValidator;
@ -133,6 +134,12 @@ public class AccountService extends QueueConsumer implements InitializingBean {
Account account = new Account();
account.setCompanyId(req.getCompanyId());
account.setAccount(req.getAccount());
if (AccountType.Info.equalsByKey(req.getAccountType())) {
Long infoSequenceId = informationAccountService.accountNextId();
String accountValue = informationAccountService.generateInfoAccount(infoSequenceId);
log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue);
account.setAccount(accountValue);
}
account.setAccountType(req.getAccountType());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
@ -143,14 +150,89 @@ public class AccountService extends QueueConsumer implements InitializingBean {
account.setCreated(now);
account.setUpdated(now);
requestInfoUpdate = fillAccountFromRelation(account, userRequest.getId(), false);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
if (requestInfoUpdate != null) return requestInfoUpdate;
Long newId = accountMap.insert(account);
Long newId = null;
if (AccountType.Corr.equalsByKey(account.getAccountType())) {
// default, дополнительные таблицы не требуются
newId = accountMap.insert(account);
} else {
// Транзакцией
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
imdgTransaction.beginTransaction();
boolean txOk = false;
try {
Imdg<Account> accountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
newId = accountMap.insert(account);
if (AccountType.Corr.equalsByKey(account.getAccountType())) {
// default, дополнительные таблицы не требуются
} else if (AccountType.Info.equalsByKey(account.getAccountType()))
makeInfoPart(imdgTransaction, account);
else if (AccountType.Depo.equalsByKey(account.getAccountType()))
makeDepoPart(imdgTransaction, account, req);
else if (AccountType.Clrn.equalsByKey(account.getAccountType()))
makeClrnPart(imdgTransaction, account);
else {
log.warn("Unexpected AccountType={}. Do not create additional record to other table's", account.getAccountType());
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed insert, new account id {} rollback", newId);
imdgTransaction.rollbackTransaction();
}
}
}
log.debug("successfully processed, new account id {}", newId);
return null;
}
protected void makeInfoPart(ImdgTransaction imdgTransaction, Account account) {
Imdg<InformationAccount> informationAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class);
InformationAccount infoAcc = new InformationAccount();
infoAcc.setAccountId(account.getId());
Account firstAccountAntl = accountMap.getFirstObjectByFieldValues(Map.of(
"companyId", Sender.One.getId(),
"accountType", AccountType.Anlt.getKey()
));
if (firstAccountAntl == null) {
log.warn("Can not find 1 ANTL account for fill information ClearingAccountId.");
} else {
infoAcc.setClearingAccountId(firstAccountAntl.getId());
}
infoAcc.setCompanyId(account.getCompanyId());
Long infoId = informationAccountMap.insert(infoAcc);
log.debug("For account id={} make InformationAccount id={}", account.getId(), infoId);
}
protected void makeDepoPart(ImdgTransaction imdgTransaction, Account account, CorrespondentAccountNewRequest req) {
Imdg<DepoAccount> depoAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
DepoAccount depoAcc = new DepoAccount();
depoAcc.setAccountId(account.getId());
depoAcc.setCompanyId(account.getCompanyId());
if (account.getAccount() != null && account.getAccount().contains("BC")) {
depoAcc.setDepoAccountType(DepoAccountType.C.getKey());
} else {
//todo в реквесте нет поля depoAcc.setDepoAccountType(req.getDepoAccountType());
}
Long depoId = depoAccountMap.insert(depoAcc);
log.debug("For account id={} make DepoAccount id={}", account.getId(), depoId);
}
protected void makeClrnPart(ImdgTransaction imdgTransaction, Account account) {
Imdg<ClearingAccount> clearingAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
ClearingAccount clnrAcc = new ClearingAccount();
clnrAcc.setAccountId(account.getId());
clnrAcc.setCompanyId(account.getCompanyId());
Long clrnId = clearingAccountMap.insert(clnrAcc);
log.debug("For account id={} make ClearingAccount id={}", account.getId(), clrnId);
}
public RequestInfoUpdate correspondentAccountUpdate(BaseRequest<CorrespondentAccountUpdateRequest> userRequest) {
log.debug("CorrespondentAccountUpdateRequest received");
@ -163,6 +245,10 @@ public class AccountService extends QueueConsumer implements InitializingBean {
CorrespondentAccountUpdateRequest request = userRequest.getRequestPayload();
Account account = accountMap.getSingleObjectByID(request.getId());
if (request.getAccountType() != null && !request.getAccountType().equals(account.getAccountType())) {
requestInfoUpdate = makeError(userRequest.getId(), AccountError.WrongFieldValue, "accountType");
return requestInfoUpdate;
}
if (request.getStatus() != null) account.setStatus(request.getStatus());
@ -237,60 +323,6 @@ public class AccountService extends QueueConsumer implements InitializingBean {
return null;
}
/**
* Заполняет поля relationId и companyId из соответствующей записи Relation
*
* @param requestId Идентификатор запроса для вывода лога
*/
public RequestInfoUpdate fillAccountFromRelation(Account account, Long requestId, boolean checkClearingMemberCategory) {
Long companyId = account.getCompanyId();
Collection<Relation> relations;
ImdgPredicateBuilder relationPredicateBuilder = relationMap.predicateBuilder();
ImdgPredicate finalRelationPredicate;
if (checkClearingMemberCategory) {
ImdgPredicateBuilder clearingMemberCategoryPredicateBuilder = clearingMemberCategoryMap.predicateBuilder();
ImdgPredicate companyIdEquals = clearingMemberCategoryPredicateBuilder.equals("companyId", companyId);
Collection<ClearingMemberCategory> clearingMemberCategories = clearingMemberCategoryMap.getCollectionObjectsByPredicate(companyIdEquals);
if (clearingMemberCategories.isEmpty())
return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, "(any)");
if (clearingMemberCategories.size() > 1)
log.warn("ClearingMemberCategory for companyId {} contains multiply elements, use first", companyId);
ClearingMemberCategory clearingMemberCategory = clearingMemberCategories.iterator().next();
ImdgPredicate consumerIdPredicate = relationPredicateBuilder.equals("consumerId", companyId);
ImdgPredicate servicePredicate;
String clearingCategoryValue = clearingMemberCategory.getClearingMemberCategory();
if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.B, ClearingCategory.I, ClearingCategory.V)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.MKR.getKey());
} else if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.F, ClearingCategory.C)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.FOND.getKey());
} else {
log.info("ClearingCategoryNotFound with clearingCategoryValue={} not implemented. Do not search Relation.", clearingCategoryValue);
return null;
//return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, clearingCategoryValue + " (case not implemented)");
}
finalRelationPredicate = relationPredicateBuilder.and(consumerIdPredicate, servicePredicate);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
} else {
finalRelationPredicate = relationPredicateBuilder.equals("consumerId", companyId);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
}
if (relations.isEmpty()) {
//return makeError(requestId, AccountError.WrongFieldValue, "companyId", finalRelationPredicate.toString());
log.info("Relation not found: {}", finalRelationPredicate.toString());
return null;
}
if (relations.size() > 1)
log.warn("Relation for consumerId {} contains multiply elements, use first", companyId);
Relation relation = relations.iterator().next();
account.setRelationId(relation.getId());
return null;
}
private RequestInfoUpdate makeError(Long reqId, AccountError accountError, Object... args) {
String errMsg = messageResolver.resolve(new EnumMessage(accountError, args));
return new RequestInfoUpdate()

View file

@ -0,0 +1,122 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.*;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.util.function.Function;
@Service
public class AccountSymbolsService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ValidationHelper validationHelper;
private final UserRoleVerification userRoleVerification;
private final ImdgProvider imdgProvider;
private final Imdg<AccountSymbols> accountSymbolsImdg;
private final RequestHelper requestHelper;
private final Function<AccountSymbolsNewRequest, IValidator> accountSymbolsNewRequestValidator;
private final IMessageResolver messageResolver;
private final Producer<String, Object> kafkaProducer;
private final KafkaSender kafkaSender;
public AccountSymbolsService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaSender,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
IMessageResolver messageResolver,
RequestHelper requestHelper,
@Qualifier("accountSymbolsDepoNewRequest")
Function<AccountSymbolsNewRequest, IValidator> accountSymbolsNewRequestValidator
) {
super(kafkaQueue, kafkaProducer);
this.kafkaProducer = kafkaProducer;
this.kafkaSender = kafkaSender;
this.validationHelper = validationHelper;
this.userRoleVerification = userRoleVerification;
this.requestHelper = requestHelper;
this.imdgProvider = imdgProvider;
this.accountSymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
this.accountSymbolsNewRequestValidator = accountSymbolsNewRequestValidator;
this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() throws Exception {
imdgProvider.waitAvailable();
callback(AccountSymbolsNewRequest.class)
.setFunction(this::accountSymbolsNew)
.forDestination(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW, callbacks::put);
callback(CommonIdRequest.class)
.setFunction(this::accountSymbolsDelete)
.forDestination(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE, callbacks::put);
init();
}
protected RequestInfoUpdate accountSymbolsNew(BaseRequest<AccountSymbolsNewRequest> userRequest) {
log.debug("AccountSymbolsNewRequest received, id={}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, accountSymbolsNewRequestValidator);
if (requestInfoUpdate != null) return requestInfoUpdate;
AccountSymbolsNewRequest req = userRequest.getRequestPayload();
Long id = accountSymbolsImdg.nextIDSequenceFor();
AccountSymbols accountSymbols = new AccountSymbols();
accountSymbols.setId(id);
accountSymbols.setAccountId(req.getAccountId());
accountSymbols.setAccountSymbolValue(req.getAccountSymbolValue());
accountSymbolsImdg.insert(accountSymbols);
log.debug("successfully processed, id {}. New accountSymbols.id={} was created", id, accountSymbols.getId());
return null;
}
protected RequestInfoUpdate accountSymbolsDelete(BaseRequest<CommonIdRequest> userRequest) {
log.debug("AccountSymbolsDeleteRequest(CommonIdRequest) received, id={}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
CommonIdRequest req = userRequest.getRequestPayload();
AccountSymbols accountSymbols = accountSymbolsImdg.getSingleObjectByID(req.getId());
if (accountSymbols == null) {
return requestHelper.makeErrorResponse(userRequest, AccountError.AccountNotFound, req.getId());
}
accountSymbolsImdg.delete(accountSymbols);
log.debug("successfully processed, id {}. New accountSymbols.id={} was deleted", userRequest.getId(), accountSymbols.getId());
return null;
}
}

View file

@ -41,7 +41,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final AccountService accountService;
private final AccountHelper accountService;
private final Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator;
private final Function<BankAccountUpdateRequest, IValidator> bankAccountUpdateRequestValidator;
@ -53,7 +53,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
ImdgProvider imdgProvider,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
AccountService accountService,
AccountHelper accountService,
@Qualifier("bankAccountNewRequestValidator")
Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator,
@Qualifier("bankAccountUpdateRequestValidator")

View file

@ -15,7 +15,10 @@ import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.misc.Notification;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf52;
import ru.clearing.platform.dictionary.ClearingCategoryDictionary;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
@ -26,6 +29,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf0
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationFeedbackRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
@ -40,19 +46,21 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.collection.Pair;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@Service
public class ClearingAccountService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private final AccountService accountService;
private final AccountHelper accountService;
private final SDFProcessService sdfProcessService;
private final ValidationHelper validationHelper;
private final ImdgProvider imdgProvider;
@ -62,15 +70,19 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
private final Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator;
private final Imdg<Account> accountImdg;
private final Imdg<ClearingAccount> clearingAccountImdg;
private final Imdg<Company> companyImdg;
private final Imdg<Relation> relationImdg;
private final Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
private final Imdg<ClearingCategoryDictionary> clearingCategoryImdg;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Notification> notificationImdg;
@Autowired
public ClearingAccountService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaResponseQueue,
KafkaSender kafkaSender,
AccountService accountService,
AccountHelper accountService,
SDFProcessService sdfProcessService,
ValidationHelper validationHelper,
ImdgProvider imdgProvider,
@ -92,9 +104,13 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
this.clearingAccountUpdateRequestValidator = clearingAccountUpdateRequestValidator;
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
this.clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingCategoryDictionary, ClearingCategoryDictionary.class);
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.notificationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Notification, Notification.class);
}
@Override
@ -108,9 +124,13 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
callback(AccountSdf01Request.class)
.setFunction(this::accountNewSdf01)
.forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put);
callback(StatementRequest.class)
.setFunction(this::accountUpdateSdf52)
.forDestination(Consts.ACCOUNT_PROCESS_SDF52, callbacks::put);
callback(NotificationFeedbackRequest.class)
.setFunction(this::accountUpdateSdf52_part2Notification)
.forDestination(Consts.ACCOUNT_NOTIFICATION_FEEDBACK, callbacks::put);
init();
}
@ -253,7 +273,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
}
}
if (accountImdg.getFirstObjectBySQL("accountType = '%s' and account = '%s'".formatted(AccountType.Clrn.getKey(), accountReq.getAccount())) != null) {
if (accountImdg.getFirstObjectBySQL("account = '%s'".formatted(accountReq.getAccount())) != null) {
log.debug("Account {} already exists", accountReq.getAccount());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
@ -302,21 +322,6 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
return null;
}
String serviceTypeByCMCOfCompany(Long companyId) {
Collection<ClearingMemberCategory> cmCategorys = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(
Map.of("companyId", companyId));
String serviceType = null;
for (ClearingMemberCategory cmc : cmCategorys) {
if (IEnumKey.contains(cmc.getClearingMemberCategory(), ClearingCategory.B, ClearingCategory.I, ClearingCategory.V)) {
serviceType = ru.spcex.platform.enumeration.Service.MKR.getKey();
}
if (IEnumKey.contains(cmc.getClearingMemberCategory(), ClearingCategory.F, ClearingCategory.C)) {
serviceType = ru.spcex.platform.enumeration.Service.MKR.getKey();
}
}
return serviceType;
}
public RequestInfoUpdate accountUpdateSdf52(BaseRequest<StatementRequest> systemRequest) {
log.debug("accountUpdateSdf52 StatementRequest received, id={}", systemRequest.getId());
@ -340,86 +345,161 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
if (sdfProcessService.parseSdf52Status(sDf52.getStatus()) == null) {
String msg = messageResolver.resolve(new EnumMessage(AccountError.WrongFieldValue, "status"));
log.warn("By generationId={} s_df52[{}] error: {}", groupId, sDf52.getId(), msg);
toProcessSDF53.add(new MutableTriple<>(sDf52, null, SDFProcessService.SDF_STATUS_ERROR));
toProcessSDF53.add(new MutableTriple<>(sDf52, null,
makeSdfErrorText(AccountError.WrongFieldValue, SDFProcessService.SDF_STATUS_ERROR)));
continue;
}
Company company = sDf52.getDeal() == null ? null : companyImdg.getSingleObjectByFieldValues(Map.of("tradingCode", sDf52.getDeal()));
if (company == null) {
String msg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotFound, sDf52.getDeal()));
log.warn("By generationId={} s_df52[{}] error: {}", groupId, sDf52.getId(), msg);
toProcessSDF53.add(new MutableTriple<>(sDf52, null, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND));
toProcessSDF53.add(new MutableTriple<>(sDf52, null,
makeSdfErrorText(AccountError.CompanyNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND)));
continue;
}
String serviceType = serviceTypeByCMCOfCompany(company.getId());
Relation relation = serviceType == null ? null : relationImdg.getSingleObjectByFieldValues(Map.of(
"consumerId", company.getId(),
"service", serviceType
));
if (relation == null) {
String msg = messageResolver.resolve(new EnumMessage(AccountError.ClearingCategoryNotFound, company.getTradingCode(), serviceType));
log.warn("By generationId={} s_df52[{}] error: {}", groupId, sDf52.getId(), msg);
toProcessSDF53.add(new MutableTriple<>(sDf52, null, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND));
continue;
}
Account account = sDf52.getAccount() == null ? null : accountImdg.getFirstObjectByFieldValues(Map.of(
Map<String, Comparable<?>> accountQuery = Map.of(
"accountType", AccountType.Clrn.getKey(),
"account", sDf52.getAccount(),
"relationId", relation.getId()
));
"companyId", company.getId()
);
Account account = sDf52.getAccount() == null ? null : accountImdg.getFirstObjectByFieldValues(accountQuery);
if (account == null) {
String msg = messageResolver.resolve(new EnumMessage(AccountError.AccountNotFound, sDf52.getAccount()));
log.warn("By generationId={} s_df52[{}] error: {}", groupId, sDf52.getId(), msg);
toProcessSDF53.add(new MutableTriple<>(sDf52, null, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND));
continue;
if (SDFProcessService.SDF52_STATUS_3Open.equals(sDf52.getStatus())) {
log.debug("By generationId={} s_df52[{}].status={}, but account not found (query: {}). COntinuse with result OK for status 3",
groupId, sDf52.getId(), sDf52.getStatus(), accountQuery);
} else {
String msg = messageResolver.resolve(new EnumMessage(AccountError.AccountNotFound, sDf52.getAccount()));
log.warn("By generationId={} s_df52[{}] (query: {}) error: {}", groupId, sDf52.getId(), accountQuery, msg);
toProcessSDF53.add(new MutableTriple<>(sDf52, null,
makeSdfErrorText(AccountError.AccountNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND)));
continue;
}
}
toProcessSDF53.add(new MutableTriple<>(sDf52, account, SDFProcessService.SDF_STATUS_OK));
toUpdate.add(new Pair<>(sDf52, account));
}
}
log.debug("Selected to update {} account's", toUpdate.size());
int countOfUpdated = 0;
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
try { // 2. обновление данных, в транзакции
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Instant now = Instant.now();
accountsLoop:
for (Pair<SDf52, Account> item : toUpdate) {
SDf52 sdf = item.getFirst();
Account account = item.getSecond();
AccountStatus newStatus = sdfProcessService.parseSdf52Status(sdf.getStatus());
if (newStatus == null) {
throw new IllegalArgumentException("Can not parse sdf status " + sdf.getStatus());
}
toProcessSDF53.add(new MutableTriple<>(sdf, account, SDFProcessService.SDF_STATUS_OK));
if (!newStatus.equalsByKey(account.getStatus())) {
// Обновление счёта
account.setStatus(newStatus.getKey());
account.setUpdated(now);
accountImdg.update(account);
log.trace("S_DF52[{}] do update status to {} for account[{}]", sdf.getId(), newStatus.getKey(), account.getId());
countOfUpdated++;
}
// 4. to notification
List<Long> notificationAccountIds = new ArrayList<>();
for (Pair<SDf52, Account> item : toUpdate) {
SDf52 sdf = item.getFirst();
Account account = item.getSecond();
AccountStatus newStatus = sdfProcessService.parseSdf52Status(sdf.getStatus());
if (newStatus == null) { // never
throw new IllegalArgumentException("Can not parse sdf status " + sdf.getStatus());
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed update, clearing accounts, rollback transaction. Request id={}; sdf52 groupId={}", systemRequest.getId(), groupId);
imdgTransaction.rollbackTransaction();
if (newStatus.equalsByKey(account.getStatus())) {
// одинаковых обычно не бывает.
continue;
}
if (AccountStatus.BLOCKED == newStatus || AccountStatus.CLOSE == newStatus) { // статус 0/2
sendNotificationRequest(ObjectType.account_block, account, newStatus);
notificationAccountIds.add(account.getId());
putNotificationWaiting(systemRequest, item.getFirst(), item.getSecond());
}
if (AccountStatus.ACTIVE == newStatus) { // статус 1/3
sendNotificationRequest(ObjectType.account_active, account, newStatus);
notificationAccountIds.add(account.getId());
putNotificationWaiting(systemRequest, item.getFirst(), item.getSecond());
}
}
sdfProcessService.process(req, toProcessSDF53);
if (txOk) {
sdfProcessService.process(req, toProcessSDF53);
}
log.info("{} account's need wait accept over notification. GroupId={}", notificationAccountIds.size(), groupId);
log.debug("successfully processed, grouping id={}. Updated {} of {} accounts.",
groupId, countOfUpdated, toUpdate.size());
log.debug("successfully processed, grouping id={} with {} accounts.",
groupId, toUpdate.size());
return null;
}
protected RequestInfoUpdate accountUpdateSdf52_part2Notification(BaseRequest<NotificationFeedbackRequest> secondSystemRequest2) {
log.debug("accountUpdateSdf52 NotificationFeedbackRequest received, id={}", secondSystemRequest2.getId());
SDF52WaitingData trigger = onNotificationResponse(secondSystemRequest2.getRequestPayload());
if (trigger == null) {
log.trace("Not triggered, continue waiting");
return null;
} else {
log.debug("Triggered, groupId={}, notification's status: {}, last notification user id={}",
trigger.getGroupId(), trigger.globalStatus, secondSystemRequest2.getUserId());
if (NotificationStatus.ACPT.equalsByKey(trigger.globalStatus)) {
return accountUpdateSdf52_part2(trigger.systemRequest, trigger.sdf, trigger.account, secondSystemRequest2);
} else if (NotificationStatus.CNCL.equalsByKey(trigger.globalStatus)) {
log.debug("groupId={} rejected by user {}.", trigger.getGroupId(), secondSystemRequest2.getUserId());
return null;
} else {
log.warn("Unknown waiting group status \"{}\"", trigger.globalStatus);
return null;
}
}
}
protected RequestInfoUpdate accountUpdateSdf52_part2(BaseRequest<StatementRequest> systemRequest1,
SDf52 sdf, Account account,
BaseRequest<NotificationFeedbackRequest> secondSystemRequest2) {
// 5. from notification:
StatementRequest req = systemRequest1.getRequestPayload();
Long groupId = req.getGroupId();
log.info("Continue Sdf52 groupId={}, first request id={}, second request id={}",
groupId, systemRequest1 == null ? null : systemRequest1.getId(), secondSystemRequest2 == null ? null : secondSystemRequest2.getId());
int countOfUpdated = 0;
// 2. обновление данных
Instant now = Instant.now();
AccountStatus newStatus = sdfProcessService.parseSdf52Status(sdf.getStatus());
if (newStatus == null) {
throw new IllegalArgumentException("Can not parse sdf status " + sdf.getStatus());
}
// За долгое время ожидания пользователя счёт мог быть обновлён, прочитать его ещё раз
account = accountImdg.getSingleObjectByID(account.getId());
if (!newStatus.equalsByKey(account.getStatus())) {
// Обновление счёта
String oldStatus = account.getStatus();
account.setStatus(newStatus.getKey());
account.setUpdated(now);
accountImdg.update(account);
log.trace("S_DF52[{}] do update status to {} for account[{}]",
sdf.getId(), newStatus.getKey(), account.getId());
if (AccountStatus.ACTIVE.equalsByKey(oldStatus) && AccountStatus.ACTIVE != newStatus) { // счёт заблокировали - значит блокируем ТКР, наоборот не надо.
// Отправка в ТКР
TradingClearingRegistryUpdateRequest tcrReq = new TradingClearingRegistryUpdateRequest();
tcrReq.setMoneyAccountId(account.getId());
tcrReq.setCompanyId(account.getCompanyId());
tcrReq.setStatus(account.getStatus());
Map<String, Long> queryTCR = new HashMap<>();
queryTCR.put("moneyAccountId", tcrReq.getMoneyAccountId());
if (tcrReq.getCompanyId() != null)
queryTCR.put("companyId", tcrReq.getCompanyId());
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getFirstObjectByFieldValues(queryTCR);
if (tcr == null) {
log.warn("TradingClearingRegistry by {} not found, do not send update TCR.", queryTCR);
} else {
tcrReq.setId(tcr.getId());
String destination = Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE;
log.debug("Send message to kafka \"{}\": {}", destination, LogFormatter.toStringWrapper(tcrReq));
kafkaSender.sendRequestToQueue(destination, tcrReq);
}
}
countOfUpdated++;
} else {
log.info("Account[{}] \"{}\" do not updated - same status \"{}\"", account.getId(), account.getAccount(), newStatus);
}
log.debug("successfully processed, grouping id={}. Updated {} accounts.",
groupId, countOfUpdated);
return null;
}
protected String makeSdfErrorText(IErrorEnumId clrError, String sdfCode) {
if (clrError == null) return sdfCode;
sdfCode = clrError.getId().toString();
if (sdfCode.length() > 3)
sdfCode = sdfCode.substring(sdfCode.length() - 3);
return sdfCode;
}
public void sendStatementRequestBack(Long groupingSdf01Id, Long groupSdf02Id, List<AccountSdfToStatementRequestPart> results) {
final String destination = Consts.STATEMENT_PROCESS;
StatementRequest request = new StatementRequest();
@ -431,4 +511,107 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
log.debug("Send message to kafka \"{}\": {}", destination, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(destination, request);
}
public Long sendNotificationRequest(ObjectType objectType, Account account, AccountStatus requestToStatus) {
String statusText = AccountStatus.BLOCKED == requestToStatus ? "Заблокирован"
: AccountStatus.CLOSE == requestToStatus ? "Закрыт"
: AccountStatus.ACTIVE == requestToStatus ? "Разблокирован" :
requestToStatus.getKey();
String message = String.format("Для счета %s будет изменен статус на «%s»", account.getAccount(), statusText);
final String destination = Consts.NOTIFICATION_NEW;
NotificationNewRequest request = new NotificationNewRequest();
request.setObjectType(objectType.getKey());
request.setObjectId(account.getId());
request.setPriority(Priority.HIGH.getKey());
request.setComment(message);
log.debug("Send message to kafka \"{}\": {}", destination, LogFormatter.toStringWrapper(request));
Long rKey = kafkaSender.sendRequestToQueue(destination, request);
log.trace("About account.id={} send notification request id={}", account.getId(), rKey);
return rKey;
}
// --------- notification apply system -----------
public static class SDF52WaitingData {
public BaseRequest<StatementRequest> systemRequest;
public SDf52 sdf;
public Account account;
public Long notAnsweredAccountId;
public String globalStatus;
public SDF52WaitingData(BaseRequest<StatementRequest> systemRequest, SDf52 sdf, Account account) {
this.systemRequest = systemRequest;
this.sdf = sdf;
this.account = account;
this.notAnsweredAccountId = account.getId();
}
public Long getGroupId() {
if (systemRequest != null && systemRequest.getRequestPayload() != null)
return systemRequest.getRequestPayload().getGroupId();
return null;
}
}
protected ConcurrentHashMap<Long, SDF52WaitingData> waitingList = new ConcurrentHashMap<>();
public boolean putNotificationWaiting(BaseRequest<StatementRequest> systemRequest, SDf52 sdf, Account account) {
SDF52WaitingData data = new SDF52WaitingData(systemRequest, sdf, account);
if (waitingList.contains(data.notAnsweredAccountId)) {
log.warn("groupId={} accountId={} already waiting", data.getGroupId(), data.notAnsweredAccountId);
}
data.globalStatus = null;
waitingList.put(data.notAnsweredAccountId, data);
return true;
}
/**
* @return triggered SDF52WaitingData or null
*/
public SDF52WaitingData onNotificationResponse(NotificationFeedbackRequest onNotification) {
if (onNotification.getNotificationId() == null) {
log.trace("notificationId was empty");
return null;
}
Notification notification = notificationImdg.getSingleObjectByID(onNotification.getNotificationId());
if (notification == null) {
log.warn("Notification with id={} not exist", onNotification.getNotificationId());
return null;
}
if (!ObjectType.account_active.equalsByKey(notification.getObjectType()) && !ObjectType.account_block.equalsByKey(notification.getObjectType())) {
log.warn("Notification[{}].objectType={} not supported", notification.getId(), notification.getObjectType());
return null;
}
if (notification.getObjectId() == null) {
log.warn("Notification[{}] with empty objectId", notification.getId());
return null;
}
final Long accountId = notification.getObjectId();
log.trace("Match accountId={} by notificationId={}", accountId, notification.getId());
SDF52WaitingData inWaitingLst = waitingList.get(accountId);
if (inWaitingLst == null) {
log.debug("SDF52 waiting list (count {}) not found for accountId={}", waitingList.size(), accountId);
return null;
}
boolean returnTrigger = false;
if (NotificationStatus.ACPT.equalsByKey(onNotification.getNotificationStatus())) {
log.trace("Triggered ACPT, by accountId={}", accountId);
inWaitingLst.globalStatus = onNotification.getNotificationStatus();
returnTrigger = true;
} else if (NotificationStatus.CNCL.equalsByKey(onNotification.getNotificationStatus())) {
log.trace("Triggered CNCL, by accountId={}", accountId);
inWaitingLst.globalStatus = onNotification.getNotificationStatus();
returnTrigger = true;
} else {
log.warn("Unknown notification[{}] status={}", onNotification.getNotificationId(), onNotification.getNotificationStatus());
}
if (returnTrigger) {
log.debug("Remove from waiting list accountId={} (list groupId={})", accountId, inWaitingLst.getGroupId());
waitingList.remove(inWaitingLst);
}
if (returnTrigger)
return inWaitingLst;
else
return null;
}
}

View file

@ -23,10 +23,7 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.SdfTable;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
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.ImdgTransaction;
@ -44,7 +41,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
private final KafkaSender kafkaSender;
private final ValidationHelper validationHelper;
private final ImdgProvider imdgProvider;
private final AccountService accountService;
private final AccountHelper accountService;
private final Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator;
public DepoAccountService(Consumer<String, Object> kafkaQueue,
@ -52,7 +49,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
KafkaSender kafkaSender,
ValidationHelper validationHelper,
ImdgProvider imdgProvider,
AccountService accountService,
AccountHelper accountService,
@Qualifier("depoAccountNewRequestValidator")
Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator) {
super(kafkaQueue, kafkaProducer);
@ -114,7 +111,11 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
depoAccount = new DepoAccount();
depoAccount.setCompanyId(req.getCompanyId());
depoAccount.setAccountId(accountId);
depoAccount.setDepoAccountType(req.getDepoAccountType());
if (account.getAccount() != null && account.getAccount().contains("BC")) {
depoAccount.setDepoAccountType(DepoAccountType.C.getKey());
} else {
depoAccount.setDepoAccountType(req.getDepoAccountType());
}
depoAccountId = depoAccountImdg.insert(depoAccount);
txOk = true;
} finally {
@ -168,7 +169,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
continue accountsLoop;
}
}
if (accountImdg.getFirstObjectBySQL("accountType = '%s' and account = '%s'".formatted(AccountType.Depo.getKey(), accountReq.getAccount())) != null) {
if (accountImdg.getFirstObjectBySQL("account = '%s'".formatted(accountReq.getAccount())) != null) {
log.debug("Account {} already exists", accountReq.getAccount());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
@ -188,7 +189,11 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
DepoAccount depoAccount = new DepoAccount();
depoAccount.setCompanyId(accountReq.getCompanyId());
depoAccount.setAccountId(accountId);
depoAccount.setDepoAccountType(accountReq.getAccountType());
if (account.getAccount() != null && account.getAccount().contains("BC")) {
depoAccount.setDepoAccountType(DepoAccountType.C.getKey());
} else {
depoAccount.setDepoAccountType(accountReq.getAccountType());
}
depoAccountId = depoAccountImdg.insert(depoAccount);

View file

@ -22,6 +22,7 @@ import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
@ -50,9 +51,10 @@ public class InformationAccountService extends QueueConsumer implements Initiali
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final ImdgProvider imdgProvider;
private final ValidationHelper validationHelper;
private final AccountService accountService;
private final AccountHelper accountHelper;
private final RequestHelper requestHelper;
private final Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator;
private final Imdg<InformationAccount> informationAccountImdg;
@ -68,18 +70,20 @@ public class InformationAccountService extends QueueConsumer implements Initiali
Producer<String, Object> kafkaResponseQueue,
KafkaSender kafkaSender,
IMessageResolver messageResolver,
UserRoleVerification userRoleVerification,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
AccountService accountService,
AccountHelper accountHelper,
RequestHelper requestHelper,
@Qualifier("informationAccountNewRequestValidator")
Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) {
super(kafkaQueue, kafkaResponseQueue);
this.kafkaSender = kafkaSender;
this.messageResolver = messageResolver;
this.userRoleVerification = userRoleVerification;
this.imdgProvider = imdgProvider;
this.validationHelper = validationHelper;
this.accountService = accountService;
this.accountHelper = accountHelper;
this.requestHelper = requestHelper;
this.infoAccountNewRequestValidator = infoAccountNewRequestValidator;
this.informationAccountImdg = imdgProvider.getImdg(
@ -101,10 +105,13 @@ public class InformationAccountService extends QueueConsumer implements Initiali
init();
}
@Deprecated
public RequestInfoUpdate informationAccountNew(BaseRequest<InformationAccountNewRequest> userRequest) {
log.debug("InformationAccountNewRequest received");
RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, infoAccountNewRequestValidator);
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, infoAccountNewRequestValidator);
if (requestInfoUpdate != null) return requestInfoUpdate;
InformationAccountNewRequest req = userRequest.getRequestPayload();
@ -128,7 +135,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
Instant now = Instant.now();
Account account = new Account();
account.setAccount(accountValue);
account.setAccount(req.getAccount());
account.setAccountType(AccountType.Info.getKey());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
@ -139,7 +146,8 @@ public class InformationAccountService extends QueueConsumer implements Initiali
account.setCompanyId(req.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) return requestInfoUpdate;
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
@ -231,7 +239,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
account.setCompanyId(forCompanyId);
account.setCreated(now);
account.setUpdated(now);
requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), false);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
if (requestInfoUpdate != null) {
log.debug("Stop make new account, cause error: {}", requestInfoUpdate.getMessage());
return requestInfoUpdate;
@ -296,7 +304,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
*
* @return infoCounter++
*/
protected Long accountNextId() {
public synchronized Long accountNextId() {
if (infoCounter == null) synchronized (this) {
if (infoCounter == null) {
log.debug("Init account-information counter.");

View file

@ -6,21 +6,28 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.misc.Notification;
import ru.clearing.classes.statics.data.sdf.SDf52;
import ru.clearing.classes.statics.data.sdf.SDf53;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationFeedbackRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.NotificationStatus;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
import ru.spcex.platform.utils.collection.Pair;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
@Service
public class SDFProcessService {
@ -31,6 +38,11 @@ public class SDFProcessService {
public static final String SDF_STATUS_ERROR_NO_TRADE = "4"; // (Ошибка. Торги не идут)
public static final String SDF_STATUS_ERROR = "9"; // (Другие ошибки, выявленные в КС) - если получены другие ошибки (т.е. account НЕ обновлена по sDf52).
protected static final Long SDF52_STATUS_0Blocked = 0L;
protected static final Long SDF52_STATUS_1Unblocked = 1L;
protected static final Long SDF52_STATUS_2Closed = 2L;
protected static final Long SDF52_STATUS_3Open = 3L;
final protected Logger log = LoggerFactory.getLogger(getClass());
protected final Producer<String, Object> kafkaResponseQueue;
@ -102,6 +114,7 @@ public class SDFProcessService {
newSdf.setAccName(sdf52.getAcc_name());
newSdf.setAccount(sdf52.getAccount());
newSdf.setDeal(sdf52.getDeal());
newSdf.setDate(sdf52.getDate());
newSdf.setStatus(sdf52.getStatus());
newSdf.setResult(result);
newSdf.setGenerationTime(now);
@ -121,12 +134,12 @@ public class SDFProcessService {
* @return AccountStatus или null
*/
public AccountStatus parseSdf52Status(Long status) {
if (Long.valueOf(1L).equals(status)) {
if (SDF52_STATUS_1Unblocked.equals(status) || SDF52_STATUS_3Open.equals(status)) {
return AccountStatus.ACTIVE;
} else if (Long.valueOf(0L).equals(status)) {
} else if (SDF52_STATUS_0Blocked.equals(status)) {
return AccountStatus.BLOCKED;
}
if (Long.valueOf(2L).equals(status)) {
if (SDF52_STATUS_2Closed.equals(status)) {
return AccountStatus.CLOSE;
}
return null;
@ -143,4 +156,5 @@ public class SDFProcessService {
log.debug("Send ExportToFileRequest({}, {}) message id={} to kafka \"{}\"",
groupId, request.getNameOfTable(), msgId, destination);
}
}

View file

@ -1,7 +1,5 @@
package ru.spcex.clearing.account.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
@ -23,40 +21,28 @@ import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.InformationAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -64,6 +50,9 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
ValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
InformationAccountService.class,
InformationAccountValidationConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
class AccountServiceTest {
@ -209,8 +198,16 @@ class AccountServiceTest {
waitingSendAndCheckRecord(0L, mockProducer);
Account resultUpdating = accountImdg.getSingleObjectByID(accountId);
existAccount.setUpdated(resultUpdating.getUpdated());
ACCOUNT_MATCHER.assertMatch(resultUpdating, existAccount);
Account expectAccount = new Account();
expectAccount.setId(existAccount.getId());
expectAccount.setAccount(account);
expectAccount.setAccountType(AccountType.Corr.getKey());
expectAccount.setStatus(ServiceStatus.Closed.getKey());
expectAccount.setCompanyId(companyId);
expectAccount.setCreated(existAccount.getCreated());
expectAccount.setUpdated(resultUpdating.getUpdated());
expectAccount.setStatus(ServiceStatus.Active.getKey());
ACCOUNT_MATCHER.assertMatch(resultUpdating, expectAccount);
accountImdg.delete(resultUpdating);
}

View file

@ -0,0 +1,164 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.Producer;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.*;
import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountSymbolsValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.KafkaTestConfig.setMockFuture;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
BeanConfiguration.class,
ValidationConfig.class,
AccountSymbolsValidationConfig.class,
AccountSymbolsService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
class AccountSymbolsServiceTest {
public static final MatcherFactory.Matcher<AccountSymbols> ACCOUNT_SYMBOL_MATCHER = usingIgnoringFieldsComparator();
private static final int PARTITION = 0;
@Autowired
AccountSymbolsService accountSymbolsService;
@Autowired
@Qualifier("hazelcastServiceTest")
private ImdgProvider hazelcastServiceTest;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@Autowired
@Qualifier("kafkaTestTemplate")
protected KafkaTemplate<String, Object> kafkaTemplate;
private Imdg<AccountSymbols> accountSymbolsImdg;
private Imdg<Account> accountImdg;
private Long accountId;
private Imdg<ClearingAccount> clearingAccountImdg;
private Long clearingAccountId;
static int newRequestCnt = 0;
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
accountSymbolsImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class
);
accountImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Account, Account.class
);
clearingAccountImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
);
Account account = new Account();
account.setStatus(ServiceStatus.Active.getKey());
account.setAccountType(AccountType.Clrn.getKey());
accountId = accountImdg.insert(account);
ClearingAccount clearingAccount = new ClearingAccount();
clearingAccount.setAccountId(accountId);
clearingAccount.setClearingAccountType("CAT");
clearingAccountId = clearingAccountImdg.insert(clearingAccount);
new TestObjectCreator(hazelcastServiceTest).createUserAdmin(1000L);
}
@PreDestroy
private void destroyTest() {
//clean test data
Account account = accountImdg.getSingleObjectByID(accountId);
if (account != null)
accountImdg.delete(account);
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(clearingAccountId);
if (clearingAccount != null)
clearingAccountImdg.delete(clearingAccount);
}
@Test
void tradingClearingRegistryNew_moneyAccount_clearingAccount() {
setMockFuture(kafkaTemplate);
AccountSymbolsNewRequest accountSymbolsNewRequest = new AccountSymbolsNewRequest();
accountSymbolsNewRequest.setAccountId(accountId);
accountSymbolsNewRequest.setAccountSymbolValue("SYMBOL1");
AccountSymbols predictableAccountSymbols = new AccountSymbols();
predictableAccountSymbols.setAccountId(accountId);
predictableAccountSymbols.setAccountSymbolValue("SYMBOL1");
String jsonString = getJsonStringForNew(accountSymbolsNewRequest, 0L);
addRecordToKafka((MockConsumer) accountSymbolsService.getConsumer(),
Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW,
newRequestCnt,
0,
jsonString);
waitingSendAndCheckRecord(0L, mockProducer);
AccountSymbols resultNew = accountSymbolsImdg.getAllValues().iterator().next();
predictableAccountSymbols.setId(resultNew.getId());
ACCOUNT_SYMBOL_MATCHER.assertMatch(resultNew, predictableAccountSymbols);
accountSymbolsImdg.delete(resultNew); // cleanup test
newRequestCnt++;
}
@Test
void tradingClearingRegistryDelete() {
AccountSymbols existAccountSymbols = new AccountSymbols();
existAccountSymbols.setAccountId(accountId);
existAccountSymbols.setAccountSymbolValue("SYMBOL 2");
Long accountSymbolId = accountSymbolsImdg.insert(existAccountSymbols);
CommonDeleteRequest accountSymbolsDeleteRequest = new CommonDeleteRequest();
accountSymbolsDeleteRequest.setId(accountSymbolId);
String jsonString = getJsonStringForDelete(accountSymbolsDeleteRequest, 0);
//ACT
addRecordToKafka((MockConsumer) accountSymbolsService.getConsumer(),
Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE,
PARTITION,
0,
jsonString);
//ASSERT
waitingSendAndCheckRecord(0L, mockProducer);
AccountSymbols resultUpdating = accountSymbolsImdg.getSingleObjectByID(accountSymbolId);
Assertions.assertNull(resultUpdating, "Должен был удалиться");
}
}

View file

@ -1,17 +1,13 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
@ -25,7 +21,6 @@ import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.BankAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.account.utils.MatcherFactory.Matcher;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
@ -34,12 +29,13 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewReq
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.test.MatcherFactory.Matcher;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
@ -49,13 +45,14 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.platform.messaging.service.Status.Error;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
AccountService.class,
AccountHelper.class,
BankAccountService.class,
ValidationConfig.class,
BankAccountValidationConfig.class,
@ -97,15 +94,11 @@ public class BankAccountServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Autowired
private BankAccountService bankAccountService;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@ -216,11 +209,11 @@ public class BankAccountServiceTest {
//AccountValidationRule.RequiredFields
//WrongFieldValue
bankAccountNewRequest.setCurrency(null);
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "currency"));
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "null, currency"));
checkError(errMsg, bankAccountNewRequest);
bankAccountNewRequest.setCurrency("TT0");
errMsg = messageResolver.resolve(new EnumMessage(AccountError.WrongFieldValue, "currency"));
errMsg = messageResolver.resolve(new EnumMessage(AccountError.DictionaryNotFound, "TT0, CurrencyCodeDictionary"));
checkError(errMsg, bankAccountNewRequest);
bankAccountNewRequest.setCurrency(currency);
@ -239,36 +232,20 @@ public class BankAccountServiceTest {
checkError(errMsg, bankAccountNewRequest);
bankAccountNewRequest.setAccount(acc);
bankAccountNewRequest.setDestination(null);
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "destination"));
checkError(errMsg, bankAccountNewRequest);
bankAccountNewRequest.setDestination(destination);
bankAccountNewRequest.setCompanyId(null);
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "companyId"));
checkError(errMsg, bankAccountNewRequest);
bankAccountNewRequest.setCompanyId(addresseeIdNew);
//AccountValidationRule.CompanyPresent
//CompanyNotFound
bankAccountNewRequest.setCompanyId(999924535239L);
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotFound, "companyId"));
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotFound, bankAccountNewRequest.getCompanyId()+", companyId"));
checkError(errMsg, bankAccountNewRequest);
//CompanyNotActive
company.setWorkflowStatus(Status.Blocked.getKey());
companyImdg.insert(company);
bankAccountNewRequest.setCompanyId(company.getId());
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotActive, "companyId"));
checkError(errMsg, bankAccountNewRequest);
//AccountValidationRule.AccountIsNew
//AccountAlreadyExist
company.setWorkflowStatus(Status.Active.getKey());
companyImdg.insert(company);
Account existAccount = getTestAccount(accountId, acc);
accountImdg.insert(existAccount);
errMsg = messageResolver.resolve(new EnumMessage(AccountError.AccountAlreadyExist, "account"));
errMsg = messageResolver.resolve(new EnumMessage(AccountError.AccountAlreadyExist, existAccount.getAccount()));
checkError(errMsg, bankAccountNewRequest);
accountImdg.delete(existAccount);
}
@ -291,8 +268,9 @@ public class BankAccountServiceTest {
//ACT
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, currentOffset, jsonString);
ArgumentCaptor<ProducerRecord> producerRecord = getCaptor(mockProducer);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(currentTime))
verify(mockProducer, timeout(30_000L).times(currentTime))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
@ -368,13 +346,13 @@ public class BankAccountServiceTest {
}
/**
* {@link BankAccountService#bankAccountDelete(BaseRequest)}
* {@link BankAccountService#bankAccountBlock(BaseRequest)}
* Тест проверяет удаление сущности {@link BankAccount} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link CommonDeleteRequest}:
* {@link CommonDeleteRequest#id} - Идентификатор записи
*/
@Test
void bankAccountDelete() {
void bankAccountBlock() {
//ARRANGE
BankAccount bankAccountExists = getBankAccount();
bankAccountImdg.insert(bankAccountExists);
@ -393,8 +371,8 @@ public class BankAccountServiceTest {
//ASSERT
waitingSendAndCheckRecord(ID, mockProducer);
BankAccount bankAccount = bankAccountImdg.getSingleObjectByID(ID);
Assertions.assertNull(bankAccount);
Account bankAccount = accountImdg.getSingleObjectByID(accountId);
assertEquals(bankAccount.getStatus(), WorkflowStatus.Blocked.getKey());
}
private Company getTestCompany() {

View file

@ -1,17 +1,13 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
@ -25,25 +21,31 @@ import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ClearingAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.Map;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
import static ru.spcex.clearing.test.config.KafkaTestConfig.setMockFuture;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -51,8 +53,9 @@ import static ru.spcex.clearing.test.TestUtils.*;
ValidationConfig.class,
ClearingAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
ClearingAccountService.class,
SDFProcessService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
class ClearingAccountServiceTest {
@ -70,16 +73,16 @@ class ClearingAccountServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@Autowired
@Qualifier("kafkaTestTemplate")
protected KafkaTemplate<String, Object> kafkaTemplate;
private Imdg<ClearingAccount> clearingAccountImdg;
private Imdg<Account> accountImdg;
private Imdg<Company> companyImdg;
@ -160,8 +163,7 @@ class ClearingAccountServiceTest {
0,
jsonString);
verify(producer, timeout(30_000L).times(2))
.send(producerRecord.capture());
waitingSendAndCheckRecord(0L, mockProducer);
Account predictableAccount = new Account();
predictableAccount.setAccount(ACCOUNT_VALUE);
@ -225,77 +227,64 @@ class ClearingAccountServiceTest {
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
}
// /**
// * {@link ClearingAccountService#accountNewSdf01(BaseRequest)}<br>
// * Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.<br>
// * Входной запрос {@link AccountSdf01Request}:<br>
// * {@link AccountSdfRequestPart#setSdfId} - текущий Id<br>
// * {@link AccountSdfRequestPart#setAccount} - 123456789123<br>
// * {@link AccountSdfRequestPart#setCompanyId} - текущий Id<br>
// * {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id<br>
// * {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)<br>
// */
// @Test
// void accountSdf01New() throws InterruptedException {
// //ARRANGE
// Long firstID = currentID.getAndIncrement();
// Long secondID = currentID.getAndIncrement();
// AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
// accountSdfRequestPart.setSdfId(firstID);
// accountSdfRequestPart.setAccount(account);
// accountSdfRequestPart.setCompanyId(firstID);
// AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
// accountSdf01Request.setGroupingSdf01Id(firstID);
// accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
// BaseRequest<AccountSdf01Request> baseNewRequest = new BaseRequest<>();
// baseNewRequest.setRequestPayload(accountSdf01Request);
// baseNewRequest.setId(firstID);
// baseNewRequest.setActionType(ActionType.NEW);
// String jsonBaseNewRequest;
// ObjectMapper objectMapper = new ObjectMapper();
// try {
// jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
// } catch (JsonProcessingException e) {
// throw new RuntimeException(e);
// }
//
// AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
// responsePart.setSdfId(firstID);
// responsePart.setErrorCode(null);
// responsePart.setErrorText(null);
// List<AccountSdfToStatementRequestPart> accountToStatement = Collections.singletonList(responsePart);
// StatementRequest statementRequest = new StatementRequest();
// statementRequest.setGroupId(firstID);
// statementRequest.setAccountCreationResults(accountToStatement);
//
// BaseRequest<Object> baseRequest = new BaseRequest<>();
// baseRequest.setId(secondID);
// baseRequest.setActionType(ActionType.SYSTEM);
// baseRequest.setRequestPayload(statementRequest);
//
// Account predictableAccount = new Account();
// predictableAccount.setAccount(account);
// predictableAccount.setCompanyId(firstID);
//
// RequestInfo predictableRequestInfo = new RequestInfo();
// predictableRequestInfo.setId(secondID);
// predictableRequestInfo.setStatus(Status.Processing);
//
// //KAFKA
// final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01;
// addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest);
//
// //waiting for kafka producer send message (finale event)
// verify(producer, timeout(30_000L).times(2))
// .send(producerRecord.capture());
// //todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError
//
// ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
//
// //ASSERT
// Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account));
// predictableAccount.setId(accountResult.getId());
// ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
// accountImdg.delete(accountResult);
// }
@Test
void makeSdfErrorText() {
Assertions.assertEquals("013", clearingAccountService.makeSdfErrorText(AccountError.CompanyNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND));
Assertions.assertEquals("2", clearingAccountService.makeSdfErrorText(null, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND));
}
/**
* {@link ClearingAccountService#accountNewSdf01(BaseRequest)}<br>
* Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link AccountSdf01Request}:<br>
* {@link AccountSdfRequestPart#setSdfId} - текущий Id<br>
* {@link AccountSdfRequestPart#setAccount} - 123456789123<br>
* {@link AccountSdfRequestPart#setCompanyId} - текущий Id<br>
* {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id<br>
* {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)<br>
*/
@Test
void accountSdf01New() throws InterruptedException {
//ARRANGE
clearImdg(accountImdg);
setMockFuture(kafkaTemplate);
Long firstID = currentID.getAndIncrement();
Long secondID = currentID.getAndIncrement();
AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
accountSdfRequestPart.setSdfId(firstID);
accountSdfRequestPart.setAccount(ACCOUNT_VALUE);
accountSdfRequestPart.setCompanyId(firstID);
AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
accountSdf01Request.setGroupingSdf01Id(firstID);
accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
String jsonString = getJsonStringForNew(accountSdf01Request, 0L);
Account predictableAccount = new Account();
predictableAccount.setAccount(ACCOUNT_VALUE);
predictableAccount.setCompanyId(firstID);
predictableAccount.setAccountType(AccountType.Clrn.getKey());
predictableAccount.setStatus(ServiceStatus.Active.getKey());
predictableAccount.setRelationId(relationId);
ClearingAccount predictableClearingAccount = new ClearingAccount();
predictableClearingAccount.setCompanyId(companyId);
// predictableClearingAccount.setClearingAccountType(CLEARING_ACCOUNT_TYPE_DICT);
//KAFKA
addRecordToKafka((MockConsumer) clearingAccountService.getConsumer(), Consts.ACCOUNT_NEW_SDF01, PARTITION, 0, jsonString);
waitingSendAndCheckRecord(0L, mockProducer);
ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
//ASSERT
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", ACCOUNT_VALUE));
ClearingAccount resultClearingAccountNew = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", accountResult.getId()));
predictableAccount.setId(accountResult.getId());
predictableClearingAccount.setAccountId(accountResult.getId());
predictableClearingAccount.setId(resultClearingAccountNew.getId());
predictableAccount.setId(accountResult.getId());
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
CLEARING_ACCOUNT_MATCHER.assertMatch(resultClearingAccountNew, predictableClearingAccount);
accountImdg.delete(accountResult);
}
}

View file

@ -24,13 +24,13 @@ import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.ClientCodeValidationConfig;
import ru.spcex.clearing.account.config.validation.TradingClearingRegistryValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.TestUtils;
import ru.spcex.clearing.test.config.ImdgTestConfig;
@ -376,7 +376,7 @@ class ClientCodeServiceTest {
waitingSendAndCheckRecord(ID, mockProducer);
ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID);
Assertions.assertNull(resultUpdate);
assertEquals(WorkflowStatus.Blocked.getKey(), resultUpdate.getStatus());
}
// /**

View file

@ -1,16 +1,11 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
@ -24,25 +19,22 @@ import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.DepoAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewRequest;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
import java.util.Map;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -50,7 +42,7 @@ import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
ValidationConfig.class,
DepoAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
DepoAccountService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
@ -69,12 +61,8 @@ class DepoAccountServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@ -159,8 +147,7 @@ class DepoAccountServiceTest {
0,
jsonString);
verify(producer, timeout(30_000L).times(2))
.send(producerRecord.capture());
waitingSendAndCheckRecord(0L, mockProducer);
Account predictableAccount = new Account();
predictableAccount.setAccount(ACCOUNT_VALUE);

View file

@ -1,17 +1,13 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
@ -24,26 +20,23 @@ import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.InformationAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct;
import java.util.Map;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.addRecordToKafka;
import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -51,7 +44,7 @@ import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
ValidationConfig.class,
InformationAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
InformationAccountService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
@ -69,12 +62,8 @@ class InformationAccountServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@ -96,6 +85,7 @@ class InformationAccountServiceTest {
accountImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Account, Account.class
);
clearImdg(accountImdg);
companyImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Company, Company.class
@ -143,6 +133,7 @@ class InformationAccountServiceTest {
void accountInformationNew() {
InformationAccountNewRequest InformationAccountNewRequest = new InformationAccountNewRequest();
InformationAccountNewRequest.setCompanyId(companyId);
InformationAccountNewRequest.setAccount(account);
String jsonString = getJsonStringForNew(InformationAccountNewRequest, 0L);
@ -152,9 +143,7 @@ class InformationAccountServiceTest {
0,
jsonString);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(2))
.send(producerRecord.capture());
waitingSendAndCheckRecord(0L, mockProducer);
Account predictableAccount = new Account();
predictableAccount.setAccountType(AccountType.Info.getKey());
@ -170,7 +159,7 @@ class InformationAccountServiceTest {
InformationAccount resultInfoAccountNew = informationAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
predictableAccount.setId(resultAccountNew.getId());
predictableAccount.setAccount(informationAccountService.generateInfoAccount(resultInfoAccountNew.getId()));
predictableAccount.setAccount(account);
predictableInfoAccount.setAccountId(resultAccountNew.getId());
predictableInfoAccount.setId(resultInfoAccountNew.getId());
@ -181,7 +170,6 @@ class InformationAccountServiceTest {
accountImdg.delete(resultAccountNew);
}
@Autowired ImdgProvider imdgProvider;
@Test
void accountIncrementSequence() {
Imdg<InformationAccount> accountInfoImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_InformationAccount, InformationAccount.class );
@ -199,8 +187,9 @@ class InformationAccountServiceTest {
accountInfo.setCompanyId(account.getCompanyId());
accountInfoImdg.insert(accountInfo);
}
UserRoleVerification userRoleVerification = Mockito.mock(UserRoleVerification.class);
InformationAccountService infoAccSvc=new InformationAccountService(null,null,null,
null, imdgProvider, null, null, null, null);
null, userRoleVerification, hazelcastServiceTest, null, null, null, null);
Long n = infoAccSvc.accountNextId();
Assertions.assertEquals(13L, n);
n = infoAccSvc.accountNextId();

View file

@ -1,6 +1,5 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
@ -27,15 +26,11 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
import java.util.Map;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -50,7 +45,7 @@ class SDFProcessServiceTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@ -103,8 +98,9 @@ class SDFProcessServiceTest {
void parseSdf52Status() {
Assertions.assertEquals(AccountStatus.BLOCKED, sdfProcessService.parseSdf52Status(0L));
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(1L));
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(3L));
Assertions.assertEquals(AccountStatus.CLOSE, sdfProcessService.parseSdf52Status(2L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(3L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(4705211956118233163L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(null));
}
}

View file

@ -1,17 +1,13 @@
package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
@ -19,31 +15,30 @@ import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.TradingClearingRegistryValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
import ru.spcex.clearing.test.MatcherFactory;
import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.KafkaTestConfig.setMockFuture;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
@ -64,18 +59,19 @@ class TradingClearingRegistryServiceTest {
TradingClearingRegistryService tradingClearingRegistryService;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
@Autowired
@Qualifier("kafkaTestTemplate")
protected KafkaTemplate<String, Object> kafkaTemplate;
private Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private Imdg<Company> companyImdg;
private Imdg<CompanySymbols> companySymbolsImdg;
private Imdg<ServiceStatusDictionary> serviceStatusDictionaryImdg;
private Imdg<ClearingAccount> clearingAccountImdg;
@ -103,6 +99,9 @@ class TradingClearingRegistryServiceTest {
companyImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Company, Company.class
);
companySymbolsImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class
);
serviceStatusDictionaryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class
);
@ -129,8 +128,14 @@ class TradingClearingRegistryServiceTest {
company.setClearingCode("77");
companyImdg.insert(company);
CompanySymbols companySymbols = new CompanySymbols();
companySymbols.setCompanyId(companyId);
companySymbols.setCompanySymbol(CompanySymbol.CLRC.getKey());
companySymbolsImdg.insert(companySymbols);
Account account = new Account();
account.setStatus(ServiceStatus.Active.getKey());
account.setAccountType(AccountType.Clrn.getKey());
accountId = accountImdg.insert(account);
account2Id = accountImdg.insert(account);
@ -154,15 +159,17 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_moneyAccount_clearingAccount() {
setMockFuture(kafkaTemplate);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077MAT");
predictableTradingClearingRegistry.setCode("0077MAT00001");
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
predictableTradingClearingRegistry.setTradingClearingRegistryType("CAT");
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
@ -178,7 +185,6 @@ class TradingClearingRegistryServiceTest {
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
predictableTradingClearingRegistry.setId(resultNew.getId());
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
@ -190,13 +196,16 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_moneyAccount_informationAccount() {
setMockFuture(kafkaTemplate);
clearImdg(tradingClearingRegistryImdg);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(account2Id);
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077MAT");
predictableTradingClearingRegistry.setCode("0077MAT00001");
predictableTradingClearingRegistry.setMoneyAccountId(account2Id);
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
@ -210,11 +219,10 @@ class TradingClearingRegistryServiceTest {
0,
jsonString);
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
predictableTradingClearingRegistry.setId(resultNew.getId());
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
@ -227,6 +235,8 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_depoAccount() {
setMockFuture(kafkaTemplate);
clearImdg(tradingClearingRegistryImdg);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
@ -234,7 +244,7 @@ class TradingClearingRegistryServiceTest {
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077CDAT");
predictableTradingClearingRegistry.setCode("0077CDATT00001");
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
predictableTradingClearingRegistry.setDepoAccountId(account2Id);
predictableTradingClearingRegistry.setTradingClearingRegistryType("DAT");
@ -249,14 +259,12 @@ class TradingClearingRegistryServiceTest {
0,
jsonString);
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
predictableTradingClearingRegistry.setId(resultNew.getId());
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
predictableTradingClearingRegistry.setCompanyId(123L);
TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry);
tradingClearingRegistryImdg.delete(resultNew);
@ -284,7 +292,7 @@ class TradingClearingRegistryServiceTest {
jsonString);
//ASSERT
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
@ -312,7 +320,7 @@ class TradingClearingRegistryServiceTest {
jsonString);
//ASSERT
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
@ -333,8 +341,8 @@ class TradingClearingRegistryServiceTest {
"000000105", TradingClearingRegistryPurpose.C, "ER", 100012L
));
Assertions.assertEquals("0105MAT100012", tradingClearingRegistryService.makeCode(
"000000105", TradingClearingRegistryPurpose.M, "ER", 100012L
Assertions.assertEquals("0105MAT00012", tradingClearingRegistryService.makeCode(
"000000105", TradingClearingRegistryPurpose.M, "A", 100012L
));
}

View file

@ -1,63 +0,0 @@
package ru.spcex.clearing.account.utils;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
public class ImapEvent<T> {
private final IMap<Long, T> iMap;
private final String listenerAdding;
private final String listenerUpdating;
private final String listenerRemoving;
private final AtomicBoolean checkEventHappened = new AtomicBoolean(false);
public ImapEvent(IMap<Long, T> iMap) {
this.iMap = iMap;
listenerAdding = iMap.addEntryListener((EntryAddedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerUpdating = iMap.addEntryListener((EntryUpdatedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerRemoving = iMap.addEntryListener((EntryRemovedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
}
public void waitWhenHappened() throws InterruptedException {
//running timer task as daemon thread
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
boolean secondRan;
@Override
public void run() {
checkEventHappened.set(secondRan);//если что-то пойдет не так не тормозить основной поток
secondRan = true;
}
}, 0, 30 * 1000);
synchronized (checkEventHappened) {
while (!checkEventHappened.get()) {
checkEventHappened.wait(100);
}
}
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerAdding);
iMap.removeEntryListener(listenerUpdating);
iMap.removeEntryListener(listenerRemoving);
}
}

View file

@ -1,38 +0,0 @@
package ru.spcex.clearing.account.utils;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Factory for creating test matchers.
* <p>
* Comparing actual and expected objects via AssertJ
*/
public class MatcherFactory {
public static <T> Matcher<T> usingIgnoringFieldsComparator(String... fieldsToIgnore) {
return new Matcher<>(fieldsToIgnore);
}
public static class Matcher<T> {
private final String[] fieldsToIgnore;
private Matcher(String... fieldsToIgnore) {
this.fieldsToIgnore = fieldsToIgnore;
}
public void assertMatch(T actual, T expected) {
assertThat(actual).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(expected);
}
@SafeVarargs
public final void assertMatch(Iterable<T> actual, T... expected) {
assertMatch(actual, Arrays.asList(expected));
}
public void assertMatch(Iterable<T> actual, Iterable<T> expected) {
assertThat(actual).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(expected);
}
}
}

View file

@ -195,6 +195,19 @@
</fileMapper>
</fileMappers>
</transformationSet>
<transformationSet>
<dir>src/main/resources/meta</dir>
<includes>
<include>data_initial.xml</include>
</includes>
<stylesheet>src/main/resources/meta/xsl/data.xsl</stylesheet>
<fileMappers>
<fileMapper
implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>data_initial.sql</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>
</transformationSets>
</configuration>
</execution>

View file

@ -1,5 +1,7 @@
package ru.spcex.clearing.backendapi.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
@ -11,6 +13,8 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
public class BackEndApiImdgConfig {
Logger log = LoggerFactory.getLogger(getClass());
@Bean(name = "taskExecutorHazelcastClientInitializer")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
return createThreadPoolTaskExecutor(1, true);
@ -21,6 +25,16 @@ public class BackEndApiImdgConfig {
return createThreadPoolTaskExecutor(1, false);
}
@Bean(name = "taskExecutorHazelcastClientInitializerHist")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializerHist() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean(name = "taskExecutorIdGeneratorAwaiterHist")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiterHist() {
return createThreadPoolTaskExecutor(1, false);
}
@Autowired
@Bean
public ImdgProvider imdgProvider(
@ -28,9 +42,33 @@ public class BackEndApiImdgConfig {
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
BackendApiSettings clientSetting
) {
return new HazelcastService(taskExecutorHazelcastClientInitializer,
if (clientSetting.getHazelcast() == null || clientSetting.getHazelcast().getClusterMembers() == null) {
log.warn("Property \"backend-api.hazelcast.cluster-members\" not set!");
throw new IllegalArgumentException("Property \"backend-api.hazelcast.cluster-members\" not set");
}
ImdgProvider imdg = new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
clientSetting.getHazelcast());
// todo корректное ожидание готовности imdg.waitAvailable();
return imdg;
}
@Autowired
@Bean
public ImdgProvider imdgProviderHist(
@Qualifier("taskExecutorHazelcastClientInitializerHist") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiterHist") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
BackendApiSettings clientSetting
) {
if (clientSetting.getHazelcastSearch() == null || clientSetting.getHazelcastSearch().getClusterMembers() == null) {
log.warn("Property \"backend-api.hazelcast-search.cluster-members\" not set!");
// может работать без history, но history будет недоступна
}
ImdgProvider imdg = new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
clientSetting.getHazelcastSearch());
// todo корректное ожидание готовности imdg.waitAvailable();
return imdg;
}

View file

@ -0,0 +1,177 @@
package ru.spcex.clearing.backendapi.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.HistorySubscription;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.*;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.LinkedList;
import java.util.List;
@Configuration
public class HistoryConfig {
private final ImdgPredicateBuilder pb;
@Autowired
public HistoryConfig(ImdgProvider imdgProvider) {
this.pb = imdgProvider.getImdg(
IMDGDistributedNames.Map_SearchMoneyBalanceRegister,
SpcexObjectBase.class
).predicateBuilder();
}
@Bean
public List<HistorySubscription> histSubscriptions() {
List<HistorySubscription> hst = new LinkedList<>();
hst.add(executionDeposit());
hst.add(executionFond());
hst.add(depoBalanceRegister());
hst.add(moneyBalanceRegister());
hst.add(admittedLiabilitiesRegister());
hst.add(coveredLiabilitiesRegister());
hst.add(moneyPaymentInstructionRegister());
hst.add(depoPaymentInstructionRegister());
hst.add(excludeLiabilitiesRegister());
hst.add(liabilitiesRegister());
hst.add(executionRegister());
return hst;
}
private HistorySubscription moneyBalanceRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("money-balance-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchMoneyBalanceRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_MoneyBalanceRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription depoBalanceRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("depo-balance-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchDepoBalanceRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_DepoBalanceRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription depoPaymentInstructionRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("depo-payment-instruction-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchDepoPaymentInstructionRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_DepoPaymentInstructionRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription excludeLiabilitiesRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("exclude-liabilities-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchExcludeLiabilitiesRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_ExcludeLiabilitiesRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription liabilitiesRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("liabilities-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchLiabilitiesRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_LiabilitiesRegister);
sbscr.setConditions(List.of(
new CreatedFromCondition(pb),
new CreatedToCondition(pb)
));
return sbscr;
}
private HistorySubscription admittedLiabilitiesRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("admitted-liabilities-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchAdmittedLiabilitiesRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_AdmittedLiabilitiesRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription executionRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("execution-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchExecutionRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_ExecutionRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription moneyPaymentInstructionRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("money-payment-instruction-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchMoneyPaymentInstructionRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_MoneyPaymentInstructionRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription coveredLiabilitiesRegister() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("covered-liabilities-registers");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchCoveredLiabilitiesRegister);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_CoveredLiabilitiesRegister);
sbscr.setConditions(List.of(
new ClearingDateFromCondition(pb),
new ClearingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription executionDeposit() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("execution-deposits");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchExecutionDeposit);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_ExecutionDeposit);
sbscr.setConditions(List.of(
new TradingDateFromCondition(pb),
new TradingDateToCondition(pb)
));
return sbscr;
}
private HistorySubscription executionFond() {
HistorySubscription sbscr = new HistorySubscription();
sbscr.setDestination("execution-fonds");
sbscr.setSearchProxyMapName(IMDGDistributedNames.Map_SearchExecutionFond);
sbscr.setFullHistoryMapName(IMDGDistributedNames.Map_ExecutionFond);
sbscr.setConditions(List.of(
new TradingDateFromCondition(pb),
new TradingDateToCondition(pb)
));
return sbscr;
}
}

View file

@ -13,6 +13,7 @@ import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
@ConfigurationProperties("backend-api")
public class BackendApiSettings {
private HazelcastClientParams hazelcast;
private HazelcastClientParams hazelcastSearch;
private KafkaProducerSettings kafkaProducer;
private KafkaConsumerSettings kafkaConsumer;
private SecuritySettings security;
@ -57,4 +58,12 @@ public class BackendApiSettings {
public void setSecurity(SecuritySettings security) {
this.security = security;
}
public HazelcastClientParams getHazelcastSearch() {
return hazelcastSearch;
}
public void setHazelcastSearch(HazelcastClientParams hazelcastSearch) {
this.hazelcastSearch = hazelcastSearch;
}
}

View file

@ -0,0 +1,71 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
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.account.AccountSymbols;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/accounting/depo-accounts-symbols")
public class AccountSymbolsController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public AccountSymbolsController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ApiOperation(value = "get all accounts-symbols.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "create AccountSymbols.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse add(
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody AccountSymbolsNewAction accountNewAction) throws ExecutionException, InterruptedException {
return processRequest(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW, accountNewAction);
}
@ApiOperation(value = "delete AccountSymbols.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
public CudResponse delete(@ApiParam(value = "Идентификатор удаляемого объекта", required = true, example = "1234")
@PathVariable("id") Long id) throws ExecutionException, InterruptedException {
CommonDeleteAction deleteAction = new CommonDeleteAction();
deleteAction.setId(id);
return processRequest(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE, deleteAction);
}
}

View file

@ -1,28 +1,40 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.account.AccountInformationNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/accounting/information-accounts")
public class InformationAccountController {
public class InformationAccountController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public InformationAccountController(IStateLoader stateLoader) {
public InformationAccountController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ -37,4 +49,15 @@ public class InformationAccountController {
response.fromEntity(all);
return response;
}
// @ApiOperation(value = "Добавление информационного счета.")
// @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
// @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
// @ResponseBody
// public CudResponse add(
// @ApiParam(value = "Параметры команды в JSON формате.", required = true)
// @RequestBody AccountInformationNewAction accountNewInformationAction) throws ExecutionException, InterruptedException {
// return processRequest(Consts.DESTINATION_INFORMATION_ACCOUNT_NEW, accountNewInformationAction);
// }
}

View file

@ -1,22 +1,28 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
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.company.CompanyRoleSetNewAction;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/company-role-sets")
@ -41,4 +47,26 @@ public class CompanyRoleSetController extends AbstractQueueController {
response.fromEntity(all);
return response;
}
@ApiOperation(value = "create CompanyRoleSet.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse create(
@ApiParam(value = "Значения полей нового объекта.", required = true)
@RequestBody CompanyRoleSetNewAction companyRoleSetNewAction) throws ExecutionException, InterruptedException {
return processRequest(Consts.DESTINATION_COMPANY_ROLE_SET_NEW, companyRoleSetNewAction);
}
@ApiOperation(value = "delete CompanyRoleSet.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class)})
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
public CudResponse delete(@ApiParam(value = "Идентификатор удаляемого объекта", required = true, example = "1234")
@PathVariable("id") Long id) throws ExecutionException, InterruptedException {
CommonDeleteAction deleteAction = new CommonDeleteAction();
deleteAction.setId(id);
return processRequest(Consts.DESTINATION_COMPANY_ROLE_SET_DELETE, deleteAction);
}
}

View file

@ -14,7 +14,11 @@ import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllRespo
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
@ -22,11 +26,16 @@ import java.util.Map;
@RequestMapping("/execution-deposits")
public class ExecutionDepositController extends AbstractQueueController {
private final IStateLoader stateLoader;
private final ImdgPredicateBuilder imdgPredicateBuilder;
@Autowired
public ExecutionDepositController(IOperator operator, IStateLoader stateLoader) {
public ExecutionDepositController(IOperator operator, IStateLoader stateLoader,
ImdgProvider imdgProvider) {
super(operator);
this.stateLoader = stateLoader;
this.imdgPredicateBuilder = imdgProvider
.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class)
.predicateBuilder();
}
@ApiOperation(value = "get all ExecutionDeposits.")
@ -34,9 +43,11 @@ public class ExecutionDepositController extends AbstractQueueController {
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
ImdgPredicate imdgPredicate = imdgPredicateBuilder.greatEqual("firstLegSettlementDate", LocalDate.now());
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_ExecutionDeposit,
ExecutionDeposit.class);
ExecutionDeposit.class,
imdgPredicate);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;

View file

@ -14,7 +14,11 @@ import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllRespo
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
@ -22,11 +26,17 @@ import java.util.Map;
@RequestMapping("/execution-fonds")
public class ExecutionFondController extends AbstractQueueController {
private final IStateLoader stateLoader;
private final ImdgPredicateBuilder imdgPredicateBuilder;
@Autowired
public ExecutionFondController(IOperator operator, IStateLoader stateLoader) {
public ExecutionFondController(IOperator operator,
IStateLoader stateLoader,
ImdgProvider imdgProvider) {
super(operator);
this.stateLoader = stateLoader;
this.imdgPredicateBuilder = imdgProvider
.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class)
.predicateBuilder();
}
@ApiOperation(value = "get all ExecutionFond.")
@ -34,9 +44,11 @@ public class ExecutionFondController extends AbstractQueueController {
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
ImdgPredicate imdgPredicate = imdgPredicateBuilder.greatEqual("settlementDate", LocalDate.now());
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_ExecutionFond,
ExecutionFond.class);
ExecutionFond.class,
imdgPredicate);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;

View file

@ -0,0 +1,95 @@
package ru.spcex.clearing.backendapi.controller.queue.history;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.ConditionProvider;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.HistorySubscription;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@Controller
@RequestMapping("/history")
public class HistController {
private final GetResponseFactory responseFactory;
private final IStateLoader stateLoader;
private final ConditionProvider conditionProvider;
@Autowired
public HistController(GetResponseFactory responseFactory,
IStateLoader stateLoader,
ConditionProvider conditionProvider) {
this.responseFactory = responseFactory;
this.stateLoader = stateLoader;
this.conditionProvider = conditionProvider;
}
@ApiOperation(value = "Get history")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getHistory(
@ApiParam(value = "destination сущности по которой запрашивается история", example = "money-balance-registers", required = true)
@RequestParam("destination")
String destination,
@ApiParam(value = "Начальная точка поиска по дате", example = "2023-01-15")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@RequestParam(name = "from", required = false)
LocalDate from,
@ApiParam(value = "Конечная точка поиска по дате", example = "2023-01-15")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@RequestParam(name = "to", required = false)
LocalDate to
) {
if (to == null && from == null) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError, "from/to url params both empty"));
}
Optional<Class<? extends SpcexObjectBase>> entityClass = responseFactory.classByDestination(destination);
//class may be added to HistorySubscription if needed
if (entityClass.isEmpty()) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError,
"destination " + "'" + destination + "' not supported (meta class not found)"));
}
HistoryRequest req = new HistoryRequest();
req.setTable(destination);
req.setFrom(from);
req.setTo(to);
HistorySubscription[] subscr = new HistorySubscription[1];
ImdgPredicate[] prdct = new ImdgPredicate[1];
conditionProvider.conditionForRequest(req).map(s -> subscr[0] = s, p -> prdct[0] = p);
Collection<Map<String, Object>> searchRes = stateLoader.getAllMetaTransform(
subscr[0].getSearchProxyMapName(),
subscr[0].getFullHistoryMapName(),
entityClass.get(),
prdct[0]
);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(searchRes);
return response;
}
}

View file

@ -0,0 +1,72 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
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 ru.spcex.platform.utils.enumeration.EnumMessage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
public class ConditionProvider {
private final Logger log = LoggerFactory.getLogger(getClass());
private final GetResponseFactory responseFactory;
private final ImdgPredicateBuilder pb;
private final Map<String, HistorySubscription> subscriptions;
@Autowired
public ConditionProvider(GetResponseFactory responseFactory, ImdgProvider imdgProvider,
List<HistorySubscription> subscriptions) {
this.responseFactory = responseFactory;
this.subscriptions = new HashMap<>();
Imdg<SpcexObjectBase> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SearchMoneyBalanceRegister, SpcexObjectBase.class);
this.pb = imdg.predicateBuilder();
subscriptions.forEach(s -> this.subscriptions.put(s.getDestination(), s));
}
public Pair<HistorySubscription, ImdgPredicate> conditionForRequest(HistoryRequest req) {
String destination = req.getTable();
HistorySubscription subscription = subscriptions.get(destination);
if (subscription == null) {
throw new ActionValidationException(new EnumMessage(BackEndError.ValidationError,
"destination " + "'" + destination + "' not supported (subscription info not found)"));
}
List<ImdgPredicate> predicates = subscription
.getConditions()
.stream()
.map(c -> c.condition(req))
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
ImdgPredicate result;
if (predicates.size() == 0) {
//add boundary conditions?
log.warn("destination '{}' zero predicates found", destination);
result = pb.alwaysTrue();
} else if (predicates.size() == 1) {
result = predicates.iterator().next();
} else {
result = pb.and(predicates.toArray(new ImdgPredicate[0]));
}
return new Pair<>(subscription, result);
}
}

View file

@ -0,0 +1,46 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import java.util.Collections;
import java.util.List;
public class HistorySubscription {
private String destination;
private List<IHistoryCondition> conditions;
private String searchProxyMapName;
private String fullHistoryMapName;
//class
public List<IHistoryCondition> getConditions() {
return conditions != null ? conditions : Collections.emptyList();
}
public void setConditions(List<IHistoryCondition> conditions) {
this.conditions = conditions;
}
public String getSearchProxyMapName() {
return searchProxyMapName;
}
public void setSearchProxyMapName(String searchProxyMapName) {
this.searchProxyMapName = searchProxyMapName;
}
public String getFullHistoryMapName() {
return fullHistoryMapName;
}
public void setFullHistoryMapName(String fullHistoryMapName) {
this.fullHistoryMapName = fullHistoryMapName;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
}

View file

@ -0,0 +1,15 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import java.util.Optional;
public interface IHistoryCondition {
Optional<ImdgPredicate> condition(HistoryRequest req);
default Optional<ImdgPredicate> of(ImdgPredicate predicate) {
return Optional.of(predicate);
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class ClearingDateFromCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public ClearingDateFromCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getFrom() != null) {
return Optional.ofNullable(pb.greatEqual("clearingDate", req.getFrom()));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class ClearingDateToCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public ClearingDateToCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getTo() != null) {
return Optional.ofNullable(pb.lessEqual("clearingDate", req.getTo()));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,26 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.time.TimeUtil;
import java.util.Optional;
public class CreatedFromCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public CreatedFromCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getFrom() != null) {
return Optional.of(pb.greatEqual("created", TimeUtil.localDateToInstant(req.getFrom())));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,26 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.time.TimeUtil;
import java.util.Optional;
public class CreatedToCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public CreatedToCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getTo() != null) {
return Optional.of(pb.lessEqual("created", TimeUtil.localDateToInstant(req.getTo())));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class TradingDateFromCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public TradingDateFromCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getFrom() != null) {
return Optional.ofNullable(pb.greatEqual("tradingDate", req.getFrom()));
}
return Optional.empty();
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.backendapi.controller.queue.history.condition.specific;
import ru.spcex.clearing.backendapi.controller.queue.history.condition.IHistoryCondition;
import ru.spcex.clearing.backendapi.controller.request.cud.history.HistoryRequest;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.util.Optional;
public class TradingDateToCondition implements IHistoryCondition {
private final ImdgPredicateBuilder pb;
public TradingDateToCondition(ImdgPredicateBuilder pb) {
this.pb = pb;
}
@Override
public Optional<ImdgPredicate> condition(HistoryRequest req) {
if (req.getTo() != null) {
return Optional.ofNullable(pb.lessEqual("tradingDate", req.getTo()));
}
return Optional.empty();
}
}

View file

@ -10,9 +10,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.ReturnDepositActionNew;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.*;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
@ -70,6 +68,19 @@ public class RegistryController extends AbstractQueueController {
return processRequest(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, returnDepositAction);
}
@ApiOperation(value = "Отметить средства на возврат депозита")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/identificationFunds/{id}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse identificationFundsAction(
@ApiParam(value = "Идентификатор изменяемого объекта.", required = true, example = "1234")
@PathVariable("id") Long id,
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody IdentificationFundsActionNew identificationFundsActionNew) throws ExecutionException, InterruptedException {
identificationFundsActionNew.setId(id);
return processRequest(Consts.REGISTRY_IDENTIFICATION_FUNDS, identificationFundsActionNew);
}
@ApiOperation(value = "Изменение даты возврата депозита")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/changeRefundDate/{groupId}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ -82,4 +93,18 @@ public class RegistryController extends AbstractQueueController {
returnDepositAction.setGroupId(groupId);
return processRequest(Consts.REGISTRY_CHANGE_REFUND_DATE_ACTION, returnDepositAction);
}
@ApiOperation(value = "Установить отметку о получение выписки")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/changeStatusExtract/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse changeStatusExtract(
@ApiParam(value = "Идентификатор регистра.", required = true, example = "1234")
@PathVariable("id") Long id,
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody ChangeStatusExtractActionNew changeStatusExtractAction) throws ExecutionException, InterruptedException {
changeStatusExtractAction.setId(id);
return processRequest(Consts.REGISTRY_CHANGE_STATUS_EXTRACT_ACTION, changeStatusExtractAction);
}
}

View file

@ -0,0 +1,71 @@
package ru.spcex.clearing.backendapi.controller.request.cud.account;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest;
public class AccountInformationNewAction implements IAction<InformationAccountNewRequest> {
@ApiModelProperty(value = "Наименование компании", example = "1200")
@JsonProperty
private Long companyId;
@ApiModelProperty(value = "Номер счета", example = "A30101111111111111776")
@JsonProperty
private String account;
@ApiModelProperty(value = "Наименование статуса", example = "ACTV")
@JsonProperty
private String status;
@ApiModelProperty(value = "Наименование типа счета", example = "INFO")
@JsonProperty
private String accountType;
@Override
public InformationAccountNewRequest toRequest() {
var req = new InformationAccountNewRequest();
req.setCompanyId(this.companyId);
req.setAccount(this.account);
req.setStatus(this.status);
req.setAccountType(this.accountType);
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
}

View file

@ -0,0 +1,47 @@
package ru.spcex.clearing.backendapi.controller.request.cud.account;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
public class AccountSymbolsNewAction implements IAction<AccountSymbolsNewRequest> {
@ApiModelProperty(value = "Номер счета", example = "1200")
@JsonProperty
private Long accountId;
@ApiModelProperty(value = "Значение реквизита", example = "ABCD")
@JsonProperty
private String accountSymbolValue;
@Override
public AccountSymbolsNewRequest toRequest() {
var req = new AccountSymbolsNewRequest();
req.setAccountId(this.accountId);
req.setAccountSymbolValue(this.accountSymbolValue);
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getAccountSymbolValue() {
return accountSymbolValue;
}
public void setAccountSymbolValue(String accountSymbolValue) {
this.accountSymbolValue = accountSymbolValue;
}
}

View file

@ -0,0 +1,59 @@
package ru.spcex.clearing.backendapi.controller.request.cud.company;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyRoleSetNewRequest;
public class CompanyRoleSetNewAction implements IAction<CompanyRoleSetNewRequest> {
@ApiModelProperty(value = "Наименование компании", example = "1234")
@JsonProperty
Long companyId;
@ApiModelProperty(value = "Код роли компании", example = "ABCD")
@JsonProperty
String companyRole;
@ApiModelProperty(value = "Код статуса", example = "ACTV")
@JsonProperty
String workflowStatus;
@Override
public CompanyRoleSetNewRequest toRequest() {
CompanyRoleSetNewRequest request = new CompanyRoleSetNewRequest();
request.setCompanyId(this.companyId);
request.setCompanyRole(this.companyRole);
request.setWorkflowStatus(this.workflowStatus);
return request;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public String getCompanyRole() {
return companyRole;
}
public void setCompanyRole(String companyRole) {
this.companyRole = companyRole;
}
public String getWorkflowStatus() {
return workflowStatus;
}
public void setWorkflowStatus(String workflowStatus) {
this.workflowStatus = workflowStatus;
}
}

View file

@ -0,0 +1,51 @@
package ru.spcex.clearing.backendapi.controller.request.cud.history;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer;
import java.time.LocalDate;
public class HistoryRequest {
@ApiModelProperty(value = "Таблица для поиска", example = "1200")
@JsonProperty
private String table;
@ApiModelProperty(value = "Начальный точка поиска по дате", example = "2022-12-25")
@JsonProperty
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate from;
@ApiModelProperty(value = "Конечная точка поиска по дате ", example = "2022-12-25")
@JsonProperty
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate to;
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public LocalDate getFrom() {
return from;
}
public void setFrom(LocalDate from) {
this.from = from;
}
public LocalDate getTo() {
return to;
}
public void setTo(LocalDate to) {
this.to = to;
}
}

View file

@ -0,0 +1,82 @@
package ru.spcex.clearing.backendapi.controller.request.cud.registry;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import java.math.BigDecimal;
public class ChangeStatusExtractActionNew implements IAction<RegistryChangeStatusExtractRequest> {
@JsonIgnore
public Long id;
@JsonProperty
public String shortName;
@JsonProperty
public String contract;
@JsonProperty
public BigDecimal balance;
@JsonProperty
public String registryStatus;
@Override
public RegistryChangeStatusExtractRequest toRequest() {
var req = new RegistryChangeStatusExtractRequest();
req.setId(id);
req.setShortName(shortName);
req.setContract(contract);
req.setBalance(balance);
req.setRegistryStatus(registryStatus);
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.UPDATE;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public String getContract() {
return contract;
}
public void setContract(String contract) {
this.contract = contract;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public String getRegistryStatus() {
return registryStatus;
}
public void setRegistryStatus(String registryStatus) {
this.registryStatus = registryStatus;
}
}

View file

@ -0,0 +1,89 @@
package ru.spcex.clearing.backendapi.controller.request.cud.registry;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.IdentificationFundsRequest;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class IdentificationFundsActionNew implements IAction<IdentificationFundsRequest>, WithId {
@JsonIgnore
public Long id;
@ApiModelProperty(value = "Сумма", example = "1600.20")
@JsonProperty
public BigDecimal balance;
@ApiModelProperty(value = "Торгово-клиринговый регистр", example = "1234")
@JsonProperty
public Long tradingClearingRegistryId;
@ApiModelProperty(value = "Идентификатор компании", example = "1234")
@JsonProperty
public Long companyId;
@Override
public IdentificationFundsRequest toRequest() {
var req = new IdentificationFundsRequest();
req.setId(id);
req.setBalance(balance);
req.setTradingClearingRegistryId(tradingClearingRegistryId);
req.setCompanyId(companyId);
return req;
}
@Override
public Collection<EnumMessage> validate() {
List<EnumMessage> errors = new ArrayList<>();
if (id == null) {
errors.add(new EnumMessage(BackEndError.ValidationError, "url parameter 'id'"));
}
return errors;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public Long getTradingClearingRegistryId() {
return tradingClearingRegistryId;
}
public void setTradingClearingRegistryId(Long tradingClearingRegistryId) {
this.tradingClearingRegistryId = tradingClearingRegistryId;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
}

View file

@ -13,6 +13,10 @@ public class NotificationUpdateAction implements IAction<NotificationUpdateReque
@ApiModelProperty(value = "Наименование статуса сообщения", example = "ACTV")
@JsonProperty
public String notificationStatus;
@ApiModelProperty(value = "Наименование отправителя (не исопльзуется)", example = "1234")
@JsonProperty(required = false)
@Deprecated
public Long senderId;
@Override
public NotificationUpdateRequest toRequest() {
@ -43,4 +47,12 @@ public class NotificationUpdateAction implements IAction<NotificationUpdateReque
public void setNotificationStatus(String notificationStatus) {
this.notificationStatus = notificationStatus;
}
public Long getSenderId() {
return senderId;
}
public void setSenderId(Long senderId) {
this.senderId = senderId;
}
}

View file

@ -36,9 +36,12 @@ public class LauncherNew implements IAction<Object> {
@JsonProperty
private Long sessionId;
@ApiModelProperty(value = "Текущий баланс", example = "12.22")
@ApiModelProperty(value = "Текущий баланс (свободно)", example = "12.22")
@JsonProperty
private BigDecimal balance;
@ApiModelProperty(value = "Текущий баланс (всего)", example = "12.22")
@JsonProperty
private BigDecimal fullBalance;
@ApiModelProperty(value = "Наименование инструмента/валюты", example = "SPB")
@JsonProperty
private String securitySymbol;
@ -72,6 +75,7 @@ public class LauncherNew implements IAction<Object> {
taskRunnerCommandRequest.setSessionType(sessionType);
taskRunnerCommandRequest.setSessionId(sessionId);
taskRunnerCommandRequest.setBalance(balance);
taskRunnerCommandRequest.setFullBalance(fullBalance);
taskRunnerCommandRequest.setSecuritySymbol(securitySymbol);
taskRunnerCommandRequest.setCreditLeg_amount(creditLeg_amount);
taskRunnerCommandRequest.setPaymentPurpose(paymentPurpose);
@ -215,4 +219,12 @@ public class LauncherNew implements IAction<Object> {
public void setDebitLeg_accountId(Long debitLeg_accountId) {
this.debitLeg_accountId = debitLeg_accountId;
}
public BigDecimal getFullBalance() {
return fullBalance;
}
public void setFullBalance(BigDecimal fullBalance) {
this.fullBalance = fullBalance;
}
}

View file

@ -1,60 +0,0 @@
package ru.spcex.clearing.backendapi.controller.test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.ApiModelProperty;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
public class AnyKafkaMessageAction implements IAction<TradingClearingRegistryNewRequest> {
@ApiModelProperty(value = "полное имя класса payload для BaseRequest", example = "ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest")
@JsonProperty
private String fullClassName;
@JsonProperty
private String topicName;
@JsonRawValue
public String json;
@JsonProperty("json")
private void unpackRawJson(JsonNode json) {
this.json = json.toString();
}
@Override
public TradingClearingRegistryNewRequest toRequest() {
var req = new TradingClearingRegistryNewRequest();
return req;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.SYSTEM;
}
public String getFullClassName() {
return fullClassName;
}
public void setFullClassName(String fullClassName) {
this.fullClassName = fullClassName;
}
public String getTopicName() {
return topicName;
}
public void setTopicName(String topicName) {
this.topicName = topicName;
}
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
}

View file

@ -1,68 +0,0 @@
package ru.spcex.clearing.backendapi.controller.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.spcex.clearing.backendapi.errors.BackEndError;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.error.ValidationException;
import ru.spcex.platform.utils.text.TextUtil;
@Controller
@RequestMapping("/anonymous/kafka-api")
public class KafkaApiController {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private static final ObjectMapper json = new ObjectMapper();
static {
}
@Autowired
public KafkaApiController(KafkaSender kafkaSender) {
this.kafkaSender = kafkaSender;
}
@ApiOperation(value = "Test backend-api availability.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = String.class)})
@RequestMapping(method = RequestMethod.POST, path = "/any/message", produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String processGet(@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody AnyKafkaMessageAction bankAccountNewAction) throws ClassNotFoundException, ValidationException, JsonProcessingException {
log.info("Call test method for backend-api controller");
validate(bankAccountNewAction);
Class<?> parameterType = ClassUtils.forName(bankAccountNewAction.getFullClassName(), ClassUtils.getDefaultClassLoader());
JavaType requestType = json.getTypeFactory().constructSimpleType(parameterType, null);
Object obj = json.readValue(bankAccountNewAction.getJson(), requestType);
Long idOfBaseRequestMessage = kafkaSender.sendRequestToQueue(bankAccountNewAction.getTopicName(), obj);
log.debug("Test message to topic {} with request id={}", bankAccountNewAction.getTopicName(), idOfBaseRequestMessage);
return "success: baseRequest.id = " + idOfBaseRequestMessage;
}
private void validate(AnyKafkaMessageAction bankAccountNewAction) throws ValidationException {
if (TextUtil.isEmpty(bankAccountNewAction.getTopicName())) {
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "topicName"));
}
if (TextUtil.isEmpty(bankAccountNewAction.getFullClassName())) {
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "fullClassName"));
}
if (TextUtil.isEmpty(bankAccountNewAction.getJson())) {
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "json"));
}
}
}

View file

@ -5,6 +5,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.utils.time.TimeUtil;
import java.text.SimpleDateFormat;
@ -130,6 +131,19 @@ public class GetResponseFactory {
response.put(name, data);
}
public Optional<Class<? extends SpcexObjectBase>> classByDestination(String destination) {
Map<String, ObjectExtracted> extracted = meta.getObjectsExtractedByDestination();
ObjectExtracted objectExtracted = extracted.get(destination);
if (objectExtracted == null) return Optional.empty();
try {
Class<? extends SpcexObjectBase> clazz = (Class<? extends SpcexObjectBase>) objectExtracted.getClazz();
return Optional.ofNullable(clazz);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
return Optional.empty();
}
}
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss+03:00")
.withLocale(Locale.US)

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.backendapi.meta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.text.TextUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@ -67,6 +68,8 @@ public class MetaServer extends MetaBase {
objectsExtractedByClazz.put(String.valueOf(classNameMock++), oe);
if (objectElement.getSubscription() != null && objectElement.getSubscription().destination != null) {
objectsExtractedByDestination.put(objectElement.getSubscription().destination, oe);
} else if (!TextUtil.isEmpty(objectElement.getDestination())) {
objectsExtractedByDestination.put(objectElement.getDestination(), oe);
}
for (ActionElement actionElement : objectElement.getActions()) {
if (actionElement.getClazz() == null) {

View file

@ -18,6 +18,10 @@ public class ObjectElement {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String table = null;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String destination = null;
@JsonProperty(value = "fields", required = true)
private List<ActionField> fields = new LinkedList<>();
@ -76,4 +80,12 @@ public class ObjectElement {
public Subscription getSubscriptionHistory() {
return subscriptionHistory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
}

View file

@ -1,6 +1,7 @@
package ru.spcex.clearing.backendapi.service;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import java.util.Collection;
import java.util.Map;
@ -15,4 +16,10 @@ public interface IStateLoader {
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransformSpecificClass(String mapName, Class<T> clazz);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, Map<String, ? extends Comparable<?>> conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, ImdgPredicate conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(
String searchMapName,
String mapName,
Class<T> clazz,
ImdgPredicate conditions);
}

View file

@ -1,28 +1,33 @@
package ru.spcex.clearing.backendapi.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class StateLoaderImpl implements IStateLoader {
private final Map<String, Imdg<?>> allImdgMaps;
private final Map<String, Imdg<?>> allHistMaps;
private final ImdgProvider imdgProvider;
private final ImdgProvider imdgHistProvider;
private final GetResponseFactory responseFactory;
@Autowired
public StateLoaderImpl(ImdgProvider imdgProvider, GetResponseFactory responseFactory) {
public StateLoaderImpl(@Qualifier("imdgProvider") ImdgProvider imdgProvider,
@Qualifier("imdgProviderHist") ImdgProvider imdgHistProvider, GetResponseFactory responseFactory) {
this.imdgHistProvider = imdgHistProvider;
this.responseFactory = responseFactory;
this.allImdgMaps = new ConcurrentHashMap<>();
this.allHistMaps = new HashMap<>();
this.imdgProvider = imdgProvider;
}
@ -59,8 +64,38 @@ public class StateLoaderImpl implements IStateLoader {
return responseFactory.responseFromObjectCollection(all);
}
@Override
public <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName,
Class<T> clazz,
ImdgPredicate conditions) {
Imdg<T> imdg = getImdg(mapName, clazz);
Collection<T> all = imdg.getCollectionObjectsByPredicate(conditions);
return responseFactory.responseFromObjectCollection(all);
}
@SuppressWarnings("unchecked")
private <T extends SpcexObjectBase> Imdg<T> getImdg(String mapName, Class<T> clazz) {
return (Imdg<T>) allImdgMaps.computeIfAbsent(mapName, (mapName1) -> imdgProvider.getImdg(mapName, clazz));
}
@SuppressWarnings("unchecked")
private <T extends SpcexObjectBase> Imdg<T> getHistImdg(String mapName, Class<T> clazz) {
return (Imdg<T>) allHistMaps.computeIfAbsent(mapName, (mapName1) -> imdgHistProvider.getImdg(mapName, clazz));
}
@Override
public <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(
String searchMapName,
String mapName,
Class<T> clazz,
ImdgPredicate conditions) {
Imdg<SpcexObjectBase> imdgSearch = getHistImdg(searchMapName, SpcexObjectBase.class);
Imdg<T> imdgHistory = getHistImdg(mapName, clazz);
Collection<Long> ids = imdgSearch.getCollectionIdsByPredicate(conditions);
return ids.stream()
.map(imdgHistory::getSingleObjectByID)
.filter(Objects::nonNull)
.map(o -> responseFactory.responseFromObject(o, clazz))
.toList();
}
}

View file

@ -87,8 +87,14 @@ public class ActionMetaValidation implements InitializingBean {
Object value = field.extractValue(object);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
log.warn("Error self-test validator on class {} and field {}: {}",
metaAction.getClazz(), field.getMemberName(), ExceptionUtils.getStackTrace(e));
String className = metaAction.getClazz().getName();
if (className.endsWith(".MoneyMarketSecurityUpdateAction") || className.endsWith(".ChangeRefundDateActionNew")) {
log.warn("Expected warning self-test validator on class {} and field {}: {}",
className, field.getMemberName(), e.toString());
} else {
log.warn("Error self-test validator on class {} and field {}: {}",
className, field.getMemberName(), ExceptionUtils.getStackTrace(e));
}
}
}
}

View file

@ -9,6 +9,9 @@ backend-api.example-setting=test
backend-api.hazelcast.cluster-members=127.0.0.1:5701
backend-api.hazelcast.login=dev
backend-api.hazelcast.password=dev-pass
backend-api.hazelcast-search.cluster-members=127.0.0.1:5702
backend-api.hazelcast-search.login=dev-hist
backend-api.hazelcast-search.password=dev-pass-hist
backend-api.kafka-producer.bootstrap-servers=localhost:9092
backend-api.kafka-producer.acks=all
backend-api.kafka-producer.retries=0

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<meta version="3.5.0.13">
<meta version="3.9.0.68">
<enums>
<allowed id="1" code="ALWD" name="Разрешено"/>
<allowed id="2" code="DEND" name="Запрещено"/>
@ -111,7 +111,7 @@
<tradingClearingRegistryType id="1" code="A" name="Владелец"/>
<tradingClearingRegistryType id="2" code="B" name="Клиентский"/>
<tradingClearingRegistryType id="3" code="C" name="Попечитель"/>
<tradingClearingRegistryType id="3" code="C" name="Клиентский"/>
<tradingClearingRegistryType id="4" code="D" name="Доверительный управляющий"/>
<tradingClearingRegistryType id="5" code="E" name="Эмитент"/>
<tradingClearingRegistryType id="6" code="Z" name="К размещению/выкупу"/>
@ -155,7 +155,8 @@
<registryUnit id="4" code="C" name="Комиссия"/>
<registryUnit id="5" code="U" name="Невыясненные"/>
<registryUnit id="5" code="I" name="Списания/зачисления"/>
<registryCode id="1" code="AMAT" name="Денежные средства - общие"/>
<registryUnit id="7" code="V" name="Выписка"/>
<registryCode id="1" code="AMAT" name="Денежные средства Участника клиринга, зарезервированные на торги"/>
<registryCode id="2" code="AMAF" name="Денежные средства - свободные"/>
<registryCode id="3" code="AMAB" name="Денежные средства - блокированные"/>
<registryCode id="4" code="TMAT" name="Требования по деньгам"/>
@ -166,7 +167,7 @@
<registryCode id="9" code="LSAT" name="Рассчитанные обязательства по бумагам"/>
<registryCode id="10" code="LMAT" name="Рассчитанные обязательства по деньгам"/>
<registryCode id="11" code="CSAT" name="Рассчитанные требования по бумагам"/>
<registryCode id="12" code="AMBT" name="Денежные средства клиента - общие"/>
<registryCode id="12" code="AMBT" name="Денежные средства Участника клиринга, зарезервированные на торги клиенты"/>
<registryCode id="13" code="AMBF" name="Денежные средства клиента - свободные"/>
<registryCode id="14" code="AMBB" name="Денежные средства клиента - блокированные"/>
<registryCode id="15" code="TMBT" name="Требования по деньгам (кл)"/>
@ -179,12 +180,18 @@
<registryCode id="22" code="CSBT" name="Рассчитанные требования по бумагам (кл)"/>
<registryCode id="23" code="DMAT" name="Возврат депозита"/>
<registryCode id="24" code="DMBT" name="Возврат депозита (кл)"/>
<registryCode id="25" code="ASAT" name="Ценные бумаги - общие"/>
<registryCode id="25" code="ASAT" name="Ценные бумаги Участника клиринга свои"/>
<registryCode id="26" code="ASAF" name="Ценные бумаги - свободные"/>
<registryCode id="27" code="ASAB" name="Ценные бумаги - блокированные"/>
<registryCode id="28" code="DMAX" name="Возврат инициатору"/>
<registryCode id="29" code="DMBX" name="Возврат инициатору (кл)"/>
<registryCode id="30" code="DMAU" name="Денежные средства - невыясненные"/>
<registryCode id="31" code="DMAV" name="Треб. выписки"/>
<registryCode id="32" code="ASZT" name="Ценные бумаги для размещения/выкупа"/>
<registryCode id="33" code="ASBT" name="Ценные бумаги Участника клиринга клиенты"/>
<registryCode id="34" code="ASCT" name="Ценные бумаги Участника клиринга клиенты-нерезиденты"/>
<registryCode id="35" code="AMCT" name="Денежные средства Участника клиринга, зарезервированные на торги клиенты"/>
<registryCode id="36" code="ASXT" name="Ценные бумаги Участника клиринга ДУ"/>
<registryStatus id="1" code="OK" name="Рассчитано"/>
<registryStatus id="2" code="UNCV" name="Не исполнено"/>
<registryStatus id="3" code="FAIL" name="Не исполнено контрагентом"/>
@ -211,7 +218,7 @@
<accountType id="10" code="DTRN" name="Депозитарный транзакционный счет"/>
<depoAccountType id="1" code="A" name="Счет участника"/>
<depoAccountType id="2" code="B" name="Счет клиента"/>
<depoAccountType id="3" code="C" name="Счет попечителя"/>
<depoAccountType id="3" code="C" name="Счет нерезидента"/>
<depoAccountType id="4" code="D" name="Счет доверительного управляющего"/>
<depoAccountType id="5" code="Z" name="Счет к размещению/выкупу"/>
<depoAccountType id="6" code="F" name="Счет держателя"/>
@ -243,6 +250,10 @@
<task id="23" code="GRET" name="Формирование отчетности по сделкам"/>
<task id="24" code="GREF" name="Формирование итоговой отчетности"/>
<task id="25" code="FDFF" name="Формирование ДФ-05 с кодом 9 (финальный)"/>
<task id="26" code="SDEP" name="Время начала возврата депозитов"/>
<task id="27" code="EDEP" name="Время завершения возврата депозитов"/>
<task id="28" code="CHDF" name="Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21"/>
<task id="29" code="CCLR" name="Завершение неудачных клиринговых сессий"/>
<taskStatus id="1" code="ACTV" name="Активна"/>
<taskStatus id="2" code="BLKD" name="Не активна"/>
<taskStatus id="3" code="CNCL" name="Отмена расписания"/>
@ -269,7 +280,7 @@
<sessionType id="1" code="FINL" name="Итоговая клиринговая сессия"/>
<sessionType id="2" code="MEDM" name="Промежуточная клиринговая сессия"/>
<sessionType id="3" code="XDEP" name="Промежуточная возврат депозитов"/>
<sessionType id="3" code="XDEP" name="Возврат депозитов"/>
<sessionType id="4" code="IPOT" name="Первичные торги Т0"/>
<sessionType id="5" code="TRDT" name="Вторичные торги Т0"/>
<sessionType id="6" code="LIQU" name="Ликвидационное прекращение обязательств"/>
@ -310,6 +321,8 @@
<objectType id="2" code="VFRS" name="verificationResult"/>
<objectType id="3" code="RGST" name="registry"/>
<objectType id="4" code="GTWY" name="gateway-api"/>
<objectType id="5" code="ACCA" name="account"/>
<objectType id="6" code="ACCB" name="account"/>
<notificationStatus id="1" code="PEND" name="В ожидании"/>
<notificationStatus id="2" code="CNCL" name="Отменено"/>
<notificationStatus id="3" code="ACPT" name="Принято"/>
@ -343,7 +356,7 @@
<errorCode id="1008" code="SECR" name="Пользователь %s неактивен."/>
<errorCode id="1010" code="SECR" name="Инструмент %s уже существует."/>
<errorCode id="1011" code="SECR" name="Инструмент %s не найден."/>
<errorCode id="1012" code="SECR" name="Инструмент %s неактивен."/>
<errorCode id="1012" code="SECR" name="Инструмент %s неактивен."/> <!-- параметр security.securitySymbol -->
<errorCode id="1013" code="SECR" name="Запись по инструменту %s уже существует."/>
<errorCode id="1014" code="SECR" name="Запись по инструменту %s не найдена."/>
<errorCode id="1015" code="SECR" name="Валюта %s уже существует."/>
@ -377,7 +390,7 @@
<errorCode id="3006" code="CMPN" name="Запись с идентификатором %s не найдена."/>
<errorCode id="3010" code="CMPN" name="Компания %s уже существует"/>
<errorCode id="3011" code="CMPN" name="Компания %s не найдена."/>
<errorCode id="3012" code="CMPN" name="Компания %s неактивна."/>
<errorCode id="3012" code="CMPN" name="Компания %s неактивна."/> <!-- параметр company.shortName -->
<errorCode id="3013" code="CMPN" name="Профиль компании %s не найден."/>
<errorCode id="3014" code="CMPN" name="Реквизит компании %s не найден."/>
<errorCode id="3015" code="CMPN" name="Контакт компании %s не найден."/>
@ -420,6 +433,8 @@
<errorCode id="5019" code="ACNT" name="Для компании %s отсутствует категория %s."/>
<errorCode id="5022" code="ACNT" name="Для компании %s отсутствует клиринговый код."/>
<errorCode id="5023" code="ACNT" name="Счет %s уже используется."/>
<errorCode id="5024" code="ACNT" name="Не указан номер счета."/>
<errorCode id="5025" code="ACNT" name="Необходимо указать ДЕПО счет."/>
<!-- error code for balance-service -->
<errorCode id="5200" code="BLNC" name="Общая ошибка модуля balance-service."/>
<errorCode id="5210" code="BLNC" name="Клиринговая сессия неактивна."/>
@ -461,10 +476,15 @@
<errorCode id="5423" code="CLRN" name="Новые сделки отсутствуют."/>
<errorCode id="5424" code="CLRN" name="Идентифицированные средства по возврату депозита превышают обязательства"/>
<errorCode id="5425" code="CLRN" name="Запрещена идентификация средства по рассчитанным обязательствам."/>
<errorCode id="5426" code="CLRN" name="Режим списаний и зачислений отключен в настройках модуля."/>
<errorCode id="5426" code="CLRN" name="Дата оплаты вклада депозита меньше новой даты возврата."/>
<errorCode id="5427" code="CLRN" name="Найдено больше одной записи %s."/>
<errorCode id="5428" code="CLRN" name="Активная клиринговая сессия уже существует."/>
<errorCode id="5429" code="CLRN" name="ДФ57 Счет %s не соответствует компании %s"/>
<errorCode id="5430" code="CLRN" name="Неверный код регистра: %s"/>
<errorCode id="5431" code="CLRN" name="Дата возврата для депозита с разделением не может быть изменена"/>
<errorCode id="5432" code="CLRN" name="После сверки обнаружена разница между плановым и фактическим балансом"/>
<errorCode id="5433" code="CLRN" name="Сессия по возврату депозита не может исполняться вне временного интервала, установленного в системе"/>
<errorCode id="5434" code="CLRN" name="Операция невозможна по счету с типом %s."/>
<!-- error code for dbf-importer -->
<errorCode id="5600" code="DBFI" name="Общая ошибка модуля dbf-importer."/>
<!-- error code for dbf-exporter -->
@ -474,6 +494,8 @@
<errorCode id="6000" code="GTWA" name="Общая ошибка модуля gateway-api."/>
<errorCode id="6001" code="GTWA" name="Не удается найти запись %s в Company"/>
<errorCode id="6002" code="GTWA" name="Не удается найти запись %s в security"/>
<errorCode id="6003" code="GTWA" name="Превышен интервал ожидания ответа от внешней системы"/>
<errorCode id="6004" code="GTWA" name="Получен отрицательный ответ на запрос системы"/>
<!-- error code for scheduler-service -->
<errorCode id="7000" code="SCHD" name="Общая ошибка модуля scheduler-service."/>
@ -510,92 +532,6 @@
</enums>
<objects>
<company id="1" fullName="АО Санкт-Петербургская Валютная Биржа" shortName="СПВБ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="2" fullName="ЗАО «Петербургский Расчетный Центр»" shortName="ПРЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="3" fullName="Торговая организация" shortName="ТС" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="4" fullName="ЗАО «Санкт-Петербургский Расчетно-Депозитарный Центр»" shortName="РДЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<!--company id="5" fullName="Центральный Банк Российской Федерации" shortName="ЦБ РФ" tradingCode="" clearingCode="" workflowStatus="ACTV"/-->
<companySymbols id="1" companyId="1" companySymbol="BIC" companySymbolValue="044030920"/>
<companySymbols id="2" companyId="2" companySymbol="BIC" companySymbolValue="044030505"/>
<currency id="643" currency_code="RUB"/>
<security instrumentType="CRNC" shortName="RUB" fullName="Российский рубль" securitySymbol="RUB" workflowStatus="ACTV" id="643"/>
<account id="1" companyId="1" account="30414810300000006000" accountType="TRAN" status="ACTV" processingSign="ALWD"/>
<account id="2" companyId="1" account="30414810600000007000" accountType="ANLT" status="ACTV" processingSign="ALWD"/>
<account id="3" companyId="1" account="700100000AT0" accountType="DTRN" status="ACTV" processingSign="ALWD"/>
<market id="1" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UESC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Обыкновенные акции"/>
<market id="2" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NESC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Обыкновенные акции"/>
<market id="3" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DESC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Обыкновенные акции"/>
<market id="4" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AESC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Обыкновенные акции"/>
<market id="5" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WESC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Обыкновенные акции"/>
<market id="6" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UEPC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Привилегированные акции"/>
<market id="7" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NEPC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Привилегированные акции"/>
<market id="8" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DEPC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Привилегированные акции"/>
<market id="9" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AEPC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Привилегированные акции"/>
<market id="10" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WEPC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Привилегированные акции"/>
<market id="11" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABVC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с переменным купоном"/>
<market id="12" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBVC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с переменным купоном"/>
<market id="13" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с переменным купоном"/>
<market id="14" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с переменным купоном"/>
<market id="15" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с переменным купоном"/>
<market id="16" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBVC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с переменным купоном"/>
<market id="17" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABFC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с постоянным купоном"/>
<market id="18" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBFC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с постоянным купоном"/>
<market id="19" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBFC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с постоянным купоном"/>
<market id="20" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBFC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с постоянным купоном"/>
<market id="21" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBFC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с постоянным купоном"/>
<market id="22" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBFC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с постоянным купоном"/>
<market id="23" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABIC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с индексированным номиналом"/>
<market id="24" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBIC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с индексированным номиналом"/>
<market id="25" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBIC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с индексированным номиналом"/>
<market id="26" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBIC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с индексированным номиналом"/>
<market id="27" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBIC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с индексированным номиналом"/>
<market id="28" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBIC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с индексированным номиналом"/>
<market id="29" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABMC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с амортизацией долга"/>
<market id="30" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBMC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с амортизацией долга"/>
<market id="31" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBMC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с амортизацией долга"/>
<market id="32" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBMC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с амортизацией долга"/>
<market id="33" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBMC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с амортизацией долга"/>
<market id="34" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBMC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с амортизацией долга"/>
<market id="35" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BKVC" name="Размещение: Аукцион БР" exchangeId="1" description="Размещение: Аукцион БР: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="36" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SKVC" name="Доразмещение: Адресные заявки БР" exchangeId="1" description="Доразмещение: Адресные заявки БР: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="37" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UKVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="38" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NKVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации Банка России с переменным купоном (КОБР)"/>
<market id="39" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DKVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="45" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABEC" name="Размещение: Аукцион СПВБ" exchangeId="1" description="Размещение: Аукцион СПВБ: Биржевые облигации"/>
<market id="46" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBEC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Биржевые облигации"/>
<market id="47" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBEC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Биржевые облигации"/>
<market id="48" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBEC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Биржевые облигации"/>
<market id="61" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMVC" name="ОФЗПК-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПК-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="62" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMVC" name="ОФЗПК-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПК-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="63" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMVC" name="ОФЗПК-Режим непрерывных торгов" exchangeId="1" description="ОФЗПК-Режим непрерывных торгов: Облигации Минфина"/>
<market id="64" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMVC" name="ОФЗПК-Дискретный аукцион" exchangeId="1" description="ОФЗПК-Дискретный аукцион: Облигации Минфина"/>
<market id="65" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMVC" name="ОФЗПК-Торги в режиме выкупа" exchangeId="1" description="ОФЗПК-Торги в режиме выкупа: Облигации Минфина"/>
<market id="66" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMFC" name="ОФЗПД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПД-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="67" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMFC" name="ОФЗПД- Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПД- Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="68" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMFC" name="ОФЗПД-Режим непрерывных торгов" exchangeId="1" description="ОФЗПД-Режим непрерывных торгов: Облигации Минфина"/>
<market id="69" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMFC" name="ОФЗПД-Дискретный аукцион" exchangeId="1" description="ОФЗПД-Дискретный аукцион: Облигации Минфина"/>
<market id="70" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMFC" name="ОФЗПД-Торги в режиме выкупа" exchangeId="1" description="ОФЗПД-Торги в режиме выкупа: Облигации Минфина"/>
<market id="71" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMMC" name="ОФЗАД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗАД-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="72" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMMC" name="ОФЗАД-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗАД-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="73" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMMC" name="ОФЗАД-Режим непрерывных торгов" exchangeId="1" description="ОФЗАД-Режим непрерывных торгов: Облигации Минфина"/>
<market id="74" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMMC" name="ОФЗАД-Дискретный аукцион" exchangeId="1" description="ОФЗАД-Дискретный аукцион: Облигации Минфина"/>
<market id="75" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMMC" name="ОФЗАД-Торги в режиме выкупа" exchangeId="1" description="ОФЗАД-Торги в режиме выкупа: Облигации Минфина"/>
<market id="76" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMIC" name="ОФЗИН-Размещение: Аукцион БР" exchangeId="1" description="ОФЗИН-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="77" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMIC" name="ОФЗИН-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗИН-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="78" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMIC" name="ОФЗИН-Режим непрерывных торгов" exchangeId="1" description="ОФЗИН-Режим непрерывных торгов: Облигации Минфина"/>
<market id="79" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMIC" name="ОФЗИН-Дискретный аукцион" exchangeId="1" description="ОФЗИН-Дискретный аукцион: Облигации Минфина"/>
<market id="80" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMIC" name="ОФЗИН-Торги в режиме выкупа" exchangeId="1" description="ОФЗИН-Торги в режиме выкупа: Облигации Минфина"/>
<market id="82" marketType="SCND" section="FOND" settlementCurrency="RUB" code="BBVC" name="ОФЗ-ПК - Аукцион БР" exchangeId="1" description="ОФЗ-ПК - Аукцион БР"/>
<market id="83" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTATSS" name="СПб ГУП АТС Смольного" exchangeId="1" description="СПб ГУП АТС Смольного"/>
<market id="88" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMTTKFSP" name="Комитет финансов СПб" exchangeId="1" description="Комитет финансов СПб"/>
<market id="89" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDSKFLO" name="Комитет финансов ЛО" exchangeId="1" description="Комитет финансов ЛО"/>
<market id="90" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTFSKB" name="ФСКМБ" exchangeId="1" description="ФСКМБ"/>
<market id="91" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDSFGGE" name="ФАУ ГГЭ" exchangeId="1" description="ФАУ ГГЭ"/>
<market id="92" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTVRGO" name="ВВО РГО" exchangeId="1" description="ВВО РГО"/>
<market id="93" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTTDRM" name="ООО Торговый дом РМ-Рейл" exchangeId="1" description="ООО Торговый дом РМ-Рейл"/>
<market id="95" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTRKFN" name="АО РК Финанс" exchangeId="1" description="АО РК Финанс"/>
</objects>
</meta>

View file

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<meta version="3.9.0.68">
<enums>
</enums>
<objects>
<company id="1" fullName="АО Санкт-Петербургская Валютная Биржа" shortName="СПВБ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="2" fullName="ЗАО «Петербургский Расчетный Центр»" shortName="ПРЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="3" fullName="Торговая организация" shortName="ТС" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<company id="4" fullName="ЗАО «Санкт-Петербургский Расчетно-Депозитарный Центр»" shortName="РДЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
<!--company id="5" fullName="Центральный Банк Российской Федерации" shortName="ЦБ РФ" tradingCode="" clearingCode="" workflowStatus="ACTV"/-->
<companySymbols id="1" companyId="1" companySymbol="BIC" companySymbolValue="044030920"/>
<companySymbols id="2" companyId="2" companySymbol="BIC" companySymbolValue="044030505"/>
<currency id="643" currency_code="RUB"/>
<security id="643" instrumentType="CRNC" shortName="RUB" fullName="Российский рубль" securitySymbol="RUB" workflowStatus="ACTV"/>
<account id="1" companyId="1" account="30414810300000006000" accountType="TRAN" status="ACTV" processingSign="ALWD"/>
<account id="2" companyId="1" account="30414810600000007000" accountType="ANLT" status="ACTV" processingSign="ALWD"/>
<account id="3" companyId="1" account="700100000AT0" accountType="DTRN" status="ACTV" processingSign="ALWD"/>
<market id="1" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UESC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Обыкновенные акции"/>
<market id="2" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NESC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Обыкновенные акции"/>
<market id="3" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DESC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Обыкновенные акции"/>
<market id="4" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AESC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Обыкновенные акции"/>
<market id="5" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WESC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Обыкновенные акции"/>
<market id="6" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UEPC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Привилегированные акции"/>
<market id="7" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NEPC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Привилегированные акции"/>
<market id="8" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DEPC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Привилегированные акции"/>
<market id="9" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AEPC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Привилегированные акции"/>
<market id="10" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WEPC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Привилегированные акции"/>
<market id="11" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABVC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с переменным купоном"/>
<market id="12" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBVC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с переменным купоном"/>
<market id="13" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с переменным купоном"/>
<market id="14" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с переменным купоном"/>
<market id="15" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с переменным купоном"/>
<market id="16" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBVC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с переменным купоном"/>
<market id="17" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABFC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с постоянным купоном"/>
<market id="18" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBFC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с постоянным купоном"/>
<market id="19" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBFC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с постоянным купоном"/>
<market id="20" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBFC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с постоянным купоном"/>
<market id="21" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBFC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с постоянным купоном"/>
<market id="22" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBFC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с постоянным купоном"/>
<market id="23" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABIC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с индексированным номиналом"/>
<market id="24" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBIC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с индексированным номиналом"/>
<market id="25" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBIC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с индексированным номиналом"/>
<market id="26" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBIC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с индексированным номиналом"/>
<market id="27" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBIC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с индексированным номиналом"/>
<market id="28" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBIC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с индексированным номиналом"/>
<market id="29" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABMC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с амортизацией долга"/>
<market id="30" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBMC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с амортизацией долга"/>
<market id="31" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBMC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с амортизацией долга"/>
<market id="32" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBMC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с амортизацией долга"/>
<market id="33" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBMC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с амортизацией долга"/>
<market id="34" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBMC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с амортизацией долга"/>
<market id="35" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BKVC" name="Размещение: Аукцион БР" exchangeId="1" description="Размещение: Аукцион БР: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="36" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SKVC" name="Доразмещение: Адресные заявки БР" exchangeId="1" description="Доразмещение: Адресные заявки БР: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="37" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UKVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="38" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NKVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации Банка России с переменным купоном (КОБР)"/>
<market id="39" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DKVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации Банка России с переменным купоном (КОБР)"/>
<market id="45" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABEC" name="Размещение: Аукцион СПВБ" exchangeId="1" description="Размещение: Аукцион СПВБ: Биржевые облигации"/>
<market id="46" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBEC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Биржевые облигации"/>
<market id="47" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBEC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Биржевые облигации"/>
<market id="48" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBEC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Биржевые облигации"/>
<market id="61" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMVC" name="ОФЗПК-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПК-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="62" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMVC" name="ОФЗПК-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПК-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="63" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMVC" name="ОФЗПК-Режим непрерывных торгов" exchangeId="1" description="ОФЗПК-Режим непрерывных торгов: Облигации Минфина"/>
<market id="64" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMVC" name="ОФЗПК-Дискретный аукцион" exchangeId="1" description="ОФЗПК-Дискретный аукцион: Облигации Минфина"/>
<market id="65" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMVC" name="ОФЗПК-Торги в режиме выкупа" exchangeId="1" description="ОФЗПК-Торги в режиме выкупа: Облигации Минфина"/>
<market id="66" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMFC" name="ОФЗПД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПД-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="67" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMFC" name="ОФЗПД- Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПД- Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="68" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMFC" name="ОФЗПД-Режим непрерывных торгов" exchangeId="1" description="ОФЗПД-Режим непрерывных торгов: Облигации Минфина"/>
<market id="69" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMFC" name="ОФЗПД-Дискретный аукцион" exchangeId="1" description="ОФЗПД-Дискретный аукцион: Облигации Минфина"/>
<market id="70" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMFC" name="ОФЗПД-Торги в режиме выкупа" exchangeId="1" description="ОФЗПД-Торги в режиме выкупа: Облигации Минфина"/>
<market id="71" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMMC" name="ОФЗАД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗАД-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="72" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMMC" name="ОФЗАД-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗАД-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="73" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMMC" name="ОФЗАД-Режим непрерывных торгов" exchangeId="1" description="ОФЗАД-Режим непрерывных торгов: Облигации Минфина"/>
<market id="74" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMMC" name="ОФЗАД-Дискретный аукцион" exchangeId="1" description="ОФЗАД-Дискретный аукцион: Облигации Минфина"/>
<market id="75" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMMC" name="ОФЗАД-Торги в режиме выкупа" exchangeId="1" description="ОФЗАД-Торги в режиме выкупа: Облигации Минфина"/>
<market id="76" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMIC" name="ОФЗИН-Размещение: Аукцион БР" exchangeId="1" description="ОФЗИН-Размещение: Аукцион БР: Облигации Минфина"/>
<market id="77" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMIC" name="ОФЗИН-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗИН-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
<market id="78" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMIC" name="ОФЗИН-Режим непрерывных торгов" exchangeId="1" description="ОФЗИН-Режим непрерывных торгов: Облигации Минфина"/>
<market id="79" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMIC" name="ОФЗИН-Дискретный аукцион" exchangeId="1" description="ОФЗИН-Дискретный аукцион: Облигации Минфина"/>
<market id="80" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMIC" name="ОФЗИН-Торги в режиме выкупа" exchangeId="1" description="ОФЗИН-Торги в режиме выкупа: Облигации Минфина"/>
<market id="82" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BBVC" name="ОФЗ-ПК - Аукцион БР" exchangeId="1" description="ОФЗ-ПК - Аукцион БР"/>
<market id="83" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTATSS" name="СПб ГУП АТС Смольного" exchangeId="1" description="СПб ГУП АТС Смольного"/>
<market id="88" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMTTKFSP" name="Комитет финансов СПб" exchangeId="1" description="Комитет финансов СПб"/>
<market id="89" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDSKFLO" name="Комитет финансов ЛО" exchangeId="1" description="Комитет финансов ЛО"/>
<market id="90" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTFSKB" name="ФСКМБ" exchangeId="1" description="ФСКМБ"/>
<market id="91" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDSFGGE" name="ФАУ ГГЭ" exchangeId="1" description="ФАУ ГГЭ"/>
<market id="92" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTVRGO" name="ВВО РГО" exchangeId="1" description="ВВО РГО"/>
<market id="93" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTTDRM" name="ООО Торговый дом РМ-Рейл" exchangeId="1" description="ООО Торговый дом РМ-Рейл"/>
<market id="95" marketType="PRMR" section="MKR" settlementCurrency="RUB" code="XMDTRKFN" name="АО РК Финанс" exchangeId="1" description="АО РК Финанс"/>
</objects>
</meta>

View file

@ -1,6 +1,6 @@
{
"version": "3.8.0.47",
"version": "3.9.0.71",
"enums": {
@ -2361,7 +2361,41 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "companyRole",
"type": 12,"dbname": "Код роли компании","name": "Наименование роли компании","shortname": "Роль","link": "companyRole","required": true
}
,
{"code": "workflowStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "companyRoleSet","linkCode": "id","required": true
}
]
}
]
}
,
"security": {
@ -2739,7 +2773,7 @@
"destination": "securities/traded-money-securities",
"class": "ru.clearing.classes.statics.data.misc.TradedMoneyMarketSecurity",
"class": "ru.clearing.classes.statics.data.security.TradedMoneyMarketSecurity",
"table": "traded_money_market_security",
@ -3294,11 +3328,11 @@
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
}
,
{"code": "periodEndDate",
{"code": "periodStartDate",
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
}
,
{"code": "periodStartDate",
{"code": "periodEndDate",
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
}
,
@ -4026,7 +4060,7 @@
,"actions":[
{"method":"post",
"name": "Досрочное изъятие депозита",
"name": "Разделение депозита",
"destination": "registries/splitDeposit",
@ -4077,6 +4111,35 @@
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
]
}
,
{"method":"post",
"name": "Идентификация неразмеченных средств",
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
,
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
]
}
,
@ -4102,6 +4165,39 @@
{"code": "refundDate",
"type": 6,"name": "Дата возврата депозита","shortname": "Возврат депозита","visible": true,"enabled": true
}
]
}
,
{"method":"put",
"name": "Установить отметку о получении выписки",
"destination": "registries/changeStatusExtract",
"confirmation": "shortName,contract,balance",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeStatusExtractActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "shortName",
"type": 2,"length": 255,"name": "Краткое наименование компании","shortname": "Компания","enabled": false
}
,
{"code": "contract",
"type": 2,"length": 255,"name": "Договор","shortname": "Номер договора","required": true,"enabled": false
}
,
{"code": "balance",
"type": 10,"name": "Текущий баланс","shortname": "Баланс","enabled": false
}
,
{"code": "registryStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "registryStatus","visible": false
}
]
}
]
@ -4159,7 +4255,7 @@
,"actions":[
{"method":"post",
"name": "Добавление корреспондентского счета",
"name": "Добавление счета",
"confirmation": "companyId,account,status",
@ -4171,7 +4267,7 @@
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
}
,
{"code": "status",
@ -4186,7 +4282,7 @@
,
{"method":"put",
"name": "Изменение корреспондентского счета",
"name": "Изменение счета",
"confirmation": "companyId,account,status",
@ -4217,7 +4313,7 @@
,
{"method":"delete",
"name": "Блокировка корреспондентского счета",
"name": "Блокировка счета",
"confirmation": "companyId,account",
@ -4526,39 +4622,16 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление информационного счета",
"confirmation": "companyId,account,status",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewInformationAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "status",
"type": 12,"name": "Наименование статуса","shortname": "Статус","link": "serviceStatus"
}
,
{"code": "accountType",
"type": 12,"name": "Наименование типа счета","shortname": "Тип","link": "accountType","required": true,"visible": false
}
]
}
]
}
,
"depoAccount": {
@ -4585,12 +4658,76 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
}
,
"accountSymbols": {
"name": "Депо КС - РДЦ",
"destination": "accounting/depo-accounts-symbols",
"class": "ru.clearing.classes.statics.data.account.AccountSymbols",
"logUpdates": "true",
"table": "depo_account_symbols",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
,
{"code": "accountId",
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","searchable": true,"sortable": true,"visible": true,"link": "account","linkCode": "account"
}
,
{"code": "accountSymbolValue",
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","searchable": true,"sortable": true,"visible": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление депо КС - РДЦ",
"confirmation": "accountId,accountSymbolValue",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction",
"fields": [
{"code": "accountId",
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","link": "account","linkCode": "account","required": true
}
,
{"code": "accountSymbolValue",
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление депо КС - РДЦ",
"confirmation": "accountId,accountSymbolValue",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true
}
]
}
]
}
,
"clearingAccount": {
@ -4617,6 +4754,10 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
@ -5182,7 +5323,7 @@
"group": "Обмен с расчетной организацией",
"name": "Запрос остатков по всем счетам (отправка ДФ-51, ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"name": "Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"fields": []
}
@ -5193,11 +5334,15 @@
"group": "Обмен с расчетной организацией",
"name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)",
"fields": [
{"code": "fullBalance",
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
}
,
{"code": "balance",
"type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false
}
,
{"code": "securitySymbol",
@ -5213,7 +5358,7 @@
}
,
{"code": "senderId",
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true
}
,
{"code": "creditLeg_accountId",
@ -5275,11 +5420,11 @@
"fields": [
{"code": "section",
"type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code"
"type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code","required": true
}
,
{"code": "sessionType",
"type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code"
"type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code","required": true
}
,
{"code": "companyId",
@ -5408,7 +5553,7 @@
"group": "Формирование отчетности",
"name": "Формирование отчетности по сделкам",
"name": "Формирование отчетности PFX64/PFX65",
"fields": []
}
@ -5432,6 +5577,28 @@
"name": "Формирование ДФ-05 с кодом 9 (финальный)",
"fields": []
}
,
{"method":"post",
"destination": "CHDF",
"group": "Общее",
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
"fields": []
}
,
{"method":"post",
"destination": "CCLR",
"group": "Клиринг",
"name": "Завершение неудачных клиринговых сессий",
"fields": []
}
]
@ -5467,7 +5634,7 @@
}
,
{"code": "sessionStatus",
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Шаг","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
}
,
{"code": "companyId",
@ -5699,10 +5866,12 @@
,
"executionDeposit": {
"name": "Сделки",
"name": "Сделки на секции МКР",
"destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true",
@ -5813,14 +5982,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code","ignore": true
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
@ -5855,6 +6024,8 @@
"destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true",
@ -5903,7 +6074,7 @@
}
,
{"code": "interestAmount",
"type": 11,"name": "Объем процентов","shortname": "Проценты","visible": true,"searchable": true,"sortable": true
"type": 11,"name": "НКД","shortname": "НКД","visible": true,"searchable": true,"sortable": true
}
,
{"code": "exchangeOrderId",
@ -5911,7 +6082,7 @@
}
,
{"code": "price",
"type": 10,"name": "Ставка по депозиту","shortname": "Ставка, %","visible": true,"searchable": true,"sortable": true
"type": 10,"name": "Цена, %","shortname": "Цена, %","visible": true,"searchable": true,"sortable": true
}
,
{"code": "settlementAmount",
@ -5961,14 +6132,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code","ignore": true
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "securityFullName",
"type": 2,"length": 255,"name": "Наименование инструмента","shortname": "Инструмент","visible": true,"searchable": true,"sortable": true
@ -6003,17 +6174,19 @@
"destination": "depo-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
"table": "balance_depo_register",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "createdAt",
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true
}
,
{"code": "updatedAt",
@ -6025,7 +6198,7 @@
}
,
{"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
}
,
{"code": "depoCode",
@ -6049,6 +6222,8 @@
"destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register",
@ -6063,7 +6238,7 @@
}
,
{"code": "infoAccount",
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true
}
,
{"code": "remainderSum",
@ -6071,23 +6246,23 @@
}
,
{"code": "blockedSum",
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "unblockedSum",
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "inn",
"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": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
}
,
{"code": "companyFullName",
"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": "companyId",
@ -6095,7 +6270,7 @@
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "createdAt",
@ -6103,7 +6278,7 @@
}
,
{"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
}
]
@ -6115,6 +6290,8 @@
"destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register",
@ -6177,6 +6354,8 @@
"destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register",
@ -6239,6 +6418,8 @@
"destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register",
@ -6293,6 +6474,8 @@
"destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register",
@ -6347,6 +6530,8 @@
"destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register",
@ -6425,6 +6610,8 @@
"destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register",
@ -6503,6 +6690,8 @@
"destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register",
@ -6884,11 +7073,11 @@
}
,
{"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время прочтения записи","shortname": "Прочитано","searchable": true,"sortable": true
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
}
,
{"code": "senderId",
"type": 1,"dbname": "Идентификатор компании-отправителя","name": "Наименование компании-отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"link": "company","ignore": true
"type": 1,"dbname": "Идентификатор отправителя","name": "Наименование отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"visible": true,"link": "userCls","linkCode": "identifier"
}
,
{"code": "addresseeId",
@ -6904,7 +7093,7 @@
}
,
{"code": "notificationStatus",
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus","ignore": true
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus"
}
,
{"code": "comment",
@ -6920,6 +7109,8 @@
"name": "Изменение статуса сообщения",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true
@ -8195,7 +8386,7 @@
}
,
{"code": "acc_name",
"type": 2,"length": 30,"name": "Наименование участника клиринга","shortname": "Наименование УК","searchable": true,"sortable": true,"visible": true
"field": "accName","type": 2,"length": 30,"name": "Наименование участника клиринга","shortname": "Наименование УК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "account",
@ -8666,6 +8857,10 @@
"table": "s_df_57",
"fields": [
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false
}
@ -8821,10 +9016,6 @@
{"code": "fileName",
"type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true
}
,
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "generationId",
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
@ -9181,7 +9372,7 @@
"destination": "operations",
"class": "",
"class": "ru.clearing.classes.statics.data.payment.Operation",
"table": "operation",
@ -9227,7 +9418,7 @@
"destination": "market-data-liquidations",
"class": "",
"class": "ru.clearing.classes.statics.data.misc.MarketDataLiquidation",
"table": "market_data_liquidation",

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.8.0.47">
<meta version="3.9.0.71">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -545,6 +545,16 @@
<companyRole type="12" dbname="Код роли компании" name="Наименование роли компании" shortname="Роль" searchable="true" sortable="true" visible="true" link="companyRole"/>
<workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" link="workflowStatus"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<actions>
<post name="Добавление роли участнику" class="ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<companyRole type="12" dbname="Код роли компании" name="Наименование роли компании" shortname="Роль" link="companyRole" required="true"/>
<workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" link="workflowStatus" required="true"/>
</post>
<delete name="Удаление роли участнику" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="companyRoleSet" linkCode="id" required="true"/>
</delete>
</actions>
</companyRoleSet>
<security name="Инструменты" destination="securities" class="ru.clearing.classes.statics.data.security.Security" logUpdates="true" table="security">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
@ -632,7 +642,7 @@
</delete>
</actions>
</moneyMarketSecurity>
<tradedMoneyMarketSecurity name="Спецификации денежного рынка, учавствующие в сделках" destination="securities/traded-money-securities" class="ru.clearing.classes.statics.data.misc.TradedMoneyMarketSecurity" table="traded_money_market_security">
<tradedMoneyMarketSecurity name="Спецификации денежного рынка, учавствующие в сделках" destination="securities/traded-money-securities" class="ru.clearing.classes.statics.data.security.TradedMoneyMarketSecurity" table="traded_money_market_security">
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="true" sortable="true" link="security" linkCode="shortName"/>
<shortName type="2" length="255" name="Краткое наименование инструмента" shortname="Краткое наименование" searchable="true" sortable="true" visible="true" extends="security"/>
<securityCode type="2" length="255" name="Полный код инструмента со сроком" shortname="Код инструмента" searchable="true" sortable="true" visible="true"/>
@ -762,8 +772,8 @@
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="true" sortable="true" link="security" linkCode="shortName"/>
<couponRate type="11" name="Купонная ставка" shortname="Ставка" searchable="true" sortable="true" visible="true"/>
<number type="3" name="Номер купона" shortname="Номер" searchable="true" sortable="true" visible="true"/>
<periodEndDate type="6" name="Начало периода действия" shortname="Начало" searchable="true" sortable="true" visible="true"/>
<periodStartDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/>
<periodStartDate type="6" name="Начало периода действия" shortname="Начало" searchable="true" sortable="true" visible="true"/>
<periodEndDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
</couponPeriod>
<listing name="Инструменты на режимах" destination="listings" class="ru.clearing.classes.statics.data.misc.Listing" logUpdates="true" table="listing">
@ -934,7 +944,7 @@
<updatedAt field="updated" type="4" name="Дата и время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
<securityId type="1" dbname="Идентификатор инструмента" name="Код инструмента" shortname="Код инструмента" searchable="false" sortable="true" visible="false" link="security" linkCode="shortName"/>
<actions>
<post name="Досрочное изъятие депозита" destination="registries/splitDeposit" confirmation="contract,outboundAmount,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew">
<post name="Разделение депозита" destination="registries/splitDeposit" confirmation="contract,outboundAmount,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew">
<companyId type="1" name="Наименование участника" shortname="Инициатор" link="company" linkCode="shortName" enabled="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
<outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/>
@ -946,11 +956,24 @@
<id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/>
<balance type="10" name="Сумма" shortname="Сумма" required="true"/>
</post>
<post name="Идентификация неразмеченных средств" destination="registries/identificationFunds" confirmation="balance,tradingClearingRegistryId" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew">
<id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/>
<balance type="10" name="Сумма" shortname="Сумма" required="true"/>
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<tradingClearingRegistryId type="1" name="Торгово-клиринговый регистр" shortname="Торгово-клиринговый регистр" link="tradingClearingRegistry" linkCode="code" required="true"/>
</post>
<put name="Изменение даты возврата депозита" destination="registries/changeRefundDate" confirmation="contact,contract,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew">
<groupId type="1" dbname="Идентификатор группы связанных регистров" name="Идентификатор группы" required="true" enabled="false" visible="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
<refundDate type="6" name="Дата возврата депозита" shortname="Возврат депозита" visible="true" enabled="true"/>
</put>
<put name="Установить отметку о получении выписки" destination="registries/changeStatusExtract" confirmation="shortName,contract,balance" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeStatusExtractActionNew">
<id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/>
<shortName type="2" length="255" name="Краткое наименование компании" shortname="Компания" enabled="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
<balance type="10" name="Текущий баланс" shortname="Баланс" enabled="false"/>
<registryStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" link="registryStatus" visible="false"/>
</put>
</actions>
</registry>
<account name="Счета" destination="accounting/accounts" class="ru.clearing.classes.statics.data.account.Account" logUpdates="true" table="account">
@ -964,20 +987,20 @@
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/>
<actions>
<post name="Добавление корреспондентского счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction">
<post name="Добавление счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
<account type="2" length="50" name="Номер счета" shortname="Счет"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
</post>
<put name="Изменение корреспондентского счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountUpdateAction">
<put name="Изменение счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountUpdateAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="account" linkCode="id" required="true"/>
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" enabled="false"/>
<account type="2" length="50" name="Номер счета" shortname="Счет" enabled="false"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
</put>
<delete name="Блокировка корреспондентского счета" confirmation="companyId,account" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<delete name="Блокировка счета" confirmation="companyId,account" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="account" linkCode="id" required="true"/>
</delete>
</actions>
@ -1051,26 +1074,35 @@
<accountId type="1" dbname="Идентификатор информационного счета" name="Номер информационного счета" shortname="Регистр на КС" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
<clearingAccountId type="1" dbname="Идентификатор аналитического счета" name="Номер аналитического счета" shortname="Клиринговый счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" />
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<actions>
<post name="Добавление информационного счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewInformationAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
</post>
</actions>
</informationAccount>
<depoAccount name="Депозитарные счета" destination="accounting/depo-accounts" class="ru.clearing.classes.statics.data.account.DepoAccount" logUpdates="true" table="depo_account">
<accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
<depoAccountType type="12" dbname="Код типа счета" name="Наименование типа счета" shortname="Тип" searchable="true" sortable="true" visible="true" link="depoAccountType"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" />
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
</depoAccount>
<accountSymbols name="Депо КС - РДЦ" destination="accounting/depo-accounts-symbols" class="ru.clearing.classes.statics.data.account.AccountSymbols" logUpdates="true" table="depo_account_symbols">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<accountId type="1" dbname="Идентификатор счета" name="Счет депо КС" shortname= "Счет депо КС" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
<accountSymbolValue type="2" length="255" name="Счет РДЦ" shortname="Счет РДЦ" searchable="true" sortable="true" visible="true"/>
<actions>
<post name="Добавление депо КС - РДЦ" confirmation="accountId,accountSymbolValue" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction">
<accountId type="1" dbname="Идентификатор счета" name="Счет депо КС" shortname= "Счет депо КС" link="account" linkCode="account" required="true"/>
<accountSymbolValue type="2" length="255" name="Счет РДЦ" shortname="Счет РДЦ" required="true"/>
</post>
<delete name="Удаление депо КС - РДЦ" confirmation="accountId,accountSymbolValue">
<id type="1" name="Идентификатор записи" shortname="ID" link="account" linkCode="id" required="true"/>
</delete>
</actions>
</accountSymbols>
<clearingAccount name="Торгово-Банковские счета" destination="accounting/clearing-accounts" class="ru.clearing.classes.statics.data.account.ClearingAccount" logUpdates="true" table="clearing_account">
<accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
<clearingAccountType type="12" dbname="Код типа счета" name="Наименование типа счета" shortname="Тип" searchable="true" sortable="true" visible="true" link="clearingAccountType" linkCode="name"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" />
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
</clearingAccount>
<plannerTemplate name="Шаблон расписания операционного дня" destination="schedule/planner-templates" class="ru.clearing.classes.statics.data.scheduler.PlannerTemplate" table="planner_template">
@ -1203,14 +1235,15 @@
</post>
<post destination="LOSC" group="Обмен с интеграционными модулями" name="Загрузка инструментов">
</post>
<post destination="GALB" group="Обмен с расчетной организацией" name="Запрос остатков по всем счетам (отправка ДФ-51, ДФ-56 для получения ответа ДФ-01, ДФ-57)">
<post destination="GALB" group="Обмен с расчетной организацией" name="Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)">
</post>
<post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)">
<balance type="10" name="Текущий баланс" shortname="Текущие средства" enabled="false"/>
<post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)">
<fullBalance type="10" name="Текущий баланс (всего)" shortname="Текущие средства (всего)" enabled="false"/>
<balance type="10" name="Текущий баланс (свободно)" shortname="Текущие средства (свободно)" enabled="false"/>
<securitySymbol type="2" name="Наименование инструмента/валюты" shortname="Валюта" enabled="false"/>
<creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма" required="true"/>
<paymentPurpose type="2" length="255" name="Назначение платежа" shortname="Основание" required="true"/>
<senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true" enabled="false"/>
<senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true"/>
<creditLeg_accountId type="1" group="Отправитель" name="Наименование счета отправителя" shortname="Регистр списания" link="account" linkCode="account"/>
<addresseeId type="1" group="Получатель" name="Участник получатель" shortname="Получатель" link="company" linkCode="shortName" required="true" enabled="false"/>
<debitLeg_accountId type="1" group="Получатель" name="Наименование счета получателя" shortname="Счет получателя" link="bankAccount" linkCode="correspondentAccount"/>
@ -1222,8 +1255,8 @@
<post destination="LIMS" group="Обмен с Торговой системой" name="Выгрузка в Торговую систему остатков по бумагам (отправка lim)">
</post>
<post destination="SCLR" group="Клиринг" name="Запуск клиринговой сессии" confirmation="section,sessionType">
<section type="12" name="Секция" shortname="Секция" link="section" linkCode="name" linkKeyCode="code"/>
<sessionType type="12" name="Тип клиринговой сессии" shortname="Тип клиринговой сессии" link="sessionType" linkCode="name" linkKeyCode="code"/>
<section type="12" name="Секция" shortname="Секция" link="section" linkCode="name" linkKeyCode="code" required="true" />
<sessionType type="12" name="Тип клиринговой сессии" shortname="Тип клиринговой сессии" link="sessionType" linkCode="name" linkKeyCode="code" required="true" />
<companyId type="1" name="Наименование инициатора" shortname="Инициатор" link="company" linkCode="shortName" visible="false"/>
<securityId type="1" name="Наименование инструмента" shortname="Инструмент" link="security" linkCode="shortName" visible="false"/>
</post>
@ -1247,12 +1280,16 @@
</post>
<post destination="ECNR" group="Формирование реестров" name="Формирование реестра сделок">
</post>
<post destination="GRET" group="Формирование отчетности" name="Формирование отчетности по сделкам">
<post destination="GRET" group="Формирование отчетности" name="Формирование отчетности PFX64/PFX65">
</post>
<post destination="GREF" group="Формирование отчетности" name="Формирование итоговой отчетности">
</post>
<post destination="FDFF" group="Обмен с расчетной организацией" name="Формирование ДФ-05 с кодом 9 (финальный)">
</post>
<post destination="CHDF" group="Общее" name="Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21">
</post>
<post destination="CCLR" group="Клиринг" name="Завершение неудачных клиринговых сессий">
</post>
</actions>
</launcher>
@ -1261,7 +1298,7 @@
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
<clearingDate type="6" name="Дата" shortname="Дата" searchable="true" sortable="true" visible="true"/>
<sessionStatus type="12" dbname="Код статуса клиринговой сессии" name="Статус клиринговой сессии" shortname="Статус" searchable="true" sortable="true" visible="true" link="sessionStatus"/>
<sessionStatus type="12" dbname="Код статуса клиринговой сессии" name="Статус клиринговой сессии" shortname="Шаг" searchable="true" sortable="true" visible="true" link="sessionStatus"/>
<companyId type="1" dbname="Идентификатор инициатора торгов" name="Наименование инициатора торгов" shortname="Инициатор" visible="false" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="false" sortable="true" visible="true" link="security" linkCode="shortName"/>
<userId type="1" dbname="Идентификатор пользователя" name="Наименование пользователя" shortname="Пользователь" searchable="true" sortable="true" visible="true" link="userCls" linkCode="identifier"/>
@ -1318,7 +1355,7 @@
<bankAccId type="2" length="12" name="Идентификатор расчетного счета/кода в клиринговой организации" shortname="Код позиции" searchable="true" sortable="true"/>
<section type="12" dbname="Код наименования секции" name="Наименование секции" shortname="Секция" searchable="true" sortable="true" visible="true" link="section"/>
</sTrades>
<executionDeposit name="Сделки" destination="execution-deposits" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit">
<executionDeposit name="Сделки на секции МКР" destination="execution-deposits" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit">
<exchangeExecutionId type="1" name="Идентификационный номер сделки в Торговой системе" shortname="Номер сделки" visible="true" searchable="true" sortable="true"/>
<exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
@ -1345,8 +1382,8 @@
<securityId type="1" dbname="Идентификатор финансового инструмента" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" link="moneyMarketSecurity" linkCode="securitySymbol" ignore="true"/>
<contract type="2" name="Продукт" shortname="Продукт" searchable="true" sortable="true" length="255" visible="true"/>
<counterPartyId type="1" dbname="Идентификатор компании-партнера, с которой заключена сделка" name="Наименование компании-партнера, с которой заключена сделка" shortname="Партнер" visible="false" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<counterPartyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" />
<counterPartyTradingClearingRegistryId type="1" dbname="Идентификатор торгово-клирингового регистра партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" link="tradingClearingRegistry" linkCode="code" ignore="true"/>
<counterPartyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" />
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<id type="1" name="Идентификатор записи" shortname="ID" visible="false" searchable="true" sortable="true"/>
@ -1354,7 +1391,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" visible="false" searchable="true" sortable="true"/>
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" visible="false" searchable="true" sortable="true"/>
</executionDeposit>
<executionFond name="Сделки на Фондовой секции" destination="execution-fonds" class="ru.clearing.classes.statics.data.execution.ExecutionFond" logUpdates="true" table="execution_fond">
<executionFond name="Сделки на Фондовой секции" destination="execution-fonds" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionFond" logUpdates="true" table="execution_fond">
<id type="1" name="Идентификатор записи" shortname="ID" visible="false" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" visible="false" searchable="true" sortable="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" visible="false" searchable="true" sortable="true"/>
@ -1365,9 +1402,9 @@
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
<securitySymbol type="2" length="255" name="Код инструмента в Торговой Системе" shortname="Код инструмента" visible="true" searchable="true" sortable="true"/>
<securityId type="1" dbname="Идентификатор финансового инструмента" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" link="security" linkCode="securitySymbol" ignore="true"/>
<interestAmount type="11" name="Объем процентов" shortname="Проценты" visible="true" searchable="true" sortable="true"/>
<interestAmount type="11" name="НКД" shortname="НКД" visible="true" searchable="true" sortable="true"/>
<exchangeOrderId type="1" name="Идентификационный номер заявки в Торговой системе" shortname="Номер заявки" visible="true" searchable="true" sortable="true"/>
<price type="10" name="Ставка по депозиту" shortname="Ставка, %" visible="true" searchable="true" sortable="true"/>
<price type="10" name="Цена, %" shortname ="Цена, %" visible="true" searchable="true" sortable="true"/>
<settlementAmount type="11" name="Объем сделки" shortname="Объем" visible="true" searchable="true" sortable="true"/>
<lots type="11" name="Количество лотов" shortname="Лоты" visible="true" searchable="true" sortable="true"/>
<quantity type="11" name="Количество штук" shortname="Штуки" visible="false" searchable="true" sortable="true"/>
@ -1380,8 +1417,8 @@
<settlementCode type="2" length="12" name="Код расчетов при размещении" shortname="Код расчетов при размещении" visible="false" searchable="true" sortable="true" ignore="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" visible="true" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<counterPartyId type="1" dbname="Идентификатор компании-партнера, с которой заключена сделка" name="Наименование компании-партнера, с которой заключена сделка" shortname="Партнер" visible="false" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<counterPartyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" />
<counterPartyTradingClearingRegistryId type="1" dbname="Идентификатор торгово-клирингового регистра партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" link="tradingClearingRegistry" linkCode="code" ignore="true"/>
<counterPartyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" />
<securityFullName type="2" length="255" name="Наименование инструмента" shortname="Инструмент" visible="true" searchable="true" sortable="true"/>
<settlementDate type="6" name="Дата расчетов" shortname="Дата расчетов" visible="true" searchable="true" sortable="true"/>
<settlementCurrency type="12" dbname="Код валюты расчетов по инструменту" name="Валюта расчетов по инструменту" shortname="Валюта" visible="true" searchable="true" sortable="true" link="currencyCode" linkCode="code"/>
@ -1389,32 +1426,32 @@
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
</executionFond>
<depoBalanceRegister name="Реестр остатков ценных бумаг" destination="depo-balance-registers" class="ru.clearing.classes.statics.data.register.DepoBalanceRegister" table="balance_depo_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<depoBalanceRegister name="Реестр остатков ценных бумаг" destination="depo-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoBalanceRegister" table="balance_depo_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" ignore="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" visible="true" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session" ignore="true"/>
<depoCode type="2" length="50" name="Код раздела субсчета/счета депо" shortname="Код счета депо" searchable="true" sortable="true"/>
<quantity type="11" name="Количество" shortname="Количество" searchable="true" sortable="true"/>
<securitySymbol type="2" length="255" name="Код ценной бумаги" shortname="Ценная бумага" searchable="true" sortable="true"/>
</depoBalanceRegister>
<moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" class="ru.clearing.classes.statics.data.register.MoneyBalanceRegister" table="money_balance_register">
<moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyBalanceRegister" table="money_balance_register">
<setHouseName type="2" length="255" name="Наименование РО" shortname="Наименование РО" searchable="true" sortable="true" visible="true"/>
<account type="2" length="50" name="Номер торгового/клирингового счета" shortname="Номер торгового/клирингового счета" searchable="true" sortable="true" visible="true"/>
<infoAccount type="2" length="50" name="Номер счета внутреннего учета СПВБ" shortname="Номер счета внутреннего учета СПВБ" searchable="true" sortable="true" visible="true"/>
<infoAccount type="2" length="50" name="Номер счета внутреннего учета СПВБ" shortname="Номер счета внутреннего учета СПВБ" searchable="true" sortable="true" visible="true" ignore="true"/>
<remainderSum type="10" name="Остаток денежных средств" shortname="Остаток" searchable="true" sortable="true"/>
<blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true"/>
<unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true"/>
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
<blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true" ignore="true"/>
<unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true" ignore="true"/>
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true" ignore="true"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session" ignore="true"/>
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true" ignore="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" ignore="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
</moneyBalanceRegister>
<admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" class="ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister" table="admitted_liabilities_register">
<admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister" table="admitted_liabilities_register">
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
@ -1428,7 +1465,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/>
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
</admittedLiabilitiesRegister>
<coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" class="ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister" table="covered_Liabilities_register">
<coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister" table="covered_Liabilities_register">
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
@ -1442,7 +1479,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/>
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
</coveredLiabilitiesRegister>
<moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" class="ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister" table="money_payment_instruction_register">
<moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister" table="money_payment_instruction_register">
<creditLegAccount type="2" length="50" name="Счет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" visible="true"/>
<creditLegAmount type="10" name="Сумма отправителя" shortname="Сумма отправителя" searchable="true" sortable="true" visible="true"/>
<creditLegCurrencyCode type="12" dbname="Код валюты отправителя" name="Наименование валюты отправителя" shortname="Валюта отправителя" searchable="true" sortable="true" visible="true" link="currency"/>
@ -1454,7 +1491,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
<clearingDate type="6" name="Дата расчета" shortname="Дата расчета" searchable="true" sortable="true" visible="true"/>
</moneyPaymentInstructionRegister>
<depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register">
<depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1466,7 +1503,7 @@
<direction type="1" name="Направление" shortname="Направление" searchable="true" sortable="true" link="inOutDirection" ignore="true"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
</depoPaymentInstructionRegister>
<excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register">
<excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1484,7 +1521,7 @@
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
</excludeLiabilitiesRegister>
<liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register">
<liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1502,7 +1539,7 @@
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
</liabilitiesRegister>
<executionRegister name="Реестр сделок" destination="execution-registers" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register">
<executionRegister name="Реестр сделок" destination="execution-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register">
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
<exchangeExecutionId type="1" name="Идентификационный номер сделки в Торговой системе" shortname="Номер сделки" visible="true" searchable="true" sortable="true"/>
<exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
@ -1593,16 +1630,16 @@
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<clearingDate type="6" name="Дата" shortname="Дата" searchable="true" sortable="true" visible="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" visible="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время прочтения записи" shortname="Прочитано" searchable="true" sortable="true"/>
<senderId type="1" dbname="Идентификатор компании-отправителя" name="Наименование компании-отправителя" shortname="Отправитель" searchable="true" sortable="true" link="company" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/>
<senderId type="1" dbname="Идентификатор отправителя" name="Наименование отправителя" shortname="Отправитель" searchable="true" sortable="true" visible="true" link="userCls" linkCode="identifier"/>
<addresseeId type="1" dbname="Идентификатор компании-получателя" name="Наименование компании-получателя" shortname="Получатель" searchable="true" sortable="true" link="company" ignore="true"/>
<objectType type="12" dbname="Код типа объекта" name="Наименование типа объекта" shortname="Объект" searchable="true" sortable="true" link="objectType" ignore="true"/>
<objectId type="1" name="Идентификатор объекта" shortname="ID объекта" searchable="true" sortable="true" ignore="true"/>
<notificationStatus type="12" dbname="Код статуса сообщения" name="Наименование статуса сообщения" shortname="Статус" searchable="true" sortable="true" visible="true" link="notificationStatus" ignore="true"/>
<notificationStatus type="12" dbname="Код статуса сообщения" name="Наименование статуса сообщения" shortname="Статус" searchable="true" sortable="true" visible="true" link="notificationStatus"/>
<comment type="2" length="255" name="Текст сообщения" shortname="Сообщение" searchable="true" sortable="true" visible="true"/>
<priority type="12" dbname="Код приоритета отображения" name="Наименование приоритета отображения" shortname="Приоритет отображения" searchable="true" sortable="true" link="priority"/>
<actions>
<put name="Изменение статуса сообщения">
<put name="Изменение статуса сообщения" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="notification" linkCode="id" required="true"/>
<notificationStatus type="12" name="Наименование статуса сообщения" shortname="Статус" link="notificationStatus" required="true"/>
</put>
@ -1893,7 +1930,7 @@
</sDf52>
<sDf53 name="ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)" destination="s-dfs/s-df53" class="ru.clearing.classes.statics.data.sdf.SDf53" table="s_df_53">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
<acc_name type="2" length="30" name="Наименование участника клиринга" shortname="Наименование УК" searchable="true" sortable="true" visible="true"/>
<acc_name field="accName" type="2" length="30" name="Наименование участника клиринга" shortname="Наименование УК" searchable="true" sortable="true" visible="true"/>
<account type="2" length="25" name="Код счета участника клиринга" shortname="Код счета УК" searchable="true" sortable="true" visible="true"/>
<deal type="2" length="4" name="Биржевой код участника клиринга" shortname="Биржевой код УК" searchable="true" sortable="true" visible="true"/>
<date type="2" length="8" name="Дата изменения состояния счета" shortname="Дата изменения состояния счета" searchable="true" sortable="true" visible="true"/>
@ -2005,6 +2042,7 @@
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
</sDf56>
<sDf57 name="ДФ-57 Список транзакций о списании/зачислении за период по всем счетам (ТБС и КС)" destination="s-dfs/s-df57" class="ru.clearing.classes.statics.data.sdf.SDf57" table="s_df_57">
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
<dbfId type="1" name="Уникальный идентификатор платежного документа (транзакции)" shortname="ID платежного поручения" searchable="true" sortable="true" visible="true"/>
<deal_deb type="2" length="4" name="Биржевой код участника клиринга (плательщик)" shortname="Инициатор в КС" searchable="true" sortable="true" visible="true"/>
@ -2044,7 +2082,6 @@
<acc_kr type="2" length="35" name="Счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/>
<specif type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" searchable="true" sortable="true" visible="true"/>
<fileName type="2" length="255" name="Наименование входящего файла" shortname="Наименование файла" searchable="true" sortable="true" visible="true"/>
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
</sDf57>
<managementJournal name="Журнал мониторинга и контроля" destination="management-journals" class="ru.clearing.classes.statics.data.journal.ManagementJournal" table="management_journal">
@ -2125,7 +2162,7 @@
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
</contractRegister>
<operation name="Проводки" destination="operations" class="" table="operation">
<operation name="Проводки" destination="operations" class="ru.clearing.classes.statics.data.payment.Operation" table="operation">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
<addresseeId type="1" dbname="Идентификатор компании-получателя" name="Наименование компании-получателя" shortname="Получатель" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<senderId type="1" dbname="Идентификатор компании-отправителя" name="Наименование компании-отправителя" shortname="Отправитель" searchable="true" sortable="true" link="company" linkCode="shortName"/>
@ -2135,7 +2172,7 @@
<operationTypeId type="1" name="Тип проводки" shortname="Тип" searchable="true" sortable="true" link="operationType"/>
<operationStatus type="12" dbname="Код статуса обработки" name="Наименование статуса обработки" shortname="Статус" searchable="true" sortable="true" link="operationStatus"/>
</operation>
<marketDataLiquidation name="Статичная ценовая информация для ликвидации активов" destination="market-data-liquidations" class="" table="market_data_liquidation">
<marketDataLiquidation name="Статичная ценовая информация для ликвидации активов" destination="market-data-liquidations" class="ru.clearing.classes.statics.data.misc.MarketDataLiquidation" table="market_data_liquidation">
<id type="1" name="Идентификатор" shortname="ID" searchable="true" sortable="true" visible="false"/>
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="true" sortable="true" visible="true" link="security" linkCode="securitySymbol"/>
<price type="10" name="Цена за 1 штуку ликвидационного актива" shortname="Цена за шт." searchable="true" sortable="true" visible="true"/>

View file

@ -43,6 +43,7 @@ DROP TABLE IF EXISTS <xsl:value-of select="$dbTableName"/>;
CREATE TABLE <xsl:value-of select="$dbTableName"/>(<xsl:apply-templates select="*" mode="field"/>);
COMMENT ON TABLE <xsl:value-of select="$dbTableName"/> IS '<xsl:value-of select="$dbNameComment"/>';
<xsl:apply-templates select="*" mode="comment-enums"/>
GRANT ALL PRIVILEGES ON TABLE <xsl:value-of select="$dbTableName"/> TO clearing;
</xsl:template>
<xsl:template match="*" mode="objects">
@ -53,6 +54,7 @@ DROP TABLE IF EXISTS <xsl:value-of select="$dbTableName"/>;
CREATE TABLE <xsl:value-of select="$dbTableName"/>(<xsl:apply-templates select="*[@name or @dbname or @type]" mode="field"/>);
COMMENT ON TABLE <xsl:value-of select="$dbTableName"/> IS '<xsl:value-of select="$dbNameTComment"/>';
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="comment-objects"/>
GRANT ALL PRIVILEGES ON TABLE <xsl:value-of select="$dbTableName"/> TO clearing;
<xsl:if test="@logUpdates">
-- History log of <xsl:value-of select="name()"/> - <xsl:value-of select="$dbNameTComment"/>
@ -65,6 +67,7 @@ COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>_HISTORY.EVENT_TIME IS '
COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>_HISTORY.EVENT_USER_ID IS 'Инициатор изменения';
COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>_HISTORY.EVENT_TYPE IS 'Тип изменения';
<xsl:apply-templates select="*[@name or @dbname or @type]" mode="comment-history-objects"/>
GRANT ALL PRIVILEGES ON TABLE <xsl:value-of select="$dbTableName"/>_HISTORY TO clearing;
</xsl:if>
</xsl:template>

View file

@ -27,6 +27,6 @@ public class StateLoaderImplTestConfig {
@Bean(name = "stateLoaderImplTest")
public StateLoaderImpl createStateLoaderImpl(@Qualifier("responseFactoryTest") GetResponseFactory responseFactory) {
return new StateLoaderImpl(hazelcastServiceTest, responseFactory);
return new StateLoaderImpl(hazelcastServiceTest, null, responseFactory);
}
}

View file

@ -88,6 +88,7 @@ import static ru.spcex.clearing.test.json.MatcherFactoryWithJson.usingIgnoringFi
DepoAccountController.class,
//account misc
ClientCodeController.class,
AccountSymbolsController.class,
//company
CompanyRoleSetController.class,
CompanyController.class,

View file

@ -0,0 +1,66 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import org.junit.jupiter.api.Test;
import ru.clearing.classes.statics.data.account.AccountSymbols;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
class AccountSymbolsControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/accounting/depo-accounts-symbols/";
/**
* {@link AccountSymbolsController#add(AccountSymbolsNewAction)}<br>
* Тест проверяет получение сущности {@link AccountSymbolsNewAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link AccountSymbolsNewAction}: {111L, "VALUE-1234"}
*/
@Test
void add() throws Exception {
//ARRANGE
AccountSymbolsNewAction accountSymbolsNewAction = new AccountSymbolsNewAction();
accountSymbolsNewAction.setAccountId(111L);
accountSymbolsNewAction.setAccountSymbolValue("VALUE-1234");
//ACT and ASSERT
checkAddingByRestApi(REST_URL, accountSymbolsNewAction);
checkSendedMessegeFromKafka(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW, accountSymbolsNewAction);
}
/**
* {@link AccountSymbolsController#delete(Long)} <br>
* Тест проверяет получение id сущности {@link Long} по REST API и отправку в Apache Kafka.<br>
* Входной запрос /accounting/depo-accounts-symbols/{@link Long}: - 0L<br>
*/
@Test
void delete() throws Exception {
//ARRANGE
long id = currentId.getAndIncrement();
CommonDeleteAction deleteAction = new CommonDeleteAction();
deleteAction.setId(id);
//ACT and ASSERT
checkDeletingByRestApi(REST_URL, id);
checkSendedMessegeFromKafka(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE, deleteAction);
}
/**
* {@link ClientCodeController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_ClientCode.<br>
* Входной запрос /client-codes/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
AccountSymbols existAccountSymbols = new AccountSymbols();
existAccountSymbols.setAccountId(111L);
existAccountSymbols.setAccountSymbolValue("AAABBBVVCD");
existAccountSymbols.setId(currentId.get());
//ACT and ASSERT
checkGettingAllFromRestApi(IMDGDistributedNames.Map_AccountSymbols, existAccountSymbols, REST_URL);
}
}

View file

@ -20,7 +20,7 @@ import java.nio.file.Paths;
public class GetResponseFactoryTestConfiguration {
@Bean("metaJsonTestPath")
public Resource metaJsonPath() {
Path path = Paths.get("src", "main", "resources", "meta.json");
Path path = Paths.get("src", "main", "resources", "meta", "meta.json");
return new PathResource(path);
}

View file

@ -1,6 +1,6 @@
{
"version": "3.8.0.47",
"version": "3.9.0.71",
"enums": {
@ -2361,7 +2361,41 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "companyRole",
"type": 12,"dbname": "Код роли компании","name": "Наименование роли компании","shortname": "Роль","link": "companyRole","required": true
}
,
{"code": "workflowStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "companyRoleSet","linkCode": "id","required": true
}
]
}
]
}
,
"security": {
@ -2739,7 +2773,7 @@
"destination": "securities/traded-money-securities",
"class": "ru.clearing.classes.statics.data.misc.TradedMoneyMarketSecurity",
"class": "ru.clearing.classes.statics.data.security.TradedMoneyMarketSecurity",
"table": "traded_money_market_security",
@ -3294,11 +3328,11 @@
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
}
,
{"code": "periodEndDate",
{"code": "periodStartDate",
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
}
,
{"code": "periodStartDate",
{"code": "periodEndDate",
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
}
,
@ -4026,7 +4060,7 @@
,"actions":[
{"method":"post",
"name": "Досрочное изъятие депозита",
"name": "Разделение депозита",
"destination": "registries/splitDeposit",
@ -4077,6 +4111,35 @@
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
]
}
,
{"method":"post",
"name": "Идентификация неразмеченных средств",
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
,
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
]
}
,
@ -4102,6 +4165,39 @@
{"code": "refundDate",
"type": 6,"name": "Дата возврата депозита","shortname": "Возврат депозита","visible": true,"enabled": true
}
]
}
,
{"method":"put",
"name": "Установить отметку о получении выписки",
"destination": "registries/changeStatusExtract",
"confirmation": "shortName,contract,balance",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeStatusExtractActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "shortName",
"type": 2,"length": 255,"name": "Краткое наименование компании","shortname": "Компания","enabled": false
}
,
{"code": "contract",
"type": 2,"length": 255,"name": "Договор","shortname": "Номер договора","required": true,"enabled": false
}
,
{"code": "balance",
"type": 10,"name": "Текущий баланс","shortname": "Баланс","enabled": false
}
,
{"code": "registryStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "registryStatus","visible": false
}
]
}
]
@ -4159,7 +4255,7 @@
,"actions":[
{"method":"post",
"name": "Добавление корреспондентского счета",
"name": "Добавление счета",
"confirmation": "companyId,account,status",
@ -4171,7 +4267,7 @@
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
}
,
{"code": "status",
@ -4186,7 +4282,7 @@
,
{"method":"put",
"name": "Изменение корреспондентского счета",
"name": "Изменение счета",
"confirmation": "companyId,account,status",
@ -4217,7 +4313,7 @@
,
{"method":"delete",
"name": "Блокировка корреспондентского счета",
"name": "Блокировка счета",
"confirmation": "companyId,account",
@ -4526,39 +4622,16 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление информационного счета",
"confirmation": "companyId,account,status",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewInformationAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "status",
"type": 12,"name": "Наименование статуса","shortname": "Статус","link": "serviceStatus"
}
,
{"code": "accountType",
"type": 12,"name": "Наименование типа счета","shortname": "Тип","link": "accountType","required": true,"visible": false
}
]
}
]
}
,
"depoAccount": {
@ -4585,12 +4658,76 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
]
}
,
"accountSymbols": {
"name": "Депо КС - РДЦ",
"destination": "accounting/depo-accounts-symbols",
"class": "ru.clearing.classes.statics.data.account.AccountSymbols",
"logUpdates": "true",
"table": "depo_account_symbols",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
,
{"code": "accountId",
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","searchable": true,"sortable": true,"visible": true,"link": "account","linkCode": "account"
}
,
{"code": "accountSymbolValue",
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","searchable": true,"sortable": true,"visible": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление депо КС - РДЦ",
"confirmation": "accountId,accountSymbolValue",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction",
"fields": [
{"code": "accountId",
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","link": "account","linkCode": "account","required": true
}
,
{"code": "accountSymbolValue",
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление депо КС - РДЦ",
"confirmation": "accountId,accountSymbolValue",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true
}
]
}
]
}
,
"clearingAccount": {
@ -4617,6 +4754,10 @@
{"code": "companyId",
"type": 1,"dbname": "Идентификатор компании","name": "Наименование компании","shortname": "Компания","searchable": true,"sortable": true,"visible": true,"link": "company","linkCode": "shortName"
}
,
{"code": "serviceStatus",
"field": "accountId","type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "id","linkCode": "status","link": "account","extends": "account"
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
@ -5182,7 +5323,7 @@
"group": "Обмен с расчетной организацией",
"name": "Запрос остатков по всем счетам (отправка ДФ-51, ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"name": "Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"fields": []
}
@ -5193,11 +5334,15 @@
"group": "Обмен с расчетной организацией",
"name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)",
"fields": [
{"code": "fullBalance",
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
}
,
{"code": "balance",
"type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false
}
,
{"code": "securitySymbol",
@ -5213,7 +5358,7 @@
}
,
{"code": "senderId",
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true
}
,
{"code": "creditLeg_accountId",
@ -5275,11 +5420,11 @@
"fields": [
{"code": "section",
"type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code"
"type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code","required": true
}
,
{"code": "sessionType",
"type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code"
"type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code","required": true
}
,
{"code": "companyId",
@ -5408,7 +5553,7 @@
"group": "Формирование отчетности",
"name": "Формирование отчетности по сделкам",
"name": "Формирование отчетности PFX64/PFX65",
"fields": []
}
@ -5432,6 +5577,28 @@
"name": "Формирование ДФ-05 с кодом 9 (финальный)",
"fields": []
}
,
{"method":"post",
"destination": "CHDF",
"group": "Общее",
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
"fields": []
}
,
{"method":"post",
"destination": "CCLR",
"group": "Клиринг",
"name": "Завершение неудачных клиринговых сессий",
"fields": []
}
]
@ -5467,7 +5634,7 @@
}
,
{"code": "sessionStatus",
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Шаг","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
}
,
{"code": "companyId",
@ -5699,10 +5866,12 @@
,
"executionDeposit": {
"name": "Сделки",
"name": "Сделки на секции МКР",
"destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true",
@ -5813,14 +5982,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code","ignore": true
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
@ -5855,6 +6024,8 @@
"destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true",
@ -5903,7 +6074,7 @@
}
,
{"code": "interestAmount",
"type": 11,"name": "Объем процентов","shortname": "Проценты","visible": true,"searchable": true,"sortable": true
"type": 11,"name": "НКД","shortname": "НКД","visible": true,"searchable": true,"sortable": true
}
,
{"code": "exchangeOrderId",
@ -5911,7 +6082,7 @@
}
,
{"code": "price",
"type": 10,"name": "Ставка по депозиту","shortname": "Ставка, %","visible": true,"searchable": true,"sortable": true
"type": 10,"name": "Цена, %","shortname": "Цена, %","visible": true,"searchable": true,"sortable": true
}
,
{"code": "settlementAmount",
@ -5961,14 +6132,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code","ignore": true
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "securityFullName",
"type": 2,"length": 255,"name": "Наименование инструмента","shortname": "Инструмент","visible": true,"searchable": true,"sortable": true
@ -6003,17 +6174,19 @@
"destination": "depo-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
"table": "balance_depo_register",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "createdAt",
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true
}
,
{"code": "updatedAt",
@ -6025,7 +6198,7 @@
}
,
{"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
}
,
{"code": "depoCode",
@ -6049,6 +6222,8 @@
"destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register",
@ -6063,7 +6238,7 @@
}
,
{"code": "infoAccount",
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true
}
,
{"code": "remainderSum",
@ -6071,23 +6246,23 @@
}
,
{"code": "blockedSum",
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "unblockedSum",
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "inn",
"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": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
}
,
{"code": "companyFullName",
"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": "companyId",
@ -6095,7 +6270,7 @@
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "createdAt",
@ -6103,7 +6278,7 @@
}
,
{"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
}
]
@ -6115,6 +6290,8 @@
"destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register",
@ -6177,6 +6354,8 @@
"destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register",
@ -6239,6 +6418,8 @@
"destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register",
@ -6293,6 +6474,8 @@
"destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register",
@ -6347,6 +6530,8 @@
"destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register",
@ -6425,6 +6610,8 @@
"destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register",
@ -6503,6 +6690,8 @@
"destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register",
@ -6884,11 +7073,11 @@
}
,
{"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время прочтения записи","shortname": "Прочитано","searchable": true,"sortable": true
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
}
,
{"code": "senderId",
"type": 1,"dbname": "Идентификатор компании-отправителя","name": "Наименование компании-отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"link": "company","ignore": true
"type": 1,"dbname": "Идентификатор отправителя","name": "Наименование отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"visible": true,"link": "userCls","linkCode": "identifier"
}
,
{"code": "addresseeId",
@ -6904,7 +7093,7 @@
}
,
{"code": "notificationStatus",
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus","ignore": true
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus"
}
,
{"code": "comment",
@ -6920,6 +7109,8 @@
"name": "Изменение статуса сообщения",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true
@ -8195,7 +8386,7 @@
}
,
{"code": "acc_name",
"type": 2,"length": 30,"name": "Наименование участника клиринга","shortname": "Наименование УК","searchable": true,"sortable": true,"visible": true
"field": "accName","type": 2,"length": 30,"name": "Наименование участника клиринга","shortname": "Наименование УК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "account",
@ -8666,6 +8857,10 @@
"table": "s_df_57",
"fields": [
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false
}
@ -8821,10 +9016,6 @@
{"code": "fileName",
"type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true
}
,
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "generationId",
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
@ -9181,7 +9372,7 @@
"destination": "operations",
"class": "",
"class": "ru.clearing.classes.statics.data.payment.Operation",
"table": "operation",
@ -9227,7 +9418,7 @@
"destination": "market-data-liquidations",
"class": "",
"class": "ru.clearing.classes.statics.data.misc.MarketDataLiquidation",
"table": "market_data_liquidation",

View file

@ -0,0 +1,33 @@
package ru.clearing.classes.statics.data.account;
import ru.clearing.classes.ConstSerializable;
import ru.spcex.platform.classes.base.SpcexObjectBase;
/**
* Депо КС - РДЦ
* <p>
* DB table: ACCOUNT_SYMBOLS
**/
public class AccountSymbols extends SpcexObjectBase {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
private Long accountId;
private String accountSymbolValue;
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long value) {
this.accountId = value;
}
public String getAccountSymbolValue() {
return accountSymbolValue;
}
public void setAccountSymbolValue(String value) {
this.accountSymbolValue = value;
}
}

View file

@ -0,0 +1,28 @@
package ru.clearing.classes.statics.data.account;
import ru.clearing.classes.ConstSerializable;
import ru.clearing.classes.objects.BusinessEvent;
import java.io.Serial;
/**
* Изменение состояния объекта Депо КС - РДЦ
* <p>
* DB table: ACCOUNT_SYMBOLS_HISTORY
**/
public class AccountSymbolsHistory extends BusinessEvent<AccountSymbols> {
@Serial
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
private AccountSymbols object;
@Override
public AccountSymbols getObject() {
return object;
}
@Override
public void setObject(AccountSymbols object) {
this.object = object;
}
}

View file

@ -204,10 +204,16 @@ public class Registry extends BusinessObject implements Cloneable {
}
public BigDecimal getBalance() {
if (balance == null) {
balance = BigDecimal.ZERO;
}
return balance;
}
public void setBalance(BigDecimal balance) {
if (balance == null) {
balance = BigDecimal.ZERO;
}
this.balance = balance;
}

View file

@ -2,6 +2,8 @@ package ru.spcex.clearing.config;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
@ -13,6 +15,7 @@ import ru.spcex.clearing.config.element.ClearingServiceSettings;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
import ru.spcex.clearing.platform.messaging.config.element.KafkaConsumerSettings;
import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
@ -20,13 +23,44 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
@Configuration
public class KafkaConfig {
@Autowired
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaConsumerSettings kafkaSettings;
public KafkaConfig(ClearingServiceSettings settings) {
this.kafkaSettings = settings.getKafkaConsumer();
Integer gtwTimeout = settings.getSessionStage().getInspectionGatewayTimeout();
if (gtwTimeout != null) {
int maxPollIntervalMs = gtwTimeout * 1000 + 1000;
log.debug("setting max.poll.interval.ms {}", maxPollIntervalMs);
this.kafkaSettings.setManuallyMaxPollIntervalMs(maxPollIntervalMs);
}
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public Consumer<String, Object> createConsumer(ClearingServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
@Bean("kafkaConsumer")
public Consumer<String, Object> createConsumer() {
return KafkaConsumerFactory.consumer(kafkaSettings);
}
@Bean("kafkaConsumerGateway")
public Supplier<Consumer<String, Object>> getwaySessionConsumer() {
AtomicInteger groupId = new AtomicInteger(1);
return () -> {
KafkaConsumerSettings consumer = kafkaSettings;
KafkaConsumerSettings gatewayConsumer = new KafkaConsumerSettings();
gatewayConsumer.setBootstrapServers(consumer.getBootstrapServers());
gatewayConsumer.setSessionTimeoutMs(consumer.getSessionTimeoutMs());
gatewayConsumer.setAutoOffsetReset(consumer.getAutoOffsetReset());
gatewayConsumer.setEnableAutoCommit(consumer.getEnableAutoCommit());
gatewayConsumer.setGroupId(consumer.getGroupId() + "-gateway-" + groupId.getAndIncrement());
return KafkaConsumerFactory.consumer(gatewayConsumer);
};
}
@Autowired

View file

@ -0,0 +1,15 @@
package ru.spcex.clearing.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
@Configuration
public class RequestHelperConfiguration {
@Bean
public RequestHelper reqHelper(IMessageResolver msgRslv) {
return new RequestHelper(msgRslv, ClearingError.GeneralError);
}
}

View file

@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.company.relation.Relation;
@ -13,6 +14,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.STrades;
import ru.clearing.classes.statics.data.misc.Session;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.*;
@ -23,10 +25,9 @@ import ru.clearing.platform.dictionary.InOutDirectionDictionary;
import ru.clearing.platform.dictionary.SectionDictionary;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.service.validation.*;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
@ -37,6 +38,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.LogPrefixId;
import ru.spcex.platform.imdg.validation.rule.AnltAccLoad;
import ru.spcex.platform.imdg.validation.rule.PresentById;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
@ -44,6 +46,7 @@ import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@Configuration
public class ValidationConfig {
@ -65,6 +68,10 @@ public class ValidationConfig {
Imdg<SectionDictionary> imdgSectionDictionary;
Imdg<Statement> imdgStatement;
Imdg<InOutDirectionDictionary> imdgInOutDirection;
Imdg<SDf55> sDf55Imdg;
Imdg<SDf54> sDf54Imdg;
Imdg<PaymentInstruction> pmtImdg;
Imdg<ClearingMemberCategory> ctgrImdg;
ImdgProvider imdgProvider;
public ValidationConfig(ImdgProvider imdgProvider) {
@ -84,6 +91,10 @@ public class ValidationConfig {
this.imdgStatement = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.imdgDepoAccount = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
this.imdgInOutDirection = imdgProvider.getImdg(IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class);
this.sDf55Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf55, SDf55.class);
this.sDf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.ctgrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.imdgProvider = imdgProvider;
}
@ -319,12 +330,14 @@ public class ValidationConfig {
ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(returnDepositRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ctgrImdg);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
ReturnDepositValidationRule.RegistryCodeCheck,
ReturnDepositValidationRule.RgsWronCodeCheck,
ReturnDepositValidationRule.CategoryCheck,
ReturnDepositValidationRule.BalanceCheck,
ReturnDepositValidationRule.DmxCheck
ReturnDepositValidationRule.Dm_Check
);
};
}
@ -343,6 +356,46 @@ public class ValidationConfig {
};
}
@Bean("statusExtractValidator")
public Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractValidator() {
return statusExtractRequest -> {
ImdgValidationContext<RegistryChangeStatusExtractRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(statusExtractRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
StatusExtractValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
StatusExtractValidationRule.RegistryCodeCheck,
StatusExtractValidationRule.ContractCheck,
StatusExtractValidationRule.RequestStatusValid,
StatusExtractValidationRule.RegistryStatusValid
);
};
}
@Bean("identificationFundsValidator")
public Function<IdentificationFundsRequest, IValidator> identificationFundsValidator() {
return identificationFundsRequest -> {
ImdgValidationContext<IdentificationFundsRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(identificationFundsRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
IdentificationFundsValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
IdentificationFundsValidationRule.RegistryCodeCheck,
IdentificationFundsValidationRule.BalanceCheck,
IdentificationFundsValidationRule.TcrCheck,
IdentificationFundsValidationRule.AssetsCheck,
new AnltAccLoad(ClearingError.GeneralError)
);
};
}
@Bean("splitDepositValidator")
public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() {
return refundDateRequest -> {
@ -361,7 +414,8 @@ public class ValidationConfig {
IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class,
ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false),
SplitDepositRequestValidationRule.PositiveAmount,
SplitDepositRequestValidationRule.CrossvalidateByRegistry
SplitDepositRequestValidationRule.CrossvalidateByRegistry,
SplitDepositRequestValidationRule.LoadContractIndexes
);
};
}
@ -373,6 +427,7 @@ public class ValidationConfig {
ctx.setValidatedObject(pmtOut);
ctx.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
ctx.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
ctx.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
return new ValidatorImpl<>(ctx,
PaymentOutboundValidationRule.RequiredFields,
IdPresentRule.instance("senderId",
@ -380,15 +435,17 @@ public class ValidationConfig {
IMDGDistributedNames.Map_Company,
Company.class,
ClearingError.RequiredFieldEmpty,
ClearingError.DictionaryNotFound),
ClearingError.WrongField),
IdPresentRule.instance("addresseeId",
PIClearingOutbondActionNewRequest::getAddresseeId,
IMDGDistributedNames.Map_Company,
Company.class,
ClearingError.RequiredFieldEmpty,
ClearingError.DictionaryNotFound),
ClearingError.WrongField),
PaymentOutboundValidationRule.CreditLegAccount,
PaymentOutboundValidationRule.DebitLegAccount);
PaymentOutboundValidationRule.DebitLegAccount,
PaymentOutboundValidationRule.AddresseePresent,
PaymentOutboundValidationRule.TcrPresent);
};
}
@ -415,6 +472,39 @@ public class ValidationConfig {
};
}
@Bean
public Function<StatementRequest, IValidator> sdf55ExecutorValidation() {
return req -> {
ImdgValidationContext<StatementRequest> ctx = new ImdgValidationContext<>();
ctx.setValidatedObject(req);
ctx.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
ctx.addImdg(IMDGDistributedNames.Map_SDf55, sDf55Imdg);
ctx.addImdg(IMDGDistributedNames.Map_SDf54, sDf54Imdg);
ctx.addImdg(IMDGDistributedNames.Map_PaymentInstruction, pmtImdg);
ctx.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
return new ValidatorImpl<>(ctx,
Sdf55ValidationRule.Fields,
Sdf55ValidationRule.GenerationIdFound,
Sdf55ValidationRule.Sdf54Present,
Sdf55ValidationRule.PaymentInstructionPresent,
Sdf55ValidationRule.TcrPresent,
Sdf55ValidationRule.AssetsPresent);
};
}
@Bean("terminateSessionValidator")
public Supplier<IValidator> terminateSessionValidator() {
return () -> {
ImdgValidationContext<Session> ctx = new ImdgValidationContext<>();
ctx.setLogPrefix(LogPrefixId.INSTANCE);
ctx.addImdg(IMDGDistributedNames.Map_Session, imdgSession);
return new ValidatorImpl<>(ctx,
SessionTerminationValidationRule.SessionPresent,
SessionTerminationValidationRule.StatusCheck
);
};
}
@Bean("userRoleVerification")
public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver msgs) {
return new UserRoleVerification(imdgProvider, msgs, ClearingError.UserVerifyDenial);

View file

@ -14,6 +14,8 @@ public class ClearingServiceSettings {
private HazelcastClientParams hazelcast;
private KafkaConsumerSettings kafkaConsumer;
private KafkaProducerSettings kafkaProducer;
private SessionStageSettings sessionStage;
private TradeSettings trade = new TradeSettings();
public HazelcastClientParams getHazelcast() {
return hazelcast;
@ -38,4 +40,20 @@ public class ClearingServiceSettings {
public void setKafkaProducer(KafkaProducerSettings kafkaProducer) {
this.kafkaProducer = kafkaProducer;
}
public SessionStageSettings getSessionStage() {
return sessionStage;
}
public void setSessionStage(SessionStageSettings sessionStage) {
this.sessionStage = sessionStage;
}
public TradeSettings getTrade() {
return trade;
}
public void setTrade(TradeSettings trade) {
this.trade = trade;
}
}

View file

@ -0,0 +1,14 @@
package ru.spcex.clearing.config.element;
public class SessionStageSettings {
//inspection-gateway-timeout
private Integer inspectionGatewayTimeout = 10;
public Integer getInspectionGatewayTimeout() {
return inspectionGatewayTimeout;
}
public void setInspectionGatewayTimeout(Integer inspectionGatewayTimeout) {
this.inspectionGatewayTimeout = inspectionGatewayTimeout;
}
}

View file

@ -0,0 +1,14 @@
package ru.spcex.clearing.config.element;
public class TradeSettings {
private Boolean valuation = false;
public Boolean getValuation() {
return valuation;
}
public void setValuation(Boolean valuation) {
this.valuation = valuation;
}
}

View file

@ -23,13 +23,19 @@ public enum ClearingError implements IErrorEnumId {
SuchRecordAlreadyExists(5405L),
TradingClearingRegistryNotFound(5418L),
TradingClearingRegistryNotActive(5419L),
CategoryNotFound(5420L),
ClearingUnavailableForCompany(5421L),
InsecurityObligation(5422L),
NewDealsNotFound(5423L),
IdentifiedFundsExceedObligations(5424L),
ObligationsAlreadyCalculated(5425L),
RefundDtLessThatValueDt(5426L),
ActiveSessionIsPresent(5428L),
AccountIsNotMatchedWithCompany(5429L),
RgsWrongCode(5430L),
RefundDateCannotBeChanged(5431L),
PlanBalanceReviseError(5432L),
XdepTimeIntervalNotMatch(5433L),
//ошибки "перенесенные" из balance-service,
CompanyNotFoundB(5211L),
CurrencyNotFound(5213L),
@ -40,6 +46,8 @@ public enum ClearingError implements IErrorEnumId {
BalanceInsufficient(5222L),
TCRegistryNotFound(3022L),
WrongField(5004L),
GatewayTimeout(6003L),
GatewayNotApproved(6004L),
;
private final Long id;

View file

@ -0,0 +1,20 @@
package ru.spcex.clearing.error;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
public enum RgsError implements IErrorEnumId {
A__tNotFound(5700L)
;
private final Long id;
RgsError(Long id) {
this.id = id;
}
@Override
public Long getId() {
return id;
}
}

View file

@ -0,0 +1,32 @@
package ru.spcex.clearing.notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.Priority;
@Component
public class NotificationSender {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
@Autowired
public NotificationSender(KafkaSender kafkaSender) {
this.kafkaSender = kafkaSender;
}
public void sendNotification(ObjectType objType, String comment, Priority priority) {
NotificationNewRequest reviseNotification = new NotificationNewRequest();
reviseNotification.setObjectType(objType.getKey());
reviseNotification.setComment(comment);
reviseNotification.setPriority(priority.getKey());
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification);
log.info("notification {} sent {}", objType, comment);
}
}

View file

@ -17,6 +17,10 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.text.TextUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class AnltSearcher {
@ -52,7 +56,10 @@ public class AnltSearcher {
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
ImdgPredicate tcrPredicate = pb.and(
pb.equals("code", commentTcrStripped),
pb.equals("status", ServiceStatus.Active.getKey())
pb.or(
pb.equals("status", ServiceStatus.Active.getKey()),
pb.equals("status", ServiceStatus.Reopened.getKey())
)
);
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByPredicate(tcrPredicate);
@ -80,17 +87,19 @@ public class AnltSearcher {
return new AnltSearch(infoAcc, company, tcr);
}
private static final Pattern tcrPattern = Pattern.compile("ТКР.*?([0-9A-Z-]{12})");
private static String getTkrCodeFromComment(String comment) {
if (comment == null) {
if (TextUtil.isEmpty(comment)) {
return null;
}
comment = comment.toUpperCase();
int tcrIndex = comment.indexOf("ТКР");
if (tcrIndex == -1) {
Matcher matcher = tcrPattern.matcher(comment);
if (matcher.find()) {
return matcher.group(1);
} else {
return null;
}
comment = comment.substring(tcrIndex + 3);
return comment.replaceAll("\\s+", "");
}
public static class AnltSearch {

View file

@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -16,9 +17,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SessionContinueE
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImportedRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
@ -55,10 +54,11 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
private final BalanceRevise balanceRevise;
private final Sdf05Sender sdf05Sender;
private final StatementServiceV2 statementService;
private final SessionTerminator sessionTerminator;
private final PaymentInstructionOutboundService pmtOutboundService;
@Autowired
public EventsReceiver(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaResponseQueue,
public EventsReceiver(@Qualifier("kafkaConsumer") Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaResponseQueue,
IMessageResolver errorResolver,
ClearingService clearingService,
RegistryService registryService,
@ -66,7 +66,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
SecondaryAuctionT0Session secondaryAuctionT0Session,
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
Sdf06Executor sdf06Executor,
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, PaymentInstructionOutboundService pmtOutboundService) {
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, SessionTerminator sessionTerminator, PaymentInstructionOutboundService pmtOutboundService) {
super(kafkaQueue, kafkaResponseQueue);
this.errorResolver = errorResolver;
this.clearingService = clearingService;
@ -84,6 +84,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
this.balanceRevise = balanceRevise;
this.sdf05Sender = sdf05Sender;
this.statementService = statementService;
this.sessionTerminator = sessionTerminator;
this.pmtOutboundService = pmtOutboundService;
}
@ -154,6 +155,12 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
callback(RegistryReturnDepositRequest.class)
.setFunction(registryService::returnDeposit)
.forDestination(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, callbacks::put);
callback(RegistryChangeStatusExtractRequest.class)
.setFunction(registryService::changeStatusExtract)
.forDestination(Consts.REGISTRY_CHANGE_STATUS_EXTRACT_ACTION, callbacks::put);
callback(IdentificationFundsRequest.class)
.setFunction(registryService::identificationFunds)
.forDestination(Consts.REGISTRY_IDENTIFICATION_FUNDS, callbacks::put);
callback(RegistryChangeRefundDateRequest.class)
.setFunction(registryService::changeRefundDate)
.forDestination(Consts.REGISTRY_CHANGE_REFUND_DATE_ACTION, callbacks::put);
@ -179,6 +186,11 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
callback(LauncherCommandRequest.class)
.setConsumer(task -> sdf05Sender.sendSdf05("9"))
.forDestination(Task.sdf05WithCode9Final.topic(), callbacks::put);
callback(Object.class)
.setFunction(sessionTerminator::stopCurrentSession)
.forDestination(Consts.KILL_SESSION, callbacks::put);
init();
}

View file

@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
@ -17,7 +18,7 @@ public class LauncherCommandReceiver extends QueueConsumer implements Initializi
private final ClearingService clearingService;
@Autowired
public LauncherCommandReceiver(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaResponseQueue,
public LauncherCommandReceiver(@Qualifier("kafkaConsumer") Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaResponseQueue,
ClearingService clearingService) {
super(kafkaQueue, kafkaResponseQueue);
this.clearingService = clearingService;

View file

@ -4,19 +4,34 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.misc.Currency;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.notification.NotificationSender;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
import ru.spcex.clearing.service.integration.GatewayRequestCreator;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.registry.RegistryManager;
import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -32,10 +47,13 @@ import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service
public class RegistryService {
@ -44,26 +62,58 @@ public class RegistryService {
private final ImdgProvider imdgProvider;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Registry> registryImdg;
private final Imdg<Account> accImdg;
private final Imdg<Currency> currImdg;
private final Imdg<Company> cmpImdg;
private final Imdg<PaymentInstruction> pmtImdg;
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
private final Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal;
private final Function<IdentificationFundsRequest, IValidator> identificationFundsVal;
private final Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal;
private final GatewayRequester gateway;
private final TradingTimeService trdTime;
private final NotificationSender notification;
private final KafkaSender kafkaSender;
private final IMessageResolver msgResolver;
private final RequestHelper reqHelp;
private final UserRoleVerification rights;
private final AssetTBFProcessing assets;
public RegistryService(ImdgProvider imdgProvider,
@Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal,
@Qualifier("refundDateValidator") Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal,
@Qualifier("identificationFundsValidator") Function<IdentificationFundsRequest, IValidator> identificationFundsVal,
@Qualifier("splitDepositValidator") Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal,
IMessageResolver msgResolver,
UserRoleVerification rights) {
@Qualifier("statusExtractValidator") Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal,
GatewayRequester gateway,
TradingTimeService tradingTimeService,
NotificationSender notification,
KafkaSender kafkaSender, IMessageResolver msgResolver,
RequestHelper reqHelp,
UserRoleVerification rights,
AssetTBFProcessing assets) {
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.accImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
this.cmpImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.returnDepositVal = returnDepositVal;
this.refundDateVal = refundDateVal;
this.identificationFundsVal = identificationFundsVal;
this.splitDepositActionVal = splitDepositActionVal;
this.statusExtractVal = statusExtractVal;
this.gateway = gateway;
this.trdTime = tradingTimeService;
this.notification = notification;
this.kafkaSender = kafkaSender;
this.assets = assets;
this.gateway.setName("RgsService|DM*V");
this.msgResolver = msgResolver;
this.reqHelp = reqHelp;
this.rights = rights;
rights.setRoleForVerification(UserRole.Admin);
}
@ -117,6 +167,59 @@ public class RegistryService {
registryImdg.update(rgs);
log.trace("TCR#id={} registry#id={} updated", tcr.getId(), rgs.getId());
});
if (registries.stream().anyMatch(r -> RegistryInstrumentType.M.equalsByKey(r.getRegistryInstrumentType()))) {
log.info("assets size {} updated by TCR#id={}, will not create new assets",
registries.size(), tcr.getId());
return;
} else if (tcr.getMoneyAccountId() == null) {
log.info("assets size {} updated by TCR#id={}, TCR#moneyAccountId 'null'. will not create AM**",
registries.size(), tcr.getId());
return;
} else {
log.info("assets size {} updated by TCR#id={}, TCR#moneyAccountId {}. creating new AM**...",
registries.size(), tcr.getId(), tcr.getMoneyAccountId());
}
Account acc = accImdg.getSingleObjectByID(tcr.getMoneyAccountId());
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
Company cmp = cmpImdg.getSingleObjectByID(tcr.getCompanyId());
if (acc == null) {
log.warn("TCR#id={} account {} not found", tcr.getId(), tcr.getMoneyAccountId());
return;
}
if (currency == null) {
log.warn("TCR#id={} currency {} not found", tcr.getId(), CurrencyCode.RUB.getKey());
return;
}
if (cmp == null) {
log.warn("TCR#id={} company {} not found", tcr.getId(), tcr.getCompanyId());
return;
}
log.debug("TCR#id={} account#id={} company#id={}, creating assets", tcr.getId(), acc.getId(), cmp.getId());
AssetTrio assets = this.assets.createMAssets(acc,
CurrencyCode.RUB.getKey(),
currency.getId(),
tcr.getTradingClearingRegistryType(),
tcr.getId(),
tcr.getCode(),
cmp);
Stream.of(assets.a__t(), assets.a__b(), assets.a__f())
.forEach(a -> {
a.setRegistryStatus(RegistryStatus.PROC.getKey());
registryImdg.insert(a);
});
log.debug("TCR#id={} created {}#id={} {}#id={} {}#id={}",
tcr.getId(),
assets.a__f().getRegistryCode(), assets.a__f().getId(),
assets.a__t().getRegistryCode(), assets.a__t().getId(),
assets.a__b().getRegistryCode(), assets.a__b().getId());
}
public RequestInfoUpdate returnDeposit(BaseRequest<RegistryReturnDepositRequest> req) {
@ -129,33 +232,144 @@ public class RegistryService {
msgResolver.resolve(err.get()));
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
}
Registry tm_t = validator.getStored(Stored.PresentById);
Registry dm_x = validator.getStored(ValidationStored.ReturnDepositDmx);
if (dm_x != null) {
dm_x.setSessionId(null);
dm_x.setSessionType(null);
dm_x.setBalance(requestPayload.getBalance());
dm_x.setUpdated(Instant.now());
registryImdg.update(dm_x);
log.debug("updated dm*x.id={} by RegistryReturnDepositRequest.id={}",
dm_x.getId(),
Registry _m_t = validator.getStored(ValidationStored.ReturnDepositOm_t);
if (_m_t == null) _m_t = validator.getStored(Stored.PresentById);
Registry dm__ = validator.getStored(ValidationStored.ReturnDepositDm__);
if (dm__ != null) {
dm__.setSessionId(null);
dm__.setSessionType(null);
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
dm__.setUpdated(Instant.now());
registryImdg.update(dm__);
log.debug("updated {}.id={} by RegistryReturnDepositRequest.id={}",
dm__.getRegistryCode(),
dm__.getId(),
req.getId());
} else {
dm_x = tm_t.clone();
dm_x.setRegistryDesignation(RegistryDesignation.D.getKey());
dm_x.setRegistryUnit(RegistryUnit.X.getKey());
dm_x.setRegistryCode(RegistryUtil.clearingCode(dm_x));
dm_x.setBalance(requestPayload.getBalance());
dm_x.setSessionId(null);
dm_x.setSessionType(null);
registryImdg.insert(dm_x);
log.debug("created dm*x.id={} by RegistryReturnDepositRequest.id={}",
dm_x.getId(),
dm__ = _m_t.clone();
dm__.setRegistryDesignation(RegistryDesignation.D.getKey());
RegistryManager.zeroState(dm__);
dm__.setSettlementDate(LocalDate.now());
dm__.setValueDate(null);
dm__.setRefundDate(null);
if (RegistryDesignation.T.equalsByKey(_m_t.getRegistryDesignation())) {
dm__.setRegistryUnit(RegistryUnit.X.getKey());
} else {
dm__.setRegistryUnit(RegistryUnit.T.getKey());
}
dm__.setRegistryCode(RegistryUtil.clearingCode(dm__));
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
dm__.setSessionId(null);
dm__.setSessionType(null);
registryImdg.insert(dm__);
log.debug("created {}.id={} by RegistryReturnDepositRequest.id={}",
dm__.getRegistryCode(),
dm__.getId(),
req.getId());
}
return new RequestInfoUpdate(req.getId(), Status.Success, null);
}
public RequestInfoUpdate changeStatusExtract(BaseRequest<RegistryChangeStatusExtractRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
RegistryChangeStatusExtractRequest payload = req.getRequestPayload();
IValidator validator = statusExtractVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("RegistryChangeStatusExtractRequest.id={} validation error: {}",
req.getId(),
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
Registry rgs = validator.getStored(Stored.PresentById);
if (trdTime.isTradingTime()) {
Long gtwReqId = kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, gtwReq(rgs));
log.debug("send request to {} id={}", Consts.ASSET_OPERATION, gtwReqId);
} else {
log.debug("RegistryChangeStatusExtractRequest rgs.id={} not sending gateway request", rgs.getId());
}
rgs.setRegistryStatus(payload.getRegistryStatus());
log.debug("changing registry.id={} status to {}", rgs.getId(), payload.getRegistryStatus());
registryImdg.update(rgs);
assets.searchMoneyByAccAndCompany(rgs.getCompanyId(), rgs.getAccountId())
.ifPresentOrElse(
astTrio -> assets.process(astTrio.a__b(),
astTrio.a__t(),
astTrio.a__f(),
BigDecimal.ZERO),
() -> log.error("RegistryChangeStatusExtractRequest rgs.id={} assets not found", rgs.getId()));
return reqHelp.success(req.getId());
}
private AssetOperationListRequest gtwReq(Registry rgs) {
AssetOperationRequest item = GatewayRequestCreator.from(rgs, InOutDirection.in);
AssetOperationListRequest gtwReq = new AssetOperationListRequest();
gtwReq.setAssetOperationRequests(Collections.singletonList(item));
return gtwReq;
}
public RequestInfoUpdate identificationFunds(BaseRequest<IdentificationFundsRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
IdentificationFundsRequest payload = req.getRequestPayload();
IValidator validator = identificationFundsVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("IdentificationFundsRequest.id={} validation error: {}",
req.getId(),
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
Registry dmau = validator.getStored(Stored.PresentById);
AnltSearcher.AnltSearch accCompTcr = validator.getStored(ValidationStored.IdentificationFundsTcrSearch);
AssetTrio asts = validator.getStored(ValidationStored.IdentificationFundsAssetTrio);
Account anltAcc = validator.getStored(Stored.AnltAccount);
BigDecimal dmauBalance = safeBD(dmau.getBalance());
BigDecimal dmauDebitBalance = safeBD(dmau.getDebit());
BigDecimal reqBalance = payload.getBalance();
BigDecimal am_tBalance = safeBD(asts.a__t().getBalance());
BigDecimal am_tCreditBalance = safeBD(asts.a__t().getCredit());
dmau.setBalance(dmauBalance.subtract(reqBalance));
dmau.setDebit(dmauDebitBalance.add(reqBalance));
asts.a__t().setBalance(am_tBalance.add(reqBalance));
asts.a__t().setCredit(am_tCreditBalance.add(reqBalance));
Instant now = Instant.now();
dmau.setUpdated(now);
asts.a__t().setUpdated(now);
//paymentInstruction
PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider)
.registry(asts.a__b())
.sender(Sender.One.getId())
.addressee(accCompTcr.getCompany().getId())
.debitLegAccount(accCompTcr.getAccount())
.creditLegAccount(anltAcc)
.amount(payload.getBalance())
.sessionId(null)
.purpose("purpose")
.build();
pmt.setTransactionStatus(TransactionStatus.ok.getKey());
pmtImdg.insert(pmt);
registryImdg.update(dmau);
registryImdg.update(asts.a__t());
assets.process(asts.a__b(), asts.a__t(), asts.a__f(), BigDecimal.ZERO);
log.debug("IdentificationFundsRequest.id={} dmau.id={} am*t.id={} payment_instruction.id={}",
req.getId(), dmau.getId(), asts.a__t().getId(), pmt.getId());
if (trdTime.isTradingTime()) {
log.trace("sending gateway request for IdentificationFundsRequest.id={} dmau.id={}",
req.getId(), dmau.getId());
kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION,
gatewayRequest(dmau, payload.getBalance(),
accCompTcr.getCompany().getTradingCode(),
asts.a__t().getTradingClearingRegistry()));
}
return reqHelp.success(req.getId());
}
public RequestInfoUpdate changeRefundDate(BaseRequest<RegistryChangeRefundDateRequest> req) {
RegistryChangeRefundDateRequest requestPayload = req.getRequestPayload();
IValidator validator = refundDateVal.apply(requestPayload);
@ -201,8 +415,14 @@ public class RegistryService {
if (moneyPredicate.isEmpty() && depoPredicate.isEmpty()) {
return Optional.empty();
}
ImdgPredicate accIdPrdct;
if (moneyPredicate.isPresent() && depoPredicate.isPresent()) {
accIdPrdct = prdBldr.or(moneyPredicate.get(), depoPredicate.get());
} else {
accIdPrdct = prdBldr.and(moneyPredicate.orElse(prdBldr.alwaysTrue()), depoPredicate.orElse(prdBldr.alwaysTrue()));
}
return Optional.ofNullable(prdBldr.and(
prdBldr.or(moneyPredicate.orElse(prdBldr.alwaysTrue()), depoPredicate.orElse(prdBldr.alwaysTrue())),
accIdPrdct,
prdBldr.equals("companyId", companyId),
prdBldr.sql("tradingClearingRegistryId == null")
));
@ -227,56 +447,70 @@ public class RegistryService {
}
public record RgsKey (Long companyId, Long accountId, Long securityId) {
public static RgsKey fromRgs(Registry rgs) {
return new RgsKey(rgs.getCompanyId(), rgs.getAccountId(), rgs.getSecurityId());
}
}
private Optional<Registry> find(List<Registry> group, RegistryTradingParams rgsCode) {
List<Registry> byCodeRes = group.stream()
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
.toList();
if (byCodeRes.size() > 1) {
Optional<Registry> any = group.stream().findFirst();
if (any.isEmpty()) throw new IllegalStateException(); //never
String err = "FATAL: found %d entries by code %s in group %s".formatted(
byCodeRes.size(),
rgsCode,
RgsKey.fromRgs(any.get()).toString()
);
throw new IllegalStateException(err);
}
return byCodeRes.stream().findFirst();
}
public void resetBalances() {
Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of(
"registryDesignation", RegistryDesignation.A.getKey())
);
for (Registry registry : registriesA) {
if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) {
registry.setBalance(BigDecimal.ZERO);
}
if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) {
Optional<Registry> registryBOptional = registriesA.stream().filter(rgs ->
rgs.getAccount() != null && rgs.getSecurityId() != null &&
rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null &&
RegistryUnit.B.equalsByKey(rgs.getRegistryUnit()) &&
rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) &&
rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) &&
rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) &&
rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId())
).findFirst();
Optional<Registry> registryTOptional = registriesA.stream().filter(rgs ->
rgs.getAccount() != null && rgs.getSecurityId() != null &&
rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null &&
RegistryUnit.T.equalsByKey(rgs.getRegistryUnit()) &&
rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) &&
rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) &&
rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) &&
rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId())
).findFirst();
BigDecimal balanceB;
if (registryBOptional.isPresent()) {
balanceB = registryBOptional.get().getBalance();
} else {
balanceB = BigDecimal.ZERO;
}
registryTOptional.ifPresent(rgsT -> registry.setBalance(rgsT.getBalance().subtract(balanceB)));
}
if (RegistryUnit.T.equalsByKey(registry.getRegistryUnit())) {
registry.setOpenBalance(registry.getBalance());
}
Map<RgsKey, List<Registry>> allAssets = registriesA
.stream()
.collect(Collectors.groupingBy(RgsKey::fromRgs));
registry.setDebit(BigDecimal.ZERO);
registry.setSettledDebit(BigDecimal.ZERO);
registry.setCredit(BigDecimal.ZERO);
registry.setSettledCredit(BigDecimal.ZERO);
registry.setPlanBalance(BigDecimal.ZERO);
registry.setCloseBalance(registry.getBalance());
registry.setUpdated(Instant.now());
registryImdg.update(registry);
Instant timestamp = Instant.now();
for (Map.Entry<RgsKey, List<Registry>> entry : allAssets.entrySet()) {
RgsKey key = entry.getKey();
List<Registry> group = entry.getValue();
Registry a__f = find(group, RegistryTradingParams.A__F).orElse(null);
Registry a__t = find(group, RegistryTradingParams.A__T).orElse(null);
Registry a__b = find(group, RegistryTradingParams.A__B).orElse(null);
if (a__t == null) {
log.warn("registry group {}: no A**T registry found.", key);
continue;
}
BigDecimal a__tBalance = safeBD(a__t.getBalance());
a__t.setOpenBalance(a__tBalance);
a__t.setCloseBalance(a__tBalance);
a__t.setCredit(BigDecimal.ZERO);
a__t.setDebit(BigDecimal.ZERO);
a__t.setSettledCredit(BigDecimal.ZERO);
a__t.setSettledDebit(BigDecimal.ZERO);
a__t.setUpdated(timestamp);
registryImdg.update(a__t);
if (a__f == null) {
a__f = assets.copy(a__t, RegistryUnit.F);
registryImdg.insert(a__f);
}
if (a__b != null) {
a__b.setBalance(BigDecimal.ZERO);
registryImdg.update(a__b);
}
assets.process(a__b, a__t, a__f, BigDecimal.ZERO);
}
}
@ -287,6 +521,7 @@ public class RegistryService {
return roleCheck;
}
Collection<Registry> baseRegistrys;
Integer index;
{
IValidator validator = splitDepositActionVal.apply(requestPayload);
Optional<EnumMessage> err = validator.tillFirstError();
@ -297,6 +532,8 @@ public class RegistryService {
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
}
baseRegistrys = validator.getStored(ValidationStored.RegistrysByContract);
index = validator.getStored(ValidationStored.SplitDepositMaxNumber);
if (index == null) index = 0;
}
ImdgTransaction txCtx = imdgProvider.newTransaction();
@ -313,6 +550,13 @@ public class RegistryService {
log.debug("Process {} for {} registry", direction, baseRegistrys.size());
Long groupId = null;
for (Registry baseRegistry : baseRegistrys) {
String cntrctWithoutTilda;
{
cntrctWithoutTilda = baseRegistry.getContract();
if (cntrctWithoutTilda.contains("~")) {
cntrctWithoutTilda = cntrctWithoutTilda.substring(0, cntrctWithoutTilda.indexOf("~"));
}
}
log.trace("Registry[{}], groupId={}, ClearingCode={}", baseRegistry.getId(), baseRegistry.getGroupId(), baseRegistry.getClearingCode());
if (groupId == null)
groupId = baseRegistry.getGroupId();
@ -331,9 +575,9 @@ public class RegistryService {
} else {
log.warn("Direction not set, do not change Balance");
}
firstRegistry.setContract(baseRegistry.getContract() + "~1");
firstRegistry.setContract(cntrctWithoutTilda + "~" + (index + 1));
firstRegistry.setParentId(baseRegistry.getId());
registryTMap.insert(firstRegistry);
// 2. Вторая группа
Registry secondRegistry = null;
if (InOutDirection.out == direction) {
@ -342,9 +586,10 @@ public class RegistryService {
secondRegistry.setCreated(now);
secondRegistry.setUpdated(null);
secondRegistry.setBalance(requestPayload.getOutboundAmount());
secondRegistry.setContract(baseRegistry.getContract() + "~2");
secondRegistry.setContract(cntrctWithoutTilda + "~" + (index + 2));
secondRegistry.setRefundDate(requestPayload.getRefundDate());
secondRegistry.setSettlementDate(requestPayload.getRefundDate());
secondRegistry.setParentId(baseRegistry.getId());
registryTMap.insert(secondRegistry);
}
@ -372,4 +617,16 @@ public class RegistryService {
return new RequestInfoUpdate(req.getId(), Status.Success, null);
}
private AssetOperationListRequest gatewayRequest(Registry dmau, BigDecimal balance, String tradingCode, String tcrCode) {
AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
AssetOperationRequest req = GatewayRequestCreator.from(
dmau.getId(),
null,
balance,
InOutDirection.in,
tradingCode,
tcrCode);
gatewayRequest.setAssetOperationRequests(List.of(req));
return gatewayRequest;
}
}

View file

@ -161,7 +161,7 @@ public class Sdf54Creator {
}
sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate())));
sDf54.setPay_val("RUR");
sDf54.setPay_val(CurrencyCode.RUB.getKey());
String sumDeb = paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : "";
sDf54.setSum_deb(BigDecimalUtil.limitDecimalPlaces(sumDeb, 2));
sDf54.setSpecif_1(paymentInstruction.getPaymentPurpose());

View file

@ -1,42 +0,0 @@
package ru.spcex.clearing.service.builder;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.math.BigDecimal;
public class PaymentInstructionBuilderDepositReturn {
private ImdgProvider imdgProvider;
private Long sessionId;
private BigDecimal amount;
private Registry lm_tRgs;
public static PaymentInstructionBuilderDepositReturn builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderDepositReturn(imdgProvider);
}
private PaymentInstructionBuilderDepositReturn(ImdgProvider imdgProvider) {
this.imdgProvider = imdgProvider;
}
public PaymentInstructionBuilderDepositReturn sessionId(Long sessionId) {
this.sessionId = sessionId;
return this;
}
public PaymentInstructionBuilderDepositReturn amount(BigDecimal amount) {
this.amount = amount;
return this;
}
public PaymentInstructionBuilderDepositReturn lm_tRgs(Registry rgs) {
this.lm_tRgs = rgs;
return this;
}
public PaymentInstruction build() {
return null;
}
}

View file

@ -44,6 +44,7 @@ public class PaymentInstructionBuilderFinalMkrDeals {
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
private String purpose;
private String lmtPurpose = null;
public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider);
@ -86,6 +87,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
return this;
}
public PaymentInstructionBuilderFinalMkrDeals paymentPurposeLmt(String purpose) {
this.lmtPurpose = purpose;
return this;
}
public Pair<PaymentInstruction, PaymentInstruction> build() {
PaymentInstruction payment1;
@ -128,7 +134,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
payment1.setPaymentPurpose(purpose);
if (lmtPurpose != null) {
payment1.setPaymentPurpose(lmtPurpose);
} else {
payment1.setPaymentPurpose(purpose);
}
payment1.setSettlementDate(lm_t.getSettlementDate());

View file

@ -4,7 +4,9 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
@ -12,12 +14,17 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
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.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.time.TimeUtil;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@ -27,6 +34,9 @@ public class PaymentInstructionBuilderV2 {
private ImdgProvider imdgProvider;
private Imdg<Company> companyImdg;
private Imdg<CompanySymbols> companySymbolsImdg;
private Imdg<Registry> rgsImdg;
private final Imdg<ClearingMemberCategory> clearingCategoryImdg;
private final Imdg<CompanyRoleSet> cmpRoleImdg;
private Long sessionId;
private BigDecimal amount;
private Account creditLegAccount;
@ -37,6 +47,9 @@ public class PaymentInstructionBuilderV2 {
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
private Long senderId;
private Long addresseeId;
private boolean useCS_BLKD = false;
private Registry am_b;
public static PaymentInstructionBuilderV2 builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderV2(imdgProvider);
@ -46,6 +59,18 @@ public class PaymentInstructionBuilderV2 {
this.imdgProvider = imdgProvider;
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.cmpRoleImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class);
}
public PaymentInstructionBuilderV2 checkBLKD(Registry rgs) {
if (rgs == null) {
return this;
}
this.useCS_BLKD = true;
this.am_b = rgs;
return this;
}
public PaymentInstructionBuilderV2 sessionId(Long sessionId) {
@ -128,7 +153,12 @@ public class PaymentInstructionBuilderV2 {
payment.setPaymentDate(Instant.now());
payment.setSettlementDate(LocalDate.now());
}
payment.setPaymentPurpose(purpose);
if (useCS_BLKD && checkAgent()) {
payment.setPaymentPurpose(SpecifFlag.CS_BLKD.getKey() + "_" + sessionId + " " + purpose);
} else {
payment.setPaymentPurpose(purpose);
}
payment.setCreditLeg_amount(amount);
payment.setDebitLeg_amount(amount);
@ -193,4 +223,41 @@ public class PaymentInstructionBuilderV2 {
return cSymbol.getCompanySymbolValue();
}
}
private boolean checkAgent() {
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
ImdgPredicate prdct = pb.and(
pb.equals("sessionId", sessionId),
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.CM__).build()),
pb.equals("companyId", addresseeId),
pb.equals("accountId", am_b.getAccountId())
);
Collection<Registry> claims = rgsImdg.getCollectionObjectsByPredicate(prdct);
boolean hasCounterPartyInitiator = false;
for (Registry claim : claims) {
Long counterPartyId = claim.getCounterPartyId();
if (categoryIOrVInitiator(counterPartyId) && companyRoleODEPPresent(counterPartyId)) {
hasCounterPartyInitiator = true;
break;
}
}
return hasCounterPartyInitiator;
}
public boolean categoryIOrVInitiator(Long companyId) {
ClearingMemberCategory category = clearingCategoryImdg.getFirstObjectByFieldValues(
Map.of("companyId", companyId));
ClearingCategory ctg = IEnumKey.getEnumByKey(ClearingCategory.class, category.getClearingMemberCategory());
return ctg != null && (ctg.equals(ClearingCategory.V) || ctg.equals(ClearingCategory.I)) ;
}
public boolean companyRoleODEPPresent(Long companyId) {
return cmpRoleImdg.getFirstObjectBySQL(
"companyId = %d and companyRole = '%s' and workflowStatus = '%s'".formatted(
companyId,
CompanyRole.ODEP.getKey(),
WorkflowStatus.Active.getKey()
)
) != null;
}
}

View file

@ -133,6 +133,7 @@ public class RegistryBuilder {
rgs.setCredit(BigDecimal.ZERO);
rgs.setDiffBalance(BigDecimal.ZERO);
rgs.setCheckBalance(BigDecimal.ZERO);
rgs.setOpenBalance(BigDecimal.ZERO);
return rgs;
}

View file

@ -133,6 +133,7 @@ public class RegistrySecurityBuilder {
rgs.setCredit(BigDecimal.ZERO);
rgs.setDiffBalance(BigDecimal.ZERO);
rgs.setCheckBalance(BigDecimal.ZERO);
rgs.setOpenBalance(BigDecimal.ZERO);
return rgs;
}

View file

@ -11,29 +11,34 @@ import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.execution.ExecutionFond;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.misc.STrades;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.config.element.ClearingServiceSettings;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.error.ClearingException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.notification.NotificationSender;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DealRegisterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.ExecutionType;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.Side;
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.enumeration.*;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.time.TimeUtil;
import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
@ -41,6 +46,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Component
@EnableScheduling
public class ExecutionFondComponent {
@ -50,6 +57,7 @@ public class ExecutionFondComponent {
private final Imdg<ExecutionFond> executionFondImdg;
private final Imdg<Listing> listingImdg;
private final Imdg<ClientCode> clientCodeImdg;
private final Imdg<FixedIncomeCashFlow> fixedIncomeCashFlowImdg;
private final Imdg<ru.clearing.classes.statics.data.misc.Market> marketImdg;
//fixme ждать ТЗ
@ -58,19 +66,26 @@ public class ExecutionFondComponent {
private final IMessageResolver msgResolver = new SimpleMessageResolver();
private final Function<STrades, IValidator> stradesValidator;
private final KafkaSender kafkaSender;
private final NotificationSender notifications;
private final boolean valuation;
@Autowired
public ExecutionFondComponent(ImdgProvider imdgProvider, Producer<String, Object> kafka,
public ExecutionFondComponent(ImdgProvider imdgProvider,
ClearingServiceSettings settings,
Producer<String, Object> kafka,
@Qualifier("sTradesValidatorFond") Function<STrades, IValidator> stradesValidator,
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender) {
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender, NotificationSender notifications) {
this.sTradeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class);
this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
this.clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, ru.clearing.classes.statics.data.misc.Market.class);
this.fixedIncomeCashFlowImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class);
this.valuation = settings.getTrade().getValuation(); //fixme
this.stradesValidator = stradesValidator;
this.kafkaSender = kafkaSender;
this.notifications = notifications;
resetTradingDay();
}
@ -119,7 +134,7 @@ public class ExecutionFondComponent {
log.info("{} strades left after already-added filtering", sTrades.size());
for (STrades sTrd : sTrades) {
log.trace("S_TRADE[{}] new", sTrd.getId());
log.info("new S_TRADE[{}], valuation {}", sTrd.getId(), valuation);
//проверки
IValidator validator = stradesValidator.apply(sTrd);
@ -165,6 +180,7 @@ public class ExecutionFondComponent {
protected ExecutionFond createExecutionFond(STrades sTrades,
IValidator validator) throws ClearingException {
Security security = validator.getStored(ValidationStored.STradesSecurity);
// Listing listing = listingImdg.getFirstObjectByFieldValues(Map.of("securityId", security.getId()));
Company company = validator.getStored(ValidationStored.STradesCompany);
Company counterCompany = validator.getStored(ValidationStored.STradesCounterCompany);
TradingClearingRegistry rgstr = validator.getStored(ValidationStored.STradesTradingClearingRegistry);
@ -212,7 +228,57 @@ public class ExecutionFondComponent {
eFond.setSecurityId(security.getId());
eFond.setInterestAmount(sTrades.getAccruedint());
eFond.setExchangeOrderId(sTrades.getOrderNum());
eFond.setSettlementAmount(sTrades.getValue());
if (valuation) {
Listing listing = listingImdg.getFirstObjectBySQL("securityId = %d and market = '%s'".formatted(security.getId(), sTrades.getClassCode()));
BigDecimal lotSize = listing != null ? safeBD(listing.getLotSize()) : BigDecimal.ONE;
BigDecimal qty = safeBD(eFond.getLots()).multiply(lotSize);
eFond.setQuantity(qty);
BigDecimal price = safeBD(sTrades.getPrice());// eFond.setPrice
BigDecimal settlementAmount = BigDecimal.ZERO;
if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
FixedIncomeSecurity fixedIncome = (FixedIncomeSecurity) security;
BigDecimal nominalValue;
ImdgPredicateBuilder pb = fixedIncomeCashFlowImdg.predicateBuilder();
ImdgPredicate prdct = pb.and(
pb.equals("securityId", fixedIncome.getId()),
sTrades.getSettleDate() != null ?
pb.equals("valueDate", sTrades.getSettleDate()) : pb.alwaysFalse()
);
FixedIncomeCashFlow cashFlow = fixedIncomeCashFlowImdg.getFirstObjectByPredicate(prdct);
if (cashFlow != null) {
nominalValue = safeBD(cashFlow.getNominalValue());
} else {
nominalValue = safeBD(fixedIncome.getNominalValue());
}
{
settlementAmount = eFond.getQuantity()
.multiply(nominalValue)
.multiply(price)
.divide(new BigDecimal(100), RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
}
} else if (InstrumentType.EQTY.equalsByKey(security.getInstrumentType())) {
BigDecimal lotsEqty = safeBD(eFond.getQuantity());
settlementAmount = lotsEqty.multiply(price).setScale(2, RoundingMode.HALF_UP);
}
eFond.setSettlementAmount(settlementAmount);
if (settlementAmount.compareTo(safeBD(sTrades.getValue())) != 0) {
log.warn("sTrades.TradeNum={} sTrades.value({}) != eFond({})",
sTrades.getTradeNum(),
safeBD(sTrades.getValue()),
settlementAmount);
notifications.sendNotification(
ObjectType.vfrs,
"Для сделки %s объем сделки в ТС %s не совпадает с расчитанным в КС %s"
.formatted(sTrades.getTradeNum(),
safeBD(sTrades.getValue()).toString(),
settlementAmount.toString()),
Priority.HIGH
);
}
} else {
eFond.setSettlementAmount(sTrades.getValue());
}
eFond.setCounterPartyId(counterCompany.getId());
{
ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder();

View file

@ -25,8 +25,8 @@ import java.util.Optional;
@Component
public class Reviser {
private final Logger log = LoggerFactory.getLogger(Reviser.class);
private static final String reviseFailedMessage = "Сверка остатков денежных средств по результатам клиринговой сессии завершена с ошибками.";
private static final String reviseSuccessMessage = "Сверка остатков денежных средств по результатам клиринговой сессии завершена успешно.";
private static final String reviseFailedMessage = "После сверки обнаружена разница между сверочным и фактическим балансом.";
private static final String reviseSuccessMessage = "Ошибок после получения остатков не обнаружено.";
private final Imdg<Registry> registryImdg;
private final Imdg<Statement> statementImdg;
private final Imdg<SDf01> sdf01Imdg;
@ -66,7 +66,7 @@ public class Reviser {
log.trace("revise ok for sdf01.id={}, stmt.id={}, registry.id={}", sdf.getId(), statement.get().getId(), registry.get().getId());
}
NotificationNewRequest reviseNotification = new NotificationNewRequest();
reviseNotification.setObjectType(ObjectType.rgst.getKey());
reviseNotification.setObjectType(ObjectType.diff.getKey());
reviseNotification.setComment(reviseFailed ? reviseFailedMessage : reviseSuccessMessage);
reviseNotification.setPriority(reviseFailed ? Priority.HIGH.getKey() : Priority.LOW.getKey());
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification);

Some files were not shown because too many files have changed in this diff Show more