Compare commits
229 commits
imdg_hist
...
10_01_2024
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c2ce48bd1 | ||
|
|
0fd9208e41 | ||
|
|
ab80d194a5 | ||
|
|
6590d63026 | ||
|
|
b96fcaae7d | ||
|
|
517dc8669a | ||
|
|
8df2442aa6 | ||
|
|
c959023094 | ||
|
|
54c3d7c235 | ||
|
|
892bdcb769 | ||
|
|
66ead14acb | ||
|
|
072a5dbcd9 | ||
|
|
730ae2aba4 | ||
|
|
5ad1b0d569 | ||
|
|
2a400e1a8a | ||
|
|
c8336ce8a4 | ||
|
|
08867e3cb9 | ||
|
|
999b0999de | ||
|
|
038f676eef | ||
|
|
c5a62a0bd4 | ||
|
|
ab34364a22 | ||
|
|
91b6f9efbc | ||
|
|
9a279eead8 | ||
|
|
c5f79afb50 | ||
|
|
de9619376b | ||
|
|
0dd5cec12e | ||
|
|
cd488b19d8 | ||
|
|
1ec2b25714 | ||
|
|
8fe43dee98 | ||
|
|
49b3191a63 | ||
|
|
2a81e33b78 | ||
|
|
313ff28cbd | ||
|
|
2656d6a78c | ||
|
|
dc21de68f2 | ||
|
|
2c2cc64595 | ||
|
|
17910bd224 | ||
|
|
02e2b3a3f2 | ||
|
|
fe48b00464 | ||
|
|
3f5fa0433f | ||
|
|
4e78439e54 | ||
|
|
673bb48938 | ||
|
|
0dc90cf828 | ||
|
|
afbe819255 | ||
|
|
9b8e68a94c | ||
|
|
d5e764131d | ||
|
|
793171b3da | ||
|
|
4bcc725c26 | ||
|
|
2da0ac042c | ||
|
|
99f4dbe292 | ||
|
|
4bd6dab4b1 | ||
|
|
e028aee516 | ||
|
|
7641b2691c | ||
|
|
970da463fc | ||
|
|
5639f9ff8b | ||
|
|
8e948bc27a | ||
|
|
0b2bef797e | ||
|
|
e04460b194 | ||
|
|
0c00c7fdb3 | ||
|
|
494bafbe18 | ||
|
|
4b1b6113f4 | ||
|
|
53198ca9f5 | ||
|
|
3e6b8911c9 | ||
|
|
1d4d831ea7 | ||
|
|
085b0cf4ce | ||
|
|
632bdf9e09 | ||
|
|
866c063b0d | ||
|
|
911c90bc45 | ||
|
|
8ae41b9d16 | ||
|
|
37a741e866 | ||
|
|
4a0df9bb48 | ||
|
|
939ea451a1 | ||
|
|
ee0f95fcde | ||
|
|
4581592380 | ||
|
|
4e431ee798 | ||
|
|
10d8803651 | ||
|
|
fac5dca462 | ||
|
|
06b38cc61f | ||
|
|
4dfb642e1b | ||
|
|
740c138ead | ||
|
|
0d134db9c6 | ||
|
|
deaa77a05c | ||
|
|
c86f1e907a | ||
|
|
04bc8e9edf | ||
|
|
e8cba0467a | ||
|
|
9f988d34c0 | ||
|
|
3fbb5931df | ||
|
|
15242a0a75 | ||
|
|
5cd8608584 | ||
|
|
943ec5f762 | ||
|
|
20f6c6a939 | ||
|
|
9e9a801bde | ||
|
|
a8386a9ed9 | ||
|
|
fd25105fe8 | ||
|
|
858e02084b | ||
|
|
eb3bed4a1d | ||
|
|
8079ec1fb3 | ||
|
|
cc2f20de3c | ||
|
|
145d3f4c74 | ||
|
|
e6ede79021 | ||
|
|
a2ebfd945b | ||
|
|
c7ad0a181c | ||
|
|
12ff85188f | ||
|
|
9c827763de | ||
|
|
59d0b000d1 | ||
|
|
60e7c6ac39 | ||
|
|
9b26fb2290 | ||
|
|
81c4c9fa99 | ||
|
|
9ac71532f7 | ||
|
|
79eaffbda6 | ||
|
|
8deebfafbb | ||
|
|
31de64e5bb | ||
|
|
afeede8baa | ||
|
|
286b3ace2c | ||
|
|
2f54dcaccf | ||
|
|
bcb4307acd | ||
|
|
0bc0f9461f | ||
|
|
681e612bbd | ||
|
|
b5b204bf5f | ||
|
|
a2dcd21867 | ||
|
|
9eff119ff2 | ||
|
|
2a61062eb9 | ||
|
|
fba4a07513 | ||
|
|
7b24b1d6ab | ||
|
|
e7c48f17e6 | ||
|
|
520233356b | ||
|
|
68a1a4d9d9 | ||
|
|
3437106728 | ||
|
|
a3d2726b23 | ||
|
|
269a74960b | ||
|
|
0befdfab92 | ||
|
|
90aba79ded | ||
|
|
02c768d273 | ||
|
|
55c8486507 | ||
|
|
e8895ebd84 | ||
|
|
39b1b25c80 | ||
|
|
e7ac9a8784 | ||
|
|
f4f313a1ce | ||
|
|
e4c362db00 | ||
|
|
846a364164 | ||
|
|
6dece4c19f | ||
|
|
113d0e0d65 | ||
|
|
03eb67f82e | ||
|
|
4006c1f233 | ||
|
|
789f18181a | ||
|
|
50ebdbacb9 | ||
|
|
894408354b | ||
|
|
3eaa2a9ac6 | ||
|
|
dc3ea5d48a | ||
|
|
391384fab2 | ||
|
|
0b4c277ea0 | ||
|
|
98a2cf46d2 | ||
|
|
38dab80e99 | ||
|
|
aa1e5f7ac1 | ||
|
|
6f04b15527 | ||
|
|
0522b3a562 | ||
|
|
76a1b74c4b | ||
|
|
53810fd4f1 | ||
|
|
723f177c25 | ||
|
|
5fd85852bb | ||
|
|
1af852e09c | ||
|
|
7e2e9dcd51 | ||
|
|
7a359c1d98 | ||
|
|
ffe2134dfd | ||
|
|
f905772251 | ||
|
|
93951a3bf5 | ||
|
|
0744364924 | ||
|
|
64c174e806 | ||
|
|
a4c4fe8c71 | ||
|
|
98922dac8c | ||
|
|
815631d5d2 | ||
|
|
98523cf528 | ||
|
|
a9ef98f4da | ||
|
|
c10e41b29e | ||
|
|
1da3af6b7a | ||
|
|
9e009307f4 | ||
|
|
934b9babd3 | ||
|
|
b15334d8ac | ||
|
|
d78105c3b7 | ||
|
|
2b3571ec85 | ||
|
|
afdfa0d6d6 | ||
|
|
6d5e5fd00e | ||
|
|
d2cf49b7c8 | ||
|
|
e99311b582 | ||
|
|
4da67d145d | ||
|
|
5aca4dc82f | ||
|
|
49119bcabd | ||
|
|
e8bb442588 | ||
|
|
93080c76c9 | ||
|
|
553d829b4f | ||
|
|
f36286e14b | ||
|
|
4f2daf06d8 | ||
|
|
afc8fb0b54 | ||
|
|
9382c6bb2c | ||
|
|
dd4cd2a314 | ||
|
|
40978a0017 | ||
|
|
9ed6a75fe5 | ||
|
|
ef317a07a5 | ||
|
|
6ec042bd30 | ||
|
|
646c8c7e77 | ||
|
|
ef972a593d | ||
|
|
e278bc1bb8 | ||
|
|
36b0381294 | ||
|
|
5adeeec3f7 | ||
|
|
a743de0dd1 | ||
|
|
7fa35d108d | ||
|
|
11f6ea0b84 | ||
|
|
bd7f6ad460 | ||
|
|
caeece00f3 | ||
|
|
43911cbb58 | ||
|
|
252b89652d | ||
|
|
4b089a91ae | ||
|
|
c66df265d9 | ||
|
|
90a2b858bb | ||
|
|
c93e59c814 | ||
|
|
1be10820a3 | ||
|
|
2ee26a3d68 | ||
|
|
96b5e90ebf | ||
|
|
8a2855e32b | ||
|
|
03aa29413c | ||
|
|
83ff343c92 | ||
|
|
bf3ba4e6aa | ||
|
|
4951559891 | ||
|
|
4df7131630 | ||
|
|
e16767c15a | ||
|
|
b749839963 | ||
|
|
9a074addcf | ||
|
|
c940316494 | ||
|
|
a80742af7d | ||
|
|
e40a8dc724 |
278 changed files with 9288 additions and 3755 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,10 +59,14 @@ public class AccountValidationConfig {
|
|||
),
|
||||
FieldRequiredSpecificRule.instance("account",
|
||||
CorrespondentAccountNewRequest::getAccount,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.AccountFieldNotSet,
|
||||
false,
|
||||
accountValue -> {
|
||||
if (accountValue.isBlank())
|
||||
return new EnumMessage(AccountError.RequiredFieldEmpty, "account");
|
||||
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
|
||||
);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class ValidationConfig {
|
|||
addImdg.accept(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
|
||||
|
||||
//for ClientCodeValidationConfig
|
||||
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public enum AccountError implements IErrorEnumId {
|
|||
ClearingCategoryNotFound(5019L),
|
||||
ClearingCompanySymbolNotFound(5022L), // Для компании %s отсутствует клиринговый код».
|
||||
AccountForTradingClearingRegistryAlreadyUsed(5023L),
|
||||
AccountFieldNotSet(5024L),
|
||||
AccountDepoTypeRequired(5025L),
|
||||
TradingClearingRegistryNotFound(3022L),
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -55,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;
|
||||
|
|
@ -67,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")
|
||||
|
|
@ -74,6 +78,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
@Qualifier("correspondentAccountBlockRequestValidator")
|
||||
Function<CommonIdRequest, IValidator> accountBlockRequestValidator) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
this.accountHelper = accountHelper;
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.accountMap = imdgProvider.getImdg(
|
||||
IMDGDistributedNames.Map_Account, Account.class
|
||||
|
|
@ -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;
|
||||
|
|
@ -128,6 +134,12 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
Account account = new Account();
|
||||
account.setCompanyId(req.getCompanyId());
|
||||
account.setAccount(req.getAccount());
|
||||
if (AccountType.Info.equalsByKey(req.getAccountType())) {
|
||||
Long infoSequenceId = informationAccountService.accountNextId();
|
||||
String accountValue = informationAccountService.generateInfoAccount(infoSequenceId);
|
||||
log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue);
|
||||
account.setAccount(accountValue);
|
||||
}
|
||||
account.setAccountType(req.getAccountType());
|
||||
if (req.getStatus() == null) {
|
||||
account.setStatus(WorkflowStatus.Active.getKey());
|
||||
|
|
@ -138,7 +150,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
account.setCreated(now);
|
||||
account.setUpdated(now);
|
||||
|
||||
requestInfoUpdate = fillAccountFromRelation(account, userRequest.getId(), false);
|
||||
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
|
||||
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||
|
||||
Long newId = null;
|
||||
|
|
@ -159,7 +171,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
} else if (AccountType.Info.equalsByKey(account.getAccountType()))
|
||||
makeInfoPart(imdgTransaction, account);
|
||||
else if (AccountType.Depo.equalsByKey(account.getAccountType()))
|
||||
makeDepoPart(imdgTransaction, account);
|
||||
makeDepoPart(imdgTransaction, account, req);
|
||||
else if (AccountType.Clrn.equalsByKey(account.getAccountType()))
|
||||
makeClrnPart(imdgTransaction, account);
|
||||
else {
|
||||
|
|
@ -198,17 +210,22 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
log.debug("For account id={} make InformationAccount id={}", account.getId(), infoId);
|
||||
}
|
||||
|
||||
protected void makeDepoPart(ImdgTransaction imdgTransaction, Account account) {
|
||||
Imdg<DepoAccount> depoAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);;
|
||||
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);;
|
||||
Imdg<ClearingAccount> clearingAccountMap = imdgTransaction.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
|
||||
ClearingAccount clnrAcc = new ClearingAccount();
|
||||
clnrAcc.setAccountId(account.getId());
|
||||
clnrAcc.setCompanyId(account.getCompanyId());
|
||||
|
|
@ -306,60 +323,6 @@ public class AccountService extends QueueConsumer implements InitializingBean {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Заполняет поля relationId и companyId из соответствующей записи Relation
|
||||
*
|
||||
* @param requestId Идентификатор запроса для вывода лога
|
||||
*/
|
||||
public RequestInfoUpdate fillAccountFromRelation(Account account, Long requestId, boolean checkClearingMemberCategory) {
|
||||
Long companyId = account.getCompanyId();
|
||||
Collection<Relation> relations;
|
||||
ImdgPredicateBuilder relationPredicateBuilder = relationMap.predicateBuilder();
|
||||
ImdgPredicate finalRelationPredicate;
|
||||
if (checkClearingMemberCategory) {
|
||||
ImdgPredicateBuilder clearingMemberCategoryPredicateBuilder = clearingMemberCategoryMap.predicateBuilder();
|
||||
ImdgPredicate companyIdEquals = clearingMemberCategoryPredicateBuilder.equals("companyId", companyId);
|
||||
Collection<ClearingMemberCategory> clearingMemberCategories = clearingMemberCategoryMap.getCollectionObjectsByPredicate(companyIdEquals);
|
||||
|
||||
if (clearingMemberCategories.isEmpty())
|
||||
return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, "(any)");
|
||||
if (clearingMemberCategories.size() > 1)
|
||||
log.warn("ClearingMemberCategory for companyId {} contains multiply elements, use first", companyId);
|
||||
ClearingMemberCategory clearingMemberCategory = clearingMemberCategories.iterator().next();
|
||||
|
||||
ImdgPredicate consumerIdPredicate = relationPredicateBuilder.equals("consumerId", companyId);
|
||||
ImdgPredicate servicePredicate;
|
||||
String clearingCategoryValue = clearingMemberCategory.getClearingMemberCategory();
|
||||
if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.B, ClearingCategory.I, ClearingCategory.V)) {
|
||||
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.MKR.getKey());
|
||||
} else if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.F, ClearingCategory.C)) {
|
||||
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.FOND.getKey());
|
||||
} else {
|
||||
log.info("ClearingCategoryNotFound with clearingCategoryValue={} not implemented. Do not search Relation.", clearingCategoryValue);
|
||||
return null;
|
||||
//return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, clearingCategoryValue + " (case not implemented)");
|
||||
}
|
||||
finalRelationPredicate = relationPredicateBuilder.and(consumerIdPredicate, servicePredicate);
|
||||
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
|
||||
} else {
|
||||
finalRelationPredicate = relationPredicateBuilder.equals("consumerId", companyId);
|
||||
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
|
||||
}
|
||||
|
||||
if (relations.isEmpty()) {
|
||||
//return makeError(requestId, AccountError.WrongFieldValue, "companyId", finalRelationPredicate.toString());
|
||||
log.info("Relation not found: {}", finalRelationPredicate.toString());
|
||||
return null;
|
||||
}
|
||||
if (relations.size() > 1)
|
||||
log.warn("Relation for consumerId {} contains multiply elements, use first", companyId);
|
||||
Relation relation = relations.iterator().next();
|
||||
account.setRelationId(relation.getId());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private RequestInfoUpdate makeError(Long reqId, AccountError accountError, Object... args) {
|
||||
String errMsg = messageResolver.resolve(new EnumMessage(accountError, args));
|
||||
return new RequestInfoUpdate()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
|
|||
private final UserRoleVerification userRoleVerification;
|
||||
private final ValidationHelper validationHelper;
|
||||
|
||||
private final AccountService accountService;
|
||||
private final AccountHelper accountService;
|
||||
|
||||
private final Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator;
|
||||
private final Function<BankAccountUpdateRequest, IValidator> bankAccountUpdateRequestValidator;
|
||||
|
|
@ -53,7 +53,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
|
|||
ImdgProvider imdgProvider,
|
||||
UserRoleVerification userRoleVerification,
|
||||
ValidationHelper validationHelper,
|
||||
AccountService accountService,
|
||||
AccountHelper accountService,
|
||||
@Qualifier("bankAccountNewRequestValidator")
|
||||
Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator,
|
||||
@Qualifier("bankAccountUpdateRequestValidator")
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ import java.util.function.Function;
|
|||
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;
|
||||
|
|
@ -70,6 +70,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
|
|||
private final Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator;
|
||||
|
||||
private final Imdg<Account> accountImdg;
|
||||
private final Imdg<ClearingAccount> clearingAccountImdg;
|
||||
private final Imdg<Company> companyImdg;
|
||||
private final Imdg<Relation> relationImdg;
|
||||
private final Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
|
||||
|
|
@ -81,7 +82,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
|
|||
public ClearingAccountService(Consumer<String, Object> kafkaQueue,
|
||||
Producer<String, Object> kafkaResponseQueue,
|
||||
KafkaSender kafkaSender,
|
||||
AccountService accountService,
|
||||
AccountHelper accountService,
|
||||
SDFProcessService sdfProcessService,
|
||||
ValidationHelper validationHelper,
|
||||
ImdgProvider imdgProvider,
|
||||
|
|
@ -103,6 +104,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
|
|||
this.clearingAccountUpdateRequestValidator = clearingAccountUpdateRequestValidator;
|
||||
|
||||
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||
this.clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
|
|
@ -362,11 +364,16 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
|
|||
);
|
||||
Account account = sDf52.getAccount() == null ? null : accountImdg.getFirstObjectByFieldValues(accountQuery);
|
||||
if (account == null) {
|
||||
String msg = messageResolver.resolve(new EnumMessage(AccountError.AccountNotFound, sDf52.getAccount()));
|
||||
log.warn("By generationId={} s_df52[{}] (query: {}) error: {}", groupId, sDf52.getId(), accountQuery, msg);
|
||||
toProcessSDF53.add(new MutableTriple<>(sDf52, null,
|
||||
makeSdfErrorText(AccountError.AccountNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND)));
|
||||
continue;
|
||||
if (SDFProcessService.SDF52_STATUS_3Open.equals(sDf52.getStatus())) {
|
||||
log.debug("By generationId={} s_df52[{}].status={}, but account not found (query: {}). COntinuse with result OK for status 3",
|
||||
groupId, sDf52.getId(), sDf52.getStatus(), accountQuery);
|
||||
} else {
|
||||
String msg = messageResolver.resolve(new EnumMessage(AccountError.AccountNotFound, sDf52.getAccount()));
|
||||
log.warn("By generationId={} s_df52[{}] (query: {}) error: {}", groupId, sDf52.getId(), accountQuery, msg);
|
||||
toProcessSDF53.add(new MutableTriple<>(sDf52, null,
|
||||
makeSdfErrorText(AccountError.AccountNotFound, SDFProcessService.SDF_STATUS_ERROR_COMPANY_NOT_FOUND)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
toProcessSDF53.add(new MutableTriple<>(sDf52, account, SDFProcessService.SDF_STATUS_OK));
|
||||
toUpdate.add(new Pair<>(sDf52, account));
|
||||
|
|
|
|||
|
|
@ -23,10 +23,7 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
|||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.validation.common.ValidationHelper;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.SdfTable;
|
||||
import ru.spcex.platform.enumeration.ServiceStatus;
|
||||
import ru.spcex.platform.enumeration.WorkflowStatus;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.ImdgTransaction;
|
||||
|
|
@ -44,7 +41,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
|
|||
private final KafkaSender kafkaSender;
|
||||
private final ValidationHelper validationHelper;
|
||||
private final ImdgProvider imdgProvider;
|
||||
private final AccountService accountService;
|
||||
private final AccountHelper accountService;
|
||||
private final Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator;
|
||||
|
||||
public DepoAccountService(Consumer<String, Object> kafkaQueue,
|
||||
|
|
@ -52,7 +49,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
|
|||
KafkaSender kafkaSender,
|
||||
ValidationHelper validationHelper,
|
||||
ImdgProvider imdgProvider,
|
||||
AccountService accountService,
|
||||
AccountHelper accountService,
|
||||
@Qualifier("depoAccountNewRequestValidator")
|
||||
Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
|
|
@ -114,7 +111,11 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
|
|||
depoAccount = new DepoAccount();
|
||||
depoAccount.setCompanyId(req.getCompanyId());
|
||||
depoAccount.setAccountId(accountId);
|
||||
depoAccount.setDepoAccountType(req.getDepoAccountType());
|
||||
if (account.getAccount() != null && account.getAccount().contains("BC")) {
|
||||
depoAccount.setDepoAccountType(DepoAccountType.C.getKey());
|
||||
} else {
|
||||
depoAccount.setDepoAccountType(req.getDepoAccountType());
|
||||
}
|
||||
depoAccountId = depoAccountImdg.insert(depoAccount);
|
||||
txOk = true;
|
||||
} finally {
|
||||
|
|
@ -188,7 +189,11 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
|
|||
DepoAccount depoAccount = new DepoAccount();
|
||||
depoAccount.setCompanyId(accountReq.getCompanyId());
|
||||
depoAccount.setAccountId(accountId);
|
||||
depoAccount.setDepoAccountType(accountReq.getAccountType());
|
||||
if (account.getAccount() != null && account.getAccount().contains("BC")) {
|
||||
depoAccount.setDepoAccountType(DepoAccountType.C.getKey());
|
||||
} else {
|
||||
depoAccount.setDepoAccountType(accountReq.getAccountType());
|
||||
}
|
||||
depoAccountId = depoAccountImdg.insert(depoAccount);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
|
|||
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;
|
||||
|
|
@ -73,7 +73,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
|
|||
UserRoleVerification userRoleVerification,
|
||||
ImdgProvider imdgProvider,
|
||||
ValidationHelper validationHelper,
|
||||
AccountService accountService,
|
||||
AccountHelper accountHelper,
|
||||
RequestHelper requestHelper,
|
||||
@Qualifier("informationAccountNewRequestValidator")
|
||||
Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) {
|
||||
|
|
@ -83,7 +83,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
|
|||
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(
|
||||
|
|
@ -147,7 +147,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
|
|||
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();
|
||||
|
|
@ -239,7 +239,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
|
|||
account.setCompanyId(forCompanyId);
|
||||
account.setCreated(now);
|
||||
account.setUpdated(now);
|
||||
requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), false);
|
||||
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
|
||||
if (requestInfoUpdate != null) {
|
||||
log.debug("Stop make new account, cause error: {}", requestInfoUpdate.getMessage());
|
||||
return requestInfoUpdate;
|
||||
|
|
@ -304,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.");
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ public class SDFProcessService {
|
|||
public static final String SDF_STATUS_ERROR_NO_TRADE = "4"; // (Ошибка. Торги не идут)
|
||||
public static final String SDF_STATUS_ERROR = "9"; // (Другие ошибки, выявленные в КС) - если получены другие ошибки (т.е. account НЕ обновлена по sDf52).
|
||||
|
||||
protected static final Long SDF52_STATUS_0Blocked = 0L;
|
||||
protected static final Long SDF52_STATUS_1Unblocked = 1L;
|
||||
protected static final Long SDF52_STATUS_2Closed = 2L;
|
||||
protected static final Long SDF52_STATUS_3Open = 3L;
|
||||
|
||||
final protected Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected final Producer<String, Object> kafkaResponseQueue;
|
||||
|
|
@ -129,12 +134,12 @@ public class SDFProcessService {
|
|||
* @return AccountStatus или null
|
||||
*/
|
||||
public AccountStatus parseSdf52Status(Long status) {
|
||||
if (Long.valueOf(1L).equals(status) || Long.valueOf(3L).equals(status)) {
|
||||
if (SDF52_STATUS_1Unblocked.equals(status) || SDF52_STATUS_3Open.equals(status)) {
|
||||
return AccountStatus.ACTIVE;
|
||||
} else if (Long.valueOf(0L).equals(status)) {
|
||||
} else if (SDF52_STATUS_0Blocked.equals(status)) {
|
||||
return AccountStatus.BLOCKED;
|
||||
}
|
||||
if (Long.valueOf(2L).equals(status)) {
|
||||
if (SDF52_STATUS_2Closed.equals(status)) {
|
||||
return AccountStatus.CLOSE;
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.MockProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
|
|
@ -23,40 +21,28 @@ import ru.clearing.platform.dictionary.AccountTypeDictionary;
|
|||
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
|
||||
import ru.spcex.clearing.account.config.BeanConfiguration;
|
||||
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.InformationAccountValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.ValidationConfig;
|
||||
import ru.spcex.clearing.account.utils.MatcherFactory;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
|
||||
import ru.spcex.clearing.platform.messaging.service.Status;
|
||||
import ru.spcex.clearing.test.MatcherFactory;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
|
|
@ -64,6 +50,9 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
|
|||
ValidationConfig.class,
|
||||
AccountValidationConfig.class,
|
||||
AccountService.class,
|
||||
AccountHelper.class,
|
||||
InformationAccountService.class,
|
||||
InformationAccountValidationConfig.class,
|
||||
ImdgTestConfig.class,
|
||||
KafkaTestConfig.class})
|
||||
class AccountServiceTest {
|
||||
|
|
@ -209,8 +198,16 @@ class AccountServiceTest {
|
|||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
Account resultUpdating = accountImdg.getSingleObjectByID(accountId);
|
||||
existAccount.setUpdated(resultUpdating.getUpdated());
|
||||
ACCOUNT_MATCHER.assertMatch(resultUpdating, existAccount);
|
||||
Account expectAccount = new Account();
|
||||
expectAccount.setId(existAccount.getId());
|
||||
expectAccount.setAccount(account);
|
||||
expectAccount.setAccountType(AccountType.Corr.getKey());
|
||||
expectAccount.setStatus(ServiceStatus.Closed.getKey());
|
||||
expectAccount.setCompanyId(companyId);
|
||||
expectAccount.setCreated(existAccount.getCreated());
|
||||
expectAccount.setUpdated(resultUpdating.getUpdated());
|
||||
expectAccount.setStatus(ServiceStatus.Active.getKey());
|
||||
ACCOUNT_MATCHER.assertMatch(resultUpdating, expectAccount);
|
||||
accountImdg.delete(resultUpdating);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, "Должен был удалиться");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.MockProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
|
|
@ -25,7 +21,6 @@ import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
|
|||
import ru.spcex.clearing.account.config.validation.BankAccountValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.ValidationConfig;
|
||||
import ru.spcex.clearing.account.errors.AccountError;
|
||||
import ru.spcex.clearing.account.utils.MatcherFactory.Matcher;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
|
|
@ -34,12 +29,13 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewReq
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.test.MatcherFactory.Matcher;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
|
|
@ -49,13 +45,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.platform.messaging.service.Status.Error;
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
AccountService.class,
|
||||
AccountHelper.class,
|
||||
BankAccountService.class,
|
||||
ValidationConfig.class,
|
||||
BankAccountValidationConfig.class,
|
||||
|
|
@ -97,15 +94,11 @@ public class BankAccountServiceTest {
|
|||
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private HazelcastService hazelcastServiceTest;
|
||||
private ImdgProvider hazelcastServiceTest;
|
||||
|
||||
@Autowired
|
||||
private BankAccountService bankAccountService;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<ProducerRecord> producerRecord;
|
||||
@SpyBean
|
||||
private MockProducer<String, Object> producer;
|
||||
@Autowired
|
||||
@Qualifier("mockProducer")
|
||||
protected Producer<String, Object> mockProducer;
|
||||
|
|
@ -216,11 +209,11 @@ public class BankAccountServiceTest {
|
|||
//AccountValidationRule.RequiredFields
|
||||
//WrongFieldValue
|
||||
bankAccountNewRequest.setCurrency(null);
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "currency"));
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "null, currency"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
bankAccountNewRequest.setCurrency("TT0");
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.WrongFieldValue, "currency"));
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.DictionaryNotFound, "TT0, CurrencyCodeDictionary"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
bankAccountNewRequest.setCurrency(currency);
|
||||
|
|
@ -239,36 +232,20 @@ public class BankAccountServiceTest {
|
|||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
bankAccountNewRequest.setAccount(acc);
|
||||
bankAccountNewRequest.setDestination(null);
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "destination"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
bankAccountNewRequest.setDestination(destination);
|
||||
bankAccountNewRequest.setCompanyId(null);
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.RequiredFieldEmpty, "companyId"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
bankAccountNewRequest.setCompanyId(addresseeIdNew);
|
||||
|
||||
//AccountValidationRule.CompanyPresent
|
||||
//CompanyNotFound
|
||||
bankAccountNewRequest.setCompanyId(999924535239L);
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotFound, "companyId"));
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotFound, bankAccountNewRequest.getCompanyId()+", companyId"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
//CompanyNotActive
|
||||
company.setWorkflowStatus(Status.Blocked.getKey());
|
||||
companyImdg.insert(company);
|
||||
bankAccountNewRequest.setCompanyId(company.getId());
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyNotActive, "companyId"));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
|
||||
//AccountValidationRule.AccountIsNew
|
||||
//AccountAlreadyExist
|
||||
company.setWorkflowStatus(Status.Active.getKey());
|
||||
companyImdg.insert(company);
|
||||
Account existAccount = getTestAccount(accountId, acc);
|
||||
accountImdg.insert(existAccount);
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.AccountAlreadyExist, "account"));
|
||||
errMsg = messageResolver.resolve(new EnumMessage(AccountError.AccountAlreadyExist, existAccount.getAccount()));
|
||||
checkError(errMsg, bankAccountNewRequest);
|
||||
accountImdg.delete(existAccount);
|
||||
}
|
||||
|
|
@ -291,8 +268,9 @@ public class BankAccountServiceTest {
|
|||
//ACT
|
||||
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, currentOffset, jsonString);
|
||||
|
||||
ArgumentCaptor<ProducerRecord> producerRecord = getCaptor(mockProducer);
|
||||
//waiting for kafka producer send message (finale event)
|
||||
verify(producer, timeout(30_000L).times(currentTime))
|
||||
verify(mockProducer, timeout(30_000L).times(currentTime))
|
||||
.send(producerRecord.capture());
|
||||
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
|
||||
|
||||
|
|
@ -368,13 +346,13 @@ public class BankAccountServiceTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@link BankAccountService#bankAccountDelete(BaseRequest)}
|
||||
* {@link BankAccountService#bankAccountBlock(BaseRequest)}
|
||||
* Тест проверяет удаление сущности {@link BankAccount} в Hazelcast при передаче из Apache Kafka.
|
||||
* Входной запрос {@link CommonDeleteRequest}:
|
||||
* {@link CommonDeleteRequest#id} - Идентификатор записи
|
||||
*/
|
||||
@Test
|
||||
void bankAccountDelete() {
|
||||
void bankAccountBlock() {
|
||||
//ARRANGE
|
||||
BankAccount bankAccountExists = getBankAccount();
|
||||
bankAccountImdg.insert(bankAccountExists);
|
||||
|
|
@ -393,8 +371,8 @@ public class BankAccountServiceTest {
|
|||
//ASSERT
|
||||
waitingSendAndCheckRecord(ID, mockProducer);
|
||||
|
||||
BankAccount bankAccount = bankAccountImdg.getSingleObjectByID(ID);
|
||||
Assertions.assertNull(bankAccount);
|
||||
Account bankAccount = accountImdg.getSingleObjectByID(accountId);
|
||||
assertEquals(bankAccount.getStatus(), WorkflowStatus.Blocked.getKey());
|
||||
}
|
||||
|
||||
private Company getTestCompany() {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.MockProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
|
|
@ -26,25 +22,30 @@ 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.errors.AccountError;
|
||||
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.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 = {
|
||||
|
|
@ -52,7 +53,7 @@ import static ru.spcex.clearing.test.TestUtils.*;
|
|||
ValidationConfig.class,
|
||||
ClearingAccountValidationConfig.class,
|
||||
AccountValidationConfig.class,
|
||||
AccountService.class,
|
||||
AccountHelper.class,
|
||||
ClearingAccountService.class,
|
||||
SDFProcessService.class,
|
||||
ImdgTestConfig.class,
|
||||
|
|
@ -72,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;
|
||||
|
|
@ -162,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);
|
||||
|
|
@ -233,77 +233,58 @@ class ClearingAccountServiceTest {
|
|||
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
|
||||
// Long firstID = currentID.getAndIncrement();
|
||||
// Long secondID = currentID.getAndIncrement();
|
||||
// AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
|
||||
// accountSdfRequestPart.setSdfId(firstID);
|
||||
// accountSdfRequestPart.setAccount(account);
|
||||
// accountSdfRequestPart.setCompanyId(firstID);
|
||||
// AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
|
||||
// accountSdf01Request.setGroupingSdf01Id(firstID);
|
||||
// accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
|
||||
// BaseRequest<AccountSdf01Request> baseNewRequest = new BaseRequest<>();
|
||||
// baseNewRequest.setRequestPayload(accountSdf01Request);
|
||||
// baseNewRequest.setId(firstID);
|
||||
// baseNewRequest.setActionType(ActionType.NEW);
|
||||
// String jsonBaseNewRequest;
|
||||
// ObjectMapper objectMapper = new ObjectMapper();
|
||||
// try {
|
||||
// jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
|
||||
// } catch (JsonProcessingException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
//
|
||||
// AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
|
||||
// responsePart.setSdfId(firstID);
|
||||
// responsePart.setErrorCode(null);
|
||||
// responsePart.setErrorText(null);
|
||||
// List<AccountSdfToStatementRequestPart> accountToStatement = Collections.singletonList(responsePart);
|
||||
// StatementRequest statementRequest = new StatementRequest();
|
||||
// statementRequest.setGroupId(firstID);
|
||||
// statementRequest.setAccountCreationResults(accountToStatement);
|
||||
//
|
||||
// BaseRequest<Object> baseRequest = new BaseRequest<>();
|
||||
// baseRequest.setId(secondID);
|
||||
// baseRequest.setActionType(ActionType.SYSTEM);
|
||||
// baseRequest.setRequestPayload(statementRequest);
|
||||
//
|
||||
// Account predictableAccount = new Account();
|
||||
// predictableAccount.setAccount(account);
|
||||
// predictableAccount.setCompanyId(firstID);
|
||||
//
|
||||
// RequestInfo predictableRequestInfo = new RequestInfo();
|
||||
// predictableRequestInfo.setId(secondID);
|
||||
// predictableRequestInfo.setStatus(Status.Processing);
|
||||
//
|
||||
// //KAFKA
|
||||
// final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01;
|
||||
// addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest);
|
||||
//
|
||||
// //waiting for kafka producer send message (finale event)
|
||||
// verify(producer, timeout(30_000L).times(2))
|
||||
// .send(producerRecord.capture());
|
||||
// //todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError
|
||||
//
|
||||
// ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
//
|
||||
// //ASSERT
|
||||
// Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account));
|
||||
// predictableAccount.setId(accountResult.getId());
|
||||
// ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
|
||||
// accountImdg.delete(accountResult);
|
||||
// }
|
||||
/**
|
||||
* {@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);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,13 +24,13 @@ import ru.spcex.clearing.account.config.BeanConfiguration;
|
|||
import ru.spcex.clearing.account.config.validation.ClientCodeValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.TradingClearingRegistryValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.ValidationConfig;
|
||||
import ru.spcex.clearing.account.utils.MatcherFactory;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.test.MatcherFactory;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.TestUtils;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
|
|
@ -376,7 +376,7 @@ class ClientCodeServiceTest {
|
|||
|
||||
waitingSendAndCheckRecord(ID, mockProducer);
|
||||
ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID);
|
||||
Assertions.assertNull(resultUpdate);
|
||||
assertEquals(WorkflowStatus.Blocked.getKey(), resultUpdate.getStatus());
|
||||
}
|
||||
|
||||
// /**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,18 +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;
|
||||
|
|
@ -25,10 +20,10 @@ 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;
|
||||
|
|
@ -36,16 +31,12 @@ 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 = {
|
||||
|
|
@ -53,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})
|
||||
|
|
@ -71,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;
|
||||
|
|
@ -98,6 +85,7 @@ class InformationAccountServiceTest {
|
|||
accountImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_Account, Account.class
|
||||
);
|
||||
clearImdg(accountImdg);
|
||||
|
||||
companyImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_Company, Company.class
|
||||
|
|
@ -145,6 +133,7 @@ class InformationAccountServiceTest {
|
|||
void accountInformationNew() {
|
||||
InformationAccountNewRequest InformationAccountNewRequest = new InformationAccountNewRequest();
|
||||
InformationAccountNewRequest.setCompanyId(companyId);
|
||||
InformationAccountNewRequest.setAccount(account);
|
||||
|
||||
String jsonString = getJsonStringForNew(InformationAccountNewRequest, 0L);
|
||||
|
||||
|
|
@ -154,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());
|
||||
|
|
@ -172,7 +159,7 @@ class InformationAccountServiceTest {
|
|||
InformationAccount resultInfoAccountNew = informationAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", resultAccountNew.getId()));
|
||||
|
||||
predictableAccount.setId(resultAccountNew.getId());
|
||||
predictableAccount.setAccount(informationAccountService.generateInfoAccount(resultInfoAccountNew.getId()));
|
||||
predictableAccount.setAccount(account);
|
||||
predictableInfoAccount.setAccountId(resultAccountNew.getId());
|
||||
predictableInfoAccount.setId(resultInfoAccountNew.getId());
|
||||
|
||||
|
|
@ -183,7 +170,6 @@ class InformationAccountServiceTest {
|
|||
accountImdg.delete(resultAccountNew);
|
||||
}
|
||||
|
||||
@Autowired ImdgProvider imdgProvider;
|
||||
@Test
|
||||
void accountIncrementSequence() {
|
||||
Imdg<InformationAccount> accountInfoImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_InformationAccount, InformationAccount.class );
|
||||
|
|
@ -203,7 +189,7 @@ class InformationAccountServiceTest {
|
|||
}
|
||||
UserRoleVerification userRoleVerification = Mockito.mock(UserRoleVerification.class);
|
||||
InformationAccountService infoAccSvc=new InformationAccountService(null,null,null,
|
||||
null, userRoleVerification, imdgProvider, null, null, null, null);
|
||||
null, userRoleVerification, hazelcastServiceTest, null, null, null, null);
|
||||
Long n = infoAccSvc.accountNextId();
|
||||
Assertions.assertEquals(13L, n);
|
||||
n = infoAccSvc.accountNextId();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.MockProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
|
|
@ -27,15 +26,11 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
|||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.enumeration.AccountStatus;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Map;
|
||||
|
||||
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
|
|
@ -50,7 +45,7 @@ class SDFProcessServiceTest {
|
|||
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private HazelcastService hazelcastServiceTest;
|
||||
private ImdgProvider hazelcastServiceTest;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<ProducerRecord> producerRecord;
|
||||
|
|
@ -103,8 +98,9 @@ class SDFProcessServiceTest {
|
|||
void parseSdf52Status() {
|
||||
Assertions.assertEquals(AccountStatus.BLOCKED, sdfProcessService.parseSdf52Status(0L));
|
||||
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(1L));
|
||||
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(3L));
|
||||
Assertions.assertEquals(AccountStatus.CLOSE, sdfProcessService.parseSdf52Status(2L));
|
||||
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(3L));
|
||||
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(4705211956118233163L));
|
||||
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(null));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.MockProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
|
|
@ -19,31 +15,30 @@ import ru.clearing.classes.statics.data.account.ClearingAccount;
|
|||
import ru.clearing.classes.statics.data.account.DepoAccount;
|
||||
import ru.clearing.classes.statics.data.account.InformationAccount;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
|
||||
import ru.spcex.clearing.account.config.BeanConfiguration;
|
||||
import ru.spcex.clearing.account.config.validation.TradingClearingRegistryValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.ValidationConfig;
|
||||
import ru.spcex.clearing.account.utils.MatcherFactory;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
|
||||
import ru.spcex.clearing.test.MatcherFactory;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.ServiceStatus;
|
||||
import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose;
|
||||
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
|
||||
import ru.spcex.platform.enumeration.WorkflowStatus;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import static ru.spcex.clearing.test.config.KafkaTestConfig.setMockFuture;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
|
|
@ -64,18 +59,19 @@ class TradingClearingRegistryServiceTest {
|
|||
TradingClearingRegistryService tradingClearingRegistryService;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private HazelcastService hazelcastServiceTest;
|
||||
private ImdgProvider hazelcastServiceTest;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<ProducerRecord> producerRecord;
|
||||
@SpyBean
|
||||
private MockProducer<String, Object> producer;
|
||||
@Autowired
|
||||
@Qualifier("mockProducer")
|
||||
protected Producer<String, Object> mockProducer;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kafkaTestTemplate")
|
||||
protected KafkaTemplate<String, Object> kafkaTemplate;
|
||||
|
||||
private Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<CompanySymbols> companySymbolsImdg;
|
||||
private Imdg<ServiceStatusDictionary> serviceStatusDictionaryImdg;
|
||||
|
||||
private Imdg<ClearingAccount> clearingAccountImdg;
|
||||
|
|
@ -103,6 +99,9 @@ class TradingClearingRegistryServiceTest {
|
|||
companyImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_Company, Company.class
|
||||
);
|
||||
companySymbolsImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class
|
||||
);
|
||||
serviceStatusDictionaryImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class
|
||||
);
|
||||
|
|
@ -129,8 +128,14 @@ class TradingClearingRegistryServiceTest {
|
|||
company.setClearingCode("77");
|
||||
companyImdg.insert(company);
|
||||
|
||||
CompanySymbols companySymbols = new CompanySymbols();
|
||||
companySymbols.setCompanyId(companyId);
|
||||
companySymbols.setCompanySymbol(CompanySymbol.CLRC.getKey());
|
||||
companySymbolsImdg.insert(companySymbols);
|
||||
|
||||
Account account = new Account();
|
||||
account.setStatus(ServiceStatus.Active.getKey());
|
||||
account.setAccountType(AccountType.Clrn.getKey());
|
||||
accountId = accountImdg.insert(account);
|
||||
|
||||
account2Id = accountImdg.insert(account);
|
||||
|
|
@ -154,15 +159,17 @@ class TradingClearingRegistryServiceTest {
|
|||
|
||||
@Test
|
||||
void tradingClearingRegistryNew_moneyAccount_clearingAccount() {
|
||||
setMockFuture(kafkaTemplate);
|
||||
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
|
||||
tradingClearingRegistryNewRequest.setCompanyId(companyId);
|
||||
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
|
||||
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
|
||||
|
||||
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
|
||||
predictableTradingClearingRegistry.setCompanyId(companyId);
|
||||
predictableTradingClearingRegistry.setCode("0077MAT");
|
||||
predictableTradingClearingRegistry.setCode("0077MAT00001");
|
||||
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryType("CAT");
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
|
||||
predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
|
||||
|
||||
|
|
@ -178,7 +185,6 @@ class TradingClearingRegistryServiceTest {
|
|||
|
||||
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
|
||||
predictableTradingClearingRegistry.setId(resultNew.getId());
|
||||
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
|
||||
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
|
||||
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
|
||||
|
||||
|
|
@ -190,13 +196,16 @@ class TradingClearingRegistryServiceTest {
|
|||
|
||||
@Test
|
||||
void tradingClearingRegistryNew_moneyAccount_informationAccount() {
|
||||
setMockFuture(kafkaTemplate);
|
||||
clearImdg(tradingClearingRegistryImdg);
|
||||
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
|
||||
tradingClearingRegistryNewRequest.setCompanyId(companyId);
|
||||
tradingClearingRegistryNewRequest.setMoneyAccountId(account2Id);
|
||||
tradingClearingRegistryNewRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
|
||||
|
||||
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
|
||||
predictableTradingClearingRegistry.setCompanyId(companyId);
|
||||
predictableTradingClearingRegistry.setCode("0077MAT");
|
||||
predictableTradingClearingRegistry.setCode("0077MAT00001");
|
||||
predictableTradingClearingRegistry.setMoneyAccountId(account2Id);
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey());
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey());
|
||||
|
|
@ -210,11 +219,10 @@ class TradingClearingRegistryServiceTest {
|
|||
0,
|
||||
jsonString);
|
||||
|
||||
waitingSendAndCheckRecord(0L, producer, producerRecord);
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
|
||||
predictableTradingClearingRegistry.setId(resultNew.getId());
|
||||
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
|
||||
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
|
||||
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
|
||||
|
||||
|
|
@ -227,6 +235,8 @@ class TradingClearingRegistryServiceTest {
|
|||
|
||||
@Test
|
||||
void tradingClearingRegistryNew_depoAccount() {
|
||||
setMockFuture(kafkaTemplate);
|
||||
clearImdg(tradingClearingRegistryImdg);
|
||||
TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest();
|
||||
tradingClearingRegistryNewRequest.setCompanyId(companyId);
|
||||
tradingClearingRegistryNewRequest.setMoneyAccountId(accountId);
|
||||
|
|
@ -234,7 +244,7 @@ class TradingClearingRegistryServiceTest {
|
|||
|
||||
TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry();
|
||||
predictableTradingClearingRegistry.setCompanyId(companyId);
|
||||
predictableTradingClearingRegistry.setCode("0077CDAT");
|
||||
predictableTradingClearingRegistry.setCode("0077CDATT00001");
|
||||
predictableTradingClearingRegistry.setMoneyAccountId(accountId);
|
||||
predictableTradingClearingRegistry.setDepoAccountId(account2Id);
|
||||
predictableTradingClearingRegistry.setTradingClearingRegistryType("DAT");
|
||||
|
|
@ -249,14 +259,12 @@ class TradingClearingRegistryServiceTest {
|
|||
0,
|
||||
jsonString);
|
||||
|
||||
waitingSendAndCheckRecord(0L, producer, producerRecord);
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next();
|
||||
predictableTradingClearingRegistry.setId(resultNew.getId());
|
||||
predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId());
|
||||
predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated());
|
||||
predictableTradingClearingRegistry.setCreated(resultNew.getCreated());
|
||||
predictableTradingClearingRegistry.setCompanyId(123L);
|
||||
|
||||
TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry);
|
||||
tradingClearingRegistryImdg.delete(resultNew);
|
||||
|
|
@ -284,7 +292,7 @@ class TradingClearingRegistryServiceTest {
|
|||
jsonString);
|
||||
|
||||
//ASSERT
|
||||
waitingSendAndCheckRecord(0L, producer, producerRecord);
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
|
||||
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
|
||||
|
|
@ -312,7 +320,7 @@ class TradingClearingRegistryServiceTest {
|
|||
jsonString);
|
||||
|
||||
//ASSERT
|
||||
waitingSendAndCheckRecord(0L, producer, producerRecord);
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId);
|
||||
existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated());
|
||||
|
|
@ -333,8 +341,8 @@ class TradingClearingRegistryServiceTest {
|
|||
"000000105", TradingClearingRegistryPurpose.C, "ER", 100012L
|
||||
));
|
||||
|
||||
Assertions.assertEquals("0105MAT100012", tradingClearingRegistryService.makeCode(
|
||||
"000000105", TradingClearingRegistryPurpose.M, "ER", 100012L
|
||||
Assertions.assertEquals("0105MAT00012", tradingClearingRegistryService.makeCode(
|
||||
"000000105", TradingClearingRegistryPurpose.M, "A", 100012L
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -38,6 +42,10 @@ public class BackEndApiImdgConfig {
|
|||
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||
BackendApiSettings clientSetting
|
||||
) {
|
||||
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());
|
||||
|
|
@ -52,6 +60,10 @@ public class BackEndApiImdgConfig {
|
|||
@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());
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ 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.ClearingDateFromCondition;
|
||||
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.ClearingDateToCondition;
|
||||
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.CreatedFromCondition;
|
||||
import ru.spcex.clearing.backendapi.controller.queue.history.condition.specific.CreatedToCondition;
|
||||
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;
|
||||
|
|
@ -32,9 +29,17 @@ public class HistoryConfig {
|
|||
@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;
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +55,54 @@ public class HistoryConfig {
|
|||
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");
|
||||
|
|
@ -62,6 +115,18 @@ public class HistoryConfig {
|
|||
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");
|
||||
|
|
@ -73,4 +138,40 @@ public class HistoryConfig {
|
|||
));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ public class HistController {
|
|||
|
||||
@ApiOperation(value = "Get history")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
|
||||
@RequestMapping(path = "/all", method = RequestMethod.POST)
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public CommonGetAllResponse getHistory(
|
||||
@ApiParam(value = "destination сущности по которой запрашивается история", example = "money-balance-registers", required = true)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,9 @@ public class IdentificationFundsActionNew implements IAction<IdentificationFunds
|
|||
@ApiModelProperty(value = "Торгово-клиринговый регистр", example = "1234")
|
||||
@JsonProperty
|
||||
public Long tradingClearingRegistryId;
|
||||
@ApiModelProperty(value = "Идентификатор компании", example = "1234")
|
||||
@JsonProperty
|
||||
public Long companyId;
|
||||
|
||||
@Override
|
||||
public IdentificationFundsRequest toRequest() {
|
||||
|
|
@ -32,6 +35,7 @@ public class IdentificationFundsActionNew implements IAction<IdentificationFunds
|
|||
req.setId(id);
|
||||
req.setBalance(balance);
|
||||
req.setTradingClearingRegistryId(tradingClearingRegistryId);
|
||||
req.setCompanyId(companyId);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
|
@ -74,4 +78,12 @@ public class IdentificationFundsActionNew implements IAction<IdentificationFunds
|
|||
public void setTradingClearingRegistryId(Long tradingClearingRegistryId) {
|
||||
this.tradingClearingRegistryId = tradingClearingRegistryId;
|
||||
}
|
||||
|
||||
public Long getCompanyId() {
|
||||
return companyId;
|
||||
}
|
||||
|
||||
public void setCompanyId(Long companyId) {
|
||||
this.companyId = companyId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ public class NotificationUpdateAction implements IAction<NotificationUpdateReque
|
|||
@ApiModelProperty(value = "Наименование статуса сообщения", example = "ACTV")
|
||||
@JsonProperty
|
||||
public String notificationStatus;
|
||||
@ApiModelProperty(value = "Наименование отправителя", example = "1234")
|
||||
@JsonProperty
|
||||
@ApiModelProperty(value = "Наименование отправителя (не исопльзуется)", example = "1234")
|
||||
@JsonProperty(required = false)
|
||||
@Deprecated
|
||||
public Long senderId;
|
||||
|
||||
@Override
|
||||
|
|
@ -22,7 +23,6 @@ public class NotificationUpdateAction implements IAction<NotificationUpdateReque
|
|||
var req = new NotificationUpdateRequest();
|
||||
req.setId(this.id);
|
||||
req.setNotificationStatus(this.notificationStatus);
|
||||
req.setSenderId(this.senderId);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,12 @@ public class LauncherNew implements IAction<Object> {
|
|||
@JsonProperty
|
||||
private Long sessionId;
|
||||
|
||||
@ApiModelProperty(value = "Текущий баланс", example = "12.22")
|
||||
@ApiModelProperty(value = "Текущий баланс (свободно)", example = "12.22")
|
||||
@JsonProperty
|
||||
private BigDecimal balance;
|
||||
@ApiModelProperty(value = "Текущий баланс (всего)", example = "12.22")
|
||||
@JsonProperty
|
||||
private BigDecimal fullBalance;
|
||||
@ApiModelProperty(value = "Наименование инструмента/валюты", example = "SPB")
|
||||
@JsonProperty
|
||||
private String securitySymbol;
|
||||
|
|
@ -72,6 +75,7 @@ public class LauncherNew implements IAction<Object> {
|
|||
taskRunnerCommandRequest.setSessionType(sessionType);
|
||||
taskRunnerCommandRequest.setSessionId(sessionId);
|
||||
taskRunnerCommandRequest.setBalance(balance);
|
||||
taskRunnerCommandRequest.setFullBalance(fullBalance);
|
||||
taskRunnerCommandRequest.setSecuritySymbol(securitySymbol);
|
||||
taskRunnerCommandRequest.setCreditLeg_amount(creditLeg_amount);
|
||||
taskRunnerCommandRequest.setPaymentPurpose(paymentPurpose);
|
||||
|
|
@ -215,4 +219,12 @@ public class LauncherNew implements IAction<Object> {
|
|||
public void setDebitLeg_accountId(Long debitLeg_accountId) {
|
||||
this.debitLeg_accountId = debitLeg_accountId;
|
||||
}
|
||||
|
||||
public BigDecimal getFullBalance() {
|
||||
return fullBalance;
|
||||
}
|
||||
|
||||
public void setFullBalance(BigDecimal fullBalance) {
|
||||
this.fullBalance = fullBalance;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package ru.spcex.clearing.backendapi.controller.test;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import ru.spcex.clearing.backendapi.errors.BackEndError;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.error.ValidationException;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/anonymous/kafka-api")
|
||||
public class KafkaApiController {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final KafkaSender kafkaSender;
|
||||
private static final ObjectMapper json = new ObjectMapper();
|
||||
static {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public KafkaApiController(KafkaSender kafkaSender) {
|
||||
this.kafkaSender = kafkaSender;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Test backend-api availability.")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = String.class)})
|
||||
@RequestMapping(method = RequestMethod.POST, path = "/any/message", produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
@ResponseBody
|
||||
public String processGet(@ApiParam(value = "Параметры команды в JSON формате.", required = true)
|
||||
@RequestBody AnyKafkaMessageAction bankAccountNewAction) throws ClassNotFoundException, ValidationException, JsonProcessingException {
|
||||
log.info("Call test method for backend-api controller");
|
||||
validate(bankAccountNewAction);
|
||||
Class<?> parameterType = ClassUtils.forName(bankAccountNewAction.getFullClassName(), ClassUtils.getDefaultClassLoader());
|
||||
JavaType requestType = json.getTypeFactory().constructSimpleType(parameterType, null);
|
||||
Object obj = json.readValue(bankAccountNewAction.getJson(), requestType);
|
||||
Long idOfBaseRequestMessage = kafkaSender.sendRequestToQueue(bankAccountNewAction.getTopicName(), obj);
|
||||
log.debug("Test message to topic {} with request id={}", bankAccountNewAction.getTopicName(), idOfBaseRequestMessage);
|
||||
return "success: baseRequest.id = " + idOfBaseRequestMessage;
|
||||
}
|
||||
|
||||
private void validate(AnyKafkaMessageAction bankAccountNewAction) throws ValidationException {
|
||||
if (TextUtil.isEmpty(bankAccountNewAction.getTopicName())) {
|
||||
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "topicName"));
|
||||
}
|
||||
if (TextUtil.isEmpty(bankAccountNewAction.getFullClassName())) {
|
||||
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "fullClassName"));
|
||||
}
|
||||
if (TextUtil.isEmpty(bankAccountNewAction.getJson())) {
|
||||
throw new ValidationException(new EnumMessage(BackEndError.ValidationError, "json"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<meta version="3.5.0.13">
|
||||
<meta version="3.9.0.68">
|
||||
<enums>
|
||||
<allowed id="1" code="ALWD" name="Разрешено"/>
|
||||
<allowed id="2" code="DEND" name="Запрещено"/>
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
|
||||
<tradingClearingRegistryType id="1" code="A" name="Владелец"/>
|
||||
<tradingClearingRegistryType id="2" code="B" name="Клиентский"/>
|
||||
<tradingClearingRegistryType id="3" code="C" name="Попечитель"/>
|
||||
<tradingClearingRegistryType id="3" code="C" name="Клиентский"/>
|
||||
<tradingClearingRegistryType id="4" code="D" name="Доверительный управляющий"/>
|
||||
<tradingClearingRegistryType id="5" code="E" name="Эмитент"/>
|
||||
<tradingClearingRegistryType id="6" code="Z" name="К размещению/выкупу"/>
|
||||
|
|
@ -156,7 +156,7 @@
|
|||
<registryUnit id="5" code="U" name="Невыясненные"/>
|
||||
<registryUnit id="5" code="I" name="Списания/зачисления"/>
|
||||
<registryUnit id="7" code="V" name="Выписка"/>
|
||||
<registryCode id="1" code="AMAT" name="Денежные средства - общие"/>
|
||||
<registryCode id="1" code="AMAT" name="Денежные средства Участника клиринга, зарезервированные на торги"/>
|
||||
<registryCode id="2" code="AMAF" name="Денежные средства - свободные"/>
|
||||
<registryCode id="3" code="AMAB" name="Денежные средства - блокированные"/>
|
||||
<registryCode id="4" code="TMAT" name="Требования по деньгам"/>
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<registryCode id="9" code="LSAT" name="Рассчитанные обязательства по бумагам"/>
|
||||
<registryCode id="10" code="LMAT" name="Рассчитанные обязательства по деньгам"/>
|
||||
<registryCode id="11" code="CSAT" name="Рассчитанные требования по бумагам"/>
|
||||
<registryCode id="12" code="AMBT" name="Денежные средства клиента - общие"/>
|
||||
<registryCode id="12" code="AMBT" name="Денежные средства Участника клиринга, зарезервированные на торги – клиенты"/>
|
||||
<registryCode id="13" code="AMBF" name="Денежные средства клиента - свободные"/>
|
||||
<registryCode id="14" code="AMBB" name="Денежные средства клиента - блокированные"/>
|
||||
<registryCode id="15" code="TMBT" name="Требования по деньгам (кл)"/>
|
||||
|
|
@ -180,14 +180,18 @@
|
|||
<registryCode id="22" code="CSBT" name="Рассчитанные требования по бумагам (кл)"/>
|
||||
<registryCode id="23" code="DMAT" name="Возврат депозита"/>
|
||||
<registryCode id="24" code="DMBT" name="Возврат депозита (кл)"/>
|
||||
<registryCode id="25" code="ASAT" name="Ценные бумаги - общие"/>
|
||||
<registryCode id="25" code="ASAT" name="Ценные бумаги Участника клиринга – свои"/>
|
||||
<registryCode id="26" code="ASAF" name="Ценные бумаги - свободные"/>
|
||||
<registryCode id="27" code="ASAB" name="Ценные бумаги - блокированные"/>
|
||||
<registryCode id="28" code="DMAX" name="Возврат инициатору"/>
|
||||
<registryCode id="29" code="DMBX" name="Возврат инициатору (кл)"/>
|
||||
<registryCode id="30" code="DMAU" name="Денежные средства - невыясненные"/>
|
||||
<registryCode id="31" code="DMAV" name="Треб. выписки"/>
|
||||
<registryCode id="32" code="ASZT" name="Ценные бумаги - общие"/>
|
||||
<registryCode id="32" code="ASZT" name="Ценные бумаги для размещения/выкупа"/>
|
||||
<registryCode id="33" code="ASBT" name="Ценные бумаги Участника клиринга – клиенты"/>
|
||||
<registryCode id="34" code="ASCT" name="Ценные бумаги Участника клиринга – клиенты-нерезиденты"/>
|
||||
<registryCode id="35" code="AMCT" name="Денежные средства Участника клиринга, зарезервированные на торги – клиенты"/>
|
||||
<registryCode id="36" code="ASXT" name="Ценные бумаги Участника клиринга – ДУ"/>
|
||||
<registryStatus id="1" code="OK" name="Рассчитано"/>
|
||||
<registryStatus id="2" code="UNCV" name="Не исполнено"/>
|
||||
<registryStatus id="3" code="FAIL" name="Не исполнено контрагентом"/>
|
||||
|
|
@ -214,7 +218,7 @@
|
|||
<accountType id="10" code="DTRN" name="Депозитарный транзакционный счет"/>
|
||||
<depoAccountType id="1" code="A" name="Счет участника"/>
|
||||
<depoAccountType id="2" code="B" name="Счет клиента"/>
|
||||
<depoAccountType id="3" code="C" name="Счет попечителя"/>
|
||||
<depoAccountType id="3" code="C" name="Счет нерезидента"/>
|
||||
<depoAccountType id="4" code="D" name="Счет доверительного управляющего"/>
|
||||
<depoAccountType id="5" code="Z" name="Счет к размещению/выкупу"/>
|
||||
<depoAccountType id="6" code="F" name="Счет держателя"/>
|
||||
|
|
@ -246,6 +250,10 @@
|
|||
<task id="23" code="GRET" name="Формирование отчетности по сделкам"/>
|
||||
<task id="24" code="GREF" name="Формирование итоговой отчетности"/>
|
||||
<task id="25" code="FDFF" name="Формирование ДФ-05 с кодом 9 (финальный)"/>
|
||||
<task id="26" code="SDEP" name="Время начала возврата депозитов"/>
|
||||
<task id="27" code="EDEP" name="Время завершения возврата депозитов"/>
|
||||
<task id="28" code="CHDF" name="Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21"/>
|
||||
<task id="29" code="CCLR" name="Завершение неудачных клиринговых сессий"/>
|
||||
<taskStatus id="1" code="ACTV" name="Активна"/>
|
||||
<taskStatus id="2" code="BLKD" name="Не активна"/>
|
||||
<taskStatus id="3" code="CNCL" name="Отмена расписания"/>
|
||||
|
|
@ -425,6 +433,8 @@
|
|||
<errorCode id="5019" code="ACNT" name="Для компании %s отсутствует категория %s."/>
|
||||
<errorCode id="5022" code="ACNT" name="Для компании %s отсутствует клиринговый код."/>
|
||||
<errorCode id="5023" code="ACNT" name="Счет %s уже используется."/>
|
||||
<errorCode id="5024" code="ACNT" name="Не указан номер счета."/>
|
||||
<errorCode id="5025" code="ACNT" name="Необходимо указать ДЕПО счет."/>
|
||||
<!-- error code for balance-service -->
|
||||
<errorCode id="5200" code="BLNC" name="Общая ошибка модуля balance-service."/>
|
||||
<errorCode id="5210" code="BLNC" name="Клиринговая сессия неактивна."/>
|
||||
|
|
@ -473,6 +483,8 @@
|
|||
<errorCode id="5430" code="CLRN" name="Неверный код регистра: %s"/>
|
||||
<errorCode id="5431" code="CLRN" name="Дата возврата для депозита с разделением не может быть изменена"/>
|
||||
<errorCode id="5432" code="CLRN" name="После сверки обнаружена разница между плановым и фактическим балансом"/>
|
||||
<errorCode id="5433" code="CLRN" name="Сессия по возврату депозита не может исполняться вне временного интервала, установленного в системе"/>
|
||||
<errorCode id="5434" code="CLRN" name="Операция невозможна по счету с типом %s."/>
|
||||
<!-- error code for dbf-importer -->
|
||||
<errorCode id="5600" code="DBFI" name="Общая ошибка модуля dbf-importer."/>
|
||||
<!-- error code for dbf-exporter -->
|
||||
|
|
@ -520,90 +532,6 @@
|
|||
|
||||
</enums>
|
||||
<objects>
|
||||
<company id="1" fullName="АО Санкт-Петербургская Валютная Биржа" shortName="СПВБ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
|
||||
<company id="2" fullName="ЗАО «Петербургский Расчетный Центр»" shortName="ПРЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
|
||||
<company id="3" fullName="Торговая организация" shortName="ТС" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
|
||||
<company id="4" fullName="ЗАО «Санкт-Петербургский Расчетно-Депозитарный Центр»" shortName="РДЦ" tradingCode="" clearingCode="" workflowStatus="ACTV"/>
|
||||
<!--company id="5" fullName="Центральный Банк Российской Федерации" shortName="ЦБ РФ" tradingCode="" clearingCode="" workflowStatus="ACTV"/-->
|
||||
<companySymbols id="1" companyId="1" companySymbol="BIC" companySymbolValue="044030920"/>
|
||||
<companySymbols id="2" companyId="2" companySymbol="BIC" companySymbolValue="044030505"/>
|
||||
<currency id="643" currency_code="RUB"/>
|
||||
<security instrumentType="CRNC" shortName="RUB" fullName="Российский рубль" securitySymbol="RUB" workflowStatus="ACTV" id="643"/>
|
||||
<account id="1" companyId="1" account="30414810300000006000" accountType="TRAN" status="ACTV" processingSign="ALWD"/>
|
||||
<account id="2" companyId="1" account="30414810600000007000" accountType="ANLT" status="ACTV" processingSign="ALWD"/>
|
||||
<account id="3" companyId="1" account="700100000AT0" accountType="DTRN" status="ACTV" processingSign="ALWD"/>
|
||||
<market id="1" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UESC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Обыкновенные акции"/>
|
||||
<market id="2" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NESC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Обыкновенные акции"/>
|
||||
<market id="3" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DESC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Обыкновенные акции"/>
|
||||
<market id="4" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AESC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Обыкновенные акции"/>
|
||||
<market id="5" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WESC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Обыкновенные акции"/>
|
||||
<market id="6" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UEPC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Привилегированные акции"/>
|
||||
<market id="7" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NEPC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Привилегированные акции"/>
|
||||
<market id="8" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DEPC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Привилегированные акции"/>
|
||||
<market id="9" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="AEPC" name="Размещение: акции (аукцион по цене)" exchangeId="1" description="Размещение: акции (аукцион по цене): Привилегированные акции"/>
|
||||
<market id="10" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WEPC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Привилегированные акции"/>
|
||||
<market id="11" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABVC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с переменным купоном"/>
|
||||
<market id="12" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBVC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с переменным купоном"/>
|
||||
<market id="13" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с переменным купоном"/>
|
||||
<market id="14" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с переменным купоном"/>
|
||||
<market id="15" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с переменным купоном"/>
|
||||
<market id="16" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBVC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с переменным купоном"/>
|
||||
<market id="17" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABFC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Купонные облигации с постоянным купоном"/>
|
||||
<market id="18" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBFC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Купонные облигации с постоянным купоном"/>
|
||||
<market id="19" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBFC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Купонные облигации с постоянным купоном"/>
|
||||
<market id="20" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBFC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Купонные облигации с постоянным купоном"/>
|
||||
<market id="21" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBFC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Купонные облигации с постоянным купоном"/>
|
||||
<market id="22" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBFC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Купонные облигации с постоянным купоном"/>
|
||||
<market id="23" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABIC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с индексированным номиналом"/>
|
||||
<market id="24" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBIC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с индексированным номиналом"/>
|
||||
<market id="25" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBIC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с индексированным номиналом"/>
|
||||
<market id="26" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBIC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с индексированным номиналом"/>
|
||||
<market id="27" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBIC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с индексированным номиналом"/>
|
||||
<market id="28" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBIC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с индексированным номиналом"/>
|
||||
<market id="29" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABMC" name="Размещение: Аукцион по цене" exchangeId="1" description="Размещение: Аукцион по цене: Облигации с амортизацией долга"/>
|
||||
<market id="30" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="KBMC" name="Размещение: Аукцион по ставке" exchangeId="1" description="Размещение: Аукцион по ставке: Облигации с амортизацией долга"/>
|
||||
<market id="31" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBMC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации с амортизацией долга"/>
|
||||
<market id="32" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBMC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации с амортизацией долга"/>
|
||||
<market id="33" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBMC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации с амортизацией долга"/>
|
||||
<market id="34" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="WBMC" name="Размещение: адресные заявки (подписка)" exchangeId="1" description="Размещение: адресные заявки (подписка): Облигации с амортизацией долга"/>
|
||||
<market id="35" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BKVC" name="Размещение: Аукцион БР" exchangeId="1" description="Размещение: Аукцион БР: Облигации Банка России с переменным купоном (КОБР)"/>
|
||||
<market id="36" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SKVC" name="Доразмещение: Адресные заявки БР" exchangeId="1" description="Доразмещение: Адресные заявки БР: Облигации Банка России с переменным купоном (КОБР)"/>
|
||||
<market id="37" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UKVC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Облигации Банка России с переменным купоном (КОБР)"/>
|
||||
<market id="38" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NKVC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Облигации Банка России с переменным купоном (КОБР)"/>
|
||||
<market id="39" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DKVC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Облигации Банка России с переменным купоном (КОБР)"/>
|
||||
<market id="45" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="ABEC" name="Размещение: Аукцион СПВБ" exchangeId="1" description="Размещение: Аукцион СПВБ: Биржевые облигации"/>
|
||||
<market id="46" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UBEC" name="Режим непрерывных торгов" exchangeId="1" description="Режим непрерывных торгов: Биржевые облигации"/>
|
||||
<market id="47" marketType="SCND" section="FOND" settlementCurrency="RUB" code="NBEC" name="Режим переговорных сделок (РПС)" exchangeId="1" description="Режим переговорных сделок (РПС): Биржевые облигации"/>
|
||||
<market id="48" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DBEC" name="Дискретный аукцион" exchangeId="1" description="Дискретный аукцион: Биржевые облигации"/>
|
||||
<market id="61" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMVC" name="ОФЗПК-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПК-Размещение: Аукцион БР: Облигации Минфина"/>
|
||||
<market id="62" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMVC" name="ОФЗПК-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПК-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
|
||||
<market id="63" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMVC" name="ОФЗПК-Режим непрерывных торгов" exchangeId="1" description="ОФЗПК-Режим непрерывных торгов: Облигации Минфина"/>
|
||||
<market id="64" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMVC" name="ОФЗПК-Дискретный аукцион" exchangeId="1" description="ОФЗПК-Дискретный аукцион: Облигации Минфина"/>
|
||||
<market id="65" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMVC" name="ОФЗПК-Торги в режиме выкупа" exchangeId="1" description="ОФЗПК-Торги в режиме выкупа: Облигации Минфина"/>
|
||||
<market id="66" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMFC" name="ОФЗПД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗПД-Размещение: Аукцион БР: Облигации Минфина"/>
|
||||
<market id="67" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMFC" name="ОФЗПД- Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗПД- Доразмещение: Адресные заявки БР: Облигации Минфина"/>
|
||||
<market id="68" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMFC" name="ОФЗПД-Режим непрерывных торгов" exchangeId="1" description="ОФЗПД-Режим непрерывных торгов: Облигации Минфина"/>
|
||||
<market id="69" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMFC" name="ОФЗПД-Дискретный аукцион" exchangeId="1" description="ОФЗПД-Дискретный аукцион: Облигации Минфина"/>
|
||||
<market id="70" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMFC" name="ОФЗПД-Торги в режиме выкупа" exchangeId="1" description="ОФЗПД-Торги в режиме выкупа: Облигации Минфина"/>
|
||||
<market id="71" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMMC" name="ОФЗАД-Размещение: Аукцион БР" exchangeId="1" description="ОФЗАД-Размещение: Аукцион БР: Облигации Минфина"/>
|
||||
<market id="72" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMMC" name="ОФЗАД-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗАД-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
|
||||
<market id="73" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMMC" name="ОФЗАД-Режим непрерывных торгов" exchangeId="1" description="ОФЗАД-Режим непрерывных торгов: Облигации Минфина"/>
|
||||
<market id="74" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMMC" name="ОФЗАД-Дискретный аукцион" exchangeId="1" description="ОФЗАД-Дискретный аукцион: Облигации Минфина"/>
|
||||
<market id="75" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMMC" name="ОФЗАД-Торги в режиме выкупа" exchangeId="1" description="ОФЗАД-Торги в режиме выкупа: Облигации Минфина"/>
|
||||
<market id="76" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="BMIC" name="ОФЗИН-Размещение: Аукцион БР" exchangeId="1" description="ОФЗИН-Размещение: Аукцион БР: Облигации Минфина"/>
|
||||
<market id="77" marketType="PRMR" section="FOND" settlementCurrency="RUB" code="SMIC" name="ОФЗИН-Доразмещение: Адресные заявки БР" exchangeId="1" description="ОФЗИН-Доразмещение: Адресные заявки БР: Облигации Минфина"/>
|
||||
<market id="78" marketType="SCND" section="FOND" settlementCurrency="RUB" code="UMIC" name="ОФЗИН-Режим непрерывных торгов" exchangeId="1" description="ОФЗИН-Режим непрерывных торгов: Облигации Минфина"/>
|
||||
<market id="79" marketType="SCND" section="FOND" settlementCurrency="RUB" code="DMIC" name="ОФЗИН-Дискретный аукцион" exchangeId="1" description="ОФЗИН-Дискретный аукцион: Облигации Минфина"/>
|
||||
<market id="80" marketType="SCND" section="FOND" settlementCurrency="RUB" code="MMIC" name="ОФЗИН-Торги в режиме выкупа" exchangeId="1" description="ОФЗИН-Торги в режиме выкупа: Облигации Минфина"/>
|
||||
<market id="82" marketType="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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
{
|
||||
"version": "3.8.0.56",
|
||||
"version": "3.9.0.71",
|
||||
|
||||
"enums": {
|
||||
|
||||
|
|
@ -3328,11 +3328,11 @@
|
|||
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
{"code": "periodEndDate",
|
||||
{"code": "periodStartDate",
|
||||
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
{"code": "periodStartDate",
|
||||
{"code": "periodEndDate",
|
||||
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
|
|
@ -4132,6 +4132,10 @@
|
|||
{"code": "balance",
|
||||
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
|
||||
}
|
||||
,
|
||||
{"code": "tradingClearingRegistryId",
|
||||
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
|
||||
|
|
@ -4263,7 +4267,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "account",
|
||||
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
|
||||
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
|
||||
}
|
||||
,
|
||||
{"code": "status",
|
||||
|
|
@ -4664,6 +4668,66 @@
|
|||
}
|
||||
]
|
||||
|
||||
}
|
||||
,
|
||||
"accountSymbols": {
|
||||
|
||||
"name": "Депо КС - РДЦ",
|
||||
|
||||
"destination": "accounting/depo-accounts-symbols",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.account.AccountSymbols",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
||||
"table": "depo_account_symbols",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
}
|
||||
,
|
||||
{"code": "accountId",
|
||||
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","searchable": true,"sortable": true,"visible": true,"link": "account","linkCode": "account"
|
||||
}
|
||||
,
|
||||
{"code": "accountSymbolValue",
|
||||
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
]
|
||||
,"actions":[
|
||||
{"method":"post",
|
||||
|
||||
"name": "Добавление депо КС - РДЦ",
|
||||
|
||||
"confirmation": "accountId,accountSymbolValue",
|
||||
|
||||
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction",
|
||||
|
||||
"fields": [
|
||||
{"code": "accountId",
|
||||
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","link": "account","linkCode": "account","required": true
|
||||
}
|
||||
,
|
||||
{"code": "accountSymbolValue",
|
||||
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
,
|
||||
{"method":"delete",
|
||||
|
||||
"name": "Удаление депо КС - РДЦ",
|
||||
|
||||
"confirmation": "accountId,accountSymbolValue",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
,
|
||||
"clearingAccount": {
|
||||
|
|
@ -5270,11 +5334,15 @@
|
|||
|
||||
"group": "Обмен с расчетной организацией",
|
||||
|
||||
"name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
|
||||
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)",
|
||||
|
||||
"fields": [
|
||||
{"code": "fullBalance",
|
||||
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "balance",
|
||||
"type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
|
||||
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "securitySymbol",
|
||||
|
|
@ -5290,7 +5358,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "senderId",
|
||||
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true
|
||||
}
|
||||
,
|
||||
{"code": "creditLeg_accountId",
|
||||
|
|
@ -5509,6 +5577,28 @@
|
|||
|
||||
"name": "Формирование ДФ-05 с кодом 9 (финальный)",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
,
|
||||
{"method":"post",
|
||||
|
||||
"destination": "CHDF",
|
||||
|
||||
"group": "Общее",
|
||||
|
||||
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
,
|
||||
{"method":"post",
|
||||
|
||||
"destination": "CCLR",
|
||||
|
||||
"group": "Клиринг",
|
||||
|
||||
"name": "Завершение неудачных клиринговых сессий",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
|
|
@ -5544,7 +5634,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "sessionStatus",
|
||||
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
|
||||
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Шаг","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
|
|
@ -5776,10 +5866,12 @@
|
|||
,
|
||||
"executionDeposit": {
|
||||
|
||||
"name": "Сделки",
|
||||
"name": "Сделки на секции МКР",
|
||||
|
||||
"destination": "execution-deposits",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
|
@ -5932,6 +6024,8 @@
|
|||
|
||||
"destination": "execution-fonds",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
|
@ -6080,17 +6174,19 @@
|
|||
|
||||
"destination": "depo-balance-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
|
||||
|
||||
"table": "balance_depo_register",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "createdAt",
|
||||
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
|
||||
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true
|
||||
}
|
||||
,
|
||||
{"code": "updatedAt",
|
||||
|
|
@ -6102,7 +6198,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "sessionId",
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "depoCode",
|
||||
|
|
@ -6126,6 +6222,8 @@
|
|||
|
||||
"destination": "money-balance-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
|
||||
|
||||
"table": "money_balance_register",
|
||||
|
|
@ -6140,7 +6238,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "infoAccount",
|
||||
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "remainderSum",
|
||||
|
|
@ -6148,23 +6246,23 @@
|
|||
}
|
||||
,
|
||||
{"code": "blockedSum",
|
||||
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
|
||||
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "unblockedSum",
|
||||
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
|
||||
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "inn",
|
||||
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "sessionId",
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "companyFullName",
|
||||
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
|
|
@ -6172,7 +6270,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "createdAt",
|
||||
|
|
@ -6180,7 +6278,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "updatedAt",
|
||||
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
|
||||
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -6192,6 +6290,8 @@
|
|||
|
||||
"destination": "admitted-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
|
||||
|
||||
"table": "admitted_liabilities_register",
|
||||
|
|
@ -6254,6 +6354,8 @@
|
|||
|
||||
"destination": "covered-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
|
||||
|
||||
"table": "covered_Liabilities_register",
|
||||
|
|
@ -6316,6 +6418,8 @@
|
|||
|
||||
"destination": "money-payment-instruction-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
|
||||
|
||||
"table": "money_payment_instruction_register",
|
||||
|
|
@ -6370,6 +6474,8 @@
|
|||
|
||||
"destination": "depo-payment-instruction-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
|
||||
|
||||
"table": "depo_payment_instruction_register",
|
||||
|
|
@ -6424,6 +6530,8 @@
|
|||
|
||||
"destination": "exclude-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
|
||||
|
||||
"table": "exclude_liabilities_register",
|
||||
|
|
@ -6502,6 +6610,8 @@
|
|||
|
||||
"destination": "liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
|
||||
|
||||
"table": "liabilities_register",
|
||||
|
|
@ -6580,6 +6690,8 @@
|
|||
|
||||
"destination": "execution-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
|
||||
|
||||
"table": "execution_register",
|
||||
|
|
@ -7007,10 +7119,6 @@
|
|||
{"code": "notificationStatus",
|
||||
"type": 12,"name": "Наименование статуса сообщения","shortname": "Статус","link": "notificationStatus","required": true
|
||||
}
|
||||
,
|
||||
{"code": "senderId",
|
||||
"type": 1,"name": "Наименование отправителя","shortname": "Отправитель","visible": false,"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
|
||||
<meta version="3.8.0.56">
|
||||
<meta version="3.9.0.71">
|
||||
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
|
||||
<!--Здесь словари-->
|
||||
<enums>
|
||||
|
|
@ -772,8 +772,8 @@
|
|||
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="true" sortable="true" link="security" linkCode="shortName"/>
|
||||
<couponRate type="11" name="Купонная ставка" shortname="Ставка" searchable="true" sortable="true" visible="true"/>
|
||||
<number type="3" name="Номер купона" shortname="Номер" searchable="true" sortable="true" visible="true"/>
|
||||
<periodEndDate type="6" name="Начало периода действия" shortname="Начало" searchable="true" sortable="true" visible="true"/>
|
||||
<periodStartDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/>
|
||||
<periodStartDate type="6" name="Начало периода действия" shortname="Начало" searchable="true" sortable="true" visible="true"/>
|
||||
<periodEndDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/>
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
</couponPeriod>
|
||||
<listing name="Инструменты на режимах" destination="listings" class="ru.clearing.classes.statics.data.misc.Listing" logUpdates="true" table="listing">
|
||||
|
|
@ -959,6 +959,7 @@
|
|||
<post name="Идентификация неразмеченных средств" destination="registries/identificationFunds" confirmation="balance,tradingClearingRegistryId" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/>
|
||||
<balance type="10" name="Сумма" shortname="Сумма" required="true"/>
|
||||
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
|
||||
<tradingClearingRegistryId type="1" name="Торгово-клиринговый регистр" shortname="Торгово-клиринговый регистр" link="tradingClearingRegistry" linkCode="code" required="true"/>
|
||||
</post>
|
||||
<put name="Изменение даты возврата депозита" destination="registries/changeRefundDate" confirmation="contact,contract,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew">
|
||||
|
|
@ -988,7 +989,7 @@
|
|||
<actions>
|
||||
<post name="Добавление счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction">
|
||||
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
|
||||
<account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
|
||||
<account type="2" length="50" name="Номер счета" shortname="Счет"/>
|
||||
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
|
||||
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
|
||||
</post>
|
||||
|
|
@ -1083,6 +1084,20 @@
|
|||
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" />
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
</depoAccount>
|
||||
<accountSymbols name="Депо КС - РДЦ" destination="accounting/depo-accounts-symbols" class="ru.clearing.classes.statics.data.account.AccountSymbols" logUpdates="true" table="depo_account_symbols">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<accountId type="1" dbname="Идентификатор счета" name="Счет депо КС" shortname= "Счет депо КС" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<accountSymbolValue type="2" length="255" name="Счет РДЦ" shortname="Счет РДЦ" searchable="true" sortable="true" visible="true"/>
|
||||
<actions>
|
||||
<post name="Добавление депо КС - РДЦ" confirmation="accountId,accountSymbolValue" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction">
|
||||
<accountId type="1" dbname="Идентификатор счета" name="Счет депо КС" shortname= "Счет депо КС" link="account" linkCode="account" required="true"/>
|
||||
<accountSymbolValue type="2" length="255" name="Счет РДЦ" shortname="Счет РДЦ" required="true"/>
|
||||
</post>
|
||||
<delete name="Удаление депо КС - РДЦ" confirmation="accountId,accountSymbolValue">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" link="account" linkCode="id" required="true"/>
|
||||
</delete>
|
||||
</actions>
|
||||
</accountSymbols>
|
||||
<clearingAccount name="Торгово-Банковские счета" destination="accounting/clearing-accounts" class="ru.clearing.classes.statics.data.account.ClearingAccount" logUpdates="true" table="clearing_account">
|
||||
<accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<clearingAccountType type="12" dbname="Код типа счета" name="Наименование типа счета" shortname="Тип" searchable="true" sortable="true" visible="true" link="clearingAccountType" linkCode="name"/>
|
||||
|
|
@ -1222,12 +1237,13 @@
|
|||
</post>
|
||||
<post destination="GALB" group="Обмен с расчетной организацией" name="Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)">
|
||||
</post>
|
||||
<post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)">
|
||||
<balance type="10" name="Текущий баланс" shortname="Текущие средства" enabled="false"/>
|
||||
<post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)">
|
||||
<fullBalance type="10" name="Текущий баланс (всего)" shortname="Текущие средства (всего)" enabled="false"/>
|
||||
<balance type="10" name="Текущий баланс (свободно)" shortname="Текущие средства (свободно)" enabled="false"/>
|
||||
<securitySymbol type="2" name="Наименование инструмента/валюты" shortname="Валюта" enabled="false"/>
|
||||
<creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма" required="true"/>
|
||||
<paymentPurpose type="2" length="255" name="Назначение платежа" shortname="Основание" required="true"/>
|
||||
<senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true" enabled="false"/>
|
||||
<senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true"/>
|
||||
<creditLeg_accountId type="1" group="Отправитель" name="Наименование счета отправителя" shortname="Регистр списания" link="account" linkCode="account"/>
|
||||
<addresseeId type="1" group="Получатель" name="Участник получатель" shortname="Получатель" link="company" linkCode="shortName" required="true" enabled="false"/>
|
||||
<debitLeg_accountId type="1" group="Получатель" name="Наименование счета получателя" shortname="Счет получателя" link="bankAccount" linkCode="correspondentAccount"/>
|
||||
|
|
@ -1270,6 +1286,10 @@
|
|||
</post>
|
||||
<post destination="FDFF" group="Обмен с расчетной организацией" name="Формирование ДФ-05 с кодом 9 (финальный)">
|
||||
</post>
|
||||
<post destination="CHDF" group="Общее" name="Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21">
|
||||
</post>
|
||||
<post destination="CCLR" group="Клиринг" name="Завершение неудачных клиринговых сессий">
|
||||
</post>
|
||||
</actions>
|
||||
</launcher>
|
||||
|
||||
|
|
@ -1278,7 +1298,7 @@
|
|||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
<clearingDate type="6" name="Дата" shortname="Дата" searchable="true" sortable="true" visible="true"/>
|
||||
<sessionStatus type="12" dbname="Код статуса клиринговой сессии" name="Статус клиринговой сессии" shortname="Статус" searchable="true" sortable="true" visible="true" link="sessionStatus"/>
|
||||
<sessionStatus type="12" dbname="Код статуса клиринговой сессии" name="Статус клиринговой сессии" shortname="Шаг" searchable="true" sortable="true" visible="true" link="sessionStatus"/>
|
||||
<companyId type="1" dbname="Идентификатор инициатора торгов" name="Наименование инициатора торгов" shortname="Инициатор" visible="false" searchable="true" sortable="true" link="company" linkCode="shortName"/>
|
||||
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="false" sortable="true" visible="true" link="security" linkCode="shortName"/>
|
||||
<userId type="1" dbname="Идентификатор пользователя" name="Наименование пользователя" shortname="Пользователь" searchable="true" sortable="true" visible="true" link="userCls" linkCode="identifier"/>
|
||||
|
|
@ -1335,7 +1355,7 @@
|
|||
<bankAccId type="2" length="12" name="Идентификатор расчетного счета/кода в клиринговой организации" shortname="Код позиции" searchable="true" sortable="true"/>
|
||||
<section type="12" dbname="Код наименования секции" name="Наименование секции" shortname="Секция" searchable="true" sortable="true" visible="true" link="section"/>
|
||||
</sTrades>
|
||||
<executionDeposit name="Сделки" destination="execution-deposits" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit">
|
||||
<executionDeposit name="Сделки на секции МКР" destination="execution-deposits" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit">
|
||||
<exchangeExecutionId type="1" name="Идентификационный номер сделки в Торговой системе" shortname="Номер сделки" visible="true" searchable="true" sortable="true"/>
|
||||
<exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
|
||||
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
|
||||
|
|
@ -1371,7 +1391,7 @@
|
|||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" visible="false" searchable="true" sortable="true"/>
|
||||
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" visible="false" searchable="true" sortable="true"/>
|
||||
</executionDeposit>
|
||||
<executionFond name="Сделки на Фондовой секции" destination="execution-fonds" class="ru.clearing.classes.statics.data.execution.ExecutionFond" logUpdates="true" table="execution_fond">
|
||||
<executionFond name="Сделки на Фондовой секции" destination="execution-fonds" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionFond" logUpdates="true" table="execution_fond">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" visible="false" searchable="true" sortable="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" visible="false" searchable="true" sortable="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" visible="false" searchable="true" sortable="true"/>
|
||||
|
|
@ -1406,32 +1426,32 @@
|
|||
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
</executionFond>
|
||||
<depoBalanceRegister name="Реестр остатков ценных бумаг" destination="depo-balance-registers" class="ru.clearing.classes.statics.data.register.DepoBalanceRegister" table="balance_depo_register">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||
<depoBalanceRegister name="Реестр остатков ценных бумаг" destination="depo-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoBalanceRegister" table="balance_depo_register">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" ignore="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" visible="true" searchable="true" sortable="true" link="company" linkCode="shortName"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session" ignore="true"/>
|
||||
<depoCode type="2" length="50" name="Код раздела субсчета/счета депо" shortname="Код счета депо" searchable="true" sortable="true"/>
|
||||
<quantity type="11" name="Количество" shortname="Количество" searchable="true" sortable="true"/>
|
||||
<securitySymbol type="2" length="255" name="Код ценной бумаги" shortname="Ценная бумага" searchable="true" sortable="true"/>
|
||||
</depoBalanceRegister>
|
||||
<moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" class="ru.clearing.classes.statics.data.register.MoneyBalanceRegister" table="money_balance_register">
|
||||
<moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyBalanceRegister" table="money_balance_register">
|
||||
<setHouseName type="2" length="255" name="Наименование РО" shortname="Наименование РО" searchable="true" sortable="true" visible="true"/>
|
||||
<account type="2" length="50" name="Номер торгового/клирингового счета" shortname="Номер торгового/клирингового счета" searchable="true" sortable="true" visible="true"/>
|
||||
<infoAccount type="2" length="50" name="Номер счета внутреннего учета СПВБ" shortname="Номер счета внутреннего учета СПВБ" searchable="true" sortable="true" visible="true"/>
|
||||
<infoAccount type="2" length="50" name="Номер счета внутреннего учета СПВБ" shortname="Номер счета внутреннего учета СПВБ" searchable="true" sortable="true" visible="true" ignore="true"/>
|
||||
<remainderSum type="10" name="Остаток денежных средств" shortname="Остаток" searchable="true" sortable="true"/>
|
||||
<blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true"/>
|
||||
<unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true"/>
|
||||
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
|
||||
<blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true" ignore="true"/>
|
||||
<unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true" ignore="true"/>
|
||||
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true" ignore="true"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session" ignore="true"/>
|
||||
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true" ignore="true"/>
|
||||
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" ignore="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
</moneyBalanceRegister>
|
||||
<admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" class="ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister" table="admitted_liabilities_register">
|
||||
<admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister" table="admitted_liabilities_register">
|
||||
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
<securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
|
||||
|
|
@ -1445,7 +1465,7 @@
|
|||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/>
|
||||
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
|
||||
</admittedLiabilitiesRegister>
|
||||
<coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" class="ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister" table="covered_Liabilities_register">
|
||||
<coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister" table="covered_Liabilities_register">
|
||||
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
<securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
|
||||
|
|
@ -1459,7 +1479,7 @@
|
|||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/>
|
||||
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
|
||||
</coveredLiabilitiesRegister>
|
||||
<moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" class="ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister" table="money_payment_instruction_register">
|
||||
<moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister" table="money_payment_instruction_register">
|
||||
<creditLegAccount type="2" length="50" name="Счет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" visible="true"/>
|
||||
<creditLegAmount type="10" name="Сумма отправителя" shortname="Сумма отправителя" searchable="true" sortable="true" visible="true"/>
|
||||
<creditLegCurrencyCode type="12" dbname="Код валюты отправителя" name="Наименование валюты отправителя" shortname="Валюта отправителя" searchable="true" sortable="true" visible="true" link="currency"/>
|
||||
|
|
@ -1471,7 +1491,7 @@
|
|||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
<clearingDate type="6" name="Дата расчета" shortname="Дата расчета" searchable="true" sortable="true" visible="true"/>
|
||||
</moneyPaymentInstructionRegister>
|
||||
<depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register">
|
||||
<depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
|
|
@ -1483,7 +1503,7 @@
|
|||
<direction type="1" name="Направление" shortname="Направление" searchable="true" sortable="true" link="inOutDirection" ignore="true"/>
|
||||
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
|
||||
</depoPaymentInstructionRegister>
|
||||
<excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register">
|
||||
<excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
|
|
@ -1501,7 +1521,7 @@
|
|||
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
|
||||
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
|
||||
</excludeLiabilitiesRegister>
|
||||
<liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register">
|
||||
<liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||
|
|
@ -1519,7 +1539,7 @@
|
|||
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
|
||||
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
|
||||
</liabilitiesRegister>
|
||||
<executionRegister name="Реестр сделок" destination="execution-registers" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register">
|
||||
<executionRegister name="Реестр сделок" destination="execution-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register">
|
||||
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
|
||||
<exchangeExecutionId type="1" name="Идентификационный номер сделки в Торговой системе" shortname="Номер сделки" visible="true" searchable="true" sortable="true"/>
|
||||
<exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
|
||||
|
|
@ -1622,7 +1642,6 @@
|
|||
<put name="Изменение статуса сообщения" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" link="notification" linkCode="id" required="true"/>
|
||||
<notificationStatus type="12" name="Наименование статуса сообщения" shortname="Статус" link="notificationStatus" required="true"/>
|
||||
<senderId type="1" name="Наименование отправителя" shortname="Отправитель" visible="false" required="true" />
|
||||
</put>
|
||||
</actions>
|
||||
</notification>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
{
|
||||
"version": "3.8.0.56",
|
||||
"version": "3.9.0.71",
|
||||
|
||||
"enums": {
|
||||
|
||||
|
|
@ -3328,11 +3328,11 @@
|
|||
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
{"code": "periodEndDate",
|
||||
{"code": "periodStartDate",
|
||||
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
{"code": "periodStartDate",
|
||||
{"code": "periodEndDate",
|
||||
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
,
|
||||
|
|
@ -4132,6 +4132,10 @@
|
|||
{"code": "balance",
|
||||
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
|
||||
}
|
||||
,
|
||||
{"code": "tradingClearingRegistryId",
|
||||
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
|
||||
|
|
@ -4263,7 +4267,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "account",
|
||||
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
|
||||
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет"
|
||||
}
|
||||
,
|
||||
{"code": "status",
|
||||
|
|
@ -4664,6 +4668,66 @@
|
|||
}
|
||||
]
|
||||
|
||||
}
|
||||
,
|
||||
"accountSymbols": {
|
||||
|
||||
"name": "Депо КС - РДЦ",
|
||||
|
||||
"destination": "accounting/depo-accounts-symbols",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.account.AccountSymbols",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
||||
"table": "depo_account_symbols",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
}
|
||||
,
|
||||
{"code": "accountId",
|
||||
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","searchable": true,"sortable": true,"visible": true,"link": "account","linkCode": "account"
|
||||
}
|
||||
,
|
||||
{"code": "accountSymbolValue",
|
||||
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","searchable": true,"sortable": true,"visible": true
|
||||
}
|
||||
]
|
||||
,"actions":[
|
||||
{"method":"post",
|
||||
|
||||
"name": "Добавление депо КС - РДЦ",
|
||||
|
||||
"confirmation": "accountId,accountSymbolValue",
|
||||
|
||||
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountSymbolsNewAction",
|
||||
|
||||
"fields": [
|
||||
{"code": "accountId",
|
||||
"type": 1,"dbname": "Идентификатор счета","name": "Счет депо КС","shortname": "Счет депо КС","link": "account","linkCode": "account","required": true
|
||||
}
|
||||
,
|
||||
{"code": "accountSymbolValue",
|
||||
"type": 2,"length": 255,"name": "Счет РДЦ","shortname": "Счет РДЦ","required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
,
|
||||
{"method":"delete",
|
||||
|
||||
"name": "Удаление депо КС - РДЦ",
|
||||
|
||||
"confirmation": "accountId,accountSymbolValue",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
,
|
||||
"clearingAccount": {
|
||||
|
|
@ -5270,11 +5334,15 @@
|
|||
|
||||
"group": "Обмен с расчетной организацией",
|
||||
|
||||
"name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
|
||||
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)",
|
||||
|
||||
"fields": [
|
||||
{"code": "fullBalance",
|
||||
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "balance",
|
||||
"type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
|
||||
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "securitySymbol",
|
||||
|
|
@ -5290,7 +5358,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "senderId",
|
||||
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true
|
||||
}
|
||||
,
|
||||
{"code": "creditLeg_accountId",
|
||||
|
|
@ -5509,6 +5577,28 @@
|
|||
|
||||
"name": "Формирование ДФ-05 с кодом 9 (финальный)",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
,
|
||||
{"method":"post",
|
||||
|
||||
"destination": "CHDF",
|
||||
|
||||
"group": "Общее",
|
||||
|
||||
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
,
|
||||
{"method":"post",
|
||||
|
||||
"destination": "CCLR",
|
||||
|
||||
"group": "Клиринг",
|
||||
|
||||
"name": "Завершение неудачных клиринговых сессий",
|
||||
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
|
|
@ -5544,7 +5634,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "sessionStatus",
|
||||
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
|
||||
"type": 12,"dbname": "Код статуса клиринговой сессии","name": "Статус клиринговой сессии","shortname": "Шаг","searchable": true,"sortable": true,"visible": true,"link": "sessionStatus"
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
|
|
@ -5776,10 +5866,12 @@
|
|||
,
|
||||
"executionDeposit": {
|
||||
|
||||
"name": "Сделки",
|
||||
"name": "Сделки на секции МКР",
|
||||
|
||||
"destination": "execution-deposits",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
|
@ -5932,6 +6024,8 @@
|
|||
|
||||
"destination": "execution-fonds",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
|
||||
|
||||
"logUpdates": "true",
|
||||
|
|
@ -6080,17 +6174,19 @@
|
|||
|
||||
"destination": "depo-balance-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
|
||||
|
||||
"table": "balance_depo_register",
|
||||
|
||||
"fields": [
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "createdAt",
|
||||
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
|
||||
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true
|
||||
}
|
||||
,
|
||||
{"code": "updatedAt",
|
||||
|
|
@ -6102,7 +6198,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "sessionId",
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "depoCode",
|
||||
|
|
@ -6126,6 +6222,8 @@
|
|||
|
||||
"destination": "money-balance-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
|
||||
|
||||
"table": "money_balance_register",
|
||||
|
|
@ -6140,7 +6238,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "infoAccount",
|
||||
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "remainderSum",
|
||||
|
|
@ -6148,23 +6246,23 @@
|
|||
}
|
||||
,
|
||||
{"code": "blockedSum",
|
||||
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
|
||||
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "unblockedSum",
|
||||
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
|
||||
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "inn",
|
||||
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "sessionId",
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
|
||||
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "companyFullName",
|
||||
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true
|
||||
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "companyId",
|
||||
|
|
@ -6172,7 +6270,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "id",
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
|
||||
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
,
|
||||
{"code": "createdAt",
|
||||
|
|
@ -6180,7 +6278,7 @@
|
|||
}
|
||||
,
|
||||
{"code": "updatedAt",
|
||||
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
|
||||
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -6192,6 +6290,8 @@
|
|||
|
||||
"destination": "admitted-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
|
||||
|
||||
"table": "admitted_liabilities_register",
|
||||
|
|
@ -6254,6 +6354,8 @@
|
|||
|
||||
"destination": "covered-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
|
||||
|
||||
"table": "covered_Liabilities_register",
|
||||
|
|
@ -6316,6 +6418,8 @@
|
|||
|
||||
"destination": "money-payment-instruction-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
|
||||
|
||||
"table": "money_payment_instruction_register",
|
||||
|
|
@ -6370,6 +6474,8 @@
|
|||
|
||||
"destination": "depo-payment-instruction-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
|
||||
|
||||
"table": "depo_payment_instruction_register",
|
||||
|
|
@ -6424,6 +6530,8 @@
|
|||
|
||||
"destination": "exclude-liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
|
||||
|
||||
"table": "exclude_liabilities_register",
|
||||
|
|
@ -6502,6 +6610,8 @@
|
|||
|
||||
"destination": "liabilities-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
|
||||
|
||||
"table": "liabilities_register",
|
||||
|
|
@ -6580,6 +6690,8 @@
|
|||
|
||||
"destination": "execution-registers",
|
||||
|
||||
"historyDestination": "history",
|
||||
|
||||
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
|
||||
|
||||
"table": "execution_register",
|
||||
|
|
@ -7007,10 +7119,6 @@
|
|||
{"code": "notificationStatus",
|
||||
"type": 12,"name": "Наименование статуса сообщения","shortname": "Статус","link": "notificationStatus","required": true
|
||||
}
|
||||
,
|
||||
{"code": "senderId",
|
||||
"type": 1,"name": "Наименование отправителя","shortname": "Отправитель","visible": false,"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package ru.clearing.classes.statics.data.account;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
|
||||
/**
|
||||
* Депо КС - РДЦ
|
||||
* <p>
|
||||
* DB table: ACCOUNT_SYMBOLS
|
||||
**/
|
||||
public class AccountSymbols extends SpcexObjectBase {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Long accountId;
|
||||
private String accountSymbolValue;
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(Long value) {
|
||||
this.accountId = value;
|
||||
}
|
||||
|
||||
public String getAccountSymbolValue() {
|
||||
return accountSymbolValue;
|
||||
}
|
||||
|
||||
public void setAccountSymbolValue(String value) {
|
||||
this.accountSymbolValue = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package ru.clearing.classes.statics.data.account;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.clearing.classes.objects.BusinessEvent;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* Изменение состояния объекта Депо КС - РДЦ
|
||||
* <p>
|
||||
* DB table: ACCOUNT_SYMBOLS_HISTORY
|
||||
**/
|
||||
public class AccountSymbolsHistory extends BusinessEvent<AccountSymbols> {
|
||||
@Serial
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private AccountSymbols object;
|
||||
|
||||
@Override
|
||||
public AccountSymbols getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObject(AccountSymbols object) {
|
||||
this.object = object;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package ru.spcex.clearing.config;
|
|||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
|
@ -26,19 +28,31 @@ import java.util.function.Supplier;
|
|||
|
||||
@Configuration
|
||||
public class KafkaConfig {
|
||||
@Autowired
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Bean("kafkaConsumer")
|
||||
public Consumer<String, Object> createConsumer(ClearingServiceSettings settings) {
|
||||
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final KafkaConsumerSettings kafkaSettings;
|
||||
|
||||
public KafkaConfig(ClearingServiceSettings settings) {
|
||||
this.kafkaSettings = settings.getKafkaConsumer();
|
||||
Integer gtwTimeout = settings.getSessionStage().getInspectionGatewayTimeout();
|
||||
if (gtwTimeout != null) {
|
||||
int maxPollIntervalMs = gtwTimeout * 1000 + 1000;
|
||||
log.debug("setting max.poll.interval.ms {}", maxPollIntervalMs);
|
||||
this.kafkaSettings.setManuallyMaxPollIntervalMs(maxPollIntervalMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Bean("kafkaConsumer")
|
||||
public Consumer<String, Object> createConsumer() {
|
||||
return KafkaConsumerFactory.consumer(kafkaSettings);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean("kafkaConsumerGateway")
|
||||
public Supplier<Consumer<String, Object>> getwaySessionConsumer(ClearingServiceSettings settings) {
|
||||
public Supplier<Consumer<String, Object>> getwaySessionConsumer() {
|
||||
AtomicInteger groupId = new AtomicInteger(1);
|
||||
return () -> {
|
||||
KafkaConsumerSettings consumer = settings.getKafkaConsumer();
|
||||
KafkaConsumerSettings consumer = kafkaSettings;
|
||||
KafkaConsumerSettings gatewayConsumer = new KafkaConsumerSettings();
|
||||
gatewayConsumer.setBootstrapServers(consumer.getBootstrapServers());
|
||||
gatewayConsumer.setSessionTimeoutMs(consumer.getSessionTimeoutMs());
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.account.AccountBalance;
|
||||
import ru.clearing.classes.statics.data.account.DepoAccount;
|
||||
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.company.relation.Relation;
|
||||
|
|
@ -45,6 +46,7 @@ import ru.spcex.platform.utils.validation.ValidatorImpl;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Configuration
|
||||
public class ValidationConfig {
|
||||
|
|
@ -69,6 +71,7 @@ public class ValidationConfig {
|
|||
Imdg<SDf55> sDf55Imdg;
|
||||
Imdg<SDf54> sDf54Imdg;
|
||||
Imdg<PaymentInstruction> pmtImdg;
|
||||
Imdg<ClearingMemberCategory> ctgrImdg;
|
||||
ImdgProvider imdgProvider;
|
||||
|
||||
public ValidationConfig(ImdgProvider imdgProvider) {
|
||||
|
|
@ -91,6 +94,7 @@ public class ValidationConfig {
|
|||
this.sDf55Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf55, SDf55.class);
|
||||
this.sDf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
|
||||
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.ctgrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
this.imdgProvider = imdgProvider;
|
||||
}
|
||||
|
||||
|
|
@ -326,12 +330,14 @@ public class ValidationConfig {
|
|||
ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(returnDepositRequest);
|
||||
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
|
||||
context.addImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ctgrImdg);
|
||||
context.setLogPrefix(LogPrefixId.INSTANCE);
|
||||
return new ValidatorImpl<>(context,
|
||||
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
|
||||
ReturnDepositValidationRule.RegistryCodeCheck,
|
||||
ReturnDepositValidationRule.RgsWronCodeCheck,
|
||||
ReturnDepositValidationRule.CategoryCheck,
|
||||
ReturnDepositValidationRule.BalanceCheck,
|
||||
ReturnDepositValidationRule.DmxCheck
|
||||
ReturnDepositValidationRule.Dm_Check
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -362,6 +368,7 @@ public class ValidationConfig {
|
|||
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
|
||||
StatusExtractValidationRule.RegistryCodeCheck,
|
||||
StatusExtractValidationRule.ContractCheck,
|
||||
StatusExtractValidationRule.RequestStatusValid,
|
||||
StatusExtractValidationRule.RegistryStatusValid
|
||||
);
|
||||
};
|
||||
|
|
@ -407,7 +414,8 @@ public class ValidationConfig {
|
|||
IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class,
|
||||
ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false),
|
||||
SplitDepositRequestValidationRule.PositiveAmount,
|
||||
SplitDepositRequestValidationRule.CrossvalidateByRegistry
|
||||
SplitDepositRequestValidationRule.CrossvalidateByRegistry,
|
||||
SplitDepositRequestValidationRule.LoadContractIndexes
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -427,13 +435,13 @@ public class ValidationConfig {
|
|||
IMDGDistributedNames.Map_Company,
|
||||
Company.class,
|
||||
ClearingError.RequiredFieldEmpty,
|
||||
ClearingError.DictionaryNotFound),
|
||||
ClearingError.WrongField),
|
||||
IdPresentRule.instance("addresseeId",
|
||||
PIClearingOutbondActionNewRequest::getAddresseeId,
|
||||
IMDGDistributedNames.Map_Company,
|
||||
Company.class,
|
||||
ClearingError.RequiredFieldEmpty,
|
||||
ClearingError.DictionaryNotFound),
|
||||
ClearingError.WrongField),
|
||||
PaymentOutboundValidationRule.CreditLegAccount,
|
||||
PaymentOutboundValidationRule.DebitLegAccount,
|
||||
PaymentOutboundValidationRule.AddresseePresent,
|
||||
|
|
@ -484,6 +492,19 @@ public class ValidationConfig {
|
|||
};
|
||||
}
|
||||
|
||||
@Bean("terminateSessionValidator")
|
||||
public Supplier<IValidator> terminateSessionValidator() {
|
||||
return () -> {
|
||||
ImdgValidationContext<Session> ctx = new ImdgValidationContext<>();
|
||||
ctx.setLogPrefix(LogPrefixId.INSTANCE);
|
||||
ctx.addImdg(IMDGDistributedNames.Map_Session, imdgSession);
|
||||
return new ValidatorImpl<>(ctx,
|
||||
SessionTerminationValidationRule.SessionPresent,
|
||||
SessionTerminationValidationRule.StatusCheck
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean("userRoleVerification")
|
||||
public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver msgs) {
|
||||
return new UserRoleVerification(imdgProvider, msgs, ClearingError.UserVerifyDenial);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public class ClearingServiceSettings {
|
|||
private KafkaConsumerSettings kafkaConsumer;
|
||||
private KafkaProducerSettings kafkaProducer;
|
||||
private SessionStageSettings sessionStage;
|
||||
private TradeSettings trade = new TradeSettings();
|
||||
|
||||
public HazelcastClientParams getHazelcast() {
|
||||
return hazelcast;
|
||||
|
|
@ -47,4 +48,12 @@ public class ClearingServiceSettings {
|
|||
public void setSessionStage(SessionStageSettings sessionStage) {
|
||||
this.sessionStage = sessionStage;
|
||||
}
|
||||
|
||||
public TradeSettings getTrade() {
|
||||
return trade;
|
||||
}
|
||||
|
||||
public void setTrade(TradeSettings trade) {
|
||||
this.trade = trade;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package ru.spcex.clearing.config.element;
|
||||
|
||||
|
||||
public class TradeSettings {
|
||||
private Boolean valuation = false;
|
||||
|
||||
public Boolean getValuation() {
|
||||
return valuation;
|
||||
}
|
||||
|
||||
public void setValuation(Boolean valuation) {
|
||||
this.valuation = valuation;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ public enum ClearingError implements IErrorEnumId {
|
|||
SuchRecordAlreadyExists(5405L),
|
||||
TradingClearingRegistryNotFound(5418L),
|
||||
TradingClearingRegistryNotActive(5419L),
|
||||
CategoryNotFound(5420L),
|
||||
ClearingUnavailableForCompany(5421L),
|
||||
InsecurityObligation(5422L),
|
||||
NewDealsNotFound(5423L),
|
||||
|
|
@ -34,6 +35,7 @@ public enum ClearingError implements IErrorEnumId {
|
|||
RgsWrongCode(5430L),
|
||||
RefundDateCannotBeChanged(5431L),
|
||||
PlanBalanceReviseError(5432L),
|
||||
XdepTimeIntervalNotMatch(5433L),
|
||||
//ошибки "перенесенные" из balance-service,
|
||||
CompanyNotFoundB(5211L),
|
||||
CurrencyNotFound(5213L),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class NotificationSender {
|
|||
|
||||
public void sendNotification(ObjectType objType, String comment, Priority priority) {
|
||||
NotificationNewRequest reviseNotification = new NotificationNewRequest();
|
||||
reviseNotification.setObjectType(ObjectType.rgst.getKey());
|
||||
reviseNotification.setObjectType(objType.getKey());
|
||||
reviseNotification.setComment(comment);
|
||||
reviseNotification.setPriority(priority.getKey());
|
||||
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
|||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Component
|
||||
public class AnltSearcher {
|
||||
|
|
@ -52,7 +56,10 @@ public class AnltSearcher {
|
|||
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
|
||||
ImdgPredicate tcrPredicate = pb.and(
|
||||
pb.equals("code", commentTcrStripped),
|
||||
pb.equals("status", ServiceStatus.Active.getKey())
|
||||
pb.or(
|
||||
pb.equals("status", ServiceStatus.Active.getKey()),
|
||||
pb.equals("status", ServiceStatus.Reopened.getKey())
|
||||
)
|
||||
);
|
||||
|
||||
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByPredicate(tcrPredicate);
|
||||
|
|
@ -80,25 +87,19 @@ public class AnltSearcher {
|
|||
return new AnltSearch(infoAcc, company, tcr);
|
||||
}
|
||||
|
||||
private static final Pattern tcrPattern = Pattern.compile("ТКР.*?([0-9A-Z-]{12})");
|
||||
|
||||
private static String getTkrCodeFromComment(String comment) {
|
||||
if (comment == null) {
|
||||
if (TextUtil.isEmpty(comment)) {
|
||||
return null;
|
||||
}
|
||||
comment = comment.toUpperCase();
|
||||
int tcrIndex = comment.indexOf("ТКР");
|
||||
if (tcrIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
if (comment.length() < (tcrIndex + 4)) {
|
||||
return null;
|
||||
}
|
||||
int spaceAfterTCR = comment.indexOf(" ", tcrIndex + 4);
|
||||
if (spaceAfterTCR == -1) {
|
||||
comment = comment.substring(tcrIndex + 4);
|
||||
Matcher matcher = tcrPattern.matcher(comment);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
comment = comment.substring(tcrIndex + 4, spaceAfterTCR);
|
||||
return null;
|
||||
}
|
||||
return comment.replaceAll("\\s+", "");
|
||||
}
|
||||
|
||||
public static class AnltSearch {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
private final BalanceRevise balanceRevise;
|
||||
private final Sdf05Sender sdf05Sender;
|
||||
private final StatementServiceV2 statementService;
|
||||
private final SessionTerminator sessionTerminator;
|
||||
private final PaymentInstructionOutboundService pmtOutboundService;
|
||||
|
||||
@Autowired
|
||||
|
|
@ -65,7 +66,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
SecondaryAuctionT0Session secondaryAuctionT0Session,
|
||||
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
|
||||
Sdf06Executor sdf06Executor,
|
||||
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, PaymentInstructionOutboundService pmtOutboundService) {
|
||||
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, SessionTerminator sessionTerminator, PaymentInstructionOutboundService pmtOutboundService) {
|
||||
super(kafkaQueue, kafkaResponseQueue);
|
||||
this.errorResolver = errorResolver;
|
||||
this.clearingService = clearingService;
|
||||
|
|
@ -83,6 +84,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
this.balanceRevise = balanceRevise;
|
||||
this.sdf05Sender = sdf05Sender;
|
||||
this.statementService = statementService;
|
||||
this.sessionTerminator = sessionTerminator;
|
||||
this.pmtOutboundService = pmtOutboundService;
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +186,11 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
callback(LauncherCommandRequest.class)
|
||||
.setConsumer(task -> sdf05Sender.sendSdf05("9"))
|
||||
.forDestination(Task.sdf05WithCode9Final.topic(), callbacks::put);
|
||||
|
||||
callback(Object.class)
|
||||
.setFunction(sessionTerminator::stopCurrentSession)
|
||||
.forDestination(Consts.KILL_SESSION, callbacks::put);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.misc.Currency;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
|
|
@ -12,14 +14,18 @@ import ru.spcex.clearing.error.ClearingError;
|
|||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.notification.NotificationSender;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.platform.messaging.service.Status;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
|
||||
import ru.spcex.clearing.service.integration.GatewayRequestCreator;
|
||||
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
|
||||
import ru.spcex.clearing.service.registry.RegistryManager;
|
||||
import ru.spcex.clearing.service.schedule.TradingTimeService;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
|
||||
|
|
@ -41,13 +47,12 @@ import ru.spcex.platform.utils.validation.IValidator;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||
|
||||
@Service
|
||||
|
|
@ -57,6 +62,9 @@ public class RegistryService {
|
|||
private final ImdgProvider imdgProvider;
|
||||
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final Imdg<Account> accImdg;
|
||||
private final Imdg<Currency> currImdg;
|
||||
private final Imdg<Company> cmpImdg;
|
||||
private final Imdg<PaymentInstruction> pmtImdg;
|
||||
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
|
||||
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
|
||||
|
|
@ -66,6 +74,7 @@ public class RegistryService {
|
|||
private final GatewayRequester gateway;
|
||||
private final TradingTimeService trdTime;
|
||||
private final NotificationSender notification;
|
||||
private final KafkaSender kafkaSender;
|
||||
|
||||
private final IMessageResolver msgResolver;
|
||||
private final RequestHelper reqHelp;
|
||||
|
|
@ -81,7 +90,7 @@ public class RegistryService {
|
|||
GatewayRequester gateway,
|
||||
TradingTimeService tradingTimeService,
|
||||
NotificationSender notification,
|
||||
IMessageResolver msgResolver,
|
||||
KafkaSender kafkaSender, IMessageResolver msgResolver,
|
||||
RequestHelper reqHelp,
|
||||
UserRoleVerification rights,
|
||||
AssetTBFProcessing assets) {
|
||||
|
|
@ -89,6 +98,9 @@ public class RegistryService {
|
|||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.accImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
|
||||
this.cmpImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.returnDepositVal = returnDepositVal;
|
||||
this.refundDateVal = refundDateVal;
|
||||
this.identificationFundsVal = identificationFundsVal;
|
||||
|
|
@ -97,6 +109,7 @@ public class RegistryService {
|
|||
this.gateway = gateway;
|
||||
this.trdTime = tradingTimeService;
|
||||
this.notification = notification;
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.assets = assets;
|
||||
this.gateway.setName("RgsService|DM*V");
|
||||
this.msgResolver = msgResolver;
|
||||
|
|
@ -154,6 +167,59 @@ public class RegistryService {
|
|||
registryImdg.update(rgs);
|
||||
log.trace("TCR#id={} registry#id={} updated", tcr.getId(), rgs.getId());
|
||||
});
|
||||
|
||||
if (registries.stream().anyMatch(r -> RegistryInstrumentType.M.equalsByKey(r.getRegistryInstrumentType()))) {
|
||||
log.info("assets size {} updated by TCR#id={}, will not create new assets",
|
||||
registries.size(), tcr.getId());
|
||||
return;
|
||||
} else if (tcr.getMoneyAccountId() == null) {
|
||||
log.info("assets size {} updated by TCR#id={}, TCR#moneyAccountId 'null'. will not create AM**",
|
||||
registries.size(), tcr.getId());
|
||||
return;
|
||||
} else {
|
||||
log.info("assets size {} updated by TCR#id={}, TCR#moneyAccountId {}. creating new AM**...",
|
||||
registries.size(), tcr.getId(), tcr.getMoneyAccountId());
|
||||
}
|
||||
|
||||
Account acc = accImdg.getSingleObjectByID(tcr.getMoneyAccountId());
|
||||
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
|
||||
Company cmp = cmpImdg.getSingleObjectByID(tcr.getCompanyId());
|
||||
|
||||
if (acc == null) {
|
||||
log.warn("TCR#id={} account {} not found", tcr.getId(), tcr.getMoneyAccountId());
|
||||
return;
|
||||
}
|
||||
if (currency == null) {
|
||||
log.warn("TCR#id={} currency {} not found", tcr.getId(), CurrencyCode.RUB.getKey());
|
||||
return;
|
||||
}
|
||||
if (cmp == null) {
|
||||
log.warn("TCR#id={} company {} not found", tcr.getId(), tcr.getCompanyId());
|
||||
return;
|
||||
}
|
||||
log.debug("TCR#id={} account#id={} company#id={}, creating assets", tcr.getId(), acc.getId(), cmp.getId());
|
||||
|
||||
AssetTrio assets = this.assets.createMAssets(acc,
|
||||
CurrencyCode.RUB.getKey(),
|
||||
currency.getId(),
|
||||
tcr.getTradingClearingRegistryType(),
|
||||
tcr.getId(),
|
||||
tcr.getCode(),
|
||||
cmp);
|
||||
|
||||
|
||||
Stream.of(assets.a__t(), assets.a__b(), assets.a__f())
|
||||
.forEach(a -> {
|
||||
a.setRegistryStatus(RegistryStatus.PROC.getKey());
|
||||
registryImdg.insert(a);
|
||||
});
|
||||
|
||||
log.debug("TCR#id={} created {}#id={} {}#id={} {}#id={}",
|
||||
tcr.getId(),
|
||||
assets.a__f().getRegistryCode(), assets.a__f().getId(),
|
||||
assets.a__t().getRegistryCode(), assets.a__t().getId(),
|
||||
assets.a__b().getRegistryCode(), assets.a__b().getId());
|
||||
|
||||
}
|
||||
|
||||
public RequestInfoUpdate returnDeposit(BaseRequest<RegistryReturnDepositRequest> req) {
|
||||
|
|
@ -166,28 +232,40 @@ public class RegistryService {
|
|||
msgResolver.resolve(err.get()));
|
||||
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
|
||||
}
|
||||
Registry tm_t = validator.getStored(Stored.PresentById);
|
||||
Registry dm_x = validator.getStored(ValidationStored.ReturnDepositDmx);
|
||||
if (dm_x != null) {
|
||||
dm_x.setSessionId(null);
|
||||
dm_x.setSessionType(null);
|
||||
dm_x.setBalance(requestPayload.getBalance());
|
||||
dm_x.setUpdated(Instant.now());
|
||||
registryImdg.update(dm_x);
|
||||
log.debug("updated dm*x.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm_x.getId(),
|
||||
Registry _m_t = validator.getStored(ValidationStored.ReturnDepositOm_t);
|
||||
if (_m_t == null) _m_t = validator.getStored(Stored.PresentById);
|
||||
|
||||
Registry dm__ = validator.getStored(ValidationStored.ReturnDepositDm__);
|
||||
if (dm__ != null) {
|
||||
dm__.setSessionId(null);
|
||||
dm__.setSessionType(null);
|
||||
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
|
||||
dm__.setUpdated(Instant.now());
|
||||
registryImdg.update(dm__);
|
||||
log.debug("updated {}.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm__.getRegistryCode(),
|
||||
dm__.getId(),
|
||||
req.getId());
|
||||
} else {
|
||||
dm_x = tm_t.clone();
|
||||
dm_x.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
dm_x.setRegistryUnit(RegistryUnit.X.getKey());
|
||||
dm_x.setRegistryCode(RegistryUtil.clearingCode(dm_x));
|
||||
dm_x.setBalance(requestPayload.getBalance());
|
||||
dm_x.setSessionId(null);
|
||||
dm_x.setSessionType(null);
|
||||
registryImdg.insert(dm_x);
|
||||
log.debug("created dm*x.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm_x.getId(),
|
||||
dm__ = _m_t.clone();
|
||||
dm__.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
RegistryManager.zeroState(dm__);
|
||||
dm__.setSettlementDate(LocalDate.now());
|
||||
dm__.setValueDate(null);
|
||||
dm__.setRefundDate(null);
|
||||
if (RegistryDesignation.T.equalsByKey(_m_t.getRegistryDesignation())) {
|
||||
dm__.setRegistryUnit(RegistryUnit.X.getKey());
|
||||
} else {
|
||||
dm__.setRegistryUnit(RegistryUnit.T.getKey());
|
||||
}
|
||||
dm__.setRegistryCode(RegistryUtil.clearingCode(dm__));
|
||||
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance()));
|
||||
dm__.setSessionId(null);
|
||||
dm__.setSessionType(null);
|
||||
registryImdg.insert(dm__);
|
||||
log.debug("created {}.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm__.getRegistryCode(),
|
||||
dm__.getId(),
|
||||
req.getId());
|
||||
}
|
||||
return new RequestInfoUpdate(req.getId(), Status.Success, null);
|
||||
|
|
@ -207,23 +285,11 @@ public class RegistryService {
|
|||
return reqHelp.error(req.getId(), err.get());
|
||||
}
|
||||
Registry rgs = validator.getStored(Stored.PresentById);
|
||||
Supplier<AssetOperationRequest> gtwBuilder = () -> GatewayRequestCreator.from(rgs);
|
||||
Optional<Boolean> gatewayOk;
|
||||
if (trdTime.isTradingTime()) {
|
||||
gatewayOk = gateway.gatewayRequestAndWait(gtwBuilder);
|
||||
Long gtwReqId = kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, gtwReq(rgs));
|
||||
log.debug("send request to {} id={}", Consts.ASSET_OPERATION, gtwReqId);
|
||||
} else {
|
||||
log.debug("RegistryChangeStatusExtractRequest rgs.id={} not sending gateway request", rgs.getId());
|
||||
gatewayOk = Optional.of(true);
|
||||
}
|
||||
if (gatewayOk.isEmpty() || !gatewayOk.get()) {
|
||||
String gtwErr = msgResolver.resolve(mapError(gatewayOk));
|
||||
log.error("{}.id={} {}",
|
||||
rgs.getRegistryCode(),
|
||||
rgs.getId(),
|
||||
gtwErr);
|
||||
notification.sendNotification(ObjectType.rgst,
|
||||
"Отметка о получении выписки: %s".formatted(gtwErr),
|
||||
Priority.HIGH);
|
||||
}
|
||||
rgs.setRegistryStatus(payload.getRegistryStatus());
|
||||
log.debug("changing registry.id={} status to {}", rgs.getId(), payload.getRegistryStatus());
|
||||
|
|
@ -238,6 +304,13 @@ public class RegistryService {
|
|||
return reqHelp.success(req.getId());
|
||||
}
|
||||
|
||||
private AssetOperationListRequest gtwReq(Registry rgs) {
|
||||
AssetOperationRequest item = GatewayRequestCreator.from(rgs, InOutDirection.in);
|
||||
AssetOperationListRequest gtwReq = new AssetOperationListRequest();
|
||||
gtwReq.setAssetOperationRequests(Collections.singletonList(item));
|
||||
return gtwReq;
|
||||
}
|
||||
|
||||
public RequestInfoUpdate identificationFunds(BaseRequest<IdentificationFundsRequest> req) {
|
||||
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
|
||||
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
|
||||
|
|
@ -281,22 +354,19 @@ public class RegistryService {
|
|||
.build();
|
||||
pmt.setTransactionStatus(TransactionStatus.ok.getKey());
|
||||
pmtImdg.insert(pmt);
|
||||
//BankAccount bnkAcc = bnkAccImdg.getFirstObjectBySQL("accountId = %d".formatted(accDeb.getId()));
|
||||
// if (bnkAcc != null) {
|
||||
// pmt.setAddresseeBankName(bnkAcc.getBankIdentificationCode());
|
||||
// pmt.setDebit_csAccount(bnkAcc.getCorrespondentAccount());
|
||||
// }
|
||||
// Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
|
||||
// if (currency != null) {
|
||||
// pmt.setCreditLeg_securityId(currency.getId());
|
||||
// pmt.setDebitLeg_securityId(currency.getId());
|
||||
// }
|
||||
// pmt.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
registryImdg.update(dmau);
|
||||
registryImdg.update(asts.a__t());
|
||||
assets.process(asts.a__b(), asts.a__t(), asts.a__f(), BigDecimal.ZERO);
|
||||
log.debug("IdentificationFundsRequest.id={} dmau.id={} am*t.id={} payment_instruction.id={}",
|
||||
req.getId(), dmau.getId(), asts.a__t().getId(), pmt.getId());
|
||||
if (trdTime.isTradingTime()) {
|
||||
log.trace("sending gateway request for IdentificationFundsRequest.id={} dmau.id={}",
|
||||
req.getId(), dmau.getId());
|
||||
kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION,
|
||||
gatewayRequest(dmau, payload.getBalance(),
|
||||
accCompTcr.getCompany().getTradingCode(),
|
||||
asts.a__t().getTradingClearingRegistry()));
|
||||
}
|
||||
return reqHelp.success(req.getId());
|
||||
}
|
||||
|
||||
|
|
@ -345,8 +415,14 @@ public class RegistryService {
|
|||
if (moneyPredicate.isEmpty() && depoPredicate.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
ImdgPredicate accIdPrdct;
|
||||
if (moneyPredicate.isPresent() && depoPredicate.isPresent()) {
|
||||
accIdPrdct = prdBldr.or(moneyPredicate.get(), depoPredicate.get());
|
||||
} else {
|
||||
accIdPrdct = prdBldr.and(moneyPredicate.orElse(prdBldr.alwaysTrue()), depoPredicate.orElse(prdBldr.alwaysTrue()));
|
||||
}
|
||||
return Optional.ofNullable(prdBldr.and(
|
||||
prdBldr.and(moneyPredicate.orElse(prdBldr.alwaysTrue()), depoPredicate.orElse(prdBldr.alwaysTrue())),
|
||||
accIdPrdct,
|
||||
prdBldr.equals("companyId", companyId),
|
||||
prdBldr.sql("tradingClearingRegistryId == null")
|
||||
));
|
||||
|
|
@ -371,56 +447,70 @@ public class RegistryService {
|
|||
}
|
||||
|
||||
|
||||
public record RgsKey (Long companyId, Long accountId, Long securityId) {
|
||||
public static RgsKey fromRgs(Registry rgs) {
|
||||
return new RgsKey(rgs.getCompanyId(), rgs.getAccountId(), rgs.getSecurityId());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Registry> find(List<Registry> group, RegistryTradingParams rgsCode) {
|
||||
List<Registry> byCodeRes = group.stream()
|
||||
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
|
||||
.toList();
|
||||
|
||||
if (byCodeRes.size() > 1) {
|
||||
Optional<Registry> any = group.stream().findFirst();
|
||||
if (any.isEmpty()) throw new IllegalStateException(); //never
|
||||
String err = "FATAL: found %d entries by code %s in group %s".formatted(
|
||||
byCodeRes.size(),
|
||||
rgsCode,
|
||||
RgsKey.fromRgs(any.get()).toString()
|
||||
);
|
||||
throw new IllegalStateException(err);
|
||||
}
|
||||
return byCodeRes.stream().findFirst();
|
||||
}
|
||||
|
||||
public void resetBalances() {
|
||||
Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of(
|
||||
"registryDesignation", RegistryDesignation.A.getKey())
|
||||
);
|
||||
|
||||
for (Registry registry : registriesA) {
|
||||
if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) {
|
||||
registry.setBalance(BigDecimal.ZERO);
|
||||
}
|
||||
if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) {
|
||||
Optional<Registry> registryBOptional = registriesA.stream().filter(rgs ->
|
||||
rgs.getAccount() != null && rgs.getSecurityId() != null &&
|
||||
rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null &&
|
||||
RegistryUnit.B.equalsByKey(rgs.getRegistryUnit()) &&
|
||||
rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) &&
|
||||
rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) &&
|
||||
rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) &&
|
||||
rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId())
|
||||
).findFirst();
|
||||
Optional<Registry> registryTOptional = registriesA.stream().filter(rgs ->
|
||||
rgs.getAccount() != null && rgs.getSecurityId() != null &&
|
||||
rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null &&
|
||||
RegistryUnit.T.equalsByKey(rgs.getRegistryUnit()) &&
|
||||
rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) &&
|
||||
rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) &&
|
||||
rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) &&
|
||||
rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId())
|
||||
).findFirst();
|
||||
BigDecimal balanceB;
|
||||
if (registryBOptional.isPresent()) {
|
||||
balanceB = registryBOptional.get().getBalance();
|
||||
} else {
|
||||
balanceB = BigDecimal.ZERO;
|
||||
}
|
||||
registryTOptional.ifPresent(rgsT -> registry.setBalance(rgsT.getBalance().subtract(balanceB)));
|
||||
}
|
||||
if (RegistryUnit.T.equalsByKey(registry.getRegistryUnit())) {
|
||||
registry.setOpenBalance(registry.getBalance());
|
||||
}
|
||||
Map<RgsKey, List<Registry>> allAssets = registriesA
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(RgsKey::fromRgs));
|
||||
|
||||
registry.setDebit(BigDecimal.ZERO);
|
||||
registry.setSettledDebit(BigDecimal.ZERO);
|
||||
registry.setCredit(BigDecimal.ZERO);
|
||||
registry.setSettledCredit(BigDecimal.ZERO);
|
||||
registry.setPlanBalance(BigDecimal.ZERO);
|
||||
registry.setCloseBalance(registry.getBalance());
|
||||
|
||||
registry.setUpdated(Instant.now());
|
||||
registryImdg.update(registry);
|
||||
Instant timestamp = Instant.now();
|
||||
for (Map.Entry<RgsKey, List<Registry>> entry : allAssets.entrySet()) {
|
||||
RgsKey key = entry.getKey();
|
||||
List<Registry> group = entry.getValue();
|
||||
Registry a__f = find(group, RegistryTradingParams.A__F).orElse(null);
|
||||
Registry a__t = find(group, RegistryTradingParams.A__T).orElse(null);
|
||||
Registry a__b = find(group, RegistryTradingParams.A__B).orElse(null);
|
||||
if (a__t == null) {
|
||||
log.warn("registry group {}: no A**T registry found.", key);
|
||||
continue;
|
||||
}
|
||||
BigDecimal a__tBalance = safeBD(a__t.getBalance());
|
||||
a__t.setOpenBalance(a__tBalance);
|
||||
a__t.setCloseBalance(a__tBalance);
|
||||
a__t.setCredit(BigDecimal.ZERO);
|
||||
a__t.setDebit(BigDecimal.ZERO);
|
||||
a__t.setSettledCredit(BigDecimal.ZERO);
|
||||
a__t.setSettledDebit(BigDecimal.ZERO);
|
||||
a__t.setUpdated(timestamp);
|
||||
registryImdg.update(a__t);
|
||||
if (a__f == null) {
|
||||
a__f = assets.copy(a__t, RegistryUnit.F);
|
||||
registryImdg.insert(a__f);
|
||||
}
|
||||
if (a__b != null) {
|
||||
a__b.setBalance(BigDecimal.ZERO);
|
||||
registryImdg.update(a__b);
|
||||
}
|
||||
assets.process(a__b, a__t, a__f, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -431,6 +521,7 @@ public class RegistryService {
|
|||
return roleCheck;
|
||||
}
|
||||
Collection<Registry> baseRegistrys;
|
||||
Integer index;
|
||||
{
|
||||
IValidator validator = splitDepositActionVal.apply(requestPayload);
|
||||
Optional<EnumMessage> err = validator.tillFirstError();
|
||||
|
|
@ -441,6 +532,8 @@ public class RegistryService {
|
|||
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
|
||||
}
|
||||
baseRegistrys = validator.getStored(ValidationStored.RegistrysByContract);
|
||||
index = validator.getStored(ValidationStored.SplitDepositMaxNumber);
|
||||
if (index == null) index = 0;
|
||||
}
|
||||
|
||||
ImdgTransaction txCtx = imdgProvider.newTransaction();
|
||||
|
|
@ -457,6 +550,13 @@ public class RegistryService {
|
|||
log.debug("Process {} for {} registry", direction, baseRegistrys.size());
|
||||
Long groupId = null;
|
||||
for (Registry baseRegistry : baseRegistrys) {
|
||||
String cntrctWithoutTilda;
|
||||
{
|
||||
cntrctWithoutTilda = baseRegistry.getContract();
|
||||
if (cntrctWithoutTilda.contains("~")) {
|
||||
cntrctWithoutTilda = cntrctWithoutTilda.substring(0, cntrctWithoutTilda.indexOf("~"));
|
||||
}
|
||||
}
|
||||
log.trace("Registry[{}], groupId={}, ClearingCode={}", baseRegistry.getId(), baseRegistry.getGroupId(), baseRegistry.getClearingCode());
|
||||
if (groupId == null)
|
||||
groupId = baseRegistry.getGroupId();
|
||||
|
|
@ -475,9 +575,9 @@ public class RegistryService {
|
|||
} else {
|
||||
log.warn("Direction not set, do not change Balance");
|
||||
}
|
||||
firstRegistry.setContract(baseRegistry.getContract() + "~1");
|
||||
firstRegistry.setContract(cntrctWithoutTilda + "~" + (index + 1));
|
||||
firstRegistry.setParentId(baseRegistry.getId());
|
||||
registryTMap.insert(firstRegistry);
|
||||
|
||||
// 2. Вторая группа
|
||||
Registry secondRegistry = null;
|
||||
if (InOutDirection.out == direction) {
|
||||
|
|
@ -486,9 +586,10 @@ public class RegistryService {
|
|||
secondRegistry.setCreated(now);
|
||||
secondRegistry.setUpdated(null);
|
||||
secondRegistry.setBalance(requestPayload.getOutboundAmount());
|
||||
secondRegistry.setContract(baseRegistry.getContract() + "~2");
|
||||
secondRegistry.setContract(cntrctWithoutTilda + "~" + (index + 2));
|
||||
secondRegistry.setRefundDate(requestPayload.getRefundDate());
|
||||
secondRegistry.setSettlementDate(requestPayload.getRefundDate());
|
||||
secondRegistry.setParentId(baseRegistry.getId());
|
||||
registryTMap.insert(secondRegistry);
|
||||
}
|
||||
|
||||
|
|
@ -516,4 +617,16 @@ public class RegistryService {
|
|||
return new RequestInfoUpdate(req.getId(), Status.Success, null);
|
||||
}
|
||||
|
||||
private AssetOperationListRequest gatewayRequest(Registry dmau, BigDecimal balance, String tradingCode, String tcrCode) {
|
||||
AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
|
||||
AssetOperationRequest req = GatewayRequestCreator.from(
|
||||
dmau.getId(),
|
||||
null,
|
||||
balance,
|
||||
InOutDirection.in,
|
||||
tradingCode,
|
||||
tcrCode);
|
||||
gatewayRequest.setAssetOperationRequests(List.of(req));
|
||||
return gatewayRequest;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
package ru.spcex.clearing.service.builder;
|
||||
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class PaymentInstructionBuilderDepositReturn {
|
||||
|
||||
private ImdgProvider imdgProvider;
|
||||
private Long sessionId;
|
||||
private BigDecimal amount;
|
||||
private Registry lm_tRgs;
|
||||
|
||||
public static PaymentInstructionBuilderDepositReturn builder(ImdgProvider imdgProvider) {
|
||||
return new PaymentInstructionBuilderDepositReturn(imdgProvider);
|
||||
}
|
||||
|
||||
private PaymentInstructionBuilderDepositReturn(ImdgProvider imdgProvider) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderDepositReturn sessionId(Long sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderDepositReturn amount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderDepositReturn lm_tRgs(Registry rgs) {
|
||||
this.lm_tRgs = rgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstruction build() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ public class PaymentInstructionBuilderFinalMkrDeals {
|
|||
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
|
||||
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
|
||||
private String purpose;
|
||||
private String lmtPurpose = null;
|
||||
|
||||
public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) {
|
||||
return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider);
|
||||
|
|
@ -86,6 +87,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderFinalMkrDeals paymentPurposeLmt(String purpose) {
|
||||
this.lmtPurpose = purpose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Pair<PaymentInstruction, PaymentInstruction> build() {
|
||||
|
||||
PaymentInstruction payment1;
|
||||
|
|
@ -128,7 +134,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
|
|||
|
||||
payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
|
||||
|
||||
payment1.setPaymentPurpose(purpose);
|
||||
if (lmtPurpose != null) {
|
||||
payment1.setPaymentPurpose(lmtPurpose);
|
||||
} else {
|
||||
payment1.setPaymentPurpose(purpose);
|
||||
}
|
||||
|
||||
payment1.setSettlementDate(lm_t.getSettlementDate());
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
|
|
@ -12,12 +14,17 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
|||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
|
|
@ -27,6 +34,9 @@ public class PaymentInstructionBuilderV2 {
|
|||
private ImdgProvider imdgProvider;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<CompanySymbols> companySymbolsImdg;
|
||||
private Imdg<Registry> rgsImdg;
|
||||
private final Imdg<ClearingMemberCategory> clearingCategoryImdg;
|
||||
private final Imdg<CompanyRoleSet> cmpRoleImdg;
|
||||
private Long sessionId;
|
||||
private BigDecimal amount;
|
||||
private Account creditLegAccount;
|
||||
|
|
@ -37,6 +47,9 @@ public class PaymentInstructionBuilderV2 {
|
|||
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
|
||||
private Long senderId;
|
||||
private Long addresseeId;
|
||||
private boolean useCS_BLKD = false;
|
||||
|
||||
private Registry am_b;
|
||||
|
||||
public static PaymentInstructionBuilderV2 builder(ImdgProvider imdgProvider) {
|
||||
return new PaymentInstructionBuilderV2(imdgProvider);
|
||||
|
|
@ -46,6 +59,18 @@ public class PaymentInstructionBuilderV2 {
|
|||
this.imdgProvider = imdgProvider;
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
|
||||
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
this.cmpRoleImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class);
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderV2 checkBLKD(Registry rgs) {
|
||||
if (rgs == null) {
|
||||
return this;
|
||||
}
|
||||
this.useCS_BLKD = true;
|
||||
this.am_b = rgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderV2 sessionId(Long sessionId) {
|
||||
|
|
@ -128,7 +153,12 @@ public class PaymentInstructionBuilderV2 {
|
|||
payment.setPaymentDate(Instant.now());
|
||||
payment.setSettlementDate(LocalDate.now());
|
||||
}
|
||||
payment.setPaymentPurpose(purpose);
|
||||
|
||||
if (useCS_BLKD && checkAgent()) {
|
||||
payment.setPaymentPurpose(SpecifFlag.CS_BLKD.getKey() + "_" + sessionId + " " + purpose);
|
||||
} else {
|
||||
payment.setPaymentPurpose(purpose);
|
||||
}
|
||||
payment.setCreditLeg_amount(amount);
|
||||
payment.setDebitLeg_amount(amount);
|
||||
|
||||
|
|
@ -193,4 +223,41 @@ public class PaymentInstructionBuilderV2 {
|
|||
return cSymbol.getCompanySymbolValue();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAgent() {
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.CM__).build()),
|
||||
pb.equals("companyId", addresseeId),
|
||||
pb.equals("accountId", am_b.getAccountId())
|
||||
);
|
||||
Collection<Registry> claims = rgsImdg.getCollectionObjectsByPredicate(prdct);
|
||||
boolean hasCounterPartyInitiator = false;
|
||||
for (Registry claim : claims) {
|
||||
Long counterPartyId = claim.getCounterPartyId();
|
||||
if (categoryIOrVInitiator(counterPartyId) && companyRoleODEPPresent(counterPartyId)) {
|
||||
hasCounterPartyInitiator = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasCounterPartyInitiator;
|
||||
}
|
||||
|
||||
public boolean categoryIOrVInitiator(Long companyId) {
|
||||
ClearingMemberCategory category = clearingCategoryImdg.getFirstObjectByFieldValues(
|
||||
Map.of("companyId", companyId));
|
||||
ClearingCategory ctg = IEnumKey.getEnumByKey(ClearingCategory.class, category.getClearingMemberCategory());
|
||||
return ctg != null && (ctg.equals(ClearingCategory.V) || ctg.equals(ClearingCategory.I)) ;
|
||||
}
|
||||
|
||||
public boolean companyRoleODEPPresent(Long companyId) {
|
||||
return cmpRoleImdg.getFirstObjectBySQL(
|
||||
"companyId = %d and companyRole = '%s' and workflowStatus = '%s'".formatted(
|
||||
companyId,
|
||||
CompanyRole.ODEP.getKey(),
|
||||
WorkflowStatus.Active.getKey()
|
||||
)
|
||||
) != null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ public class RegistryBuilder {
|
|||
rgs.setCredit(BigDecimal.ZERO);
|
||||
rgs.setDiffBalance(BigDecimal.ZERO);
|
||||
rgs.setCheckBalance(BigDecimal.ZERO);
|
||||
rgs.setOpenBalance(BigDecimal.ZERO);
|
||||
return rgs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ public class RegistrySecurityBuilder {
|
|||
rgs.setCredit(BigDecimal.ZERO);
|
||||
rgs.setDiffBalance(BigDecimal.ZERO);
|
||||
rgs.setCheckBalance(BigDecimal.ZERO);
|
||||
rgs.setOpenBalance(BigDecimal.ZERO);
|
||||
return rgs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,29 +11,34 @@ import org.springframework.stereotype.Component;
|
|||
import ru.clearing.classes.statics.data.account.ClientCode;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow;
|
||||
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
|
||||
import ru.clearing.classes.statics.data.misc.Listing;
|
||||
import ru.clearing.classes.statics.data.misc.STrades;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.spcex.clearing.config.element.ClearingServiceSettings;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.error.ClearingException;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.notification.NotificationSender;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DealRegisterNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.ExecutionType;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.platform.enumeration.CurrencyCode;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
import ru.spcex.platform.enumeration.Side;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.*;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
|
|
@ -41,6 +46,8 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||
|
||||
@Component
|
||||
@EnableScheduling
|
||||
public class ExecutionFondComponent {
|
||||
|
|
@ -50,6 +57,7 @@ public class ExecutionFondComponent {
|
|||
private final Imdg<ExecutionFond> executionFondImdg;
|
||||
private final Imdg<Listing> listingImdg;
|
||||
private final Imdg<ClientCode> clientCodeImdg;
|
||||
private final Imdg<FixedIncomeCashFlow> fixedIncomeCashFlowImdg;
|
||||
private final Imdg<ru.clearing.classes.statics.data.misc.Market> marketImdg;
|
||||
|
||||
//fixme ждать ТЗ
|
||||
|
|
@ -58,19 +66,26 @@ public class ExecutionFondComponent {
|
|||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||
private final Function<STrades, IValidator> stradesValidator;
|
||||
private final KafkaSender kafkaSender;
|
||||
private final NotificationSender notifications;
|
||||
private final boolean valuation;
|
||||
|
||||
|
||||
@Autowired
|
||||
public ExecutionFondComponent(ImdgProvider imdgProvider, Producer<String, Object> kafka,
|
||||
public ExecutionFondComponent(ImdgProvider imdgProvider,
|
||||
ClearingServiceSettings settings,
|
||||
Producer<String, Object> kafka,
|
||||
@Qualifier("sTradesValidatorFond") Function<STrades, IValidator> stradesValidator,
|
||||
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender) {
|
||||
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender, NotificationSender notifications) {
|
||||
this.sTradeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class);
|
||||
this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
|
||||
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
|
||||
this.clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
|
||||
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, ru.clearing.classes.statics.data.misc.Market.class);
|
||||
this.fixedIncomeCashFlowImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class);
|
||||
this.valuation = settings.getTrade().getValuation(); //fixme
|
||||
this.stradesValidator = stradesValidator;
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.notifications = notifications;
|
||||
|
||||
resetTradingDay();
|
||||
}
|
||||
|
|
@ -119,7 +134,7 @@ public class ExecutionFondComponent {
|
|||
log.info("{} strades left after already-added filtering", sTrades.size());
|
||||
|
||||
for (STrades sTrd : sTrades) {
|
||||
log.trace("S_TRADE[{}] new", sTrd.getId());
|
||||
log.info("new S_TRADE[{}], valuation {}", sTrd.getId(), valuation);
|
||||
|
||||
//проверки
|
||||
IValidator validator = stradesValidator.apply(sTrd);
|
||||
|
|
@ -165,6 +180,7 @@ public class ExecutionFondComponent {
|
|||
protected ExecutionFond createExecutionFond(STrades sTrades,
|
||||
IValidator validator) throws ClearingException {
|
||||
Security security = validator.getStored(ValidationStored.STradesSecurity);
|
||||
// Listing listing = listingImdg.getFirstObjectByFieldValues(Map.of("securityId", security.getId()));
|
||||
Company company = validator.getStored(ValidationStored.STradesCompany);
|
||||
Company counterCompany = validator.getStored(ValidationStored.STradesCounterCompany);
|
||||
TradingClearingRegistry rgstr = validator.getStored(ValidationStored.STradesTradingClearingRegistry);
|
||||
|
|
@ -212,7 +228,57 @@ public class ExecutionFondComponent {
|
|||
eFond.setSecurityId(security.getId());
|
||||
eFond.setInterestAmount(sTrades.getAccruedint());
|
||||
eFond.setExchangeOrderId(sTrades.getOrderNum());
|
||||
eFond.setSettlementAmount(sTrades.getValue());
|
||||
if (valuation) {
|
||||
Listing listing = listingImdg.getFirstObjectBySQL("securityId = %d and market = '%s'".formatted(security.getId(), sTrades.getClassCode()));
|
||||
BigDecimal lotSize = listing != null ? safeBD(listing.getLotSize()) : BigDecimal.ONE;
|
||||
BigDecimal qty = safeBD(eFond.getLots()).multiply(lotSize);
|
||||
eFond.setQuantity(qty);
|
||||
BigDecimal price = safeBD(sTrades.getPrice());// eFond.setPrice
|
||||
BigDecimal settlementAmount = BigDecimal.ZERO;
|
||||
if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
|
||||
FixedIncomeSecurity fixedIncome = (FixedIncomeSecurity) security;
|
||||
BigDecimal nominalValue;
|
||||
ImdgPredicateBuilder pb = fixedIncomeCashFlowImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.equals("securityId", fixedIncome.getId()),
|
||||
sTrades.getSettleDate() != null ?
|
||||
pb.equals("valueDate", sTrades.getSettleDate()) : pb.alwaysFalse()
|
||||
);
|
||||
FixedIncomeCashFlow cashFlow = fixedIncomeCashFlowImdg.getFirstObjectByPredicate(prdct);
|
||||
if (cashFlow != null) {
|
||||
nominalValue = safeBD(cashFlow.getNominalValue());
|
||||
} else {
|
||||
nominalValue = safeBD(fixedIncome.getNominalValue());
|
||||
}
|
||||
{
|
||||
settlementAmount = eFond.getQuantity()
|
||||
.multiply(nominalValue)
|
||||
.multiply(price)
|
||||
.divide(new BigDecimal(100), RoundingMode.HALF_UP)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
} else if (InstrumentType.EQTY.equalsByKey(security.getInstrumentType())) {
|
||||
BigDecimal lotsEqty = safeBD(eFond.getQuantity());
|
||||
settlementAmount = lotsEqty.multiply(price).setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
eFond.setSettlementAmount(settlementAmount);
|
||||
if (settlementAmount.compareTo(safeBD(sTrades.getValue())) != 0) {
|
||||
log.warn("sTrades.TradeNum={} sTrades.value({}) != eFond({})",
|
||||
sTrades.getTradeNum(),
|
||||
safeBD(sTrades.getValue()),
|
||||
settlementAmount);
|
||||
notifications.sendNotification(
|
||||
ObjectType.vfrs,
|
||||
"Для сделки %s объем сделки в ТС %s не совпадает с расчитанным в КС %s"
|
||||
.formatted(sTrades.getTradeNum(),
|
||||
safeBD(sTrades.getValue()).toString(),
|
||||
settlementAmount.toString()),
|
||||
Priority.HIGH
|
||||
);
|
||||
}
|
||||
} else {
|
||||
eFond.setSettlementAmount(sTrades.getValue());
|
||||
}
|
||||
eFond.setCounterPartyId(counterCompany.getId());
|
||||
{
|
||||
ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder();
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import java.util.Optional;
|
|||
@Component
|
||||
public class Reviser {
|
||||
private final Logger log = LoggerFactory.getLogger(Reviser.class);
|
||||
private static final String reviseFailedMessage = "Сверка остатков денежных средств по результатам клиринговой сессии завершена с ошибками.";
|
||||
private static final String reviseSuccessMessage = "Сверка остатков денежных средств по результатам клиринговой сессии завершена успешно.";
|
||||
private static final String reviseFailedMessage = "После сверки обнаружена разница между сверочным и фактическим балансом.";
|
||||
private static final String reviseSuccessMessage = "Ошибок после получения остатков не обнаружено.";
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final Imdg<Statement> statementImdg;
|
||||
private final Imdg<SDf01> sdf01Imdg;
|
||||
|
|
@ -66,7 +66,7 @@ public class Reviser {
|
|||
log.trace("revise ok for sdf01.id={}, stmt.id={}, registry.id={}", sdf.getId(), statement.get().getId(), registry.get().getId());
|
||||
}
|
||||
NotificationNewRequest reviseNotification = new NotificationNewRequest();
|
||||
reviseNotification.setObjectType(ObjectType.rgst.getKey());
|
||||
reviseNotification.setObjectType(ObjectType.diff.getKey());
|
||||
reviseNotification.setComment(reviseFailed ? reviseFailedMessage : reviseSuccessMessage);
|
||||
reviseNotification.setPriority(reviseFailed ? Priority.HIGH.getKey() : Priority.LOW.getKey());
|
||||
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification);
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ import java.math.BigDecimal;
|
|||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Service
|
||||
|
|
@ -112,7 +110,9 @@ public class Sdf01Executor extends AbstractExecutor<SDf01> {
|
|||
result.setChildGenerationId(generationIdForGroup);
|
||||
result.setFileName(filenameObtainer.getFilename(sdf, sdf01Imdg, statementRequest.getGroupId()));
|
||||
log.info("SDF01 execution: sdf01 file={} number={}, groupId={}", result.getFileName(), sdf.size(), sdf.stream().findFirst().map(SDf01::getGenerationId).orElse(null));
|
||||
for (SDf01 sdf01 : sdf) {
|
||||
ArrayList<SDf01> orderedSdf = new ArrayList<>(sdf);
|
||||
orderedSdf.sort(Comparator.comparing(SDf01::getId));// Сортировка по возрастанию id, чтобы сохранить последовательность строк SDF02, как в SDF01
|
||||
for (SDf01 sdf01 : orderedSdf) {
|
||||
IValidator validator = sDf01Validator.apply(sdf01);
|
||||
Optional<EnumMessage> error = validator.tillFirstError();
|
||||
Company company = validator.getStored(ValidationStored.Sdf01Company);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRe
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.AssetTrio;
|
||||
import ru.spcex.clearing.service.integration.GatewayRequestCreator;
|
||||
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
|
||||
import ru.spcex.clearing.service.registry.DmiService;
|
||||
import ru.spcex.clearing.service.schedule.TradingTimeService;
|
||||
import ru.spcex.clearing.service.validation.Sdf06NewValidationRule;
|
||||
|
|
@ -66,6 +68,7 @@ public class Sdf06Executor {
|
|||
private final KafkaSender kafkaSender;
|
||||
private final FilenameObtainer filenameObtainer;
|
||||
private final DmiService dmiService;
|
||||
private final AssetTBFProcessing assets;
|
||||
|
||||
private final static BigDecimal successResult = BigDecimal.ZERO;
|
||||
//идет сессия (не возвращаем такую ошибку)
|
||||
|
|
@ -87,7 +90,7 @@ public class Sdf06Executor {
|
|||
public Sdf06Executor(ImdgProvider imdgProvider,
|
||||
IMessageResolver messageResolver,
|
||||
@Qualifier("sdf06ValidatorNew") Function<SDf06, IValidator> sDf06Validator,
|
||||
TradingTimeService tradingTimeService, KafkaSender kafkaSender, FilenameObtainer filenameObtainer, DmiService dmiService) {
|
||||
TradingTimeService tradingTimeService, KafkaSender kafkaSender, FilenameObtainer filenameObtainer, DmiService dmiService, AssetTBFProcessing assets) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.tradingTimeService = tradingTimeService;
|
||||
|
|
@ -102,6 +105,7 @@ public class Sdf06Executor {
|
|||
this.sdf07Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf07, SDf07.class);
|
||||
this.filenameObtainer = filenameObtainer;
|
||||
this.dmiService = dmiService;
|
||||
this.assets = assets;
|
||||
}
|
||||
|
||||
public void execute(BaseRequest<StatementRequest> systemRequest) {
|
||||
|
|
@ -160,6 +164,8 @@ public class Sdf06Executor {
|
|||
CurrencyCode.RUB.getKey(),
|
||||
safeBD(sDf06.getSum()),
|
||||
sDf06.getNumber().toString());
|
||||
Optional<AssetTrio> asts = assets.searchMoneyByAccAndCompany(company.getId(), tcr.getMoneyAccountId());
|
||||
asts.ifPresent(ast -> assets.process(ast.a__b(), ast.a__t(), ast.a__f(), BigDecimal.ZERO));
|
||||
}
|
||||
sdf07WasCreated = true;
|
||||
}
|
||||
|
|
@ -211,6 +217,9 @@ public class Sdf06Executor {
|
|||
if (ClearingError.WrongField.equals(err.getSubject())) {
|
||||
result = errorResult4;
|
||||
}
|
||||
if (ClearingError.ActiveSessionIsPresent.equals(err.getSubject())) {
|
||||
result = errorResult1;
|
||||
}
|
||||
if (result == null) {
|
||||
result = errorResult4;
|
||||
}
|
||||
|
|
@ -263,11 +272,16 @@ public class Sdf06Executor {
|
|||
Instant updatedTime = Instant.now();
|
||||
if (gatewayMsg.isApproved()) {
|
||||
processedApproved(stmt, sdf06, updatedTime);
|
||||
dmiService.setProcContract(searchTcrOnGatewayResponse(sdf06).map(SpcexObjectBase::getId).orElse(null),
|
||||
Optional<TradingClearingRegistry> tcr = searchTcrOnGatewayResponse(sdf06);
|
||||
dmiService.setProcContract(tcr.map(SpcexObjectBase::getId).orElse(null),
|
||||
CurrencyCode.RUB.getKey(),
|
||||
safeBD(sdf06.getSum()),
|
||||
sdf06.getNumber().toString()
|
||||
);
|
||||
if (tcr.isPresent()) {
|
||||
Optional<AssetTrio> asts = assets.searchMoneyByAccAndCompany(tcr.get().getCompanyId(), tcr.get().getMoneyAccountId());
|
||||
asts.ifPresent(a -> assets.process(a.a__b(), a.a__t(), a.a__f(), BigDecimal.ZERO));
|
||||
}
|
||||
} else {
|
||||
log.trace("statement.id={}, sdf07.id={}, sdf06.id={} rejected (by gateway answer)",
|
||||
statementId,
|
||||
|
|
|
|||
|
|
@ -346,6 +346,7 @@ public class Sdf08Executor extends AbstractExecutor<SDf08> {
|
|||
rgs.setCredit(BigDecimal.ZERO);
|
||||
rgs.setDiffBalance(BigDecimal.ZERO);
|
||||
rgs.setCheckBalance(BigDecimal.ZERO);
|
||||
rgs.setOpenBalance(BigDecimal.ZERO);
|
||||
rgs.setBalanceDimension(BalanceDimension.MONY.getKey());
|
||||
rgs.setTradingDate(statement.getSettlementDate());
|
||||
rgs.setClearingDate(LocalDate.now());
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApp
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
|
||||
import ru.spcex.clearing.service.registry.RegistryManager;
|
||||
import ru.spcex.clearing.service.schedule.TradingTimeService;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
|
|
@ -68,6 +69,7 @@ public class Sdf10Executor {
|
|||
private final TradingTimeService tradingTimeService;
|
||||
private final KafkaSender kafkaSender;
|
||||
private final SecuritySelector<Security> scrtSlct;
|
||||
private final AssetTBFProcessing assets;
|
||||
|
||||
private final static String OK = "OK";
|
||||
private final static String SYNTAX_ERROR = "Синтаксическая ошибка (файл сформирован неверно)";
|
||||
|
|
@ -88,7 +90,7 @@ public class Sdf10Executor {
|
|||
public Sdf10Executor(ImdgProvider imdgProvider,
|
||||
RegistryManager rgsMng, IMessageResolver messageResolver,
|
||||
@Qualifier("sdf10Validator") Function<SDf10, IValidator> sDf10Validator,
|
||||
TradingTimeService tradingTimeService, KafkaSender kafkaSender) {
|
||||
TradingTimeService tradingTimeService, KafkaSender kafkaSender, AssetTBFProcessing assets) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
|
|
@ -102,6 +104,7 @@ public class Sdf10Executor {
|
|||
this.sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class);
|
||||
this.plannerAllTodayImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
|
||||
this.scrtSlct = new SecuritySelector<>(imdgProvider, Security.class);
|
||||
this.assets = assets;
|
||||
}
|
||||
|
||||
public void execute(BaseRequest<StatementRequest> systemRequest) {
|
||||
|
|
@ -166,7 +169,11 @@ public class Sdf10Executor {
|
|||
SDf11 sDf11 = processedApproved(stmt, sDf10, now, sdf11GroupId);
|
||||
BigDecimal amount = InOutDirection.in.equalsByKey(stmt.getInOutDirection()) ?
|
||||
stmt.getAmount() : safeBD(stmt.getAmount()).negate();
|
||||
createDs_iWithoutGateway(tcr.getId(), company.getId(), security.getSecuritySymbol(), amount, sDf10.getOutDocument());
|
||||
createDs_iWithoutGateway(tcr.getId(),
|
||||
company.getId(),
|
||||
security.getSecuritySymbol(),
|
||||
amount,
|
||||
sDf10.getOutDocument());
|
||||
sdf11WasCreated = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -190,6 +197,7 @@ public class Sdf10Executor {
|
|||
return;
|
||||
}
|
||||
createDs_i(as_t.get(), summ, outDocument);
|
||||
assets.processByA__t(as_t.get(), BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private void createDs_iWithoutGateway(Long tcrId, Long companyId, String securitySymobl, BigDecimal summ, String outDocument) {
|
||||
|
|
@ -203,19 +211,19 @@ public class Sdf10Executor {
|
|||
return;
|
||||
}
|
||||
createDs_i(as_t.get(), summ, outDocument);
|
||||
assets.processByA__t(as_t.get(), BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private void createDs_i(Registry as_t, BigDecimal summ, String outDocument) {
|
||||
Registry rgsD = as_t.clone();
|
||||
RegistryManager.zeroState(rgsD);
|
||||
rgsD.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
rgsD.setRegistryUnit(RegistryUnit.I.getKey());
|
||||
rgsD.setRegistryCode(RegistryUtil.clearingCode(rgsD));
|
||||
rgsD.setBalance(summ);
|
||||
rgsD.setDebit(BigDecimal.ZERO);
|
||||
rgsD.setCredit(BigDecimal.ZERO);
|
||||
rgsD.setDiffBalance(BigDecimal.ZERO);
|
||||
rgsD.setCheckBalance(BigDecimal.ZERO);
|
||||
rgsD.setRegistryStatus(RegistryStatus.PROC.getKey());
|
||||
rgsD.setOpenBalance(BigDecimal.ZERO);
|
||||
rgsD.setCloseBalance(BigDecimal.ZERO);
|
||||
rgsD.setContract(outDocument);
|
||||
registryImdg.insert(rgsD);
|
||||
log.debug("created DS*I.id={}", rgsD.getId());
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ public class Sdf20Executor {
|
|||
Long securityId) {
|
||||
Statement stmt = new Statement();
|
||||
stmt.setAddresseeId(companyId);
|
||||
stmt.setSenderId(Sender.Prc.getId());
|
||||
stmt.setSenderId(Sender.Rdc.getId());
|
||||
stmt.setStatementType(StatementType.incr.getKey());
|
||||
//fixme stmt.setComment(sdf10.());
|
||||
stmt.setAccountId(account.getId());
|
||||
|
|
|
|||
|
|
@ -137,11 +137,11 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
|
|||
result.setChildGenerationId(generationIdForGroup);
|
||||
log.info("SDF21 execution: sdf21 number={}, groupId={}", sdf.size(), sdf.stream().findFirst().map(SDf21::getGenerationId).orElse(null));
|
||||
for (SDf21 sdf21 : sdf) {
|
||||
LocalDate opDt = operationDateParse(sdf21.getOperationDate());
|
||||
if (opDt == null || !opDt.equals(LocalDate.now())) {
|
||||
log.debug("skip sdf21.id={}, operation date {}", sdf21.getId(), sdf21.getOperationDate());
|
||||
continue;
|
||||
}
|
||||
//LocalDate opDt = operationDateParse(sdf21.getOperationDate());
|
||||
//if (opDt == null || !opDt.equals(LocalDate.now())) {
|
||||
// log.debug("skip sdf21.id={}, operation date {}", sdf21.getId(), sdf21.getOperationDate());
|
||||
// continue;
|
||||
//}
|
||||
IValidator validator = sDf21Validator.apply(sdf21);
|
||||
Optional<EnumMessage> error = validator.tillFirstError();
|
||||
if (error.isPresent()) {
|
||||
|
|
@ -260,7 +260,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
|
|||
private Statement create(SDf21 sdf21, Company cmp, Account acc) {
|
||||
Statement statement = new Statement();
|
||||
statement.setAddresseeId(cmp.getId());
|
||||
statement.setSenderId(Sender.Prc.getId());
|
||||
statement.setSenderId(Sender.Rdc.getId());
|
||||
statement.setStatementType(StatementType.incr.getKey());
|
||||
//fixme statement.setComment(sdf21.());
|
||||
statement.setAccountId(acc.getId());
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import ru.clearing.classes.statics.data.security.Security;
|
|||
import ru.clearing.classes.statics.data.statement.Statement;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.notification.NotificationSender;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest;
|
||||
|
|
@ -47,6 +48,7 @@ import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
|||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
|
|
@ -61,6 +63,7 @@ import java.util.Optional;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.D__V;
|
||||
|
|
@ -93,13 +96,14 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
private final TradingTimeService timeService;
|
||||
private final KafkaSender kafka;
|
||||
private final AssetTBFProcessing assets;
|
||||
private final NotificationSender notification;
|
||||
private final Pattern pattern = Pattern.compile("№.*");
|
||||
|
||||
public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator,
|
||||
LoggingService errorLogger,
|
||||
ImdgProvider imdgProvider,
|
||||
IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver, DmiService dmiService, TradingTimeService timeService,
|
||||
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets) {
|
||||
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets, NotificationSender notification) {
|
||||
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
|
||||
|
|
@ -121,6 +125,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
this.timeService = timeService;
|
||||
this.kafka = kafka;
|
||||
this.assets = assets;
|
||||
this.notification = notification;
|
||||
}
|
||||
|
||||
//todo доделать контроль sdf01 и sdf57
|
||||
|
|
@ -164,6 +169,9 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
result.setChildGenerationId(generationIdForGroup);
|
||||
log.info("SDF57 execution: sdf57 number={}, groupId={}", sdf.size(), sdf.stream().findFirst().map(SDf57::getGenerationId).orElse(null));
|
||||
AtomicReference<Boolean> sessionIsNeededFlag = new AtomicReference<>(false);
|
||||
boolean sessionIsPresent = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"workflowStatus", SessionStatus.ACTV.getKey()
|
||||
)) != null;
|
||||
for (SDf57 sdf57 : sdf) {
|
||||
IValidator validator = sDf57Validator.apply(sdf57);
|
||||
Optional<EnumMessage> error = validator.tillFirstError();
|
||||
|
|
@ -320,26 +328,52 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
registryD.getId());
|
||||
sessionIsNeededFlag.set(true);
|
||||
} else if (tm_tFound.isPresent()) {
|
||||
Registry tm_t = tm_tFound.get();
|
||||
Registry registryD = copyRegD(tm_t, stmt, RegistryUnit.X);
|
||||
registryImdg.insert(registryD);
|
||||
log.debug("stmt.id={}, sdf57.specif={} found TM*T.id={} new DM*X.id={}. Return money identification for Initiator account based on TM*T registry searchin on companyId, accountId, contract and registry_status=PROC|MGN",
|
||||
stmt.getId(),
|
||||
sdf57.getSpecif(),
|
||||
tm_t.getId(),
|
||||
registryD.getId());
|
||||
sessionIsNeededFlag.set(true);
|
||||
Optional<Registry> dm_xFound = RegistrySearch.builder(registryImdg)
|
||||
.rgsCode(RegistryTradingParams.DM_X)
|
||||
.companyId(company.getId())
|
||||
.accountId(account.getId())
|
||||
.contract(stmt.getContract())
|
||||
.statusNotOk()
|
||||
.find();
|
||||
if (dm_xFound.isEmpty()) {
|
||||
Registry tm_t = tm_tFound.get();
|
||||
Registry registryD = copyRegD(tm_t, stmt, RegistryUnit.X);
|
||||
registryImdg.insert(registryD);
|
||||
log.debug("stmt.id={}, sdf57.specif={} found TM*T.id={} new DM*X.id={}. Return money identification for Initiator account based on TM*T registry searchin on companyId, accountId, contract and registry_status=PROC|MGN",
|
||||
stmt.getId(),
|
||||
sdf57.getSpecif(),
|
||||
tm_t.getId(),
|
||||
registryD.getId());
|
||||
sessionIsNeededFlag.set(true);
|
||||
} else {
|
||||
Registry dm_x = dm_xFound.get();
|
||||
dm_x.setBalance(safeBD(dm_x.getBalance()).add(safeBD(stmt.getAmount())));
|
||||
dm_x.setUpdated(Instant.now());
|
||||
registryImdg.update(dm_x);
|
||||
log.debug("stmt.id={}, sdf57.specif={} updated {}.id={}",
|
||||
stmt.getId(),
|
||||
sdf57.getSpecif(),
|
||||
dm_x.getRegistryCode(),
|
||||
dm_x.getId());
|
||||
sessionIsNeededFlag.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
stmt.setOperationStatus(OperationStatus.Executed.getKey());
|
||||
statementImdg.update(stmt);
|
||||
log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey());
|
||||
if (!dm_tWasCreated && timeService.isTradingTime() && InOutDirection.in.equalsByKey(stmt.getInOutDirection())) {
|
||||
log.trace("sending gateway request for stmt.id={}", stmt.getId());
|
||||
kafka.sendRequestToQueue(Consts.ASSET_OPERATION,
|
||||
gatewayRequest(stmt,
|
||||
company.getTradingCode(),
|
||||
asts.a__t().getTradingClearingRegistry()));
|
||||
if (TextUtil.isEmpty(asts.a__t().getTradingClearingRegistry())) {
|
||||
log.trace("stmt.id={} {}.id={} TCR is empty, skipping gateway request",
|
||||
stmt.getId(), asts.a__t().getRegistryCode(), asts.a__t().getId());
|
||||
} else {
|
||||
log.trace("sending gateway request for stmt.id={}", stmt.getId());
|
||||
Optional<AssetOperationListRequest> gtwReq = gatewayRequest(stmt,
|
||||
company,
|
||||
account,
|
||||
asts.a__t().getTradingClearingRegistry());
|
||||
gtwReq.ifPresent(r -> kafka.sendRequestToQueue(Consts.ASSET_OPERATION, r));
|
||||
}
|
||||
}
|
||||
return Optional.of(asts);
|
||||
} else {
|
||||
|
|
@ -365,10 +399,17 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
searchResult.getCompany().getId());
|
||||
asts = createRegistryIfNeeded.apply(new StmtCmpAcc(stmt, searchResult.getCompany(), searchResult.getAccount()));
|
||||
if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) {
|
||||
dmiService.setOk(searchResult.getTcr().getId(),
|
||||
Optional<BigDecimal> dmiBalance = dmiService.setOk(searchResult.getTcr().getId(),
|
||||
CurrencyCode.RUB.getKey(),
|
||||
sdf57.getDbfId().toString());
|
||||
asts.ifPresent(trio -> assets.process(trio.a__b(), trio.a__t(), trio.a__f(), BigDecimal.ZERO));
|
||||
asts.ifPresent(trio -> {
|
||||
if (dmiBalance.isPresent() && sessionIsPresent) {
|
||||
BigDecimal planBalance = safeBD(trio.a__t().getPlanBalance());
|
||||
trio.a__t().setPlanBalance(planBalance.add(dmiBalance.get()));
|
||||
registryImdg.update(trio.a__t());
|
||||
}
|
||||
assets.process(trio.a__b(), trio.a__t(), trio.a__f(), BigDecimal.ZERO);
|
||||
});
|
||||
}
|
||||
} else if (InOutDirection.in.equals(IEnumKey.getEnumByKey(InOutDirection.class, stmt.getInOutDirection()))) {
|
||||
log.debug("stmt.id={} comment='{}' error: {}. Operating through DMAU registry",
|
||||
|
|
@ -402,10 +443,17 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
}
|
||||
} else if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) {
|
||||
if (asts.isPresent()) {
|
||||
dmiService.setOk(asts.get().a__t().getTradingClearingRegistryId(),
|
||||
Optional<BigDecimal> dmiBalance = dmiService.setOk(asts.get().a__t().getTradingClearingRegistryId(),
|
||||
CurrencyCode.RUB.getKey(),
|
||||
sdf57.getDbfId().toString());
|
||||
asts.ifPresent(trio -> assets.process(trio.a__b(), trio.a__t(), trio.a__f(), BigDecimal.ZERO));
|
||||
asts.ifPresent(trio -> {
|
||||
if (dmiBalance.isPresent() && sessionIsPresent) {
|
||||
BigDecimal planBalance = safeBD(trio.a__t().getPlanBalance());
|
||||
trio.a__t().setPlanBalance(planBalance.add(dmiBalance.get()));
|
||||
registryImdg.update(trio.a__t());
|
||||
}
|
||||
assets.process(trio.a__b(), trio.a__t(), trio.a__f(), BigDecimal.ZERO);
|
||||
});
|
||||
} else {
|
||||
log.error("stmt.id={} operationStatus={} but couldn't extract TCR.id for DM*I update",
|
||||
stmt.getId(),
|
||||
|
|
@ -417,11 +465,16 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
statementCred.map(stmt -> new StmtCmpAcc(stmt, companyCred, accountCred)).ifPresent(registersUpdate);
|
||||
}
|
||||
if (sessionIsNeededFlag.get()) {
|
||||
result.setSessionWasStarted(true);
|
||||
LauncherCommandRequest sessionTask = new LauncherCommandRequest();
|
||||
sessionTask.setSection(Section.MKR.getKey());
|
||||
sessionTask.setSessionType(SessionType.XDEP.getKey());
|
||||
kafka.sendRequestToQueue(Task.startOfClearing.topic(), sessionTask);
|
||||
if (!timeService.timeForXdep()) {
|
||||
EnumMessage err = new EnumMessage(ClearingError.XdepTimeIntervalNotMatch);
|
||||
notification.sendNotification(ObjectType.session, messageResolver.resolve(err), Priority.HIGH);
|
||||
} else {
|
||||
result.setSessionWasStarted(true);
|
||||
LauncherCommandRequest sessionTask = new LauncherCommandRequest();
|
||||
sessionTask.setSection(Section.MKR.getKey());
|
||||
sessionTask.setSessionType(SessionType.XDEP.getKey());
|
||||
kafka.sendRequestToQueue(Task.startOfClearing.topic(), sessionTask);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -610,6 +663,14 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
return this;
|
||||
}
|
||||
|
||||
private RegistrySearch statusNotOk() {
|
||||
predicate = pb.and(predicate, pb.or(
|
||||
pb.equals("registryStatus", RegistryStatus.PROC.getKey()),
|
||||
pb.equals("registryStatus", RegistryStatus.UNCV.getKey())
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
private Optional<Registry> find() {
|
||||
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(predicate));
|
||||
}
|
||||
|
|
@ -693,25 +754,56 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
R apply(T1 arg1, T2 arg2, T3 arg3);
|
||||
}
|
||||
|
||||
private AssetOperationListRequest gatewayRequest(Statement stmt, String tradingCode, String tcrCode) {
|
||||
private static final Pattern csBlkd = Pattern.compile(SpecifFlag.CS_BLKD.getKey() + "_(\\d+).*");
|
||||
|
||||
private Optional<AssetOperationListRequest> gatewayRequest(Statement stmt, Company company, Account account, String tcrCode) {
|
||||
if (AccountType.Anlt.equalsByKey(account.getAccountType())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String tradingCode = company.getTradingCode();
|
||||
AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
|
||||
AssetOperationRequest req = GatewayRequestCreator.from(stmt, tradingCode, tcrCode);
|
||||
Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"workflowStatus", SessionStatus.ACTV.getKey()
|
||||
));
|
||||
if (existActiveSession != null) {
|
||||
log.debug("active session.id={} type {}", existActiveSession.getId(), existActiveSession.getSessionType());
|
||||
List<Registry> d__vs = assets.searchByParams(stmt.getAccount(), CurrencyCode.RUB.getKey(), stmt.getSenderId(), D__V)
|
||||
.stream()
|
||||
.filter(rgs -> existActiveSession.getId().equals(rgs.getSessionId()))
|
||||
.toList();
|
||||
BigDecimal d__vSum = d__vs.stream()
|
||||
.map(rgs -> safeBD(rgs.getBalance()))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal amount = req.getAmount();
|
||||
req.setAmount(safeBD(amount).subtract(d__vSum));
|
||||
String specif = stmt.getComment();
|
||||
|
||||
Matcher m;
|
||||
if (!TextUtil.isEmpty(specif) && (m = csBlkd.matcher(specif)).find()) {
|
||||
try {
|
||||
Long sessionId = Long.valueOf(m.group(1));
|
||||
List<Registry> d__vs = assets.searchByParams(account.getAccount(), CurrencyCode.RUB.getKey(), company.getId(), D__V)
|
||||
.stream()
|
||||
.filter(rgs -> sessionId.equals(rgs.getSessionId()))
|
||||
.toList();
|
||||
BigDecimal d__vSum = d__vs.stream()
|
||||
.map(rgs -> safeBD(rgs.getBalance()))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal amount = req.getAmount();
|
||||
req.setAmount(safeBD(amount).subtract(d__vSum));
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("stmt.id={} failed to parse specif {} {}",
|
||||
stmt.getId(),
|
||||
specif,
|
||||
ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
//Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
// "workflowStatus", SessionStatus.ACTV.getKey()
|
||||
//));
|
||||
//if (existActiveSession != null) {
|
||||
// log.debug("active session.id={} type {}", existActiveSession.getId(), existActiveSession.getSessionType());
|
||||
// List<Registry> d__vs = assets.searchByParams(stmt.getAccount(), CurrencyCode.RUB.getKey(), stmt.getSenderId(), D__V)
|
||||
// .stream()
|
||||
// .filter(rgs -> existActiveSession.getId().equals(rgs.getSessionId()))
|
||||
// .toList();
|
||||
// BigDecimal d__vSum = d__vs.stream()
|
||||
// .map(rgs -> safeBD(rgs.getBalance()))
|
||||
// .reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// BigDecimal amount = req.getAmount();
|
||||
// req.setAmount(safeBD(amount).subtract(d__vSum));
|
||||
//}
|
||||
if (req.getAmount().compareTo(BigDecimal.ZERO) == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
gatewayRequest.setAssetOperationRequests(List.of(req));
|
||||
return gatewayRequest;
|
||||
return Optional.of(gatewayRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,14 @@ public class GatewayRequestCreator {
|
|||
}
|
||||
|
||||
public static AssetOperationRequest from(Registry rgs) {
|
||||
return from(rgs, InOutDirection.out);
|
||||
}
|
||||
|
||||
public static AssetOperationRequest from(Registry rgs, InOutDirection dir) {
|
||||
return from(rgs.getId(),
|
||||
null,
|
||||
BigDecimalUtil.safeBD(rgs.getBalance()).abs(),
|
||||
InOutDirection.out,
|
||||
dir,
|
||||
rgs.getTradingCode(),
|
||||
rgs.getTradingClearingRegistry());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,12 +125,13 @@ public class PaymentInstructionOutboundService {
|
|||
log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}",
|
||||
accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount);
|
||||
|
||||
String purpose = tcr != null ? "Вывод средств по ТКР " + tcr.getCode() + " ." : "Вывод средств.";
|
||||
String purpose = tcr != null ? "Возврат денежных средств, свободных от обязательств с ТКР " + tcr.getCode() + " ." : "Вывод средств.";
|
||||
if (payload.getPaymentPurpose() != null) {
|
||||
purpose += " " + payload.getPaymentPurpose();
|
||||
if (!(purpose.endsWith(".") || purpose.endsWith("!") || purpose.endsWith("?") || purpose.endsWith(";"))) {
|
||||
purpose += ".";
|
||||
String reqPmtPrpse = payload.getPaymentPurpose();
|
||||
if (!(reqPmtPrpse.endsWith(".") || reqPmtPrpse.endsWith("!") || reqPmtPrpse.endsWith("?") || reqPmtPrpse.endsWith(";"))) {
|
||||
reqPmtPrpse += ".";
|
||||
}
|
||||
purpose = reqPmtPrpse + " " + purpose;
|
||||
}
|
||||
PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider)
|
||||
.registry(new Registry())
|
||||
|
|
@ -144,7 +145,7 @@ public class PaymentInstructionOutboundService {
|
|||
.build();
|
||||
BankAccount bnkAcc = bnkAccImdg.getFirstObjectBySQL("accountId = %d".formatted(accDeb.getId()));
|
||||
if (bnkAcc != null) {
|
||||
pmt.setAddresseeBankName(bnkAcc.getBankIdentificationCode());
|
||||
pmt.setAddresseeBankName(bnkAcc.getBankName());
|
||||
pmt.setDebit_csAccount(bnkAcc.getCorrespondentAccount());
|
||||
}
|
||||
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
|
||||
|
|
|
|||
|
|
@ -45,34 +45,71 @@ public class AssetTBFProcessing {
|
|||
this.rgsMng = new RegistryManager(rgsImdg);
|
||||
}
|
||||
|
||||
//если нет B ссчитаем что он 0
|
||||
//если нет F надо его создать...
|
||||
//если нет T журнал WARN и ничего не делаем
|
||||
public Registry copy(Registry a__t, RegistryUnit rgsUnit) {
|
||||
Registry a___ = a__t.clone();
|
||||
a___.setRegistryUnit(rgsUnit.getKey());
|
||||
a___.setRegistryCode(RegistryUtil.clearingCode(a___));
|
||||
RegistryManager.zeroState(a___);
|
||||
return a___;
|
||||
}
|
||||
|
||||
/**
|
||||
* пересчитывает A**F = A**T - A**B + D**I - D**V
|
||||
* учитываются только D**I с отрицательным balance.
|
||||
* @param am_b регистр блокированных средств
|
||||
* @param am_t регистр средств под торги
|
||||
* @param am_f регистр свободных средств
|
||||
* @param sum отнимается от блокировки.
|
||||
*/
|
||||
public void process(Registry am_b, Registry am_t, Registry am_f, BigDecimal sum) {
|
||||
boolean am_bExists = am_b != null;
|
||||
if (!am_bExists) {
|
||||
am_b = new Registry();
|
||||
}
|
||||
safeWrapField(am_t::getBalance, am_t::setBalance);
|
||||
safeWrapField(am_b::getBalance, am_b::setBalance);
|
||||
safeWrapField(am_f::getBalance, am_f::setBalance);
|
||||
Collection<Registry> d__is = searchByParams(am_b.getAccount(),
|
||||
am_b.getSecuritySymbol(),
|
||||
am_b.getCompanyId(),
|
||||
D__I.type(am_b.getRegistryInstrumentType()));
|
||||
Collection<Registry> d__is = searchByParams(am_t.getAccount(),
|
||||
am_t.getSecuritySymbol(),
|
||||
am_t.getCompanyId(),
|
||||
D__I.type(am_t.getRegistryInstrumentType()));
|
||||
BigDecimal d__iSum = d__is.stream()
|
||||
.filter(d__i -> safeBD(d__i.getBalance()).compareTo(BigDecimal.ZERO) < 0)
|
||||
.map(rgs -> safeBD(rgs.getBalance()))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
Collection<Registry> d__vs = searchByParams(am_b.getAccount(),
|
||||
am_b.getSecuritySymbol(),
|
||||
am_b.getCompanyId(),
|
||||
D__V.type(am_b.getRegistryInstrumentType()));
|
||||
Collection<Registry> d__vs = searchByParams(am_t.getAccount(),
|
||||
am_t.getSecuritySymbol(),
|
||||
am_t.getCompanyId(),
|
||||
D__V.type(am_t.getRegistryInstrumentType()));
|
||||
BigDecimal d__vSum = d__vs.stream()
|
||||
.map(rgs -> safeBD(rgs.getBalance()))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
Instant now = Instant.now();
|
||||
|
||||
BigDecimal am_fBalanceForLoging = am_f.getBalance();
|
||||
BigDecimal am_bBalanceForLoging = am_b.getBalance();
|
||||
if (!am_bExists && sum != null && sum.compareTo(BigDecimal.ZERO) != 0) {
|
||||
log.error("FATAL: A**F.id={}; A**T.id={} A**B is null, yet #sum={}", am_f.getId(), am_t.getId(), sum);
|
||||
}
|
||||
am_b.setBalance(am_b.getBalance().subtract(sum));
|
||||
am_f.setBalance(am_t.getBalance().subtract(am_b.getBalance()).add(d__iSum).subtract(d__vSum));
|
||||
am_b.setUpdated(now);
|
||||
if (am_bExists) {
|
||||
am_b.setUpdated(now);
|
||||
rgsImdg.update(am_b);
|
||||
}
|
||||
am_f.setUpdated(now);
|
||||
|
||||
rgsImdg.update(am_b);
|
||||
rgsImdg.update(am_f);
|
||||
log.debug("assets processing [{}#id={}#balance={} | {}#id={}#balance={} | {}#id={}#balance={}] " +
|
||||
"D**I.size={} D**V.size={}. {}.balance -> {}, {}.balance -> {}",
|
||||
am_f.getRegistryCode(), am_f.getId(), am_fBalanceForLoging,
|
||||
am_t.getRegistryCode(), am_t.getId(), am_t.getBalance(),
|
||||
am_b.getRegistryCode(), am_b.getId(), am_bBalanceForLoging,
|
||||
d__is.size(), d__vs.size(),
|
||||
am_b.getRegistryCode(), am_b.getBalance(),
|
||||
am_f.getRegistryCode(), am_f.getBalance());
|
||||
}
|
||||
|
||||
public Collection<Registry> searchByParams(String account,
|
||||
|
|
@ -106,7 +143,7 @@ public class AssetTBFProcessing {
|
|||
}
|
||||
}
|
||||
|
||||
public void processByAm_f(Registry am_f, BigDecimal sum) {
|
||||
public Optional<AssetTrio> processByAm_f(Registry am_f, BigDecimal sum) {
|
||||
Optional<Registry> am_b = rgsMng.findRegByUnit(am_f.getCompanyId(),
|
||||
am_f.getAccountId(),
|
||||
am_f.getContract(),
|
||||
|
|
@ -119,6 +156,28 @@ public class AssetTBFProcessing {
|
|||
RegistryUnit.T);
|
||||
if (am_b.isPresent() && am_t.isPresent()) {
|
||||
process(am_b.get(), am_t.get(), am_f, sum);
|
||||
return Optional.of(new AssetTrio(am_f, am_b.get(), am_t.get()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<AssetTrio> processByA__t(Registry a__t, BigDecimal sum) {
|
||||
Optional<Registry> a__b = rgsMng.findRegByUnit(a__t.getCompanyId(),
|
||||
a__t.getAccountId(),
|
||||
a__t.getContract(),
|
||||
a__t,
|
||||
RegistryUnit.B);
|
||||
Optional<Registry> a__f = rgsMng.findRegByUnit(a__t.getCompanyId(),
|
||||
a__t.getAccountId(),
|
||||
a__t.getContract(),
|
||||
a__t,
|
||||
RegistryUnit.F);
|
||||
if (a__b.isPresent() && a__f.isPresent()) {
|
||||
process(a__b.get(), a__t, a__f.get(), sum);
|
||||
return Optional.of(new AssetTrio(a__t, a__b.get(), a__f.get()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,6 +209,42 @@ public class AssetTBFProcessing {
|
|||
ast.setTradingClearingRegistry(tcr);
|
||||
ast.setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
ast.setBalanceDimension(BalanceDimension.PICS.getKey());
|
||||
ast.setOpenBalance(BigDecimal.ZERO);
|
||||
RegistryManager.zeroState(ast);
|
||||
Registry asf = copy(ast, RegistryUnit.F);
|
||||
Registry asb = copy(ast, RegistryUnit.B);
|
||||
return new AssetTrio(asf, asb, ast);
|
||||
}
|
||||
|
||||
public AssetTrio createMAssets(Account acc,
|
||||
String securitySymbol,
|
||||
Long securityId,
|
||||
String tcrType,
|
||||
Long tcrId,
|
||||
String tcr,
|
||||
Company company) {
|
||||
Registry ast = new Registry();
|
||||
ast.setCreated(Instant.now());
|
||||
ast.setSecuritySymbol(securitySymbol);
|
||||
ast.setSecurityId(securityId);
|
||||
ast.setAccountId(acc.getId());
|
||||
ast.setAccount(acc.getAccount());
|
||||
ast.setAccountType(acc.getAccountType());
|
||||
ast.setRegistryDesignation(RegistryDesignation.A.getKey());
|
||||
ast.setRegistryInstrumentType(RegistryInstrumentType.M.getKey());
|
||||
ast.setRegistryCapacity(tcrType);
|
||||
ast.setRegistryUnit(RegistryUnit.T.getKey());
|
||||
ast.setRegistryCode(RegistryUtil.clearingCode(ast));
|
||||
ast.setClearingCode(company.getClearingCode());
|
||||
ast.setTradingCode(company.getClearingCode());
|
||||
ast.setCompanyId(company.getId());
|
||||
ast.setShortName(company.getShortName());
|
||||
ast.setFullName(company.getFullName());
|
||||
ast.setTradingClearingRegistryId(tcrId);
|
||||
ast.setTradingClearingRegistry(tcr);
|
||||
ast.setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
ast.setBalanceDimension(BalanceDimension.MONY.getKey());
|
||||
ast.setOpenBalance(BigDecimal.ZERO);
|
||||
RegistryManager.zeroState(ast);
|
||||
Registry asf = ast.clone();
|
||||
asf.setRegistryUnit(RegistryUnit.F.getKey());
|
||||
|
|
@ -169,7 +264,8 @@ public class AssetTBFProcessing {
|
|||
pb.sql(RegistryCodeSqlBuilder.getInstance(params).build()),
|
||||
pb.equals("tradingClearingRegistryId", rgs.getTradingClearingRegistryId()),
|
||||
pb.equals("companyId", rgs.getCompanyId()),
|
||||
pb.equals("accountId", rgs.getAccountId())
|
||||
pb.equals("accountId", rgs.getAccountId()),
|
||||
pb.equals("securityId", rgs.getSecurityId())
|
||||
);
|
||||
return Optional.ofNullable(rgsImdg.getFirstObjectByPredicate(prdct));
|
||||
}
|
||||
|
|
@ -191,6 +287,23 @@ public class AssetTBFProcessing {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<AssetTrio> searchSecurityByAccAndCompany(Long companyId, Long accountId, String securitySymbol) {
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
Function<RegistryTradingParams, ImdgPredicate> prdct = rgsCode -> pb.and(
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(rgsCode).build()),
|
||||
pb.equals("companyId", companyId),
|
||||
pb.equals("accountId", accountId),
|
||||
pb.equals("securitySymbol", securitySymbol)
|
||||
);
|
||||
Registry amf = rgsImdg.getFirstObjectByPredicate(prdct.apply(AS_F));
|
||||
Registry amb = rgsImdg.getFirstObjectByPredicate(prdct.apply(AS_B));
|
||||
Registry amt = rgsImdg.getFirstObjectByPredicate(prdct.apply(AS_T));
|
||||
if (amf != null && amb != null && amt != null) {
|
||||
return Optional.of(new AssetTrio(amf, amb, amt));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public boolean insufficientBalance(Registry registry, BigDecimal amount) {
|
||||
return safeBD(registry.getBalance()).compareTo(safeBD(amount)) < 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,17 +4,18 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf57;
|
||||
import ru.clearing.classes.statics.data.statement.Statement;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.session.stage.util.RegistryUtil;
|
||||
import ru.spcex.platform.enumeration.RegistryDesignation;
|
||||
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||
import ru.spcex.platform.enumeration.RegistryTradingParams;
|
||||
import ru.spcex.platform.enumeration.RegistryUnit;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
|
@ -24,10 +25,14 @@ import java.util.Optional;
|
|||
public class DmiService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Registry> rgsImdg;
|
||||
private final Imdg<SDf57> sDf57Imdg;
|
||||
private final Imdg<Statement> statementImdg;
|
||||
private final RegistryManager rgsMng;
|
||||
|
||||
public DmiService(ImdgProvider imdgProvider, RegistryManager rgsMng) {
|
||||
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.sDf57Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf57, SDf57.class);
|
||||
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.rgsMng = rgsMng;
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +91,33 @@ public class DmiService {
|
|||
findDmiByComment(tcrId, securitySymbol, comment).ifPresentOrElse(d__i -> {
|
||||
d__i.setContract(contract);
|
||||
d__i.setUpdated(Instant.now());
|
||||
try {
|
||||
Long dbfId = Long.valueOf(contract);
|
||||
SDf57 sdf57 = sDf57Imdg.getFirstObjectBySQL("dbfId=%d".formatted(dbfId));
|
||||
if (sdf57 != null) {
|
||||
ImdgPredicateBuilder pb = statementImdg.predicateBuilder();
|
||||
ImdgPredicate stmtPrdct = pb.and(
|
||||
pb.equals("inSDfId", sdf57.getId()),
|
||||
pb.equals("inOutSDfType", InOutSDfType.type57.getKey())
|
||||
);
|
||||
Statement stmt = statementImdg.getFirstObjectByPredicate(stmtPrdct);
|
||||
if (stmt != null && OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) {
|
||||
d__i.setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
} else {
|
||||
log.warn("tcrId={} securitySymbol={} comment={} sdf57 dbfId={} found, stmt.id={} status {}. d**i status will not be updated",
|
||||
tcrId,
|
||||
securitySymbol,
|
||||
comment,
|
||||
dbfId,
|
||||
stmt != null ? stmt.getId() : null,
|
||||
stmt != null ? stmt.getOperationStatus() : null);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error("sdf57 search by {}: error {}",
|
||||
contract,
|
||||
ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
rgsImdg.update(d__i);
|
||||
log.trace("set {}.id={} contract {}", d__i.getRegistryCode(), d__i.getId(), contract);
|
||||
}, () -> log.trace("didn't find DM*I by tcr.id={} securitySymbol={} comment={}",
|
||||
|
|
@ -97,18 +129,21 @@ public class DmiService {
|
|||
* ищем D**I по tcrId/security/contract
|
||||
* задаем статус ОК
|
||||
*/
|
||||
public void setOk(Long tcrId,
|
||||
public Optional<BigDecimal> setOk(Long tcrId,
|
||||
String securitySymbol,
|
||||
String contract) {
|
||||
BigDecimal[] dmiBalance = {null};
|
||||
findDmiByContract(tcrId, securitySymbol, contract).ifPresentOrElse(d__i -> {
|
||||
d__i.setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
d__i.setUpdated(Instant.now());
|
||||
log.trace("updating {} status to {}", d__i.getRegistryCode(), d__i.getRegistryStatus());
|
||||
rgsImdg.update(d__i);
|
||||
dmiBalance[0] = BigDecimalUtil.safeBD(d__i.getBalance());
|
||||
}, () -> {
|
||||
log.trace("didn't find DM*I by tcr.id={} securitySymbol={} contract={}",
|
||||
tcrId, securitySymbol, contract);
|
||||
});
|
||||
return Optional.ofNullable(dmiBalance[0]);
|
||||
}
|
||||
|
||||
private Optional<Registry> findDmiByContract(Long tcrId, String securitySymbol, String contract) {
|
||||
|
|
@ -156,15 +191,14 @@ public class DmiService {
|
|||
return Optional.empty();
|
||||
}
|
||||
Registry rgsD = am_t.clone();
|
||||
RegistryManager.zeroState(rgsD);
|
||||
rgsD.setOpenBalance(BigDecimal.ZERO);
|
||||
rgsD.setCloseBalance(BigDecimal.ZERO);
|
||||
rgsD.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
rgsD.setRegistryUnit(RegistryUnit.I.getKey());
|
||||
rgsD.setRegistryCode(RegistryUtil.clearingCode(rgsD));
|
||||
rgsD.setBalance(summ);
|
||||
|
||||
rgsD.setDebit(BigDecimal.ZERO);
|
||||
rgsD.setCredit(BigDecimal.ZERO);
|
||||
rgsD.setDiffBalance(BigDecimal.ZERO);
|
||||
rgsD.setCheckBalance(BigDecimal.ZERO);
|
||||
rgsD.setRegistryStatus(RegistryStatus.PROC.getKey());
|
||||
return Optional.of(rgsD);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ public class PaymentStateMarkService {
|
|||
Collection<Registry> claimsAndLiabilities = rgsImdg.getCollectionObjectsByPredicate(prdct);
|
||||
Map<Long, List<Registry>> groups = claimsAndLiabilities
|
||||
.stream()
|
||||
.filter(rgs -> rgs.getValueDate() != null)
|
||||
.filter(rgs -> rgs.getSettlementDate() != null)
|
||||
.filter(rgs -> rgs.getSettlementDate().equals(rgs.getValueDate()))
|
||||
.collect(Collectors.groupingBy(Registry::getGroupId));
|
||||
log.debug("found {} ({} groups) CM*T/LM*T by {}", claimsAndLiabilities.size(), groups.size(), prdct.toString());
|
||||
for (Map.Entry<Long, List<Registry>> group : groups.entrySet()) {
|
||||
|
|
|
|||
|
|
@ -38,11 +38,17 @@ public class RegistryManager {
|
|||
|
||||
public Optional<Registry> searchDmxByCounterParty(Registry rgs) {
|
||||
if (TextUtil.isEmpty(rgs.getContract())) return Optional.empty();
|
||||
String sqlCondition = String.format("(%s) and companyId = %d and contract = '%s'",
|
||||
RegistryCodeSqlBuilder.getInstance(DM_X).build(),
|
||||
rgs.getCounterPartyId(),
|
||||
rgs.getContract());
|
||||
Registry dmx = rgsImdg.getFirstObjectBySQL(sqlCondition);
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(DM_X).build()),
|
||||
pb.equals("companyId", rgs.getCounterPartyId()),
|
||||
pb.equals("contract", rgs.getContract()),
|
||||
pb.or(
|
||||
pb.equals("registryStatus", RegistryStatus.PROC.getKey()),
|
||||
pb.equals("registryStatus", RegistryStatus.MNG.getKey())
|
||||
)
|
||||
);
|
||||
Registry dmx = rgsImdg.getFirstObjectByPredicate(prdct);
|
||||
return Optional.ofNullable(dmx);
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +189,8 @@ public class RegistryManager {
|
|||
//балансы
|
||||
rgs.setBalance(BigDecimal.ZERO);
|
||||
rgs.setDebit(BigDecimal.ZERO);
|
||||
rgs.setSettledDebit(BigDecimal.ZERO);
|
||||
rgs.setSettledCredit(BigDecimal.ZERO);
|
||||
rgs.setCredit(BigDecimal.ZERO);
|
||||
rgs.setDiffBalance(BigDecimal.ZERO);
|
||||
rgs.setCheckBalance(BigDecimal.ZERO);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class TradingTimeService {
|
|||
this.plannerAllTodayImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
|
||||
}
|
||||
|
||||
public boolean isTradingTime() {
|
||||
private boolean isTradingTime(Task startTime, Task endTime) {
|
||||
ImdgPredicateBuilder pb = plannerAllTodayImdg.predicateBuilder();
|
||||
Function<Task, Optional<PlannerAllToday>> plannerByTask = task -> {
|
||||
ImdgPredicate plannerPrdct = pb.and(
|
||||
|
|
@ -34,19 +34,28 @@ public class TradingTimeService {
|
|||
);
|
||||
return Optional.ofNullable(plannerAllTodayImdg.getFirstObjectByPredicate(plannerPrdct));
|
||||
};
|
||||
LocalTime startTradingTime = plannerByTask.apply(Task.createRegistry_STRS)
|
||||
LocalTime startTradingTime = plannerByTask.apply(startTime)
|
||||
.map(PlannerAllToday::getTaskTime)
|
||||
.orElse(null);
|
||||
LocalTime endTradingTime = plannerByTask.apply(Task.createRegistry_ETRS)
|
||||
LocalTime endTradingTime = plannerByTask.apply(endTime)
|
||||
.map(PlannerAllToday::getTaskTime)
|
||||
.orElse(null);
|
||||
if (startTradingTime == null || endTradingTime == null) {
|
||||
log.warn("startTradingTime or endTradingTime is null");
|
||||
log.warn("{} or {} not found in planner all today", startTime.getKey(), endTime.getKey());
|
||||
return false;
|
||||
}
|
||||
LocalTime now = LocalTime.now();
|
||||
boolean isTradingTime = !now.isBefore(startTradingTime) && !now.isAfter(endTradingTime);
|
||||
log.debug("now: {}, startTradingTime: {}, endTradingTime: {}. trading time: {}", now, startTradingTime, endTradingTime, isTradingTime);
|
||||
log.debug("now: {}, {}: {}, {}: {}. period check in: {}",
|
||||
now, startTime.getKey(), startTradingTime, endTime.getKey(), endTradingTime, isTradingTime);
|
||||
return isTradingTime;
|
||||
}
|
||||
|
||||
public boolean isTradingTime() {
|
||||
return isTradingTime(Task.createRegistry_STRS, Task.createRegistry_ETRS);
|
||||
}
|
||||
|
||||
public boolean timeForXdep() {
|
||||
return isTradingTime(Task.startTime_SDEP, Task.endTime_EDEP);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public enum IdentificationFundsValidationRule implements IValidationRule<ImdgVal
|
|||
if (tcr == null) {
|
||||
return of(ClearingError.TCRegistryNotFound, validatedObject.getTradingClearingRegistryId());
|
||||
}
|
||||
if (!ServiceStatus.Active.equalsByKey(tcr.getStatus())) {
|
||||
if (!ServiceStatus.Active.equalsByKey(tcr.getStatus()) && !ServiceStatus.Reopened.equalsByKey(tcr.getStatus())) {
|
||||
return of(ClearingError.TradingClearingRegistryNotActive, tcr.getCode());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,56 +1,129 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.service.registry.RegistryManager;
|
||||
import ru.spcex.platform.enumeration.RegistryDesignation;
|
||||
import ru.spcex.platform.enumeration.RegistryInstrumentType;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||
import ru.spcex.platform.enumeration.RegistryUnit;
|
||||
import ru.spcex.platform.enumeration.RegistryTradingParams;
|
||||
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.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.imdg.validation.Stored;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ru.spcex.clearing.service.registry.RegistryManager.equalsByCode;
|
||||
|
||||
//1. Проверки
|
||||
//1.1 Проверить, в запросе у регистра код:
|
||||
// 1.1.1 Если регистр TM-T:
|
||||
// Проверить, что у registry.companyId существует категория I, иначе ошибка: 5420 - "Доступ к клирингу на «%s» не найден для компании %s."/> Где %s = категории И
|
||||
// Проверить, что найденного регистра DM*X: registry.status!=OK, иначе ошибка: 5425 - "Запрещена идентификация средства по рассчитанным обязательствам".
|
||||
// Создать/добавить в баланс DM-X на базе TM-T
|
||||
// 1.1.2 Если регистр OM-T:
|
||||
// Проверить, что у registry.companyId существует категория V, иначе ошибка: 5420 - "Доступ к клирингу на «%s» не найден для компании %s."/> Где %s = категории В
|
||||
// Проверить, что найденного регистра DM*T: registry.status!=OK, иначе ошибка: 5425 - "Запрещена идентификация средства по рассчитанным обязательствам".
|
||||
// Создать/добавить в баланс DM-T на базе OM-T
|
||||
//1.2 Проверить, баланс в запросе
|
||||
// Баланс должен быть положительный
|
||||
public enum ReturnDepositValidationRule implements IValidationRule<ImdgValidationContext<RegistryReturnDepositRequest>> {
|
||||
RegistryCodeCheck() {
|
||||
RgsWronCodeCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
if (!RegistryDesignation.T.equalsByKey(rgs.getRegistryDesignation())
|
||||
|| !RegistryInstrumentType.M.equalsByKey(rgs.getRegistryInstrumentType())
|
||||
|| !RegistryUnit.T.equalsByKey(rgs.getRegistryUnit())) {
|
||||
return of(ClearingError.RecordNotFoundInDictionary, "TM*T", "Registry");
|
||||
if (!equalsByCode(RegistryTradingParams.TM_T, rgs)) { //!equalsByCode(RegistryTradingParams.OM_T, rgs)
|
||||
return of(ClearingError.RgsWrongCode, "{}.id={}", rgs.getRegistryCode(), rgs.getId());
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
}, BalanceCheck() {
|
||||
},
|
||||
CategoryCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
Imdg<ClearingMemberCategory> ctgImdg = context.obtainMap(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
Collection<ClearingMemberCategory> category = ctgImdg.getCollectionObjectsBySQL(
|
||||
"companyId = %d".formatted(rgs.getCompanyId()));
|
||||
|
||||
Optional<ClearingCategory> ctgr = category.stream()
|
||||
.map(c -> IEnumKey.getEnumByKey(ClearingCategory.class, c.getClearingMemberCategory()))
|
||||
.filter(c -> ClearingCategory.V.equals(c) || ClearingCategory.I.equals(c))
|
||||
.findFirst();
|
||||
|
||||
if (ctgr.isEmpty()) {
|
||||
return of(ClearingError.CategoryNotFound, "I/V", rgs.getCompanyId());
|
||||
}
|
||||
if (ctgr.get().equals(ClearingCategory.V)) {
|
||||
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.equals("groupId", rgs.getGroupId()),
|
||||
pb.equals("contract", rgs.getContract())
|
||||
);
|
||||
Collection<Registry> group = rgsImdg.getCollectionObjectsByPredicate(prdct);
|
||||
Optional<Registry> om_t = group.stream()
|
||||
.filter(r -> r.getSettlementDate() != null)
|
||||
.filter(r -> r.getValueDate() != null)
|
||||
.filter(r -> r.getSettlementDate().isAfter(r.getValueDate()))
|
||||
.filter(r -> equalsByCode(RegistryTradingParams.OM_T, r))
|
||||
.findFirst();
|
||||
if (om_t.isEmpty()) return of(ClearingError.RecordNotFound, "OM*T.groupId=%d".formatted(rgs.getGroupId()));
|
||||
context.storeObject(ValidationStored.ReturnDepositOm_t, om_t.get());
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
BalanceCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
RegistryReturnDepositRequest request = context.getValidatedObject();
|
||||
if (request.getBalance() == null || request.getBalance().compareTo(rgs.getBalance()) > 0) {
|
||||
if (request.getBalance() == null || request.getBalance().compareTo(BigDecimal.ZERO) < 0) {
|
||||
return of(ClearingError.WrongField, "balance");
|
||||
}
|
||||
if (request.getBalance().compareTo(rgs.getBalance()) > 0) {
|
||||
return of(ClearingError.IdentifiedFundsExceedObligations);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}, DmxCheck() {
|
||||
}, Dm_Check() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
Registry rgs = context.getStoredObject(ValidationStored.ReturnDepositOm_t);
|
||||
if (rgs == null) rgs = context.getStoredObject(Stored.PresentById);
|
||||
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
RegistryManager rgsMng = new RegistryManager(rgsImdg);
|
||||
Optional<Registry> dmx = rgsMng.searchDmxByCompanyId(rgs);
|
||||
if (dmx.isPresent() && RegistryStatus.OK.equalsByKey(dmx.get().getRegistryStatus()) ) {
|
||||
if (TextUtil.isEmpty(rgs.getContract())) {
|
||||
return empty();
|
||||
}
|
||||
RegistryTradingParams rgsCode;
|
||||
if (equalsByCode(RegistryTradingParams.TM_T, rgs)) {
|
||||
rgsCode = RegistryTradingParams.DM_X;
|
||||
} else {
|
||||
rgsCode = RegistryTradingParams.DM_T;
|
||||
}
|
||||
String sqlCondition = String.format("(%s) and companyId = %d and contract = '%s'",
|
||||
RegistryCodeSqlBuilder.getInstance(rgsCode).build(),
|
||||
rgs.getCompanyId(),
|
||||
rgs.getContract());
|
||||
Registry dm__ = rgsImdg.getFirstObjectBySQL(sqlCondition);
|
||||
if (dm__ != null && RegistryStatus.OK.equalsByKey(dm__.getRegistryStatus()) ) {
|
||||
return of(ClearingError.ObligationsAlreadyCalculated);
|
||||
}
|
||||
dmx.ifPresent(dmxRgs -> context.storeObject(ValidationStored.ReturnDepositDmx, dmxRgs));
|
||||
return Optional.empty();
|
||||
if (dm__ != null) {
|
||||
context.storeObject(ValidationStored.ReturnDepositDm__, dm__);
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ public enum Sdf06NewValidationRule implements IValidationRule<ImdgValidationCont
|
|||
prdctBldr.and(
|
||||
prdctByRegistryCode.apply(RegistryTradingParams.DM_T),
|
||||
prdctBldr.or(
|
||||
prdctBldr.equals("registryStatus", RegistryStatus.OK.getKey()),
|
||||
prdctBldr.equals("registryStatus", RegistryStatus.PROC.getKey()),
|
||||
prdctBldr.equals("registryStatus", RegistryStatus.MNG.getKey())
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ import ru.spcex.clearing.error.ClearingError;
|
|||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.service.AssetTrio;
|
||||
import ru.spcex.clearing.service.registry.RegistryManager;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.NoRef;
|
||||
import ru.spcex.platform.enumeration.OperationCode;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
|
|
@ -67,6 +65,12 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
|
|||
if (acc == null) {
|
||||
return of(ClearingError.AccountNotFoundB, depoCodeCl);
|
||||
}
|
||||
ServiceStatus status = IEnumKey.getEnumByKey(ServiceStatus.class, acc.getStatus());
|
||||
if (!ServiceStatus.Active.equals(status)
|
||||
&& !ServiceStatus.Reopened.equals(status)
|
||||
&& !ServiceStatus.Appl.equals(status)) {
|
||||
return of(ClearingError.AccountNotActive, acc.getId());
|
||||
}
|
||||
context.storeObject(ValidationStored.Sdf20Account, acc);
|
||||
return empty();
|
||||
}
|
||||
|
|
@ -86,6 +90,9 @@ public enum Sdf20ValidationRule implements IValidationRule<ImdgValidationContext
|
|||
if (company == null) {
|
||||
return of(ClearingError.CompanyNotFoundB, acc.getCompanyId());
|
||||
}
|
||||
if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) {
|
||||
return of(ClearingError.CompanyNotActive, company.getId());
|
||||
}
|
||||
context.storeObject(ValidationStored.Sdf20Company, company);
|
||||
return empty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.session.stage.TaskType;
|
||||
import ru.spcex.platform.enumeration.SessionStatus;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum SessionTerminationValidationRule implements IValidationRule<ImdgValidationContext<Session>> {
|
||||
SessionPresent() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<Session> context) {
|
||||
Imdg<Session> sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class);
|
||||
Session session = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"workflowStatus", SessionStatus.ACTV.getKey()
|
||||
));
|
||||
if (session == null) {
|
||||
log.warn("Cannot stop session, failed to find workflowStatus 'ACTV'");
|
||||
return of(ClearingError.RecordNotFound, "с активной клиринговой сессией для обнуления");
|
||||
}
|
||||
context.storeObject(ValidationStored.SessionTerminate, session);
|
||||
context.setValidatedObject(session);
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
StatusCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<Session> context) {
|
||||
Session session = context.getStoredObject(ValidationStored.SessionTerminate);
|
||||
TaskType status = IEnumKey.getEnumByKey(TaskType.class, session.getSessionStatus());
|
||||
if (status == null || status.ordinal() >= TaskType.FormingPaymentInstruction.ordinal()) {
|
||||
log.warn("Cannot stop session.id={}, unknown sessionStatus '{}'",
|
||||
session.getId(), session.getSessionStatus());
|
||||
return of(ClearingError.IncorrectValue, "статуса для обнуления клиринговой сессии");
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
;
|
||||
private final static Logger log = LoggerFactory.getLogger(SessionTerminationValidationRule.class);
|
||||
@Override
|
||||
public String ruleName() {
|
||||
return "SessionTerminationValidationRule." + name();
|
||||
}
|
||||
}
|
||||
|
|
@ -14,12 +14,14 @@ 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.text.TextUtil;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum SplitDepositRequestValidationRule implements IValidationRule<ImdgValidationContext<RegistrySplitDepositActionRequest>> {
|
||||
PositiveAmount() {
|
||||
|
|
@ -78,6 +80,51 @@ public enum SplitDepositRequestValidationRule implements IValidationRule<ImdgVal
|
|||
return Optional.of(new EnumMessage(ClearingError.WrongFieldValue, "RefundDate"));
|
||||
}
|
||||
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
LoadContractIndexes() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistrySplitDepositActionRequest> context) {
|
||||
Imdg<Registry> registryImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
RegistrySplitDepositActionRequest validatedObject = context.getValidatedObject();
|
||||
String contract = validatedObject.getContract();
|
||||
if (TextUtil.isEmpty(contract)) {
|
||||
return of(ClearingError.WrongField, "contract");
|
||||
}
|
||||
String cntrSrch;
|
||||
int i = contract.indexOf("~");
|
||||
if (i == -1) {
|
||||
context.storeObject(ValidationStored.SplitDepositMaxNumber, 0);
|
||||
return empty();
|
||||
} else {
|
||||
cntrSrch = contract.substring(0, i);
|
||||
}
|
||||
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
|
||||
ImdgPredicate allContracts = pb.and(
|
||||
pb.or(pb.equals("registryStatus", RegistryStatus.PROC.getKey()), pb.equals("registryStatus", RegistryStatus.MNG.getKey())),
|
||||
pb.or(pb.equals("registryDesignation", RegistryDesignation.O.getKey()), pb.equals("registryDesignation", RegistryDesignation.T.getKey())),
|
||||
pb.equals("registryUnit", RegistryUnit.T.getKey()),
|
||||
pb.regex("contract", cntrSrch + ".*")
|
||||
);
|
||||
Collection<Registry> rgss = registryImdg.getCollectionObjectsByPredicate(allContracts);
|
||||
Integer maxContractNumber = rgss.stream()
|
||||
.map(Registry::getContract)
|
||||
.filter(c -> c.contains("~"))
|
||||
.map(c -> c.substring(c.lastIndexOf("~") + 1))
|
||||
.flatMap(number -> {
|
||||
try {
|
||||
return Stream.of(Integer.valueOf(number));
|
||||
} catch (NumberFormatException e) {
|
||||
return Stream.empty();
|
||||
}
|
||||
})
|
||||
.max(Integer::compareTo)
|
||||
.orElse(0);
|
||||
if (maxContractNumber == 0) {
|
||||
log.warn("contract {} contains '~' but no maximum number was extracted", contract);
|
||||
}
|
||||
context.storeObject(ValidationStored.SplitDepositMaxNumber, maxContractNumber);
|
||||
return empty();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public enum StatusExtractValidationRule implements IValidationRule<ImdgValidatio
|
|||
return empty();
|
||||
}
|
||||
},
|
||||
RegistryStatusValid() {
|
||||
RequestStatusValid() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryChangeStatusExtractRequest> context) {
|
||||
RegistryChangeStatusExtractRequest validatedObject = context.getValidatedObject();
|
||||
|
|
@ -76,6 +76,17 @@ public enum StatusExtractValidationRule implements IValidationRule<ImdgValidatio
|
|||
}
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
RegistryStatusValid() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryChangeStatusExtractRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
RegistryStatus status = IEnumKey.getEnumByKey(RegistryStatus.class, rgs.getRegistryStatus());
|
||||
if (RegistryStatus.OK.equals(status)) {
|
||||
return of(ClearingError.ObligationsAlreadyCalculated);
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
;
|
||||
private final static Logger log = LoggerFactory.getLogger(StatusExtractValidationRule.class);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public enum ValidationStored {
|
|||
|
||||
Sdf06Company, Sdf06Account, Sdf06Tcr,
|
||||
|
||||
ReturnDepositDmx,
|
||||
ReturnDepositDm__, ReturnDepositOm_t,
|
||||
|
||||
IdentificationFundsTcrSearch, IdentificationFundsAssetTrio,
|
||||
|
||||
|
|
@ -32,5 +32,7 @@ public enum ValidationStored {
|
|||
|
||||
SecurityBySecurityCode,
|
||||
|
||||
RegistrysByContract
|
||||
SessionTerminate,
|
||||
|
||||
RegistrysByContract, SplitDepositMaxNumber
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,11 @@ public abstract class AbstractSession {
|
|||
|
||||
protected void continueRunning(TaskType t) {
|
||||
synchronized (this.currStage) {
|
||||
//if (WorkflowStatus.Blocked.equalsByKey(this.currSession.getWorkflowStatus())) {
|
||||
// log.error("cannot run task {}.{}. session.id={} workflowStatus is {}",
|
||||
// t, t.getKey(), this.currSession.getId(), this.currSession.getWorkflowStatus());
|
||||
// throw new StageException();
|
||||
//}
|
||||
this.currStage.set(t);
|
||||
this.currSession.setSessionStatus(t.getKey());
|
||||
this.currSession.setUpdated(Instant.now());
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
|
|||
inspectionObligations.setSection(section());
|
||||
formingPaymentInstructionDeals.setSection(section());
|
||||
formingPaymentInstructionDeals.setSessionType(sessionType());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ public class IntermediateMkrSession extends AbstractSession implements Initializ
|
|||
inspectionObligations.setSessionType(sessionType());
|
||||
inspectionObligations.setSection(section());
|
||||
formingPaymentInstructionDeals.setSection(section());
|
||||
formingPaymentInstructionDeals.setSessionType(sessionType());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public class PrimaryAuctionB0Session extends AbstractSession implements Initiali
|
|||
inclusionObligations.setSessionType(sessionType());
|
||||
inspectionObligations.setSection(section());
|
||||
finishingSession.setSection(section());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
|||
inclusionObligations.setSessionType(sessionType());
|
||||
inspectionObligations.setSection(section());
|
||||
finishingSession.setSection(section());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
@ -214,16 +215,16 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
|||
public void finishPart() {
|
||||
try {
|
||||
//stage 9 continue revision
|
||||
{
|
||||
StageResult<Object> reviseRes = runStage(TaskType.AgainRevise, currSession.getId(), balanceRevise, false);
|
||||
if (!reviseRes.isSuccess()) {
|
||||
this.afterReviseErrorMonitor = SessionMonitorFactory.waitReviseError(section());
|
||||
log.warn("{} stage error, created monitor for {}",
|
||||
TaskType.AgainRevise,
|
||||
afterReviseErrorMonitor.allConditions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
//{
|
||||
// StageResult<Object> reviseRes = runStage(TaskType.AgainRevise, currSession.getId(), balanceRevise, false);
|
||||
// if (!reviseRes.isSuccess()) {
|
||||
// this.afterReviseErrorMonitor = SessionMonitorFactory.waitReviseError(section());
|
||||
// log.warn("{} stage error, created monitor for {}",
|
||||
// TaskType.AgainRevise,
|
||||
// afterReviseErrorMonitor.allConditions());
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
//stage 10
|
||||
{
|
||||
FinishingSessionPayload payload = new FinishingSessionPayload();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
inclusionObligations.setSessionType(sessionType());
|
||||
inspectionObligations.setSection(section());
|
||||
finishingSession.setSection(section());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public class ReturnDepositSession extends AbstractSession implements Initializin
|
|||
rgsPrctBuilder.less("valueDate", LocalDate.now())
|
||||
)
|
||||
);
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
@ -160,6 +161,7 @@ public class ReturnDepositSession extends AbstractSession implements Initializin
|
|||
{
|
||||
InspectionPoolPayload companyIdPayload = new InspectionPoolPayload();
|
||||
companyIdPayload.setProcessedCompanyId(currSession.getCompanyId());
|
||||
companyIdPayload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligationsDepositReturn);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
|
|||
inclusionObligations.setSessionType(sessionType());
|
||||
inspectionObligations.setSection(section());
|
||||
finishingSession.setSection(section());
|
||||
finishingSession.setSessionType(sessionType());
|
||||
imdgProvider.waitAvailable();
|
||||
initSessionIfPresent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
|||
import ru.spcex.clearing.notification.NotificationSender;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||
import ru.spcex.clearing.service.schedule.TradingTimeService;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
|
@ -33,13 +34,14 @@ public class SessionManager {
|
|||
private final IntermediateMkrSession intermediateMkrSession;
|
||||
private final FinalMkrSession finalMkrSession;
|
||||
private final ReturnDepositSession returnDepositSession;
|
||||
private final TradingTimeService time;
|
||||
|
||||
public SessionManager(ImdgProvider imdgProvider,
|
||||
NotificationSender notification, IMessageResolver msgs, PrimaryAuctionT0Session primaryAuctionT0Session,
|
||||
PrimaryAuctionBnSession primaryAuctionBnSession,
|
||||
PrimaryAuctionB0Session primaryAuctionB0Session,
|
||||
SecondaryAuctionT0Session secondaryAuctionT0Session,
|
||||
IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession) {
|
||||
IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, TradingTimeService time) {
|
||||
this.notification = notification;
|
||||
this.msgs = msgs;
|
||||
this.primaryAuctionT0Session = primaryAuctionT0Session;
|
||||
|
|
@ -51,6 +53,7 @@ public class SessionManager {
|
|||
this.returnDepositSession = returnDepositSession;
|
||||
|
||||
sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class);
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public void defineAndStartSession(BaseRequest<LauncherCommandRequest> r) throws ValidationException { //task sclr section fond sessiontype trdt
|
||||
|
|
@ -63,6 +66,43 @@ public class SessionManager {
|
|||
return;
|
||||
}
|
||||
BaseRequest<?> baseRequest = new BaseRequest<>();
|
||||
AbstractSession session = sessionByType(sessionType);
|
||||
if (session != null) {
|
||||
//checkActive
|
||||
checkAllowSessionStart();
|
||||
|
||||
session.runSession(baseRequest);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkAllowSessionStart() throws ValidationException {
|
||||
EnumMessage err = null;
|
||||
Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"workflowStatus", SessionStatus.ACTV.getKey()
|
||||
));
|
||||
if (existActiveSession != null) {
|
||||
log.warn("Can not start new session, cause exist active session.id={}", existActiveSession.getId());
|
||||
err = new EnumMessage(ClearingError.ActiveSessionIsPresent, String.valueOf(existActiveSession.getId()));
|
||||
}
|
||||
if (err != null) {
|
||||
notification.sendNotification(ObjectType.session, msgs.resolve(err), Priority.HIGH);
|
||||
throw new ValidationException(err);
|
||||
}
|
||||
}
|
||||
|
||||
public void endSession(Session session) {
|
||||
SessionType sessionType = IEnumKey.getEnumByKey(SessionType.class, session.getSessionType());
|
||||
String err = "failed to stop session.id=%d: unknown sessionType: %s"
|
||||
.formatted(session.getId(), session.getSessionType());
|
||||
if (sessionType == null) {
|
||||
throw new IllegalStateException(err);
|
||||
}
|
||||
AbstractSession sessionFlow = sessionByType(sessionType);
|
||||
if (sessionFlow == null) throw new IllegalStateException(err);
|
||||
sessionFlow.endSession();
|
||||
}
|
||||
|
||||
private AbstractSession sessionByType(SessionType sessionType) {
|
||||
AbstractSession session = null;
|
||||
switch (sessionType){
|
||||
case IPOB -> session = primaryAuctionBnSession;
|
||||
|
|
@ -73,24 +113,6 @@ public class SessionManager {
|
|||
case FINL -> session = finalMkrSession;
|
||||
case XDEP -> session = returnDepositSession;
|
||||
}
|
||||
|
||||
if (session != null) {
|
||||
//checkActive
|
||||
checkActiveSession();
|
||||
|
||||
session.runSession(baseRequest);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkActiveSession() throws ValidationException {
|
||||
Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"workflowStatus", SessionStatus.ACTV.getKey()
|
||||
));
|
||||
if (existActiveSession != null) {
|
||||
log.warn("Can not start new session, cause exist active session.id={}", existActiveSession.getId());
|
||||
EnumMessage err = new EnumMessage(ClearingError.ActiveSessionIsPresent, String.valueOf(existActiveSession.getId()));
|
||||
notification.sendNotification(ObjectType.session, msgs.resolve(err), Priority.HIGH);
|
||||
throw new ValidationException(err);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
package ru.spcex.clearing.session.stage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.notification.NotificationSender;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.clearing.util.services.RequestHelper;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
import ru.spcex.platform.enumeration.ObjectType;
|
||||
import ru.spcex.platform.enumeration.Priority;
|
||||
import ru.spcex.platform.enumeration.RegistryTradingParams;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Service
|
||||
public class SessionTerminator {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<ExecutionDeposit> execDpstImdg;
|
||||
private final Imdg<ExecutionFond> execFondImdg;
|
||||
private final Imdg<Registry> rgsImdg;
|
||||
|
||||
private final NotificationSender notification;
|
||||
private final AssetTBFProcessing assets;
|
||||
private final IMessageResolver msgs;
|
||||
private final RequestHelper reqInfo;
|
||||
private final Supplier<IValidator> validation;
|
||||
private final SessionManager sessionMng;
|
||||
|
||||
|
||||
public SessionTerminator(ImdgProvider imdgProvider,
|
||||
NotificationSender notification,
|
||||
AssetTBFProcessing assets, IMessageResolver msgs,
|
||||
RequestHelper reqInfo,
|
||||
@Qualifier("terminateSessionValidator") Supplier<IValidator> validation, SessionManager sessionMng) {
|
||||
this.notification = notification;
|
||||
this.assets = assets;
|
||||
this.msgs = msgs;
|
||||
this.execDpstImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||
this.execFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
|
||||
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.reqInfo = reqInfo;
|
||||
this.validation = validation;
|
||||
this.sessionMng = sessionMng;
|
||||
}
|
||||
|
||||
public RequestInfoUpdate stopCurrentSession(BaseRequest<?> req) {
|
||||
IValidator validator = validation.get();
|
||||
Optional<EnumMessage> err = validator.tillFirstError();
|
||||
if (err.isPresent()) {
|
||||
notification.sendNotification(ObjectType.session, msgs.resolve(err.get()), Priority.HIGH);
|
||||
return reqInfo.error(req.getId(), err.get());
|
||||
}
|
||||
Session session = validator.getStored(ValidationStored.SessionTerminate);
|
||||
rollbackExecutions(session);
|
||||
rollbackAssetBalances(session.getId());
|
||||
deleteLiabilitiesAndClaims(session.getId());
|
||||
sessionMng.endSession(session);
|
||||
return reqInfo.success(session.getId());
|
||||
}
|
||||
|
||||
private void rollbackExecutions(Session session) {
|
||||
Instant now = Instant.now();
|
||||
|
||||
Consumer<Imdg<ExecutionCommon>> nullifier = imdg -> {
|
||||
Collection<ExecutionCommon> execs = imdg.getCollectionObjectsBySQL(
|
||||
"sessionId = " + session.getId()
|
||||
);
|
||||
for (ExecutionCommon exec : execs) {
|
||||
exec.setSessionId(null);
|
||||
exec.setCoverageStatus(null);
|
||||
exec.setUpdated(now);
|
||||
imdg.update(exec);
|
||||
}
|
||||
log.info("updated {} executions with sessionId={}", execs.size(), session.getId());
|
||||
};
|
||||
log.debug("session.id={} section {}", session.getId(), session.getSection());
|
||||
|
||||
if (Section.FOND.equalsByKey(session.getSection())) {
|
||||
nullifier.accept(upcastImdg(execFondImdg));
|
||||
} else if (Section.MKR.equalsByKey(session.getSection())) {
|
||||
nullifier.accept(upcastImdg(execDpstImdg));
|
||||
} else throw new IllegalStateException("unknown section.");
|
||||
}
|
||||
|
||||
private void rollbackAssetBalances(Long sessionId) {
|
||||
Instant now = Instant.now();
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.A__B).build()),
|
||||
pb.not(pb.equals("balance", BigDecimal.ZERO))
|
||||
);
|
||||
|
||||
Collection<Registry> a__bs = rgsImdg.getCollectionObjectsByPredicate(prdct);
|
||||
a__bs.forEach(rgs -> {
|
||||
rgs.setBalance(BigDecimal.ZERO);
|
||||
rgs.setUpdated(now);
|
||||
rgsImdg.update(rgs);
|
||||
assets.processByAm_b(rgs, BigDecimal.ZERO);
|
||||
});
|
||||
log.debug("set ZERO balance for {} A**B by predicate: {}", a__bs.size(), prdct);
|
||||
}
|
||||
|
||||
private void deleteLiabilitiesAndClaims(Long sessionId) {
|
||||
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.and(
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.or(
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.C__T).build()),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.L__T).build()),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.O__T).build()),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.T__T).build())
|
||||
)
|
||||
);
|
||||
Collection<Registry> liabilitiesAndClaims = rgsImdg.getCollectionObjectsByPredicate(prdct);
|
||||
liabilitiesAndClaims.forEach(rgsImdg::delete);
|
||||
log.debug("deleted {} liabilities and claims by predicate: {}", liabilitiesAndClaims.size(), prdct);
|
||||
}
|
||||
|
||||
|
||||
private static <T extends SpcexObjectBase, U extends T> Imdg<T> upcastImdg(Imdg<U> imdg) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Imdg<T> result = (Imdg<T>) imdg;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ public class BalanceRevise implements ISessionStage {
|
|||
NotificationNewRequest nRequest = new NotificationNewRequest();
|
||||
nRequest.setObjectType(ObjectType.rgst.getKey());
|
||||
nRequest.setPriority(Priority.HIGH.getKey());
|
||||
nRequest.setComment("После сверки обнаружена разница между плановым и фактическим балансом");
|
||||
nRequest.setComment("Сверка по результатам клиринговой сессии завершена с ошибками.");
|
||||
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, nRequest);
|
||||
return new StageResult<>(new EnumMessage(ClearingError.PlanBalanceReviseError), false);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
|
|
@ -29,18 +28,22 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
|
|||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.utils.collection.Pair;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ru.spcex.clearing.error.ClearingErrorInternal.SessionGeneralError;
|
||||
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
||||
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
|
|
@ -57,6 +60,7 @@ public class FinishingSession implements ISessionStage {
|
|||
private final IMessageResolver msgResolver;
|
||||
private final Sdf05Sender sdf05Sender;
|
||||
private final Sdf14Sender sdf14Sender;
|
||||
private SessionType sessionType;
|
||||
private Section section;
|
||||
|
||||
@Autowired
|
||||
|
|
@ -76,6 +80,9 @@ public class FinishingSession implements ISessionStage {
|
|||
public void setSection(Section section) {
|
||||
this.section = section;
|
||||
}
|
||||
public void setSessionType(SessionType sessionType) {
|
||||
this.sessionType = sessionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StageResult<?> submit(Task<?> task) {
|
||||
|
|
@ -108,39 +115,79 @@ public class FinishingSession implements ISessionStage {
|
|||
log.error("Session id={} not found. Can not update Execution's.", sessionId);
|
||||
} else {
|
||||
Collection<Registry> oRegs = findORegistryBySessionId(sessionId);
|
||||
Set<Long> exchangeExecutionIdAllowed = oRegs.stream()
|
||||
.filter(rgs -> RegistryStatus.CLRD.equalsByKey(rgs.getRegistryStatus()))
|
||||
.map(Registry::getGroupId) // Registry::getGroupId == Execution.ExchangeExecutionId, см. RegistryFondBuilder/RegistryDepoBuilder
|
||||
Map<Long, RegistryStatus> obligationStatusByGroupId;
|
||||
obligationStatusByGroupId = oRegs.stream()
|
||||
.map(rgs -> new Pair<>(rgs.getGroupId(), getEnumByKey(RegistryStatus.class, rgs.getRegistryStatus())))
|
||||
.filter(pair -> pair.getSecond() != null)
|
||||
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (o1, o2) -> o1));
|
||||
Function<Long, CoverageStatus> statusByExchangeId = id-> {
|
||||
RegistryStatus obligationStatus = obligationStatusByGroupId.get(id);
|
||||
if (obligationStatus == null) return null;
|
||||
return switch (obligationStatus) {
|
||||
case CLRD -> CoverageStatus.ALWD;
|
||||
case FAIL, UNCV, NACK, NACC -> CoverageStatus.DEND;
|
||||
default -> null;
|
||||
};
|
||||
};
|
||||
Set<Long> exchangeExecutionIdsPreviousDay = oRegs.stream()
|
||||
.filter(rgs -> Objects.nonNull(rgs.getSettlementDate()))
|
||||
.filter(rgs -> Objects.nonNull(rgs.getTradingDate()))
|
||||
.filter(rgs -> rgs.getSettlementDate().compareTo(rgs.getTradingDate()) > 0)
|
||||
.map(Registry::getGroupId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
log.trace("obligations number with second leg in the past: {}", exchangeExecutionIdsPreviousDay.size());
|
||||
int allowed = 0;
|
||||
int notAllowed = 0;
|
||||
if (IEnumKey.contains(session.getSessionType(), SessionType.FINL, SessionType.MEDM)) {
|
||||
Collection<ExecutionDeposit> executions = findExecutionDepositBySessionId(sessionId);
|
||||
int notAllowed = 0;
|
||||
log.trace("loaded {} ExecutionDeposits for sessionId {}", executions.size(), sessionId);
|
||||
for (ExecutionDeposit execution : executions) {
|
||||
CoverageStatus toStatus = exchangeExecutionIdAllowed.contains(execution.getExchangeExecutionId()) ?
|
||||
CoverageStatus.ALWD : CoverageStatus.DNED;
|
||||
if (toStatus == CoverageStatus.DNED)
|
||||
CoverageStatus toStatus = statusByExchangeId.apply(execution.getExchangeExecutionId());
|
||||
if (toStatus == null) {
|
||||
log.trace("CoverageStatus not defined for execution.id={}", execution.getId());
|
||||
continue;
|
||||
}
|
||||
if (toStatus == CoverageStatus.DEND) {
|
||||
notAllowed++;
|
||||
}
|
||||
if (toStatus == CoverageStatus.ALWD) {
|
||||
allowed++;
|
||||
}
|
||||
execution.setCoverageStatus(toStatus.getKey());
|
||||
execution.setUpdated(Instant.now());
|
||||
executionDepositImdg.update(execution);
|
||||
}
|
||||
log.trace("By sessionId={} update {} ExecutionDeposit: {} allowed, {} denied", sessionId,
|
||||
executions.size(), exchangeExecutionIdAllowed.size(), notAllowed);
|
||||
log.trace("By sessionId={} processed {} ExecutionDeposit: {} allowed, {} denied, skipped {}",
|
||||
sessionId,
|
||||
executions.size(),
|
||||
allowed,
|
||||
notAllowed,
|
||||
executions.size() - (allowed + notAllowed));
|
||||
} else if (IEnumKey.contains(session.getSessionType(), SessionType.TRDT, SessionType.IPOB, SessionType.IPO0, SessionType.IPOT)) {
|
||||
Collection<ExecutionFond> executions = findExecutionFondBySessionId(sessionId);
|
||||
int notAllowed = 0;
|
||||
log.trace("loaded {} ExecutionFonds for sessionId {}", executions.size(), sessionId);
|
||||
for (ExecutionFond execution : executions) {
|
||||
CoverageStatus toStatus = exchangeExecutionIdAllowed.contains(execution.getExchangeExecutionId()) ?
|
||||
CoverageStatus.ALWD : CoverageStatus.DNED;
|
||||
if (toStatus == CoverageStatus.DNED)
|
||||
CoverageStatus toStatus = statusByExchangeId.apply(execution.getExchangeExecutionId());
|
||||
if (toStatus == null) {
|
||||
log.trace("CoverageStatus not defined for execution.id={}", execution.getId());
|
||||
continue;
|
||||
}
|
||||
if (toStatus == CoverageStatus.DEND) {
|
||||
notAllowed++;
|
||||
}
|
||||
if (toStatus == CoverageStatus.ALWD) {
|
||||
allowed++;
|
||||
}
|
||||
execution.setCoverageStatus(toStatus.getKey());
|
||||
execution.setUpdated(Instant.now());
|
||||
executionFondImdg.update(execution);
|
||||
}
|
||||
log.trace("By sessionId={} update {} ExecutionFond: {} allowed, {} denied", sessionId,
|
||||
executions.size(), exchangeExecutionIdAllowed.size(), notAllowed);
|
||||
log.trace("By sessionId={} processed {} ExecutionFond: allowed {}, denied {}, skipped {}",
|
||||
sessionId,
|
||||
executions.size(),
|
||||
allowed,
|
||||
notAllowed,
|
||||
executions.size() - (allowed + notAllowed));
|
||||
} else {
|
||||
log.warn("Unsupported session[{}].SessionType={} for update Executions", sessionId, session.getSessionType());
|
||||
}
|
||||
|
|
@ -156,7 +203,7 @@ public class FinishingSession implements ISessionStage {
|
|||
return sResult;
|
||||
}
|
||||
for (Registry registryA : forRegistries) {
|
||||
if (!RegistryDesignation.A.equalsByKey(registryA.getRegistryUnit())) {
|
||||
if (!RegistryDesignation.A.equalsByKey(registryA.getRegistryUnit())) { //fixme Unit -> Designation
|
||||
log.warn("For registry {}.RegistryDesignation is not A.", registryA.getId());
|
||||
continue;
|
||||
}
|
||||
|
|
@ -240,23 +287,43 @@ public class FinishingSession implements ISessionStage {
|
|||
// registryStatus - любой статус
|
||||
pb.equals("registryDesignation", RegistryDesignation.O.getKey()));
|
||||
Collection<Registry> result = registryImdg.getCollectionObjectsByPredicate(prdct);
|
||||
log.trace("found {} liabilities by query {} ", result.size(), prdct);
|
||||
int size = result.size();
|
||||
result = result.stream()
|
||||
.filter(registry -> Objects.equals(registry.getSettlementDate(), LocalDate.now()))
|
||||
.filter(registry -> Objects.equals(registry.getValueDate(), registry.getSettlementDate()))
|
||||
.collect(Collectors.toList());
|
||||
log.debug("found {} liabilities 'O' by query {} and ValueDate==SettlementDate", result.size(), prdct);
|
||||
.collect(Collectors.toList());
|
||||
log.debug("found {} liabilities by query {} and {} liabilities after filtering ValueDate==SettlementDate",
|
||||
size, result.size(), prdct);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Collection<ExecutionFond> findExecutionFondBySessionId(Long sessionId) {
|
||||
Collection<ExecutionFond> result = executionFondImdg.getCollectionObjectsByFieldValues(Map.of("sessionId", sessionId));
|
||||
ImdgPredicateBuilder pb = executionFondImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.or(
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.equals("settlementDate", LocalDate.now())
|
||||
);
|
||||
Collection<ExecutionFond> result = executionFondImdg.getCollectionObjectsByPredicate(prdct)
|
||||
.stream()
|
||||
.filter(eFond -> Objects.nonNull(eFond.getSessionId()))
|
||||
.filter(eFond -> {
|
||||
if (sessionId.equals(eFond.getSessionId())) return true;
|
||||
Session session = sessionImdg.getSingleObjectByID(eFond.getSessionId());
|
||||
return sessionType.equalsByKey(session.getSessionType());
|
||||
})
|
||||
.toList();
|
||||
log.trace("found {} ExecutionFond by sessionId={}", result.size(), sessionId);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Collection<ExecutionDeposit> findExecutionDepositBySessionId(Long sessionId) {
|
||||
Collection<ExecutionDeposit> result = executionDepositImdg.getCollectionObjectsByFieldValues(Map.of("sessionId", sessionId));
|
||||
log.trace("found {} ExecutionDeposit by sessionId={}", result.size(), sessionId);
|
||||
ImdgPredicateBuilder pb = executionDepositImdg.predicateBuilder();
|
||||
ImdgPredicate prdct = pb.or(
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.equals("firstLegSettlementDate", LocalDate.now())
|
||||
);
|
||||
Collection<ExecutionDeposit> result = executionDepositImdg.getCollectionObjectsByPredicate(prdct);
|
||||
log.trace("found {} ExecutionDeposit by {}", result.size(), prdct);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
|
||||
private StageResult<?> formingPaymentInstructions(FormingPaymentInstructionPayload payload) {
|
||||
Long sessionId = payload.getSessionId();
|
||||
if (SessionType.FINL.equals(sessionType)) {
|
||||
if (SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) {
|
||||
dmvSrv.createDmv(sessionId);
|
||||
}
|
||||
Collection<Registry> AMBregistries = selectAMBRegistries(sessionId);
|
||||
|
|
@ -156,12 +156,6 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
for (Registry registry : AMBregistries) {
|
||||
//по каждому AMB регистру создаем PaymentInstruction
|
||||
//проверяем balance посчитанный на шаге 5
|
||||
|
||||
if (registry.getBalance().compareTo(BigDecimal.ZERO) == 0) {
|
||||
log.debug("Skip creating paymentInstruction by registry with 0 balance");
|
||||
continue;
|
||||
}
|
||||
boolean isPositiveBalance = registry.getBalance().compareTo(BigDecimal.ZERO) > 0;
|
||||
Account counterAcc = null;
|
||||
if (AccountType.Clrn.equalsByKey(registry.getAccountType())) {
|
||||
counterAcc = accountImdg.getSingleObjectByID(registry.getAccountId());
|
||||
|
|
@ -176,12 +170,16 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
Account debitLegAccount;
|
||||
Account creditLegAccount;
|
||||
BigDecimal amount;
|
||||
amount = safeBD(registry.getBalance()).add(adjustAmountByReturns(registry, sessionId));
|
||||
boolean isPositiveBalance = amount.compareTo(BigDecimal.ZERO) > 0;
|
||||
if (amount.compareTo(BigDecimal.ZERO) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (isPositiveBalance) {
|
||||
senderId = registry.getCompanyId();
|
||||
addresseeId = Sender.One.getId();
|
||||
debitLegAccount = tranAcc;
|
||||
creditLegAccount = counterAcc;
|
||||
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
|
||||
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(
|
||||
registry.getTradingClearingRegistryId(),
|
||||
registry.getCompanyId(),
|
||||
|
|
@ -196,7 +194,6 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
addresseeId = registry.getCompanyId();
|
||||
debitLegAccount = counterAcc;
|
||||
creditLegAccount = tranAcc;
|
||||
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
|
||||
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(
|
||||
registry.getTradingClearingRegistryId(),
|
||||
registry.getCompanyId(),
|
||||
|
|
@ -208,6 +205,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
setUpdatedStoreInImdg(amt, now);
|
||||
});
|
||||
}
|
||||
amount = amount.abs();
|
||||
|
||||
PaymentInstructionBuilderV2 paymentInstructionBuilder = PaymentInstructionBuilderV2.builder(imdgProvider)
|
||||
.registry(registry)
|
||||
|
|
@ -217,6 +215,8 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
.creditLegAccount(creditLegAccount)
|
||||
.amount(amount)
|
||||
.sessionId(sessionId)
|
||||
.checkBLKD((SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType))
|
||||
&& !isPositiveBalance ? registry : null)
|
||||
.purpose(String.format("Перевод по итогу клиринга по ТКР %s", registry.getTradingClearingRegistry()));
|
||||
PaymentInstruction paymentInstruction = paymentInstructionBuilder.build();
|
||||
log.debug("Created paymentInstruction by registry.id: {}", registry.getId());
|
||||
|
|
@ -311,6 +311,41 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
return stageResult;
|
||||
}
|
||||
|
||||
private BigDecimal adjustAmountByReturns(Registry amb, Long sessionId) {//companyid, tcr/account, sessionId, RUB
|
||||
Long companyId = amb.getCompanyId();
|
||||
Long tradingClearingRegistryId = amb.getTradingClearingRegistryId();
|
||||
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
|
||||
ImdgPredicate cL = pb.and(
|
||||
pb.equals("companyId", companyId),
|
||||
pb.equals("tradingClearingRegistryId", tradingClearingRegistryId),
|
||||
pb.equals("registryStatus", RegistryStatus.OK.getKey()),
|
||||
pb.equals("sessionId", sessionId),
|
||||
pb.or(
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(LM_T).build()),
|
||||
pb.sql(RegistryCodeSqlBuilder.getInstance(CM_T).build())
|
||||
)
|
||||
);
|
||||
BigDecimal reduce = registryImdg.getCollectionObjectsByPredicate(cL)
|
||||
.stream()
|
||||
.filter(rgs -> rgs.getValueDate() != null)
|
||||
.filter(rgs -> rgs.getSettlementDate() != null)
|
||||
.filter(rgs -> rgs.getSettlementDate().isAfter(rgs.getValueDate()))
|
||||
.map(rgs -> {
|
||||
if (RegistryDesignation.C.equalsByKey(rgs.getRegistryDesignation())) {
|
||||
return rgs.getBalance();
|
||||
} else {
|
||||
return rgs.getBalance().abs().negate();
|
||||
}
|
||||
})
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
log.debug("{}.id={} {} adjust value {}",
|
||||
amb.getRegistryCode(),
|
||||
amb.getId(),
|
||||
cL,
|
||||
reduce);
|
||||
return reduce;
|
||||
|
||||
}
|
||||
|
||||
private void setUpdatedStoreInImdg(Registry rgs, Instant now) {
|
||||
rgs.setUpdated(now);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
|||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
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.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
|
|
@ -58,6 +59,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
private final ImdgProvider imdgProvider;
|
||||
private final ImdgId idGenerator;
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final Imdg<BankAccount> bankAccImdg;
|
||||
private final Imdg<ru.clearing.classes.statics.data.misc.Currency> currImdg;
|
||||
private final Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||
private final Imdg<Security> securityImdg;
|
||||
private final Imdg<Account> accountImdg;
|
||||
|
|
@ -81,6 +84,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class);
|
||||
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
|
||||
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.bankAccImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
|
||||
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, ru.clearing.classes.statics.data.misc.Currency.class);
|
||||
this.sdf03Creator = sdf03Creator;
|
||||
this.rgsMng = rgsMng;
|
||||
}
|
||||
|
|
@ -102,6 +107,13 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
|
||||
private StageResult formingPaymentInstruction(Long sessionId) {
|
||||
Instant now = Instant.now();
|
||||
Account tranAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
|
||||
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
|
||||
if (tranAcc == null) {
|
||||
return new StageResult<>(
|
||||
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()),
|
||||
false);
|
||||
}
|
||||
|
||||
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(LM_T,CM_T, LS_T, CS_T);
|
||||
String registryCodeCondition = registryCodeSqlBuilder.build();
|
||||
|
|
@ -128,15 +140,15 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
Optional<Registry> lmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(LM_T, rgs)).findFirst();
|
||||
Optional<Registry> cmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(CM_T, rgs)).findFirst();
|
||||
if (lmtO.isEmpty() || cmtO.isEmpty()) {
|
||||
log.error("LM*T or CM*T not found for group {}", entry.getKey());
|
||||
log.error("groupId {} LM*T or CM*T not found", entry.getKey());
|
||||
continue;
|
||||
}
|
||||
Registry lm_t = lmtO.get(); //obligation by money
|
||||
Registry cm_t = cmtO.get();
|
||||
Optional<Registry> dmx = rgsMng.searchDmxByCounterPartyNotOk(lm_t);
|
||||
if (dmx.isPresent()) {
|
||||
log.debug("LM*T#id={}, DM*X#id={} found, no action needed for group {}, skipping liability",
|
||||
lm_t.getId(), dmx.get().getId(), lm_t.getGroupId());
|
||||
log.debug("groupId {} LM*T#id={}, DM*X#id={} found, no action needed, skipping liability",
|
||||
lm_t.getGroupId(), lm_t.getId(), dmx.get().getId());
|
||||
dmx.get().setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
setUpdatedStoreInImdg(dmx.get(), now);
|
||||
continue;
|
||||
|
|
@ -144,25 +156,35 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
|
||||
Optional<Registry> dmtInfo = rgsMng.searchDmtInfoNotOk(lm_t);
|
||||
if (dmtInfo.isPresent()) {
|
||||
BigDecimal balance = safeBD(lm_t.getBalance()).add(safeBD(cm_t.getBalance())); //fixme????
|
||||
PaymentInstruction payInstr = createPaymentInstruction(List.of(lm_t, cm_t), balance, sessionId);
|
||||
lm_t.setPaymentId(payInstr.getId());
|
||||
log.debug("groupId {} LM*T#id={}, DM*T(INFO)#id={} found",
|
||||
lm_t.getGroupId(), lm_t.getId(), dmtInfo.get().getId());
|
||||
Pair<PaymentInstruction, PaymentInstruction> pmts = PaymentInstructionBuilderFinalMkrDeals.builder(imdgProvider)
|
||||
.lm_t(lm_t)
|
||||
.cm_t(cm_t)
|
||||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
|
||||
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.build();
|
||||
Pair.forEach(pmts, paymentInstructionImdg::insert);
|
||||
Pair.forEach(pmts, pmtCreated::add);
|
||||
lm_t.setPaymentId(pmts.getFirst().getId());
|
||||
cm_t.setPaymentId(pmts.getSecond().getId());
|
||||
lm_t.setUpdated(Instant.now());
|
||||
cm_t.setUpdated(Instant.now());
|
||||
registryImdg.update(lm_t);
|
||||
registryImdg.update(cm_t);
|
||||
dmtInfo.get().setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
setUpdatedStoreInImdg(dmtInfo.get(), now);
|
||||
log.debug("groupId {} LM*T#id={} CM*T#id={} created PmtInst.id={} and PmtInst.id={}",
|
||||
lm_t.getGroupId(), lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<Registry> dmtClnr = rgsMng.searchDmtClrnNotOk(lm_t);
|
||||
if (dmtClnr.isPresent()) {
|
||||
Account tranAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
|
||||
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
|
||||
if (tranAcc == null) {
|
||||
return new StageResult<>(
|
||||
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()),
|
||||
false);
|
||||
}
|
||||
log.debug("groupId {} {}#id={} found",
|
||||
lm_t.getGroupId(), dmtClnr.get().getRegistryCode(), dmtClnr.get().getId());
|
||||
{
|
||||
//изменение активов - блокируем средства беред отправкой sdf'ов
|
||||
Optional<Registry> amfO = rgsMng.findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), lm_t.getSecuritySymbol(), AM_F);
|
||||
|
|
@ -177,21 +199,21 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
ambO.map(Registry::getId).orElse(null),
|
||||
receiverAmtO.map(Registry::getId).orElse(null)
|
||||
);
|
||||
amfO.ifPresent(amf -> {
|
||||
amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance())));
|
||||
setUpdatedStoreInImdg(amf, now);
|
||||
});
|
||||
//amfO.ifPresent(amf -> {
|
||||
// amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance())));
|
||||
// setUpdatedStoreInImdg(amf, now);
|
||||
//});
|
||||
payerAmtO.ifPresent(amt -> {
|
||||
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
|
||||
setUpdatedStoreInImdg(amt, now);
|
||||
});
|
||||
ambO.ifPresent(amb -> {
|
||||
amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance())));
|
||||
setUpdatedStoreInImdg(amb, now);
|
||||
});
|
||||
//ambO.ifPresent(amb -> {
|
||||
// amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance())));
|
||||
// setUpdatedStoreInImdg(amb, now);
|
||||
//});
|
||||
receiverAmtO.ifPresent(amt -> {
|
||||
// у отправителя и получателя одинаково, см. в FormingPaymentInstruction
|
||||
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
|
||||
amt.setSettledCredit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
|
||||
setUpdatedStoreInImdg(amt, now);
|
||||
});
|
||||
}
|
||||
|
|
@ -201,11 +223,12 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
|
||||
.build();
|
||||
paymentInstructionImdg.insert(pmts.getFirst());
|
||||
paymentInstructionImdg.insert(pmts.getSecond());
|
||||
log.debug("LM*T#id={}, CM*T#id={} found, PaymentInstruction id={} and id={} created",
|
||||
lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId());
|
||||
log.debug("groupId {} LM*T#id={}, CM*T#id={} found, PaymentInstruction id={} and id={} created",
|
||||
lm_t.getGroupId(), lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId());
|
||||
pmtCreated.add(pmts.getFirst());
|
||||
pmtCreated.add(pmts.getSecond());
|
||||
dmtClnr.get().setRegistryStatus(RegistryStatus.OK.getKey());
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ public class FormingPaymentInstructionReturnMkr implements ISessionStage {
|
|||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
|
||||
.build();
|
||||
paymentInstructionImdg.insert(pmts.getFirst());
|
||||
paymentInstructionImdg.insert(pmts.getSecond());
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
|||
.stream()
|
||||
.collect(Collectors.groupingBy(Registry::getGroupId));
|
||||
log.debug("groups.size = {}", groups.size());
|
||||
Map<Long, PaymentGroup> lstGroups = RegistryLiabilitiesGroup.group(registries);
|
||||
Map<Long, PaymentGroup> lstGroups = RegistryLiabilitiesGroup.group(groups);
|
||||
for (Map.Entry<Long, List<Registry>> group : groups.entrySet()) {
|
||||
Long groupId = group.getKey();
|
||||
Function<RegistryTradingParams, Registry> findByCode = rgsCode -> group.getValue()
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue