Compare commits

..

407 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
AKurakin
b8df4ad882 imdg http://jira.mfd.msk:8088/browse/CLS-502 DDL 3.8 bugfix MoneyMarketSecurityMapStore 2023-09-06 19:05:11 +03:00
AKurakin
b048c84bee account-service http://jira.mfd.msk:8088/browse/CLS-489 sdf52 2023-09-06 17:55:22 +03:00
AKurakin
d69bbc09b5 backend-api KafkaConfig scope - prototype (должно было и раньше работать, т.к. там больше очередей нет) 2023-09-06 17:25:44 +03:00
AKurakin
da5f351c54 http://jira.mfd.msk:8088/browse/CLS-502 DDL 3.8.1 2023-09-06 17:04:15 +03:00
etreschenkov
7a520e49d6 build distr 2023-09-06 16:30:50 +03:00
AKurakin
4eb265d2f0 dbf-exporter http://jira.mfd.msk:8088/browse/CLS-515 S_DF53 2023-09-06 16:18:43 +03:00
AKurakin
2954c33821 http://jira.mfd.msk:8088/browse/CLS-502 DDL 3.8 backend-api imdg classes db-scripts 2023-09-06 15:36:24 +03:00
etreschenkov
1ea2c551ee build distr 2023-09-06 14:50:52 +03:00
etreschenkov
e24b580ca6 build distr 2023-09-06 14:15:47 +03:00
etreschenkov
a8b4293225 build distr 2023-09-06 14:15:47 +03:00
AKurakin
b40d8a959a http://jira.mfd.msk:8088/browse/CLS-465 обновил DATA.sql 2023-09-06 13:18:49 +03:00
AKurakin
59496d97b0 backend-api http://jira.mfd.msk:8088/browse/CLS-512 meta 2023-09-06 12:49:35 +03:00
ialbert
f75b262c75 http://jira.mfd.msk:8088/browse/CLS-488 Sdf11#outDocument 2023-09-06 12:30:19 +03:00
AKurakin
de16808e25 clearing-service http://jira.mfd.msk:8088/browse/CLS-311 доделки Sdf54 2023-09-06 12:14:43 +03:00
AKurakin
534e1d8cfe securities-service http://jira.mfd.msk:8088/browse/CLS-516 2023-09-06 11:58:14 +03:00
akulikov
e4c8fc8278 http://jira.mfd.msk:8088/browse/CLS-497 some big decimal fixes 2023-09-06 11:47:06 +03:00
ialbert
21df705094 SDF группы для сессий
избавился от StatementService.java
2023-09-05 19:14:17 +03:00
akulikov
0eadc2f7e3 http://jira.mfd.msk:8088/browse/CLS-497 some big decimal fixes 2023-09-05 14:18:49 +03:00
ialbert
8840d89bb0 SdfGroup unit test 2023-09-05 14:00:08 +03:00
ialbert
b92475b272 http://jira.mfd.msk:8088/browse/CLS-465 data.xml добавил новую ошибку в клиринг 2023-09-05 13:52:01 +03:00
ialbert
7ed3e267db SdfGroup added Session sdf groups 2023-09-05 13:50:06 +03:00
ialbert
d68220bf41 http://jira.mfd.msk:8088/browse/CLS-465 2023-09-05 13:48:27 +03:00
AKurakin
4b021a5bdf Merge remote-tracking branch 'origin/tmp_cls' into dev 2023-09-05 12:54:42 +03:00
AKurakin
8fbee21a95 clearing-service http://jira.mfd.msk:8088/browse/CLS-311 поправил заполнение Sdf54 2023-09-05 12:42:46 +03:00
AKurakin
881c66dc1b Merge branch 'tmp_cls' into dev 2023-09-05 11:09:04 +03:00
akulikov
4a08f72d40 http://jira.mfd.msk:8088/browse/CLS-497 KSCommissionTradesReportBuilder fix 2023-09-05 11:04:26 +03:00
AKurakin
67d851b5b6 clearing-service http://jira.mfd.msk:8088/browse/CLS-504 + добавил новую ошибку 2023-09-04 18:05:31 +03:00
AKurakin
b9f924aa8d clearing-service http://jira.mfd.msk:8088/browse/CLS-513 2023-09-04 16:06:54 +03:00
AKurakin
ede6699a56 clearing-service http://jira.mfd.msk:8088/browse/CLS-504 2023-09-04 13:36:28 +03:00
AKurakin
9564202df6 clearing-service http://jira.mfd.msk:8088/browse/CLS-500 поправил код ошибки 5004 2023-09-04 12:44:49 +03:00
AKurakin
5d7772d45e clearing-service http://jira.mfd.msk:8088/browse/CLS-500 2023-09-04 12:33:07 +03:00
akulikov
199d9b3c58 http://jira.mfd.msk:8088/browse/CLS-497 2023-09-01 18:33:36 +03:00
AKurakin
ecb92d024f clearing-service fix ExecutionDepositComponent 2023-09-01 18:22:55 +03:00
519 changed files with 21747 additions and 4931 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,31 +6,43 @@ 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 {
public static final String SDF_STATUS_OK = "0"; // (Операция выполнена успешно) - если account обновлена по sDf52;
public static final String SDF_STATUS_OK = "OK"; // (Операция выполнена успешно) - если account обновлена по sDf52;
public static final String SDF_STATUS_ERROR_REPEAT = "1"; // (Ошибка. Попытка повторно исполнить операцию)
public static final String SDF_STATUS_ERROR_COMPANY_NOT_FOUND = "2"; // (Ошибка. Участник не найден) - если получена ошибка (5013) "Компания %s не найдена" (т.е. account НЕ обновлена по sDf52);
public static final String SDF_STATUS_ERROR_LIMIT_SUMM = "3"; // (Ошибка. Сумма списания превышает сумму средств на торговом счете участника в ТС)
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

@ -1,35 +1,26 @@
package ru.spcex.clearing.backendapi.config;
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Scope;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import ru.spcex.clearing.backendapi.config.element.BackendApiSettings;
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
@Configuration
public class KafkaConfig {
@ -40,8 +31,6 @@ public class KafkaConfig {
return KafkaProducerFactory.producer(settings.getKafkaProducer());
}
@Bean
public ProducerFactory<String, Object> pf(BackendApiSettings settings) {
KafkaProducerSettings kafkaSettings = settings.getKafkaProducer();
@ -73,6 +62,7 @@ public class KafkaConfig {
@Profile("!kafkaDisabled")
@Autowired
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public Consumer<String, Object> createConsumer(BackendApiSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());

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

@ -39,7 +39,10 @@ public class FixedIncomeSecurityNewAction implements IAction<FixedIncomeSecurity
@ApiModelProperty(value = "Размер лота", example = "300.5")
@JsonProperty
public BigDecimal lotSize;
@ApiModelProperty(value = "Номинал", example = "200.5")
@ApiModelProperty(value = "Текущее значение номинала", example = "200.4")
@JsonProperty
public BigDecimal nominalForDate;
@ApiModelProperty(value = "Номинал инструмента", example = "200.5")
@JsonProperty
public BigDecimal nominalValue;
@ApiModelProperty(value = "Наименование валюты номинала", example = "RUB")
@ -83,6 +86,7 @@ public class FixedIncomeSecurityNewAction implements IAction<FixedIncomeSecurity
req.setIsin(this.getIsin());
req.setBondType(this.getBondType());
req.setLotSize(this.getLotSize());
req.setNominalForDate(this.getNominalForDate());
req.setNominalValue(this.getNominalValue());
req.setNominalCurrency(this.getNominalCurrency());
req.setMaturityDate(this.getMaturityDate());
@ -151,6 +155,14 @@ public class FixedIncomeSecurityNewAction implements IAction<FixedIncomeSecurity
this.lotSize = lotSize;
}
public BigDecimal getNominalForDate() {
return nominalForDate;
}
public void setNominalForDate(BigDecimal nominalForDate) {
this.nominalForDate = nominalForDate;
}
public BigDecimal getNominalValue() {
return nominalValue;
}

View file

@ -41,7 +41,10 @@ public class FixedIncomeSecurityUpdateAction implements IAction<FixedIncomeSecur
@ApiModelProperty(value = "Размер лота", example = "300.5")
@JsonProperty
public BigDecimal lotSize;
@ApiModelProperty(value = "Номинал", example = "200.5")
@ApiModelProperty(value = "Текущее значение номинала", example = "200.4")
@JsonProperty
public BigDecimal nominalForDate;
@ApiModelProperty(value = "Номинал инструмента", example = "200.5")
@JsonProperty
public BigDecimal nominalValue;
@ApiModelProperty(value = "Наименование валюты номинала", example = "RUB")
@ -85,6 +88,7 @@ public class FixedIncomeSecurityUpdateAction implements IAction<FixedIncomeSecur
req.setIsin(this.getIsin());
req.setBondType(this.getBondType());
req.setLotSize(this.getLotSize());
req.setNominalForDate(this.getNominalForDate());
req.setNominalValue(this.getNominalValue());
req.setNominalCurrency(this.getNominalCurrency());
req.setMaturityDate(this.getMaturityDate());
@ -161,6 +165,14 @@ public class FixedIncomeSecurityUpdateAction implements IAction<FixedIncomeSecur
this.lotSize = lotSize;
}
public BigDecimal getNominalForDate() {
return nominalForDate;
}
public void setNominalForDate(BigDecimal nominalForDate) {
this.nominalForDate = nominalForDate;
}
public BigDecimal getNominalValue() {
return nominalValue;
}

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,8 +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 -->
@ -472,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."/>
@ -508,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.7.0.45",
"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": {
@ -2536,6 +2570,10 @@
{"code": "fullNameEng",
"type": 2,"length": 255,"name": "Полное наименование инструмента на английском","shortname": "Наименование на английском","searchable": true,"sortable": true,"visible": true,"extends": "security"
}
,
{"code": "clearingOrganization",
"type": 2,"length": 255,"name": "Клиринговая организация","shortname": "Клиринговая организация","searchable": true,"sortable": true,"visible": true,"filterable": "true","filterValue": "АО СПВБ"
}
,
{"code": "isin",
"type": 2,"length": 50,"name": "Наименование инструмента ISIN","shortname": "ISIN","searchable": true,"sortable": true,"visible": true,"extends": "security"
@ -2735,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",
@ -3000,9 +3038,13 @@
{"code": "maturityDate",
"type": 6,"name": "Дата погашения","shortname": "Погашение","searchable": true,"sortable": true
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал","searchable": true,"sortable": true
}
,
{"code": "nominalValue",
"type": 10,"name": "Номинал","shortname": "Номинал","searchable": true,"sortable": true
"type": 10,"name": "Номинал инструмента","shortname": "Номинал","searchable": true,"sortable": true
}
,
{"code": "nominalCurrency",
@ -3078,9 +3120,13 @@
{"code": "lotSize",
"type": 11,"name": "Размер лота","shortname": "Лот","visible": false
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал"
}
,
{"code": "nominalValue",
"type": 10,"name": "Текущий номинал","shortname": "Текущий номинал"
"type": 10,"name": "Номинал инструмента","shortname": "Номинал"
}
,
{"code": "nominalCurrency",
@ -3157,9 +3203,13 @@
{"code": "lotSize",
"field": "securityId","type": 11,"name": "Размер лота","shortname": "Лот","linkKeyCode": "securityId","linkCode": "lotSize","link": "listing","visible": false
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал"
}
,
{"code": "nominalValue",
"type": 10,"name": "Текущий номинал","shortname": "Текущий номинал"
"type": 10,"name": "Номинал инструмента","shortname": "Номинал"
}
,
{"code": "nominalCurrency",
@ -3278,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
}
,
@ -4010,7 +4060,7 @@
,"actions":[
{"method":"post",
"name": "Досрочное изъятие депозита",
"name": "Разделение депозита",
"destination": "registries/splitDeposit",
@ -4061,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
}
]
}
,
@ -4086,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
}
]
}
]
@ -4143,7 +4255,7 @@
,"actions":[
{"method":"post",
"name": "Добавление корреспондентского счета",
"name": "Добавление счета",
"confirmation": "companyId,account,status",
@ -4155,7 +4267,7 @@
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
}
,
{"code": "status",
@ -4170,7 +4282,7 @@
,
{"method":"put",
"name": "Изменение корреспондентского счета",
"name": "Изменение счета",
"confirmation": "companyId,account,status",
@ -4201,7 +4313,7 @@
,
{"method":"delete",
"name": "Блокировка корреспондентского счета",
"name": "Блокировка счета",
"confirmation": "companyId,account",
@ -4510,6 +4622,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
@ -4542,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": {
@ -4574,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
@ -5139,7 +5323,7 @@
"group": "Обмен с расчетной организацией",
"name": "Запрос остатков по всем счетам (отправка ДФ-51, ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"name": "Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"fields": []
}
@ -5150,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",
@ -5170,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",
@ -5232,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",
@ -5365,7 +5553,7 @@
"group": "Формирование отчетности",
"name": "Формирование отчетности по сделкам",
"name": "Формирование отчетности PFX64/PFX65",
"fields": []
}
@ -5389,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": []
}
]
@ -5424,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",
@ -5656,10 +5866,12 @@
,
"executionDeposit": {
"name": "Сделки",
"name": "Сделки на секции МКР",
"destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true",
@ -5686,17 +5898,9 @@
{"code": "partyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "market",
"type": 12,"dbname": "Код секции финансового инструмента","name": "Секция финансового инструмента","shortname": "Секция","visible": true,"searchable": true,"sortable": true,"link": "market","linkKeyCode": "code","linkCode": "description"
"type": 2,"length": 8,"dbname": "Код секции финансового инструмента","name": "Секция финансового инструмента","shortname": "Секция","visible": true,"searchable": true,"sortable": true,"link": "market","linkKeyCode": "code","linkCode": "description"
}
,
{"code": "price",
@ -5778,6 +5982,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"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"
@ -5812,6 +6024,8 @@
"destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true",
@ -5860,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",
@ -5868,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",
@ -5896,15 +6110,7 @@
}
,
{"code": "partyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "comment",
@ -5926,6 +6132,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"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
@ -5960,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",
@ -5982,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",
@ -6006,6 +6222,8 @@
"destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register",
@ -6020,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",
@ -6028,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",
@ -6052,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",
@ -6060,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
}
]
@ -6072,6 +6290,8 @@
"destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register",
@ -6134,6 +6354,8 @@
"destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register",
@ -6196,6 +6418,8 @@
"destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register",
@ -6250,6 +6474,8 @@
"destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register",
@ -6304,6 +6530,8 @@
"destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register",
@ -6382,6 +6610,8 @@
"destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register",
@ -6460,6 +6690,8 @@
"destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register",
@ -6841,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",
@ -6861,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",
@ -6877,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
@ -8152,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",
@ -8162,6 +8396,10 @@
{"code": "deal",
"type": 2,"length": 4,"name": "Биржевой код участника клиринга","shortname": "Биржевой код УК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "date",
"type": 2,"length": 8,"name": "Дата изменения состояния счета","shortname": "Дата изменения состояния счета","searchable": true,"sortable": true,"visible": true
}
,
{"code": "status",
"type": 3,"name": "Статус счета","shortname": "Статус","searchable": true,"sortable": true,"visible": true
@ -8619,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
}
@ -8774,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
@ -9134,7 +9372,7 @@
"destination": "operations",
"class": "",
"class": "ru.clearing.classes.statics.data.payment.Operation",
"table": "operation",
@ -9180,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.7.0.45">
<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"/>
@ -583,7 +593,7 @@
<issuerId type="1" dbname="Идентификатор эмитента" name="Наименование эмитента" shortname="Эмитент" searchable="true" sortable="true" link="company" extends="security" linkCode="shortName"/>
<shortNameEng type="2" length="255" name="Краткое наименование инструмента на английском" shortname="Краткое наименование на английском" searchable="true" sortable="true" visible="true" extends="security"/>
<fullNameEng type="2" length="255" name="Полное наименование инструмента на английском" shortname="Наименование на английском" searchable="true" sortable="true" visible="true" extends="security"/>
<!-- todo скоро добавят задание, поправить базу перед этим<clearingOrganization type="2" length="255" name="Клиринговая организация" shortname="Клиринговая организация" searchable="true" sortable="true" visible="true" filterable="true" filterValue="АО СПВБ"/> -->
<clearingOrganization type="2" length="255" name="Клиринговая организация" shortname="Клиринговая организация" searchable="true" sortable="true" visible="true" filterable="true" filterValue="АО СПВБ"/>
<isin type="2" length="50" name="Наименование инструмента ISIN" shortname="ISIN" searchable="true" sortable="true" visible="true" extends="security"/>
<workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" link="workflowStatus" extends="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"/>
@ -694,7 +704,8 @@
<instrumentType type="12" dbname="Код типа инструмента" name="Наименование типа инструмента" shortname="Тип инструмента" searchable="true" sortable="true" visible="true" link="instrumentType" extends="security"/>
<bondType type="12" dbname="Код типа облигации" name="Наименование типа облигации" shortname="Тип облигации" searchable="true" sortable="true" visible="true" link="bondType"/>
<maturityDate type="6" name="Дата погашения" shortname="Погашение" searchable="true" sortable="true"/>
<nominalValue type="10" name="Номинал" shortname="Номинал" searchable="true" sortable="true"/>
<nominalForDate type="10" name="Текущее значение номинала" shortname="Текущий номинал" searchable="true" sortable="true"/>
<nominalValue type="10" name="Номинал инструмента" shortname="Номинал" searchable="true" sortable="true"/>
<nominalCurrency type="12" dbname="Код валюты номинала" name="Наименование валюты номинала" shortname="Валюта номинала" searchable="true" sortable="true" link="currencyCode"/>
<coupon type="10" name="Купон" shortname="Купон" searchable="true" sortable="true"/>
<couponFrequency type="3" name="Длительность купона" shortname="Длительность" searchable="true" sortable="true"/>
@ -713,7 +724,8 @@
<isin type="2" length="50" name="Наименование инструмента ISIN" shortname="ISIN"/>
<bondType type="12" dbname="Код типа облигации" name="Наименование типа облигации" shortname="Тип облигации" link="bondType"/>
<lotSize type="11" name="Размер лота" shortname="Лот" visible="false"/>
<nominalValue type="10" name="Текущий номинал" shortname="Текущий номинал"/>
<nominalForDate type="10" name="Текущее значение номинала" shortname="Текущий номинал"/>
<nominalValue type="10" name="Номинал инструмента" shortname="Номинал"/>
<nominalCurrency type="12" name="Наименование валюты номинала" shortname="Валюта номинала" link="currencyCode" linkCode="code"/>
<maturityDate type="6" name="Дата погашения" shortname="Погашение"/>
<coupon type="10" name="Купон" shortname="Купон"/>
@ -732,7 +744,8 @@
<isin type="2" length="50" name="Наименование инструмента ISIN" shortname="ISIN"/>
<bondType type="12" dbname="Код типа облигации" name="Наименование типа облигации" shortname="Тип облигации" link="bondType"/>
<lotSize field="securityId" type="11" name="Размер лота" shortname="Лот" linkKeyCode="securityId" linkCode="lotSize" link="listing" visible="false"/>
<nominalValue type="10" name="Текущий номинал" shortname="Текущий номинал"/>
<nominalForDate type="10" name="Текущее значение номинала" shortname="Текущий номинал"/>
<nominalValue type="10" name="Номинал инструмента" shortname="Номинал"/>
<nominalCurrency type="12" name="Наименование валюты номинала" shortname="Валюта номинала" link="currencyCode" linkCode="code"/>
<maturityDate type="6" name="Дата погашения" shortname="Погашение"/>
<coupon type="10" name="Купон" shortname="Купон"/>
@ -759,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">
@ -931,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"/>
@ -943,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">
@ -961,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>
@ -1048,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">
@ -1200,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"/>
@ -1219,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>
@ -1244,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>
@ -1258,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"/>
@ -1315,13 +1355,13 @@
<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"/>
<tradingClearingRegistryId type="1" dbname="Идентификатор торгово-клирингового регистра" name="Торгово-клиринговый регистр" shortname="ТКР" visible="true" searchable="true" sortable="true" link="tradingClearingRegistry" linkCode="code"/>
<partyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр " name="Торгово-клиринговый регистр " shortname="ТКР " searchable="true" sortable="true" ignore="true"/>
<market type="12" dbname="Код секции финансового инструмента" name="Секция финансового инструмента" shortname="Секция" visible="true" searchable="true" sortable="true" link="market" linkKeyCode="code" linkCode="description"/>
<market type="2" length="8" dbname="Код секции финансового инструмента" name="Секция финансового инструмента" shortname="Секция" visible="true" searchable="true" sortable="true" link="market" linkKeyCode="code" linkCode="description"/>
<price type="10" 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"/>
@ -1351,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"/>
@ -1362,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"/>
@ -1386,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"/>
@ -1425,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"/>
@ -1439,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"/>
@ -1451,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"/>
@ -1463,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"/>
@ -1481,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"/>
@ -1499,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"/>
@ -1590,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>
@ -1890,9 +1930,10 @@
</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"/>
<status type="3" name="Статус счета" shortname="Статус" searchable="true" sortable="true" visible="true"/>
<result type="2" length="255" name="Код завершения операции" shortname="Код завершения операции" searchable="true" sortable="true" visible="true"/>
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
@ -2001,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"/>
@ -2040,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">
@ -2121,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"/>
@ -2131,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.7.0.45",
"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": {
@ -2536,6 +2570,10 @@
{"code": "fullNameEng",
"type": 2,"length": 255,"name": "Полное наименование инструмента на английском","shortname": "Наименование на английском","searchable": true,"sortable": true,"visible": true,"extends": "security"
}
,
{"code": "clearingOrganization",
"type": 2,"length": 255,"name": "Клиринговая организация","shortname": "Клиринговая организация","searchable": true,"sortable": true,"visible": true,"filterable": "true","filterValue": "АО СПВБ"
}
,
{"code": "isin",
"type": 2,"length": 50,"name": "Наименование инструмента ISIN","shortname": "ISIN","searchable": true,"sortable": true,"visible": true,"extends": "security"
@ -2735,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",
@ -3000,9 +3038,13 @@
{"code": "maturityDate",
"type": 6,"name": "Дата погашения","shortname": "Погашение","searchable": true,"sortable": true
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал","searchable": true,"sortable": true
}
,
{"code": "nominalValue",
"type": 10,"name": "Номинал","shortname": "Номинал","searchable": true,"sortable": true
"type": 10,"name": "Номинал инструмента","shortname": "Номинал","searchable": true,"sortable": true
}
,
{"code": "nominalCurrency",
@ -3078,9 +3120,13 @@
{"code": "lotSize",
"type": 11,"name": "Размер лота","shortname": "Лот","visible": false
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал"
}
,
{"code": "nominalValue",
"type": 10,"name": "Текущий номинал","shortname": "Текущий номинал"
"type": 10,"name": "Номинал инструмента","shortname": "Номинал"
}
,
{"code": "nominalCurrency",
@ -3157,9 +3203,13 @@
{"code": "lotSize",
"field": "securityId","type": 11,"name": "Размер лота","shortname": "Лот","linkKeyCode": "securityId","linkCode": "lotSize","link": "listing","visible": false
}
,
{"code": "nominalForDate",
"type": 10,"name": "Текущее значение номинала","shortname": "Текущий номинал"
}
,
{"code": "nominalValue",
"type": 10,"name": "Текущий номинал","shortname": "Текущий номинал"
"type": 10,"name": "Номинал инструмента","shortname": "Номинал"
}
,
{"code": "nominalCurrency",
@ -3278,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
}
,
@ -4010,7 +4060,7 @@
,"actions":[
{"method":"post",
"name": "Досрочное изъятие депозита",
"name": "Разделение депозита",
"destination": "registries/splitDeposit",
@ -4061,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
}
]
}
,
@ -4086,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
}
]
}
]
@ -4143,7 +4255,7 @@
,"actions":[
{"method":"post",
"name": "Добавление корреспондентского счета",
"name": "Добавление счета",
"confirmation": "companyId,account,status",
@ -4155,7 +4267,7 @@
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
}
,
{"code": "status",
@ -4170,7 +4282,7 @@
,
{"method":"put",
"name": "Изменение корреспондентского счета",
"name": "Изменение счета",
"confirmation": "companyId,account,status",
@ -4201,7 +4313,7 @@
,
{"method":"delete",
"name": "Блокировка корреспондентского счета",
"name": "Блокировка счета",
"confirmation": "companyId,account",
@ -4510,6 +4622,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
@ -4542,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": {
@ -4574,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
@ -5139,7 +5323,7 @@
"group": "Обмен с расчетной организацией",
"name": "Запрос остатков по всем счетам (отправка ДФ-51, ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"name": "Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)",
"fields": []
}
@ -5150,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",
@ -5170,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",
@ -5232,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",
@ -5365,7 +5553,7 @@
"group": "Формирование отчетности",
"name": "Формирование отчетности по сделкам",
"name": "Формирование отчетности PFX64/PFX65",
"fields": []
}
@ -5389,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": []
}
]
@ -5424,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",
@ -5656,10 +5866,12 @@
,
"executionDeposit": {
"name": "Сделки",
"name": "Сделки на секции МКР",
"destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true",
@ -5686,17 +5898,9 @@
{"code": "partyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
}
,
{"code": "market",
"type": 12,"dbname": "Код секции финансового инструмента","name": "Секция финансового инструмента","shortname": "Секция","visible": true,"searchable": true,"sortable": true,"link": "market","linkKeyCode": "code","linkCode": "description"
"type": 2,"length": 8,"dbname": "Код секции финансового инструмента","name": "Секция финансового инструмента","shortname": "Секция","visible": true,"searchable": true,"sortable": true,"link": "market","linkKeyCode": "code","linkCode": "description"
}
,
{"code": "price",
@ -5778,6 +5982,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"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"
@ -5812,6 +6024,8 @@
"destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true",
@ -5860,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",
@ -5868,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",
@ -5896,15 +6110,7 @@
}
,
{"code": "partyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true
}
,
{"code": "counterPartyTradingClearingRegistryId",
"type": 1,"dbname": "Идентификатор торгово-клирингового регистра партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true,"link": "tradingClearingRegistry","linkCode": "code"
}
,
{"code": "counterPartyTradingClearingRegistry",
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр партнера","name": "Торгово-клиринговый регистр партнера","shortname": "ТКР партнера","visible": true,"searchable": true,"sortable": true
"type": 2,"length": 20,"dbname": "Торгово-клиринговый регистр ","name": "Торгово-клиринговый регистр ","shortname": "ТКР ","searchable": true,"sortable": true,"ignore": true
}
,
{"code": "comment",
@ -5926,6 +6132,14 @@
{"code": "counterPartyId",
"type": 1,"dbname": "Идентификатор компании-партнера, с которой заключена сделка","name": "Наименование компании-партнера, с которой заключена сделка","shortname": "Партнер","visible": false,"searchable": true,"sortable": true,"link": "company","linkCode": "shortName"
}
,
{"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
@ -5960,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",
@ -5982,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",
@ -6006,6 +6222,8 @@
"destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register",
@ -6020,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",
@ -6028,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",
@ -6052,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",
@ -6060,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
}
]
@ -6072,6 +6290,8 @@
"destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register",
@ -6134,6 +6354,8 @@
"destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register",
@ -6196,6 +6418,8 @@
"destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register",
@ -6250,6 +6474,8 @@
"destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register",
@ -6304,6 +6530,8 @@
"destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register",
@ -6382,6 +6610,8 @@
"destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register",
@ -6460,6 +6690,8 @@
"destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register",
@ -6841,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",
@ -6861,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",
@ -6877,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
@ -8152,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",
@ -8162,6 +8396,10 @@
{"code": "deal",
"type": 2,"length": 4,"name": "Биржевой код участника клиринга","shortname": "Биржевой код УК","searchable": true,"sortable": true,"visible": true
}
,
{"code": "date",
"type": 2,"length": 8,"name": "Дата изменения состояния счета","shortname": "Дата изменения состояния счета","searchable": true,"sortable": true,"visible": true
}
,
{"code": "status",
"type": 3,"name": "Статус счета","shortname": "Статус","searchable": true,"sortable": true,"visible": true
@ -8619,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
}
@ -8774,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
@ -9134,7 +9372,7 @@
"destination": "operations",
"class": "",
"class": "ru.clearing.classes.statics.data.payment.Operation",
"table": "operation",
@ -9180,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

@ -18,6 +18,7 @@ public class FixedIncomeSecurity extends Security {
private Long securityId;
private String bondType;
private LocalDate maturityDate;
private BigDecimal nominalForDate;
private BigDecimal nominalValue;
private String nominalCurrency;
private BigDecimal coupon;
@ -45,6 +46,13 @@ public class FixedIncomeSecurity extends Security {
this.maturityDate=value;
}
public BigDecimal getNominalForDate() {
return nominalForDate;
}
public void setNominalForDate(BigDecimal nominalForDate) {
this.nominalForDate = nominalForDate;
}
public BigDecimal getNominalValue() {
return nominalValue;
}

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

@ -5,6 +5,7 @@ import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
/**
* ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)
@ -16,6 +17,7 @@ public class SDf53 extends SpcexObjectBase {
private String account;
private String deal;
private String date;
private Long status;
private String result;
private Instant generationTime;
@ -39,6 +41,14 @@ public class SDf53 extends SpcexObjectBase {
this.deal = value;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Long getStatus() {
return status;
}

View file

@ -20,6 +20,7 @@ public class MoneyMarketSecurity extends Security {
private String convention;
private String termType;
private BigDecimal lotSize;
private String clearingOrganization;
public Long getSecurityId() {
return securityId;
@ -92,4 +93,12 @@ public class MoneyMarketSecurity extends Security {
public void setLotSize(BigDecimal lotSize) {
this.lotSize = lotSize;
}
public String getClearingOrganization() {
return clearingOrganization;
}
public void setClearingOrganization(String clearingOrganization) {
this.clearingOrganization = clearingOrganization;
}
}

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;
}
@ -199,6 +210,7 @@ public class ValidationConfig {
return new ValidatorImpl<>(context,
Sdf57ValidationRule.CompanyDebOrCredPresent,
Sdf57ValidationRule.AccountDebOrCredPresent,
Sdf57ValidationRule.AccountAndCompanyMatch,
Sdf57ValidationRule.CurrencyCodeCheck
);
};
@ -318,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
);
};
}
@ -342,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 -> {
@ -360,7 +414,8 @@ public class ValidationConfig {
IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class,
ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false),
SplitDepositRequestValidationRule.PositiveAmount,
SplitDepositRequestValidationRule.CrossvalidateByRegistry
SplitDepositRequestValidationRule.CrossvalidateByRegistry,
SplitDepositRequestValidationRule.LoadContractIndexes
);
};
}
@ -372,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",
@ -379,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);
};
}
@ -414,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

@ -32,6 +32,7 @@ import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
@Configuration("sessionStateMachineFactory")
@ -134,6 +135,10 @@ public class StateBnConfig extends EnumStateMachineConfigurerAdapter<TaskType, S
states
.withStates()
.initial(TaskType.StartRevise, context -> {
Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of("workflowStatus", SessionStatus.ACTV.getKey()));
if (existActiveSession != null) {
throw new RuntimeException("ActiveSessionIsPresent " + existActiveSession);
}
Session newSession = new Session();
newSession.setSection(Section.FOND.getKey());
newSession.setSessionType(SessionType.IPOB.getKey());

View file

@ -23,11 +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),
@ -38,8 +46,8 @@ public enum ClearingError implements IErrorEnumId {
BalanceInsufficient(5222L),
TCRegistryNotFound(3022L),
WrongField(5004L),
ActiveSessionIsPresent(-1L),
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,7 +6,9 @@ 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;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
@ -15,24 +17,28 @@ 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;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.service.executors.Sdf06Executor;
import ru.spcex.clearing.service.executors.Sdf10Executor;
import ru.spcex.clearing.service.payment.PaymentInstructionOutboundService;
import ru.spcex.clearing.session.stage.*;
import ru.spcex.clearing.session.stage.impl.BalanceRevise;
import ru.spcex.clearing.statement.StatementServiceV2;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ValidationException;
import static ru.spcex.clearing.platform.messaging.domain.Consts.S_TRADES_IMPORTED;
@Service
public class EventsReceiver extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final IMessageResolver errorResolver;
private final ClearingService clearingService;
private final RegistryService registryService;
private final PrimaryAuctionBnSession primaryAuctionBnSession;
@ -47,18 +53,22 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
private final Sdf10Executor sdf10Executor;
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,
PrimaryAuctionBnSession primaryAuctionBnSession,
SecondaryAuctionT0Session secondaryAuctionT0Session,
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
Sdf06Executor sdf06Executor,
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, PaymentInstructionOutboundService pmtOutboundService) {
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, SessionTerminator sessionTerminator, PaymentInstructionOutboundService pmtOutboundService) {
super(kafkaQueue, kafkaResponseQueue);
this.errorResolver = errorResolver;
this.clearingService = clearingService;
this.registryService = registryService;
this.primaryAuctionBnSession = primaryAuctionBnSession;
@ -73,6 +83,8 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
this.sdf10Executor = sdf10Executor;
this.balanceRevise = balanceRevise;
this.sdf05Sender = sdf05Sender;
this.statementService = statementService;
this.sessionTerminator = sessionTerminator;
this.pmtOutboundService = pmtOutboundService;
}
@ -95,12 +107,22 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
.forDestination(Consts.CONTINUE_CLEARING, callbacks::put);
callback(LauncherCommandRequest.class)
.setConsumer(sessionManager::defineAndStartSession)
.setFunction(r -> {
try {
sessionManager.defineAndStartSession(r);
} catch (ValidationException ve) {
return makeErrorResponse(r, ve);
}
return null;
})
.forDestination(Task.startOfClearing.topic(), callbacks::put);
callback(PIClearingOutbondActionNewRequest.class)
.setFunction(pmtOutboundService::sendOutBoundPayment)
.forDestination(Consts.PAYMENT_INSTRUCTION_CLEARING_OUTBOUND_ACTION, callbacks::put);
callback(StatementRequest.class)
.setConsumer(statementService::processReq)
.forDestination(Consts.STATEMENT_PROCESS, callbacks::put);
callback(SessionContinueEvent.class)
.setConsumer(req -> {
primaryAuctionBnSession.continueSession(req);
@ -133,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);
@ -158,6 +186,21 @@ 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();
}
RequestInfoUpdate makeErrorResponse(BaseRequest<?> r, ValidationException ve) {
String errorText = errorResolver.resolve(ve.getEnumMsg());
log.error("Error at {}: {}", r, errorText);
RequestInfoUpdate errorMsg = new RequestInfoUpdate();
errorMsg.setId(r.getId());
errorMsg.setStatus(Status.Error);
errorMsg.setMessage(errorText);
return errorMsg;
}
}

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

@ -11,10 +11,7 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CompanySymbol;
import ru.spcex.platform.enumeration.Sender;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -50,24 +47,10 @@ public class Sdf54Creator {
public SDf54 create(PaymentInstruction paymentInstruction) {
Instant now = Instant.now();
AccountType creditAccType = getAccountType(paymentInstruction.getCreditLeg_accountId());
AccountType debAccType = getAccountType(paymentInstruction.getDebitLeg_accountId());
String c_acc_deb = null;
String c_acc_cred = null;
Account anltAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s'"
.formatted(AccountType.Anlt.getKey(), Status.Active.getKey()));
if (AccountType.Info.equals(creditAccType) ^ AccountType.Info.equals(debAccType)) {
if (anltAcc == null) {
throw new IllegalStateException("SDF54 creation error: paymentInstruction.creditLeg_accountId="
+ paymentInstruction.getCreditLeg_accountId() + " accountType 'Info' but no 'ANLT' account found");
}
if (AccountType.Info.equals(creditAccType)) {
c_acc_deb = anltAcc.getAccount();
} else {
c_acc_cred = anltAcc.getAccount();
}
}
c_acc_deb = c_acc_deb == null ? paymentInstruction.getCreditLeg_account() : c_acc_deb;
// c_acc_deb = c_acc_deb == null ? paymentInstruction.getCreditLeg_account() : c_acc_deb;
c_acc_cred = c_acc_cred == null ? paymentInstruction.getDebitLeg_account() : c_acc_cred;
@ -111,42 +94,74 @@ public class Sdf54Creator {
if (anltAcc != null) {
sDf54.setAcc_deb(anltAcc.getAccount());
}
Account accDebAcc = accountImdg.getSingleObjectByID(paymentInstruction.getDebitLeg_accountId());
if (accDebAcc == null || !AccountStatus.ACTIVE.equalsByKey(accDebAcc.getStatus())) {
log.warn("paymentInstruction[{}].DebitLeg_accountId={} account not exist or not active.", paymentInstruction.getId(), paymentInstruction.getDebitLeg_accountId());
}
BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(paymentInstruction.getDebitLeg_accountId()));
if (bnkAcc != null) {
sDf54.setInn_cred(bnkAcc.getTaxpayerIdentificationNumber());
sDf54.setKpp_cred(bnkAcc.getTaxRegistrationReasonCode());
c_acc_cred = bnkAcc.getCorrespondentAccount();
} else {
log.warn("Bank account not found for DebitLeg_accountId={}", paymentInstruction.getDebitLeg_accountId());
}
sDf54.setAcc_kr_1(paymentInstruction.getDebitLeg_account());
{
Account prcCorrAcc = accountImdg.getFirstObjectBySQL("companyId=%d and accountType = '%s' and status = '%s'"
.formatted(Sender.Prc.getId(), AccountType.Corr.getKey(), Status.Active.getKey()));
if (prcCorrAcc == null) {
log.warn("Account for PRC CORR not found");
} else {
sDf54.setC_acc_deb(prcCorrAcc.getAccount());
}
}
//**********************
sDf54.setSend_type("срочно");
sDf54.setDoc_type("002");
sDf54.setDocnm_ref(docnmRefFormatter.format(TimeUtil.toDateTime(now)));
sDf54.setC_acc_deb(c_acc_deb);
// Account rBnkAccount = accountImdg.getFirstObjectBySQL("companyId=%s and accountType = '%s' and status = '%s'"
// .formatted(paymentInstruction.getAddresseeId(), AccountType.Bank.getKey(), Status.Active.getKey()));
// BankAccount rBnkAcc = rBnkAccount == null ? null : bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(rBnkAccount.getId()));
if (bnkAcc != null) {
sDf54.setRbankcode(bnkAcc.getBankIdentificationCode());
SpecifUtil.fillSegmentsBy35Symbols(bnkAcc.getCorrespondentAccountName(),
sDf54::setRbanknam1,
sDf54::setRbanknam2,
sDf54::setRbanknam3,
sDf54::setRbanknam4,
sDf54::setRbanknam5);
}
sDf54.setC_acc_cred(c_acc_cred);
String addresseeSbankName = "";
if (paymentInstruction.getAddresseeId().equals(1L)) {
addresseeSbankName = paymentInstruction.getAddresseeBankName();
} else {
Company company = companyImdg.getSingleObjectByID(paymentInstruction.getAddresseeId());
if (company != null) {
addresseeSbankName = company.getShortName();
{
Company company1 = companyImdg.getSingleObjectByID(Sender.One.getId());
if (company1 != null) { // "АО СПВБ" company.shortName[id = 1]
SpecifUtil.fillSegmentsBy35Symbols(company1.getShortName(),
sDf54::setSclientn1,
sDf54::setSclientn2,
sDf54::setSclientn3,
sDf54::setSclientn4);
} else {
log.warn("Company id=1 not exist");
}
}
{
if (bnkAcc != null) {
SpecifUtil.fillSegmentsBy35Symbols(bnkAcc.getBankName(),
sDf54::setRclientn1,
sDf54::setRclientn2,
sDf54::setRclientn3,
sDf54::setRclientn4);
}
}
SpecifUtil.fillSegmentsBy35Symbols(addresseeSbankName,
sDf54::setRbanknam1,
sDf54::setRbanknam2,
sDf54::setRbanknam3,
sDf54::setRbanknam4,
sDf54::setRbanknam5);
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());

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