Compare commits

..

4 commits

381 changed files with 4065 additions and 14231 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,6 +2,8 @@ package ru.spcex.clearing.account.config.validation;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.AccountTypeDictionary; import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.clearing.platform.dictionary.ServiceStatusDictionary;
@ -9,17 +11,21 @@ import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; 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.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@ -51,17 +57,32 @@ public class InformationAccountValidationConfig {
return AccountError.CompanyNotActive; return AccountError.CompanyNotActive;
return null; return null;
}), }),
FieldNotBlankRequiredRule.instance("account", InformationAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty),
DictionaryPresentRule.instance("status", InformationAccountNewRequest::getStatus, DictionaryPresentRule.instance("status", InformationAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class, IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false), AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false),
DictionaryPresentRule.instance("accountType", InformationAccountNewRequest::getAccountType, DictionaryPresentRule.instance("accountType", InformationAccountNewRequest::getAccountType,
IMDGDistributedNames.Map_AccountTypeDictionary, AccountTypeDictionary.class, IMDGDistributedNames.Map_AccountTypeDictionary, AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false), AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false),
new SameAccountValidationRule<>(AccountType.Info, InformationAccountNewRequest::getAccount) new SameInfoAccountValidation()
); );
}; };
} }
static class SameInfoAccountValidation implements IValidationRule<ImdgValidationContext<InformationAccountNewRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<InformationAccountNewRequest> context) {
InformationAccountNewRequest req = context.getValidatedObject();
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
String accountType = AccountType.Info.getKey(); // or req.getAccountType()
Account existAccount = accountImdg.getFirstObjectByFieldValues(Map.of(
"account", req.getAccount(),
"accountType", accountType,
"status", ServiceStatus.Active.getKey()
));
if (existAccount != null) {
return of(AccountError.AccountAlreadyExist, existAccount.getAccount());
}
return empty();
}
}
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -54,7 +54,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
private final UserRoleVerification userRoleVerification; private final UserRoleVerification userRoleVerification;
private final ImdgProvider imdgProvider; private final ImdgProvider imdgProvider;
private final ValidationHelper validationHelper; private final ValidationHelper validationHelper;
private final AccountHelper accountHelper; private final AccountService accountService;
private final RequestHelper requestHelper; private final RequestHelper requestHelper;
private final Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator; private final Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator;
private final Imdg<InformationAccount> informationAccountImdg; private final Imdg<InformationAccount> informationAccountImdg;
@ -73,7 +73,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
UserRoleVerification userRoleVerification, UserRoleVerification userRoleVerification,
ImdgProvider imdgProvider, ImdgProvider imdgProvider,
ValidationHelper validationHelper, ValidationHelper validationHelper,
AccountHelper accountHelper, AccountService accountService,
RequestHelper requestHelper, RequestHelper requestHelper,
@Qualifier("informationAccountNewRequestValidator") @Qualifier("informationAccountNewRequestValidator")
Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) { Function<InformationAccountNewRequest, IValidator> infoAccountNewRequestValidator) {
@ -83,7 +83,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
this.userRoleVerification = userRoleVerification; this.userRoleVerification = userRoleVerification;
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
this.validationHelper = validationHelper; this.validationHelper = validationHelper;
this.accountHelper = accountHelper; this.accountService = accountService;
this.requestHelper = requestHelper; this.requestHelper = requestHelper;
this.infoAccountNewRequestValidator = infoAccountNewRequestValidator; this.infoAccountNewRequestValidator = infoAccountNewRequestValidator;
this.informationAccountImdg = imdgProvider.getImdg( this.informationAccountImdg = imdgProvider.getImdg(
@ -105,7 +105,6 @@ public class InformationAccountService extends QueueConsumer implements Initiali
init(); init();
} }
@Deprecated
public RequestInfoUpdate informationAccountNew(BaseRequest<InformationAccountNewRequest> userRequest) { public RequestInfoUpdate informationAccountNew(BaseRequest<InformationAccountNewRequest> userRequest) {
log.debug("InformationAccountNewRequest received"); log.debug("InformationAccountNewRequest received");
@ -147,7 +146,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
account.setCreated(now); account.setCreated(now);
account.setUpdated(now); account.setUpdated(now);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), true); requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) return requestInfoUpdate; if (requestInfoUpdate != null) return requestInfoUpdate;
ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
@ -239,7 +238,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
account.setCompanyId(forCompanyId); account.setCompanyId(forCompanyId);
account.setCreated(now); account.setCreated(now);
account.setUpdated(now); account.setUpdated(now);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false); requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), false);
if (requestInfoUpdate != null) { if (requestInfoUpdate != null) {
log.debug("Stop make new account, cause error: {}", requestInfoUpdate.getMessage()); log.debug("Stop make new account, cause error: {}", requestInfoUpdate.getMessage());
return requestInfoUpdate; return requestInfoUpdate;
@ -304,7 +303,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
* *
* @return infoCounter++ * @return infoCounter++
*/ */
public synchronized Long accountNextId() { protected Long accountNextId() {
if (infoCounter == null) synchronized (this) { if (infoCounter == null) synchronized (this) {
if (infoCounter == null) { if (infoCounter == null) {
log.debug("Init account-information counter."); log.debug("Init account-information counter.");

View file

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

View file

@ -1,5 +1,7 @@
package ru.spcex.clearing.account.service; 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.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer; import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.Producer;
@ -21,28 +23,40 @@ import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.config.BeanConfiguration; import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig; 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.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames; 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.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest; 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.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.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo; import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.test.MatcherFactory; import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.test.TestObjectCreator; import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig; import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig; import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg; 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 ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; 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.*; import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { @ContextConfiguration(classes = {
@ -50,9 +64,6 @@ import static ru.spcex.clearing.test.TestUtils.*;
ValidationConfig.class, ValidationConfig.class,
AccountValidationConfig.class, AccountValidationConfig.class,
AccountService.class, AccountService.class,
AccountHelper.class,
InformationAccountService.class,
InformationAccountValidationConfig.class,
ImdgTestConfig.class, ImdgTestConfig.class,
KafkaTestConfig.class}) KafkaTestConfig.class})
class AccountServiceTest { class AccountServiceTest {
@ -198,16 +209,8 @@ class AccountServiceTest {
waitingSendAndCheckRecord(0L, mockProducer); waitingSendAndCheckRecord(0L, mockProducer);
Account resultUpdating = accountImdg.getSingleObjectByID(accountId); Account resultUpdating = accountImdg.getSingleObjectByID(accountId);
Account expectAccount = new Account(); existAccount.setUpdated(resultUpdating.getUpdated());
expectAccount.setId(existAccount.getId()); ACCOUNT_MATCHER.assertMatch(resultUpdating, existAccount);
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); accountImdg.delete(resultUpdating);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -195,19 +195,6 @@
</fileMapper> </fileMapper>
</fileMappers> </fileMappers>
</transformationSet> </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> </transformationSets>
</configuration> </configuration>
</execution> </execution>

View file

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

View file

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

View file

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

View file

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

View file

@ -51,13 +51,13 @@ public class InformationAccountController extends AbstractQueueController {
} }
// @ApiOperation(value = "Добавление информационного счета.") @ApiOperation(value = "Добавление информационного счета.")
// @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) @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) @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
// @ResponseBody @ResponseBody
// public CudResponse add( public CudResponse add(
// @ApiParam(value = "Параметры команды в JSON формате.", required = true) @ApiParam(value = "Параметры команды в JSON формате.", required = true)
// @RequestBody AccountInformationNewAction accountNewInformationAction) throws ExecutionException, InterruptedException { @RequestBody AccountInformationNewAction accountNewInformationAction) throws ExecutionException, InterruptedException {
// return processRequest(Consts.DESTINATION_INFORMATION_ACCOUNT_NEW, accountNewInformationAction); return processRequest(Consts.DESTINATION_INFORMATION_ACCOUNT_NEW, accountNewInformationAction);
// } }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,9 +17,4 @@ public interface IStateLoader {
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransformSpecificClass(String mapName, Class<T> clazz); <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransformSpecificClass(String mapName, Class<T> clazz);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, Map<String, ? extends Comparable<?>> conditions); <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, Map<String, ? extends Comparable<?>> conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, ImdgPredicate conditions); <T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(String mapName, Class<T> clazz, ImdgPredicate conditions);
<T extends SpcexObjectBase> Collection<Map<String, Object>> getAllMetaTransform(
String searchMapName,
String mapName,
Class<T> clazz,
ImdgPredicate conditions);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
{ {
"version": "3.9.0.71", "version": "3.8.0.51",
"enums": { "enums": {
@ -2361,41 +2361,7 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
] ]
,"actions":[
{"method":"post",
"name": "Добавление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "companyRole",
"type": 12,"dbname": "Код роли компании","name": "Наименование роли компании","shortname": "Роль","link": "companyRole","required": true
}
,
{"code": "workflowStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "companyRoleSet","linkCode": "id","required": true
}
]
}
]
} }
, ,
"security": { "security": {
@ -3328,11 +3294,11 @@
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true "type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "periodStartDate", {"code": "periodEndDate",
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true "type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "periodEndDate", {"code": "periodStartDate",
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true "type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
} }
, ,
@ -4060,7 +4026,7 @@
,"actions":[ ,"actions":[
{"method":"post", {"method":"post",
"name": "Разделение депозита", "name": "Досрочное изъятие депозита",
"destination": "registries/splitDeposit", "destination": "registries/splitDeposit",
@ -4111,35 +4077,6 @@
{"code": "balance", {"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true "type": 10,"name": "Сумма","shortname": "Сумма","required": true
} }
]
}
,
{"method":"post",
"name": "Идентификация неразмеченных средств",
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
,
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
] ]
} }
, ,
@ -4170,7 +4107,7 @@
, ,
{"method":"put", {"method":"put",
"name": "Установить отметку о получении выписки", "name": "Установить отметку о получение выписки",
"destination": "registries/changeStatusExtract", "destination": "registries/changeStatusExtract",
@ -4267,7 +4204,7 @@
} }
, ,
{"code": "account", {"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет" "type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
} }
, ,
{"code": "status", {"code": "status",
@ -4631,7 +4568,34 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
] ]
,"actions":[
{"method":"post",
"name": "Добавление информационного счета",
"confirmation": "companyId,account,status",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountInformationNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "status",
"type": 12,"name": "Наименование статуса","shortname": "Статус","link": "serviceStatus"
}
,
{"code": "accountType",
"type": 12,"name": "Наименование типа счета","shortname": "Тип","link": "accountType","required": true,"visible": false
}
]
}
]
} }
, ,
"depoAccount": { "depoAccount": {
@ -4668,66 +4632,6 @@
} }
] ]
}
,
"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": { "clearingAccount": {
@ -5334,15 +5238,11 @@
"group": "Обмен с расчетной организацией", "group": "Обмен с расчетной организацией",
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)", "name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
"fields": [ "fields": [
{"code": "fullBalance",
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
}
,
{"code": "balance", {"code": "balance",
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false "type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
} }
, ,
{"code": "securitySymbol", {"code": "securitySymbol",
@ -5358,7 +5258,7 @@
} }
, ,
{"code": "senderId", {"code": "senderId",
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true "type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
} }
, ,
{"code": "creditLeg_accountId", {"code": "creditLeg_accountId",
@ -5577,28 +5477,6 @@
"name": "Формирование ДФ-05 с кодом 9 (финальный)", "name": "Формирование ДФ-05 с кодом 9 (финальный)",
"fields": []
}
,
{"method":"post",
"destination": "CHDF",
"group": "Общее",
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
"fields": []
}
,
{"method":"post",
"destination": "CCLR",
"group": "Клиринг",
"name": "Завершение неудачных клиринговых сессий",
"fields": [] "fields": []
} }
] ]
@ -5634,7 +5512,7 @@
} }
, ,
{"code": "sessionStatus", {"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", {"code": "companyId",
@ -5866,12 +5744,10 @@
, ,
"executionDeposit": { "executionDeposit": {
"name": "Сделки на секции МКР", "name": "Сделки",
"destination": "execution-deposits", "destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit", "class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true", "logUpdates": "true",
@ -6024,8 +5900,6 @@
"destination": "execution-fonds", "destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond", "class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true", "logUpdates": "true",
@ -6174,19 +6048,17 @@
"destination": "depo-balance-registers", "destination": "depo-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister", "class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
"table": "balance_depo_register", "table": "balance_depo_register",
"fields": [ "fields": [
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
, ,
{"code": "createdAt", {"code": "createdAt",
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true "field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
@ -6198,7 +6070,7 @@
} }
, ,
{"code": "sessionId", {"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
} }
, ,
{"code": "depoCode", {"code": "depoCode",
@ -6222,8 +6094,6 @@
"destination": "money-balance-registers", "destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister", "class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register", "table": "money_balance_register",
@ -6238,7 +6108,7 @@
} }
, ,
{"code": "infoAccount", {"code": "infoAccount",
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "remainderSum", {"code": "remainderSum",
@ -6246,23 +6116,23 @@
} }
, ,
{"code": "blockedSum", {"code": "blockedSum",
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true "type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
} }
, ,
{"code": "unblockedSum", {"code": "unblockedSum",
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true "type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
} }
, ,
{"code": "inn", {"code": "inn",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "sessionId", {"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
} }
, ,
{"code": "companyFullName", {"code": "companyFullName",
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "companyId", {"code": "companyId",
@ -6270,7 +6140,7 @@
} }
, ,
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
, ,
{"code": "createdAt", {"code": "createdAt",
@ -6278,7 +6148,7 @@
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true "field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
} }
] ]
@ -6290,8 +6160,6 @@
"destination": "admitted-liabilities-registers", "destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register", "table": "admitted_liabilities_register",
@ -6354,8 +6222,6 @@
"destination": "covered-liabilities-registers", "destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register", "table": "covered_Liabilities_register",
@ -6418,8 +6284,6 @@
"destination": "money-payment-instruction-registers", "destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister", "class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register", "table": "money_payment_instruction_register",
@ -6474,8 +6338,6 @@
"destination": "depo-payment-instruction-registers", "destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister", "class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register", "table": "depo_payment_instruction_register",
@ -6530,8 +6392,6 @@
"destination": "exclude-liabilities-registers", "destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register", "table": "exclude_liabilities_register",
@ -6610,8 +6470,6 @@
"destination": "liabilities-registers", "destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register", "table": "liabilities_register",
@ -6690,8 +6548,6 @@
"destination": "execution-registers", "destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister", "class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register", "table": "execution_register",
@ -7073,11 +6929,11 @@
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true "field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время прочтения записи","shortname": "Прочитано","searchable": true,"sortable": true
} }
, ,
{"code": "senderId", {"code": "senderId",
"type": 1,"dbname": "Идентификатор отправителя","name": "Наименование отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"visible": true,"link": "userCls","linkCode": "identifier" "type": 1,"dbname": "Идентификатор компании-отправителя","name": "Наименование компании-отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"link": "company","ignore": true
} }
, ,
{"code": "addresseeId", {"code": "addresseeId",
@ -7093,7 +6949,7 @@
} }
, ,
{"code": "notificationStatus", {"code": "notificationStatus",
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus" "type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus","ignore": true
} }
, ,
{"code": "comment", {"code": "comment",
@ -7109,8 +6965,6 @@
"name": "Изменение статуса сообщения", "name": "Изменение статуса сообщения",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction",
"fields": [ "fields": [
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true
@ -8857,10 +8711,6 @@
"table": "s_df_57", "table": "s_df_57",
"fields": [ "fields": [
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false
} }
@ -9016,6 +8866,10 @@
{"code": "fileName", {"code": "fileName",
"type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true "type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true
} }
,
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
, ,
{"code": "generationId", {"code": "generationId",
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true "type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?--> <!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.9.0.71"> <meta version="3.8.0.51">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" --> <!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари--> <!--Здесь словари-->
<enums> <enums>
@ -545,16 +545,6 @@
<companyRole type="12" dbname="Код роли компании" name="Наименование роли компании" shortname="Роль" searchable="true" sortable="true" visible="true" link="companyRole"/> <companyRole type="12" dbname="Код роли компании" name="Наименование роли компании" shortname="Роль" searchable="true" sortable="true" visible="true" link="companyRole"/>
<workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" link="workflowStatus"/> <workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" link="workflowStatus"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<actions>
<post name="Добавление роли участнику" class="ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<companyRole type="12" dbname="Код роли компании" name="Наименование роли компании" shortname="Роль" link="companyRole" required="true"/>
<workflowStatus type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" link="workflowStatus" required="true"/>
</post>
<delete name="Удаление роли участнику" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="companyRoleSet" linkCode="id" required="true"/>
</delete>
</actions>
</companyRoleSet> </companyRoleSet>
<security name="Инструменты" destination="securities" class="ru.clearing.classes.statics.data.security.Security" logUpdates="true" table="security"> <security name="Инструменты" destination="securities" class="ru.clearing.classes.statics.data.security.Security" logUpdates="true" table="security">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
@ -772,8 +762,8 @@
<securityId type="1" dbname="Идентификатор инструмента" name="Наименование инструмента" shortname="Инструмент" searchable="true" sortable="true" link="security" linkCode="shortName"/> <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"/> <couponRate type="11" name="Купонная ставка" shortname="Ставка" searchable="true" sortable="true" visible="true"/>
<number type="3" name="Номер купона" shortname="Номер" searchable="true" sortable="true" visible="true"/> <number type="3" 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"/>
<periodEndDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/> <periodStartDate type="6" name="Окончание периода действия" shortname="Окончание" searchable="true" sortable="true" visible="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
</couponPeriod> </couponPeriod>
<listing name="Инструменты на режимах" destination="listings" class="ru.clearing.classes.statics.data.misc.Listing" logUpdates="true" table="listing"> <listing name="Инструменты на режимах" destination="listings" class="ru.clearing.classes.statics.data.misc.Listing" logUpdates="true" table="listing">
@ -944,7 +934,7 @@
<updatedAt field="updated" type="4" name="Дата и время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/> <updatedAt field="updated" type="4" name="Дата и время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
<securityId type="1" dbname="Идентификатор инструмента" name="Код инструмента" shortname="Код инструмента" searchable="false" sortable="true" visible="false" link="security" linkCode="shortName"/> <securityId type="1" dbname="Идентификатор инструмента" name="Код инструмента" shortname="Код инструмента" searchable="false" sortable="true" visible="false" link="security" linkCode="shortName"/>
<actions> <actions>
<post name="Разделение депозита" destination="registries/splitDeposit" confirmation="contract,outboundAmount,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew"> <post name="Досрочное изъятие депозита" destination="registries/splitDeposit" confirmation="contract,outboundAmount,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew">
<companyId type="1" name="Наименование участника" shortname="Инициатор" link="company" linkCode="shortName" enabled="false"/> <companyId type="1" name="Наименование участника" shortname="Инициатор" link="company" linkCode="shortName" enabled="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/> <contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
<outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/> <outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/>
@ -956,18 +946,12 @@
<id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/> <id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/>
<balance type="10" name="Сумма" shortname="Сумма" required="true"/> <balance type="10" name="Сумма" shortname="Сумма" required="true"/>
</post> </post>
<post name="Идентификация неразмеченных средств" destination="registries/identificationFunds" confirmation="balance,tradingClearingRegistryId" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew">
<id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/>
<balance type="10" name="Сумма" shortname="Сумма" required="true"/>
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<tradingClearingRegistryId type="1" name="Торгово-клиринговый регистр" shortname="Торгово-клиринговый регистр" link="tradingClearingRegistry" linkCode="code" required="true"/>
</post>
<put name="Изменение даты возврата депозита" destination="registries/changeRefundDate" confirmation="contact,contract,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew"> <put name="Изменение даты возврата депозита" destination="registries/changeRefundDate" confirmation="contact,contract,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew">
<groupId type="1" dbname="Идентификатор группы связанных регистров" name="Идентификатор группы" required="true" enabled="false" visible="false"/> <groupId type="1" dbname="Идентификатор группы связанных регистров" name="Идентификатор группы" required="true" enabled="false" visible="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/> <contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
<refundDate type="6" name="Дата возврата депозита" shortname="Возврат депозита" visible="true" enabled="true"/> <refundDate type="6" name="Дата возврата депозита" shortname="Возврат депозита" visible="true" enabled="true"/>
</put> </put>
<put name="Установить отметку о получении выписки" destination="registries/changeStatusExtract" confirmation="shortName,contract,balance" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeStatusExtractActionNew"> <put name="Установить отметку о получение выписки" destination="registries/changeStatusExtract" confirmation="shortName,contract,balance" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeStatusExtractActionNew">
<id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/> <id type="1" name="Идентификатор записи" shortname="ID" link="registry" linkCode="id" required="true"/>
<shortName type="2" length="255" name="Краткое наименование компании" shortname="Компания" enabled="false"/> <shortName type="2" length="255" name="Краткое наименование компании" shortname="Компания" enabled="false"/>
<contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/> <contract type="2" length="255" name="Договор" shortname="Номер договора" required="true" enabled="false"/>
@ -989,7 +973,7 @@
<actions> <actions>
<post name="Добавление счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction"> <post name="Добавление счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/> <companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<account type="2" length="50" name="Номер счета" shortname="Счет"/> <account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/> <status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/> <accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
</post> </post>
@ -1076,6 +1060,14 @@
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/> <companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" /> <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"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<actions>
<post name="Добавление информационного счета" confirmation="companyId,account,status" class="ru.spcex.clearing.backendapi.controller.request.cud.account.AccountInformationNewAction">
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" required="true"/>
<account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus"/>
<accountType type="12" name="Наименование типа счета" shortname="Тип" link="accountType" required="true" visible="false"/>
</post>
</actions>
</informationAccount> </informationAccount>
<depoAccount name="Депозитарные счета" destination="accounting/depo-accounts" class="ru.clearing.classes.statics.data.account.DepoAccount" logUpdates="true" table="depo_account"> <depoAccount name="Депозитарные счета" destination="accounting/depo-accounts" class="ru.clearing.classes.statics.data.account.DepoAccount" logUpdates="true" table="depo_account">
<accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/> <accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
@ -1084,20 +1076,6 @@
<serviceStatus field="accountId" type="12" dbname="Код статуса" name="Наименование статуса" shortname="Статус" searchable="true" sortable="true" visible="true" linkKeyCode="id" linkCode="status" link="account" extends="account" /> <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"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
</depoAccount> </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"> <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"/> <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"/> <clearingAccountType type="12" dbname="Код типа счета" name="Наименование типа счета" shortname="Тип" searchable="true" sortable="true" visible="true" link="clearingAccountType" linkCode="name"/>
@ -1237,13 +1215,12 @@
</post> </post>
<post destination="GALB" group="Обмен с расчетной организацией" name="Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)"> <post destination="GALB" group="Обмен с расчетной организацией" name="Запрос остатков по всем счетам (отправка ДФ-56 для получения ответа ДФ-01, ДФ-57)">
</post> </post>
<post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)"> <post destination="OUTV" group="Обмен с расчетной организацией" name="Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)">
<fullBalance type="10" name="Текущий баланс (всего)" shortname="Текущие средства (всего)" enabled="false"/> <balance type="10" name="Текущий баланс" shortname="Текущие средства" enabled="false"/>
<balance type="10" name="Текущий баланс (свободно)" shortname="Текущие средства (свободно)" enabled="false"/>
<securitySymbol type="2" name="Наименование инструмента/валюты" shortname="Валюта" enabled="false"/> <securitySymbol type="2" name="Наименование инструмента/валюты" shortname="Валюта" enabled="false"/>
<creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма" required="true"/> <creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма" required="true"/>
<paymentPurpose type="2" length="255" 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"/> <senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true" enabled="false"/>
<creditLeg_accountId type="1" group="Отправитель" name="Наименование счета отправителя" shortname="Регистр списания" link="account" linkCode="account"/> <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"/> <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"/> <debitLeg_accountId type="1" group="Получатель" name="Наименование счета получателя" shortname="Счет получателя" link="bankAccount" linkCode="correspondentAccount"/>
@ -1286,10 +1263,6 @@
</post> </post>
<post destination="FDFF" group="Обмен с расчетной организацией" name="Формирование ДФ-05 с кодом 9 (финальный)"> <post destination="FDFF" group="Обмен с расчетной организацией" name="Формирование ДФ-05 с кодом 9 (финальный)">
</post> </post>
<post destination="CHDF" group="Общее" name="Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21">
</post>
<post destination="CCLR" group="Клиринг" name="Завершение неудачных клиринговых сессий">
</post>
</actions> </actions>
</launcher> </launcher>
@ -1298,7 +1271,7 @@
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="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"/> <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"/> <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"/> <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"/> <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"/> <userId type="1" dbname="Идентификатор пользователя" name="Наименование пользователя" shortname="Пользователь" searchable="true" sortable="true" visible="true" link="userCls" linkCode="identifier"/>
@ -1355,7 +1328,7 @@
<bankAccId type="2" length="12" name="Идентификатор расчетного счета/кода в клиринговой организации" shortname="Код позиции" searchable="true" sortable="true"/> <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"/> <section type="12" dbname="Код наименования секции" name="Наименование секции" shortname="Секция" searchable="true" sortable="true" visible="true" link="section"/>
</sTrades> </sTrades>
<executionDeposit name="Сделки на секции МКР" destination="execution-deposits" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit"> <executionDeposit name="Сделки" destination="execution-deposits" class="ru.clearing.classes.statics.data.execution.ExecutionDeposit" logUpdates="true" table="execution_deposit">
<exchangeExecutionId type="1" 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"/> <exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/> <tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
@ -1391,7 +1364,7 @@
<updatedAt field="updated" 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"/>
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" visible="false" searchable="true" sortable="true"/> <clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" visible="false" searchable="true" sortable="true"/>
</executionDeposit> </executionDeposit>
<executionFond name="Сделки на Фондовой секции" destination="execution-fonds" historyDestination="history" class="ru.clearing.classes.statics.data.execution.ExecutionFond" logUpdates="true" table="execution_fond"> <executionFond name="Сделки на Фондовой секции" destination="execution-fonds" 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"/> <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"/> <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"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" visible="false" searchable="true" sortable="true"/>
@ -1426,32 +1399,32 @@
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/> <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"/> <sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
</executionFond> </executionFond>
<depoBalanceRegister name="Реестр остатков ценных бумаг" destination="depo-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoBalanceRegister" table="balance_depo_register"> <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" ignore="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" 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"/> <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"/> <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" ignore="true"/> <sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<depoCode type="2" length="50" name="Код раздела субсчета/счета депо" shortname="Код счета депо" searchable="true" sortable="true"/> <depoCode type="2" length="50" name="Код раздела субсчета/счета депо" shortname="Код счета депо" searchable="true" sortable="true"/>
<quantity type="11" 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"/> <securitySymbol type="2" length="255" name="Код ценной бумаги" shortname="Ценная бумага" searchable="true" sortable="true"/>
</depoBalanceRegister> </depoBalanceRegister>
<moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyBalanceRegister" table="money_balance_register"> <moneyBalanceRegister name="Реестр остатков денежных средств" destination="money-balance-registers" 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"/> <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"/> <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" ignore="true"/> <infoAccount type="2" length="50" name="Номер счета внутреннего учета СПВБ" shortname="Номер счета внутреннего учета СПВБ" searchable="true" sortable="true" visible="true"/>
<remainderSum type="10" name="Остаток денежных средств" shortname="Остаток" searchable="true" sortable="true"/> <remainderSum type="10" name="Остаток денежных средств" shortname="Остаток" searchable="true" sortable="true"/>
<blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true" ignore="true"/> <blockedSum type="10" name="Сумма блокированных денежных средств" shortname="Блокированные" searchable="true" sortable="true"/>
<unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true" ignore="true"/> <unblockedSum type="10" name="Сумма свободных денежных средств" shortname="Свободные" searchable="true" sortable="true"/>
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true" ignore="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" ignore="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" ignore="true"/> <companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/> <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" ignore="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="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"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/>
</moneyBalanceRegister> </moneyBalanceRegister>
<admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister" table="admitted_liabilities_register"> <admittedLiabilitiesRegister name="Реестр обязательств, допущенных к клирингу" destination="admitted-liabilities-registers" 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"/> <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"/> <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"/> <securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
@ -1465,7 +1438,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/> <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"/> <clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
</admittedLiabilitiesRegister> </admittedLiabilitiesRegister>
<coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister" table="covered_Liabilities_register"> <coveredLiabilitiesRegister name="Реестр обязательств, прошедших процедуру контроля обеспечения" destination="covered-liabilities-registers" 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"/> <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"/> <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"/> <securitySymbol type="2" length="255" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" visible="true"/>
@ -1479,7 +1452,7 @@
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" visible="false"/> <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"/> <clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" searchable="true" sortable="true" visible="false"/>
</coveredLiabilitiesRegister> </coveredLiabilitiesRegister>
<moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister" table="money_payment_instruction_register"> <moneyPaymentInstructionRegister name="Реестр распоряжений, направленных расчетной организации" destination="money-payment-instruction-registers" 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"/> <creditLegAccount type="2" length="50" name="Счет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" visible="true"/>
<creditLegAmount type="10" 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"/> <creditLegCurrencyCode type="12" dbname="Код валюты отправителя" name="Наименование валюты отправителя" shortname="Валюта отправителя" searchable="true" sortable="true" visible="true" link="currency"/>
@ -1491,7 +1464,7 @@
<updatedAt field="updated" 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"/> <clearingDate type="6" name="Дата расчета" shortname="Дата расчета" searchable="true" sortable="true" visible="true"/>
</moneyPaymentInstructionRegister> </moneyPaymentInstructionRegister>
<depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register"> <depoPaymentInstructionRegister name="Реестр распоряжений, направленных расчетному депозитарию" destination="depo-payment-instruction-registers" class="ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister" table="depo_payment_instruction_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <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"/> <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"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1503,7 +1476,7 @@
<direction type="1" name="Направление" shortname="Направление" searchable="true" sortable="true" link="inOutDirection" ignore="true"/> <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"/> <sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
</depoPaymentInstructionRegister> </depoPaymentInstructionRegister>
<excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register"> <excludeLiabilitiesRegister name="Реестр обязательств, исключенных из клирингового пула" destination="exclude-liabilities-registers" class="ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister" table="exclude_liabilities_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <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"/> <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"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1521,7 +1494,7 @@
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/> <sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/> <settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
</excludeLiabilitiesRegister> </excludeLiabilitiesRegister>
<liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register"> <liabilitiesRegister name="Реестр учета обязательств" destination="liabilities-registers" class="ru.clearing.classes.statics.data.register.LiabilitiesRegister" table="liabilities_register">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <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"/> <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"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
@ -1539,7 +1512,7 @@
<sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/> <sumLiabilities type="10" name="Сумма обязательств" shortname="Обязательства" searchable="true" sortable="true" visible="true"/>
<settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/> <settlementDate type="6" name="Дата расчета" shortname="Расчет" searchable="true" sortable="true"/>
</liabilitiesRegister> </liabilitiesRegister>
<executionRegister name="Реестр сделок" destination="execution-registers" historyDestination="history" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register"> <executionRegister name="Реестр сделок" destination="execution-registers" class="ru.clearing.classes.statics.data.register.ExecutionRegister" table="execution_register">
<tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/> <tradingDate type="6" name="Дата заключения сделки" shortname="Дата заключения сделки" visible="true" searchable="true" sortable="true"/>
<exchangeExecutionId type="1" 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"/> <exchangeExecutionTime type="4" name="Время заключения сделки в Торговой системе" shortname="Время заключения сделки" visible="true" searchable="true" sortable="true"/>
@ -1630,16 +1603,16 @@
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<clearingDate type="6" name="Дата" shortname="Дата" searchable="true" sortable="true" visible="true"/> <clearingDate type="6" name="Дата" shortname="Дата" searchable="true" sortable="true" visible="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" visible="true"/> <createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" visible="true"/>
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true"/> <updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время прочтения записи" shortname="Прочитано" searchable="true" sortable="true"/>
<senderId type="1" dbname="Идентификатор отправителя" name="Наименование отправителя" shortname="Отправитель" searchable="true" sortable="true" visible="true" link="userCls" linkCode="identifier"/> <senderId type="1" dbname="Идентификатор компании-отправителя" name="Наименование компании-отправителя" shortname="Отправитель" searchable="true" sortable="true" link="company" ignore="true"/>
<addresseeId type="1" dbname="Идентификатор компании-получателя" name="Наименование компании-получателя" shortname="Получатель" searchable="true" sortable="true" link="company" ignore="true"/> <addresseeId type="1" dbname="Идентификатор компании-получателя" name="Наименование компании-получателя" shortname="Получатель" searchable="true" sortable="true" link="company" ignore="true"/>
<objectType type="12" dbname="Код типа объекта" name="Наименование типа объекта" shortname="Объект" searchable="true" sortable="true" link="objectType" ignore="true"/> <objectType type="12" dbname="Код типа объекта" name="Наименование типа объекта" shortname="Объект" searchable="true" sortable="true" link="objectType" ignore="true"/>
<objectId type="1" name="Идентификатор объекта" shortname="ID объекта" searchable="true" sortable="true" ignore="true"/> <objectId type="1" name="Идентификатор объекта" shortname="ID объекта" searchable="true" sortable="true" ignore="true"/>
<notificationStatus type="12" dbname="Код статуса сообщения" name="Наименование статуса сообщения" shortname="Статус" searchable="true" sortable="true" visible="true" link="notificationStatus"/> <notificationStatus type="12" dbname="Код статуса сообщения" name="Наименование статуса сообщения" shortname="Статус" searchable="true" sortable="true" visible="true" link="notificationStatus" ignore="true"/>
<comment type="2" length="255" name="Текст сообщения" shortname="Сообщение" searchable="true" sortable="true" visible="true"/> <comment type="2" length="255" name="Текст сообщения" shortname="Сообщение" searchable="true" sortable="true" visible="true"/>
<priority type="12" dbname="Код приоритета отображения" name="Наименование приоритета отображения" shortname="Приоритет отображения" searchable="true" sortable="true" link="priority"/> <priority type="12" dbname="Код приоритета отображения" name="Наименование приоритета отображения" shortname="Приоритет отображения" searchable="true" sortable="true" link="priority"/>
<actions> <actions>
<put name="Изменение статуса сообщения" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction"> <put name="Изменение статуса сообщения">
<id type="1" name="Идентификатор записи" shortname="ID" link="notification" linkCode="id" required="true"/> <id type="1" name="Идентификатор записи" shortname="ID" link="notification" linkCode="id" required="true"/>
<notificationStatus type="12" name="Наименование статуса сообщения" shortname="Статус" link="notificationStatus" required="true"/> <notificationStatus type="12" name="Наименование статуса сообщения" shortname="Статус" link="notificationStatus" required="true"/>
</put> </put>
@ -2042,7 +2015,6 @@
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/> <generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
</sDf56> </sDf56>
<sDf57 name="ДФ-57 Список транзакций о списании/зачислении за период по всем счетам (ТБС и КС)" destination="s-dfs/s-df57" class="ru.clearing.classes.statics.data.sdf.SDf57" table="s_df_57"> <sDf57 name="ДФ-57 Список транзакций о списании/зачислении за период по всем счетам (ТБС и КС)" destination="s-dfs/s-df57" class="ru.clearing.classes.statics.data.sdf.SDf57" table="s_df_57">
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/> <id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
<dbfId type="1" name="Уникальный идентификатор платежного документа (транзакции)" shortname="ID платежного поручения" searchable="true" sortable="true" visible="true"/> <dbfId type="1" name="Уникальный идентификатор платежного документа (транзакции)" shortname="ID платежного поручения" searchable="true" sortable="true" visible="true"/>
<deal_deb type="2" length="4" name="Биржевой код участника клиринга (плательщик)" shortname="Инициатор в КС" searchable="true" sortable="true" visible="true"/> <deal_deb type="2" length="4" name="Биржевой код участника клиринга (плательщик)" shortname="Инициатор в КС" searchable="true" sortable="true" visible="true"/>
@ -2082,6 +2054,7 @@
<acc_kr type="2" length="35" name="Счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/> <acc_kr type="2" length="35" name="Счет получателя" shortname="Счет получателя" searchable="true" sortable="true" visible="true"/>
<specif type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" searchable="true" sortable="true" visible="true"/> <specif type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" searchable="true" sortable="true" visible="true"/>
<fileName type="2" length="255" name="Наименование входящего файла" shortname="Наименование файла" searchable="true" sortable="true" visible="true"/> <fileName type="2" length="255" name="Наименование входящего файла" shortname="Наименование файла" searchable="true" sortable="true" visible="true"/>
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/> <generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
</sDf57> </sDf57>
<managementJournal name="Журнал мониторинга и контроля" destination="management-journals" class="ru.clearing.classes.statics.data.journal.ManagementJournal" table="management_journal"> <managementJournal name="Журнал мониторинга и контроля" destination="management-journals" class="ru.clearing.classes.statics.data.journal.ManagementJournal" table="management_journal">

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
{ {
"version": "3.9.0.71", "version": "3.8.0.51",
"enums": { "enums": {
@ -2361,41 +2361,7 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
] ]
,"actions":[
{"method":"post",
"name": "Добавление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyRoleSetNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "companyRole",
"type": 12,"dbname": "Код роли компании","name": "Наименование роли компании","shortname": "Роль","link": "companyRole","required": true
}
,
{"code": "workflowStatus",
"type": 12,"dbname": "Код статуса","name": "Наименование статуса","shortname": "Статус","link": "workflowStatus","required": true
}
]
}
,
{"method":"delete",
"name": "Удаление роли участнику",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "companyRoleSet","linkCode": "id","required": true
}
]
}
]
} }
, ,
"security": { "security": {
@ -3328,11 +3294,11 @@
"type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true "type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "periodStartDate", {"code": "periodEndDate",
"type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true "type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "periodEndDate", {"code": "periodStartDate",
"type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true "type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true
} }
, ,
@ -4060,7 +4026,7 @@
,"actions":[ ,"actions":[
{"method":"post", {"method":"post",
"name": "Разделение депозита", "name": "Досрочное изъятие депозита",
"destination": "registries/splitDeposit", "destination": "registries/splitDeposit",
@ -4111,35 +4077,6 @@
{"code": "balance", {"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true "type": 10,"name": "Сумма","shortname": "Сумма","required": true
} }
]
}
,
{"method":"post",
"name": "Идентификация неразмеченных средств",
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
"fields": [
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "registry","linkCode": "id","required": true
}
,
{"code": "balance",
"type": 10,"name": "Сумма","shortname": "Сумма","required": true
}
,
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
] ]
} }
, ,
@ -4170,7 +4107,7 @@
, ,
{"method":"put", {"method":"put",
"name": "Установить отметку о получении выписки", "name": "Установить отметку о получение выписки",
"destination": "registries/changeStatusExtract", "destination": "registries/changeStatusExtract",
@ -4267,7 +4204,7 @@
} }
, ,
{"code": "account", {"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет" "type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
} }
, ,
{"code": "status", {"code": "status",
@ -4631,7 +4568,34 @@
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
] ]
,"actions":[
{"method":"post",
"name": "Добавление информационного счета",
"confirmation": "companyId,account,status",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountInformationNewAction",
"fields": [
{"code": "companyId",
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true
}
,
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "status",
"type": 12,"name": "Наименование статуса","shortname": "Статус","link": "serviceStatus"
}
,
{"code": "accountType",
"type": 12,"name": "Наименование типа счета","shortname": "Тип","link": "accountType","required": true,"visible": false
}
]
}
]
} }
, ,
"depoAccount": { "depoAccount": {
@ -4668,66 +4632,6 @@
} }
] ]
}
,
"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": { "clearingAccount": {
@ -5334,15 +5238,11 @@
"group": "Обмен с расчетной организацией", "group": "Обмен с расчетной организацией",
"name": "Вывод свободных средств с клирингового регистра (отправка ДФ-54 для получения ответа ДФ-55)", "name": "Вывод свободных средств инициаторов В (отправка ДФ-54 для получения ответа ДФ-55)",
"fields": [ "fields": [
{"code": "fullBalance",
"type": 10,"name": "Текущий баланс (всего)","shortname": "Текущие средства (всего)","enabled": false
}
,
{"code": "balance", {"code": "balance",
"type": 10,"name": "Текущий баланс (свободно)","shortname": "Текущие средства (свободно)","enabled": false "type": 10,"name": "Текущий баланс","shortname": "Текущие средства","enabled": false
} }
, ,
{"code": "securitySymbol", {"code": "securitySymbol",
@ -5358,7 +5258,7 @@
} }
, ,
{"code": "senderId", {"code": "senderId",
"type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true "type": 1,"group": "Отправитель","name": "Участник отправитель","shortname": "Отправитель","link": "company","linkCode": "shortName","required": true,"enabled": false
} }
, ,
{"code": "creditLeg_accountId", {"code": "creditLeg_accountId",
@ -5577,28 +5477,6 @@
"name": "Формирование ДФ-05 с кодом 9 (финальный)", "name": "Формирование ДФ-05 с кодом 9 (финальный)",
"fields": []
}
,
{"method":"post",
"destination": "CHDF",
"group": "Общее",
"name": "Проверка наличия пары ДФ-01/ДФ-57 и ДФ-08/ДФ-21",
"fields": []
}
,
{"method":"post",
"destination": "CCLR",
"group": "Клиринг",
"name": "Завершение неудачных клиринговых сессий",
"fields": [] "fields": []
} }
] ]
@ -5634,7 +5512,7 @@
} }
, ,
{"code": "sessionStatus", {"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", {"code": "companyId",
@ -5866,12 +5744,10 @@
, ,
"executionDeposit": { "executionDeposit": {
"name": "Сделки на секции МКР", "name": "Сделки",
"destination": "execution-deposits", "destination": "execution-deposits",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit", "class": "ru.clearing.classes.statics.data.execution.ExecutionDeposit",
"logUpdates": "true", "logUpdates": "true",
@ -6024,8 +5900,6 @@
"destination": "execution-fonds", "destination": "execution-fonds",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.execution.ExecutionFond", "class": "ru.clearing.classes.statics.data.execution.ExecutionFond",
"logUpdates": "true", "logUpdates": "true",
@ -6174,19 +6048,17 @@
"destination": "depo-balance-registers", "destination": "depo-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister", "class": "ru.clearing.classes.statics.data.register.DepoBalanceRegister",
"table": "balance_depo_register", "table": "balance_depo_register",
"fields": [ "fields": [
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
, ,
{"code": "createdAt", {"code": "createdAt",
"field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true "field": "created","type": 4,"webtype": "5","dbname": "Дата-время создания записи","name": "Время создания записи","shortname": "Создано","searchable": true,"sortable": true,"ignore": true
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
@ -6198,7 +6070,7 @@
} }
, ,
{"code": "sessionId", {"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
} }
, ,
{"code": "depoCode", {"code": "depoCode",
@ -6222,8 +6094,6 @@
"destination": "money-balance-registers", "destination": "money-balance-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister", "class": "ru.clearing.classes.statics.data.register.MoneyBalanceRegister",
"table": "money_balance_register", "table": "money_balance_register",
@ -6238,7 +6108,7 @@
} }
, ,
{"code": "infoAccount", {"code": "infoAccount",
"type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 50,"name": "Номер счета внутреннего учета СПВБ","shortname": "Номер счета внутреннего учета СПВБ","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "remainderSum", {"code": "remainderSum",
@ -6246,23 +6116,23 @@
} }
, ,
{"code": "blockedSum", {"code": "blockedSum",
"type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true,"ignore": true "type": 10,"name": "Сумма блокированных денежных средств","shortname": "Блокированные","searchable": true,"sortable": true
} }
, ,
{"code": "unblockedSum", {"code": "unblockedSum",
"type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true,"ignore": true "type": 10,"name": "Сумма свободных денежных средств","shortname": "Свободные","searchable": true,"sortable": true
} }
, ,
{"code": "inn", {"code": "inn",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "sessionId", {"code": "sessionId",
"type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session","ignore": true "type": 1,"dbname": "Идентификатор клиринговой сессии","name": "Клиринговая сессия","shortname": "Сессия","visible": true,"searchable": true,"sortable": true,"link": "session"
} }
, ,
{"code": "companyFullName", {"code": "companyFullName",
"type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true,"ignore": true "type": 2,"length": 255,"name": "Полное наименование компании","shortname": "Полное наименование компании","searchable": true,"sortable": true,"visible": true
} }
, ,
{"code": "companyId", {"code": "companyId",
@ -6270,7 +6140,7 @@
} }
, ,
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"ignore": true "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
} }
, ,
{"code": "createdAt", {"code": "createdAt",
@ -6278,7 +6148,7 @@
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true "field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true
} }
] ]
@ -6290,8 +6160,6 @@
"destination": "admitted-liabilities-registers", "destination": "admitted-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.AdmittedLiabilitiesRegister",
"table": "admitted_liabilities_register", "table": "admitted_liabilities_register",
@ -6354,8 +6222,6 @@
"destination": "covered-liabilities-registers", "destination": "covered-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.CoveredLiabilitiesRegister",
"table": "covered_Liabilities_register", "table": "covered_Liabilities_register",
@ -6418,8 +6284,6 @@
"destination": "money-payment-instruction-registers", "destination": "money-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister", "class": "ru.clearing.classes.statics.data.register.MoneyPaymentInstructionRegister",
"table": "money_payment_instruction_register", "table": "money_payment_instruction_register",
@ -6474,8 +6338,6 @@
"destination": "depo-payment-instruction-registers", "destination": "depo-payment-instruction-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister", "class": "ru.clearing.classes.statics.data.register.DepoPaymentInstructionRegister",
"table": "depo_payment_instruction_register", "table": "depo_payment_instruction_register",
@ -6530,8 +6392,6 @@
"destination": "exclude-liabilities-registers", "destination": "exclude-liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.ExcludeLiabilitiesRegister",
"table": "exclude_liabilities_register", "table": "exclude_liabilities_register",
@ -6610,8 +6470,6 @@
"destination": "liabilities-registers", "destination": "liabilities-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister", "class": "ru.clearing.classes.statics.data.register.LiabilitiesRegister",
"table": "liabilities_register", "table": "liabilities_register",
@ -6690,8 +6548,6 @@
"destination": "execution-registers", "destination": "execution-registers",
"historyDestination": "history",
"class": "ru.clearing.classes.statics.data.register.ExecutionRegister", "class": "ru.clearing.classes.statics.data.register.ExecutionRegister",
"table": "execution_register", "table": "execution_register",
@ -7073,11 +6929,11 @@
} }
, ,
{"code": "updatedAt", {"code": "updatedAt",
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true "field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время прочтения записи","shortname": "Прочитано","searchable": true,"sortable": true
} }
, ,
{"code": "senderId", {"code": "senderId",
"type": 1,"dbname": "Идентификатор отправителя","name": "Наименование отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"visible": true,"link": "userCls","linkCode": "identifier" "type": 1,"dbname": "Идентификатор компании-отправителя","name": "Наименование компании-отправителя","shortname": "Отправитель","searchable": true,"sortable": true,"link": "company","ignore": true
} }
, ,
{"code": "addresseeId", {"code": "addresseeId",
@ -7093,7 +6949,7 @@
} }
, ,
{"code": "notificationStatus", {"code": "notificationStatus",
"type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus" "type": 12,"dbname": "Код статуса сообщения","name": "Наименование статуса сообщения","shortname": "Статус","searchable": true,"sortable": true,"visible": true,"link": "notificationStatus","ignore": true
} }
, ,
{"code": "comment", {"code": "comment",
@ -7109,8 +6965,6 @@
"name": "Изменение статуса сообщения", "name": "Изменение статуса сообщения",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.NotificationUpdateAction",
"fields": [ "fields": [
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "notification","linkCode": "id","required": true
@ -8857,10 +8711,6 @@
"table": "s_df_57", "table": "s_df_57",
"fields": [ "fields": [
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
,
{"code": "id", {"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false "type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true,"visible": false
} }
@ -9016,6 +8866,10 @@
{"code": "fileName", {"code": "fileName",
"type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true "type": 2,"length": 255,"name": "Наименование входящего файла","shortname": "Наименование файла","searchable": true,"sortable": true,"visible": true
} }
,
{"code": "generationTime",
"type": 4,"name": "Дата и время создания записи","shortname": "Дата и время создания","searchable": true,"sortable": true,"visible": true
}
, ,
{"code": "generationId", {"code": "generationId",
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true "type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true

View file

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

View file

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

View file

@ -2,8 +2,6 @@ package ru.spcex.clearing.config;
import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer; 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.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -28,37 +26,25 @@ import java.util.function.Supplier;
@Configuration @Configuration
public class KafkaConfig { public class KafkaConfig {
private final Logger log = LoggerFactory.getLogger(getClass()); @Autowired
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) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean("kafkaConsumer") @Bean("kafkaConsumer")
public Consumer<String, Object> createConsumer() { public Consumer<String, Object> createConsumer(ClearingServiceSettings settings) {
return KafkaConsumerFactory.consumer(kafkaSettings); return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
} }
@Autowired
@Bean("kafkaConsumerGateway") @Bean("kafkaConsumerGateway")
public Supplier<Consumer<String, Object>> getwaySessionConsumer() { public Supplier<Consumer<String, Object>> getwaySessionConsumer(ClearingServiceSettings settings) {
AtomicInteger groupId = new AtomicInteger(1); AtomicInteger groupId = new AtomicInteger(1);
return () -> { return () -> {
KafkaConsumerSettings consumer = kafkaSettings; KafkaConsumerSettings consumer = settings.getKafkaConsumer();
KafkaConsumerSettings gatewayConsumer = new KafkaConsumerSettings(); KafkaConsumerSettings gatewayConsumer = new KafkaConsumerSettings();
gatewayConsumer.setBootstrapServers(consumer.getBootstrapServers()); gatewayConsumer.setBootstrapServers(consumer.getBootstrapServers());
gatewayConsumer.setSessionTimeoutMs(consumer.getSessionTimeoutMs()); gatewayConsumer.setSessionTimeoutMs(consumer.getSessionTimeoutMs());
gatewayConsumer.setAutoOffsetReset(consumer.getAutoOffsetReset()); gatewayConsumer.setAutoOffsetReset(consumer.getAutoOffsetReset());
gatewayConsumer.setEnableAutoCommit(consumer.getEnableAutoCommit()); gatewayConsumer.setEnableAutoCommit(consumer.getEnableAutoCommit());
gatewayConsumer.setGroupId(consumer.getGroupId() + "-gateway-" + groupId.getAndIncrement()); gatewayConsumer.setGroupId(consumer.getGroupId() + "-session-" + groupId.getAndIncrement());
return KafkaConsumerFactory.consumer(gatewayConsumer); return KafkaConsumerFactory.consumer(gatewayConsumer);
}; };
} }

View file

@ -5,7 +5,6 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance; import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.account.DepoAccount; 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.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.company.relation.Relation;
@ -27,7 +26,10 @@ import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*; import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.service.validation.*; import ru.spcex.clearing.service.validation.*;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
@ -38,7 +40,6 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.LogPrefixId; import ru.spcex.platform.imdg.validation.LogPrefixId;
import ru.spcex.platform.imdg.validation.rule.AnltAccLoad;
import ru.spcex.platform.imdg.validation.rule.PresentById; import ru.spcex.platform.imdg.validation.rule.PresentById;
import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
@ -46,7 +47,6 @@ import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
@Configuration @Configuration
public class ValidationConfig { public class ValidationConfig {
@ -71,7 +71,6 @@ public class ValidationConfig {
Imdg<SDf55> sDf55Imdg; Imdg<SDf55> sDf55Imdg;
Imdg<SDf54> sDf54Imdg; Imdg<SDf54> sDf54Imdg;
Imdg<PaymentInstruction> pmtImdg; Imdg<PaymentInstruction> pmtImdg;
Imdg<ClearingMemberCategory> ctgrImdg;
ImdgProvider imdgProvider; ImdgProvider imdgProvider;
public ValidationConfig(ImdgProvider imdgProvider) { public ValidationConfig(ImdgProvider imdgProvider) {
@ -94,7 +93,6 @@ public class ValidationConfig {
this.sDf55Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf55, SDf55.class); this.sDf55Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf55, SDf55.class);
this.sDf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class); this.sDf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.ctgrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
} }
@ -330,14 +328,12 @@ public class ValidationConfig {
ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>(); ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(returnDepositRequest); context.setValidatedObject(returnDepositRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry); context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ctgrImdg);
context.setLogPrefix(LogPrefixId.INSTANCE); context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true), new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
ReturnDepositValidationRule.RgsWronCodeCheck, ReturnDepositValidationRule.RegistryCodeCheck,
ReturnDepositValidationRule.CategoryCheck,
ReturnDepositValidationRule.BalanceCheck, ReturnDepositValidationRule.BalanceCheck,
ReturnDepositValidationRule.Dm_Check ReturnDepositValidationRule.DmxCheck
); );
}; };
} }
@ -366,36 +362,12 @@ public class ValidationConfig {
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
StatusExtractValidationRule.Fields, StatusExtractValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true), new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
StatusExtractValidationRule.RegistryCodeCheck,
StatusExtractValidationRule.ContractCheck, StatusExtractValidationRule.ContractCheck,
StatusExtractValidationRule.RequestStatusValid,
StatusExtractValidationRule.RegistryStatusValid StatusExtractValidationRule.RegistryStatusValid
); );
}; };
} }
@Bean("identificationFundsValidator")
public Function<IdentificationFundsRequest, IValidator> identificationFundsValidator() {
return identificationFundsRequest -> {
ImdgValidationContext<IdentificationFundsRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(identificationFundsRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
IdentificationFundsValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
IdentificationFundsValidationRule.RegistryCodeCheck,
IdentificationFundsValidationRule.BalanceCheck,
IdentificationFundsValidationRule.TcrCheck,
IdentificationFundsValidationRule.AssetsCheck,
new AnltAccLoad(ClearingError.GeneralError)
);
};
}
@Bean("splitDepositValidator") @Bean("splitDepositValidator")
public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() { public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() {
return refundDateRequest -> { return refundDateRequest -> {
@ -414,8 +386,7 @@ public class ValidationConfig {
IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class, IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class,
ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false), ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false),
SplitDepositRequestValidationRule.PositiveAmount, SplitDepositRequestValidationRule.PositiveAmount,
SplitDepositRequestValidationRule.CrossvalidateByRegistry, SplitDepositRequestValidationRule.CrossvalidateByRegistry
SplitDepositRequestValidationRule.LoadContractIndexes
); );
}; };
} }
@ -427,7 +398,6 @@ public class ValidationConfig {
ctx.setValidatedObject(pmtOut); ctx.setValidatedObject(pmtOut);
ctx.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); ctx.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
ctx.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); ctx.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
ctx.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry);
return new ValidatorImpl<>(ctx, return new ValidatorImpl<>(ctx,
PaymentOutboundValidationRule.RequiredFields, PaymentOutboundValidationRule.RequiredFields,
IdPresentRule.instance("senderId", IdPresentRule.instance("senderId",
@ -435,17 +405,15 @@ public class ValidationConfig {
IMDGDistributedNames.Map_Company, IMDGDistributedNames.Map_Company,
Company.class, Company.class,
ClearingError.RequiredFieldEmpty, ClearingError.RequiredFieldEmpty,
ClearingError.WrongField), ClearingError.DictionaryNotFound),
IdPresentRule.instance("addresseeId", IdPresentRule.instance("addresseeId",
PIClearingOutbondActionNewRequest::getAddresseeId, PIClearingOutbondActionNewRequest::getAddresseeId,
IMDGDistributedNames.Map_Company, IMDGDistributedNames.Map_Company,
Company.class, Company.class,
ClearingError.RequiredFieldEmpty, ClearingError.RequiredFieldEmpty,
ClearingError.WrongField), ClearingError.DictionaryNotFound),
PaymentOutboundValidationRule.CreditLegAccount, PaymentOutboundValidationRule.CreditLegAccount,
PaymentOutboundValidationRule.DebitLegAccount, PaymentOutboundValidationRule.DebitLegAccount);
PaymentOutboundValidationRule.AddresseePresent,
PaymentOutboundValidationRule.TcrPresent);
}; };
} }
@ -492,19 +460,6 @@ 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") @Bean("userRoleVerification")
public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver msgs) { public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver msgs) {
return new UserRoleVerification(imdgProvider, msgs, ClearingError.UserVerifyDenial); return new UserRoleVerification(imdgProvider, msgs, ClearingError.UserVerifyDenial);

View file

@ -15,7 +15,6 @@ public class ClearingServiceSettings {
private KafkaConsumerSettings kafkaConsumer; private KafkaConsumerSettings kafkaConsumer;
private KafkaProducerSettings kafkaProducer; private KafkaProducerSettings kafkaProducer;
private SessionStageSettings sessionStage; private SessionStageSettings sessionStage;
private TradeSettings trade = new TradeSettings();
public HazelcastClientParams getHazelcast() { public HazelcastClientParams getHazelcast() {
return hazelcast; return hazelcast;
@ -48,12 +47,4 @@ public class ClearingServiceSettings {
public void setSessionStage(SessionStageSettings sessionStage) { public void setSessionStage(SessionStageSettings sessionStage) {
this.sessionStage = sessionStage; this.sessionStage = sessionStage;
} }
public TradeSettings getTrade() {
return trade;
}
public void setTrade(TradeSettings trade) {
this.trade = trade;
}
} }

View file

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

View file

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

View file

@ -22,7 +22,7 @@ public class NotificationSender {
public void sendNotification(ObjectType objType, String comment, Priority priority) { public void sendNotification(ObjectType objType, String comment, Priority priority) {
NotificationNewRequest reviseNotification = new NotificationNewRequest(); NotificationNewRequest reviseNotification = new NotificationNewRequest();
reviseNotification.setObjectType(objType.getKey()); reviseNotification.setObjectType(ObjectType.rgst.getKey());
reviseNotification.setComment(comment); reviseNotification.setComment(comment);
reviseNotification.setPriority(priority.getKey()); reviseNotification.setPriority(priority.getKey());
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification); kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, reviseNotification);

View file

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

View file

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

View file

@ -4,31 +4,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; 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.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; 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.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.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.*; import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status; 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.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
import ru.spcex.clearing.session.stage.util.RegistryUtil; import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.util.services.RequestHelper;
@ -47,13 +35,10 @@ import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.util.Collection;
import java.util.*; import java.util.Map;
import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service @Service
public class RegistryService { public class RegistryService {
@ -62,56 +47,29 @@ public class RegistryService {
private final ImdgProvider imdgProvider; private final ImdgProvider imdgProvider;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg; private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Registry> registryImdg; 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<RegistryReturnDepositRequest, IValidator> returnDepositVal;
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal; private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
private final Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal; private final Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal;
private final Function<IdentificationFundsRequest, IValidator> identificationFundsVal;
private final Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal; private final Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal;
private final GatewayRequester gateway;
private final TradingTimeService trdTime;
private final NotificationSender notification;
private final KafkaSender kafkaSender;
private final IMessageResolver msgResolver; private final IMessageResolver msgResolver;
private final RequestHelper reqHelp; private final RequestHelper reqHelp;
private final UserRoleVerification rights; private final UserRoleVerification rights;
private final AssetTBFProcessing assets;
public RegistryService(ImdgProvider imdgProvider, public RegistryService(ImdgProvider imdgProvider,
@Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal, @Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal,
@Qualifier("refundDateValidator") Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal, @Qualifier("refundDateValidator") Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal,
@Qualifier("identificationFundsValidator") Function<IdentificationFundsRequest, IValidator> identificationFundsVal,
@Qualifier("splitDepositValidator") Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal, @Qualifier("splitDepositValidator") Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal,
@Qualifier("statusExtractValidator") Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal, @Qualifier("statusExtractValidator") Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal,
GatewayRequester gateway, IMessageResolver msgResolver,
TradingTimeService tradingTimeService, RequestHelper reqHelp, UserRoleVerification rights) {
NotificationSender notification,
KafkaSender kafkaSender, IMessageResolver msgResolver,
RequestHelper reqHelp,
UserRoleVerification rights,
AssetTBFProcessing assets) {
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.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.returnDepositVal = returnDepositVal;
this.refundDateVal = refundDateVal; this.refundDateVal = refundDateVal;
this.identificationFundsVal = identificationFundsVal;
this.splitDepositActionVal = splitDepositActionVal; this.splitDepositActionVal = splitDepositActionVal;
this.statusExtractVal = statusExtractVal; this.statusExtractVal = statusExtractVal;
this.gateway = gateway;
this.trdTime = tradingTimeService;
this.notification = notification;
this.kafkaSender = kafkaSender;
this.assets = assets;
this.gateway.setName("RgsService|DM*V");
this.msgResolver = msgResolver; this.msgResolver = msgResolver;
this.reqHelp = reqHelp; this.reqHelp = reqHelp;
this.rights = rights; this.rights = rights;
@ -167,59 +125,6 @@ public class RegistryService {
registryImdg.update(rgs); registryImdg.update(rgs);
log.trace("TCR#id={} registry#id={} updated", tcr.getId(), rgs.getId()); 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) { public RequestInfoUpdate returnDeposit(BaseRequest<RegistryReturnDepositRequest> req) {
@ -232,40 +137,28 @@ public class RegistryService {
msgResolver.resolve(err.get())); msgResolver.resolve(err.get()));
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get())); return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
} }
Registry _m_t = validator.getStored(ValidationStored.ReturnDepositOm_t); Registry tm_t = validator.getStored(Stored.PresentById);
if (_m_t == null) _m_t = validator.getStored(Stored.PresentById); Registry dm_x = validator.getStored(ValidationStored.ReturnDepositDmx);
if (dm_x != null) {
Registry dm__ = validator.getStored(ValidationStored.ReturnDepositDm__); dm_x.setSessionId(null);
if (dm__ != null) { dm_x.setSessionType(null);
dm__.setSessionId(null); dm_x.setBalance(requestPayload.getBalance());
dm__.setSessionType(null); dm_x.setUpdated(Instant.now());
dm__.setBalance(safeBD(dm__.getBalance()).add(requestPayload.getBalance())); registryImdg.update(dm_x);
dm__.setUpdated(Instant.now()); log.debug("updated dm*x.id={} by RegistryReturnDepositRequest.id={}",
registryImdg.update(dm__); dm_x.getId(),
log.debug("updated {}.id={} by RegistryReturnDepositRequest.id={}",
dm__.getRegistryCode(),
dm__.getId(),
req.getId()); req.getId());
} else { } else {
dm__ = _m_t.clone(); dm_x = tm_t.clone();
dm__.setRegistryDesignation(RegistryDesignation.D.getKey()); dm_x.setRegistryDesignation(RegistryDesignation.D.getKey());
RegistryManager.zeroState(dm__); dm_x.setRegistryUnit(RegistryUnit.X.getKey());
dm__.setSettlementDate(LocalDate.now()); dm_x.setRegistryCode(RegistryUtil.clearingCode(dm_x));
dm__.setValueDate(null); dm_x.setBalance(requestPayload.getBalance());
dm__.setRefundDate(null); dm_x.setSessionId(null);
if (RegistryDesignation.T.equalsByKey(_m_t.getRegistryDesignation())) { dm_x.setSessionType(null);
dm__.setRegistryUnit(RegistryUnit.X.getKey()); registryImdg.insert(dm_x);
} else { log.debug("created dm*x.id={} by RegistryReturnDepositRequest.id={}",
dm__.setRegistryUnit(RegistryUnit.T.getKey()); dm_x.getId(),
}
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()); req.getId());
} }
return new RequestInfoUpdate(req.getId(), Status.Success, null); return new RequestInfoUpdate(req.getId(), Status.Success, null);
@ -284,89 +177,10 @@ public class RegistryService {
msgResolver.resolve(err.get())); msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get()); return reqHelp.error(req.getId(), err.get());
} }
Registry rgs = validator.getStored(Stored.PresentById); Registry registry = validator.getStored(Stored.PresentById);
if (trdTime.isTradingTime()) { registry.setRegistryStatus(payload.getRegistryStatus());
Long gtwReqId = kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, gtwReq(rgs)); log.debug("changing registry.id={} status to {}", registry.getId(), payload.getRegistryStatus());
log.debug("send request to {} id={}", Consts.ASSET_OPERATION, gtwReqId); registryImdg.update(registry);
} else {
log.debug("RegistryChangeStatusExtractRequest rgs.id={} not sending gateway request", rgs.getId());
}
rgs.setRegistryStatus(payload.getRegistryStatus());
log.debug("changing registry.id={} status to {}", rgs.getId(), payload.getRegistryStatus());
registryImdg.update(rgs);
assets.searchMoneyByAccAndCompany(rgs.getCompanyId(), rgs.getAccountId())
.ifPresentOrElse(
astTrio -> assets.process(astTrio.a__b(),
astTrio.a__t(),
astTrio.a__f(),
BigDecimal.ZERO),
() -> log.error("RegistryChangeStatusExtractRequest rgs.id={} assets not found", rgs.getId()));
return reqHelp.success(req.getId());
}
private AssetOperationListRequest gtwReq(Registry rgs) {
AssetOperationRequest item = GatewayRequestCreator.from(rgs, InOutDirection.in);
AssetOperationListRequest gtwReq = new AssetOperationListRequest();
gtwReq.setAssetOperationRequests(Collections.singletonList(item));
return gtwReq;
}
public RequestInfoUpdate identificationFunds(BaseRequest<IdentificationFundsRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
IdentificationFundsRequest payload = req.getRequestPayload();
IValidator validator = identificationFundsVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("IdentificationFundsRequest.id={} validation error: {}",
req.getId(),
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
Registry dmau = validator.getStored(Stored.PresentById);
AnltSearcher.AnltSearch accCompTcr = validator.getStored(ValidationStored.IdentificationFundsTcrSearch);
AssetTrio asts = validator.getStored(ValidationStored.IdentificationFundsAssetTrio);
Account anltAcc = validator.getStored(Stored.AnltAccount);
BigDecimal dmauBalance = safeBD(dmau.getBalance());
BigDecimal dmauDebitBalance = safeBD(dmau.getDebit());
BigDecimal reqBalance = payload.getBalance();
BigDecimal am_tBalance = safeBD(asts.a__t().getBalance());
BigDecimal am_tCreditBalance = safeBD(asts.a__t().getCredit());
dmau.setBalance(dmauBalance.subtract(reqBalance));
dmau.setDebit(dmauDebitBalance.add(reqBalance));
asts.a__t().setBalance(am_tBalance.add(reqBalance));
asts.a__t().setCredit(am_tCreditBalance.add(reqBalance));
Instant now = Instant.now();
dmau.setUpdated(now);
asts.a__t().setUpdated(now);
//paymentInstruction
PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider)
.registry(asts.a__b())
.sender(Sender.One.getId())
.addressee(accCompTcr.getCompany().getId())
.debitLegAccount(accCompTcr.getAccount())
.creditLegAccount(anltAcc)
.amount(payload.getBalance())
.sessionId(null)
.purpose("purpose")
.build();
pmt.setTransactionStatus(TransactionStatus.ok.getKey());
pmtImdg.insert(pmt);
registryImdg.update(dmau);
registryImdg.update(asts.a__t());
assets.process(asts.a__b(), asts.a__t(), asts.a__f(), BigDecimal.ZERO);
log.debug("IdentificationFundsRequest.id={} dmau.id={} am*t.id={} payment_instruction.id={}",
req.getId(), dmau.getId(), asts.a__t().getId(), pmt.getId());
if (trdTime.isTradingTime()) {
log.trace("sending gateway request for IdentificationFundsRequest.id={} dmau.id={}",
req.getId(), dmau.getId());
kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION,
gatewayRequest(dmau, payload.getBalance(),
accCompTcr.getCompany().getTradingCode(),
asts.a__t().getTradingClearingRegistry()));
}
return reqHelp.success(req.getId()); return reqHelp.success(req.getId());
} }
@ -415,14 +229,8 @@ public class RegistryService {
if (moneyPredicate.isEmpty() && depoPredicate.isEmpty()) { if (moneyPredicate.isEmpty() && depoPredicate.isEmpty()) {
return Optional.empty(); 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( return Optional.ofNullable(prdBldr.and(
accIdPrdct, prdBldr.or(moneyPredicate.orElse(prdBldr.alwaysTrue()), depoPredicate.orElse(prdBldr.alwaysTrue())),
prdBldr.equals("companyId", companyId), prdBldr.equals("companyId", companyId),
prdBldr.sql("tradingClearingRegistryId == null") prdBldr.sql("tradingClearingRegistryId == null")
)); ));
@ -447,70 +255,56 @@ 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() { public void resetBalances() {
Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of( Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of(
"registryDesignation", RegistryDesignation.A.getKey()) "registryDesignation", RegistryDesignation.A.getKey())
); );
Map<RgsKey, List<Registry>> allAssets = registriesA for (Registry registry : registriesA) {
.stream() if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) {
.collect(Collectors.groupingBy(RgsKey::fromRgs)); 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());
}
Instant timestamp = Instant.now(); registry.setDebit(BigDecimal.ZERO);
for (Map.Entry<RgsKey, List<Registry>> entry : allAssets.entrySet()) { registry.setSettledDebit(BigDecimal.ZERO);
RgsKey key = entry.getKey(); registry.setCredit(BigDecimal.ZERO);
List<Registry> group = entry.getValue(); registry.setSettledCredit(BigDecimal.ZERO);
Registry a__f = find(group, RegistryTradingParams.A__F).orElse(null); registry.setPlanBalance(BigDecimal.ZERO);
Registry a__t = find(group, RegistryTradingParams.A__T).orElse(null); registry.setCloseBalance(registry.getBalance());
Registry a__b = find(group, RegistryTradingParams.A__B).orElse(null);
if (a__t == null) { registry.setUpdated(Instant.now());
log.warn("registry group {}: no A**T registry found.", key); registryImdg.update(registry);
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);
} }
} }
@ -521,7 +315,6 @@ public class RegistryService {
return roleCheck; return roleCheck;
} }
Collection<Registry> baseRegistrys; Collection<Registry> baseRegistrys;
Integer index;
{ {
IValidator validator = splitDepositActionVal.apply(requestPayload); IValidator validator = splitDepositActionVal.apply(requestPayload);
Optional<EnumMessage> err = validator.tillFirstError(); Optional<EnumMessage> err = validator.tillFirstError();
@ -532,8 +325,6 @@ public class RegistryService {
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get())); return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
} }
baseRegistrys = validator.getStored(ValidationStored.RegistrysByContract); baseRegistrys = validator.getStored(ValidationStored.RegistrysByContract);
index = validator.getStored(ValidationStored.SplitDepositMaxNumber);
if (index == null) index = 0;
} }
ImdgTransaction txCtx = imdgProvider.newTransaction(); ImdgTransaction txCtx = imdgProvider.newTransaction();
@ -550,13 +341,6 @@ public class RegistryService {
log.debug("Process {} for {} registry", direction, baseRegistrys.size()); log.debug("Process {} for {} registry", direction, baseRegistrys.size());
Long groupId = null; Long groupId = null;
for (Registry baseRegistry : baseRegistrys) { 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()); log.trace("Registry[{}], groupId={}, ClearingCode={}", baseRegistry.getId(), baseRegistry.getGroupId(), baseRegistry.getClearingCode());
if (groupId == null) if (groupId == null)
groupId = baseRegistry.getGroupId(); groupId = baseRegistry.getGroupId();
@ -575,9 +359,9 @@ public class RegistryService {
} else { } else {
log.warn("Direction not set, do not change Balance"); log.warn("Direction not set, do not change Balance");
} }
firstRegistry.setContract(cntrctWithoutTilda + "~" + (index + 1)); firstRegistry.setContract(baseRegistry.getContract() + "~1");
firstRegistry.setParentId(baseRegistry.getId());
registryTMap.insert(firstRegistry); registryTMap.insert(firstRegistry);
// 2. Вторая группа // 2. Вторая группа
Registry secondRegistry = null; Registry secondRegistry = null;
if (InOutDirection.out == direction) { if (InOutDirection.out == direction) {
@ -586,10 +370,9 @@ public class RegistryService {
secondRegistry.setCreated(now); secondRegistry.setCreated(now);
secondRegistry.setUpdated(null); secondRegistry.setUpdated(null);
secondRegistry.setBalance(requestPayload.getOutboundAmount()); secondRegistry.setBalance(requestPayload.getOutboundAmount());
secondRegistry.setContract(cntrctWithoutTilda + "~" + (index + 2)); secondRegistry.setContract(baseRegistry.getContract() + "~2");
secondRegistry.setRefundDate(requestPayload.getRefundDate()); secondRegistry.setRefundDate(requestPayload.getRefundDate());
secondRegistry.setSettlementDate(requestPayload.getRefundDate()); secondRegistry.setSettlementDate(requestPayload.getRefundDate());
secondRegistry.setParentId(baseRegistry.getId());
registryTMap.insert(secondRegistry); registryTMap.insert(secondRegistry);
} }
@ -617,16 +400,4 @@ public class RegistryService {
return new RequestInfoUpdate(req.getId(), Status.Success, null); return new RequestInfoUpdate(req.getId(), Status.Success, null);
} }
private AssetOperationListRequest gatewayRequest(Registry dmau, BigDecimal balance, String tradingCode, String tcrCode) {
AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
AssetOperationRequest req = GatewayRequestCreator.from(
dmau.getId(),
null,
balance,
InOutDirection.in,
tradingCode,
tcrCode);
gatewayRequest.setAssetOperationRequests(List.of(req));
return gatewayRequest;
}
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,34 +11,29 @@ import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.execution.ExecutionFond; 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.Listing;
import ru.clearing.classes.statics.data.misc.STrades; import ru.clearing.classes.statics.data.misc.STrades;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.security.Security; 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.ClearingError;
import ru.spcex.clearing.error.ClearingException; import ru.spcex.clearing.error.ClearingException;
import ru.spcex.clearing.imdg.IMDGDistributedNames; 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.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DealRegisterNewRequest; 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.domain.cud.registry.ExecutionType;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.Side;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; 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.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.*; import ru.spcex.platform.utils.enumeration.*;
import ru.spcex.platform.utils.log.ExceptionUtils; import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.time.TimeUtil; import ru.spcex.platform.utils.time.TimeUtil;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Collection; import java.util.Collection;
@ -46,8 +41,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Component @Component
@EnableScheduling @EnableScheduling
public class ExecutionFondComponent { public class ExecutionFondComponent {
@ -57,7 +50,6 @@ public class ExecutionFondComponent {
private final Imdg<ExecutionFond> executionFondImdg; private final Imdg<ExecutionFond> executionFondImdg;
private final Imdg<Listing> listingImdg; private final Imdg<Listing> listingImdg;
private final Imdg<ClientCode> clientCodeImdg; private final Imdg<ClientCode> clientCodeImdg;
private final Imdg<FixedIncomeCashFlow> fixedIncomeCashFlowImdg;
private final Imdg<ru.clearing.classes.statics.data.misc.Market> marketImdg; private final Imdg<ru.clearing.classes.statics.data.misc.Market> marketImdg;
//fixme ждать ТЗ //fixme ждать ТЗ
@ -66,26 +58,19 @@ public class ExecutionFondComponent {
private final IMessageResolver msgResolver = new SimpleMessageResolver(); private final IMessageResolver msgResolver = new SimpleMessageResolver();
private final Function<STrades, IValidator> stradesValidator; private final Function<STrades, IValidator> stradesValidator;
private final KafkaSender kafkaSender; private final KafkaSender kafkaSender;
private final NotificationSender notifications;
private final boolean valuation;
@Autowired @Autowired
public ExecutionFondComponent(ImdgProvider imdgProvider, public ExecutionFondComponent(ImdgProvider imdgProvider, Producer<String, Object> kafka,
ClearingServiceSettings settings,
Producer<String, Object> kafka,
@Qualifier("sTradesValidatorFond") Function<STrades, IValidator> stradesValidator, @Qualifier("sTradesValidatorFond") Function<STrades, IValidator> stradesValidator,
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender, NotificationSender notifications) { @Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafkaSender) {
this.sTradeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class); this.sTradeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class);
this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
this.clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.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.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.stradesValidator = stradesValidator;
this.kafkaSender = kafkaSender; this.kafkaSender = kafkaSender;
this.notifications = notifications;
resetTradingDay(); resetTradingDay();
} }
@ -134,7 +119,7 @@ public class ExecutionFondComponent {
log.info("{} strades left after already-added filtering", sTrades.size()); log.info("{} strades left after already-added filtering", sTrades.size());
for (STrades sTrd : sTrades) { for (STrades sTrd : sTrades) {
log.info("new S_TRADE[{}], valuation {}", sTrd.getId(), valuation); log.trace("S_TRADE[{}] new", sTrd.getId());
//проверки //проверки
IValidator validator = stradesValidator.apply(sTrd); IValidator validator = stradesValidator.apply(sTrd);
@ -180,7 +165,6 @@ public class ExecutionFondComponent {
protected ExecutionFond createExecutionFond(STrades sTrades, protected ExecutionFond createExecutionFond(STrades sTrades,
IValidator validator) throws ClearingException { IValidator validator) throws ClearingException {
Security security = validator.getStored(ValidationStored.STradesSecurity); Security security = validator.getStored(ValidationStored.STradesSecurity);
// Listing listing = listingImdg.getFirstObjectByFieldValues(Map.of("securityId", security.getId()));
Company company = validator.getStored(ValidationStored.STradesCompany); Company company = validator.getStored(ValidationStored.STradesCompany);
Company counterCompany = validator.getStored(ValidationStored.STradesCounterCompany); Company counterCompany = validator.getStored(ValidationStored.STradesCounterCompany);
TradingClearingRegistry rgstr = validator.getStored(ValidationStored.STradesTradingClearingRegistry); TradingClearingRegistry rgstr = validator.getStored(ValidationStored.STradesTradingClearingRegistry);
@ -228,57 +212,7 @@ public class ExecutionFondComponent {
eFond.setSecurityId(security.getId()); eFond.setSecurityId(security.getId());
eFond.setInterestAmount(sTrades.getAccruedint()); eFond.setInterestAmount(sTrades.getAccruedint());
eFond.setExchangeOrderId(sTrades.getOrderNum()); eFond.setExchangeOrderId(sTrades.getOrderNum());
if (valuation) { eFond.setSettlementAmount(sTrades.getValue());
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()); eFond.setCounterPartyId(counterCompany.getId());
{ {
ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder(); ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder();

View file

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

View file

@ -41,7 +41,9 @@ import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
@Service @Service
@ -110,9 +112,7 @@ public class Sdf01Executor extends AbstractExecutor<SDf01> {
result.setChildGenerationId(generationIdForGroup); result.setChildGenerationId(generationIdForGroup);
result.setFileName(filenameObtainer.getFilename(sdf, sdf01Imdg, statementRequest.getGroupId())); 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)); log.info("SDF01 execution: sdf01 file={} number={}, groupId={}", result.getFileName(), sdf.size(), sdf.stream().findFirst().map(SDf01::getGenerationId).orElse(null));
ArrayList<SDf01> orderedSdf = new ArrayList<>(sdf); for (SDf01 sdf01 : sdf) {
orderedSdf.sort(Comparator.comparing(SDf01::getId));// Сортировка по возрастанию id, чтобы сохранить последовательность строк SDF02, как в SDF01
for (SDf01 sdf01 : orderedSdf) {
IValidator validator = sDf01Validator.apply(sdf01); IValidator validator = sDf01Validator.apply(sdf01);
Optional<EnumMessage> error = validator.tillFirstError(); Optional<EnumMessage> error = validator.tillFirstError();
Company company = validator.getStored(ValidationStored.Sdf01Company); Company company = validator.getStored(ValidationStored.Sdf01Company);

View file

@ -22,9 +22,7 @@ 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.AssetOperationApprovalRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse; import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; 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.integration.GatewayRequestCreator;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.registry.DmiService; import ru.spcex.clearing.service.registry.DmiService;
import ru.spcex.clearing.service.schedule.TradingTimeService; import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.Sdf06NewValidationRule; import ru.spcex.clearing.service.validation.Sdf06NewValidationRule;
@ -68,7 +66,6 @@ public class Sdf06Executor {
private final KafkaSender kafkaSender; private final KafkaSender kafkaSender;
private final FilenameObtainer filenameObtainer; private final FilenameObtainer filenameObtainer;
private final DmiService dmiService; private final DmiService dmiService;
private final AssetTBFProcessing assets;
private final static BigDecimal successResult = BigDecimal.ZERO; private final static BigDecimal successResult = BigDecimal.ZERO;
//идет сессия (не возвращаем такую ошибку) //идет сессия (не возвращаем такую ошибку)
@ -90,7 +87,7 @@ public class Sdf06Executor {
public Sdf06Executor(ImdgProvider imdgProvider, public Sdf06Executor(ImdgProvider imdgProvider,
IMessageResolver messageResolver, IMessageResolver messageResolver,
@Qualifier("sdf06ValidatorNew") Function<SDf06, IValidator> sDf06Validator, @Qualifier("sdf06ValidatorNew") Function<SDf06, IValidator> sDf06Validator,
TradingTimeService tradingTimeService, KafkaSender kafkaSender, FilenameObtainer filenameObtainer, DmiService dmiService, AssetTBFProcessing assets) { TradingTimeService tradingTimeService, KafkaSender kafkaSender, FilenameObtainer filenameObtainer, DmiService dmiService) {
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.tradingTimeService = tradingTimeService; this.tradingTimeService = tradingTimeService;
@ -105,7 +102,6 @@ public class Sdf06Executor {
this.sdf07Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf07, SDf07.class); this.sdf07Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf07, SDf07.class);
this.filenameObtainer = filenameObtainer; this.filenameObtainer = filenameObtainer;
this.dmiService = dmiService; this.dmiService = dmiService;
this.assets = assets;
} }
public void execute(BaseRequest<StatementRequest> systemRequest) { public void execute(BaseRequest<StatementRequest> systemRequest) {
@ -156,16 +152,14 @@ public class Sdf06Executor {
statementImdg.insert(stmt); statementImdg.insert(stmt);
log.debug("Statement created: {}", stmt.getId()); log.debug("Statement created: {}", stmt.getId());
if (InOutDirection.out.getKey().equals(stmt.getInOutDirection()) && tradingTimeService.isTradingTime()) { if (InOutDirection.out.getKey().equals(stmt.getInOutDirection()) && tradingTimeService.isTradingTime()) {
requests.add(GatewayRequestCreator.from(stmt, company.getTradingCode(), tcr.getCode())); requests.add(GatewayRequestCreator.gatewayRequestPart(stmt, company.getTradingCode(), tcr.getCode()));
} else { } else {
processedApproved(stmt, sDf06, now, sdf07GroupId); processedApproved(stmt, sDf06, now, sdf07GroupId);
if (tcr != null) { if (tcr != null) {
dmiService.setProcContract(tcr.getId(), dmiService.setProc(tcr.getId(),
CurrencyCode.RUB.getKey(), CurrencyCode.RUB.getKey(),
safeBD(sDf06.getSum()), safeBD(sDf06.getSum()),
sDf06.getNumber().toString()); 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; sdf07WasCreated = true;
} }
@ -217,9 +211,6 @@ public class Sdf06Executor {
if (ClearingError.WrongField.equals(err.getSubject())) { if (ClearingError.WrongField.equals(err.getSubject())) {
result = errorResult4; result = errorResult4;
} }
if (ClearingError.ActiveSessionIsPresent.equals(err.getSubject())) {
result = errorResult1;
}
if (result == null) { if (result == null) {
result = errorResult4; result = errorResult4;
} }
@ -272,16 +263,11 @@ public class Sdf06Executor {
Instant updatedTime = Instant.now(); Instant updatedTime = Instant.now();
if (gatewayMsg.isApproved()) { if (gatewayMsg.isApproved()) {
processedApproved(stmt, sdf06, updatedTime); processedApproved(stmt, sdf06, updatedTime);
Optional<TradingClearingRegistry> tcr = searchTcrOnGatewayResponse(sdf06); dmiService.setProc(searchTcrOnGatewayResponse(sdf06).map(SpcexObjectBase::getId).orElse(null),
dmiService.setProcContract(tcr.map(SpcexObjectBase::getId).orElse(null),
CurrencyCode.RUB.getKey(), CurrencyCode.RUB.getKey(),
safeBD(sdf06.getSum()), safeBD(sdf06.getSum()),
sdf06.getNumber().toString() 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 { } else {
log.trace("statement.id={}, sdf07.id={}, sdf06.id={} rejected (by gateway answer)", log.trace("statement.id={}, sdf07.id={}, sdf06.id={} rejected (by gateway answer)",
statementId, statementId,

View file

@ -346,7 +346,6 @@ public class Sdf08Executor extends AbstractExecutor<SDf08> {
rgs.setCredit(BigDecimal.ZERO); rgs.setCredit(BigDecimal.ZERO);
rgs.setDiffBalance(BigDecimal.ZERO); rgs.setDiffBalance(BigDecimal.ZERO);
rgs.setCheckBalance(BigDecimal.ZERO); rgs.setCheckBalance(BigDecimal.ZERO);
rgs.setOpenBalance(BigDecimal.ZERO);
rgs.setBalanceDimension(BalanceDimension.MONY.getKey()); rgs.setBalanceDimension(BalanceDimension.MONY.getKey());
rgs.setTradingDate(statement.getSettlementDate()); rgs.setTradingDate(statement.getSettlementDate());
rgs.setClearingDate(LocalDate.now()); rgs.setClearingDate(LocalDate.now());

View file

@ -25,7 +25,6 @@ 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.gateway.SingleAssetResponse;
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest; import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; 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.registry.RegistryManager;
import ru.spcex.clearing.service.schedule.TradingTimeService; import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.clearing.service.validation.ValidationStored;
@ -69,7 +68,6 @@ public class Sdf10Executor {
private final TradingTimeService tradingTimeService; private final TradingTimeService tradingTimeService;
private final KafkaSender kafkaSender; private final KafkaSender kafkaSender;
private final SecuritySelector<Security> scrtSlct; private final SecuritySelector<Security> scrtSlct;
private final AssetTBFProcessing assets;
private final static String OK = "OK"; private final static String OK = "OK";
private final static String SYNTAX_ERROR = "Синтаксическая ошибка (файл сформирован неверно)"; private final static String SYNTAX_ERROR = "Синтаксическая ошибка (файл сформирован неверно)";
@ -90,7 +88,7 @@ public class Sdf10Executor {
public Sdf10Executor(ImdgProvider imdgProvider, public Sdf10Executor(ImdgProvider imdgProvider,
RegistryManager rgsMng, IMessageResolver messageResolver, RegistryManager rgsMng, IMessageResolver messageResolver,
@Qualifier("sdf10Validator") Function<SDf10, IValidator> sDf10Validator, @Qualifier("sdf10Validator") Function<SDf10, IValidator> sDf10Validator,
TradingTimeService tradingTimeService, KafkaSender kafkaSender, AssetTBFProcessing assets) { TradingTimeService tradingTimeService, KafkaSender kafkaSender) {
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
@ -104,7 +102,6 @@ public class Sdf10Executor {
this.sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class); this.sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class);
this.plannerAllTodayImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class); this.plannerAllTodayImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class);
this.scrtSlct = new SecuritySelector<>(imdgProvider, Security.class); this.scrtSlct = new SecuritySelector<>(imdgProvider, Security.class);
this.assets = assets;
} }
public void execute(BaseRequest<StatementRequest> systemRequest) { public void execute(BaseRequest<StatementRequest> systemRequest) {
@ -169,11 +166,7 @@ public class Sdf10Executor {
SDf11 sDf11 = processedApproved(stmt, sDf10, now, sdf11GroupId); SDf11 sDf11 = processedApproved(stmt, sDf10, now, sdf11GroupId);
BigDecimal amount = InOutDirection.in.equalsByKey(stmt.getInOutDirection()) ? BigDecimal amount = InOutDirection.in.equalsByKey(stmt.getInOutDirection()) ?
stmt.getAmount() : safeBD(stmt.getAmount()).negate(); stmt.getAmount() : safeBD(stmt.getAmount()).negate();
createDs_iWithoutGateway(tcr.getId(), createDs_iWithoutGateway(tcr.getId(), company.getId(), security.getSecuritySymbol(), amount, sDf10.getOutDocument());
company.getId(),
security.getSecuritySymbol(),
amount,
sDf10.getOutDocument());
sdf11WasCreated = true; sdf11WasCreated = true;
} }
} }
@ -197,7 +190,6 @@ public class Sdf10Executor {
return; return;
} }
createDs_i(as_t.get(), summ, outDocument); 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) { private void createDs_iWithoutGateway(Long tcrId, Long companyId, String securitySymobl, BigDecimal summ, String outDocument) {
@ -211,19 +203,19 @@ public class Sdf10Executor {
return; return;
} }
createDs_i(as_t.get(), summ, outDocument); 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) { private void createDs_i(Registry as_t, BigDecimal summ, String outDocument) {
Registry rgsD = as_t.clone(); Registry rgsD = as_t.clone();
RegistryManager.zeroState(rgsD);
rgsD.setRegistryDesignation(RegistryDesignation.D.getKey()); rgsD.setRegistryDesignation(RegistryDesignation.D.getKey());
rgsD.setRegistryUnit(RegistryUnit.I.getKey()); rgsD.setRegistryUnit(RegistryUnit.I.getKey());
rgsD.setRegistryCode(RegistryUtil.clearingCode(rgsD)); rgsD.setRegistryCode(RegistryUtil.clearingCode(rgsD));
rgsD.setBalance(summ); 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.setRegistryStatus(RegistryStatus.PROC.getKey());
rgsD.setOpenBalance(BigDecimal.ZERO);
rgsD.setCloseBalance(BigDecimal.ZERO);
rgsD.setContract(outDocument); rgsD.setContract(outDocument);
registryImdg.insert(rgsD); registryImdg.insert(rgsD);
log.debug("created DS*I.id={}", rgsD.getId()); log.debug("created DS*I.id={}", rgsD.getId());

View file

@ -195,7 +195,7 @@ public class Sdf20Executor {
Long securityId) { Long securityId) {
Statement stmt = new Statement(); Statement stmt = new Statement();
stmt.setAddresseeId(companyId); stmt.setAddresseeId(companyId);
stmt.setSenderId(Sender.Rdc.getId()); stmt.setSenderId(Sender.Prc.getId());
stmt.setStatementType(StatementType.incr.getKey()); stmt.setStatementType(StatementType.incr.getKey());
//fixme stmt.setComment(sdf10.()); //fixme stmt.setComment(sdf10.());
stmt.setAccountId(account.getId()); stmt.setAccountId(account.getId());

View file

@ -137,11 +137,11 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
result.setChildGenerationId(generationIdForGroup); result.setChildGenerationId(generationIdForGroup);
log.info("SDF21 execution: sdf21 number={}, groupId={}", sdf.size(), sdf.stream().findFirst().map(SDf21::getGenerationId).orElse(null)); log.info("SDF21 execution: sdf21 number={}, groupId={}", sdf.size(), sdf.stream().findFirst().map(SDf21::getGenerationId).orElse(null));
for (SDf21 sdf21 : sdf) { for (SDf21 sdf21 : sdf) {
//LocalDate opDt = operationDateParse(sdf21.getOperationDate()); LocalDate opDt = operationDateParse(sdf21.getOperationDate());
//if (opDt == null || !opDt.equals(LocalDate.now())) { if (opDt == null || !opDt.equals(LocalDate.now())) {
// log.debug("skip sdf21.id={}, operation date {}", sdf21.getId(), sdf21.getOperationDate()); log.debug("skip sdf21.id={}, operation date {}", sdf21.getId(), sdf21.getOperationDate());
// continue; continue;
//} }
IValidator validator = sDf21Validator.apply(sdf21); IValidator validator = sDf21Validator.apply(sdf21);
Optional<EnumMessage> error = validator.tillFirstError(); Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) { if (error.isPresent()) {
@ -260,7 +260,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
private Statement create(SDf21 sdf21, Company cmp, Account acc) { private Statement create(SDf21 sdf21, Company cmp, Account acc) {
Statement statement = new Statement(); Statement statement = new Statement();
statement.setAddresseeId(cmp.getId()); statement.setAddresseeId(cmp.getId());
statement.setSenderId(Sender.Rdc.getId()); statement.setSenderId(Sender.Prc.getId());
statement.setStatementType(StatementType.incr.getKey()); statement.setStatementType(StatementType.incr.getKey());
//fixme statement.setComment(sdf21.()); //fixme statement.setComment(sdf21.());
statement.setAccountId(acc.getId()); statement.setAccountId(acc.getId());

View file

@ -50,7 +50,7 @@ public class Sdf55Executor {
this.assets = assets; this.assets = assets;
} }
public synchronized void execute(BaseRequest<StatementRequest> systemRequest) { public void execute(BaseRequest<StatementRequest> systemRequest) {
StatementRequest payload = systemRequest.getRequestPayload(); StatementRequest payload = systemRequest.getRequestPayload();
log.debug("executing {}.generationId={}", payload.getTable(), payload.getGroupId()); log.debug("executing {}.generationId={}", payload.getTable(), payload.getGroupId());
IValidator validator = validation.apply(payload); IValidator validator = validation.apply(payload);
@ -68,10 +68,12 @@ public class Sdf55Executor {
pmt.setTransactionStatus(TransactionStatus.ok.getKey()); pmt.setTransactionStatus(TransactionStatus.ok.getKey());
pmt.setUpdated(Instant.now()); pmt.setUpdated(Instant.now());
pmtImdg.update(pmt); pmtImdg.update(pmt);
dmiService.setContract(tcr.getId(), CurrencyCode.RUB.getKey(), sDf54.getDocnm_ref(), sDf55.getDocnmprev()); if (tcr != null) {
assets.process(assetTrio.a__b(), dmiService.setOk(tcr.getId(), CurrencyCode.RUB.getKey(), sDf54.getDocnm_ref());
assetTrio.a__t(), assets.process(assetTrio.a__b(),
assetTrio.a__f(), assetTrio.a__t(),
BigDecimal.ZERO); assetTrio.a__f(),
BigDecimal.ZERO);
}
} }
} }

View file

@ -19,15 +19,12 @@ import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.classes.statics.data.statement.Statement; import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; 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.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest; 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.AssetOperationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.AnltSearcher; import ru.spcex.clearing.service.AnltSearcher;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.LoggingService; import ru.spcex.clearing.service.LoggingService;
import ru.spcex.clearing.service.builder.RegistryBuilder; import ru.spcex.clearing.service.builder.RegistryBuilder;
import ru.spcex.clearing.service.integration.GatewayRequestCreator; import ru.spcex.clearing.service.integration.GatewayRequestCreator;
@ -48,7 +45,6 @@ import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.enumeration.IMessageResolver; 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.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
@ -63,11 +59,9 @@ import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static ru.spcex.platform.enumeration.RegistryTradingParams.D__V; import static ru.spcex.platform.enumeration.RegistryTradingParams.D__V;
import static ru.spcex.platform.enumeration.RegistryTradingParams.OM_T;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service @Service
@ -96,14 +90,13 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
private final TradingTimeService timeService; private final TradingTimeService timeService;
private final KafkaSender kafka; private final KafkaSender kafka;
private final AssetTBFProcessing assets; private final AssetTBFProcessing assets;
private final NotificationSender notification;
private final Pattern pattern = Pattern.compile("№.*"); private final Pattern pattern = Pattern.compile("№.*");
public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator, public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator,
LoggingService errorLogger, LoggingService errorLogger,
ImdgProvider imdgProvider, ImdgProvider imdgProvider,
IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver, DmiService dmiService, TradingTimeService timeService, IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver, DmiService dmiService, TradingTimeService timeService,
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets, NotificationSender notification) { @Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets) {
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
@ -125,7 +118,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
this.timeService = timeService; this.timeService = timeService;
this.kafka = kafka; this.kafka = kafka;
this.assets = assets; this.assets = assets;
this.notification = notification;
} }
//todo доделать контроль sdf01 и sdf57 //todo доделать контроль sdf01 и sdf57
@ -168,10 +160,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId(); Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId();
result.setChildGenerationId(generationIdForGroup); result.setChildGenerationId(generationIdForGroup);
log.info("SDF57 execution: sdf57 number={}, groupId={}", sdf.size(), sdf.stream().findFirst().map(SDf57::getGenerationId).orElse(null)); 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) { for (SDf57 sdf57 : sdf) {
IValidator validator = sDf57Validator.apply(sdf57); IValidator validator = sDf57Validator.apply(sdf57);
Optional<EnumMessage> error = validator.tillFirstError(); Optional<EnumMessage> error = validator.tillFirstError();
@ -209,7 +197,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
statementDeb.map(SpcexObjectBase::getId).orElse(null), statementDeb.map(SpcexObjectBase::getId).orElse(null),
statementCred.map(SpcexObjectBase::getId).orElse(null)); statementCred.map(SpcexObjectBase::getId).orElse(null));
Function<StmtCmpAcc, Optional<AssetTrio>> createRegistryIfNeeded = stmtCmpAcc -> { Function<StmtCmpAcc, Optional<Long>> createRegistryIfNeeded = stmtCmpAcc -> {
Statement stmt = stmtCmpAcc.statement(); Statement stmt = stmtCmpAcc.statement();
Company company = stmtCmpAcc.company(); Company company = stmtCmpAcc.company();
Account account = stmtCmpAcc.account(); Account account = stmtCmpAcc.account();
@ -220,7 +208,8 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
.companyId(company.getId()) //раньше было stmt.getAddresseeId() .companyId(company.getId()) //раньше было stmt.getAddresseeId()
.accountId(account.getId()) //раньше было stmt.getAccountId() .accountId(account.getId()) //раньше было stmt.getAccountId()
.find(); .find();
AssetTrio asts = amtFound.map(rgs -> { AtomicReference<Registry> amtCached = new AtomicReference<>();
amtFound.ifPresentOrElse(rgs -> {
log.debug("stmt.id={}, found AM*T.id={}, updating...", stmt.getId(), rgs.getId()); log.debug("stmt.id={}, found AM*T.id={}, updating...", stmt.getId(), rgs.getId());
updateReg(stmt, rgs); updateReg(stmt, rgs);
//добавил создание если не найдены //добавил создание если не найдены
@ -250,8 +239,8 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
rgs.getBalance(), rgs.getBalance(),
rgs.getDebit(), rgs.getDebit(),
rgs.getCredit()); rgs.getCredit());
return new AssetTrio(registryUnitF, registryUnitB, rgs); amtCached.set(rgs);
}).orElseGet(() -> { }, () -> {
Registry registry = RegistryBuilder.builder(imdgProvider) Registry registry = RegistryBuilder.builder(imdgProvider)
.statement(stmt) .statement(stmt)
.company(company) .company(company)
@ -270,17 +259,17 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
registry.getId(), registry.getId(),
registryF.getId(), registryF.getId(),
registryB.getId()); registryB.getId());
return new AssetTrio(registryF, registryB, registry); amtCached.set(registry);
}); });
InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, stmt.getInOutDirection()); InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, stmt.getInOutDirection());
boolean dm_tWasCreated = false; boolean dm_tWasCreated = false;
if (!StringUtils.isEmpty(stmt.getContract()) && InOutDirection.in.equals(direction)) { if (!StringUtils.isEmpty(sdf57.getSpecif()) && pattern.matcher(sdf57.getSpecif()).find() && InOutDirection.in.equals(direction)) {
//todo доделать 11. Идентификация средств УК на клиринговом счете //todo доделать 11. Идентификация средств УК на клиринговом счете
//stmt.id=340270002, sdf57.specif=Возврат депозита по договору DT1000S001U/280623/8/7 new DM*T.id=339610032 //stmt.id=340270002, sdf57.specif=Возврат депозита по договору DT1000S001U/280623/8/7 new DM*T.id=339610032
//1. у stmt accountId 3021, addresseId 2610034, contract DT1000S001U/280623/8/7 //1. у stmt accountId 3021, addresseId 2610034, contract DT1000S001U/280623/8/7
// //
Optional<Registry> dm__Found = RegistrySearch.builder(registryImdg) Optional<Registry> dm__Found = RegistrySearch.builder(registryImdg)
.rgsCode(RegistryTradingParams.DM_T) .rgsCode(RegistryTradingParams.DM__)
.companyId(company.getId()) .companyId(company.getId())
.accountId(account.getId()) .accountId(account.getId())
.contract(stmt.getContract()) .contract(stmt.getContract())
@ -326,56 +315,29 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
sdf57.getSpecif(), sdf57.getSpecif(),
om_t.getId(), om_t.getId(),
registryD.getId()); registryD.getId());
sessionIsNeededFlag.set(true);
} else if (tm_tFound.isPresent()) { } else if (tm_tFound.isPresent()) {
Optional<Registry> dm_xFound = RegistrySearch.builder(registryImdg) Registry tm_t = tm_tFound.get();
.rgsCode(RegistryTradingParams.DM_X) Registry registryD = copyRegD(tm_t, stmt, RegistryUnit.X);
.companyId(company.getId()) registryImdg.insert(registryD);
.accountId(account.getId()) 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",
.contract(stmt.getContract()) stmt.getId(),
.statusNotOk() sdf57.getSpecif(),
.find(); tm_t.getId(),
if (dm_xFound.isEmpty()) { registryD.getId());
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()); stmt.setOperationStatus(OperationStatus.Executed.getKey());
statementImdg.update(stmt); statementImdg.update(stmt);
log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey()); log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey());
if (!dm_tWasCreated && timeService.isTradingTime() && InOutDirection.in.equalsByKey(stmt.getInOutDirection())) { if (!dm_tWasCreated && timeService.isTradingTime() && InOutDirection.in.equalsByKey(stmt.getInOutDirection())) {
if (TextUtil.isEmpty(asts.a__t().getTradingClearingRegistry())) { log.trace("sending gateway request for stmt.id={}", stmt.getId());
log.trace("stmt.id={} {}.id={} TCR is empty, skipping gateway request", kafka.sendRequestToQueue(Consts.ASSET_OPERATION,
stmt.getId(), asts.a__t().getRegistryCode(), asts.a__t().getId()); gatewayRequest(stmt,
} else { company.getTradingCode(),
log.trace("sending gateway request for stmt.id={}", stmt.getId()); amtCached.get().getTradingClearingRegistry()));
Optional<AssetOperationListRequest> gtwReq = gatewayRequest(stmt,
company,
account,
asts.a__t().getTradingClearingRegistry());
gtwReq.ifPresent(r -> kafka.sendRequestToQueue(Consts.ASSET_OPERATION, r));
}
} }
return Optional.of(asts); return Optional.ofNullable(amtCached.get().getTradingClearingRegistryId());
} else { } else {
log.debug("statement.id={} activness validation failed {}", stmt.getId(), messageResolver.resolve(err.get())); log.debug("statement.id={} activness validation failed {}", stmt.getId(), messageResolver.resolve(err.get()));
stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert
@ -388,7 +350,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
Statement stmt = stmtCmpAcc.statement(); Statement stmt = stmtCmpAcc.statement();
Company cmp = stmtCmpAcc.company(); Company cmp = stmtCmpAcc.company();
Account acc = stmtCmpAcc.account(); Account acc = stmtCmpAcc.account();
Optional<AssetTrio> asts = createRegistryIfNeeded.apply(stmtCmpAcc); Optional<Long> tcrId = createRegistryIfNeeded.apply(stmtCmpAcc);
if (accountIsAnlt(acc)) { if (accountIsAnlt(acc)) {
AnltSearcher.AnltSearch searchResult = anltSearcher.loadByAnlt(stmt.getComment()); AnltSearcher.AnltSearch searchResult = anltSearcher.loadByAnlt(stmt.getComment());
if (searchResult.isFound()) { if (searchResult.isFound()) {
@ -397,21 +359,13 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
stmt.getComment(), stmt.getComment(),
searchResult.getAccount().getId(), searchResult.getAccount().getId(),
searchResult.getCompany().getId()); searchResult.getCompany().getId());
asts = createRegistryIfNeeded.apply(new StmtCmpAcc(stmt, searchResult.getCompany(), searchResult.getAccount())); createRegistryIfNeeded.apply(new StmtCmpAcc(stmt, searchResult.getCompany(), searchResult.getAccount()));
if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) { if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) {
Optional<BigDecimal> dmiBalance = dmiService.setOk(searchResult.getTcr().getId(), dmiService.setOk(searchResult.getTcr().getId(),
CurrencyCode.RUB.getKey(), CurrencyCode.RUB.getKey(),
sdf57.getDbfId().toString()); sdf57.getDbfId().toString());
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()))) { } else {
log.debug("stmt.id={} comment='{}' error: {}. Operating through DMAU registry", log.debug("stmt.id={} comment='{}' error: {}. Operating through DMAU registry",
stmt.getId(), stmt.getId(),
stmt.getComment(), stmt.getComment(),
@ -442,18 +396,10 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
//DMAU подразумевает увеличение остатка поля balance и credit registry.code=DMAU //DMAU подразумевает увеличение остатка поля balance и credit registry.code=DMAU
} }
} else if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) { } else if (OperationStatus.Executed.equalsByKey(stmt.getOperationStatus())) {
if (asts.isPresent()) { if (tcrId.isPresent()) {
Optional<BigDecimal> dmiBalance = dmiService.setOk(asts.get().a__t().getTradingClearingRegistryId(), dmiService.setOk(tcrId.get(),
CurrencyCode.RUB.getKey(), CurrencyCode.RUB.getKey(),
sdf57.getDbfId().toString()); sdf57.getDbfId().toString());
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 { } else {
log.error("stmt.id={} operationStatus={} but couldn't extract TCR.id for DM*I update", log.error("stmt.id={} operationStatus={} but couldn't extract TCR.id for DM*I update",
stmt.getId(), stmt.getId(),
@ -464,18 +410,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
statementDeb.map(stmt -> new StmtCmpAcc(stmt, companyDeb, accountDeb)).ifPresent(registersUpdate); statementDeb.map(stmt -> new StmtCmpAcc(stmt, companyDeb, accountDeb)).ifPresent(registersUpdate);
statementCred.map(stmt -> new StmtCmpAcc(stmt, companyCred, accountCred)).ifPresent(registersUpdate); statementCred.map(stmt -> new StmtCmpAcc(stmt, companyCred, accountCred)).ifPresent(registersUpdate);
} }
if (sessionIsNeededFlag.get()) {
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; return result;
} }
@ -663,14 +597,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
return this; 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() { private Optional<Registry> find() {
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(predicate)); return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(predicate));
} }
@ -719,34 +645,31 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
return comment.replaceAll("\\s+", ""); return comment.replaceAll("\\s+", "");
} }
private String getContractFromSpecif(String specif) { private static String getContractFromSpecif(String specif) {
if (TextUtil.isEmpty(specif)) { if (specif == null) {
return null; return null;
} }
ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); int index = specif.indexOf("");
ImdgPredicate prdct = pb.and( if (index == -1) {
pb.sql(RegistryCodeSqlBuilder.getInstance(OM_T).build()), return null;
pb.or(
pb.equals("registryStatus", RegistryStatus.PROC.getKey()),
pb.equals("registryStatus", RegistryStatus.MNG.getKey())
),
pb.notNull("contract"),
pb.not(pb.equals("contract", ""))
);
String contract = registryImdg.getCollectionObjectsByPredicate(prdct)
.stream()
.filter(r -> r.getValueDate() != null)
.filter(r -> r.getRefundDate() != null)
.filter(r -> r.getValueDate().isBefore(r.getRefundDate()))
.map(Registry::getContract)
.filter(specif::contains)
.findFirst()
.orElse(null);
if (contract == null) {
log.warn("couldn't find match for specif {}", specif);
} }
return contract; StringBuilder buffer = new StringBuilder();
String afterN = specif.substring(index + 1);
int countSlashes = 0;
for(int i = 0; i < afterN.length(); i++) {
char c = afterN.charAt(i);
if (!Character.isWhitespace(c)) {
buffer.append(c);
if (c == '/') {
countSlashes++;
}
} else {
if (countSlashes == 3) {
break;
}
}
}
return buffer.toString();
} }
@FunctionalInterface @FunctionalInterface
@ -754,56 +677,25 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
R apply(T1 arg1, T2 arg2, T3 arg3); R apply(T1 arg1, T2 arg2, T3 arg3);
} }
private static final Pattern csBlkd = Pattern.compile(SpecifFlag.CS_BLKD.getKey() + "_(\\d+).*"); private AssetOperationListRequest gatewayRequest(Statement stmt, String tradingCode, String tcrCode) {
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(); AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
AssetOperationRequest req = GatewayRequestCreator.from(stmt, tradingCode, tcrCode); AssetOperationRequest req = GatewayRequestCreator.gatewayRequestPart(stmt, tradingCode, tcrCode);
String specif = stmt.getComment(); Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
"workflowStatus", SessionStatus.ACTV.getKey()
Matcher m; ));
if (!TextUtil.isEmpty(specif) && (m = csBlkd.matcher(specif)).find()) { if (existActiveSession != null) {
try { log.debug("active session.id={} type {}", existActiveSession.getId(), existActiveSession.getSessionType());
Long sessionId = Long.valueOf(m.group(1)); List<Registry> d__vs = assets.searchByParams(stmt.getAccount(), CurrencyCode.RUB.getKey(), stmt.getSenderId(), D__V)
List<Registry> d__vs = assets.searchByParams(account.getAccount(), CurrencyCode.RUB.getKey(), company.getId(), D__V) .stream()
.stream() .filter(rgs -> existActiveSession.getId().equals(rgs.getSessionId()))
.filter(rgs -> sessionId.equals(rgs.getSessionId())) .toList();
.toList(); BigDecimal d__vSum = d__vs.stream()
BigDecimal d__vSum = d__vs.stream() .map(rgs -> safeBD(rgs.getBalance()))
.map(rgs -> safeBD(rgs.getBalance())) .reduce(BigDecimal.ZERO, BigDecimal::add);
.reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal amount = req.getAmount();
BigDecimal amount = req.getAmount(); req.setAmount(safeBD(amount).subtract(d__vSum));
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)); gatewayRequest.setAssetOperationRequests(List.of(req));
return Optional.of(gatewayRequest); return gatewayRequest;
} }
} }

View file

@ -1,17 +1,14 @@
package ru.spcex.clearing.service.integration; package ru.spcex.clearing.service.integration;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.statement.Statement; import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
import ru.spcex.platform.enumeration.CurrencyCode; import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.InOutDirection; import ru.spcex.platform.enumeration.InOutDirection;
import ru.spcex.platform.utils.number.BigDecimalUtil;
import java.math.BigDecimal; import java.math.BigDecimal;
public class GatewayRequestCreator { public class GatewayRequestCreator {
public static AssetOperationRequest from(Statement stmt, String tradingCode, String tcrCode) { public static AssetOperationRequest gatewayRequestPart(Statement stmt, String tradingCode, String tcrCode) {
AssetOperationRequest req = new AssetOperationRequest(); AssetOperationRequest req = new AssetOperationRequest();
req.setEntityId(stmt.getId()); req.setEntityId(stmt.getId());
req.setAmount(stmt.getAmount()); req.setAmount(stmt.getAmount());
@ -22,34 +19,12 @@ public class GatewayRequestCreator {
return req; return req;
} }
public static AssetOperationRequest from(Registry rgs) { public static AssetOperationRequest gatewayRequestPart(Long entityId,
return from(rgs, InOutDirection.out); Long sessionId,
} BigDecimal amount,
InOutDirection direction,
public static AssetOperationRequest from(Registry rgs, InOutDirection dir) { String tradingCode,
return from(rgs.getId(), String tcrCode) {
null,
BigDecimalUtil.safeBD(rgs.getBalance()).abs(),
dir,
rgs.getTradingCode(),
rgs.getTradingClearingRegistry());
}
public static AssetOperationRequest from(PaymentInstruction pmt, String tradingCode, String tcr) {
return from(pmt.getId(),
null,
pmt.getCreditLeg_amount(),
InOutDirection.out,
tradingCode,
tcr);
}
public static AssetOperationRequest from(Long entityId,
Long sessionId,
BigDecimal amount,
InOutDirection direction,
String tradingCode,
String tcrCode) {
AssetOperationRequest req = new AssetOperationRequest(); AssetOperationRequest req = new AssetOperationRequest();
req.setSessionId(sessionId); req.setSessionId(sessionId);
req.setEntityId(entityId); req.setEntityId(entityId);

View file

@ -10,7 +10,6 @@ public class Result {
private Long childGenerationId; private Long childGenerationId;
private String fileName; private String fileName;
private boolean anyHasError; private boolean anyHasError;
private boolean sessionWasStarted = false;
public List<AccountSdfRequestPart> getAccountRequests() { public List<AccountSdfRequestPart> getAccountRequests() {
return accountRequests; return accountRequests;
@ -43,12 +42,4 @@ public class Result {
public void setAnyHasError(boolean anyHasError) { public void setAnyHasError(boolean anyHasError) {
this.anyHasError = anyHasError; this.anyHasError = anyHasError;
} }
public boolean isSessionWasStarted() {
return sessionWasStarted;
}
public void setSessionWasStarted(boolean sessionWasStarted) {
this.sessionWasStarted = sessionWasStarted;
}
} }

View file

@ -14,10 +14,8 @@ import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf54; import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; 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.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
@ -26,15 +24,14 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.AssetTrio; import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.service.Sdf54Creator; import ru.spcex.clearing.service.Sdf54Creator;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2; 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.AssetTBFProcessing;
import ru.spcex.clearing.service.registry.DmiService; import ru.spcex.clearing.service.registry.DmiService;
import ru.spcex.clearing.service.registry.RegistryManager; 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.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.TransactionStatus;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
@ -47,9 +44,7 @@ import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service @Service
@ -72,15 +67,12 @@ public class PaymentInstructionOutboundService {
private final KafkaSender kafkaSender; private final KafkaSender kafkaSender;
private final AssetTBFProcessing assetsMng; private final AssetTBFProcessing assetsMng;
private final DmiService dmiService; private final DmiService dmiService;
private final TradingTimeService time;
private final GatewayRequester gateway;
private final NotificationSender notification;
@Autowired @Autowired
public PaymentInstructionOutboundService(UserRoleVerification rights, public PaymentInstructionOutboundService(UserRoleVerification rights,
IMessageResolver msgs, IMessageResolver msgs,
ImdgProvider imdgProvider, ImdgProvider imdgProvider,
Function<PIClearingOutbondActionNewRequest, IValidator> validation, RegistryManager rgsMng, KafkaSender kafkaSender, AssetTBFProcessing assetsMng, DmiService dmiService, TradingTimeService time, GatewayRequester gateway, NotificationSender notification) { Function<PIClearingOutbondActionNewRequest, IValidator> validation, RegistryManager rgsMng, KafkaSender kafkaSender, AssetTBFProcessing assetsMng, DmiService dmiService) {
this.imdgProvider = imdgProvider; this.imdgProvider = imdgProvider;
this.rights = rights; this.rights = rights;
this.msgs = msgs; this.msgs = msgs;
@ -98,10 +90,6 @@ public class PaymentInstructionOutboundService {
this.kafkaSender = kafkaSender; this.kafkaSender = kafkaSender;
this.assetsMng = assetsMng; this.assetsMng = assetsMng;
this.dmiService = dmiService; this.dmiService = dmiService;
this.time = time;
this.gateway = gateway;
this.gateway.setName("PaymentInstructionOutboundService|PI");
this.notification = notification;
} }
public RequestInfoUpdate sendOutBoundPayment(BaseRequest<PIClearingOutbondActionNewRequest> req) { public RequestInfoUpdate sendOutBoundPayment(BaseRequest<PIClearingOutbondActionNewRequest> req) {
@ -118,20 +106,20 @@ public class PaymentInstructionOutboundService {
} }
Account accCred = validator.getStored(ValidationStored.PIOutboundAccountCred); Account accCred = validator.getStored(ValidationStored.PIOutboundAccountCred);
Account accDeb = validator.getStored(ValidationStored.PIOutboundAccountDeb); Account accDeb = validator.getStored(ValidationStored.PIOutboundAccountDeb);
Company addressee = validator.getStored(ValidationStored.PIOOutboundAddressee); Company addressee = cmpImdg.getSingleObjectByID(payload.getAddresseeId());
TradingClearingRegistry tcr = validator.getStored(ValidationStored.PIOutboundTcr);
Company sender = cmpImdg.getSingleObjectByID(payload.getSenderId()); Company sender = cmpImdg.getSingleObjectByID(payload.getSenderId());
BigDecimal amount = safeBD(payload.getCreditLeg_amount()); BigDecimal amount = safeBD(payload.getCreditLeg_amount());
log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}", log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}",
accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount); accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount);
String purpose = tcr != null ? "Возврат денежных средств, свободных от обязательств с ТКР " + tcr.getCode() + " ." : "Вывод средств."; TradingClearingRegistry tcr = tcrImdg.getFirstObjectBySQL("moneyAccountId = '%d' and companyId = %d"
.formatted(accCred.getId(), addressee.getId()));
String purpose = tcr != null ? "Вывод средств по ТКР " + tcr.getCode() + "." : "Вывод средств.";
if (payload.getPaymentPurpose() != null) { if (payload.getPaymentPurpose() != null) {
String reqPmtPrpse = payload.getPaymentPurpose(); purpose += " " + payload.getPaymentPurpose();
if (!(reqPmtPrpse.endsWith(".") || reqPmtPrpse.endsWith("!") || reqPmtPrpse.endsWith("?") || reqPmtPrpse.endsWith(";"))) { if (!(purpose.endsWith(".") || purpose.endsWith("!") || purpose.endsWith("?") || purpose.endsWith(";"))) {
reqPmtPrpse += "."; purpose += ".";
} }
purpose = reqPmtPrpse + " " + purpose;
} }
PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider) PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider)
.registry(new Registry()) .registry(new Registry())
@ -145,7 +133,7 @@ public class PaymentInstructionOutboundService {
.build(); .build();
BankAccount bnkAcc = bnkAccImdg.getFirstObjectBySQL("accountId = %d".formatted(accDeb.getId())); BankAccount bnkAcc = bnkAccImdg.getFirstObjectBySQL("accountId = %d".formatted(accDeb.getId()));
if (bnkAcc != null) { if (bnkAcc != null) {
pmt.setAddresseeBankName(bnkAcc.getBankName()); pmt.setAddresseeBankName(bnkAcc.getBankIdentificationCode());
pmt.setDebit_csAccount(bnkAcc.getCorrespondentAccount()); pmt.setDebit_csAccount(bnkAcc.getCorrespondentAccount());
} }
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey())); Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
@ -153,7 +141,7 @@ public class PaymentInstructionOutboundService {
pmt.setCreditLeg_securityId(currency.getId()); pmt.setCreditLeg_securityId(currency.getId());
pmt.setDebitLeg_securityId(currency.getId()); pmt.setDebitLeg_securityId(currency.getId());
} }
pmt.setTransactionStatus(TransactionStatus.stld.getKey()); pmt.setTransactionStatus(TransactionStatus.exec.getKey());
//fixme pmt.setDocumentNumber(registry.getSecurityId()); //fixme pmt.setDocumentNumber(registry.getSecurityId());
pmtImdg.insert(pmt); pmtImdg.insert(pmt);
@ -174,29 +162,12 @@ public class PaymentInstructionOutboundService {
sDf54.setGenerationId(pmt.getId()); sDf54.setGenerationId(pmt.getId());
sdf54Imdg.insert(sDf54); sdf54Imdg.insert(sDf54);
log.debug("new sdf54.id: {}", sDf54.getId()); log.debug("new sdf54.id: {}", sDf54.getId());
dmiService.setProcComment(tcr.getId(), if (tcr != null) {
CurrencyCode.RUB.getKey(), dmiService.setProc(tcr.getId(),
safeBD(amount).negate(), CurrencyCode.RUB.getKey(),
sDf54.getDocnm_ref()); safeBD(amount).negate(),
assetsMng.process(assets.get().a__b(), assets.get().a__t(), assets.get().a__f(), BigDecimal.ZERO); sDf54.getDocnm_ref());
if (time.isTradingTime()) { assetsMng.process(assets.get().a__b(), assets.get().a__t(), assets.get().a__f(), BigDecimal.ZERO);
Supplier<AssetOperationRequest> builder = () -> GatewayRequestCreator.from(pmt,
assets.get().a__b().getTradingCode(),
tcr.getCode());
Optional<Boolean> gatewayOk = gateway.gatewayRequestAndWait(builder);
if (gatewayOk.isEmpty() || gatewayOk.get().equals(Boolean.FALSE)) {
String gtwErrMsg = msgs.resolve(mapError(gatewayOk));
log.error("sdf54.id={} pmt.id={} {}", sDf54.getId(),
pmt.getId(),
gtwErrMsg);
notification.sendNotification(ObjectType.gateway,
gtwErrMsg,
Priority.HIGH);
pmt.setTransactionStatus(TransactionStatus.fail.getKey());
pmt.setUpdated(now);
pmtImdg.update(pmt);
return error(req.getId(), ClearingError.GeneralError);
}
} }
SdfClearingRequest exp = new SdfClearingRequest(); SdfClearingRequest exp = new SdfClearingRequest();
exp.setGroupId(sDf54.getGenerationId()); exp.setGroupId(sDf54.getGenerationId());

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