Compare commits

...
Sign in to create a new pull request.

1063 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
ialbert
04f35dcdaa TaskType revise key fix 2023-09-05 12:03:09 +03:00
ialbert
25d8915647 rollback SdfGroup 2023-09-05 11:40:01 +03:00
ialbert
2b4e189a54 StatementServiceV2 move to package 2023-09-05 11:38:49 +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
AKurakin
afb21eb2ba clearing-service BalanceRevise ревизии 3 стадии AgainRevise, вынес стадию 1. 2023-09-04 11:23:45 +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
AKurakin
210b855cb2 clearing-service BalanceRevise ревизии 3 стадии AgainRevise. 2023-09-01 18:11:30 +03:00
AKurakin
ef217e8ff7 clearing-service FinishingSession статусы для Execution. imdg добавил индексы 2023-09-01 12:38:39 +03:00
akulikov
3ec26e9d91 http://jira.mfd.msk:8088/browse/CLS-497 2023-09-01 12:04:16 +03:00
AKurakin
76ba3463cf clearing-service статусы в InspectionObligationsDepositReturn при неполном покрытии amount для/до финальной стадии 2023-08-31 14:39:00 +03:00
AKurakin
cd67d0b113 clearing-service SDF_01 поправил сверку баланса для инфосчетов 2023-08-31 14:39:00 +03:00
akulikov
317b24748c http://jira.mfd.msk:8088/browse/CLS-497 change predicate 2023-08-31 12:13:43 +03:00
AKurakin
f35e4bce23 clearing-service http://jira.mfd.msk:8088/browse/CLS-508 Sdf13 fix status 2023-08-30 19:21:57 +03:00
AKurakin
27ed787013 meta update 30.08.2023 2023-08-30 19:10:26 +03:00
AKurakin
835f9932d9 clearing-service http://jira.mfd.msk:8088/browse/CLS-508 Sdf04 / Sdf13 ожидание полностью готовой группы в SessionMonitor 2023-08-30 18:01:37 +03:00
AKurakin
f5d5c8acfb clearing-service Sdf13 ожидание полностью готовой группы в SessionMonitor 2023-08-30 17:53:52 +03:00
AKurakin
47d0830e9e clearing-service Sdf04 ожидание полностью готовой группы в SessionMonitor 2023-08-30 17:39:50 +03:00
AKurakin
546359752b clearing-service Sdf04 ожидание полностью готовой группы в SessionMonitor 2023-08-30 16:58:25 +03:00
AKurakin
960ed3f0c8 gateway-api http://jira.mfd.msk:8088/browse/CLS-347 bug fix 2023-08-30 16:07:18 +03:00
AKurakin
228b290570 gateway-api http://jira.mfd.msk:8088/browse/CLS-347 bug fix 2023-08-30 15:27:38 +03:00
AKurakin
38916cdeb1 clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT улучшил валидацию 2023-08-30 15:18:05 +03:00
AKurakin
a448a78415 clearing-service Sdf04 ожидание полностью готовой группы в SessionMonitor 2023-08-30 14:28:25 +03:00
AKurakin
fe61ca6e02 db-scripts DATA.sql обновил 2023-08-30 13:22:09 +03:00
akulikov
75fe7a9593 http://jira.mfd.msk:8088/browse/CLS-497 date format fixes 2023-08-29 21:40:38 +03:00
AKurakin
5cdf12a323 clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT bug fix 2023-08-29 17:05:54 +03:00
AKurakin
6237f534f2 clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT default direction 2023-08-29 14:18:43 +03:00
AKurakin
f720d2a945 clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT рефакторинг 2023-08-29 13:38:21 +03:00
AKurakin
99e83b8bf9 clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT todo уточнить ТЗ 2023-08-28 16:16:15 +03:00
AKurakin
94831710e4 up meta version 2023-08-28 12:33:39 +03:00
akulikov
4dc73661d8 http://jira.mfd.msk:8088/browse/CLS-497 add TRADE_NUM 2023-08-28 11:43:30 +03:00
ialbert
9f046ae383 возврат депозитов шаг 5: DM*X/DM*T 2023-08-25 19:08:52 +03:00
ialbert
cca5991bd6 sdf20 запрос в gateway только при зачислении 2023-08-25 18:15:00 +03:00
AKurakin
b4397a25a8 dbf-importer рефакторинг, юниттесты 2023-08-25 18:09:38 +03:00
AKurakin
e9de1c87a7 gateway-api company-service http://jira.mfd.msk:8088/browse/CLS-347 2023-08-25 18:05:08 +03:00
ialbert
d81c4b7040 sdf20, sdf21 2023-08-25 17:45:57 +03:00
ialbert
8b54b86ae9 SDF20 поиск DS*T 2023-08-25 17:26:53 +03:00
psemenkov
adc20ee46b http://jira.mfd.msk:8088/browse/CLS-467
Исправил TransactionNumber в ДФ-20.
2023-08-25 16:12:55 +03:00
ialbert
316a5bb6aa sdf06 TCR validation log fix 2023-08-25 15:25:43 +03:00
ialbert
cfda9a6eba sdf06 TCR validation log fix 2023-08-25 15:23:26 +03:00
ialbert
d6a790cec7 sdf06 missing TCR
при ожидание ответа gateway новые sdf06 запросы добавляются в очередь
2023-08-25 15:09:49 +03:00
AKurakin
4763724315 securities-service http://jira.mfd.msk:8088/browse/CLS-420 GatewaySecurityService будет пытаться делать, несмотря на ошибки. 2023-08-25 10:55:54 +03:00
etreshenkov
f5831500c8 Revert "backend-api update meta поправил поле в ChangeRefundDateActionNew.java в соответствии с метой"
This reverts commit e053ff652d.
2023-08-24 20:04:11 +03:00
etreshenkov
3c22c99e51 Revert "backend-api update meta поправил поле в ChangeRefundDateActionNew.java в соответствии с метой (fix)"
This reverts commit d7f0860726.
2023-08-24 20:04:10 +03:00
ialbert
9a84b80c83 первичная B0 сессия условие на выбор сделок 2023-08-24 17:12:39 +03:00
AKurakin
d7f0860726 backend-api update meta поправил поле в ChangeRefundDateActionNew.java в соответствии с метой (fix) 2023-08-24 16:20:02 +03:00
AKurakin
e053ff652d backend-api update meta поправил поле в ChangeRefundDateActionNew.java в соответствии с метой 2023-08-24 15:27:34 +03:00
AKurakin
49b920c6e9 backend-api update meta (3.7.0.43 24.08.2023 http://jira.mfd.msk:8088/browse/CLS-405) 2023-08-24 15:10:06 +03:00
ialbert
1eb2b029e1 промежуточная сессия МКР inclusion to POOL value date condition 2023-08-24 14:45:50 +03:00
AKurakin
f95f1f241d account-service http://jira.mfd.msk:8088/browse/CLS-489 продолжение обработки до SDF_53, добавил имя входного файла для запроса генерации квитанций DF-53 2023-08-24 11:33:31 +03:00
AKurakin
f54efc6b2b dbf-exporter http://jira.mfd.msk:8088/browse/CLS-489 добавил логи 2023-08-23 20:18:17 +03:00
AKurakin
622ea90e81 dbf-exporter http://jira.mfd.msk:8088/browse/CLS-489 добавил логи 2023-08-23 19:36:22 +03:00
ialbert
79a6cc846f clearing-service refund date change for registries 2023-08-23 18:38:45 +03:00
ialbert
d14b49ce85 http://jira.mfd.msk:8088/browse/CLS-498 backend-api 2023-08-23 17:57:30 +03:00
akulikov
d1082874cb http://jira.mfd.msk:8088/browse/CLS-497 2023-08-23 17:41:41 +03:00
AKurakin
f253caf3d2 account-service http://jira.mfd.msk:8088/browse/CLS-489 продолжение обработки до SDF_53. 2023-08-23 17:06:44 +03:00
ialbert
523d5b4bc1 CLRD статус регистров для всех сессий 2023-08-23 17:04:25 +03:00
ialbert
bdc4f3fb67 FormingPaymentInstructionSecurities добавил условие sessionId для сделок по деньгам 2023-08-23 14:50:46 +03:00
ialbert
582472b951 Первичная T0 сессия фикс маркет кодов 2023-08-23 14:36:43 +03:00
ialbert
7ee4e14126 промежуточная МКР сессия MEDM: убрал возврат депозитов (5 и 7 шаги) 2023-08-23 14:32:48 +03:00
ialbert
dd272858f8 проверка sdf21 на наличие DS*T transactionNumber 2023-08-23 14:18:44 +03:00
AKurakin
5c4b7adf31 swt-importer добавил юниттест 2023-08-23 14:09:00 +03:00
ialbert
54b209a5ab swt-importer sdf21 учитывается направление при проверке на выгруженность 2023-08-23 14:04:52 +03:00
ialbert
d41edf57ff DM*I поиск по TCR#id 2023-08-23 14:04:51 +03:00
psemenkov
2f0d91574c http://jira.mfd.msk:8088/browse/CLS-467
Добавил новые поля в ДФ-20.
2023-08-23 13:44:32 +03:00
AKurakin
5c49e4e624 swt-importer комментарий 2023-08-23 13:34:19 +03:00
ialbert
866849dc8f добавил условие на sessionId: сессии TRDT, финальная/промежуточная МКР, возврат депозитов 2023-08-23 12:12:08 +03:00
psemenkov
7164442752 http://jira.mfd.msk:8088/browse/CLS-453
Сделал проверку на уникальность security.securitysymbol регистронезависимой.
2023-08-23 11:50:13 +03:00
ialbert
0ad02d573b SDF06, SDF57 DM*I 2023-08-23 11:01:43 +03:00
AKurakin
c4476c89a9 swt-exporter clearing-service DF11Exporter result OK убрал возможный ! 2023-08-23 10:47:44 +03:00
AKurakin
82e2b08df1 swt-exporter DF11Exporter result OK убрал возможный ! 2023-08-23 10:26:23 +03:00
ialbert
7e0eda6fe3 FormingPaymentInstructionSecurities bugfix 2023-08-22 18:37:06 +03:00
psemenkov
e9636e8723 http://jira.mfd.msk:8088/browse/CLS-262
Обновил выгрузку денег.
2023-08-22 17:41:15 +03:00
ialbert
0933657ea3 D**I 2023-08-22 16:03:25 +03:00
akulikov
017f54a559 http://jira.mfd.msk:8088/browse/CLS-358 2023-08-22 15:17:51 +03:00
ialbert
ce8c397fca moved RegistryManager to separate package
added TradingTimeService
added RegistryUnit.I
2023-08-22 14:34:18 +03:00
psemenkov
8e57cd810e http://jira.mfd.msk:8088/browse/CLS-262
Обновил выгрузку ценных бумаг DEPO
2023-08-22 13:44:32 +03:00
AKurakin
bc101f6cb4 imdg http://jira.mfd.msk:8088/browse/CLS-473 поправил ограничение по дате на ExecutionFondMapStore, рефакторинг 2023-08-22 10:50:22 +03:00
ialbert
91d31132be SDF20 2023-08-21 19:46:34 +03:00
ialbert
944d402c8d SDF10/SDF20 2023-08-21 18:45:29 +03:00
psemenkov
79d52d96ab Удалил поиск по clearingDate потому что старые PlannerAllToday не будут сохраняться. 2023-08-21 17:22:16 +03:00
ialbert
ae3abdb638 SDF20
SDF21
SDF10
2023-08-21 17:20:54 +03:00
AKurakin
bd65726668 account-service dbf-importer http://jira.mfd.msk:8088/browse/CLS-489 изменение статусов клиринговых счетов по S_DF52 2023-08-21 17:18:33 +03:00
ialbert
8d864e8aca SDF20 bugfix 2023-08-21 12:00:32 +03:00
psemenkov
661c5916db http://jira.mfd.msk:8088/browse/CLS-464
Исправил ошибку.
2023-08-21 11:57:35 +03:00
AKurakin
2ea1c4332e imdg поправил Map_TradingClearingRegistryHistory (баг в 2527755afc), CLS-473 alt+ctrl+L SimpleObjectMapStore 2023-08-21 11:29:50 +03:00
AKurakin
63eab63c48 imdg http://jira.mfd.msk:8088/browse/CLS-473 ExecutionFondMapStore выгрузка по SETTLEMENT_DATE 2023-08-21 11:15:37 +03:00
ialbert
31fee0e8f3 SDF20 validation fix 2023-08-18 19:39:51 +03:00
ialbert
334a91fb81 SDF20
SDF55
SDF10 в DS*T#contract кладется sdf10.outDocument а не sdf11.outDocument
блокировки в PaymentInstructionOutboundService
imdg SDf20/SDf21/SDf57 выгружаются за все дни
2023-08-18 19:33:46 +03:00
AKurakin
64e6f932bc scheduler-service fix NullPointerException в backend-api.RequestInfoAccepter: улучшил редирект сообщения (временный статус) 2023-08-18 16:40:03 +03:00
psemenkov
e9e93ece7e http://jira.mfd.msk:8088/browse/CLS-496
Теперь, вместо nominal_value будет приходить nominal_for_date и его необходимо записывать в поле fixedIncomeSecurity.nominalValue.
2023-08-18 16:14:30 +03:00
AKurakin
50494d87c0 scheduler-service fix NullPointerException в backend-api.RequestInfoAccepter: userRequest.id и userId пробрасывается также. 2023-08-18 16:02:58 +03:00
AKurakin
51ccc27090 backend-api fix NullPointerException в RequestInfoAccepter (теперь только warn) 2023-08-18 13:51:21 +03:00
psemenkov
d6cefd3902 http://jira.mfd.msk:8088/browse/CLS-51
Bag fixing.
2023-08-18 13:16:50 +03:00
ialbert
745a13a8f8 PaymentInstruction Outbound
SDf06
2023-08-17 19:27:36 +03:00
AKurakin
848c26d69a scheduler-service OUTV шедулер редиректит его в очередь PAYMENT_INSTRUCTION_CLEARING_OUTBOUND_ACTION 2023-08-17 17:49:44 +03:00
psemenkov
25c2be5c52 http://jira.mfd.msk:8088/browse/CLS-51
Bag fixing.
2023-08-17 17:10:33 +03:00
psemenkov
1abbc5f734 http://jira.mfd.msk:8088/browse/CLS-51
Поправил обработку PlannerAllToday.
2023-08-17 16:12:43 +03:00
AKurakin
fd22d89ecb backend-api OUTV разрешил для /launchers/specific 2023-08-17 11:13:10 +03:00
ialbert
19579ec0b0 SDF10
* добавил ограничение на активную сессию
* tradingTime
2023-08-16 19:47:52 +03:00
ialbert
0e2adf5807 SDF10 статусы 2023-08-16 16:47:02 +03:00
ialbert
af70ae6392 правки валидации sdf10
определение запрос для sdf06/sdf10 - Sdf10Executor и Sdf06Executor
правки запроса к gateway (поле section)
2023-08-16 15:59:18 +03:00
psemenkov
cef5460726 http://jira.mfd.msk:8088/browse/CLS-487
Поправил вывод ДФ-11.
2023-08-16 15:26:17 +03:00
AKurakin
818fda3058 meta.xml OUTV fix field 2023-08-16 11:53:09 +03:00
ialbert
2900a17f7a ExecutionFond/ExecutionDeposit#CounterPartyTradingClearingRegistry 2023-08-15 20:50:47 +03:00
ialbert
4ad1ee7df7 ExecutionDeposit map store counter_party_trading_clearing_registry_id 2023-08-15 20:35:05 +03:00
ialbert
bd253e7f4a ExecutionDeposit STrades counter 2023-08-15 20:26:51 +03:00
ialbert
8baedb31ea ExecutionDeposit STrades counter 2023-08-15 20:23:02 +03:00
ialbert
eeb8e4dc5f ExecutionDeposit заполнение поля CounterPartyTradingClearingRegistryId
SDF10
2023-08-15 19:33:03 +03:00
AKurakin
00090857a8 DDL http://jira.mfd.msk:8088/browse/CLS-405 meta 3.7 (up json) 2023-08-15 17:31:28 +03:00
AKurakin
a98e791824 DDL http://jira.mfd.msk:8088/browse/CLS-405 meta 3.7 2023-08-15 17:28:51 +03:00
ialbert
a3551bbc88 sdf06 error "3" for unsatisfied balances 2023-08-15 16:57:56 +03:00
ialbert
0b81edefbb SDF06 поиск по ANLT account
вынес поиск ТКР в валидацию
2023-08-15 15:11:40 +03:00
psemenkov
38a0c7c0f8 http://jira.mfd.msk:8088/browse/CLS-486
При передаче amount домножаем передаваемое значение *100.
2023-08-15 14:24:53 +03:00
psemenkov
7960e05d55 http://jira.mfd.msk:8088/browse/CLS-483
Simple fixing.
2023-08-15 12:19:46 +03:00
AKurakin
7c0b2d9215 backend-api platform-messaging scheduler-service meta add field to Launcher OUTV 2023-08-15 12:12:06 +03:00
ialbert
6907d648d3 LS*T grouping bugfix 2023-08-14 18:53:11 +03:00
AKurakin
988344ee1a reports-service http://jira.mfd.msk:8088/browse/CLS-358 refactoring predicate todo 2023-08-14 17:40:39 +03:00
AKurakin
f06308bcad reports-service оправил имя лог-файла для единообразия 2023-08-14 17:37:03 +03:00
AKurakin
679a7ebd23 reports-service http://jira.mfd.msk:8088/browse/CLS-358 refactoring predicate 2023-08-14 17:30:07 +03:00
akulikov
5863500e51 http://jira.mfd.msk:8088/browse/CLS-358 fixes 2023-08-14 17:00:47 +03:00
ialbert
0e4e3c91a8 FormingPaymentInstructions output types 2023-08-14 16:33:36 +03:00
psemenkov
8681cb4db4 http://jira.mfd.msk:8088/browse/CLS-310
Добавил очередь для отправки ДФ-55.
2023-08-14 16:28:36 +03:00
ialbert
122e5f9d26 forming payment instructions by money AM*B registers 2023-08-14 16:21:30 +03:00
ialbert
0c0bc7d910 IPOT 7 шаг по формированию PaymentInstruction по бумагам 2023-08-11 19:49:02 +03:00
psemenkov
6b3eaa1e24 http://jira.mfd.msk:8088/browse/CLS-314
Исправил вывод поля RESULT добавил ACC_NAME.
2023-08-11 17:18:03 +03:00
ialbert
c1516d207a clearing-service sessions SDF05 PR 2023-08-11 15:46:57 +03:00
ialbert
d45b64b53f removed fatal from log... 2023-08-11 15:32:34 +03:00
ialbert
f1267387a3 clearing-service SDF01 filename 2023-08-11 15:31:01 +03:00
ialbert
c01cc429a0 swt-importer SDF21 transactionNumber 2023-08-11 12:01:42 +03:00
psemenkov
c2a1f4a20a http://jira.mfd.msk:8088/browse/CLS-454
Поправил вывод сообщений об ошибках валидации.
2023-08-11 11:30:22 +03:00
ialbert
6769f5cd20 clearing-service SDF12 fix 2023-08-11 11:23:15 +03:00
ialbert
c1a519dc86 clearing-service sdf14 fix 2023-08-11 11:07:02 +03:00
AKurakin
9aad5d1553 swt-exporter DF09 header fix, поправил имена файлов 2023-08-10 19:33:30 +03:00
AKurakin
6daf7c0227 trade-importer улучшил лог 2023-08-10 19:32:47 +03:00
ialbert
d0ca401ab1 SDF21 пропуск operationDate не сегодня 2023-08-10 19:03:07 +03:00
ialbert
6666c63fa5 SDF14 exporter removed unnecessary imdg 2023-08-10 18:53:08 +03:00
ialbert
b5a3e7289e SDF12 в swt-exporter используется sessionId для определения имени файла 2023-08-10 18:51:27 +03:00
AKurakin
51949a281a dbf-exporter http://jira.mfd.msk:8088/browse/CLS-474 2023-08-10 17:54:01 +03:00
ialbert
1c1b134edf SDF01 SDF06 fileName пробрасывается для экспортера 2023-08-10 17:48:38 +03:00
ialbert
06c809f48f dbf-exporter ExportToFileRequest добавил fileName 2023-08-10 17:38:53 +03:00
ialbert
5ed3f63e91 DF-14 2023-08-10 16:18:42 +03:00
AKurakin
0e4acc54fa classes http://jira.mfd.msk:8088/browse/CLS-405 ConstSerializable up version 2023-08-10 14:17:01 +03:00
AKurakin
4463f9479f imdg classes http://jira.mfd.msk:8088/browse/CLS-405 ddl и классы. 2023-08-10 14:05:12 +03:00
AKurakin
bcd0f1a85a dbf-exporter S_DF07_Converter поля... Ограничение 254 у javadbf-1.13.1.jar 2023-08-10 13:21:51 +03:00
AKurakin
807dffdc92 dbf-exporter http://jira.mfd.msk:8088/browse/CLS-474 начало 2023-08-10 12:53:45 +03:00
AKurakin
5ccf3ed734 dbf-exporter S_DF07_Converter поля... 2023-08-10 12:50:46 +03:00
AKurakin
d2539e5819 dbf-exporter S_DF07_Converter SUM 2023-08-10 12:38:36 +03:00
ialbert
fbfe589ea3 statement services fixes 2023-08-09 21:41:22 +03:00
ialbert
3f3c59cc00 http://jira.mfd.msk:8088/browse/CLS-475 2023-08-09 19:02:36 +03:00
AKurakin
02ee4b461e swt-exporter DF12Exporter fix header 20 вообще-то это как минимум WARN, если не ошибка. Они все должны быть одинаковы. 2023-08-09 16:35:06 +03:00
AKurakin
2e25c733ba swt-exporter DF12Exporter fix header 20 2023-08-09 16:08:29 +03:00
psemenkov
d4142e3b03 http://jira.mfd.msk:8088/browse/CLS-467
Добавил загрузку файлов ДФ-20.
2023-08-09 16:03:24 +03:00
AKurakin
2c65f7ab92 dbf-exporter S_DF07_Converter временно INN,BIC as string 2023-08-09 14:29:12 +03:00
ialbert
a181c0981a SDF07 spec 2023-08-09 14:16:36 +03:00
ialbert
6b3d68320e SDF08 update AS*T fix 2023-08-09 13:49:42 +03:00
ialbert
817166005f SDF21 проверка на существование инструмента, убрал дубликат sql в поиске 2023-08-09 13:13:52 +03:00
AKurakin
f39991a559 swt-exporter http://jira.mfd.msk:8088/browse/CLS-478 S_DF09 2023-08-09 11:55:08 +03:00
psemenkov
acb9b5a674 http://jira.mfd.msk:8088/browse/CLS-469
Исправил ошибки
2023-08-09 11:14:36 +03:00
AKurakin
31e8a7af86 swt-exporter http://jira.mfd.msk:8088/browse/CLS-478 windows rn line separator 2023-08-09 10:56:40 +03:00
ialbert
475c3f99ac SDF21 добавил условие на поиск регистра по securityId
swt-importer фикс поля 35B/83D
2023-08-08 21:43:11 +03:00
ialbert
f00cf0ee3b SDF07 SUM/CLIENTN/INN/BIC/SPEC/NUMBER/RESULT
swt-exporter Charset.forName("windows-1251")
2023-08-08 21:26:51 +03:00
ialbert
4316830043 session sdf04/sdf13 2023-08-08 20:46:06 +03:00
AKurakin
e57ee9a72e db-scripts http://jira.mfd.msk:8088/browse/CLS-405 ddl (часть) 2023-08-08 18:09:58 +03:00
ialbert
39a3504c02 swt-exporter request groupId fix 2023-08-08 17:59:29 +03:00
ialbert
18b5e7232d Sdf21 operationDate format 2023-08-08 17:53:45 +03:00
ialbert
08f498f774 sdf21 validation company search tradingCode strip leading zeroes 2023-08-08 17:25:14 +03:00
ialbert
835beb55cc SDF56 dbf-exporter time format length 2023-08-08 17:04:30 +03:00
ialbert
add4335677 stmtService log + swt-importer sdf21 message 2023-08-08 16:51:26 +03:00
ialbert
8c80c30958 Merge branch 'ReturnDepositSessionFix' into dev
# Conflicts:
#	clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java
2023-08-08 16:27:59 +03:00
ialbert
0383068815 sdf08 sdf21 2023-08-08 16:25:38 +03:00
ialbert
6740c4ed23 StatementService SDF types restriction 2023-08-08 16:25:13 +03:00
AKurakin
fb0b57bffc dbf-exporter поправил формат S_DF07_Converter TYPE 2023-08-08 16:11:54 +03:00
ialbert
8fd329c129 LauncherCommandReceiver removed error log 2023-08-08 13:42:16 +03:00
ialbert
34d860b749 Merge branch 'ReturnDepositSessionFix' into dev 2023-08-08 13:14:02 +03:00
ialbert
33e75e6e81 sdf07 groupId bug 2023-08-08 12:59:55 +03:00
ialbert
68a7aec74c Merge branch 'ReturnDepositSessionFix' into dev 2023-08-08 12:22:17 +03:00
ialbert
8ecb0b7c9e SDF06 поиск компании по deal 2023-08-08 12:13:41 +03:00
ialbert
7279fdf743 Sdf07/Sdf09 fix 2023-08-08 11:53:38 +03:00
ialbert
92db7d5f1e Merge branch 'dev' into CLNRWORM 2023-08-07 19:21:00 +03:00
ialbert
7caa78edef added session monitor for sdf04/sdf13/sdf01/sdf57 2023-08-07 19:20:15 +03:00
ialbert
55f66994b3 Merge branch 'ReturnDepositSessionFix' into CLNRWORM 2023-08-07 19:16:48 +03:00
ialbert
9f9b260a4f sdf01/sdf02 bug fix sdf02 groupid 2023-08-07 17:52:24 +03:00
psemenkov
d71a7187fa http://jira.mfd.msk:8088/browse/CLS-469
Добавил загрузку документа DF-21.
2023-08-07 13:43:56 +03:00
akulikov
98335c8b2e http://jira.mfd.msk:8088/browse/CLS-358 refactor 2023-08-04 18:35:55 +03:00
ialbert
edb00e4608 SDF01 проверка curr_code RUR/RUB 2023-08-04 16:26:07 +03:00
akulikov
1e713c1292 http://jira.mfd.msk:8088/browse/CLS-358 fix logger names 2023-08-04 13:37:35 +03:00
akulikov
117e94ef2e http://jira.mfd.msk:8088/browse/CLS-358 company not found fixes 2023-08-04 13:33:27 +03:00
ialbert
8ea1ba2e79 Merge branch 'ReturnDepositSessionFix' into CLNRWORM 2023-08-04 13:03:33 +03:00
ialbert
b10d6bb0c3 Inclusion to pool fix 2023-08-04 12:58:17 +03:00
AKurakin
9ba69c188f dbf-importer SDf06Table поправил формат - тримлю числа, пустые как null 2023-08-04 11:40:07 +03:00
AKurakin
d8ad75dce9 dbf-importer SDf06Table поправил формат - тримлю числа 2023-08-04 11:17:24 +03:00
ialbert
7fa4b6aec5 Sdf21Executor.java 2023-08-03 21:13:23 +03:00
ialbert
5dd85d742f правки по D*** регистрам 2023-08-03 21:12:16 +03:00
ialbert
050c742313 SDF08/SDF21 2023-08-03 19:14:41 +03:00
ialbert
b1db92425e Merge branch 'dev' into CLNRWORM 2023-08-03 18:00:03 +03:00
psemenkov
7d51561c71 http://jira.mfd.msk:8088/browse/CLS-317
Привел конце документа ДФ-12
2023-08-03 17:42:47 +03:00
psemenkov
9208483045 http://jira.mfd.msk:8088/browse/CLS-462
Привел выгрузку поля 35A к виду ":35A:SHS10000,"
2023-08-03 12:12:08 +03:00
AKurakin
4522aec93f dbf-importer SDf06Table поправил формат inn, bic 2023-08-03 11:23:24 +03:00
ialbert
aa755cbd89 промежуточная сессия
заполнение баланса для регистра по облигациям в ExecutionFond
2023-08-02 21:46:48 +03:00
ialbert
c8fa6e052e правка 7 шага для МКР и промежуточной сессии 2023-08-02 19:18:13 +03:00
ialbert
7174024333 вынесены рассчет блокировок 2023-08-02 19:17:42 +03:00
akulikov
94af268598 http://jira.mfd.msk:8088/browse/CLS-358?focusedCommentId=55653&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-55653 2023-08-02 13:34:45 +03:00
ialbert
06c37e11be securitySymbol 2023-08-01 20:59:37 +03:00
ialbert
6ea0cf3e38 убрал исключение для нечетного количества сделок в 2 шаге сессий 2023-08-01 16:54:55 +03:00
ialbert
b6e19b9f8d SDF08 executor skip error sdf08 2023-08-01 16:53:32 +03:00
ialbert
d0eef0b15f IMDG log improved on 'More than one element found...' 2023-08-01 16:43:56 +03:00
akulikov
24eb6f9446 http://jira.mfd.msk:8088/browse/CLS-358 some fixes 2023-08-01 16:06:59 +03:00
ialbert
241f88199d выпилил из шага с PaymentInstruction блокировку активов 2023-08-01 14:49:10 +03:00
ialbert
89e8f2dae7 CLNRWORM hot fix session 2023-08-01 13:07:03 +03:00
ialbert
206ff77b97 update registries by new TCR bugfix 2023-08-01 11:46:02 +03:00
ialbert
63b72f0f67 swt-exporter SFTP 2023-07-31 20:21:38 +03:00
ialbert
67a80c7475 swt-exporter SFTP 2023-07-31 20:19:17 +03:00
etreschenkov
5343be3b58 обработка sdf04/sdf13 и изменения balance для регистров 2023-07-31 18:03:27 +03:00
etreschenkov
e8232caf2b обработка sdf04/sdf13 и изменения balance для регистров 2023-07-31 18:03:27 +03:00
akulikov
49c836cbde http://jira.mfd.msk:8088/browse/CLS-358 sftp fix after review 2023-07-31 16:07:52 +03:00
etreschenkov
79b65e0023 обработка sdf04 и изменения balance для регистров 2023-07-31 15:39:07 +03:00
etreschenkov
a5bb906eea шаг 7 для SecondaryAuctionT0 сессии: создание paymentInstruction по ASB/AMB регистрам 2023-07-31 15:39:07 +03:00
akulikov
b58895da59 http://jira.mfd.msk:8088/browse/CLS-358 sftp 2023-07-31 15:28:48 +03:00
akulikov
2c0ed58c2a http://jira.mfd.msk:8088/browse/CLS-358 sftp 2023-07-31 15:24:47 +03:00
akulikov
626d8d3206 http://jira.mfd.msk:8088/browse/CLS-358 sftp 2023-07-31 15:22:21 +03:00
etreschenkov
cec22d06f8 шаг 7 для SecondaryAuctionT0 сессии: создание paymentInstruction по ASB/AMB регистрам 2023-07-31 13:20:52 +03:00
etreschenkov
a9c9f1d47f пересчет F = T-B при снятии блокировок 2023-07-31 11:06:55 +03:00
etreschenkov
6883496845 пересчет F = T-B при обработке sdf08 2023-07-31 11:06:55 +03:00
etreschenkov
72d9896fca блокировка средств на активах, дополнительная логика для FOND секций 2023-07-31 11:06:55 +03:00
etreschenkov
218c67bbf6 созданние B и F регистров по sdf08 2023-07-31 11:06:55 +03:00
akulikov
cb0d720ae0 http://jira.mfd.msk:8088/browse/CLS-358 hot fix 2023-07-28 18:51:04 +03:00
ialbert
2d559f9bf1 registry#groupId и 2 шаг сессий 2023-07-27 19:04:23 +03:00
ialbert
cf1db1b604 STrades validation: проверка security для Fond 2023-07-27 17:56:53 +03:00
ialbert
6fbf4efa1c data.xml 2023-07-27 12:36:38 +03:00
aalehin
e50abf16cd http://jira.mfd.msk:8088/browse/CLS-280
---
fix up
2023-07-27 12:32:30 +03:00
aalehin
a6c2851bd2 http://jira.mfd.msk:8088/browse/CLS-280
---
addded validation
2023-07-27 12:31:56 +03:00
ialbert
c646bfe866 meta.xml 3.5.0.41 2023-07-27 12:30:12 +03:00
ialbert
158a9db90c SDF57 обработка пишет ошибку если DM** со статусом OK 2023-07-27 12:12:35 +03:00
ialbert
c92dc63fa8 http://jira.mfd.msk:8088/browse/CLS-444
http://jira.mfd.msk:8088/browse/CLS-445
2023-07-27 11:54:24 +03:00
aalehin
9518c7130a http://jira.mfd.msk:8088/browse/CLS-280
---
рефакторинг
2023-07-26 18:22:46 +03:00
ialbert
98db18e687 http://jira.mfd.msk:8088/browse/CLS-439 2023-07-26 18:06:31 +03:00
ialbert
f7cb4855aa http://jira.mfd.msk:8088/browse/CLS-444
http://jira.mfd.msk:8088/browse/CLS-445
backend-api/clearing-service return deposit request
2023-07-26 17:36:18 +03:00
aalehin
dac9c80c6f http://jira.mfd.msk:8088/browse/CLS-280
---
правки по ревью
2023-07-26 15:42:07 +03:00
ialbert
87c114370c http://jira.mfd.msk:8088/browse/CLS-439 обновлять STrades только по команде (не по шкедулеру).
команда на клиринг сервис отправляется только в случае если было обновление или создание strades
2023-07-26 12:22:45 +03:00
ialbert
b36ea99b28 вынес настройки удаленной SFTP папки с файлами в отдельный класс
теперь модуль можно запустить без SFTP (при отсутствии соответствующих настроек)
2023-07-25 19:33:30 +03:00
ialbert
a0d5baef17 swt-importer SFTP включен только при наличии настройки import-swt-service.store.sftp-src-dir 2023-07-25 19:00:11 +03:00
ialbert
ccb669ca75 added SFTP to swt-importer 2023-07-25 18:29:58 +03:00
aalehin
39e1d9dd65 http://jira.mfd.msk:8088/browse/CLS-280
---
fix up
2023-07-25 16:28:36 +03:00
ialbert
39ccef91a5 http://jira.mfd.msk:8088/browse/CLS-437 2023-07-25 16:05:34 +03:00
ialbert
b569062294 http://jira.mfd.msk:8088/browse/CLS-437 2023-07-25 15:49:13 +03:00
aalehin
478b711dee http://jira.mfd.msk:8088/browse/CLS-280
---
добавил (обновление или добавление) registerExecution по итогам сделки
ввел проверку на дубликат при генерации всего реестра
2023-07-25 14:42:36 +03:00
ialbert
26145a7587 http://jira.mfd.msk:8088/browse/CLS-437 2023-07-25 13:22:10 +03:00
aalehin
168b50bdfc http://jira.mfd.msk:8088/browse/CLS-280
---
Исправил заполнение depoPaymentInstructionRegister. Поля tradingClearingRegistryType и tradingClearingRegistry.
2023-07-24 19:10:43 +03:00
ialbert
112fee67e4 session#updated/created
dm** registries sessionId/sessionType
dm** registryStatus update
2023-07-24 12:48:00 +03:00
ialbert
6dc5133d10 сортировка регистров на 5 шаге 2023-07-24 10:59:47 +03:00
ialbert
79e1867e7f обработка SDF57 проставление баланса при создании DMAU
проставление SessionType на шаге включения в пул
апдейт статуса DM*T(clnr) в fail/manage
2023-07-21 19:06:21 +03:00
ialbert
cb03a62265 http://jira.mfd.msk:8088/browse/CLS-435 2023-07-21 15:19:33 +03:00
ialbert
62b847fcef http://jira.mfd.msk:8088/browse/CLS-436 2023-07-20 19:26:10 +03:00
ialbert
e1d565522b 5 шаг сессии по возврату: поиск DM*T(clnr) условие на контракт 2023-07-20 16:22:14 +03:00
ialbert
cba1772bf6 сессия шаг 5 контроль обязательств по возвратам: поиск DM*X и DM*T(info) 2023-07-20 13:39:13 +03:00
ialbert
a14ee21fd6 SdDf57Executor: фикс поисков регистров B и F в случае инфо счета 2023-07-20 11:48:21 +03:00
ialbert
f5d7a7b127 dbf-importer фикс чтобы забирал с SFTP без фильтрации 2023-07-19 18:58:07 +03:00
ialbert
828ba91ba0 5 шаг по сессиям 2023-07-19 18:10:29 +03:00
ialbert
7660f88387 промежуточная сессия МКР: removed fail status для второй части сделки 2023-07-19 15:25:58 +03:00
ialbert
5018e8a4be заполнение Sd06#sum ожидает string/bigdecimal [2] 2023-07-19 15:02:33 +03:00
ialbert
5c1bcc3b1b Промежуточная сессия МКР: 5 шаг сессий по сегодняшним сделкам, статусы FAIL/UNCV -> MNG 2023-07-19 14:45:22 +03:00
ialbert
315d1e43ec http://jira.mfd.msk:8088/browse/CLS-424 issuerId для instrument_type = RATE 2023-07-19 14:32:05 +03:00
ialbert
2a109ed496 заполнение Sd06#sum ожидает string/bigdecimal 2023-07-19 14:25:39 +03:00
ialbert
9382a8be8a промежуточная сессия МКР 5 шаг пропускать проверки для бумаг 2023-07-19 12:51:13 +03:00
ialbert
4c69d38069 http://jira.mfd.msk:8088/browse/CLS-424 заполнение SecurityFondGatewayRequest#Uuid 2023-07-19 12:32:57 +03:00
ialbert
bfca0aadf5 заполнение registry#securitySymbol при обработке SDF01/57 2023-07-19 11:31:21 +03:00
ialbert
aea33dcd13 http://jira.mfd.msk:8088/browse/CLS-428 dbf-importer SFTP support 2023-07-18 18:24:13 +03:00
ialbert
c4416f2034 session (step 2) registry#capacity fix 2023-07-18 18:19:55 +03:00
akulikov
96c8441307 http://jira.mfd.msk:8088/browse/CLS-358 fix after review 2023-07-18 15:56:16 +03:00
akulikov
a8fb21f599 http://jira.mfd.msk:8088/browse/CLS-358 KSCommissionTrades 2023-07-18 15:37:48 +03:00
ialbert
2399cfd8cc убрал yyyyMMdd из groupId регистров по ExecutionDeposit/ExecutionFond 2023-07-18 13:48:10 +03:00
ialbert
7cc1097c69 http://jira.mfd.msk:8088/browse/CLS-425 2023-07-17 19:22:10 +03:00
akulikov
95ff52de20 http://jira.mfd.msk:8088/browse/CLS-358 2023-07-17 18:55:51 +03:00
ialbert
07293ff3eb http://jira.mfd.msk:8088/browse/CLS-427 реализация методов в transactional Imdg 2023-07-17 18:20:36 +03:00
ialbert
658810cc85 http://jira.mfd.msk:8088/browse/CLS-423 2023-07-17 17:21:15 +03:00
ialbert
18a2c6705d sdf08 не создавать registry если не найден security
правки по промежуточной сессии
2023-07-17 12:57:07 +03:00
etreschenkov
aa49f28d69 Merge remote-tracking branch 'origin/gateway' into dev 2023-07-14 18:37:11 +03:00
ialbert
fb45dda0f5 http://jira.mfd.msk:8088/browse/CLS-421 6 symbols -> 7 symbols 2023-07-14 18:31:45 +03:00
etreschenkov
14b29edf84 Merge branch 'gateway' into dev 2023-07-14 18:18:04 +03:00
etreschenkov
60da507f71 http://jira.mfd.msk:8088/browse/CLS-420 2023-07-14 18:17:51 +03:00
ialbert
da566c4c81 http://jira.mfd.msk:8088/browse/CLS-421 2023-07-14 18:14:05 +03:00
ialbert
7f8e2dd027 http://jira.mfd.msk:8088/browse/CLS-422 2023-07-14 18:11:28 +03:00
ialbert
56a89b7e6d Merge remote-tracking branch 'origin/dev' into dev 2023-07-14 14:31:30 +03:00
akulikov
2b1606c113 http://jira.mfd.msk:8088/browse/CLS-358 KSListSessionReport 2023-07-13 20:44:49 +03:00
akulikov
c01f499648 http://jira.mfd.msk:8088/browse/CLS-358 fix KSRepTrades and logs for KSRepDepoNetto 2023-07-13 20:44:48 +03:00
akulikov
3b30b34a34 http://jira.mfd.msk:8088/browse/CLS-358 fix SessionIdParam reports 2023-07-13 20:44:48 +03:00
ialbert
67149d08fe Merge branch 'gateway' into dev
# Conflicts:
#	clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java
#	clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java
2023-07-13 17:52:46 +03:00
ialbert
85a4cc95fe cherry-pick fix 2023-07-13 17:42:47 +03:00
ialbert
b3c58b0442 ограничение на создание счетов по sdf01/sdf08 2023-07-13 17:39:37 +03:00
ialbert
43c15d193b strades import operation=купля/продажа -> B/S 2023-07-13 16:40:47 +03:00
AKurakin
7f400066b9 backend-api поправил стук при анонимном пользователе 2023-07-13 15:31:31 +03:00
AKurakin
d9e0a4ada2 backend-api поправил стук при анонимном заходе 2023-07-13 14:52:38 +03:00
ialbert
7612126b9e ограничение на создание счетов по sdf01/sdf08 2023-07-13 14:08:35 +03:00
etreschenkov
997118ceb8 поправлены баги при создании инструментов 2023-07-12 19:29:20 +03:00
etreschenkov
d5b083dcfe Merge branch 'gateway' into dev 2023-07-12 18:57:02 +03:00
etreschenkov
97322f6e0f поправлены баги при создании инструментов 2023-07-12 18:56:46 +03:00
etreschenkov
343277caa3 поправлены баги при создании компаний и инструментов 2023-07-12 18:48:16 +03:00
ialbert
2d37a2ec95 forming payment instruction refactoring: common registry searches 2023-07-12 16:17:23 +03:00
ialbert
e184c68be2 refactor IMDG getSingle* -> getFirst* 2023-07-12 14:22:44 +03:00
etreschenkov
8da9583854 поправил баг в gateway 2023-07-12 13:52:11 +03:00
etreschenkov
656920e1ac убрал из загрузки trades некоторые поля 2023-07-12 13:51:55 +03:00
ialbert
c3b967dddc http://jira.mfd.msk:8088/browse/CLS-396 2023-07-10 18:13:26 +03:00
ialbert
86469d6ff7 В финальной МКР часть про возврат депозитов скопированна из сесси по возвратам депозитов 2023-07-10 15:30:24 +03:00
etreschenkov
1dce1a2fe7 http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-10 14:26:32 +03:00
etreschenkov
e9f3d9ba4a http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-10 13:42:11 +03:00
etreschenkov
87349837f3 http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-10 13:31:43 +03:00
ialbert
53e248b674 сессия по возврату депозитов: формирование PaymentInstruction
1. Блокировка ассетов
2. фиксы полей PaymentInstruction
3. SDF03 подмена счетов если один из них INFO
2023-07-10 12:24:24 +03:00
etreschenkov
dde7c8eef2 http://jira.mfd.msk:8088/browse/CLS-367 2023-07-10 11:41:00 +03:00
ialbert
5c7218e7f0 сессия по возврату депозитов, DM*T 'CLNR' создание PaymentInstruction 2023-07-09 16:36:57 +03:00
ialbert
a63782a57b заполнение statement#contract 2023-07-09 15:21:05 +03:00
etreschenkov
d805a1d462 http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-09 14:55:44 +03:00
etreschenkov
7522a8f899 http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-09 14:24:11 +03:00
ialbert
cdd4c4069c sdf03 anlt account search bugfix 2023-07-09 14:19:03 +03:00
ialbert
667ca04eeb SDF03 создание подмена на ANLT номер счета для Info счетов
SDF04 обработка снятие блокировок для счетов при пришедшем ANLT счете
2023-07-09 13:52:55 +03:00
etreschenkov
7d30f24525 http://jira.mfd.msk:8088/browse/CLS-410 2023-07-09 13:44:40 +03:00
etreschenkov
1d4e1b4a3e http://jira.mfd.msk:8088/browse/CLS-410 2023-07-09 13:10:43 +03:00
etreschenkov
0668fa8b46 http://jira.mfd.msk:8088/browse/CLS-411 // http://jira.mfd.msk:8088/browse/CLS-410 2023-07-09 12:26:24 +03:00
ialbert
a82ab9b0ca SDF57 поиск счета по comment (в случае ANLT) 2023-07-09 12:23:35 +03:00
AKurakin
c4c12ccad7 meta xsl поправил авто-генерацию extends 2023-07-07 20:55:37 +03:00
akulikov
a4f2da37d4 http://jira.mfd.msk:8088/browse/CLS-358 refactor 2023-07-07 19:47:30 +03:00
etreschenkov
705b24910d http://jira.mfd.msk:8088/browse/CLS-410 2023-07-07 19:44:53 +03:00
AKurakin
03e3188b39 meta 3.5.0.40 2023-07-07 19:43:59 +03:00
ialbert
abdc6d69b8 session step 2 O/T creation capacity for accountType=info 2023-07-07 19:40:01 +03:00
ialbert
690ab4c35d PaymentInstruction#paymentPurpose расмещение "Размещение депозита ... по ТКР ..." 2023-07-07 19:32:09 +03:00
akulikov
ab46e96c28 http://jira.mfd.msk:8088/browse/CLS-358 refactor 2023-07-07 19:28:46 +03:00
ialbert
28102d34af SDF57 обработка
1. DMAU регистры
2. поиск счетов для кейса accountType=ANLT
2023-07-07 19:22:17 +03:00
akulikov
075591d2ea http://jira.mfd.msk:8088/browse/CLS-358 refactor 2023-07-07 19:21:23 +03:00
AKurakin
69c5e63158 http://jira.mfd.msk:8088/browse/CLS-410 SDf04 поправил в соответствии в мета 2023-07-07 18:19:03 +03:00
aalehin
d6de26963b http://jira.mfd.msk:8088/browse/CLS-280
---
fixup
2023-07-07 18:15:59 +03:00
aalehin
7a0bbb9bce http://jira.mfd.msk:8088/browse/CLS-280
---
fixup
2023-07-07 18:07:59 +03:00
etreschenkov
274e967888 исправлено поля TP для sdf05 2023-07-07 16:10:21 +03:00
aalehin
cd920fbdf8 http://jira.mfd.msk:8088/browse/CLS-280
---
fixup
2023-07-07 16:00:34 +03:00
etreschenkov
a0de1d0afc http://jira.mfd.msk:8088/browse/CLS-409 2023-07-07 15:47:11 +03:00
AKurakin
a998f75ed9 account-service http://jira.mfd.msk:8088/browse/CLS-271 поправил валидацию. 2023-07-07 14:20:56 +03:00
etreschenkov
ac10bc4fb2 http://jira.mfd.msk:8088/browse/CLS-317 2023-07-07 14:07:10 +03:00
etreschenkov
02b870f95b http://jira.mfd.msk:8088/browse/CLS-367 2023-07-07 13:18:37 +03:00
etreschenkov
db8fd60495 refactoring: новый энут для определения типа отчета 2023-07-07 13:10:06 +03:00
etreschenkov
d1378a4cf4 refactoring: enum name 2023-07-07 13:07:58 +03:00
etreschenkov
93a3df9bfb http://jira.mfd.msk:8088/browse/CLS-367 2023-07-07 12:49:29 +03:00
etreschenkov
e59b718eab http://jira.mfd.msk:8088/browse/CLS-367 2023-07-07 12:40:46 +03:00
akulikov
7179c09c29 http://jira.mfd.msk:8088/browse/CLS-358 csv bean writer prototype 2023-07-07 12:38:55 +03:00
aalehin
6ff6d246a4 http://jira.mfd.msk:8088/browse/CLS-280
---
fixup
2023-07-07 10:47:12 +03:00
etreshenkov
2bdfb10743 http://jira.mfd.msk:8088/browse/CLS-406 2023-07-06 19:14:19 +03:00
ialbert
9f018d13c4 Sdf08Executor registry capacity: DepoAccount search fix 2023-07-06 19:04:30 +03:00
etreshenkov
b469c162b2 http://jira.mfd.msk:8088/browse/CLS-408 2023-07-06 19:03:20 +03:00
ialbert
73e93a4c46 sdf57 уловия поиска регистров B и F +accountId = statement.accountId 2023-07-06 15:56:59 +03:00
ialbert
6c1ec5380e account-service TCR validation bugfix
clearing-service поменял местами SDF01Executor и SDF57Executor
разнес нотификацию сверки и Sdf01Executor
2023-07-06 14:52:56 +03:00
AKurakin
30349030dd http://jira.mfd.msk:8088/browse/CLS-404 (bug fix CLS-313) поправил поиск по файлам 2023-07-06 14:09:17 +03:00
akulikov
262166d470 http://jira.mfd.msk:8088/browse/CLS-358 some fixes 2023-07-05 21:48:36 +03:00
AKurakin
810ebc3f58 http://jira.mfd.msk:8088/browse/CLS-400 meta 3.5.0.39 2023-07-05 19:31:18 +03:00
akulikov
c8dc5cdbcc http://jira.mfd.msk:8088/browse/CLS-358 for review 2023-07-05 18:20:09 +03:00
AKurakin
05a42541de account-service http://jira.mfd.msk:8088/browse/CLS-271 убрано автосоздание ТКР, оставлено только для ClientCode 2023-07-05 17:43:47 +03:00
akulikov
109240166e http://jira.mfd.msk:8088/browse/CLS-358 send reports to gateway 2023-07-05 15:17:24 +03:00
akulikov
20f84b8311 http://jira.mfd.msk:8088/browse/CLS-358 GREF and GRET processing 2023-07-05 14:03:42 +03:00
akulikov
d0d4c3a19f http://jira.mfd.msk:8088/browse/CLS-358 GREF 2023-07-05 13:25:37 +03:00
akulikov
a3a749f587 http://jira.mfd.msk:8088/browse/CLS-358 builders 2023-07-05 13:25:24 +03:00
ialbert
a529135daf http://jira.mfd.msk:8088/browse/CLS-398 2023-07-05 12:36:06 +03:00
ialbert
2ad79bb683 http://jira.mfd.msk:8088/browse/CLS-398
добавил отправку команды на clearing-service по событиям tcr new/tcr new auto
добавил поиск и обновление регистров на базе созданных ТКР
2023-07-04 19:23:24 +03:00
ialbert
be55af4c5f http://jira.mfd.msk:8088/browse/CLS-396 создание SDF05 по команде из кафки с pr="9" 2023-07-04 16:40:30 +03:00
ialbert
5b3fedfc0c logPrefix для валидации 2023-07-04 14:41:11 +03:00
AKurakin
dfe3e271d7 backend-api логирование 2023-07-04 14:22:32 +03:00
AKurakin
e25b8c771f backend-api http://jira.mfd.msk:8088/browse/CLS-390 s-df's controller 2023-07-04 14:01:13 +03:00
ialbert
9b2d5dbf3a http://jira.mfd.msk:8088/browse/CLS-383 imdg выгрузка данных за сегодня:
execution_deposit/execution_fond по trading_date
s_trades по trade_date
statement по clearing_date
notification по clearing_date
s_df по generation_time
2023-07-04 13:37:17 +03:00
ialbert
5944cf8208 http://jira.mfd.msk:8088/browse/CLS-363 2023-07-04 11:52:44 +03:00
akulikov
132a3e7096 http://jira.mfd.msk:8088/browse/CLS-313 fix send sftp 2023-07-03 20:20:44 +03:00
akulikov
d253f9e1ff http://jira.mfd.msk:8088/browse/CLS-313 todo issue 2023-07-03 20:08:07 +03:00
ialbert
8548c6a8f7 5 шаг InspectionObligations:
1. spring scope prototype fix
2. log fix
2023-07-03 19:18:08 +03:00
AKurakin
716e70b10a backend-api data 3.5.0.12 + meta 2023-07-03 19:01:15 +03:00
ialbert
df4802c856 dbf-exporter/clearing-service: изменил заполнение SDf05#TM и DBF тип DATE -> CHARACTER(8) 2023-07-03 18:48:01 +03:00
AKurakin
ccc6538225 backend-api http://jira.mfd.msk:8088/browse/CLS-390 + meta 2023-07-03 17:31:40 +03:00
aalehin
dc798c4d64 http://jira.mfd.msk:8088/browse/CLS-280
---
поправил стук и добавил логику для заполнения MoneyBalanceRegister
2023-07-03 14:09:49 +03:00
akulikov
717e861fe0 http://jira.mfd.msk:8088/browse/CLS-358 (report builders) 2023-06-30 20:29:28 +03:00
ialbert
7f9d8badec SDF57 executor balance из statement
финальная сессия МКР 5 шаг UNCV/FAIL
2023-06-30 19:05:47 +03:00
ialbert
61332c5b73 финальная сессия МКР шаг 7 2023-06-30 18:44:32 +03:00
ialbert
d91383b4e5 финальная сессия МКР часть 5 шага по сделкам 2023-06-30 18:04:35 +03:00
ialbert
679b5cc01b изменения по финальной МКР сессии 5/7 шаг bugfix 2023-06-30 17:20:15 +03:00
ialbert
84ccc444b8 изменения по финальной МКР сессии шаг 5 фикс поиска DM*X 2023-06-30 17:06:03 +03:00
ialbert
f90365a191 изменения по финальной МКР сессии:
1. шаг 5 поменял статус регистров MNG -> FAIL
1. шаг 7 добавлено условие на valueDate<settlementDate при отсеивании по DM*X
2023-06-30 16:44:38 +03:00
ialbert
19184c3a4a изменения по финальной МКР сессии:
1. перенесен шаг 5 из сессии по возврату депозитов. (отличие: при невыполнении условия на DM*X статус FAIL вместо MNG)
2. шаг 7 форм. PaymentInstruction: выпилил редактирование активов по обязательствам LM*T
3. шаг 7 форм. PaymentInstruction: пропускаем формирование если найден DM*X по обязательству
2023-06-30 15:45:26 +03:00
AKurakin
ef94bdc2fe http://jira.mfd.msk:8088/browse/CLS-362 META data 2023-06-30 11:35:43 +03:00
AKurakin
ad4e699bb6 clearing-service возвращение ответа в REQUEST_INFO_UPDATE 2023-06-30 11:08:20 +03:00
AKurakin
23fbf503c9 clearing-service fix NPE on fix reset-balance 6b036c8e91 2023-06-30 10:50:49 +03:00
etreshenkov
6b036c8e91 fix reset-balance 2023-06-30 09:28:09 +03:00
AKurakin
9146fb67b0 meta new 3.5.0.34 2023-06-29 18:21:35 +03:00
ialbert
0086bbf98b SDF01 executor определение статуса сделки bugfix
SDF57 executor trim all whitespaces from statement#contract
2023-06-29 16:41:07 +03:00
AKurakin
c85d82c2b7 company-service http://jira.mfd.msk:8088/browse/CLS-374 ClearingMemberCategory -> Relation не для всех категорий нужен 2023-06-29 15:47:56 +03:00
AKurakin
ac5cd3b842 db-scripts поправил апдейт скрипт 2023-06-29 15:04:32 +03:00
ialbert
b221f4d76f rollback сессия по возвратам кейс с созданными PaymentInstruction 2023-06-29 14:42:50 +03:00
ialbert
afc4669cad сессия по возвратам депозитов шаг 7 возвращать пустой результат 2023-06-29 14:32:27 +03:00
ialbert
d63d080023 Сессия по возвратам депозитов проверка средств (шаг 5) формирование PaymentInstruction (шаг 7) 2023-06-29 14:16:50 +03:00
AKurakin
27e9c75e78 account-service CLS-361 после ТКР отмена автоматического "сообщение на открытие клиринговых регистров" 2023-06-29 14:04:15 +03:00
AKurakin
fe0887b808 account-srvice http://jira.mfd.msk:8088/browse/CLS-361 CLS-271 дублирование ТКР поправил 2023-06-29 13:56:02 +03:00
ialbert
f5783dbdb6 SDF57 обработка создание DM*X по TM*T 2023-06-29 13:48:12 +03:00
AKurakin
c7f1b490ed account-srvice http://jira.mfd.msk:8088/browse/CLS-265 http://jira.mfd.msk:8088/browse/CLS-333 Info-account - поправил инкремент 2023-06-29 13:25:31 +03:00
AKurakin
5aa1de8b18 account-service http://jira.mfd.msk:8088/browse/CLS-361 TCR sequence 2023-06-29 13:01:36 +03:00
AKurakin
fa2cb814c8 utility-service поправил возвращение ответов при обработки Notification. 2023-06-29 11:55:44 +03:00
ialbert
55fa772b52 clearing-service поправил приоритет нотификаций при сверке: HIGH если не сошлось, LOW если ок 2023-06-29 11:14:46 +03:00
ialbert
8004353f37 SDF57 registry#tradingClearingRegistry/tradingClearingRegistryId поиск TradingClearingRegistry добавил условие status ACTV 2023-06-28 19:35:53 +03:00
etreschenkov
5e7e31066c http://jira.mfd.msk:8088/browse/CLS-373 2023-06-28 19:34:55 +03:00
etreschenkov
db24212cc6 http://jira.mfd.msk:8088/browse/CLS-373 2023-06-28 19:32:20 +03:00
AKurakin
563e7f47c4 account-service http://jira.mfd.msk:8088/browse/CLS-361 валидация 3.5 для ТКР нового 2023-06-28 19:04:27 +03:00
etreschenkov
0c1a02ba7f http://jira.mfd.msk:8088/browse/CLS-373 2023-06-28 18:52:36 +03:00
AKurakin
33c9fd87e0 account-service http://jira.mfd.msk:8088/browse/CLS-361 проставление в ТКР code 2023-06-28 18:47:15 +03:00
ialbert
b59cd10acc SDF57 поиск счетов c_acc_deb/c_acc_cred -> acc_deb/acc_kr 2023-06-28 18:44:49 +03:00
AKurakin
fda13da0fd db-script http://jira.mfd.msk:8088/browse/CLS-355 скрипт обновления базы 2023-06-28 18:42:33 +03:00
etreschenkov
577a4cc42d http://jira.mfd.msk:8088/browse/CLS-373 2023-06-28 17:39:18 +03:00
etreschenkov
6a91ce85e2 http://jira.mfd.msk:8088/browse/CLS-373 2023-06-28 17:39:00 +03:00
aalehin
d388d5a39e http://jira.mfd.msk:8088/browse/CLS-317
---
fix up
2023-06-28 17:06:18 +03:00
AKurakin
e9661f8ec6 clearing-service http://jira.mfd.msk:8088/browse/CLS-265 Sdf08Executor поправил определеление depo type 2023-06-28 14:21:43 +03:00
ialbert
2155c02a75 шаг 6 формирование L/C регистров условие регистров на sessionId 2023-06-28 13:55:00 +03:00
ialbert
92fcdb8bb4 SDF57 AM*T.diffBalance = AM*T.balance - AM*T.checkBalance 2023-06-28 13:25:33 +03:00
ialbert
b8cffb8f6a обновляем sessionId регистров при включении в сессионный пул 2023-06-28 11:41:26 +03:00
ialbert
cd35d5ba9c GVER теперь запускает сверку 2023-06-28 10:13:30 +03:00
ialbert
82cf75ac2d SDF57 опечатка в логе 2023-06-27 20:36:03 +03:00
ialbert
d52e335174 SDF57 обработка добавил логи 2023-06-27 17:56:42 +03:00
ialbert
864f64bba3 SDF01 обработка, логи 2023-06-27 17:32:43 +03:00
ialbert
6219add3c9 поправил все логи в trace для clearing-service 2023-06-27 17:06:24 +03:00
ialbert
7b6c6a4ad0 http://jira.mfd.msk:8088/browse/CLS-372 SDF57 создается DM*T по любым specif №.* 2023-06-27 16:53:06 +03:00
ialbert
91f1c9a5df обработка SDF01 отправка Notification по результатам сверки 2023-06-27 14:50:58 +03:00
ialbert
9ace5c276d логи по сессиям 2023-06-27 13:53:46 +03:00
ialbert
524d59eece http://jira.mfd.msk:8088/browse/CLS-357 SDF06 inOutDirection in не требует проверки через gateway 2023-06-27 12:02:59 +03:00
ialbert
7a9b9b6eff выгрузка сделок на шаге 1 для промежуточной сессии МКР аналогично финальной МКР (выгружаем все ExecutionDeposit) 2023-06-26 19:47:14 +03:00
ialbert
4fe117236f обновление workflowStatus при закрытии 2023-06-26 19:09:40 +03:00
ialbert
da10e2bd0d http://jira.mfd.msk:8088/browse/CLS-359 sdf03#sbanknam/rbanknam, sdf03#sum_deb, sdf12#quantity 2023-06-26 16:06:48 +03:00
AKurakin
4fa1cbf32a utility-service http://jira.mfd.msk:8088/browse/CLS-339 Notification priority enum 2023-06-26 15:55:46 +03:00
AKurakin
baa7492e99 utility-service http://jira.mfd.msk:8088/browse/CLS-339 Notification новые поля 2023-06-26 15:52:46 +03:00
psemenkov
5c69305e1f http://jira.mfd.msk:8088/browse/CLS-268
Поправил валидацию clearingCalendar.
2023-06-26 15:04:11 +03:00
psemenkov
f27b313044 http://jira.mfd.msk:8088/browse/CLS-268
Поправил ошибки и вывод в лог.
2023-06-26 15:04:11 +03:00
AKurakin
54cacc7e2e DDL meta http://jira.mfd.msk:8088/browse/CLS-355 Добавление полей comment и priority в notification, справочника priority 2023-06-26 14:35:56 +03:00
AKurakin
88fda6d2b9 securities-service http://jira.mfd.msk:8088/browse/CLS-258 очередные мелкие баги с валидацией поправил 2023-06-23 19:15:46 +03:00
ialbert
2acf7a1e24 инициирование сверки SDF56 по команде от scheduler-service 2023-06-23 15:48:35 +03:00
ialbert
168d54a040 SDF57 executor diffBalance/checkBalance for registry_unit B/F fix 2023-06-23 13:06:45 +03:00
AKurakin
c18d9d41aa swt-exporter http://jira.mfd.msk:8088/browse/CLS-317 поправил формат DF09, DF11, DF12, DF14 2023-06-22 19:08:28 +03:00
etreschenkov
385992cdb1 http://jira.mfd.msk:8088/browse/CLS-348 2023-06-22 18:50:23 +03:00
etreschenkov
d759e54f6d вводы/выводы - gateway 2023-06-22 16:05:00 +03:00
aalehin
4ac51b04ef http://jira.mfd.msk:8088/browse/CLS-280
---
refactor
2023-06-22 16:00:28 +03:00
etreschenkov
b18e047f84 вводы/выводы - gateway 2023-06-22 12:49:56 +03:00
etreschenkov
aa9081ccf3 вводы/выводы - gateway 2023-06-22 12:38:20 +03:00
etreschenkov
bf68d50b3e реформат реквеста для security-service 2023-06-22 10:52:24 +03:00
AKurakin
1d639b5b48 backend-api http://jira.mfd.msk:8088/browse/CLS-356 + убрал древние валидаторы из ActionValidationProvider 2023-06-21 18:42:59 +03:00
AKurakin
8467b8ef9d securities-service добавил обработку DESTINATION_GATEWAY_MONEY_MARKET_SECURITY 2023-06-21 18:05:46 +03:00
etreschenkov
43dde65830 отправить ответный запрос с gateway в клиринг сервис 2023-06-21 15:35:38 +03:00
AKurakin
11fbb281a6 company-service поправил текст ошибок для CompanySymbolNew (todo refactoring update) 2023-06-21 13:50:59 +03:00
AKurakin
e3cbd73807 company-service поправил текст ошибок для company-new/update 2023-06-21 13:38:51 +03:00
etreschenkov
28006c3a33 поправил заполнение id у запроса от gateway 2023-06-21 12:08:06 +03:00
AKurakin
fa17164d81 securities-service рефакторинг обработки запросов. 2023-06-21 11:46:07 +03:00
etreshenkov
058c5ec1b4 fix company-service 2023-06-21 11:17:12 +03:00
ialbert
b19ec97a5d http://jira.mfd.msk:8088/browse/CLS-357 SDF06 executor 2023-06-20 19:46:24 +03:00
etreshenkov
8f7bd69f4e fix bug 2023-06-20 19:07:11 +03:00
aalehin
7a685c8f0c http://jira.mfd.msk:8088/browse/CLS-280
---
refactor
2023-06-20 19:04:58 +03:00
AKurakin
4382cc5572 swt-exporter http://jira.mfd.msk:8088/browse/CLS-317 поправил формат 2023-06-20 18:36:07 +03:00
ialbert
8d4c38a9cb creating payment instruction session step 7 bugfix: transaction_number -> transactionNumber 2023-06-20 15:39:07 +03:00
AKurakin
40c2bdc64a account-service http://jira.mfd.msk:8088/browse/CLS-271 ТКР, часть, остальное см. company-service что присылает. 2023-06-20 14:40:47 +03:00
ialbert
f5acd1e0e5 marketCodes T0/B0 session bugfix 2023-06-20 14:31:09 +03:00
ialbert
e935b3c366 bugfix подготовка сделок для сессий первичные торги B0/T0 marketType -> market 2023-06-20 12:32:41 +03:00
ialbert
34faab9220 SDF06 executor bugfix 2023-06-19 19:07:21 +03:00
ialbert
ae7e03fda8 SDF57 executor NLP fix 2023-06-19 18:17:58 +03:00
ialbert
eae1e816da statement service bugfix 2023-06-19 18:10:23 +03:00
AKurakin
99d141bf41 account-service imdg - wait available 2023-06-19 17:51:53 +03:00
etreschenkov
142c534aa2 http://jira.mfd.msk:8088/browse/CLS-259 2023-06-19 17:00:20 +03:00
ialbert
b81559002f обработка SDF06 взаимодействие с gateway 2023-06-19 16:56:05 +03:00
AKurakin
c98087ccd6 securities-service api-gateway http://jira.mfd.msk:8088/browse/CLS-348 2023-06-19 16:46:21 +03:00
ialbert
699a40f157 обработка SDF06 клиринг сервисом 2023-06-19 12:41:21 +03:00
etreschenkov
4a4af8a442 проставлять securityType для запроса от gateway 2023-06-19 12:35:14 +03:00
ialbert
54307516ad clearing-service SDF06 amount, direction 2023-06-16 19:55:00 +03:00
etreschenkov
c676be8f0d http://jira.mfd.msk:8088/browse/CLS-357 2023-06-16 19:52:04 +03:00
etreschenkov
0865c8b1d7 http://jira.mfd.msk:8088/browse/CLS-357 2023-06-16 19:49:57 +03:00
AKurakin
98964a3f3e account-service http://jira.mfd.msk:8088/browse/CLS-265 поправил валидацию status 2023-06-16 19:41:34 +03:00
ialbert
2e7011921d убрал проверку на маркет U для SDF06 2023-06-16 19:25:02 +03:00
ialbert
a13b874b3e bugfix sdf06 validation 2023-06-16 19:09:13 +03:00
AKurakin
e5e7f774e5 backend-api http://jira.mfd.msk:8088/browse/CLS-64 UserSettingsController fix unit test (see ea561b9a85) 2023-06-16 19:01:54 +03:00
AKurakin
26e8dd200a backend-api db-scripts http://jira.mfd.msk:8088/browse/CLS-354 meta json update 2023-06-16 19:01:54 +03:00
ialbert
9690dd727e зависимость на модуль проверки прав для клиринг сервиса 2023-06-16 18:53:30 +03:00
ialbert
654b4f643c обработка SDF06 клиринг сервисом 2023-06-16 18:47:44 +03:00
etreschenkov
869315ce5a some refactroing gateway 2023-06-16 18:42:33 +03:00
etreschenkov
b399d238c3 rename class 2023-06-16 18:38:22 +03:00
etreschenkov
fa76c1fb35 fix logging 2023-06-16 18:35:17 +03:00
etreschenkov
3f8b24319c some refactroing gateway 2023-06-16 18:22:25 +03:00
etreschenkov
33c40cfa66 some refactroing gateway 2023-06-16 18:12:14 +03:00
etreschenkov
b6f94a4069 some refactroing gateway 2023-06-16 18:11:31 +03:00
etreschenkov
c15f3fba9d some refactroing gateway 2023-06-16 17:23:19 +03:00
etreschenkov
2d2a89264d some refactroing gateway 2023-06-16 16:21:52 +03:00
etreschenkov
9e095a1825 some refactroing gateway 2023-06-16 15:27:23 +03:00
etreschenkov
8d0f1faae8 http://jira.mfd.msk:8088/browse/CLS-357 2023-06-16 15:20:32 +03:00
etreschenkov
1c155e4804 http://jira.mfd.msk:8088/browse/CLS-357 2023-06-16 14:54:38 +03:00
etreshenkov
e704b8d70c изменил(упростил) логику gatewa 2023-06-16 14:22:47 +03:00
AKurakin
1cd52cd2c3 dbf-importer SDf57Table Ext_date теперь любой тип доступен :) 2023-06-15 18:35:26 +03:00
AKurakin
ea561b9a85 backend-api http://jira.mfd.msk:8088/browse/CLS-64 UserSettingsController.java 2023-06-15 18:26:21 +03:00
AKurakin
ef187881b2 dbf-importer SDf57Table unixtime Ext_date 2023-06-15 18:19:01 +03:00
ialbert
ca05eb96c0 пример переноса логики сессии первичных торгов Bn на Spring State Machine 2023-06-15 17:14:49 +03:00
AKurakin
f7cd2307a5 clearing-validation добавил валидацию на инициализацию валидатора 2023-06-15 17:09:37 +03:00
AKurakin
18b0c66920 account-service http://jira.mfd.msk:8088/browse/CLS-265 TradingClearingRegistry правки заполнения и валидации счетов 2023-06-15 17:06:57 +03:00
AKurakin
df5175b2a5 account-service http://jira.mfd.msk:8088/browse/CLS-265 TradingClearingRegistry правки заполнения и валидации счетов 2023-06-15 16:49:05 +03:00
AKurakin
3f35a92afd imdg оптимизация *AccountMapStore 2023-06-15 14:11:24 +03:00
etreschenkov
abaf107700 fix CompanyService 2023-06-14 18:46:38 +03:00
etreschenkov
acbd5c4b05 refactoring gateway 2023-06-14 18:46:38 +03:00
etreschenkov
a8dd8d78ef http://jira.mfd.msk:8088/browse/CLS-301 2023-06-14 18:46:38 +03:00
AKurakin
9292206208 clearing-service http://jira.mfd.msk:8088/browse/CLS-265 Sdf08Executor поправил тип счёта-депо (рефакторинг) 2023-06-14 18:35:48 +03:00
AKurakin
c211870d3f clearing-service http://jira.mfd.msk:8088/browse/CLS-265 Sdf08Executor поправил тип счёта-депо 2023-06-14 17:37:52 +03:00
ialbert
01db30a3bc добавил поднятие сессии из IMDG при старте clearing-service
пофиксил тип сессии для первичных торгов B0
2023-06-13 18:52:16 +03:00
etreshenkov
b1af5cc68f fix bug 2023-06-13 18:38:18 +03:00
etreshenkov
75bf1db1ab remove balance-service from build distr 2023-06-13 17:16:36 +03:00
etreshenkov
2b4c5fef77 fix bug 2023-06-13 17:09:40 +03:00
etreshenkov
0e225d7804 fix init messageResolver bean 2023-06-13 12:14:10 +03:00
etreshenkov
4f8e13ca3c add section to Limit request 2023-06-13 12:03:22 +03:00
psemenkov
d087b1caa7 http://jira.mfd.msk:8088/browse/CLS-316
Поправил заполнение s_df10.client_name.
2023-06-13 11:02:29 +03:00
psemenkov
fe5ff2a422 http://jira.mfd.msk:8088/browse/CLS-316
Поправил заполнение s_df10.client_name.
2023-06-13 10:25:48 +03:00
AKurakin
f1cb711326 securities-service http://jira.mfd.msk:8088/browse/CLS-348 часть 1/3 2023-06-09 20:52:19 +03:00
psemenkov
c94fe7d4db http://jira.mfd.msk:8088/browse/CLS-316
Поправил вывод в лог.
2023-06-09 18:58:07 +03:00
psemenkov
7d47af9e18 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java
2023-06-09 18:51:28 +03:00
psemenkov
5dd546ae4f http://jira.mfd.msk:8088/browse/CLS-316
Поправил ошибку загрузки нескольких строк.
2023-06-09 18:47:33 +03:00
AKurakin
dd151e80d2 clearing-service sdf08 обработка автосоздания счетов. Оказалось что DEPO ужно делать (част 2/2). Поправил транзакции. 2023-06-09 18:23:47 +03:00
AKurakin
872b66984d clearing-service sdf08 обработка автосоздания счетов. Оказалось что DEPO ужно делать (част 1/2) 2023-06-09 17:35:10 +03:00
AKurakin
ad09a31171 clearing-service sdf08 обработка автосоздания счетов 2023-06-09 17:15:50 +03:00
AKurakin
f9fa84ad64 clearing-service sdf08 обработка автосоздания счетов 2023-06-09 16:50:12 +03:00
AKurakin
5cffd47463 company-service http://jira.mfd.msk:8088/browse/CLS-347 MultiCompanyService добавил обновления 2023-06-09 13:44:10 +03:00
AKurakin
79c56c4571 Больше логов SDF08... 2023-06-09 12:15:21 +03:00
psemenkov
8f7a64122c Merge remote-tracking branch 'origin/dev' into dev 2023-06-09 12:11:11 +03:00
psemenkov
b3f5ac1026 http://jira.mfd.msk:8088/browse/CLS-316
Поправил ошибку.
2023-06-09 12:11:04 +03:00
AKurakin
4e795ee832 . 2023-06-09 11:49:21 +03:00
ialbert
f21e7dea88 sdf04 fix 2023-06-09 10:58:58 +03:00
ialbert
e6b32c4943 фикс обработки SDF04 2023-06-09 10:56:31 +03:00
AKurakin
b85247dfaf account-service http://jira.mfd.msk:8088/browse/CLS-265 2023-06-09 10:39:00 +03:00
AKurakin
66cf85a688 account-service fix TCR validation; clearing-service swt-importer логи 2023-06-08 19:29:56 +03:00
AKurakin
12f9d024aa clearing-service sdf08 2023-06-08 18:23:58 +03:00
psemenkov
c62e99fd7d Merge remote-tracking branch 'origin/dev' into dev 2023-06-08 18:02:30 +03:00
psemenkov
754b915aed http://jira.mfd.msk:8088/browse/CLS-262
Поправил ошибку.
2023-06-08 18:02:21 +03:00
ialbert
f759ce4d56 создание PaymentInstruction при обработке сделок для итоговой сессии МКР - блокировка средств 2023-06-08 17:22:48 +03:00
AKurakin
af2c9fac0e account-service http://jira.mfd.msk:8088/browse/CLS-271 TCR правки 2023-06-08 16:44:11 +03:00
etreshenkov
9a1a878513 http://jira.mfd.msk:8088/browse/CLS-313 2023-06-08 16:36:32 +03:00
ialbert
fb77fb7603 создание PaymentInstruction при обработке сделок для итоговой сессии МКР SDF03 Sbanknam 2023-06-08 16:33:26 +03:00
ialbert
5d4005a087 создание PaymentInstruction при обработке сделок для итоговой сессии МКР payeeBic 2023-06-08 16:10:22 +03:00
AKurakin
f45ed7fa1f clearing-service account+sdf01... 2023-06-08 16:03:42 +03:00
AKurakin
7b6a74fd0a clearing-service account-service правки связей счетов и s_df 01, 08. 2023-06-08 16:00:17 +03:00
ialbert
29ecf18e2e создание PaymentInstruction при обработке сделок для итоговой сессии МКР создание SDF03 фикс 2023-06-08 16:00:00 +03:00
ialbert
9d2be448ee создание PaymentInstruction при обработке сделок для итоговой сессии МКР fix payeeBic 2023-06-08 15:56:30 +03:00
ialbert
2319f1a345 создание PaymentInstruction при обработке сделок для итоговой сессии МКР поля AdresseeBic/PayeeBic 2023-06-08 15:09:13 +03:00
ialbert
5ed749dbab создание PaymentInstruction при обработке сделок addresseId 2023-06-08 15:00:07 +03:00
AKurakin
768ba7c47f clearing-service account-service правки создания ClearingAccount 2023-06-08 14:46:02 +03:00
ialbert
f5a7842ab1 создание PaymentInstruction по возвратам для итоговой сессии МКР условия и поля 2023-06-08 14:42:37 +03:00
ialbert
4e283ff5e8 ialbert 3 minutes ago создание PaymentInstruction для итоговой МКР по сделкам bugfix 2023-06-08 14:32:50 +03:00
ialbert
62c92ea4b3 создание PaymentInstruction для итоговой МКР по сделкам bugfix 2023-06-08 14:29:47 +03:00
AKurakin
621069c933 account-service http://jira.mfd.msk:8088/browse/CLS-271 поправил зацикливание и создание счёта по SDF-01 2023-06-08 14:11:39 +03:00
ialbert
d8e519c838 итоговая МКР создание PaymentInstruction по сделкам bugfix 2023-06-08 14:00:04 +03:00
ialbert
e7d2b420d4 формирование PaymentInstruction для сделок итоговой МКР logs 2023-06-08 13:36:26 +03:00
ialbert
ef17c60c58 итоговая МКР добавил создание PaymentInstruction по возврату
поправил отправку SDF03
2023-06-08 13:33:02 +03:00
etreshenkov
14c4dc58f2 http://jira.mfd.msk:8088/browse/CLS-301 2023-06-08 12:43:39 +03:00
psemenkov
420bfca7d1 Merge remote-tracking branch 'origin/dev' into dev 2023-06-08 12:40:03 +03:00
psemenkov
04b5498542 http://jira.mfd.msk:8088/browse/CLS-321
Поправил ошибки.
2023-06-08 12:39:52 +03:00
ialbert
7abf031246 ReturnDepositSession убрал условие на sessionType при включении в пул 2023-06-07 17:11:20 +03:00
psemenkov
d3fc4ae105 http://jira.mfd.msk:8088/browse/CLS-321
Изменил директорию для уведомлений.
2023-06-07 17:00:39 +03:00
ialbert
7bda8ea334 итоговая МКР условия выборки регистров на шаге 4 2023-06-07 16:04:45 +03:00
psemenkov
2f2d99e7ce Merge remote-tracking branch 'origin/dev' into dev 2023-06-07 16:04:08 +03:00
psemenkov
e049752508 http://jira.mfd.msk:8088/browse/CLS-321
Реализовал формирование уведомлений newInfoAccount и newTradingClearingRegistry.
2023-06-07 16:02:13 +03:00
ialbert
c99fa30bbd создание PaymentInstruction при обработке сделок для итоговой сессии МКР 2023-06-07 15:10:11 +03:00
ialbert
56719d4d37 фикс D регистров при обработке Sdf57 2023-06-07 12:13:34 +03:00
etreshenkov
9a3cb66037 fix creating registryD by sdf57 2023-06-06 19:01:21 +03:00
AKurakin
c6d047a7ea gateway-api временно убрал валидацию GatewayController 2023-06-06 18:38:17 +03:00
AKurakin
7a01ffc6c0 company-service http://jira.mfd.msk:8088/browse/CLS-347 ... 2023-06-06 18:02:55 +03:00
AKurakin
865af17158 company-service http://jira.mfd.msk:8088/browse/CLS-347 ока только new заделал. Доделать update, transaction 2023-06-06 17:58:05 +03:00
etreshenkov
5129a05bb8 send one package with all info about company to company-service 2023-06-06 17:39:53 +03:00
AKurakin
5c2c600d46 gateway-api company-service MultiCompanyRequest Начало. 2023-06-06 16:26:11 +03:00
aalehin
333d935a26 http://jira.mfd.msk:8088/browse/CLS-339
---
refactor from code review
2023-06-06 16:23:14 +03:00
AKurakin
6bb00569d3 company-service relation удаление по ClearingMemberCategory (правильно понял ТЗ) 2023-06-06 13:04:16 +03:00
ialbert
41c414497d убрал для итоговой МКР провверку обязательств по бумагам в шаге 5
добавил обновление статусов регистров в FAIL по второму дню в шаге 5
2023-06-06 12:55:10 +03:00
etreshenkov
c7a752120d fix logging request 2023-06-06 12:37:47 +03:00
AKurakin
e99d83fb4f company-service http://jira.mfd.msk:8088/browse/CLS-259 часть правок (доделать relation) 2023-06-05 20:42:24 +03:00
AKurakin
3db1ef31b8 meta правки опечаток 2023-06-05 19:32:10 +03:00
AKurakin
bff41c81f9 securities-service . 2023-06-05 18:58:22 +03:00
AKurakin
a036261319 securities-service http://jira.mfd.msk:8088/browse/CLS-326 2023-06-05 18:53:43 +03:00
akulikov
2254f94de7 http://jira.mfd.msk:8088/browse/CLS-301 2023-06-05 18:15:57 +03:00
AKurakin
ae37e501f6 securities-service http://jira.mfd.msk:8088/browse/CLS-258 оправил заполнение поля 2023-06-05 18:12:33 +03:00
ialbert
c10dd23a38 убрал проверку account#relationId при валидации регистров на шаге сессии ObligationAdmission 2023-06-05 18:07:57 +03:00
aalehin
9c3e8737a0 http://jira.mfd.msk:8088/browse/CLS-339
---
NotificationService set up
2023-06-05 17:42:41 +03:00
ialbert
415d5697d8 session closing 2023-06-05 17:06:45 +03:00
etreshenkov
56e3507e26 fix registry builders 2023-06-05 14:00:34 +03:00
etreshenkov
c8f7f5212e fix registry builders 2023-06-05 13:09:17 +03:00
ialbert
e3352e6fdf privamr 2023-06-05 12:25:12 +03:00
etreshenkov
989dcdec73 fix registry builders 2023-06-05 12:24:23 +03:00
ialbert
629b8c63aa deposit/fond registry builder 2023-06-05 12:17:44 +03:00
etreshenkov
0f7a017a8d fix registry builders 2023-06-05 12:13:41 +03:00
ialbert
d26ee55b55 fond/deposit registry builder 2023-06-05 12:05:08 +03:00
etreshenkov
46d87a046e fix registry builders 2023-06-05 11:13:54 +03:00
akulikov
89c8dc7434 http://jira.mfd.msk:8088/browse/CLS-301 2023-06-04 14:27:12 +03:00
akulikov
501a160f14 http://jira.mfd.msk:8088/browse/CLS-301 2023-06-04 14:24:02 +03:00
AKurakin
46c6d73cd9 company-service account-service http://jira.mfd.msk:8088/browse/CLS-284 ACCOUNT_TERMINATION/ACCOUNT_TERMINATION_STEP2 2023-06-02 20:24:46 +03:00
etreschenkov
f046ffb3ab fix FinalMkrSession 2023-06-02 20:11:14 +03:00
etreschenkov
e2a0f33012 add payload to paymentInstructionForming for every session 2023-06-02 17:57:20 +03:00
AKurakin
e5dc6d4487 company-service http://jira.mfd.msk:8088/browse/CLS-284 rreellaattiioonn 2023-06-02 17:17:09 +03:00
ialbert
3310559df6 FormingPaymentInstructionDepositReturn.java 2023-06-02 16:25:31 +03:00
aalehin
21d959740f http://jira.mfd.msk:8088/browse/CLS-280
---
fix up
2023-06-02 15:33:06 +03:00
ialbert
6536852791 PaymentInstructions for deposit return session 2023-06-02 15:12:43 +03:00
aalehin
a57907dc9d http://jira.mfd.msk:8088/browse/CLS-280
---
refactoring
2023-06-02 15:10:26 +03:00
etreschenkov
6139772966 fix sdf-4 bugs 2023-06-02 14:02:53 +03:00
etreschenkov
2cab7c7b5a fix sdf-4 bugs 2023-06-02 13:49:44 +03:00
AKurakin
c564373382 account-service http://jira.mfd.msk:8088/browse/CLS-271 добавление оповещений о TradingClearingRegistryService 2023-06-02 10:45:28 +03:00
AKurakin
b30f01e3eb account-service http://jira.mfd.msk:8088/browse/CLS-271 добавление оповещений о TradingClearingRegistryService 2023-06-02 10:33:05 +03:00
akulikov
d62829f3b1 http://jira.mfd.msk:8088/browse/CLS-283 some fixes 2023-06-01 21:21:40 +03:00
AKurakin
c929b196b1 account-service http://jira.mfd.msk:8088/browse/CLS-271 добавление оповещений о TradingClearingRegistryService 2023-06-01 20:11:15 +03:00
AKurakin
a7fd8dc0ab company-service RelationService оправил проверку статусов 2023-06-01 18:56:32 +03:00
AKurakin
f4517b7736 securities-service http://jira.mfd.msk:8088/browse/CLS-326 часть правок 2023-06-01 18:46:45 +03:00
AKurakin
bd8af7fc16 account-service http://jira.mfd.msk:8088/browse/CLS-272 http://jira.mfd.msk:8088/browse/CLS-271 2023-06-01 18:46:24 +03:00
aalehin
903fed53b3 http://jira.mfd.msk:8088/browse/CLS-280
---
execution register
2023-06-01 18:07:54 +03:00
aalehin
0db6f75823 http://jira.mfd.msk:8088/browse/CLS-280
---
fix up
2023-06-01 18:07:54 +03:00
aalehin
dab63ad8be http://jira.mfd.msk:8088/browse/CLS-280
---
fix up
2023-06-01 18:07:54 +03:00
aalehin
5fa0bcd9be http://jira.mfd.msk:8088/browse/CLS-316
---
fix up
2023-06-01 18:07:53 +03:00
etreshenkov
226c33faaf creation DF-03/12 by PaymentInstruction 2023-06-01 17:46:48 +03:00
etreshenkov
a8eaf758c4 creation DF-03/12 by PaymentInstruction 2023-06-01 17:33:55 +03:00
AKurakin
42b26f4988 account-service http://jira.mfd.msk:8088/browse/CLS-265 2023-06-01 17:18:49 +03:00
ialbert
e9a1b245f1 ReturnDepositSession XDEP 2023-06-01 16:39:40 +03:00
etreshenkov
36e8d5f096 creation DF-03/12 by PaymentInstruction 2023-06-01 16:37:59 +03:00
etreshenkov
0987180bd3 fix stage 7 2023-06-01 16:37:00 +03:00
ialbert
8955aafdb9 ReturnDepositSession 2023-06-01 15:44:48 +03:00
AKurakin
c040188512 account-service http://jira.mfd.msk:8088/browse/CLS-271 TradingClearingRegistryService Что с кодом? Такой баг я где-то уже правил. Как тогда на тесте смогли что-то сделать? 2023-06-01 15:23:00 +03:00
etreshenkov
fa09badd70 fix reset balance 2023-06-01 14:35:01 +03:00
etreshenkov
c5d8260b38 fix stage 7 2023-06-01 14:07:05 +03:00
AKurakin
283e623f19 backend-api meta валидация Listing*Action 2 2023-06-01 14:05:05 +03:00
AKurakin
131c32978c backend-api meta валидация Listing*Action 2023-06-01 13:14:19 +03:00
etreshenkov
d1a9462029 fix stage 7 2023-06-01 13:06:14 +03:00
akulikov
baa61228fa http://jira.mfd.msk:8088/browse/CLS-301 some fixes 2023-06-01 12:36:13 +03:00
AKurakin
3a887732ac securities-service оправил параметры текста ошибки в SpecialIdPresentRule 2023-06-01 12:22:03 +03:00
AKurakin
d734d02a14 securities-service ListingValidation fix 2 2023-06-01 12:03:53 +03:00
AKurakin
f93525823a securities-service ListingValidation fix 2023-06-01 11:44:41 +03:00
AKurakin
07ffb36104 securities-service исправление e70cbc108d 2023-06-01 09:57:34 +03:00
AKurakin
5c3cc9265e platform-messaging debug log++ 2023-05-31 20:28:15 +03:00
AKurakin
86b9bd095f company-service ClearingMemberCategoryService -> RelationService правки взаимодествия 2023-05-31 20:22:36 +03:00
etreschenkov
a622fccc71 fix stage 7 2023-05-31 19:25:12 +03:00
etreschenkov
6af1575053 fix stage 7 2023-05-31 19:14:40 +03:00
aalehin
7b7baf52d3 http://jira.mfd.msk:8088/browse/CLS-280
---
update
2023-05-31 18:51:18 +03:00
AKurakin
750d5c1e76 company-service CompanyService CompanyInfo заполнение (начало) 2023-05-31 18:36:40 +03:00
etreschenkov
e1dea39b1f fix stage 5 2023-05-31 18:35:30 +03:00
ialbert
74697eb48f InclusionObligations 2023-05-31 18:14:05 +03:00
AKurakin
e224a4ffb7 account-service http://jira.mfd.msk:8088/browse/CLS-272 ClientCodeService, TradingClearingRegistryService 2023-05-31 18:05:46 +03:00
etreschenkov
2a873a22b3 http://jira.mfd.msk:8088/browse/CLS-328 2023-05-31 17:46:32 +03:00
AKurakin
53a574f34f securities-service http://jira.mfd.msk:8088/browse/CLS-326 Listing-валидация. 2023-05-31 16:52:52 +03:00
ialbert
14915bf450 ExecutionDeposit - always money 2023-05-31 16:25:33 +03:00
ialbert
15d950bee8 privamr 2023-05-31 16:09:49 +03:00
etreschenkov
37bc4b72cd add check on exist sdf57 record by dbfId 2023-05-31 15:57:51 +03:00
ialbert
1621a3cfb9 DealsPrepare session stage tradingDate condition 2023-05-31 15:56:50 +03:00
ialbert
50201be458 final MKR deals conditions 2023-05-31 15:48:19 +03:00
etreschenkov
59d06cd0a8 http://jira.mfd.msk:8088/browse/CLS-303 2023-05-31 15:36:29 +03:00
AKurakin
329e2dda28 IMDGMessageResolver добавил номер ошибки в текст 2023-05-31 15:30:27 +03:00
etreschenkov
29b7bd7f38 http://jira.mfd.msk:8088/browse/CLS-303 2023-05-31 15:25:51 +03:00
etreschenkov
e641510e7c http://jira.mfd.msk:8088/browse/CLS-303 2023-05-31 14:51:42 +03:00
ialbert
8255f4a1eb sdf57 executor 2023-05-31 14:39:06 +03:00
AKurakin
e70cbc108d security-util SecuritySelector 2023-05-31 14:38:25 +03:00
etreschenkov
addf59853e http://jira.mfd.msk:8088/browse/CLS-303 2023-05-31 14:20:07 +03:00
akulikov
93fb2eaa07 http://jira.mfd.msk:8088/browse/CLS-301 fix send securities, test added 2023-05-31 14:09:29 +03:00
ialbert
9360387bd0 registries B/F для sdf57 executor 2023-05-31 13:55:18 +03:00
etreschenkov
0a2e7ca09a http://jira.mfd.msk:8088/browse/CLS-303 2023-05-31 13:50:25 +03:00
ialbert
f52f5fe304 sdf57 executor clearing-service 2023-05-31 13:16:17 +03:00
AKurakin
2527755afc imdg добавление некоторых History 2023-05-31 12:28:53 +03:00
akulikov
7e8566cb14 http://jira.mfd.msk:8088/browse/CLS-301 swagger fix 2023-05-31 11:33:12 +03:00
AKurakin
d5c6123575 scheduler-service dbf-exporter http://jira.mfd.msk:8088/browse/CLS-268 параметры запуска, валидация. Task.java 2023-05-31 11:31:43 +03:00
AKurakin
eebfd0b16a meta 3.5.0.31 2023-05-31 11:14:47 +03:00
etreschenkov
79c3c9bdad Merge branch 'sdf08' into dev 2023-05-31 10:45:44 +03:00
akulikov
24e9b4f548 http://jira.mfd.msk:8088/browse/CLS-301 swagger and validate common request 2023-05-30 20:59:36 +03:00
akulikov
587da25d0c http://jira.mfd.msk:8088/browse/CLS-301 fix bad logic and search company for company symbols, if company not found in request 2023-05-30 20:02:44 +03:00
975 changed files with 64000 additions and 15034 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

@ -12,18 +12,18 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAcco
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest;
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.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
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.enumeration.WorkflowStatus;
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.IErrorEnumId;
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;
@ -57,10 +57,16 @@ public class AccountValidationConfig {
AccountError.CompanyNotFound
// company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive
),
FieldRequiredRule.instance("account",
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
);
@ -70,29 +76,37 @@ public class AccountValidationConfig {
ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null;
return AccountError.AccountAlreadyExist;
return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}),
DictionaryPresentRule.instance("status",
CorrespondentAccountNewRequest::getStatus,
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)
);
};
}
@ -115,13 +129,7 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
account -> {
// проверка на заблокированность счёта
if (!AccountStatus.ACTIVE.getKey().equalsIgnoreCase(account.getStatus()))
return AccountError.AccountNotActive;
return null;
}),
AccountError.AccountNotFound),
IdPresentRule.instance("companyId",
CorrespondentAccountUpdateRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
@ -130,26 +138,29 @@ public class AccountValidationConfig {
AccountError.CompanyNotFound,
false,
company -> {
IErrorEnumId error = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive;
error = Objects.equals(company.getId(), correspondentAccountUpdateRequest.getCompanyId()) ? error : AccountError.WrongFieldValue;
return error;
if (Objects.equals(company.getId(), correspondentAccountUpdateRequest.getCompanyId()))
return null;
return AccountError.WrongFieldValue;
}),
DictionaryPresentRule.instance("status",
CorrespondentAccountUpdateRequest::getStatus,
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;
// }
)
);
};
}
@ -164,15 +175,16 @@ public class AccountValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Account);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
IdPresentSpecificRule.instance("id",
CommonIdRequest::getId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
account -> {
if (WorkflowStatus.Active.equalsByKey(account.getStatus())) return null;
return AccountError.AccountNotActive;
if (AccountStatus.BLOCKED.equalsByKey(account.getStatus()))
return new EnumMessage(AccountError.AccountNotActive, account.getAccount());
return null;
})
);
};

View file

@ -6,23 +6,24 @@ import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
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.BankAccountNewRequest;
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;
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.enumeration.WorkflowStatus;
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;
@ -45,6 +46,7 @@ public class BankAccountValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_BankAccount);
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary);
return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId",
@ -54,36 +56,30 @@ public class BankAccountValidationConfig {
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound,
false),
FieldRequiredRule.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 AccountError.AccountAlreadyExist;
}),
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),
FieldRequiredRule.instance("bankName",
BankAccountNewRequest::getBankName,
AccountError.RequiredFieldEmpty)
AccountError.RequiredFieldEmpty),
DictionaryPresentRule.instance("status",
BankAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
);
};
}
@ -122,7 +118,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_CurrencyCodeDictionary,
CurrencyCodeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};
@ -139,7 +135,7 @@ public class BankAccountValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_BankAccount);
addImdg.accept(IMDGDistributedNames.Map_Account);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
IdPresentSpecificRule.instance("id",
CommonIdRequest::getId,
IMDGDistributedNames.Map_BankAccount,
BankAccount.class,
@ -151,8 +147,10 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_Account, Account.class
);
Account account = accountImdg.getSingleObjectByID(accountId);
if (account == null) return AccountError.AccountNotFound;
if (!AccountStatus.ACTIVE.equalsByKey(account.getStatus())) return AccountError.AccountNotActive;
if (account == null)
return new EnumMessage(AccountError.AccountNotFound, accountId);
if (AccountStatus.BLOCKED.equalsByKey(account.getStatus()))
return new EnumMessage(AccountError.AccountNotActive, account.getAccount());
return null;
})
);

View file

@ -5,17 +5,19 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary;
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.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;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@ -43,6 +45,7 @@ public class ClearingAccountValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_ClearingAccount);
addImdg.accept(IMDGDistributedNames.Map_ClearingAccountTypeDictionary);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId",
ClearingAccountNewRequest::getCompanyId,
@ -52,30 +55,23 @@ public class ClearingAccountValidationConfig {
AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
),
FieldRequiredRule.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 AccountError.AccountAlreadyExist;
}),
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.DictionaryNotFound,
false)
);
};
}
@ -98,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
);
@ -126,7 +124,7 @@ public class ClearingAccountValidationConfig {
Imdg<Company> companyImdg = context.obtainMap(
IMDGDistributedNames.Map_Company, Company.class
);
Company company = companyImdg.getSingleObjectByFieldValues(Map.of("tradingCode", dealValue));
Company company = companyImdg.getFirstObjectByFieldValues(Map.of("tradingCode", dealValue));
if (company == null) return AccountError.WrongFieldValue;
return null;
})

View file

@ -5,8 +5,7 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
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.ClientCodeNewRequest;
@ -38,7 +37,7 @@ public class ClientCodeValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, AccountError.RequiredFieldEmpty),
IdPresentRule.instance("companyId",
@ -72,8 +71,8 @@ public class ClientCodeValidationConfig {
DictionaryPresentRule.instance("stauts",
ClientCodeNewRequest::getStatus,
IMDGDistributedNames.Map_WorkflowStatusDictionary,
WorkflowStatusDictionary.class,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
@ -91,7 +90,7 @@ public class ClientCodeValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<ImdgValidationContext<ClientCodeUpdateRequest>>(context,
IdPresentRule.instance("id",
ClientCodeUpdateRequest::getId,
@ -132,8 +131,8 @@ public class ClientCodeValidationConfig {
DictionaryPresentRule.instance("stauts",
ClientCodeUpdateRequest::getStatus,
IMDGDistributedNames.Map_WorkflowStatusDictionary,
WorkflowStatusDictionary.class,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)

View file

@ -4,18 +4,18 @@ 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.company.Company;
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.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.enumeration.WorkflowStatus;
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.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -39,6 +39,7 @@ public class DepoAccountValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_DepoAccount);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId",
DepoAccountNewRequest::getCompanyId,
@ -48,27 +49,20 @@ public class DepoAccountValidationConfig {
AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
),
FieldRequiredRule.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 AccountError.AccountAlreadyExist;
}),
AccountError.RequiredFieldEmpty),
new SameAccountValidationRule<>(AccountType.Depo, DepoAccountNewRequest::getAccount),
FieldRequiredRule.instance("depoAccountType",
DepoAccountNewRequest::getDepoAccountType,
AccountError.RequiredFieldEmpty)
AccountError.RequiredFieldEmpty),
DictionaryPresentRule.instance("status",
DepoAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
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

@ -2,10 +2,10 @@ 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.ClearingAccount;
import ru.clearing.classes.statics.data.account.Account;
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.errors.AccountError;
@ -16,14 +16,22 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingR
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CompanySymbol;
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.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
@ -39,32 +47,63 @@ public class TradingClearingRegistryValidationConfig {
context.setValidatedObject(tradingClearingRegistryNewRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbols);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_ClearingAccount);
addImdg.accept(IMDGDistributedNames.Map_DepoAccount);
addImdg.accept(IMDGDistributedNames.Map_InformationAccount);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId",
IdPresentSpecificRule.instance("companyId",
TradingClearingRegistryNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound),
AccountError.CompanyNotFound,
true,
company -> {
Imdg<CompanySymbols> companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
CompanySymbols symbol = companySymbolsImdg.getFirstObjectByFieldValues(Map.of(
"companyId", company.getId(),
"companySymbol", CompanySymbol.CLRC.getKey()
));
if (symbol == null)
return new EnumMessage(AccountError.ClearingCompanySymbolNotFound, company.getShortName());
return null;
}),
FieldRequiredRule.instance("moneyAccountId",
TradingClearingRegistryNewRequest::getMoneyAccountId,
AccountError.RequiredFieldEmpty,
moneyAccountId -> {
Imdg<ClearingAccount> clearingAccountImdg = context.obtainMap(
IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(moneyAccountId);
if (clearingAccount == null) {
Imdg<InformationAccount> informationAccountImdg = context.obtainMap(
IMDGDistributedNames.Map_InformationAccount, InformationAccount.class
);
InformationAccount infoAccount = informationAccountImdg.getSingleObjectByID(moneyAccountId);
if (infoAccount == null) return AccountError.AccountNotFound;
Account account = accountImdg.getSingleObjectByID(moneyAccountId);
if (account == null) {
return AccountError.AccountNotFound;
} else {
if (AccountType.Clrn.equalsByKey(account.getAccountType()) || AccountType.Info.equalsByKey(account.getAccountType())) {
// ok
} else {
// неправильный тип
return AccountError.AccountNotFound;
}
}
// Imdg<ClearingAccount> clearingAccountImdg = context.obtainMap(
// IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
// );
// ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByFieldValues(
// Map.of("accountId",moneyAccountId)
// );
// if (clearingAccount == null) {
// Imdg<InformationAccount> informationAccountImdg = context.obtainMap(
// IMDGDistributedNames.Map_InformationAccount, InformationAccount.class
// );
// InformationAccount infoAccount = informationAccountImdg.getSingleObjectByFieldValues(
// Map.of("accountId",moneyAccountId));
// if (infoAccount == null) return AccountError.AccountNotFound;
// }
return null;
}),
FieldRequiredRule.instance("depoAccountId",
@ -74,7 +113,9 @@ public class TradingClearingRegistryValidationConfig {
depoAccountId -> {
if (depoAccountId == null) return null;
Imdg<DepoAccount> depoAccountImdg = context.obtainMap(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
DepoAccount depoAccount = depoAccountImdg.getSingleObjectByID(depoAccountId);
DepoAccount depoAccount = depoAccountImdg.getFirstObjectByFieldValues(
Map.of("accountId", depoAccountId)
);
if (depoAccount == null) return AccountError.AccountNotFound;
return null;
}),
@ -83,17 +124,49 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
false,
statusValue -> {
String statusCode = statusValue.getCode();
if (ServiceStatus.Active.equalsByKey(statusCode)) return null;
return AccountError.WrongFieldValue;
})
AccountError.DictionaryNotFound,
false),
new newTCRDuplicateCheck()
);
};
}
static class newTCRDuplicateCheck implements IValidationRule<ImdgValidationContext<TradingClearingRegistryNewRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TradingClearingRegistryNewRequest> context) {
TradingClearingRegistryNewRequest validatedObject = context.getValidatedObject();
Imdg<TradingClearingRegistry> tcrMap = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
if (validatedObject.getMoneyAccountId() == null) {
return of(AccountError.RequiredFieldEmpty, "MoneyAccountId");
}
//Map<String, Comparable<?>> query = new HashMap<>();
// query.put("moneyAccountId", validatedObject.getMoneyAccountId());
// if (validatedObject.getDepoAccountId() != null) {
// query.put("depoAccountId", validatedObject.getDepoAccountId());
// }
ImdgPredicateBuilder pb = tcrMap.predicateBuilder();
ImdgPredicate query = pb.equals("moneyAccountId", validatedObject.getMoneyAccountId());
if (validatedObject.getDepoAccountId() != null) {
query = pb.or(query, pb.equals("depoAccountId", validatedObject.getDepoAccountId()));
}
Collection<TradingClearingRegistry> existTCR = tcrMap.getCollectionObjectsByPredicate(query);
if (existTCR.isEmpty()) {
return empty();
} else {
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account account = accountImdg.getSingleObjectByID(validatedObject.getMoneyAccountId());
if (account == null && validatedObject.getDepoAccountId() != null) account = accountImdg.getSingleObjectByID(validatedObject.getDepoAccountId());
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, account.getAccount());
// String tcrIds = existTCR.stream().map(tcr -> String.valueOf(tcr.getId())).collect(Collectors.joining(";"));
// return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, tcrIds);
}
}
}
@Bean("tradingClearingRegistryUpdateRequest")
public Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
@ -116,7 +189,7 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.*;
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.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.*;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -28,6 +29,7 @@ public class ValidationConfig {
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass));
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
addImdg.accept(IMDGDistributedNames.Map_ClearingAccountTypeDictionary, ClearingAccountTypeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_Account, Account.class);
@ -39,9 +41,9 @@ 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_WorkflowStatusDictionary, WorkflowStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
return imdg;

View file

@ -19,7 +19,11 @@ public enum AccountError implements IErrorEnumId {
DepoAccountNotFound(5017L),
MoneyAccountNotFound(5018L),
ClearingCategoryNotFound(5019L),
TradingClearingRegistryNotFound(5022L),
ClearingCompanySymbolNotFound(5022L), // Для компании %s отсутствует клиринговый код».
AccountForTradingClearingRegistryAlreadyUsed(5023L),
AccountFieldNotSet(5024L),
AccountDepoTypeRequired(5025L),
TradingClearingRegistryNotFound(3022L),
;
private final Long id;

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,18 @@ 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.account.sdf01.AccountTerminationRequest;
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.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -41,14 +40,14 @@ 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
public class AccountService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final Imdg<Account> accountMap;
private final Imdg<ClearingMemberCategory> clearingMemberCategoryMap;
private final Imdg<Relation> relationMap;
@ -56,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;
@ -68,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")
@ -75,6 +78,8 @@ 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
);
@ -88,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;
@ -95,9 +101,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
@Override
public void afterPropertiesSet() {
callback(AccountSdf01Request.class)
.setFunction(this::accountNewSdf01)
.forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put);
imdgProvider.waitAvailable();
callback(CorrespondentAccountNewRequest.class)
.setFunction(this::accountCorrespondentNew)
.forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_NEW, callbacks::put);
@ -107,6 +111,10 @@ public class AccountService extends QueueConsumer implements InitializingBean {
callback(CommonIdRequest.class)
.setFunction(this::correspondentAccountBlock)
.forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_BLOCK, callbacks::put);
callback(AccountTerminationRequest.class)
.setFunction(this::accountTerminationForCompany)
.forDestination(Consts.ACCOUNT_TERMINATION, callbacks::put);
init();
}
@ -126,19 +134,105 @@ 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());
account.setStatus(req.getStatus());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
log.trace("Status not set in request. Use default: {}", account.getStatus());
} else {
account.setStatus(req.getStatus());
}
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");
@ -151,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());
@ -183,98 +281,45 @@ public class AccountService extends QueueConsumer implements InitializingBean {
return null;
}
@Deprecated
public RequestInfoUpdate accountNewSdf01(BaseRequest<AccountSdf01Request> userRequest) {
log.debug("AccountSdf01Request received");
AccountSdf01Request req = userRequest.getRequestPayload();
List<AccountSdfToStatementRequestPart> accountToStatement = new ArrayList<>();
for (AccountSdfRequestPart accountReq : req.getAccounts()) {
Account account = new Account();
account.setAccount(accountReq.getAccount());
account.setCompanyId(accountReq.getCompanyId());
account.setAccountType(accountReq.getAccountType());
accountMap.insert(account);
AccountSdfToStatementRequestPart responsePart = responsePart(accountReq.getSdfId());
accountToStatement.add(responsePart);
}
sendStatementRequestBack(req.getGroupingSdf01Id(), accountToStatement);
log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size());
public RequestInfoUpdate accountTerminationForCompany(BaseRequest<AccountTerminationRequest> userRequest) {
log.debug("AccountTerminationRequest received, id={}", userRequest.getId());
return null;
}
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate; // never - system
public void accountUpdateWithBrake(BaseRequest<AccountSdf01Request> userRequest) {
}
public AccountSdfToStatementRequestPart responsePart(Long sdf01Id) {
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(sdf01Id);
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
return responsePart;
}
@Deprecated
public void sendStatementRequestBack(Long groupingSdf01Id, List<AccountSdfToStatementRequestPart> results) {
StatementRequest request = new StatementRequest();
request.setGroupId(groupingSdf01Id);
request.setAccountCreationResults(results);
log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request);
}
/**
* Заполняет поля 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)");
AccountTerminationRequest req = userRequest.getRequestPayload();
final Long companyId = req.getCompanyId();
Collection<Account> accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId);
log.trace("Found {} accounts (will be terminated) by company {}", accounts.size(), companyId);
int blockCount = 0;
ImdgTransaction tx = imdgProvider.newTransaction();
boolean txOk = false;
try {
tx.beginTransaction();
for (Account account : accounts) {
//Account account = accountMap.getSingleObjectByID(request.getId());
if (!ServiceStatus.Blocked.equalsByKey(account.getStatus())) {
account.setStatus(ServiceStatus.Blocked.getKey());
account.setUpdated(Instant.now());
accountMap.update(account);
blockCount++;
}
}
finalRelationPredicate = relationPredicateBuilder.and(consumerIdPredicate, servicePredicate);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
} else {
finalRelationPredicate = relationPredicateBuilder.equals("consumerId", companyId);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
txOk = true;
} finally {
if (txOk)
tx.commitTransaction();
else
tx.beginTransaction();
}
log.debug("For company {} block {} account (of {} account)", companyId, blockCount, accounts.size());
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());
Long reqId = kafkaSender.sendRequestToQueue(Consts.ACCOUNT_TERMINATION_STEP2, req);
log.info("On termination request id={} send to next step {} new request id={}",
userRequest.getId(), Consts.ACCOUNT_TERMINATION_STEP2, reqId);
log.debug("successfully processed, account termination");
return null;
}

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

@ -22,6 +22,7 @@ import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
@ -40,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;
@ -52,13 +53,13 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
ImdgProvider imdgProvider,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
AccountService accountService,
AccountHelper accountService,
@Qualifier("bankAccountNewRequestValidator")
Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator,
Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator,
@Qualifier("bankAccountUpdateRequestValidator")
Function<BankAccountUpdateRequest, IValidator> bankAccountUpdateRequestValidator,
Function<BankAccountUpdateRequest, IValidator> bankAccountUpdateRequestValidator,
@Qualifier("bankAccountBlockRequestValidator")
Function<CommonIdRequest, IValidator> bankAccountBlockRequestValidator) {
Function<CommonIdRequest, IValidator> bankAccountBlockRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.bankAccountMap = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
this.accountMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
@ -101,7 +102,12 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
Account account = new Account();
account.setAccount(req.getAccount());
account.setAccountType(AccountType.Bank.getKey());
account.setStatus(ServiceStatus.Active.getKey());
if (req.getStatus() == null) {
log.trace("Status not set in request. Use default: {}", account.getStatus());
account.setStatus(WorkflowStatus.Active.getKey());
} else {
account.setStatus(req.getStatus());
}
account.setCompanyId(req.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
@ -114,6 +120,8 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
Imdg<BankAccount> bankAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
Imdg<Account> accountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountId = accountMap.insert(account);
BankAccount bankAccount = new BankAccount();
@ -174,6 +182,8 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
Imdg<BankAccount> bankAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
Imdg<Account> accountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountMap.update(account);
bankAccountMap.update(bankAccount);
txOk = true;
@ -188,7 +198,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
bankAccount.getId(),
account.getId());
imdgTransaction.rollbackTransaction();
}
}
}
log.debug("successfully update, existing bankAccount with id {}", bankAccount.getId());
return null;
@ -209,27 +219,10 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
Account account = accountMap.getSingleObjectByID(bankAccount.getAccountId());
account.setStatus(ServiceStatus.Blocked.getKey());
account.setUpdated(Instant.now());
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
accountMap.update(account);
//без изменений bankAccountMap.update(bankAccount);
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
log.debug("successfully processed, new bank account id {}, account id {}",
bankAccount.getId(),
account.getId());
} else {
log.debug("failed block, bank account id {}, new account id {}",
bankAccount.getId(),
account.getId());
imdgTransaction.rollbackTransaction();
}
}
accountMap.update(account);
//без изменений bankAccountMap.update(bankAccount);
log.debug("successfully block, existing bankAccount with id {}", bankAccount.getId());
return null;
}

View file

@ -1,5 +1,7 @@
package ru.spcex.clearing.account.service;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
@ -10,71 +12,105 @@ 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.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;
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.registry.TradingClearingRegistryNewRequest;
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.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;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
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;
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.IErrorEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.Map;
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;
private final Imdg<Account> accountImdg;
private final Imdg<ClearingAccount> clearingAccountImdg;
private final IMessageResolver messageResolver;
private final RequestHelper requestHelper;
private final Function<ClearingAccountNewRequest, IValidator> clearingAccountNewRequestValidator;
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,
IMessageResolver messageResolver,
RequestHelper requestHelper,
@Qualifier("clearingAccountNewRequestValidator")
Function<ClearingAccountNewRequest, IValidator> clearingAccountNewRequestValidator,
Function<ClearingAccountNewRequest, IValidator> clearingAccountNewRequestValidator,
@Qualifier("clearingAccountUpdateRequestValidator")
Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator) {
Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator) {
super(kafkaQueue, kafkaResponseQueue);
this.kafkaSender = kafkaSender;
this.accountService = accountService;
this.sdfProcessService = sdfProcessService;
this.validationHelper = validationHelper;
this.imdgProvider = imdgProvider;
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
this.messageResolver = messageResolver;
this.requestHelper = requestHelper;
this.clearingAccountNewRequestValidator = clearingAccountNewRequestValidator;
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
@ -85,6 +121,17 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
callback(ClearingAccountUpdateRequest.class)
.setFunction(this::clearingAccountUpdate)
.forDestination(Consts.DESTINATION_CLEARING_ACCOUNT_UPDATE, callbacks::put);
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();
}
@ -100,7 +147,12 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
Account account = new Account();
account.setAccount(req.getAccount());
account.setAccountType(AccountType.Clrn.getKey());
account.setStatus(ServiceStatus.Active.getKey());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
log.trace("Status not set in request. Use default: {}", account.getStatus());
} else {
account.setStatus(req.getStatus());
}
account.setCompanyId(req.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
@ -114,6 +166,8 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
imdgTransaction.beginTransaction();
ClearingAccount clearingAccount = null;
try {
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<ClearingAccount> clearingAccountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
accountId = accountImdg.insert(account);
clearingAccount = new ClearingAccount();
@ -125,12 +179,6 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest();
request.setMoneyAccountId(accountId);
request.setCompanyId(clearingAccount.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW,
LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request);
log.debug("successfully processed, new clearing account id {}, account id {}", clearingAccountId, accountId);
} else {
log.debug("failed insert, new clearing account id {}, new account id {} (if id = -1 then insert is failed)",
@ -149,29 +197,421 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
if (requestInfoUpdate != null) return requestInfoUpdate;
ClearingAccountUpdateRequest req = userRequest.getRequestPayload();
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate accountValuePredicate = pb.equals("account", req.getAccount());
ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey());
ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey());
ImdgPredicate finalPredicate = pb.and(accountValuePredicate,
accountStatusPredicate,
accountTypePredicate);
Account account = accountImdg.getCollectionObjectsByPredicate(finalPredicate).iterator().next();
Long accountId = account.getId();
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<ClearingAccount> clearingAccountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByFieldValues(Map.of("accountId", accountId));
if (clearingAccount == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.AccountNotFound, account.getAccount());
ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate accountValuePredicate = pb.equals("account", req.getAccount());
ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey());
ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey());
ImdgPredicate finalPredicate = pb.and(accountValuePredicate,
accountStatusPredicate,
accountTypePredicate);
Integer statusValue = req.getStatus();
if (statusValue == 0) account.setStatus(ServiceStatus.Blocked.getKey());
else if (statusValue == 1) account.setStatus(ServiceStatus.Active.getKey());
else if (statusValue == 2) account.setStatus(ServiceStatus.Closed.getKey());
account.setUpdated(Instant.now());
Account account = accountImdg.getCollectionObjectsByPredicate(finalPredicate).iterator().next();
Long accountId = account.getId();
accountImdg.update(account);
ClearingAccount clearingAccount = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", accountId));
if (clearingAccount == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.AccountNotFound, account.getAccount());
Integer statusValue = req.getStatus();
if (statusValue == 0) account.setStatus(ServiceStatus.Blocked.getKey());
else if (statusValue == 1) account.setStatus(ServiceStatus.Active.getKey());
else if (statusValue == 2) account.setStatus(ServiceStatus.Closed.getKey());
account.setUpdated(Instant.now());
accountImdg.update(account);
txOk = true;
} finally {
if (txOk) imdgTransaction.commitTransaction();
else imdgTransaction.rollbackTransaction();
}
return null;
}
public RequestInfoUpdate accountNewSdf01(BaseRequest<AccountSdf01Request> userRequest) {
log.debug("AccountSdf01Request received, id={}", userRequest.getId());
AccountSdf01Request req = userRequest.getRequestPayload();
List<AccountSdfToStatementRequestPart> accountToStatement = new ArrayList<>();
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<ClearingAccount> clearingAccountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
accountsLoop:
for (AccountSdfRequestPart accountReq : req.getAccounts()) {
Instant now = Instant.now();
Account account = new Account();
account.setAccount(accountReq.getAccount());
account.setAccountType(AccountType.Clrn.getKey());
account.setStatus(ServiceStatus.Active.getKey());
account.setCompanyId(accountReq.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
RequestInfoUpdate requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) {
log.warn("Error fill new account from relation. {}", /*account.getId(),*/ requestInfoUpdate.getMessage());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(AccountError.ClearingCategoryNotFound.getId()); // see accountService.fillAccountFromRelation
responsePart.setErrorText(requestInfoUpdate.getMessage());
accountToStatement.add(responsePart);
continue accountsLoop;
}
}
if (accountImdg.getFirstObjectBySQL("account = '%s'".formatted(accountReq.getAccount())) != null) {
log.debug("Account {} already exists", accountReq.getAccount());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
accountToStatement.add(responsePart);
continue accountsLoop;
}
}
Long clearingAccountId = -1L;
Long accountId = -1L;
ClearingAccount clearingAccount = null;
accountId = accountImdg.insert(account);
clearingAccount = new ClearingAccount();
clearingAccount.setCompanyId(accountReq.getCompanyId());
clearingAccount.setAccountId(accountId);
clearingAccount.setClearingAccountType(accountReq.getAccountType());
clearingAccountId = clearingAccountImdg.insert(clearingAccount);
log.debug("New account {}, clearingAccount {} was created.", accountId, clearingAccountId);
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
accountToStatement.add(responsePart);
}
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed insert, new clearing accounts. Request id={}", userRequest.getId());
imdgTransaction.rollbackTransaction();
}
}
sendStatementRequestBack(req.getGroupingSdf01Id(), req.getGroupingSdf02Id(), accountToStatement);
log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size());
return null;
}
public RequestInfoUpdate accountUpdateSdf52(BaseRequest<StatementRequest> systemRequest) {
log.debug("accountUpdateSdf52 StatementRequest received, id={}", systemRequest.getId());
StatementRequest req = systemRequest.getRequestPayload();
Long groupId = req.getGroupId();
if (SdfTable.SDF_52 != req.getTable()) {
log.warn("Unsupported table {} received on accountUpdateSdf52. Expected only {}.",
req.getTable(), SdfTable.SDF_52);
}
Collection<SDf52> sdfs = sdfProcessService.sdfsByGroupId(groupId);
if (sdfs.isEmpty()) {
log.info("Do not processing SDF52: S_DF52 not found by groupId={}", groupId);
return null;
}
log.info("start processing {} SDF52: groupId={}", sdfs.size(), groupId);
List<Pair<SDf52, Account>> toUpdate = new ArrayList<>();
List<Triple<SDf52, Account, String>> toProcessSDF53 = new ArrayList<>();
{ // 1. Выборка данных
for (SDf52 sDf52 : sdfs) {
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,
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,
makeSdfErrorText(AccountError.CompanyNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND)));
continue;
}
Map<String, Comparable<?>> accountQuery = Map.of(
"accountType", AccountType.Clrn.getKey(),
"account", sDf52.getAccount(),
"companyId", company.getId()
);
Account account = sDf52.getAccount() == null ? null : accountImdg.getFirstObjectByFieldValues(accountQuery);
if (account == null) {
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());
// 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());
}
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);
log.info("{} account's need wait accept over notification. GroupId={}", notificationAccountIds.size(), groupId);
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();
request.setGroupId(groupingSdf01Id);
request.setChildGenerationId(groupSdf02Id);
request.setAccountCreationResults(results);
request.setContinueSdf(true);
request.setTable(SdfTable.SDF_01); // по нему запрос получили
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

@ -34,8 +34,8 @@ import ru.spcex.platform.enumeration.WorkflowStatus;
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.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ClearingBaseException;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.validation.IValidator;
@ -51,6 +51,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
private final Logger log = LoggerFactory.getLogger(getClass());
private final Producer<String, Object> kafkaProducer;
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final Imdg<ClientCode> clientCodeMap;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryMap;
@ -79,6 +80,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
@Qualifier("clientCodeDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.kafkaProducer = kafkaProducer;
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.clientCodeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
this.tradingClearingRegistryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
@ -94,6 +96,8 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
@Override
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
callback(ClientCodeNewRequest.class)
.setFunction(this::clientCodeNew)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
@ -111,6 +115,33 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
}
/**
* Проверки
* 3.5.1 если не была найдена запись в tradingClearingRegistry по companyId, moneyAccountId, depoAccountId и tradingClearingRegistryType=B (п 3.5.1)
* 3.5.2 если не заполнены поля moneyAccountId ИЛИ moneyAccountId и depoAccountId
* @param userRequest
* @param moneyAccountId req.getMoneyAccountId()
* @param depoAccountId req.getDepoAccountId()
* @param companyId req.getCompanyId()
* @return
*/
RequestInfoUpdate crossValidate(BaseRequest<?> userRequest, Long moneyAccountId, Long depoAccountId, Long companyId) {
if (moneyAccountId == null) { // Если не заполнены moneyAccountId ИЛИ moneyAccountId и depoAccountId
EnumMessage error = null;
if (companyId == null) {
error = new EnumMessage(AccountError.RequiredFieldEmpty, "companyId");
} else {
TradingClearingRegistry tcr = tradingClearingRegistryMap.getFirstObjectByFieldValues(Map.of("companyId", companyId));
if (tcr==null) {
error=new EnumMessage(AccountError.TradingClearingRegistryNotFound, companyId);
}
}
if (error != null) {
return requestHelper.makeErrorResponse(userRequest, error);
}
}
return null;
}
protected RequestInfoUpdate clientCodeNew(BaseRequest<ClientCodeNewRequest> userRequest) {
log.debug("ClientCodeNewRequest received {}", userRequest.getId());
@ -122,13 +153,17 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (requestInfoUpdate != null) return requestInfoUpdate;
ClientCodeNewRequest req = userRequest.getRequestPayload();
// дополнительная проверка
requestInfoUpdate = crossValidate(userRequest, req.getMoneyAccountId(), req.getDepoAccountId(), req.getCompanyId());
if (requestInfoUpdate != null) return requestInfoUpdate;
boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (doCreateTCR) {
try {
createAndWaitTCR(userRequest.getId(), null,
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), null,
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
} catch (ClearingBaseException e) {
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
@ -145,7 +180,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
protected RequestInfoUpdate clientCodeNewFromApiUmCompany(BaseRequest<ClientCodeNewRequest> userRequest) {
log.debug("ClientCodeNewRequest received {}", userRequest.getId());
log.debug("ClientCodeNewRequest (UM_COMPANY) received {}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
@ -155,13 +190,17 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
ClientCodeNewRequest req = userRequest.getRequestPayload();
// дополнительная проверка
requestInfoUpdate = crossValidate(userRequest, req.getMoneyAccountId(), req.getDepoAccountId(), req.getCompanyId());
if (requestInfoUpdate != null) return requestInfoUpdate;
boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (doCreateTCR) {
try {
createAndWaitTCR(userRequest.getId(), null,
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), null,
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
} catch (ClearingBaseException e) {
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
@ -185,6 +224,9 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clientCodeUpdateRequestValidator);
if (requestInfoUpdate != null) return requestInfoUpdate;
// дополнительная проверка
requestInfoUpdate = crossValidate(userRequest, req.getMoneyAccountId(), req.getDepoAccountId(), req.getCompanyId());
if (requestInfoUpdate != null) return requestInfoUpdate;
log.debug("ClientCodeUpdateRequest received, id={}", req.getId());
@ -196,9 +238,10 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (doCreateTCR) {
try {
createAndWaitTCR(userRequest.getId(), clientCode.getId(),
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), clientCode.getId(),
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
} catch (ClearingBaseException e) {
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
@ -248,7 +291,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (depoAccountId != null) {
query.put("depoAccountId", depoAccountId);
}
TradingClearingRegistry result = tradingClearingRegistryMap.getSingleObjectByFieldValues(query);
TradingClearingRegistry result = tradingClearingRegistryMap.getFirstObjectByFieldValues(query);
log.trace("TradingClearingRegistry by: {}; {}found", query, result == null ? "not " : "");
return result;
}
@ -266,8 +309,8 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
}
}
protected void createAndWaitTCR(Long reqId, Long clientCode,
Long companyId, Long moneyAccountId, Long depoAccountId) throws ClearingBaseException {
protected RequestInfoUpdate createAndWaitTCR(Long reqId, Long clientCode,
Long companyId, Long moneyAccountId, Long depoAccountId) {
log.debug("For request {}, clientCode={} need create TCR: companyId={}, moneyAccountId={}, depoAccountId={}",
reqId, clientCode == null ? "new" : clientCode,
companyId, moneyAccountId, depoAccountId);
@ -281,17 +324,13 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
// requestPayload.setStatus(WorkflowStatus.Active.getKey());
requestPayload.setTradingClearingRegistryType(TradingClearingRegistryType.Client_B.getKey());
request.setRequestPayload(requestPayload);
try {
// Следующий вызываемый метод обязательно должен быть synchronized.
RequestInfoUpdate reply = tradingClearingRegistryService.tradingClearingRegistryNew(request);
if (reply != null && Status.Error.equals(reply.getStatus())) {
throw new ClearingBaseException(AccountError.GeneralError, "tradingClearingRegistryService return error: " + reply.getMessage());
}
} catch (ClearingBaseException expected) {
throw expected;
} catch (Exception e) {
throw new ClearingBaseException(AccountError.GeneralError, "Waiting account-service timeout");
// Следующий вызываемый метод обязательно должен быть synchronized.
RequestInfoUpdate reply = tradingClearingRegistryService.tradingClearingRegistryNew(request);
if (reply != null && Status.Error.equals(reply.getStatus())) {
log.warn("tradingClearingRegistryService return error: " + reply.getMessage());
}
return reply;
}
protected void sendBlockTCR(Long tradingClearingRegistryId, Long moneyAccountId) {

View file

@ -9,24 +9,29 @@ 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.DepoAccount;
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.DepoAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
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.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.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
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;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
@Service
@ -36,17 +41,15 @@ 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;
private final Imdg<Account> accountImdg;
private final Imdg<DepoAccount> depoAccountImdg;
public DepoAccountService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaSender,
ValidationHelper validationHelper,
ImdgProvider imdgProvider,
AccountService accountService,
AccountHelper accountService,
@Qualifier("depoAccountNewRequestValidator")
Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator) {
super(kafkaQueue, kafkaProducer);
@ -55,8 +58,6 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
this.imdgProvider = imdgProvider;
this.accountService = accountService;
this.depoAccountNewRequestValidator = depoAccountNewRequestValidator;
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
}
@Override
@ -64,6 +65,10 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
callback(DepoAccountNewRequest.class)
.setFunction(this::depoAccountNew)
.forDestination(Consts.DESTINATION_DEPO_ACCOUNT_NEW, callbacks::put);
callback(AccountSdf01Request.class)
.setFunction(this::accountNewSdf08)
.forDestination(Consts.ACCOUNT_NEW_SDF08, callbacks::put);
init();
}
@ -80,7 +85,12 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
Account account = new Account();
account.setAccount(req.getAccount());
account.setAccountType(AccountType.Depo.getKey());
account.setStatus(ServiceStatus.Active.getKey());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
log.trace("Status not set in request. Use default: {}", account.getStatus());
} else {
account.setStatus(req.getStatus());
}
account.setCompanyId(req.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
@ -94,22 +104,23 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
imdgTransaction.beginTransaction();
DepoAccount depoAccount = null;
try {
Imdg<Account> accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<DepoAccount> depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
accountId = accountImdg.insert(account);
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 {
if (txOk) {
imdgTransaction.commitTransaction();
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest();
request.setDepoAccountId(accountId);
request.setCompanyId(depoAccount.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request);
log.debug("successfully processed, new depo account id {}, account id {}", depoAccountId, accountId);
} else {
log.debug("failed insert, new depo account id {}, new account id {} (if id = -1 then insert is failed)",
@ -120,4 +131,107 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
}
return null;
}
public RequestInfoUpdate accountNewSdf08(BaseRequest<AccountSdf01Request> userRequest) {
log.debug("AccountSdf08Request received, id={}", userRequest.getId());
AccountSdf01Request req = userRequest.getRequestPayload();
List<AccountSdfToStatementRequestPart> accountToStatement = new ArrayList<>();
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
Imdg<Account> accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<DepoAccount> depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
accountsLoop:
for (AccountSdfRequestPart accountReq : req.getAccounts()) {
// DepoAccountNewRequest req = userRequest.getRequestPayload();
Instant now = Instant.now();
Account account = new Account();
account.setAccount(accountReq.getAccount());
account.setAccountType(AccountType.Depo.getKey());
account.setStatus(ServiceStatus.Active.getKey());
account.setCompanyId(accountReq.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
RequestInfoUpdate requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) {
log.warn("Error fill new account from relation. {}", /*account.getId(),*/ requestInfoUpdate.getMessage());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(AccountError.ClearingCategoryNotFound.getId()); // see accountService.fillAccountFromRelation
responsePart.setErrorText(requestInfoUpdate.getMessage());
accountToStatement.add(responsePart);
continue accountsLoop;
}
}
if (accountImdg.getFirstObjectBySQL("account = '%s'".formatted(accountReq.getAccount())) != null) {
log.debug("Account {} already exists", accountReq.getAccount());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
accountToStatement.add(responsePart);
continue accountsLoop;
}
}
Long depoAccountId = -1L;
Long accountId = -1L;
accountId = accountImdg.insert(account);
DepoAccount depoAccount = new DepoAccount();
depoAccount.setCompanyId(accountReq.getCompanyId());
depoAccount.setAccountId(accountId);
if (account.getAccount() != null && account.getAccount().contains("BC")) {
depoAccount.setDepoAccountType(DepoAccountType.C.getKey());
} else {
depoAccount.setDepoAccountType(accountReq.getAccountType());
}
depoAccountId = depoAccountImdg.insert(depoAccount);
log.debug("New account {}, depoAccount {} was created.", accountId, depoAccountId);
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
accountToStatement.add(responsePart);
}
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed insert, new clearing accounts. Request id={}", userRequest.getId());
imdgTransaction.rollbackTransaction();
}
}
sendStatementRequestBack(req.getGroupingSdf01Id(), req.getGroupingSdf02Id(), accountToStatement);
log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size());
return null;
}
public void sendStatementRequestBack(Long groupingSdf01Id, Long groupingSdf02Id, List<AccountSdfToStatementRequestPart> results) {
StatementRequest request = new StatementRequest();
request.setGroupId(groupingSdf01Id);
request.setChildGenerationId(groupingSdf02Id);
request.setContinueSdf(true); //fixme????
request.setAccountCreationResults(results);
request.setTable(SdfTable.SDF_08); // по нему запрос получили
log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request);
}
}

View file

@ -17,14 +17,17 @@ 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.InformationAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest;
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;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
@ -48,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;
@ -66,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(
@ -99,11 +105,16 @@ 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();
Long newId = informationAccountImdg.nextIDSequenceFor();
Long infoSequenceId = accountNextId();
@ -124,13 +135,19 @@ 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());
account.setStatus(ServiceStatus.Active.getKey());
account.setCompanyId(userRequest.getRequestPayload().getCompanyId());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
log.trace("Status not set in request. Use default: {}", account.getStatus());
} else {
account.setStatus(req.getStatus());
}
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();
@ -140,23 +157,21 @@ public class InformationAccountService extends QueueConsumer implements Initiali
Long accountId = -1L;
InformationAccount informationAccount = null;
try {
Imdg<InformationAccount> informationAccountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class);
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountId = accountImdg.insert(account);
informationAccount = new InformationAccount();
informationAccount.setId(newId);
informationAccount.setAccountId(accountId);
informationAccount.setClearingAccountId(anltAccount.getId());
informationAccount.setCompanyId(userRequest.getRequestPayload().getCompanyId());
informationAccount.setCompanyId(req.getCompanyId());
informationAccountId = informationAccountImdg.insert(informationAccount);
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest();
request.setMoneyAccountId(informationAccountId);
request.setCompanyId(informationAccount.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request);
log.debug("successfully processed, new information account id {}, new account id {}",
informationAccountId,
accountId);
@ -173,7 +188,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
public RequestInfoUpdate informationAccountSystemNew(BaseRequest<InformationAccountNewRequest> userRequest) {
log.debug("InformationAccountNewRequest received (system)");
log.debug("InformationAccountNewRequest received (system), request id={}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate;
// RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, infoAccountNewRequestValidator);
@ -194,23 +209,27 @@ public class InformationAccountService extends QueueConsumer implements Initiali
}
// todo требуется последовательность n+1
Long newId = informationAccountImdg.nextIDSequenceFor();
Long infoSequenceId = accountNextId();
Long infoSequenceId = accountNextId(); // требуется последовательность n+1
String accountValue = generateInfoAccount(infoSequenceId);
log.trace("New info-account id={}, sequenceId={}, account={}", newId, infoSequenceId, accountValue);
ImdgPredicate andPredicate = pb.and(
pb.equals("companyId", 1L),
pb.equals("accountType", AccountType.Anlt.getKey())
);
Collection<Account> accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate);
if (accountsAnlt.isEmpty()) {
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "clearingAccountId");
} else if (accountsAnlt.size() > 1) {
log.warn("Account for companyId 1 and accountType=ANLT contains multiply elements, use first");
Long anltAccountId = null;
{
ImdgPredicate andPredicate = pb.and(
pb.equals("companyId", 1L),
pb.equals("accountType", AccountType.Anlt.getKey())
);
Collection<Account> accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate);
if (accountsAnlt.isEmpty()) {
log.error("Account with {} not exist.", andPredicate);
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "clearingAccountId");
} else if (accountsAnlt.size() > 1) {
log.warn("Account for companyId 1 and accountType=ANLT contains multiply elements, use first");
}
Account anltAccount = accountsAnlt.iterator().next();
anltAccountId = anltAccount.getId();
}
Account anltAccount = accountsAnlt.iterator().next();
Instant now = Instant.now();
Account account = new Account();
@ -220,8 +239,11 @@ public class InformationAccountService extends QueueConsumer implements Initiali
account.setCompanyId(forCompanyId);
account.setCreated(now);
account.setUpdated(now);
requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
if (requestInfoUpdate != null) {
log.debug("Stop make new account, cause error: {}", requestInfoUpdate.getMessage());
return requestInfoUpdate;
}
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
imdgTransaction.beginTransaction();
@ -230,23 +252,20 @@ public class InformationAccountService extends QueueConsumer implements Initiali
Long accountId = -1L;
InformationAccount informationAccount = null;
try {
Imdg<InformationAccount> informationAccountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class);
Imdg<Account> accountImdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountId = accountImdg.insert(account);
informationAccount = new InformationAccount();
informationAccount.setId(newId);
informationAccount.setAccountId(accountId);
informationAccount.setClearingAccountId(anltAccount.getId());
informationAccount.setClearingAccountId(anltAccountId);
informationAccount.setCompanyId(userRequest.getRequestPayload().getCompanyId());
informationAccountId = informationAccountImdg.insert(informationAccount);
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest();
request.setMoneyAccountId(informationAccountId);
request.setCompanyId(informationAccount.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request);
log.debug("successfully processed, new information account id {}, new account id {}",
informationAccountId,
accountId);
@ -258,9 +277,23 @@ public class InformationAccountService extends QueueConsumer implements Initiali
}
}
// send to kafka
sendNotificationToReport(informationAccount, account);
return null;
}
/**
* Формирование уведолмения о регистрации УК
*/
protected void sendNotificationToReport(InformationAccount informationAccount, Account account) {
NotificationRequest request = new NotificationRequest();
request.setConsumerId(account.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_NOTIFICATION_NTCR, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.CREATE_NOTIFICATION_NCMP, request);
}
public String generateInfoAccount(Long id) {
return "%d%d%08d%d".formatted(39911, 810, id, 7000);
}
@ -271,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.");
@ -283,10 +316,12 @@ public class InformationAccountService extends QueueConsumer implements Initiali
Pattern accPattern = Pattern.compile("39911810([0-9]{8})7000");
int maxN = 1;
int parsedCount = 0;
String lastAccount = null; // for debug
for (Account acc : allInfoAcc) {
try {
String number = acc.getAccount();
if (StringUtils.isEmpty(number)) continue;
lastAccount = number;
Matcher m = accPattern.matcher(number);
if (m.find()) {
String seqNumber = m.group(1);
@ -303,10 +338,12 @@ public class InformationAccountService extends QueueConsumer implements Initiali
infoCounter = new AtomicLong(maxN);
log.debug("Parsed {} information accounts ({} pattern match) in map. n={}",
allInfoAcc.size(), parsedCount, infoCounter.get());
if (parsedCount == 0 && lastAccount != null)
log.debug("Last unparseable account: {}", lastAccount);
}
}
}
return infoCounter.getAndIncrement();
return infoCounter.incrementAndGet();
}
}

View file

@ -0,0 +1,160 @@
package ru.spcex.clearing.account.service;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.kafka.clients.producer.Producer;
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 = "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;
protected final KafkaSender kafkaSender;
protected final ImdgProvider imdgProvider;
protected final ImdgId idGenerator;
private final Imdg<SDf52> sdf52Imdg;
public SDFProcessService(
Producer<String, Object> kafkaResponseQueue,
KafkaSender kafkaSender,
ImdgProvider imdgProvider) {
this.kafkaResponseQueue = kafkaResponseQueue;
this.kafkaSender = kafkaSender;
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.sdf52Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf52, SDf52.class);
}
public Collection<SDf52> sdfsByGroupId(Long generationId) {
Collection<SDf52> sdfs = sdf52Imdg.getCollectionObjectsByFieldValues(Map.of(
"generationId", generationId
));
return sdfs;
}
public void process(StatementRequest req, List<Triple<SDf52, Account, String>> toProcessSDF53) {
final Long generationId = req.getGroupId();
log.info("Create S_DF53 generationId={} by {} S_DF_52",
generationId, toProcessSDF53.size());
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
boolean txOk = false;
imdgTransaction.beginTransaction();
HashSet<String> fileNames = new HashSet<>();
try { // 2. обновление данных, в транзакции
Imdg<SDf53> sdf53Imdg = imdgTransaction.getImdg(IMDGDistributedNames.Map_SDf53, SDf53.class);
Instant now = Instant.now();
for (Triple<SDf52, Account, String> item : toProcessSDF53) {
SDf53 sDf53 = createBy(item.getLeft(), item.getRight(), now, generationId);
sdf53Imdg.insert(sDf53);
fileNames.add(item.getLeft().getFileName());
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed create new SDF53, rollback transaction. sdf52 generationId={}", generationId);
imdgTransaction.rollbackTransaction();
}
}
if (fileNames.size() > 1)
log.warn("generationId={}, too many different file names in S_DF52: {}", generationId, fileNames);
String fileNameSingle = fileNames.stream().filter(Objects::nonNull).findAny().orElse(null);
log.info("Send export command for SDF53 generationId={} with source file name {}",
generationId, (fileNameSingle == null ? null : "\"" + fileNameSingle + "\""));
messageStatementToExport53(generationId, fileNameSingle);
}
SDf53 createBy(SDf52 sdf52, String result, Instant now, Long newGenerationId) {
SDf53 newSdf = new SDf53();
newSdf.setId(idGenerator.nextId());
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);
newSdf.setGenerationId(sdf52.getGenerationId());
if (!Objects.equals(newGenerationId, newSdf.getGenerationId())) { // never
log.warn("Different GenerationId={} for sdf53[{}] and GenerationId={} for group of sdf52",
newSdf.getGenerationId(), newSdf.getId(), newGenerationId
);
}
newSdf.setInSDfId(sdf52.getId());
return newSdf;
}
/**
* @param status sdf.getStatus()
* @return AccountStatus или null
*/
public AccountStatus parseSdf52Status(Long status) {
if (SDF52_STATUS_1Unblocked.equals(status) || SDF52_STATUS_3Open.equals(status)) {
return AccountStatus.ACTIVE;
} else if (SDF52_STATUS_0Blocked.equals(status)) {
return AccountStatus.BLOCKED;
}
if (SDF52_STATUS_2Closed.equals(status)) {
return AccountStatus.CLOSE;
}
return null;
}
void messageStatementToExport53(Long groupId, String fileName) {
final String destination = Consts.EXPORT_PROCESS; // dbf-exporter
ExportToFileRequest request = new ExportToFileRequest();
request.setNameOfTable("DF-53"); // SdfTable.SDF_53
request.setSdfGroupId(groupId);
request.setFileName(fileName);
Long msgId = kafkaSender.sendRequestToQueue(destination, request);
log.debug("Send ExportToFileRequest({}, {}) message id={} to kafka \"{}\"",
groupId, request.getNameOfTable(), msgId, destination);
}
}

View file

@ -2,9 +2,6 @@ package ru.spcex.clearing.account.service;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.header.Header;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
@ -19,33 +16,32 @@ import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.account.errors.AccountError;
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.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest;
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;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
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.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
@Service
@ -55,6 +51,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
private final ValidationHelper validationHelper;
private final UserRoleVerification userRoleVerification;
private final ImdgProvider imdgProvider;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<DepoAccount> depoAccountImdg;
private final Imdg<ClearingAccount> clearingAccountImdg;
@ -66,13 +63,16 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
private final Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator;
private final RequestHelper requestHelper;
private final Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryNewRequestValidator;
private final Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryAutoNewRequestValidator;
private final Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator;
private final IMessageResolver messageResolver;
private final Producer<String, Object> kafkaProducer;
private final KafkaSender kafkaSender;
public TradingClearingRegistryService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaSender,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@ -86,19 +86,20 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.kafkaProducer = kafkaProducer;
this.kafkaSender = kafkaSender;
this.validationHelper = validationHelper;
this.userRoleVerification = userRoleVerification;
this.requestHelper = requestHelper;
this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
);
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
this.informationAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator;
this.tradingClearingRegistryAutoNewRequestValidator = tradingClearingRegistryNewRequestValidator; // без relation.
this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator;
this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator;
this.messageResolver = messageResolver;
@ -106,8 +107,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
@Override
public void afterPropertiesSet() throws Exception {
init();
callback(TradingClearingRegistryNewRequest.class)
imdgProvider.waitAvailable();
callback(TradingClearingRegistryNewRequest.class) // todo deprecated - unused.
.setFunction(this::tradingClearingRegistryAutoNew)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put);
callback(TradingClearingRegistryNewRequest.class)
@ -119,14 +120,16 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
callback(CommonIdRequest.class)
.setFunction(this::tradingClearingRegistryBlock)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put);
init();
}
@Deprecated
public RequestInfoUpdate tradingClearingRegistryAutoNew(BaseRequest<TradingClearingRegistryNewRequest> userRequest) {
log.debug("TradingClearingRegistryNewRequest received");
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryNewRequestValidator);
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryAutoNewRequestValidator);
if (requestInfoUpdate != null) return requestInfoUpdate;
TradingClearingRegistryNewRequest req = userRequest.getRequestPayload();
@ -138,85 +141,73 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId());
tradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()) : null;
Account depoAccountMain = depoAccount != null ? accountImdg.getSingleObjectByID(depoAccount.getAccountId()) : null;
Account depoAccountMain = req.getDepoAccountId() != null ? accountImdg.getSingleObjectByID(req.getDepoAccountId()) : null;
DepoAccount depoAccount = depoAccountMain != null ? depoAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", req.getDepoAccountId())) : null;
InformationAccount infoAccount = null;
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId());
if (clearingAccount == null) infoAccount = informationAccountImdg.getSingleObjectByID(req.getMoneyAccountId());
Long accountId = clearingAccount != null ? clearingAccount.getAccountId() : infoAccount.getAccountId();
Account accountMain = accountImdg.getSingleObjectByID(accountId);
// InformationAccount infoAccount = null;
ClearingAccount clearingAccount = null;
Account accountMain = null;
if (req.getMoneyAccountId() != null) {
clearingAccount = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", req.getMoneyAccountId()));
// if (clearingAccount == null) infoAccount = informationAccountImdg.getSingleObjectByFieldValues(Map.of("accountId", req.getMoneyAccountId()));
Long accountId = req.getMoneyAccountId(); //clearingAccount != null ? clearingAccount.getAccountId() : infoAccount.getAccountId();
accountMain = accountImdg.getSingleObjectByID(accountId);
}
// TODO
// Проверка выглядит очень сложно и запутанно, потому что репортеры сами не до конца понимают, какая она должна быть.
// Пока что она соответствует ТЗ, но возможно будет правиться, поэтому расписана без выноса кода в методы и
// прочих методов сокращения кода. В дальнейшем, после тестирования и окончательного выяснения вида проверки,
// её стоит вынести на этап валидации запроса.
// кроссвалидация
if (req.getMoneyAccountId() == null && (req.getMoneyAccountId() == null || req.getDepoAccountId() == null)) {
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registryByCompany == null) {
log.trace("Not found registry with companyId={}",
req.getCompanyId());
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryNotFound,
req.getCompanyId());
}
}
Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", req.getCompanyId()));
if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) {
TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registry != null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.getId());
if (tradingClearingRegistry.getMoneyAccountId() == null && tradingClearingRegistry.getDepoAccountId() != null) {
Collection<TradingClearingRegistry> registriesByCompany = tradingClearingRegistryImdg.getCollectionObjectsByFieldValues(Map.of("companyId", req.getCompanyId()));
TradingClearingRegistry targetExistTradingClearingRegistry = null;
for (TradingClearingRegistry existRegistry : registriesByCompany) {
if (existRegistry.getMoneyAccountId() != null && existRegistry.getDepoAccountId() == null) {
targetExistTradingClearingRegistry = existRegistry;
}
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
} else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(relation.getService())) {
if (AccountType.Info.equalsByKey(accountMain.getStatus())) {
TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of(
"companyId", req.getCompanyId(),
"tradingClearingRegistryType", TradingClearingRegistryPurpose.M.getKey()
));
if (registry != null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.getId());
if (targetExistTradingClearingRegistry == null) {
log.warn("TradingClearingRegister with MoneyAccountId for companyId={} not found. Search exist accounts for company", req.getCompanyId());
Long accountId;
InformationAccount infoAccount = null;
clearingAccount = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (clearingAccount == null) {
infoAccount = informationAccountImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (infoAccount == null) {
log.warn("ClearingAccount and InfoAccount not exist for company {}.", req.getCompanyId());
accountId = null;
} else {
accountId = infoAccount.getAccountId();
log.debug("Found account.id={} and infoaccount.id={} by companyId={}", accountId, infoAccount.getId(), req.getCompanyId());
}
} else {
accountId = clearingAccount.getAccountId();
log.debug("Found account.id={} and clearingAccount.id={} by companyId={}", accountId, clearingAccount.getId(), req.getCompanyId());
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
} else if (AccountType.Clrn.equalsByKey(accountMain.getStatus())) {
ImdgPredicateBuilder imdgPredicateBuilder = tradingClearingRegistryImdg.predicateBuilder();
ImdgPredicate predicate = imdgPredicateBuilder.and(
imdgPredicateBuilder.equals("companyId", req.getCompanyId()),
imdgPredicateBuilder.or(
imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.M.getKey()),
imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.C.getKey())
)
);
Collection<TradingClearingRegistry> registry = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(predicate);
if (!registry.isEmpty()) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.iterator().next().getId());
if (accountId != null) {
accountMain = accountImdg.getSingleObjectByID(accountId);
if (accountMain == null) { // never, только с инконсистентными данными
log.warn("Account {} not exist.", accountId);
} else {
tradingClearingRegistry.setMoneyAccountId(accountId);
log.debug("Set tradingClearingRegistry[{}].MoneyAccountId={}", tradingClearingRegistry.getId(), accountId);
}
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null) {
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
}
} else if (AccountType.Depo.equalsByKey(accountMain.getStatus())) {
InformationAccount infoAccountForCheck = informationAccountImdg.getSingleObjectByFieldValues(
Map.of("companyId", req.getCompanyId())
);
ClearingAccount clearingAccountForCheck = clearingAccountImdg.getSingleObjectByFieldValues(
Map.of("companyId", req.getCompanyId())
);
if (infoAccountForCheck == null && clearingAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.MoneyAccountNotFound, req.getCompanyId());
} else {
log.debug("Update exist TCR.id={}, set DepoAccountId={}", targetExistTradingClearingRegistry, req.getDepoAccountId());
targetExistTradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
targetExistTradingClearingRegistry.setUpdated(Instant.now());
tradingClearingRegistryImdg.update(targetExistTradingClearingRegistry);
log.debug("successfully processed, id {}. Updated exist TradingClearingRegistry.id={}", id, targetExistTradingClearingRegistry.getId());
return null;
}
}
@ -260,10 +251,9 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = companyImdg.getSingleObjectByID(req.getCompanyId());
String code = "%4s".formatted(company.getClearingCode()).replace(' ', '0');
code += registryPurpose.getKey();
if (registryPurpose == TradingClearingRegistryPurpose.C) code += tradingRegistryType + id;
else code += "AT" + id;
Long seqId = companySequenceNextId(req.getCompanyId(), registryPurpose, tradingRegistryType);
String code = makeCode(company.getClearingCode(), registryPurpose, tradingRegistryType, seqId);
log.debug("For new TCR.id={} of companyId={} next sequence={}; code={}", id, req.getCompanyId(), seqId, code);
tradingClearingRegistry.setCode(code);
Instant now = Instant.now();
@ -271,6 +261,12 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistryImdg.insert(tradingClearingRegistry);
log.debug("New TCR.id={} was created", tradingClearingRegistry.getId());
// sendNotificationToCompanySvc(tradingClearingRegistry); при автосоздании ТКР в company-service не отправлять.
// sendNotificationToClearingSvc(tradingClearingRegistry);
sendNotificationToReportSvc(tradingClearingRegistry);
sendNotificationToClearingSvc(tradingClearingRegistry);
log.debug("successfully processed, id {}", id);
return null;
@ -291,7 +287,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
TradingClearingRegistryNewRequest req = userRequest.getRequestPayload();
// Дополнительная проверка
if (req.getMoneyAccountId() == null && (req.getMoneyAccountId() == null || req.getDepoAccountId() == null)) {
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registryByCompany == null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryNotFound,
@ -306,13 +302,21 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId());
tradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()) : null;
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId());
DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", req.getDepoAccountId())) : null;
ClearingAccount clearingAccount = req.getMoneyAccountId() != null ? clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", req.getMoneyAccountId())) : null;
tradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
if (req.getStatus() == null) {
tradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
log.trace("TCR status in request not set. Use default: {}", tradingClearingRegistry.getStatus());
} else {
tradingClearingRegistry.setStatus(req.getStatus());
log.trace("TCR status in request set: {}", tradingClearingRegistry.getStatus());
}
String tradingRegistryType;
if (depoAccount != null) {
if (req.getTradingClearingRegistryType() != null) {
tradingRegistryType = req.getTradingClearingRegistryType();
} else if (depoAccount != null) {
tradingRegistryType = depoAccount.getDepoAccountType();
} else {
if (clearingAccount != null) tradingRegistryType = clearingAccount.getClearingAccountType();
@ -326,10 +330,9 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = companyImdg.getSingleObjectByID(req.getCompanyId());
String code = "%4s".formatted(company.getClearingCode()).replace(' ', '0');
code += registryPurpose.getKey();
if (registryPurpose == TradingClearingRegistryPurpose.C) code += tradingRegistryType + id;
else code += "AT" + id;
Long seqId = companySequenceNextId(req.getCompanyId(), registryPurpose, tradingRegistryType);
String code = makeCode(company.getClearingCode(), registryPurpose, tradingRegistryType, seqId);
log.debug("For new TCR.id={} of companyId={} next sequence={}; code={}", id, req.getCompanyId(), seqId, code);
tradingClearingRegistry.setCode(code);
Instant now = Instant.now();
@ -337,11 +340,70 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistryImdg.insert(tradingClearingRegistry);
log.info("New TCR.id={} was created.", tradingClearingRegistry.getId());
sendNotificationToReportSvc(tradingClearingRegistry);
sendNotificationToClearingSvc(tradingClearingRegistry);
log.debug("successfully processed, id {}", id);
return null;
}
protected Long companySequenceNextId(Long companyId, TradingClearingRegistryPurpose registryPurpose, String tradingRegistryType) {
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
Collection<TradingClearingRegistry> existTCR = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("companyId", companyId),
pb.equals("tradingClearingRegistryPurpose", registryPurpose.getKey()),
pb.equals("tradingClearingRegistryType", tradingRegistryType)
)
);
if (existTCR.isEmpty()) {
log.trace("For company id={} not found exist TCR.", companyId);
return 1L;
}
log.trace("For company id={} found {} exist TCR.", companyId, existTCR.size());
long maxN = 0;
for (TradingClearingRegistry tcr : existTCR) {
Long codeN = parseCodeSeqId(tcr.getCode());
if (codeN != null) {
if (maxN < codeN)
maxN = codeN;
}
}
return maxN + 1;
}
protected Long parseCodeSeqId(String code) {
if (code == null || code.isBlank())
return null;
try {
String toParse = code.trim();
if (toParse.length() > 5)
toParse = toParse.substring(toParse.length() - 5);
return Long.parseLong(toParse);
} catch (NumberFormatException nan) {
log.warn("Can not parse number from TCR code \"{}\": {}", code, nan.getMessage());
}
return null;
}
protected String makeCode(String companyClearingCode, TradingClearingRegistryPurpose registryPurpose, String tradingRegistryType, Long id) {
String code;
code = companyClearingCode;
if (code.length() > 4)
code = code.substring(code.length() - 4);
code = "%4s".formatted(code).replace(' ', '0');
code += registryPurpose.getKey(); // C / M / ...
String trType = tradingRegistryType + "T"; // 2 символа
code += trType;
String sId = "%5s".formatted(id).replace(' ', '0');
if (sId.length() > 5)
sId = sId.substring(sId.length() - 5);
code += sId;
return code; // 12 имволов
}
public RequestInfoUpdate tradingClearingRegistryUpdate(BaseRequest<TradingClearingRegistryUpdateRequest> userRequest) {
log.debug("TradingClearingRegistryUpdateRequest received");
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
@ -352,22 +414,27 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
TradingClearingRegistryUpdateRequest req = userRequest.getRequestPayload();
TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(req.getId());
// Дополнительная проверка
if (req.getMoneyAccountId() == null && (req.getMoneyAccountId() == null || req.getDepoAccountId() == null)) {
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registryByCompany == null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryNotFound,
"companyId=" + req.getCompanyId());
}
// кроссвалидация - нельзя менять эти поля:
if (req.getMoneyAccountId() != null && !req.getMoneyAccountId().equals(tradingClearingRegistry.getMoneyAccountId())) {
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "MoneyAccountId", req.getMoneyAccountId());
}
if (req.getDepoAccountId() != null && !req.getDepoAccountId().equals(tradingClearingRegistry.getDepoAccountId())) {
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "DepoAccountId", req.getDepoAccountId());
}
// tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId());
// tradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
if (req.getStatus() != null) tradingClearingRegistry.setStatus(req.getStatus());
Instant now = Instant.now();
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistryImdg.update(tradingClearingRegistry);
if (req.getStatus() != null && !Objects.equals(req.getStatus(), tradingClearingRegistry.getStatus())) {
Instant now = Instant.now();
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistry.setStatus(req.getStatus());
tradingClearingRegistryImdg.update(tradingClearingRegistry);
log.debug("Update TCR.id={}.", tradingClearingRegistry.getId());
} else {
log.debug("Nothing to update TCR.id={}.", tradingClearingRegistry.getId());
}
log.debug("successfully processed, id {}", tradingClearingRegistry.getId());
return null;
@ -392,4 +459,40 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
log.debug("successfully processed, id {}", tradingClearingRegistry.getId());
return null;
}
/**
* company-service сообщение об успешном добавлении ТКР клиента с параметром tradingClearingRegistry.code
*/
protected void sendNotificationToCompanySvc(TradingClearingRegistry tradingClearingRegistry) {
ClientCodeNewRequest request = new ClientCodeNewRequest();
request.setTradingClearingRegistryId(tradingClearingRegistry.getId());
request.setCompanyId(tradingClearingRegistry.getCompanyId());
request.setCode(tradingClearingRegistry.getCode());
request.setMoneyAccountId(tradingClearingRegistry.getMoneyAccountId());
request.setDepoAccountId(tradingClearingRegistry.getDepoAccountId());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, request);
}
/**
* clearing-service сообщение на открытие клиринговых регистров;
*/
protected void sendNotificationToClearingSvc(TradingClearingRegistry tradingClearingRegistry) {
CreateRegistryRequest request = new CreateRegistryRequest();
request.setCompanyId(tradingClearingRegistry.getCompanyId());
request.setTradingClearingRegistryId(tradingClearingRegistry.getId());
log.debug("Send message to kafka \"{}\": {}", Consts.REGISTRY_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.REGISTRY_NEW, request);
}
/**
* report-service сообщение на формирование уведомления о создании нового ТКР
*/
protected void sendNotificationToReportSvc(TradingClearingRegistry tradingClearingRegistry) {
NotificationRequest request = new NotificationRequest();
request.setConsumerId(tradingClearingRegistry.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_NOTIFICATION_NTCR, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.CREATE_NOTIFICATION_NTCR, request);
}
}

View file

@ -38,7 +38,7 @@ public enum AccountValidationRule implements IValidationRule<ImdgValidationConte
public Optional<EnumMessage> validate(ImdgValidationContext<BankAccountNewRequest> context) {
BankAccountNewRequest bankAccountRequest = context.getValidatedObject();
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account account = accountImdg.getSingleObjectByFieldValues(Map.of("account", bankAccountRequest.getAccount(),
Account account = accountImdg.getFirstObjectByFieldValues(Map.of("account", bankAccountRequest.getAccount(),
"accountStatus", Status.Active.getKey()));
if (account != null) {
return of(AccountError.AccountAlreadyExist);

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,13 +50,15 @@ 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 {
public static final MatcherFactory.Matcher<Account> ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
public static final MatcherFactory.Matcher<RequestInfo> REQUEST_INFO_MATCHER_MATCHER = usingIgnoringFieldsComparator("created");
private static final int PARTITION = 0;
private static final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01;
private static final String account = "123456789123";
private static final Long companyId = 0L;
private static final Long relationId = 0L;
@ -210,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);
}
@ -247,76 +243,4 @@ class AccountServiceTest {
accountImdg.delete(resultBlock);
}
/**
* {@link AccountService#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
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);
}
}

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;
@ -179,8 +172,8 @@ public class BankAccountServiceTest {
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonString);
waitingSendAndCheckRecord(ID, mockProducer);
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", acc));
BankAccount bankAccountResult = bankAccountImdg.getSingleObjectBySQL(String.format("account = %s or companyId = %s", acc, addresseeIdNew));
Account accountResult = accountImdg.getFirstObjectBySQL(String.format("account = %s", acc));
BankAccount bankAccountResult = bankAccountImdg.getFirstObjectBySQL(String.format("account = %s or companyId = %s", acc, addresseeIdNew));
predictableBankAccount.setAccountId(accountResult.getId());
predictableBankAccount.setId(bankAccountResult.getId());
setSameValueToField(accountResult, predictableAccount);
@ -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,16 +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;
@ -24,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 = {
@ -50,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 {
@ -69,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;
@ -159,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);
@ -173,8 +176,8 @@ class ClearingAccountServiceTest {
predictableClearingAccount.setCompanyId(companyId);
predictableClearingAccount.setClearingAccountType(CLEARING_ACCOUNT_TYPE_DICT);
Account resultAccountNew = accountImdg.getSingleObjectByFieldValues(Map.of("accountType", AccountType.Clrn.getKey()));
ClearingAccount resultClearingAccountNew = clearingAccountImdg.getSingleObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
Account resultAccountNew = accountImdg.getFirstObjectByFieldValues(Map.of("accountType", AccountType.Clrn.getKey()));
ClearingAccount resultClearingAccountNew = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
predictableAccount.setId(resultAccountNew.getId());
predictableClearingAccount.setAccountId(resultAccountNew.getId());
@ -224,4 +227,64 @@ class ClearingAccountServiceTest {
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
}
@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

@ -1,7 +1,6 @@
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;
@ -9,10 +8,8 @@ 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;
@ -27,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;
@ -211,7 +208,7 @@ class ClientCodeServiceTest {
//ASSERT
waitingSendAndCheckRecord(ID, mockProducer);
ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode));
ClientCode resultNew = clientCodeImdg.getFirstObjectBySQL(String.format("code = '%s'", ccCode));
predictableClientCode.setId(resultNew.getId());
CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode);
assertNotNull(resultNew.getCreated());
@ -249,7 +246,7 @@ class ClientCodeServiceTest {
//ASSERT
TestUtils.waitingSendAndCheckRecord(ID, mockProducer, producerRecord);
ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode));
ClientCode resultNew = clientCodeImdg.getFirstObjectBySQL(String.format("code = '%s'", ccCode));
predictableClientCode.setId(resultNew.getId());
CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode);
assertNotNull(resultNew.getCreated());
@ -289,7 +286,7 @@ class ClientCodeServiceTest {
//ASSERT
waitingSendAndCheckRecord(ID, mockProducer);
ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode));
ClientCode resultNew = clientCodeImdg.getFirstObjectBySQL(String.format("code = '%s'", ccCode));
predictableClientCode.setId(resultNew.getId());
CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode);
assertNotNull(resultNew.getCreated());
@ -379,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);
@ -173,8 +160,8 @@ class DepoAccountServiceTest {
predictableDepoAccount.setCompanyId(companyId);
predictableDepoAccount.setDepoAccountType(DEPO_ACCOUNT_TYPE_DICT);
Account resultAccountNew = accountImdg.getSingleObjectByFieldValues(Map.of("accountType", AccountType.Depo.getKey()));
DepoAccount resultDepoAccountNew = depoAccountImdg.getSingleObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
Account resultAccountNew = accountImdg.getFirstObjectByFieldValues(Map.of("accountType", AccountType.Depo.getKey()));
DepoAccount resultDepoAccountNew = depoAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
predictableAccount.setId(resultAccountNew.getId());
predictableDepoAccount.setAccountId(resultAccountNew.getId());

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());
@ -166,11 +155,11 @@ class InformationAccountServiceTest {
predictableInfoAccount.setCompanyId(companyId);
predictableInfoAccount.setClearingAccountId(anltAccountId);
Account resultAccountNew = accountImdg.getSingleObjectByFieldValues(Map.of("accountType", AccountType.Info.getKey()));
InformationAccount resultInfoAccountNew = informationAccountImdg.getSingleObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
Account resultAccountNew = accountImdg.getFirstObjectByFieldValues(Map.of("accountType", AccountType.Info.getKey()));
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,11 +187,12 @@ 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(12L, n);
n = infoAccSvc.accountNextId();
Assertions.assertEquals(13L, n);
n = infoAccSvc.accountNextId();
Assertions.assertEquals(14L, n);
}
}

View file

@ -0,0 +1,106 @@
package ru.spcex.clearing.account.service;
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;
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.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary;
import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
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.AccountStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import javax.annotation.PostConstruct;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
BeanConfiguration.class,
ValidationConfig.class,
SDFProcessService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
class SDFProcessServiceTest {
@Autowired
SDFProcessService sdfProcessService;
@Autowired
@Qualifier("hazelcastServiceTest")
private ImdgProvider hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@Autowired
@Qualifier("mockProducer")
protected Producer<String, Object> mockProducer;
private Imdg<ClearingAccount> clearingAccountImdg;
private Imdg<Account> accountImdg;
private Imdg<Company> companyImdg;
private Imdg<ClearingAccountTypeDictionary> clearingAccountTypeDictionaryImdg;
private Imdg<AccountTypeDictionary> accountTypeDictionaryImdg;
private Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
private Imdg<Relation> relationImdg;
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
clearingAccountImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
);
accountImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Account, Account.class
);
companyImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Company, Company.class
);
accountTypeDictionaryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_AccountTypeDictionary, AccountTypeDictionary.class
);
clearingAccountTypeDictionaryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingAccountTypeDictionary, ClearingAccountTypeDictionary.class
);
clearingMemberCategoryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class
);
relationImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_Relation, Relation.class
);
new TestObjectCreator(hazelcastServiceTest).createUserAdmin(1000L);
}
@Test
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(4705211956118233163L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(null));
}
}

View file

@ -1,16 +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;
@ -18,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 = {
@ -63,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;
@ -102,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
);
@ -128,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);
@ -153,15 +159,17 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_moneyAccount_clearingAccount() {
setMockFuture(kafkaTemplate);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(clearingAccountId);
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077MAT");
predictableTradingClearingRegistry.setMoneyAccountId(clearingAccountId);
predictableTradingClearingRegistry.setTradingClearingRegistryType("CAT");
predictableTradingClearingRegistry.setCode("0077MAT00001");
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
@ -177,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());
@ -189,14 +196,17 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_moneyAccount_informationAccount() {
setMockFuture(kafkaTemplate);
clearImdg(tradingClearingRegistryImdg);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(infoAccountId);
tradingClearingRegistryNewRequest.setMoneyAccountId(account2Id);
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077MAT");
predictableTradingClearingRegistry.setMoneyAccountId(infoAccountId);
predictableTradingClearingRegistry.setCode("0077MAT00001");
predictableTradingClearingRegistry.setMoneyAccountId(account2Id);
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
@ -209,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());
@ -226,16 +235,18 @@ class TradingClearingRegistryServiceTest {
@Test
void tradingClearingRegistryNew_depoAccount() {
setMockFuture(kafkaTemplate);
clearImdg(tradingClearingRegistryImdg);
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
tradingClearingRegistryNewRequest.setCompanyId(companyId);
tradingClearingRegistryNewRequest.setMoneyAccountId(clearingAccountId);
tradingClearingRegistryNewRequest.setDepoAccountId(depoAccountId);
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
tradingClearingRegistryNewRequest.setDepoAccountId(account2Id);
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
predictableTradingClearingRegistry.setCompanyId(companyId);
predictableTradingClearingRegistry.setCode("0077CDAT");
predictableTradingClearingRegistry.setMoneyAccountId(clearingAccountId);
predictableTradingClearingRegistry.setDepoAccountId(depoAccountId);
predictableTradingClearingRegistry.setCode("0077CDATT00001");
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
predictableTradingClearingRegistry.setDepoAccountId(account2Id);
predictableTradingClearingRegistry.setTradingClearingRegistryType("DAT");
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.C.getKey());
predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
@ -248,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);
@ -283,7 +292,7 @@ class TradingClearingRegistryServiceTest {
jsonString);
//ASSERT
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
@ -311,7 +320,7 @@ class TradingClearingRegistryServiceTest {
jsonString);
//ASSERT
waitingSendAndCheckRecord(0L, producer, producerRecord);
waitingSendAndCheckRecord(0L, mockProducer);
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
@ -319,4 +328,30 @@ class TradingClearingRegistryServiceTest {
TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultUpdating, existTradingClearingRegistry);
tradingClearingRegistryImdg.delete(resultUpdating);
}
@Test
void makeCode() {
Assertions.assertEquals("0005CAT00001", tradingClearingRegistryService.makeCode(
"5", TradingClearingRegistryPurpose.C, TradingClearingRegistryType.Owner_A.getKey(), 1L
));
Assertions.assertEquals("0005CET00012", tradingClearingRegistryService.makeCode(
"005", TradingClearingRegistryPurpose.C, "E", 12L
));
Assertions.assertEquals("0105CERT00012", tradingClearingRegistryService.makeCode(
"000000105", TradingClearingRegistryPurpose.C, "ER", 100012L
));
Assertions.assertEquals("0105MAT00012", tradingClearingRegistryService.makeCode(
"000000105", TradingClearingRegistryPurpose.M, "A", 100012L
));
}
@Test
void parseCodeSeqId() {
Assertions.assertEquals(Long.valueOf(1L), tradingClearingRegistryService.parseCodeSeqId("0005CAT00001"));
Assertions.assertEquals(Long.valueOf(5001), tradingClearingRegistryService.parseCodeSeqId("0005CAT05001"));
Assertions.assertEquals(null, tradingClearingRegistryService.parseCodeSeqId("0005CAT"));
Assertions.assertEquals(null, tradingClearingRegistryService.parseCodeSeqId(""));
Assertions.assertEquals(null, tradingClearingRegistryService.parseCodeSeqId(null));
}
}

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

@ -0,0 +1,40 @@
package ru.spcex.clearing.backendapi.controller.queue.clearing;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import ru.clearing.classes.statics.data.clearing.VerificationResult;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
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 java.util.Collection;
import java.util.Map;
@Controller
@RequestMapping("/verification-results")
public class VerificationResultController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public VerificationResultController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ApiOperation(value = "get all VerificationResult's.")
@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_VerificationResult, VerificationResult.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
}

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

@ -1,22 +1,30 @@
package ru.spcex.clearing.backendapi.controller.queue.misc;
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.misc.Notification;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction;
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("/notifications")
@ -39,4 +47,14 @@ public class NotificationController extends AbstractQueueController {
response.fromEntity(all);
return response;
}
@ApiOperation(value = "create Notification.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse update(
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody NotificationUpdateAction notificationUpdateAction) throws ExecutionException, InterruptedException {
return processRequest(Consts.NOTIFICATION_UPDATE, notificationUpdateAction);
}
}

View file

@ -7,13 +7,10 @@ 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 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.RSplitDepositActionNew;
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;
@ -57,4 +54,57 @@ public class RegistryController extends AbstractQueueController {
@RequestBody RSplitDepositActionNew rSplitDepositActionNew) throws ExecutionException, InterruptedException {
return processRequest(Consts.REGISTRY_SPLIT_DEPOSIT_ACTION, rSplitDepositActionNew);
}
@ApiOperation(value = "Отметить средства на возврат депозита")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/returnDeposit/{id}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse returnDepositAction(
@ApiParam(value = "Идентификатор изменяемого объекта.", required = true, example = "1234")
@PathVariable("id") Long id,
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody ReturnDepositActionNew returnDepositAction) throws ExecutionException, InterruptedException {
returnDepositAction.setId(id);
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)
@ResponseBody
public CudResponse changeRefundDate(
@ApiParam(value = "Идентификатор группы связанных регистров.", required = true, example = "1234")
@PathVariable("groupId") Long groupId,
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
@RequestBody ChangeRefundDateActionNew returnDepositAction) throws ExecutionException, InterruptedException {
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

@ -4,6 +4,8 @@ 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.HttpStatus;
import org.springframework.http.MediaType;
@ -29,6 +31,7 @@ import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
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;
@ -38,6 +41,7 @@ import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/launchers")
public class LauncherController extends AbstractQueueController {
protected final Logger log = LoggerFactory.getLogger(getClass());
private final IStateLoader stateLoader;
private final Imdg<User> userImdg;
private final Imdg<AbstractDictionary> taskDictionary;
@ -69,14 +73,14 @@ public class LauncherController extends AbstractQueueController {
@ResponseBody
public CudResponse add(@ApiParam(value = "Код задания из taskDictionary", required = true, example = "ABLK")
@PathVariable("task-code") String dictionaryName) throws ExecutionException, InterruptedException {
AbstractDictionary taskEnum = taskDictionary.getSingleObjectByFieldValues(Map.of("code", dictionaryName));
AbstractDictionary taskEnum = taskDictionary.getFirstObjectByFieldValues(Map.of("code", dictionaryName));
if (taskEnum == null) {
throw new NotFound404Exception("task dictionary element with code '" + dictionaryName + "'");
}
LauncherNew launcherCommand = new LauncherNew();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
User user = userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
throw new IllegalStateException("cannot obtain userId from logged in user " + username);
}
@ -96,16 +100,16 @@ public class LauncherController extends AbstractQueueController {
if (launcherNew.getTask() == null) {
throw new NotFound404Exception("task dictionary element with code '" + launcherNew.getTask() + "'");
}
AbstractDictionary taskEnum = taskDictionary.getSingleObjectByFieldValues(Map.of("code", launcherNew.getTask()));
AbstractDictionary taskEnum = taskDictionary.getFirstObjectByFieldValues(Map.of("code", launcherNew.getTask()));
if (taskEnum == null) {
throw new NotFound404Exception("task dictionary element with code '" + launcherNew.getTask() + "'");
}
if (!Task.startOfClearing.getKey().equals(taskEnum.getCode())) {
throw new IllegalStateException(String.format("Task %s not support request with body", taskEnum.getCode()));
}
if (!IEnumKey.contains(taskEnum.getCode(), Task.startOfClearing, Task.dbfExport_OUTV)) {
log.warn(String.format("Task %s not support request with body", taskEnum.getCode()));
} // else В мете эти модели с дополнительными параметрами (OUTV).
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
User user = userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
throw new IllegalStateException("cannot obtain userId from logged in user " + username);
}

View file

@ -0,0 +1,318 @@
package ru.spcex.clearing.backendapi.controller.queue.sdf;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
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 ru.clearing.classes.statics.data.sdf.*;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
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 java.util.Collection;
import java.util.Map;
@Controller
@RequestMapping("/s-dfs")
public class SdfsController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public SdfsController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ApiOperation(value = "get all S_DF01")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df01", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf01() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf01,
SDf01.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF02")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df02", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf02() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf02,
SDf02.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF03")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df03", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf03() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf03,
SDf03.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF04")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df04", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf04() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf04,
SDf04.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF05")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df05", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf05() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf05,
SDf05.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF06")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df06", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf06() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf06,
SDf06.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF07")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df07", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf07() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf07,
SDf07.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF08")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df08", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf08() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf08,
SDf08.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF09")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df09", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf09() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf09,
SDf09.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF10")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df10", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf10() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf10,
SDf10.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF11")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df11", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf11() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf11,
SDf11.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF12")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df12", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf12() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf12,
SDf12.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF13")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df13", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf13() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf13,
SDf13.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF14")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df14", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf14() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf14,
SDf14.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF20")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df20", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf20() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf20,
SDf20.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF21")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df21", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf21() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf21,
SDf21.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF52")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df52", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf52() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf52,
SDf52.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF53")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df53", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf53() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf53,
SDf53.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF54")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df54", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf54() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf54,
SDf54.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF55")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df55", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf55() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf55,
SDf55.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF56")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df56", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf56() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf56,
SDf56.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF57")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df57", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf57() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf57,
SDf57.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
}

View file

@ -68,7 +68,7 @@ public class UserController extends AbstractQueueController {
UserIdResponse response = new UserIdResponse();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
User user = username == null ? null : userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
log.info("getId user {} authenticated, but User object was not created", username);
throw new IllegalStateException("couldn't return user id");

View file

@ -45,12 +45,21 @@ public class UserSettingsController extends AbstractQueueController {
this.userImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_User, User.class);
}
@ApiOperation(value = "get all user settings.")
@ApiOperation(value = "get all user settings for current user.")
@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_UserSettings, UserSettings.class);
public CommonGetAllResponse getAllForCurrentUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = username == null ? null : userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
throw new IllegalStateException("cannot obtain userId from logged in user " + username);
}
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_UserSettings, UserSettings.class,
Map.of("userId", user.getId())
);
var response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
@ -65,7 +74,7 @@ public class UserSettingsController extends AbstractQueueController {
@RequestBody UserSettingsUpdateAction userSettingsUpdateAction) throws ExecutionException, InterruptedException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
User user = userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
throw new IllegalStateException("cannot obtain userId from logged in user " + username);
}

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,71 @@
package ru.spcex.clearing.backendapi.controller.request.cud.registry;
import com.fasterxml.jackson.annotation.JsonIgnore;
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.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.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ChangeRefundDateActionNew implements IAction<RegistryChangeRefundDateRequest> {
@JsonIgnore
public Long groupId;
@JsonProperty
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
public LocalDate refundDate;
@Override
public RegistryChangeRefundDateRequest toRequest() {
var req = new RegistryChangeRefundDateRequest();
req.setGroupId(groupId);
req.setRefundDate(refundDate);
return req;
}
@Override
public Collection<EnumMessage> validate() {
List<EnumMessage> errors = new ArrayList<>();
if (groupId == null) {
errors.add(new EnumMessage(BackEndError.ValidationError, "url parameter 'groupId'"));
}
if (refundDate == null) {
errors.add(new EnumMessage(BackEndError.ValidationError, "refundDate"));
}
return errors;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.UPDATE;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public LocalDate getRefundDate() {
return refundDate;
}
public void setRefundDate(LocalDate refundDate) {
this.refundDate = refundDate;
}
}

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

@ -0,0 +1,58 @@
package ru.spcex.clearing.backendapi.controller.request.cud.registry;
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.utilities.NotificationUpdateRequest;
public class NotificationUpdateAction implements IAction<NotificationUpdateRequest> {
@ApiModelProperty(value = "Идентификатор записи", example = "123")
@JsonProperty
public Long id;
@ApiModelProperty(value = "Наименование статуса сообщения", example = "ACTV")
@JsonProperty
public String notificationStatus;
@ApiModelProperty(value = "Наименование отправителя (не исопльзуется)", example = "1234")
@JsonProperty(required = false)
@Deprecated
public Long senderId;
@Override
public NotificationUpdateRequest toRequest() {
var req = new NotificationUpdateRequest();
req.setId(this.id);
req.setNotificationStatus(this.notificationStatus);
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 getNotificationStatus() {
return notificationStatus;
}
public void setNotificationStatus(String notificationStatus) {
this.notificationStatus = notificationStatus;
}
public Long getSenderId() {
return senderId;
}
public void setSenderId(Long senderId) {
this.senderId = senderId;
}
}

View file

@ -36,6 +36,9 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
@ApiModelProperty(value = "Договор для разделения", example = "ABCD")
@JsonProperty
public String contract;
@ApiModelProperty(value = "Направление", example = "OUT")
@JsonProperty
public String direction;
@Override
@ -45,6 +48,7 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
req.setOutboundAmount(this.outboundAmount);
req.setRefundDate(this.refundDate);
req.setContract(this.contract);
req.setDirection(this.direction);
return req;
}
@ -85,4 +89,12 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
public void setContract(String contract) {
this.contract = contract;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
}

View file

@ -0,0 +1,68 @@
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.RegistryReturnDepositRequest;
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 ReturnDepositActionNew implements IAction<RegistryReturnDepositRequest>, WithId {
@JsonIgnore
public Long id;
@ApiModelProperty(value = "Сумма", example = "1600.20")
@JsonProperty
public BigDecimal balance;
@Override
public RegistryReturnDepositRequest toRequest() {
var req = new RegistryReturnDepositRequest();
req.setId(id);
req.setBalance(balance);
return req;
}
@Override
public Collection<EnumMessage> validate() {
List<EnumMessage> errors = new ArrayList<>();
if (id == null) {
errors.add(new EnumMessage(BackEndError.ValidationError, "url parameter 'id'"));
}
if (balance == null) {
errors.add(new EnumMessage(BackEndError.ValidationError, "balance"));
}
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;
}
}

View file

@ -9,6 +9,7 @@ import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -35,6 +36,34 @@ public class LauncherNew implements IAction<Object> {
@JsonProperty
private Long sessionId;
@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;
@ApiModelProperty(value = "Сумма отправителя", example = "12.22")
@JsonProperty
private BigDecimal creditLeg_amount;
@ApiModelProperty(value = "Назначение платежа", example = "text")
@JsonProperty
private String paymentPurpose;
@ApiModelProperty(value = "Участник отправитель", example = "1000")
@JsonProperty
private Long senderId;
@ApiModelProperty(value = "Наименование счета отправителя", example = "1000")
@JsonProperty
private Long creditLeg_accountId;
@ApiModelProperty(value = "Участник получатель", example = "1000")
@JsonProperty
private Long addresseeId;
@ApiModelProperty(value = "Наименование счета получателя", example = "1000")
@JsonProperty
private Long debitLeg_accountId;
@Override
public Object toRequest() {
LauncherCommandRequest taskRunnerCommandRequest = new LauncherCommandRequest();
@ -45,6 +74,15 @@ public class LauncherNew implements IAction<Object> {
taskRunnerCommandRequest.setSection(section);
taskRunnerCommandRequest.setSessionType(sessionType);
taskRunnerCommandRequest.setSessionId(sessionId);
taskRunnerCommandRequest.setBalance(balance);
taskRunnerCommandRequest.setFullBalance(fullBalance);
taskRunnerCommandRequest.setSecuritySymbol(securitySymbol);
taskRunnerCommandRequest.setCreditLeg_amount(creditLeg_amount);
taskRunnerCommandRequest.setPaymentPurpose(paymentPurpose);
taskRunnerCommandRequest.setSenderId(senderId);
taskRunnerCommandRequest.setCreditLeg_accountId(creditLeg_accountId);
taskRunnerCommandRequest.setAddresseeId(addresseeId);
taskRunnerCommandRequest.setDebitLeg_accountId(debitLeg_accountId);
return taskRunnerCommandRequest;
}
@ -117,4 +155,76 @@ public class LauncherNew implements IAction<Object> {
public void setSessionId(Long sessionId) {
this.sessionId = sessionId;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public String getSecuritySymbol() {
return securitySymbol;
}
public void setSecuritySymbol(String securitySymbol) {
this.securitySymbol = securitySymbol;
}
public BigDecimal getCreditLeg_amount() {
return creditLeg_amount;
}
public void setCreditLeg_amount(BigDecimal creditLeg_amount) {
this.creditLeg_amount = creditLeg_amount;
}
public String getPaymentPurpose() {
return paymentPurpose;
}
public void setPaymentPurpose(String paymentPurpose) {
this.paymentPurpose = paymentPurpose;
}
public Long getSenderId() {
return senderId;
}
public void setSenderId(Long senderId) {
this.senderId = senderId;
}
public Long getCreditLeg_accountId() {
return creditLeg_accountId;
}
public void setCreditLeg_accountId(Long creditLeg_accountId) {
this.creditLeg_accountId = creditLeg_accountId;
}
public Long getAddresseeId() {
return addresseeId;
}
public void setAddresseeId(Long addresseeId) {
this.addresseeId = addresseeId;
}
public Long getDebitLeg_accountId() {
return debitLeg_accountId;
}
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

@ -84,7 +84,7 @@ public class DictionaryController {
@ApiParam(value = "Код словаря", required = true, example = "1234")
@PathVariable("code") String code) {
Imdg<AbstractDictionary> dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class);
AbstractDictionary value = dictionary.getSingleObjectByFieldValues(Map.of("code", code));
AbstractDictionary value = dictionary.getFirstObjectByFieldValues(Map.of("code", code));
if (value == null) throw new NotFound404Exception(dictionaryName + " code='" + code + "'");
DictionaryBackendGetSingleValueV2 response = new DictionaryBackendGetSingleValueV2();
response.setPayload(responseFactory.responseFromDictionary(dictionaryName, value));

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,67 +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);
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

@ -3,15 +3,23 @@ package ru.spcex.clearing.backendapi.security;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.spi.KeycloakAccount;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;;
import org.springframework.security.core.Authentication;
public class KeycloakUtils {
static Logger log = LoggerFactory.getLogger(KeycloakUtils.class);
/**
* Достать username из Keycloak имплементации Authentication
*/
public static String getUserNameFromAuthentication(Authentication authentication) {
if (authentication == null) return null;
if (!(authentication instanceof KeycloakAuthenticationToken)) { // AnonymousAuthenticationToken
log.trace("Authentication token class {} is not KeycloakAuthenticationToken", authentication.getClass().getName());
return null;
}
KeycloakAuthenticationToken auth = (KeycloakAuthenticationToken) authentication;
if (auth == null) return null;
KeycloakAccount details = (KeycloakAccount) auth.getDetails();
return ((KeycloakPrincipal) details.getPrincipal())
.getKeycloakSecurityContext()

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

@ -14,6 +14,10 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
/**
* Сервис для сигнализирования результатов запросов клиентов. Ассинхронное обновление статуса.
* Клиент запрашивает периодически (или по событию) таблицу Map_RequestInfo и видит результат выполнения запросов.
*/
@Service
public class RequestInfoAccepter extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
@ -37,9 +41,15 @@ public class RequestInfoAccepter extends QueueConsumer implements InitializingBe
private void updateRequestInfo(BaseRequest<RequestInfoUpdate> requestInfoUpdateBaseRequest) {
//will throw exception for any class other than RequestInfoUpdate
RequestInfoUpdate statusInfo = requestInfoUpdateBaseRequest.getRequestPayload();
if (statusInfo == null || statusInfo.getId() == null) {
log.warn("BaseRequest id={}, RequestPayload={}: requestInfo id was null",
requestInfoUpdateBaseRequest.getId(), statusInfo);
return;
}
RequestInfo requestInfo = requestInfoImdg.getSingleObjectByID(statusInfo.getId());
if (requestInfo == null) {
log.warn("unknown requestInfo id={}", statusInfo.getId());
log.warn("unknown requestInfo id={}; statusInfo: {}",
statusInfo.getId(), statusInfo);
return;
}
requestInfo.setStatus(statusInfo.getStatus());

View file

@ -58,7 +58,7 @@ public class OperatorImpl implements IOperator {
protected Long currentUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
User user = StringUtils.isEmpty(username) ? null : userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
User user = StringUtils.isEmpty(username) ? null : userImdg.getFirstObjectByFieldValues(Map.of("identifier", username));
if (user == null) {
log.warn("UserID not found by login \"{}\"", username);
return null;
@ -82,6 +82,7 @@ public class OperatorImpl implements IOperator {
saveRequestToStorage(destination, request);
Future<RecordMetadata> send = kafka.send(new ProducerRecord<>(destination, request));
send.get();
log.debug("Request id={} by user {} send to queue \"{}\". Action: {}", request.getId(), request.getUserId(), destination, iAction);
return new QueueSuccessResponse(request.getActionType(), request.getId());
}
@ -101,13 +102,15 @@ public class OperatorImpl implements IOperator {
saveRequestToStorage(destination, request);
Future<RecordMetadata> send = kafka.send(new ProducerRecord<>(destination, request));
send.get();
log.debug("Request id={} by user {} send to queue \"{}\". Action: {}", request.getId(), userId, destination, iAction);
return new QueueSuccessResponse(request.getActionType(), request.getId());
}
private void saveRequestToStorage(String destination, BaseRequest<Object> request) {
Imdg<RequestInfo> requestStorage = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
RequestInfo requestInfo = RequestInfo.create(request.getId());
requestStorage.insert(requestInfo);
Long storeId = requestStorage.insert(requestInfo);
log.trace("Request id={} saved as RequestInfo with id={}", request.getId(), storeId);
}
private void throwValidate(String destination, IAction<?> iAction) {

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

@ -37,10 +37,8 @@ public class ActionValidationProvider implements InitializingBean {
@Override
public void afterPropertiesSet() {
validators.put(Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE, idPresent(IMDGDistributedNames.Map_MoneyMarketSecurity));
validators.put(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, idPresent(IMDGDistributedNames.Map_MoneyMarketSecurity));
validators.put(Consts.DESTINATION_RELATION_UPDATE, idPresent(IMDGDistributedNames.Map_Relation));
validators.put(Consts.LAUNCHER_NEW, taskRunnerNew());
validators.put(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, idPresent(IMDGDistributedNames.Map_Registry));
}
@SuppressWarnings("unchecked")

View file

@ -18,7 +18,7 @@ public enum LauncherNewValidationRule implements IValidationRule<ImdgValidationC
public Optional<EnumMessage> validate(ImdgValidationContext<LauncherNew> context) {
LauncherNew validatedObject = context.getValidatedObject();
Imdg<AbstractDictionary> taskDictionaryImdg = context.obtainMap(IMDGDistributedNames.Map_TaskDictionary, AbstractDictionary.class);
AbstractDictionary taskEnum = taskDictionaryImdg.getSingleObjectByFieldValues(Map.of("code", validatedObject.getTask()));
AbstractDictionary taskEnum = taskDictionaryImdg.getFirstObjectByFieldValues(Map.of("code", validatedObject.getTask()));
if (taskEnum == null) {
return of(BackEndError.ResourceNotFound, "taskDictionary " + validatedObject.getTask());
}

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
@ -23,6 +26,10 @@ backend-api.kafka-consumer.auto-offset-reset=latest
backend-api.kafka-consumer.linger-ms=1
backend-api.kafka-consumer.buffer-memory=33554432
backend-api.security.authorization-disabled=false
#access logs, sample
#server.tomcat.accesslog.directory=logs
#server.tomcat.accesslog.enabled=true
#server.tomcat.accesslog.pattern=%h %l %u %t \"%r\" %>s %b
##keycloak
##keycloak.auth-server-url=http://10.200.200.147:8080/
##keycloak.realm=master

File diff suppressed because it is too large Load diff

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>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,8 @@
<xsl:template match="meta">-- DB version: <xsl:value-of select="$meta/@version"/>
-- DATA version: <xsl:value-of select="@version"/>
-- INSERT INTO DB_VERSION(ID, VERSION) values (1, '<xsl:value-of select="$meta/@version"/>') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION
<xsl:apply-templates select="*"/>
</xsl:template>

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>
@ -73,12 +76,12 @@ COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>_HISTORY.EVENT_TYPE IS '
<xsl:variable name="tp" select="@type"/>
<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:when test="@linkKeyCode"></xsl:when>
<!--<xsl:when test="@linkKeyCode"></xsl:when>-->
<xsl:when test="@extends"></xsl:when>
<xsl:otherwise><xsl:if test="position() != '1'">, </xsl:if><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="@linkKeyCode"></xsl:when>
<!--<xsl:when test="@linkKeyCode"></xsl:when>-->
<xsl:when test="@extends"></xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text><xsl:value-of select="/meta/types/*[@id=$tp]/@type"/>
@ -96,7 +99,7 @@ COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>.<xsl:call-template name=
<xsl:template match="*" mode="comment-objects">
<xsl:choose>
<xsl:when test="@linkKeyCode"></xsl:when>
<!--<xsl:when test="@linkKeyCode"></xsl:when>-->
<xsl:when test="@extends"></xsl:when>
<xsl:otherwise>
<xsl:variable name="dbTableName"><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name(parent::*)'/></xsl:call-template></xsl:variable>
@ -106,7 +109,7 @@ COMMENT ON COLUMN <xsl:value-of select="$dbTableName"/>.<xsl:call-template name=
<xsl:template match="*" mode="comment-history-objects"><!-- todo похож на comment-objects только именем таблицы различается попробовать объединить -->
<xsl:choose>
<xsl:when test="@linkKeyCode"></xsl:when>
<!--<xsl:when test="@ "></xsl:when>-->
<xsl:when test="@extends"></xsl:when>
<xsl:otherwise>
<xsl:variable name="dbTableName"><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name(parent::*)'/></xsl:call-template></xsl:variable>

View file

@ -255,48 +255,44 @@ public class <xsl:value-of select="$nameObjFmt"/>HistoryMapStore extends Templat
}
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="mapstore-field-getFields" ><xsl:if test="position() != '1'">, </xsl:if> "<xsl:choose>
<xsl:template match="*" mode="mapstore-field-getFields" ><xsl:choose><xsl:when test="@extends"></xsl:when><xsl:otherwise><xsl:if test="position() != '1'">, </xsl:if> "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"</xsl:template>
</xsl:choose>"</xsl:otherwise></xsl:choose></xsl:template>
<xsl:template match="*" mode="mapstore-field-setters" >
<xsl:variable name="tp" select="@type"/>
<xsl:variable name="javatp" select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:choose>
<xsl:when test="$javatp='Instant'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getInstantFromTimestamp(resultSet, "<xsl:choose>
<xsl:text> <!-- space &#160; 4 new line -->
</xsl:text><xsl:if test="@extends">//ext: </xsl:if>
<xsl:variable name="javatp" select="/meta/types/*[@id=$tp]/@javatype"/>
<xsl:choose>
<xsl:when test="$javatp='Instant'">object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getInstantFromTimestamp(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:when test="$javatp='LocalDate'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalDateFromSqlDate(resultSet, "<xsl:choose>
<xsl:when test="$javatp='LocalDate'">object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalDateFromSqlDate(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:when test="$javatp='LocalTime'">
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalTimeFromSqlTime(resultSet, "<xsl:choose>
<xsl:when test="$javatp='LocalTime'">object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(getLocalTimeFromSqlTime(resultSet, "<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>"))</xsl:when>
<xsl:otherwise>
object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(resultSet.getObject("<xsl:choose>
<xsl:otherwise>object.set<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>(resultSet.getObject("<xsl:choose>
<xsl:when test="@dbfield"><xsl:value-of select="@dbfield"/></xsl:when>
<xsl:otherwise><xsl:call-template name='convertDbStyle'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:otherwise>
</xsl:choose>", <xsl:value-of select="$javatp"/>.class))</xsl:otherwise>
</xsl:choose>;</xsl:template>
<xsl:template match="*" mode="mapstore-field-getters" ><xsl:if test="position() != '1'">, </xsl:if><!-- todo запятую в конце а не в начале, см. last()-->
<xsl:template match="*" mode="mapstore-field-getters" ><xsl:if test="position() != '1' and not(@extends)">, </xsl:if><!-- todo запятую в конце а не в начале, см. last()-->
<xsl:variable name="tp" select="@type"/>
<xsl:variable name="javatp" select="/meta/types/*[@id=$tp]/@javatype"/>
<xsl:text> <!-- space &#160; 4 new line -->
</xsl:text><xsl:if test="@extends">//ext: </xsl:if>
<xsl:choose>
<xsl:when test="$javatp='Instant'">
TimeUtil.toDateFromInstant(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalDate'">
TimeUtil.toDateFromLocalDate(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalTime'">
TimeUtil.toDateFromLocalTime(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:otherwise>
object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>()</xsl:otherwise>
</xsl:choose>
<xsl:when test="$javatp='Instant'">TimeUtil.toDateFromInstant(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalDate'">TimeUtil.toDateFromLocalDate(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:when test="$javatp='LocalTime'">TimeUtil.toDateFromLocalTime(object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>())</xsl:when>
<xsl:otherwise>object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template>()</xsl:otherwise></xsl:choose>
</xsl:template>
@ -305,7 +301,7 @@ object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconv
<xsl:variable name="tp" select="@type"/>
<xsl:if test="name()='id'"> // (in parent) </xsl:if> private <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:text> <!-- space &#160; --></xsl:text><xsl:value-of select="name()"/>;
<xsl:if test="@extends"> // extend: </xsl:if><xsl:if test="name()='id'"> // (in parent) </xsl:if> private <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> <xsl:text> <!-- space &#160; --></xsl:text><xsl:value-of select="name()"/>;
<xsl:choose>
<xsl:when test="@dbfield"> // DB field: <xsl:value-of select="@dbfield"/></xsl:when>
<!-- new line -->
@ -360,6 +356,7 @@ object.get<xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconv
<xsl:variable name="tp" select="@type"/>
<xsl:choose>
<xsl:when test="name()='id'"></xsl:when>
<xsl:when test="@extends"></xsl:when>
<xsl:otherwise>
<xsl:variable name="NameFmt"><xsl:call-template name='convertFirstUC_'><xsl:with-param name='toconvert' select='name()'/></xsl:call-template></xsl:variable>
public <xsl:value-of select="/meta/types/*[@id=$tp]/@javatype"/> get<xsl:value-of select="$NameFmt"/>() {

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

@ -21,7 +21,7 @@ class UserSettingsControllerTest extends AbstractControllerTest {
//ARRANGE
UserSettings userSettings = new UserSettings();
userSettings.setId(currentId.get());
userSettings.setUserId(currentId.get());
userSettings.setUserId(currentId.get()); // отдаются по userId CLS-64, todo в тесте null
userSettings.setJson("json");
userSettings.setVersion("version");

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);
}

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