Merge branch 'refs/heads/dev' into dev_gitlab_cicd

This commit is contained in:
etreschenkov 2024-07-09 14:10:41 +03:00
commit 281fa4f5d6
349 changed files with 16378 additions and 6586 deletions

View file

@ -5,7 +5,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -1,5 +1,9 @@
package ru.spcex.clearing.account.config.validation;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
@ -7,9 +11,12 @@ import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.account.validation.BackendClientCodeValidationRule;
import ru.spcex.clearing.account.validation.GatewayClientCodeValidationRule;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
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.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
@ -17,18 +24,9 @@ import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
@Configuration
public class ClientCodeValidationConfig {
@ -41,86 +39,50 @@ public class ClientCodeValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistryList);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, AccountError.RequiredFieldEmpty),
IdPresentRule.instance("companyId",
ClientCodeNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound),
FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, AccountError.RequiredFieldEmpty),
IdPresentRule.instance("companyId",
ClientCodeNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound),
IdPresentRule.instance("moneyAccountId",
ClientCodeNewRequest::getMoneyAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
IdPresentRule.instance("depoAccountId",
ClientCodeNewRequest::getDepoAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
new ExistAllCurrencyAccountId<>("currencyAccountList",
ClientCodeNewRequest::getCurrencyAccountList
),
DictionaryPresentRule.instance("stauts",
ClientCodeNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
IdPresentRule.instance("moneyAccountId",
ClientCodeNewRequest::getMoneyAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
IdPresentRule.instance("depoAccountId",
ClientCodeNewRequest::getDepoAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
BackendClientCodeValidationRule.AllAccountsPresent,
BackendClientCodeValidationRule.TcrIsNotPresentByAccount,
DictionaryPresentRule.instance("status",
ClientCodeNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
);
};
}
public static class ExistAllCurrencyAccountId<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, List<Long>> idGetter;
public ExistAllCurrencyAccountId(String fieldName, Function<R, List<Long>> idGetter) {
this.fieldName = fieldName;
this.idGetter = idGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
List<Long> ids = idGetter.apply(validatedObject);
if (ids == null || ids.isEmpty()) {
return empty(); // необязательное поле
}
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
for (Long id:ids) {
if (id == null) { // null значения в массиве не ожидаются
return of(AccountError.RequiredFieldEmpty, fieldName);
}
Account byIdObject = imdg.getSingleObjectByID(id);
if (byIdObject == null)
return of(AccountError.AccountNotFound, id, fieldName);
}
return empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
@Bean("clientCodeUpdateRequestValidator")
public Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return clientCodeUpdateRequest -> {
@ -132,54 +94,51 @@ public class ClientCodeValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<ImdgValidationContext<ClientCodeUpdateRequest>>(context,
IdPresentRule.instance("id",
ClientCodeUpdateRequest::getId,
IMDGDistributedNames.Map_ClientCode,
ClientCode.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound
),
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
ClientCodeUpdateRequest::getId,
IMDGDistributedNames.Map_ClientCode,
ClientCode.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound
),
FieldRequiredRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, AccountError.RequiredFieldEmpty),
IdPresentRule.instance("companyId",
ClientCodeUpdateRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound),
FieldRequiredRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, AccountError.RequiredFieldEmpty),
IdPresentRule.instance("companyId",
ClientCodeUpdateRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound),
IdPresentRule.instance("moneyAccountId",
ClientCodeUpdateRequest::getMoneyAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
IdPresentRule.instance("depoAccountId",
ClientCodeUpdateRequest::getDepoAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
new ExistAllCurrencyAccountId<>("currencyAccountList",
ClientCodeUpdateRequest::getCurrencyAccountList
),
DictionaryPresentRule.instance("stauts",
ClientCodeUpdateRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
IdPresentRule.instance("moneyAccountId",
ClientCodeUpdateRequest::getMoneyAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
true,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
IdPresentRule.instance("depoAccountId",
ClientCodeUpdateRequest::getDepoAccountId,
IMDGDistributedNames.Map_Account,
Account.class,
AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound,
false,
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
? null : AccountError.AccountNotFound
),
BackendClientCodeValidationRule.AllAccountsPresent,
DictionaryPresentRule.instance("stauts",
ClientCodeUpdateRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
);
};
}
@ -192,14 +151,35 @@ public class ClientCodeValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_ClientCode);
return new ValidatorImpl<>(context,
// FieldRequiredRule.instance("id", CommonDeleteRequest::getId, CompanyErrors.RequiredFieldEmpty),
IdPresentRule.instance("id",
CommonDeleteRequest::getId,
IMDGDistributedNames.Map_ClientCode,
ClientCode.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound)
IdPresentRule.instance("id",
CommonDeleteRequest::getId,
IMDGDistributedNames.Map_ClientCode,
ClientCode.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound)
);
};
}
@Bean("tkrAccountsGatewayValidator")
public Function<TkrAccount, IValidator> newTkrAccountsGatewayValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return tkrGatewayRequest -> {
ImdgValidationContext<TkrAccount> context = new ImdgValidationContext<>();
context.setValidatedObject(tkrGatewayRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbols);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("client_code", TkrAccount::getClientCode, AccountError.RequiredFieldEmpty),
GatewayClientCodeValidationRule.CompanyPresent,
GatewayClientCodeValidationRule.AllAccountsPresent,
GatewayClientCodeValidationRule.DepoAccountsPresent,
GatewayClientCodeValidationRule.TcrIsNotPresent,
GatewayClientCodeValidationRule.TcrListIsNotPresent
);
};
}
}

View file

@ -1,6 +1,8 @@
package ru.spcex.clearing.account.config.validation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@ -49,25 +51,27 @@ public class TradingClearingRegistryListValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<>(context,
IdPresentRule.instance("tradingClearingRegistryId",
TradingClearingRegistryListNewRequest::getTradingClearingRegistryId,
IMDGDistributedNames.Map_TradingClearingRegistry,
TradingClearingRegistry.class,
AccountError.RequiredFieldEmpty,
AccountError.TradingClearingRegistryNotFound,
false),
new ExistAllAccountId<>("accountId",
TradingClearingRegistryListNewRequest::getAccountId,
false,
null),
DictionaryPresentRule.instance("stauts",
TradingClearingRegistryListNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false),
NotAlreadyPresent.instance
IdPresentRule.instance("tradingClearingRegistryId",
TradingClearingRegistryListNewRequest::getTradingClearingRegistryId,
IMDGDistributedNames.Map_TradingClearingRegistry,
TradingClearingRegistry.class,
AccountError.RequiredFieldEmpty,
AccountError.TradingClearingRegistryNotFound,
false),
new ExistAllAccountId<>("accountId",
TradingClearingRegistryListNewRequest::getCurrencyAccountList,
TradingClearingRegistryListNewRequest::getAccountId,
TradingClearingRegistryListNewRequest::getTradingClearingRegistryId,
false,
null),
DictionaryPresentRule.instance("stauts",
TradingClearingRegistryListNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false),
NotAlreadyPresent.instance
);
};
}
@ -83,43 +87,43 @@ public class TradingClearingRegistryListValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
return new ValidatorImpl<ImdgValidationContext<TradingClearingRegistryListUpdateRequest>>(context,
IdPresentRule.instance2("id",
TradingClearingRegistryListUpdateRequest::getId,
IMDGDistributedNames.Map_TradingClearingRegistryList,
TradingClearingRegistryList.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound,
true,
(tcrList)-> {
Long accountId = tcrList.getAccountId();
if (accountId==null)
return null;
if (!IEnumKey.contains(context.getValidatedObject().getStatus(),
ServiceStatus.Active, ServiceStatus.Reopened))
return null;
IdPresentRule.instance2("id",
TradingClearingRegistryListUpdateRequest::getId,
IMDGDistributedNames.Map_TradingClearingRegistryList,
TradingClearingRegistryList.class,
AccountError.RequiredFieldEmpty,
AccountError.RecordNotFound,
true,
(tcrList) -> {
Long accountId = tcrList.getAccountId();
if (accountId == null)
return null;
if (!IEnumKey.contains(context.getValidatedObject().getStatus(),
ServiceStatus.Active, ServiceStatus.Reopened))
return null;
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
ImdgPredicateBuilder pb = tradingClearingRegistryListImdg.predicateBuilder();
ImdgPredicate query = pb.and(pb.equals("status", WorkflowStatus.Active.getKey()),
pb.equals("accountId", accountId));
query = pb.and(query, pb.not(pb.equals("id", tcrList.getId())));
Collection<TradingClearingRegistryList> inOtherLists = tradingClearingRegistryListImdg.getCollectionObjectsByPredicate(query);
if (!inOtherLists.isEmpty()) {
Collection<Long> duplicateAccounts = inOtherLists.stream()
.map(TradingClearingRegistryList::getAccountId)
.filter(accountId::equals)
.collect(Collectors.toSet());
return new EnumMessage(AccountError.AccountForTradingClearingRegistryAlreadyUsed, duplicateAccounts, "accountId"); // (5023) «Счет %s уже используется»
}
return null;
}),
DictionaryPresentRule.instance("status",
TradingClearingRegistryListUpdateRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
true)
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
ImdgPredicateBuilder pb = tradingClearingRegistryListImdg.predicateBuilder();
ImdgPredicate query = pb.and(pb.equals("status", WorkflowStatus.Active.getKey()),
pb.equals("accountId", accountId));
query = pb.and(query, pb.not(pb.equals("id", tcrList.getId())));
Collection<TradingClearingRegistryList> inOtherLists = tradingClearingRegistryListImdg.getCollectionObjectsByPredicate(query);
if (!inOtherLists.isEmpty()) {
Collection<Long> duplicateAccounts = inOtherLists.stream()
.map(TradingClearingRegistryList::getAccountId)
.filter(accountId::equals)
.collect(Collectors.toSet());
return new EnumMessage(AccountError.AccountForTradingClearingRegistryAlreadyUsed, duplicateAccounts, "accountId"); // (5023) «Счет %s уже используется»
}
return null;
}),
DictionaryPresentRule.instance("status",
TradingClearingRegistryListUpdateRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
true)
);
};
}
@ -153,13 +157,21 @@ public class TradingClearingRegistryListValidationConfig {
public static class ExistAllAccountId<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, List<Long>> accountIdListGetter;
Function<R, Long> accountIdGetter;
Function<R, Long> tkrIdGetter;
boolean required;
Function<R, Long> idGetter;
public ExistAllAccountId(String fieldName, Function<R, Long> accountIdGetter, boolean required, Function<R, Long> idGetter) {
public ExistAllAccountId(String fieldName,
Function<R, List<Long>> accountIdListGetter,
Function<R, Long> accountIdGetter,
Function<R, Long> tkrIdGetter,
boolean required, Function<R, Long> idGetter) {
this.fieldName = fieldName;
this.accountIdListGetter = accountIdListGetter;
this.accountIdGetter = accountIdGetter;
this.tkrIdGetter = tkrIdGetter;
this.required = required;
this.idGetter = idGetter;
}
@ -167,8 +179,15 @@ public class TradingClearingRegistryListValidationConfig {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
Long accountId = accountIdGetter.apply(validatedObject);
if (accountId == null) {
List<Long> accounts = accountIdListGetter.apply(validatedObject);
if (accounts == null) {
accounts = new ArrayList<>();
}
Long singleAccountId = accountIdGetter.apply(validatedObject);
if (singleAccountId != null) {
accounts.add(singleAccountId);
}
if (accounts.isEmpty()) {
if (required)
return of(AccountError.RequiredFieldEmpty, fieldName); // обязательное поле
else
@ -177,36 +196,50 @@ public class TradingClearingRegistryListValidationConfig {
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
// Проверить существование счетов
{
Account byIdObject = accountImdg.getSingleObjectByID(accountId);
if (byIdObject == null)
return of(AccountError.AccountNotFound, accountId, fieldName);
if (!IEnumKey.contains(byIdObject.getAccountType(), AccountType.Clrn, AccountType.Info)) {
return of(AccountError.AccountIsNotACurrency, accountId,
for (Long accountId : accounts) {
Account byIdObject = accountImdg.getSingleObjectByID(accountId);
if (byIdObject == null)
return of(AccountError.AccountNotFound, accountId, fieldName);
if (!IEnumKey.contains(byIdObject.getAccountType(), AccountType.Clrn, AccountType.Info)) {
return of(AccountError.AccountIsNotACurrency, accountId,
fieldName, "expected: CLRN/INFO but is " + byIdObject.getAccountType()); // Счет %S не
}
if (CurrencyCode.isRub(byIdObject.getCurrency()) || StringUtils.isEmpty(byIdObject.getCurrency())) {
return of(AccountError.AccountIsNotACurrency, accountId, fieldName); // Счет %S не валютный
}
}
}
if (CurrencyCode.isRub(byIdObject.getCurrency()) || StringUtils.isEmpty(byIdObject.getCurrency())) {
return of(AccountError.AccountIsNotACurrency, accountId, fieldName); // Счет %S не валютный
}
// Проверка отсутствия других TradingClearingRegistryList с этими счетами
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
ImdgPredicateBuilder pb = tradingClearingRegistryListImdg.predicateBuilder();
ImdgPredicate query = pb.and(pb.equals("status", WorkflowStatus.Active.getKey()),
pb.equals("accountId", accountId));
if (idGetter != null) {
Long id = idGetter.apply(validatedObject);
if (id == null) // never
return of(AccountError.RequiredFieldEmpty, "id");
query = pb.and(query, pb.not(pb.equals("id", id)));
}
Collection<TradingClearingRegistryList> inOtherLists = tradingClearingRegistryListImdg.getCollectionObjectsByPredicate(query);
if (!inOtherLists.isEmpty()) {
Collection<Long> duplicateAccounts = inOtherLists.stream()
.map(TradingClearingRegistryList::getAccountId)
.filter(accountId::equals)
.collect(Collectors.toSet());
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, duplicateAccounts, fieldName); // (5023) «Счет %s уже используется»
// Проверка отсутствия других TradingClearingRegistryList с этими счетами
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
ImdgPredicateBuilder pb = tradingClearingRegistryListImdg.predicateBuilder();
Collection<TradingClearingRegistryList> listWithAccountId = tradingClearingRegistryListImdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("accountId", accountId),
pb.equals("status", WorkflowStatus.Active.getKey())
));
if (!listWithAccountId.isEmpty()){
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, byIdObject.getAccount(), fieldName); // (5023) «Данная счет %s уже используется»
}
Long tkrId = tkrIdGetter.apply(validatedObject);
ImdgPredicate query = pb.and(
pb.equals("tradingClearingRegistryId", tkrId),
pb.equals("status", WorkflowStatus.Active.getKey()),
pb.equals("currency", byIdObject.getCurrency()));
if (idGetter != null) {
Long id = idGetter.apply(validatedObject);
if (id == null) // never
return of(AccountError.RequiredFieldEmpty, "id");
query = pb.and(query, pb.not(pb.equals("id", id)));
}
Collection<TradingClearingRegistryList> inOtherLists = tradingClearingRegistryListImdg.getCollectionObjectsByPredicate(query);
if (!inOtherLists.isEmpty()) {
// Collection<String> duplicateAccounts = inOtherLists.stream()
// .map(tradingClearingRegistryList ->
// accountImdg.getSingleObjectByID(tradingClearingRegistryList.getAccountId()).getAccount())
// .collect(Collectors.toSet());
return of(AccountError.CurrencyForTradingClearingRegistryListAlreadyUsed, byIdObject.getCurrency(), fieldName); // (5023) «Данная валюта %s уже используется»
}
}
}
return empty();

View file

@ -31,6 +31,7 @@ import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
@ -140,11 +141,6 @@ public class TradingClearingRegistryValidationConfig {
if (validatedObject.getMoneyAccountId() == null) {
return of(AccountError.RequiredFieldEmpty, "MoneyAccountId");
}
//Map<String, Comparable<?>> query = new HashMap<>();
// query.put("moneyAccountId", validatedObject.getMoneyAccountId());
// if (validatedObject.getDepoAccountId() != null) {
// query.put("depoAccountId", validatedObject.getDepoAccountId());
// }
ImdgPredicateBuilder pb = tcrMap.predicateBuilder();
ImdgPredicate query = pb.equals("moneyAccountId", validatedObject.getMoneyAccountId());
if (validatedObject.getDepoAccountId() != null) {
@ -160,8 +156,49 @@ public class TradingClearingRegistryValidationConfig {
Account account = accountImdg.getSingleObjectByID(validatedObject.getMoneyAccountId());
if (account == null && validatedObject.getDepoAccountId() != null) account = accountImdg.getSingleObjectByID(validatedObject.getDepoAccountId());
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, account.getAccount());
// String tcrIds = existTCR.stream().map(tcr -> String.valueOf(tcr.getId())).collect(Collectors.joining(";"));
// return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, tcrIds);
}
}
}
static class updateTCRDepoCheck implements IValidationRule<ImdgValidationContext<TradingClearingRegistryUpdateRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TradingClearingRegistryUpdateRequest> context) {
TradingClearingRegistryUpdateRequest validatedObject = context.getValidatedObject();
Long depoAccountId = validatedObject.getDepoAccountId();
if (depoAccountId == null) // необязательное поле
return empty();
// Проверка типа счёта ДЕПО, что существует
Imdg<DepoAccount> depoAccountImdg = context.obtainMap(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
DepoAccount depoAccount = depoAccountImdg.getFirstObjectByFieldValues(
Map.of("accountId", depoAccountId)
);
if (depoAccount == null)
return of(AccountError.AccountNotFound, depoAccountId);
// Проверка компании ТКР и счёта
Imdg<TradingClearingRegistry> tcrMap = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account account = accountImdg.getSingleObjectByID(validatedObject.getMoneyAccountId());
if (account == null) { // never
return of(AccountError.AccountNotFound, depoAccountId);
}
TradingClearingRegistry updateObject = tcrMap.getSingleObjectByID(validatedObject.getId());
if (!Objects.equals(account.getCompanyId(), updateObject.getCompanyId())) {
return of(AccountError.AccountNotFound, depoAccountId); // или UserVerifyDenial
}
// Проверка использования счёта в других ТКР
ImdgPredicateBuilder pb = tcrMap.predicateBuilder();
ImdgPredicate query = pb.and(pb.equals("depoAccountId", validatedObject.getDepoAccountId()),
pb.not(pb.equals("id", validatedObject.getId()))
);
Collection<TradingClearingRegistry> existTCR = tcrMap.getCollectionObjectsByPredicate(query);
if (existTCR.isEmpty()) {
return empty();
} else {
if (account == null && validatedObject.getDepoAccountId() != null) account = accountImdg.getSingleObjectByID(validatedObject.getDepoAccountId());
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, account.getAccount());
}
}
}
@ -177,6 +214,8 @@ public class TradingClearingRegistryValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
addImdg.accept(IMDGDistributedNames.Map_Account);
addImdg.accept(IMDGDistributedNames.Map_DepoAccount);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
TradingClearingRegistryUpdateRequest::getId,
@ -190,7 +229,9 @@ public class TradingClearingRegistryValidationConfig {
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.DictionaryNotFound,
false)
false),
new updateTCRDepoCheck()
);
};
}

View file

@ -1,15 +1,28 @@
package ru.spcex.clearing.account.config.validation;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.*;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountSymbols;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.ClientCode;
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.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.misc.Currency;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.clearing.platform.dictionary.*;
import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary;
import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.classes.base.SpcexObjectBase;
@ -17,10 +30,6 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
@Configuration
public class ValidationConfig {
@ -44,6 +53,7 @@ public class ValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
addImdg.accept(IMDGDistributedNames.Map_Currency, Currency.class);
//for ClientCodeValidationConfig
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);

View file

@ -24,6 +24,12 @@ public enum AccountError implements IErrorEnumId {
AccountFieldNotSet(5024L),
AccountDepoTypeRequired(5025L),
AccountIsNotACurrency(5026L), // Счет %S не валютный
CompanyHasNotClearingMemberCategory(5027L),
//ошибки для трансляции в модуль gateway
TCR_NOT_FOUND_GTW(5028L),
ACCOUNT_NOT_FOUND_GTW(5029L),
COMPANY_NOT_FOUND_GTW(5030L),
CurrencyForTradingClearingRegistryListAlreadyUsed(5031L),
TradingClearingRegistryNotFound(3022L),
CurrencyNotFound(1016L),
;

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.account.model;
import java.util.List;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.platform.enumeration.Status;
public class ClientCodeBusiness {
private Status code;
private Company company;
private Account moneyAccount;
private Account depoAccount;
private List<Account> currentAccounts;
private TradingClearingRegistry tradingClearingRegistry;
private Status status;
public ClientCodeBusiness(Status code,
Company company, Account moneyAccount, Account depoAccount, List<Account> currentAccounts, TradingClearingRegistry tradingClearingRegistry, Status status) {
this.code = code;
this.company = company;
this.moneyAccount = moneyAccount;
this.depoAccount = depoAccount;
this.currentAccounts = currentAccounts;
this.tradingClearingRegistry = tradingClearingRegistry;
this.status = status;
}
}

View file

@ -0,0 +1,79 @@
package ru.spcex.clearing.account.model;
import java.util.Optional;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
public class TradingClearingRegistryBusiness {
private Company company;
private Account moneyAccount;
private Status status;
private Optional<DepoAccount> depoAccount;
private Optional<TradingClearingRegistryType> tradingClearingRegistryType;
private TradingClearingRegistryBusiness() {
this.depoAccount = Optional.empty();
this.tradingClearingRegistryType = Optional.empty();
}
public static TradingClearingRegistryBusiness builder() {
return new TradingClearingRegistryBusiness();
}
public TradingClearingRegistryBusiness company(Company company) {
this.company = company;
return this;
}
public TradingClearingRegistryBusiness moneyAccount(Account moneyAccount) {
this.moneyAccount = moneyAccount;
return this;
}
public TradingClearingRegistryBusiness depoAccount(DepoAccount depoAccount) {
this.depoAccount = Optional.of(depoAccount);
return this;
}
public TradingClearingRegistryBusiness status(Status status) {
this.status = status;
return this;
}
public TradingClearingRegistryBusiness tradingClearingRegistryType(TradingClearingRegistryType type) {
this.tradingClearingRegistryType = Optional.of(type);
return this;
}
public TradingClearingRegistryBusiness build() {
TradingClearingRegistryBusiness tradingClearingRegistryBusiness = new TradingClearingRegistryBusiness();
tradingClearingRegistryBusiness.company = this.company;
tradingClearingRegistryBusiness.status = this.status;
tradingClearingRegistryBusiness.depoAccount = this.depoAccount;
tradingClearingRegistryBusiness.moneyAccount = this.moneyAccount;
tradingClearingRegistryBusiness.tradingClearingRegistryType = this.tradingClearingRegistryType;
return tradingClearingRegistryBusiness;
}
public Company getCompany() {
return company;
}
public Account getMoneyAccount() {
return moneyAccount;
}
public Optional<DepoAccount> getDepoAccount() {
return depoAccount;
}
public Status getStatus() {
return status;
}
public Optional<TradingClearingRegistryType> getTradingClearingRegistryType() {
return tradingClearingRegistryType;
}
}

View file

@ -0,0 +1,12 @@
package ru.spcex.clearing.account.model;
import java.util.Optional;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
public record ValidationResult(IValidator validator, Optional<EnumMessage> error, Optional<String> errorMsg) {
public boolean isValid() {
return error.isEmpty();
}
}

View file

@ -34,6 +34,7 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.DepoAccountType;
import ru.spcex.platform.enumeration.Sender;
import ru.spcex.platform.enumeration.ServiceStatus;
@ -137,20 +138,21 @@ public class AccountService extends QueueConsumer implements InitializingBean {
CorrespondentAccountNewRequest req = userRequest.getRequestPayload();
Currency currency = validator.getStored(Stored.currency);
String currencyCode = req.getCurrency() == null ? CurrencyCode.RUB.getKey() : req.getCurrency();
Long currencyCodeId = CurrencyCode.RUB.getKey().equals(currencyCode) ? 810 : currency.getId();
Instant now = Instant.now();
Account account = new Account();
account.setCompanyId(req.getCompanyId());
account.setAccount(req.getAccount());
if (AccountType.Info.equalsByKey(req.getAccountType())) {
Long infoSequenceId = informationAccountService.accountNextId(currency.getCurrencyCode(), currency.getId());
Long infoSequenceId = informationAccountService.accountNextId(currencyCode, currencyCodeId);
String accountValue = informationAccountService.generateInfoAccount(currency.getId(), infoSequenceId);
String accountValue = informationAccountService.generateInfoAccount(currencyCodeId, infoSequenceId);
log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue);
account.setAccount(accountValue);
}
account.setAccountType(req.getAccountType());
account.setCurrency(currency.getCurrencyCode());
account.setCurrency(currencyCode);
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
log.trace("Status not set in request. Use default: {}", account.getStatus());

View file

@ -138,6 +138,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
bankAccount.setCompanyId(req.getCompanyId());
bankAccount.setAccountId(accountId);
bankAccount.setSwiftCode(req.getSwiftCode());
bankAccount.setIntermediarySwiftCode(req.getIntermediarySwiftCode());
bankAccountId = bankAccountMap.insert(bankAccount);
txOk = true;
@ -176,6 +177,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
bankAccount.setTaxRegistrationReasonCode(req.getTaxRegistrationReasonCode());
bankAccount.setAccount(req.getAccount());
bankAccount.setSwiftCode(req.getSwiftCode());
bankAccount.setIntermediarySwiftCode(req.getIntermediarySwiftCode());
Account account = accountMap.getSingleObjectByID(bankAccount.getAccountId());
account.setAccount(req.account);

View file

@ -18,6 +18,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
@ -27,6 +28,7 @@ import ru.clearing.classes.statics.data.misc.Currency;
import ru.clearing.classes.statics.data.misc.Notification;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf52;
import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary;
import ru.clearing.platform.dictionary.ClearingCategoryDictionary;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -92,6 +94,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
private final Imdg<ClearingCategoryDictionary> clearingCategoryImdg;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Notification> notificationImdg;
private final Imdg<ClearingAccountTypeDictionary> clearingAccountTypeDictionaryImdg;
@Autowired
public ClearingAccountService(Consumer<String, Object> kafkaQueue,
@ -127,6 +130,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
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);
this.clearingAccountTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccountTypeDictionary, ClearingAccountTypeDictionary.class);
}
@Override
@ -378,6 +382,30 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
* @return
*/
private synchronized Account createSdf52Account(String accountValue, String acctType, Long companyId, Long userRequestId) {
{ // Валидация
boolean existClearingAccountTypeDictionary;
if (!StringUtils.hasText(acctType)) {
existClearingAccountTypeDictionary = false;
} else {
ClearingAccountTypeDictionary catd = clearingAccountTypeDictionaryImdg.getFirstObjectByFieldValues(
Map.of("code", acctType));
existClearingAccountTypeDictionary = catd != null;
}
if (!existClearingAccountTypeDictionary) {
String errMsg = messageResolver.resolve(new EnumMessage(AccountError.DictionaryNotFound, acctType, clearingAccountTypeDictionaryImdg.getMapName()));
log.warn(errMsg);
return null;
}
ClearingMemberCategory companyAnyCMC = clearingMemberCategoryImdg.getFirstObjectByFieldValues(Map.of(
"companyId", companyId
));
if (companyAnyCMC == null) {
String errMsg = messageResolver.resolve(new EnumMessage(AccountError.CompanyHasNotClearingMemberCategory, companyId));
log.warn(errMsg);
}
}
Instant now = Instant.now();
Account account = new Account();
account.setAccount(accountValue);
@ -388,7 +416,9 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
Long currencyId = Long.valueOf(accountValue.substring(5, 8));
Currency currency = currImdg.getSingleObjectByID(currencyId);
account.setCurrency(currency.getCurrencyCode());
} catch (Throwable e) {}
} catch (Throwable e) {
log.trace("When obtain currency from accountValue: {}", e.toString());
}
}
if (TextUtil.isEmpty(account.getCurrency())) {
log.warn("Sdf52: Wrong accountValue=\"{}\" - can not parse for get currency", accountValue);
@ -477,14 +507,11 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
Account account = sDf52.getAccount() == null ? null : accountImdg.getFirstObjectByFieldValues(accountQuery);
if (account == null) {
if (SDFProcessService.SDF52_STATUS_3Open.equals(sDf52.getStatus())) {
//log.debug("By generationId={} s_df52[{}].status={}, but account not found (query: {}). Continue with result OK for status 3",
// groupId, sDf52.getId(), sDf52.getStatus(), accountQuery);
// todo http://jira.mfd.msk:8088/browse/CLS-585 добавят поле acc_type в формат дф52
log.trace("By generationId={} s_df52[{}].status={}, account not found (query: {}). Try create new account.",
groupId, sDf52.getId(), sDf52.getStatus(), accountQuery);
account = createSdf52Account(sDf52.getAccount(),sDf52.getAcc_type(), company.getId(), systemRequest.getId());
if (account == null) {
log.warn("Can not create account: \"{}\", companyId={}. Ignore SDF52.id={}",
log.info("Can not create account: \"{}\", companyId={}. Ignore SDF52.id={}",
sDf52.getAccount(), company.getId(), sDf52.getId());
continue;
}

View file

@ -1,5 +1,14 @@
package ru.spcex.clearing.account.service;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
@ -11,7 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -20,7 +31,11 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgResponse;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.Tkr;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryListNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryListUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
@ -29,6 +44,7 @@ import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
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;
@ -42,15 +58,6 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.log.ExceptionUtils;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Function;
@Service
public class ClientCodeService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
@ -59,11 +66,12 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
private final ImdgProvider imdgProvider;
private final Imdg<ClientCode> clientCodeMap;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryMap;
private final Imdg<CompanySymbols> companySymbolsImdg;
private final Imdg<Account> accountImdg;
private final Function<ClientCodeNewRequest, IValidator> clientCodeNewRequestValidator;
private final Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator;
private final Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator;
private final Function<TkrAccount, IValidator> tkrAccountsGatewayValidator;
private final ValidationHelper validationHelper;
private final UserRoleVerification userRoleVerification;
private final IMessageResolver messageResolver;
@ -71,11 +79,13 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
protected TradingClearingRegistryService tradingClearingRegistryService;
protected ConfigurableApplicationContext context;
private final KafkaSender kafkaSender;
//protected TradingClearingRegistryListService tradingClearingRegistryListService;
@Autowired
public ClientCodeService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaSender,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
IMessageResolver messageResolver,
@ -85,16 +95,21 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
UserRoleVerification userRoleVerification,
@Qualifier("clientCodeNewRequestValidator") Function<ClientCodeNewRequest, IValidator> clientCodeNewRequestValidator,
@Qualifier("clientCodeUpdateRequestValidator") Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator,
@Qualifier("clientCodeDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator) {
@Qualifier("clientCodeDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator,
@Qualifier("tkrAccountsGatewayValidator") Function<TkrAccount, IValidator> tkrAccountsGatewayValidator) {
super(kafkaQueue, kafkaProducer);
this.kafkaProducer = kafkaProducer;
this.kafkaSender = kafkaSender;
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.clientCodeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
this.tradingClearingRegistryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.clientCodeNewRequestValidator = clientCodeNewRequestValidator;
this.clientCodeUpdateRequestValidator = clientCodeUpdateRequestValidator;
this.clientCodeDeleteRequestValidator = clientCodeDeleteRequestValidator;
this.tkrAccountsGatewayValidator = tkrAccountsGatewayValidator;
this.validationHelper = validationHelper;
this.requestHelper = requestHelper;
this.messageResolver = messageResolver;
@ -107,19 +122,23 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
// callback(ClientCodeNewRequest.class)
// .setFunction(this::clientCodeNew)
// .forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
//note переехало в ClientCodeMessageListener[новая версия сервиса]
// callback(TkrAccountsGatewayRequest.class)
// .setFunction(this::clientCodeNewFromGateway)
// .forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_FROM_GATEWAY, callbacks::put);
callback(ClientCodeNewRequest.class)
.setFunction(this::clientCodeNew)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
callback(ClientCodeNewRequest.class)
.setFunction(this::clientCodeNewFromApiUmCompany)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, callbacks::put);
.setFunction(this::clientCodeNewFromApiUmCompany)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, callbacks::put);
callback(ClientCodeUpdateRequest.class)
.setFunction(this::clientCodeUpdate)
.forDestination(Consts.DESTINATION_CLIENT_CODE_UPDATE, callbacks::put);
.setFunction(this::clientCodeUpdate)
.forDestination(Consts.DESTINATION_CLIENT_CODE_UPDATE, callbacks::put);
callback(CommonDeleteRequest.class)
.setFunction(this::clientCodeDelete)
.forDestination(Consts.DESTINATION_CLIENT_CODE_DELETE, callbacks::put);
.setFunction(this::clientCodeDelete)
.forDestination(Consts.DESTINATION_CLIENT_CODE_DELETE, callbacks::put);
init();
}
@ -153,10 +172,6 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
return null;
}
protected RequestInfoUpdate clientCodeNew(BaseRequest<ClientCodeNewRequest> userRequest) {
return clientCodeNew0(userRequest, false);
}
protected RequestInfoUpdate clientCodeNew0(BaseRequest<ClientCodeNewRequest> userRequest, boolean fromTCRList) {
log.debug("ClientCodeNewRequest received {}", userRequest.getId());
@ -175,12 +190,12 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (doCreateTCR) {
try {
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), null,
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
return makeErrorResponse(userRequest, AccountError.GeneralError, "Can not create TCR: " + e.getMessage());
}
}
@ -211,8 +226,8 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of tradingClearingRegistryList. request id={}; {}",
userRequest.getId(),
ExceptionUtils.getStackTrace(e));
userRequest.getId(),
ExceptionUtils.getStackTrace(e));
return makeErrorResponse(userRequest, AccountError.GeneralError, "Can not create TCR: " + e.getMessage());
}
}
@ -254,12 +269,12 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (doCreateTCR) {
try {
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), null,
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
return makeErrorResponse(userRequest, AccountError.GeneralError, "Can not create TCR at this moment" + e.getMessage());
}
}
@ -289,8 +304,8 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of tradingClearingRegistryList. request id={}; {}",
userRequest.getId(),
ExceptionUtils.getStackTrace(e));
userRequest.getId(),
ExceptionUtils.getStackTrace(e));
return makeErrorResponse(userRequest, AccountError.GeneralError, "Can not create TCR: " + e.getMessage());
}
}
@ -333,12 +348,12 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
if (doCreateTCR) {
try {
requestInfoUpdate = createAndWaitTCR(userRequest.getId(), clientCode.getId(),
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (requestInfoUpdate != null) return requestInfoUpdate;
} catch (Exception e) {
log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}",
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(),
e.toString());
return makeErrorResponse(userRequest, AccountError.GeneralError, "Can not create TCR: " + e.getMessage());
}
}
@ -387,7 +402,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
query.put("depoAccountId", depoAccountId);
}
TradingClearingRegistry result = tradingClearingRegistryMap.getFirstObjectByFieldValues(query);
log.trace("TradingClearingRegistry by: {}; {}found", query, result == null ? "not " : "");
log.trace("TradingClearingRegistry by: {}; {} found", query, result == null ? "not" : "");
return result;
}
@ -407,8 +422,8 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
protected RequestInfoUpdate createAndWaitTCR(Long reqId, Long clientCode,
Long companyId, Long moneyAccountId, Long depoAccountId) {
log.debug("For request {}, clientCode={} need create TCR: companyId={}, moneyAccountId={}, depoAccountId={}",
reqId, clientCode == null ? "new" : clientCode,
companyId, moneyAccountId, depoAccountId);
reqId, clientCode == null ? "new" : clientCode,
companyId, moneyAccountId, depoAccountId);
BaseRequest<TradingClearingRegistryNewRequest> request = new BaseRequest<>();
request.setId(idGenerator.nextId());
request.setActionType(ActionType.NEW);
@ -495,7 +510,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (tradingClearingRegistry == null) {
log.warn("TCR not found: CompanyId {}, MoneyAccountId {}, DepoAccountId {}",
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
} else {
clientCode.setTradingClearingRegistryId(tradingClearingRegistry.getId());
}
@ -518,7 +533,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
if (tradingClearingRegistry == null) {
log.warn("TCR not found: CompanyId {}, MoneyAccountId {}, DepoAccountId {}",
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId());
} else {
clientCode.setTradingClearingRegistryId(tradingClearingRegistry.getId());
}
@ -532,4 +547,21 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
clientCode.setUpdated(Instant.now());
}
private Tkr crateErrorTkrToGateway(TkrAccount tkrAccount, Optional<String> errorMsg) {
Tkr tkr = new Tkr();
tkr.setTkrCode(tkrAccount.getTkrCode());
tkr.setClientCode(tkrAccount.getClientCode());
tkr.setCompanyId(tkrAccount.getCompanyId());
tkr.setDepoAccount(tkrAccount.getDepoAccount());
errorMsg.ifPresent(tkr::setErrorMessage);
return tkr;
}
private MoneyAccountMsgResponse convertAccountToResponse(MoneyAccountMsgRequest moneyAccountMsgRequest) {
MoneyAccountMsgResponse msgResponse = new MoneyAccountMsgResponse();
msgResponse.setAccount(moneyAccountMsgRequest.getAccount());
msgResponse.setCurrCode(moneyAccountMsgRequest.getCurrCode());
return msgResponse;
}
}

View file

@ -302,7 +302,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
}
public String generateInfoAccount(Long currencyCodeId, Long id) {
return "%d%d%08d%d".formatted(39911, currencyCodeId, id, 7000);
return "%d%03d%08d%d".formatted(39911, currencyCodeId, id, 7000);
}
public synchronized Long accountNextId(String currency) {
@ -316,6 +316,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
* @return infoCounter++
*/
public synchronized Long accountNextId(String currency, Long currencyCodeId) {
String idWithTrailingZero = String.format("%03d", currencyCodeId);
if (currency == null)
currency = CurrencyCode.RUB.getKey(); // default
AtomicLong infoCounter = infoCounterByCurrency.get(currency);
@ -338,7 +339,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali
infoCounter = new AtomicLong(1);
log.debug("No account information on map. n={}", infoCounter.get());
} else {
Pattern accPattern = Pattern.compile("39911%d([0-9]{8})7000".formatted(currencyCodeId));
Pattern accPattern = Pattern.compile("39911%s([0-9]{8})7000".formatted(idWithTrailingZero));
int maxN = 1;
int parsedCount = 0;
String lastAccount = null; // for debug

View file

@ -141,7 +141,6 @@ public class TradingClearingRegistryListService extends QueueConsumer implements
TradingClearingRegistryListNewRequest req = userRequest.getRequestPayload();
Account account = accountImdg.getSingleObjectByID(req.getAccountId());
Instant now = Instant.now();
List<Long> newIds=new ArrayList<>();
@ -153,6 +152,7 @@ public class TradingClearingRegistryListService extends QueueConsumer implements
tradingClearingRegistryList.setUpdated(now);
tradingClearingRegistryList.setTradingClearingRegistryId(req.getTradingClearingRegistryId());
tradingClearingRegistryList.setAccountId(currAccId);
Account account = accountImdg.getSingleObjectByID(currAccId);
tradingClearingRegistryList.setCurrency(account.getCurrency());
if (req.getStatus() == null) {
tradingClearingRegistryList.setStatus(ServiceStatus.Active.getKey());

View file

@ -6,6 +6,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
@ -14,23 +15,34 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountSymbols;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.account.InformationAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
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.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccountsGatewayRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgResponse;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SendTkrRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.Tkr;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
@ -38,7 +50,12 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CompanySymbol;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.Status;
import static ru.spcex.platform.enumeration.Task.makeFiles_MTCR;
import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.imdg.api.Imdg;
@ -56,12 +73,16 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
private final ImdgProvider imdgProvider;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg;
private final Imdg<DepoAccount> depoAccountImdg;
private final Imdg<ClearingAccount> clearingAccountImdg;
private final Imdg<InformationAccount> informationAccountImdg;
private final Imdg<Account> accountImdg;
private final Imdg<AccountSymbols> accountSymbolsImdg;
private final Imdg<Company> companyImdg;
private final Imdg<CompanySymbols> companySymbolsImdg;
private final Imdg<Relation> relationImdg;
private final Imdg<ClientCode> clientCodeImdg;
private final Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator;
private final RequestHelper requestHelper;
@ -82,11 +103,11 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
IMessageResolver messageResolver,
RequestHelper requestHelper,
@Qualifier("tradingClearingRegistryNewRequest")
Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryNewRequestValidator,
Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryNewRequestValidator,
@Qualifier("tradingClearingRegistryUpdateRequest")
Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator,
Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator,
@Qualifier("tradingClearingRegistryBlockRequest")
Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator) {
Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.kafkaProducer = kafkaProducer;
this.kafkaSender = kafkaSender;
@ -95,12 +116,16 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
this.requestHelper = requestHelper;
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.tradingClearingRegistryListImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
this.informationAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.accountSymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
this.clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator;
this.tradingClearingRegistryAutoNewRequestValidator = tradingClearingRegistryNewRequestValidator; // без relation.
this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator;
@ -112,17 +137,23 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
public void afterPropertiesSet() throws Exception {
imdgProvider.waitAvailable();
callback(TradingClearingRegistryNewRequest.class) // todo deprecated - unused.
.setFunction(this::tradingClearingRegistryAutoNew)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put);
.setFunction(this::tradingClearingRegistryAutoNew)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put);
callback(TradingClearingRegistryNewRequest.class)
.setFunction(this::tradingClearingRegistryNew)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put);
.setFunction(this::tradingClearingRegistryNew)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put);
callback(TradingClearingRegistryUpdateRequest.class)
.setFunction(this::tradingClearingRegistryUpdate)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, callbacks::put);
.setFunction(this::tradingClearingRegistryUpdate)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, callbacks::put);
callback(CommonIdRequest.class)
.setFunction(this::tradingClearingRegistryBlock)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put);
.setFunction(this::tradingClearingRegistryBlock)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put);
callback(TkrAccountsGatewayRequest.class)
.setFunction(this::tradingClearingRegistryCheck)
.forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_CHECK, callbacks::put);
callback(LauncherCommandRequest.class)
.setConsumer(this::sendAllTkrToGateway)
.forDestination(makeFiles_MTCR.topic(), callbacks::put);
init();
}
@ -162,10 +193,10 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registryByCompany == null) {
log.trace("Not found registry with companyId={}",
req.getCompanyId());
req.getCompanyId());
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryNotFound,
req.getCompanyId());
AccountError.TradingClearingRegistryNotFound,
req.getCompanyId());
}
}
@ -210,6 +241,12 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
targetExistTradingClearingRegistry.setUpdated(Instant.now());
tradingClearingRegistryImdg.update(targetExistTradingClearingRegistry);
log.debug("successfully processed, id {}. Updated exist TradingClearingRegistry.id={}", id, targetExistTradingClearingRegistry.getId());
Optional<Tkr> tkr = createRequestToGateway(tradingClearingRegistry);
if (tkr.isPresent()) {
SendTkrRequest sendTkrRequest = new SendTkrRequest();
sendTkrRequest.getTkrs().add(tkr.get());
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
}
return null;
}
}
@ -248,9 +285,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
}
tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType);
TradingClearingRegistryPurpose registryPurpose;
if (req.getDepoAccountId() != null) registryPurpose = TradingClearingRegistryPurpose.C;
else registryPurpose = TradingClearingRegistryPurpose.M;
TradingClearingRegistryPurpose registryPurpose = TradingClearingRegistryPurpose.C;
//http://jira.mfd.msk:8088/browse/CLS-631#comment-60200
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = companyImdg.getSingleObjectByID(req.getCompanyId());
@ -293,8 +329,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
TradingClearingRegistry registryByCompany = tradingClearingRegistryImdg.getFirstObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registryByCompany == null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryNotFound,
"companyId=" + req.getCompanyId());
AccountError.TradingClearingRegistryNotFound,
"companyId=" + req.getCompanyId());
}
}
@ -327,9 +363,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
}
tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType);
TradingClearingRegistryPurpose registryPurpose;
if (req.getDepoAccountId() != null) registryPurpose = TradingClearingRegistryPurpose.C;
else registryPurpose = TradingClearingRegistryPurpose.M;
//http://jira.mfd.msk:8088/browse/CLS-631#comment-60200
TradingClearingRegistryPurpose registryPurpose = TradingClearingRegistryPurpose.C;
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = companyImdg.getSingleObjectByID(req.getCompanyId());
@ -344,6 +379,12 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
tradingClearingRegistryImdg.insert(tradingClearingRegistry);
log.info("New TCR.id={} was created.", tradingClearingRegistry.getId());
Optional<Tkr> tkr = createRequestToGateway(tradingClearingRegistry);
if (tkr.isPresent()) {
SendTkrRequest sendTkrRequest = new SendTkrRequest();
sendTkrRequest.getTkrs().add(tkr.get());
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
}
sendNotificationToReportSvc(tradingClearingRegistry);
sendNotificationToClearingSvc(tradingClearingRegistry);
@ -355,11 +396,11 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
protected Long companySequenceNextId(Long companyId, TradingClearingRegistryPurpose registryPurpose, String tradingRegistryType) {
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
Collection<TradingClearingRegistry> existTCR = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("companyId", companyId),
pb.equals("tradingClearingRegistryPurpose", registryPurpose.getKey()),
pb.equals("tradingClearingRegistryType", tradingRegistryType)
)
pb.and(
pb.equals("companyId", companyId),
pb.equals("tradingClearingRegistryPurpose", registryPurpose.getKey()),
pb.equals("tradingClearingRegistryType", tradingRegistryType)
)
);
if (existTCR.isEmpty()) {
log.trace("For company id={} not found exist TCR.", companyId);
@ -423,18 +464,26 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
if (req.getMoneyAccountId() != null && !req.getMoneyAccountId().equals(tradingClearingRegistry.getMoneyAccountId())) {
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "MoneyAccountId", req.getMoneyAccountId());
}
if (req.getDepoAccountId() != null && !req.getDepoAccountId().equals(tradingClearingRegistry.getDepoAccountId())) {
if (tradingClearingRegistry.getDepoAccountId() != null && // но можно с null заменить
req.getDepoAccountId() != null && !req.getDepoAccountId().equals(tradingClearingRegistry.getDepoAccountId())) {
return requestHelper.makeErrorResponse(userRequest, AccountError.WrongFieldValue, "DepoAccountId", req.getDepoAccountId());
}
// tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId());
// tradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
if (req.getStatus() != null && !Objects.equals(req.getStatus(), tradingClearingRegistry.getStatus())) {
if (req.getStatus() != null && !Objects.equals(req.getStatus(), tradingClearingRegistry.getStatus())
|| req.getDepoAccountId() != null && !req.getDepoAccountId().equals(tradingClearingRegistry.getDepoAccountId())
) {
Instant now = Instant.now();
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistry.setStatus(req.getStatus());
tradingClearingRegistry.setDepoAccountId(req.getDepoAccountId());
tradingClearingRegistryImdg.update(tradingClearingRegistry);
Optional<Tkr> tkr = createRequestToGateway(tradingClearingRegistry);
if (tkr.isPresent()) {
SendTkrRequest sendTkrRequest = new SendTkrRequest();
sendTkrRequest.getTkrs().add(tkr.get());
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
}
log.debug("Update TCR.id={}.", tradingClearingRegistry.getId());
} else {
log.debug("Nothing to update TCR.id={}.", tradingClearingRegistry.getId());
@ -464,6 +513,127 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
return null;
}
public RequestInfoUpdate tradingClearingRegistryCheck(BaseRequest<TkrAccountsGatewayRequest> gatewayRequest) {
TkrAccountsGatewayRequest req = gatewayRequest.getRequestPayload();
log.debug("TradingClearingRegistryCheckRequest received with requestId : {}", req.getRequestId());
for (TkrAccount accountForCheck : req.getAccounts()) {
log.debug("Checking TKR with code: {}", accountForCheck.getTkrCode());
TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(
Map.of("code", accountForCheck.getTkrCode())
);
Optional<Tkr> tkr = createRequestToGateway(tradingClearingRegistry);
if (tkr.isPresent()) {
SendTkrRequest sendTkrRequest = new SendTkrRequest();
sendTkrRequest.getTkrs().add(tkr.get());
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
}
}
return null;
}
public RequestInfoUpdate sendAllTkrToGateway(BaseRequest<?> gatewayRequest) {
Collection<TradingClearingRegistry> tkrs = tradingClearingRegistryImdg.getAllValues();
SendTkrRequest sendTkrRequest = new SendTkrRequest();
for (TradingClearingRegistry tkr : tkrs) {
log.debug("Create TKR request with id: {}", tkr.getId());
Optional<Tkr> tkrRequest = createRequestToGateway(tkr);
tkrRequest.ifPresent(value -> sendTkrRequest.getTkrs().add(value));
}
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
return null;
}
private Optional<Tkr> createRequestToGateway(TradingClearingRegistry tradingClearingRegistry) {
if (tradingClearingRegistry != null) {
Tkr tkr = new Tkr();
log.debug("Found TKR with id: {} and code: {}", tradingClearingRegistry.getId(), tradingClearingRegistry.getCode());
Company company = companyImdg.getSingleObjectByID(tradingClearingRegistry.getCompanyId());
CompanySymbols companySymbols = companySymbolsImdg.getSingleObjectByFieldValues(
Map.of(
"companySymbol", CompanySymbol.UUID.getKey(),
"companyId", company.getId()
)
);
if (companySymbols == null) {
log.warn("CompanySymbols is null, searched by company.id: {}, skip this tkr", company.getId());
return Optional.empty();
}
ClientCode clientCode = clientCodeImdg.getFirstObjectByFieldValues(
Map.of("tradingClearingRegistryId", tradingClearingRegistry.getId())
);
tkr.setCompanyId(companySymbols.getCompanySymbolValue());
tkr.setTradingCode(Long.valueOf(company.getTradingCode()));
tkr.setTkrCode(tradingClearingRegistry.getCode());
tkr.setTkrType(tradingClearingRegistry.getTradingClearingRegistryPurpose());
tkr.setActive(Status.Active.equalsByKey(tradingClearingRegistry.getStatus()));
String accountType;
if (clientCode == null) {
if (TradingClearingRegistryType.Client_B.equalsByKey(
tradingClearingRegistry.getTradingClearingRegistryType())) {
accountType = "Клиентский общий";
} else {
accountType = "Общий";
}
} else {
tkr.setClientCode(clientCode.getCode());
accountType = "Клиентский обособленный";
}
tkr.setAccountTypeName(accountType);
if (tradingClearingRegistry.getDepoAccountId() != null) {
AccountSymbols depoAccountSymbol = accountSymbolsImdg.getFirstObjectByFieldValues(
Map.of("accountId", tradingClearingRegistry.getDepoAccountId())
);
if (depoAccountSymbol != null) {
tkr.setDepoAccount(depoAccountSymbol.getAccountSymbolValue());
}
}
{
if (tradingClearingRegistry.getMoneyAccountId() != null) {
Account moneyAccount = accountImdg.getSingleObjectByID(tradingClearingRegistry.getMoneyAccountId());
MoneyAccountMsgResponse moneyAccountMsg = new MoneyAccountMsgResponse();
moneyAccountMsg.setAccount(moneyAccount.getAccount());
moneyAccountMsg.setCurrCode(StringUtils.hasText(moneyAccount.getCurrency()) ? moneyAccount.getCurrency() : "RUB");
getEksAccount(moneyAccount).ifPresent(moneyAccountMsg::setEksAccount);
moneyAccountMsg.setActive(Status.Active.equalsByKey(moneyAccount.getStatus()));
tkr.getMoneyAccounts().add(moneyAccountMsg);
}
}
{
Collection<TradingClearingRegistryList> tradingClearingRegistries = tradingClearingRegistryListImdg.getCollectionObjectsByFieldValues(
Map.of(
"tradingClearingRegistryId", tradingClearingRegistry.getId()
)
);
for (TradingClearingRegistryList tkrList : tradingClearingRegistries) {
Account additionalAcc = accountImdg.getSingleObjectByID(tkrList.getAccountId());
MoneyAccountMsgResponse moneyAccountMsg = new MoneyAccountMsgResponse();
moneyAccountMsg.setAccount(additionalAcc.getAccount());
getEksAccount(additionalAcc).ifPresent(moneyAccountMsg::setEksAccount);
moneyAccountMsg.setCurrCode(StringUtils.hasText(additionalAcc.getCurrency()) ? additionalAcc.getCurrency() : "RUB");
moneyAccountMsg.setActive(Status.Active.equalsByKey(additionalAcc.getStatus()));
tkr.getMoneyAccounts().add(moneyAccountMsg);
}
}
return Optional.of(tkr);
}
return Optional.empty();
}
private Optional<String> getEksAccount(Account account) {
if (AccountType.Info.equalsByKey(account.getAccountType())) {
String currency = StringUtils.hasText(account.getCurrency()) ? account.getCurrency() : CurrencyCode.RUB.getKey();
Account anltAcc = accountImdg.getFirstObjectByFieldValues(
Map.of(
"currency", currency,
"accountType", AccountType.Anlt.getKey()
)
);
if (anltAcc != null) {
return Optional.of(anltAcc.getAccount());
}
}
return Optional.empty();
}
/**
* company-service сообщение об успешном добавлении ТКР клиента с параметром tradingClearingRegistry.code

View file

@ -0,0 +1,130 @@
package ru.spcex.clearing.account.service.v2;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgResponse;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.Tkr;
import ru.spcex.platform.enumeration.CompanySymbol;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Service
public class GatewayRequestCreator {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
public GatewayRequestCreator(ImdgProvider imdgProvider) {
this.imdgProvider = imdgProvider;
}
public Tkr crateErrorTkrToGateway(TkrAccount tkrAccount, Optional<String> errorMsg) {
Tkr tkr = new Tkr();
tkr.setTkrCode(tkrAccount.getTkrCode());
tkr.setClientCode(tkrAccount.getClientCode());
tkr.setCompanyId(tkrAccount.getCompanyId());
tkr.setDepoAccount(tkrAccount.getDepoAccount());
tkr.setMoneyAccounts(tkrAccount.getMoneyAccounts()
.stream()
.map(this::convertAccountToResponse)
.collect(Collectors.toList()));
errorMsg.ifPresent(tkr::setErrorMessage);
return tkr;
}
public Tkr createTkrGatewayReq(TradingClearingRegistry tradingClearingRegistry) {
Tkr tkr = new Tkr();
log.debug("Found TKR with id: {} and code: {}", tradingClearingRegistry.getId(), tradingClearingRegistry.getCode());
Imdg<Company> companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
Imdg<CompanySymbols> companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
Imdg<ClientCode> clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
Imdg<Account> accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = imdgProvider.
getImdg(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
Company company = companyImdg.getSingleObjectByID(tradingClearingRegistry.getCompanyId());
CompanySymbols companySymbols = companySymbolsImdg.getSingleObjectByFieldValues(
Map.of(
"companySymbol", CompanySymbol.UUID.getKey(),
"companyId", company.getId()
)
);
ClientCode clientCode = clientCodeImdg.getFirstObjectByFieldValues(
Map.of("tradingClearingRegistryId", tradingClearingRegistry.getId())
);
tkr.setCompanyId(companySymbols.getCompanySymbolValue());
tkr.setTradingCode(Long.valueOf(company.getTradingCode()));
tkr.setTkrCode(tradingClearingRegistry.getCode());
tkr.setTkrType(tradingClearingRegistry.getTradingClearingRegistryPurpose());
tkr.setActive(Status.Active.equalsByKey(tradingClearingRegistry.getStatus()));
String accountType;
if (clientCode == null) {
if (TradingClearingRegistryType.Client_B.equalsByKey(
tradingClearingRegistry.getTradingClearingRegistryType())) {
accountType = "Клиентский общий";
} else {
accountType = "Общий";
}
} else {
tkr.setClientCode(clientCode.getCode());
accountType = "Клиентский обособленный";
}
tkr.setAccountTypeName(accountType);
if (tradingClearingRegistry.getDepoAccountId() != null) {
Account depoAccount = accountImdg.getSingleObjectByID(tradingClearingRegistry.getDepoAccountId());
if (depoAccount != null) {
tkr.setDepoAccount(depoAccount.getAccount());
}
}
{
if (tradingClearingRegistry.getMoneyAccountId() != null) {
Account moneyAccount = accountImdg.getSingleObjectByID(tradingClearingRegistry.getMoneyAccountId());
MoneyAccountMsgResponse moneyAccountMsg = new MoneyAccountMsgResponse();
moneyAccountMsg.setAccount(moneyAccount.getAccount());
moneyAccountMsg.setCurrCode(StringUtils.hasText(moneyAccount.getCurrency()) ? moneyAccount.getCurrency() : "RUB");
moneyAccountMsg.setActive(Status.Active.equalsByKey(moneyAccount.getStatus()));
tkr.getMoneyAccounts().add(moneyAccountMsg);
}
}
{
Collection<TradingClearingRegistryList> tradingClearingRegistries = tradingClearingRegistryListImdg.getCollectionObjectsByFieldValues(
Map.of(
"tradingClearingRegistryId", tradingClearingRegistry.getId()
)
);
for (TradingClearingRegistryList tkrList : tradingClearingRegistries) {
Account additionalAcc = accountImdg.getSingleObjectByID(tkrList.getAccountId());
MoneyAccountMsgResponse moneyAccountMsg = new MoneyAccountMsgResponse();
moneyAccountMsg.setAccount(additionalAcc.getAccount());
moneyAccountMsg.setCurrCode(StringUtils.hasText(additionalAcc.getCurrency()) ? additionalAcc.getCurrency() : "RUB");
moneyAccountMsg.setActive(Status.Active.equalsByKey(additionalAcc.getStatus()));
tkr.getMoneyAccounts().add(moneyAccountMsg);
}
}
return tkr;
}
private MoneyAccountMsgResponse convertAccountToResponse(MoneyAccountMsgRequest moneyAccountMsgRequest) {
MoneyAccountMsgResponse msgResponse = new MoneyAccountMsgResponse();
msgResponse.setAccount(moneyAccountMsgRequest.getAccount());
msgResponse.setCurrCode(moneyAccountMsgRequest.getCurrCode());
return msgResponse;
}
}

View file

@ -0,0 +1,122 @@
package ru.spcex.clearing.account.service.v2.facade;
import java.time.Instant;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.ClientCode;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryListNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.platform.classes.base.interfaces.IClearingFacade;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class ClientCodeFacade implements IClearingFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final Imdg<ClientCode> clientCodeImdg;
private final TradingClearingRegistryFacade tradingClearingRegistryFacade;
private final TradingClearingRegistryListFacade tradingClearingRegistryListFacade;
public ClientCodeFacade(ImdgProvider imdgProvider,
TradingClearingRegistryFacade tradingClearingRegistryFacade, TradingClearingRegistryListFacade tradingClearingRegistryListFacade) {
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.imdgProvider = imdgProvider;
this.clientCodeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
this.tradingClearingRegistryFacade = tradingClearingRegistryFacade;
this.tradingClearingRegistryListFacade = tradingClearingRegistryListFacade;
}
/**
* Создает clientCode, TCR и опционально TCRList, если указаны валюты.
*/
public void createClientCode(ClientCodeNewRequest request, IValidator validator) {
log.trace("Start process creating new client code");
TradingClearingRegistry tradingClearingRegistry;
{
log.debug("Trading Clearing Registry is not exist, creating...");
TradingClearingRegistryNewRequest creationTcrRequest = new TradingClearingRegistryNewRequest();
creationTcrRequest.setCompanyId(request.getCompanyId());
creationTcrRequest.setMoneyAccountId(request.getMoneyAccountId());
creationTcrRequest.setDepoAccountId(request.getDepoAccountId());
creationTcrRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Client_B.getKey());
tradingClearingRegistry = tradingClearingRegistryFacade.createTradingClearingRegistry(creationTcrRequest, null);
}
{
if (request.getCurrencyAccountList() != null && !request.getCurrencyAccountList().isEmpty()) {
TradingClearingRegistryListNewRequest tcrListNew = new TradingClearingRegistryListNewRequest();
tcrListNew.setTradingClearingRegistryId(tradingClearingRegistry.getId());
tcrListNew.setCurrencyAccountList(request.getCurrencyAccountList());
List<Long> tkrListIds = tradingClearingRegistryListFacade.createTradingClearingRegistryList(tcrListNew, null);
}
}
{
ClientCode clientCode = new ClientCode();
clientCode.setCreated(Instant.now());
clientCode.setUpdated(clientCode.getCreated());
clientCode.setCompanyId(request.getCompanyId());
clientCode.setCode(request.getCode());
clientCode.setMoneyAccountId(request.getMoneyAccountId());
clientCode.setDepoAccountId(request.getDepoAccountId());
clientCode.setStatus(request.getStatus());
clientCodeImdg.insert(clientCode);
log.debug("successfully processed, new clientCode id {}", clientCode.getId());
}
}
// public void createClientCode(ClientCodeBusiness businessRequest) {
// log.trace("Start process creating new client code");
// TradingClearingRegistry tradingClearingRegistry;
// {
// log.debug("Trading Clearing Registry is not exist, creating...");
// TradingClearingRegistryBusiness creationTcrRequest = new TradingClearingRegistryBusiness();
// creationTcrRequest.setCompanyId(request.getCompanyId());
// creationTcrRequest.setMoneyAccountId(request.getMoneyAccountId());
// creationTcrRequest.setDepoAccountId(request.getDepoAccountId());
// creationTcrRequest.setTradingClearingRegistryType(TradingClearingRegistryType.Client_B.getKey());
// tradingClearingRegistry = tradingClearingRegistryFacade.createTradingClearingRegistry(creationTcrRequest, null);
// }
// {
// if (request.getCurrencyAccountList() != null && !request.getCurrencyAccountList().isEmpty()) {
// TradingClearingRegistryListNewRequest tcrListNew = new TradingClearingRegistryListNewRequest();
// tcrListNew.setTradingClearingRegistryId(tradingClearingRegistry.getId());
// tcrListNew.setCurrencyAccountList(request.getCurrencyAccountList());
// List<Long> tkrListIds = tradingClearingRegistryListFacade.createTradingClearingRegistryList(tcrListNew, null);
// }
// }
//
// {
// ClientCode clientCode = new ClientCode();
// clientCode.setCreated(Instant.now());
// clientCode.setUpdated(clientCode.getCreated());
//
// clientCode.setCompanyId(request.getCompanyId());
// clientCode.setCode(request.getCode());
// clientCode.setMoneyAccountId(request.getMoneyAccountId());
// clientCode.setDepoAccountId(request.getDepoAccountId());
// clientCode.setStatus(request.getStatus());
// clientCodeImdg.insert(clientCode);
// log.debug("successfully processed, new clientCode id {}", clientCode.getId());
// }
// }
public void lock() {
// tradingClearingRegistryFacade.lock()
// tradingClearingRegistryListFacade.lock()
}
public void unlock() {
// tradingClearingRegistryFacade.lock()
// tradingClearingRegistryListFacade.lock()
}
}

View file

@ -0,0 +1,248 @@
package ru.spcex.clearing.account.service.v2.facade;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.account.model.TradingClearingRegistryBusiness;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class TradingClearingRegistryFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final KafkaSender kafkaSender;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<DepoAccount> depoAccountImdg;
private final Imdg<ClearingAccount> clearingAccountImdg;
private final Imdg<Company> companyImdg;
public TradingClearingRegistryFacade(ImdgProvider imdgProvider,
KafkaSender kafkaSender) {
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry,
TradingClearingRegistry.class);
this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.kafkaSender = kafkaSender;
}
public TradingClearingRegistry createTradingClearingRegistry(TradingClearingRegistryNewRequest request,
IValidator validator) {
Long id = tradingClearingRegistryImdg.nextIDSequenceFor();
TradingClearingRegistry tradingClearingRegistry = new TradingClearingRegistry();
tradingClearingRegistry.setId(id);
tradingClearingRegistry.setCompanyId(request.getCompanyId());
tradingClearingRegistry.setMoneyAccountId(request.getMoneyAccountId());
tradingClearingRegistry.setDepoAccountId(request.getDepoAccountId());
DepoAccount depoAccount = request.getDepoAccountId() != null ?
depoAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", request.getDepoAccountId())) : null;
ClearingAccount clearingAccount = request.getMoneyAccountId() != null ?
clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", request.getMoneyAccountId())) : null;
if (request.getStatus() == null) {
tradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
log.trace("TCR status in request not set. Use default: {}", tradingClearingRegistry.getStatus());
} else {
tradingClearingRegistry.setStatus(request.getStatus());
log.trace("TCR status in request set: {}", tradingClearingRegistry.getStatus());
}
String tradingRegistryType;
if (request.getTradingClearingRegistryType() != null) {
tradingRegistryType = request.getTradingClearingRegistryType();
} else if (depoAccount != null) {
tradingRegistryType = depoAccount.getDepoAccountType();
} else {
if (clearingAccount != null) tradingRegistryType = clearingAccount.getClearingAccountType();
else tradingRegistryType = TradingClearingRegistryType.Owner_A.getKey();
}
tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType);
//http://jira.mfd.msk:8088/browse/CLS-631#comment-60200
TradingClearingRegistryPurpose registryPurpose = TradingClearingRegistryPurpose.C;
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = companyImdg.getSingleObjectByID(request.getCompanyId());
Long seqId = companySequenceNextId(request.getCompanyId(), registryPurpose, tradingRegistryType);
String code = makeCode(company.getClearingCode(), registryPurpose, tradingRegistryType, seqId);
log.debug("For new TCR.id={} of companyId={} next sequence={}; code={}", id, request.getCompanyId(), seqId, code);
tradingClearingRegistry.setCode(code);
Instant now = Instant.now();
tradingClearingRegistry.setCreated(now);
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistryImdg.insert(tradingClearingRegistry);
log.info("New TCR.id={} was created.", tradingClearingRegistry.getId());
sendNotificationToReportSvc(tradingClearingRegistry);
sendNotificationToClearingSvc(tradingClearingRegistry);
log.debug("successfully processed, id {}", id);
return tradingClearingRegistry;
}
public TradingClearingRegistry createTradingClearingRegistry(TradingClearingRegistryBusiness businessRequest) {
Long id = tradingClearingRegistryImdg.nextIDSequenceFor();
TradingClearingRegistry tradingClearingRegistry = new TradingClearingRegistry();
tradingClearingRegistry.setId(id);
tradingClearingRegistry.setCompanyId(businessRequest.getCompany().getId());
tradingClearingRegistry.setMoneyAccountId(businessRequest.getMoneyAccount().getId());
businessRequest.getDepoAccount().ifPresent(depoAccount ->
tradingClearingRegistry.setDepoAccountId(depoAccount.getId()));
;
if (businessRequest.getTradingClearingRegistryType().isEmpty()){
if (businessRequest.getDepoAccount().isPresent()){
}
}
// ClearingAccount clearingAccount = request.getMoneyAccountId() != null ?
// clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", request.getMoneyAccountId())) : null;
//
// if (request.getStatus() == null) {
// tradingClearingRegistry.setStatus(ServiceStatus.Active.getKey());
// log.trace("TCR status in request not set. Use default: {}", tradingClearingRegistry.getStatus());
// } else {
// tradingClearingRegistry.setStatus(request.getStatus());
// log.trace("TCR status in request set: {}", tradingClearingRegistry.getStatus());
// }
//
// String tradingRegistryType;
// if (request.getTradingClearingRegistryType() != null) {
// tradingRegistryType = request.getTradingClearingRegistryType();
// } else if (depoAccount != null) {
// tradingRegistryType = depoAccount.getDepoAccountType();
// } else {
// if (clearingAccount != null) tradingRegistryType = clearingAccount.getClearingAccountType();
// else tradingRegistryType = TradingClearingRegistryType.Owner_A.getKey();
// }
// tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType);
//http://jira.mfd.msk:8088/browse/CLS-631#comment-60200
TradingClearingRegistryPurpose registryPurpose = TradingClearingRegistryPurpose.C;
tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey());
Company company = businessRequest.getCompany();
// Long seqId = companySequenceNextId(company.getId(), registryPurpose, tradingRegistryType);
// String code = makeCode(company.getClearingCode(), registryPurpose, tradingRegistryType, seqId);
// log.debug("For new TCR.id={} of companyId={} next sequence={}; code={}", id, company.getId(), seqId, code);
// tradingClearingRegistry.setCode(code);
Instant now = Instant.now();
tradingClearingRegistry.setCreated(now);
tradingClearingRegistry.setUpdated(now);
tradingClearingRegistryImdg.insert(tradingClearingRegistry);
log.info("New TCR.id={} was created.", tradingClearingRegistry.getId());
sendNotificationToReportSvc(tradingClearingRegistry);
sendNotificationToClearingSvc(tradingClearingRegistry);
log.debug("successfully processed, id {}", id);
return tradingClearingRegistry;
}
private Long companySequenceNextId(Long companyId,
TradingClearingRegistryPurpose registryPurpose,
String tradingRegistryType) {
Imdg<TradingClearingRegistry> tradingClearingRegistryImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
);
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
Collection<TradingClearingRegistry> existTCR = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(
pb.and(
pb.equals("companyId", companyId),
pb.equals("tradingClearingRegistryPurpose", registryPurpose.getKey()),
pb.equals("tradingClearingRegistryType", tradingRegistryType)
)
);
if (existTCR.isEmpty()) {
log.trace("For company id={} not found exist TCR.", companyId);
return 1L;
}
log.trace("For company id={} found {} exist TCR.", companyId, existTCR.size());
long maxN = 0;
for (TradingClearingRegistry tcr : existTCR) {
Long codeN = parseCodeSeqId(tcr.getCode());
if (codeN != null) {
if (maxN < codeN)
maxN = codeN;
}
}
return maxN + 1;
}
private Long parseCodeSeqId(String code) {
if (code == null || code.isBlank())
return null;
try {
String toParse = code.trim();
if (toParse.length() > 5)
toParse = toParse.substring(toParse.length() - 5);
return Long.parseLong(toParse);
} catch (NumberFormatException nan) {
log.warn("Can not parse number from TCR code \"{}\": {}", code, nan.getMessage());
}
return null;
}
private String makeCode(String companyClearingCode,
TradingClearingRegistryPurpose registryPurpose,
String tradingRegistryType,
Long id) {
String code;
code = companyClearingCode;
if (code.length() > 4)
code = code.substring(code.length() - 4);
code = "%4s".formatted(code).replace(' ', '0');
// code += registryPurpose.getKey(); // C / M / ...
code += "C";//пока ставим всегда С, возможно придется откатить
String trType = tradingRegistryType + "T"; // 2 символа
code += trType;
String sId = "%5s".formatted(id).replace(' ', '0');
if (sId.length() > 5)
sId = sId.substring(sId.length() - 5);
code += sId;
return code; // 12 символов
}
private void sendNotificationToClearingSvc(TradingClearingRegistry tradingClearingRegistry) {
CreateRegistryRequest request = new CreateRegistryRequest();
request.setCompanyId(tradingClearingRegistry.getCompanyId());
request.setTradingClearingRegistryId(tradingClearingRegistry.getId());
log.debug("Send message to kafka \"{}\": {}", Consts.REGISTRY_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.REGISTRY_NEW, request);
}
/**
* report-service сообщение на формирование уведомления о создании нового ТКР
*/
private void sendNotificationToReportSvc(TradingClearingRegistry tradingClearingRegistry) {
NotificationRequest request = new NotificationRequest();
request.setConsumerId(tradingClearingRegistry.getCompanyId());
log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_NOTIFICATION_NTCR, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.CREATE_NOTIFICATION_NTCR, request);
}
}

View file

@ -0,0 +1,87 @@
package ru.spcex.clearing.account.service.v2.facade;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryListNewRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Service
public class TradingClearingRegistryListFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final KafkaSender kafkaSender;
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg;
private final Imdg<Account> accountImdg;
public TradingClearingRegistryListFacade(ImdgProvider imdgProvider,
KafkaSender kafkaSender) {
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry,
TradingClearingRegistry.class);
this.tradingClearingRegistryListImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistryList,
TradingClearingRegistryList.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.kafkaSender = kafkaSender;
}
public static class Stored {
TradingClearingRegistry tcr;
Account account;
}
public List<Long> createTradingClearingRegistryList(TradingClearingRegistryListNewRequest request,
Stored stored) {
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByID(request.getTradingClearingRegistryId());
Instant now = Instant.now();
List<Long> newIds = new ArrayList<>();
for (Long currAccId : request.getCurrencyAccountList()) {
Long id = tradingClearingRegistryListImdg.nextIDSequenceFor();
TradingClearingRegistryList tradingClearingRegistryList = new TradingClearingRegistryList();
tradingClearingRegistryList.setId(id);
tradingClearingRegistryList.setCreated(now);
tradingClearingRegistryList.setUpdated(now);
tradingClearingRegistryList.setTradingClearingRegistryId(tcr.getId());
tradingClearingRegistryList.setAccountId(currAccId);
Account account = accountImdg.getSingleObjectByID(currAccId);
tradingClearingRegistryList.setCurrency(account.getCurrency());
if (request.getStatus() == null) {
tradingClearingRegistryList.setStatus(ServiceStatus.Active.getKey());
log.trace("TCRList status in request not set. Use default: {}", tradingClearingRegistryList.getStatus());
} else {
tradingClearingRegistryList.setStatus(request.getStatus());
}
tradingClearingRegistryListImdg.insert(tradingClearingRegistryList);
newIds.add(id);
}
log.info("New TCRList.id={} has created.", newIds);
newIds.forEach(listId -> sendNotificationToClearingSvc(listId, tcr));
return newIds;
}
private void sendNotificationToClearingSvc(Long tradingClearingRegistryId, TradingClearingRegistry tcr) {
CreateRegistryRequest request = new CreateRegistryRequest();
request.setTcrListId(tradingClearingRegistryId);
request.setCompanyId(tcr.getCompanyId());
request.setTradingClearingRegistryId(tcr.getId());
log.debug("Send message to kafka \"{}\": {}", Consts.REGISTRY_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.REGISTRY_NEW, request);
}
}

View file

@ -0,0 +1,191 @@
package ru.spcex.clearing.account.service.v2.listeners;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
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.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.account.model.ValidationResult;
import ru.spcex.clearing.account.service.v2.GatewayRequestCreator;
import ru.spcex.clearing.account.service.v2.facade.ClientCodeFacade;
import ru.spcex.clearing.account.service.v2.validators.ClientCodeValidator;
import ru.spcex.clearing.account.validation.ClientCodeStoreObjects;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccountsGatewayRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SendTkrRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.Tkr;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.TradingClearingRegistryType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class ClientCodeMessageListener extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private final ImdgProvider imdgProvider;
private final ClientCodeFacade clientCodeFacade;
private final ClientCodeValidator clientCodeValidator;
private final GatewayRequestCreator gatewayRequestCreator;
private final UserRoleVerification userRoleVerification;
public ClientCodeMessageListener(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaSender,
ImdgProvider imdgProvider,
ClientCodeFacade clientCodeFacade,
ClientCodeValidator clientCodeValidator,
GatewayRequestCreator gatewayRequestCreator,
UserRoleVerification userRoleVerification) {
super(kafkaQueue, kafkaProducer);
this.kafkaSender = kafkaSender;
this.imdgProvider = imdgProvider;
this.clientCodeFacade = clientCodeFacade;
this.clientCodeValidator = clientCodeValidator;
this.gatewayRequestCreator = gatewayRequestCreator;
this.userRoleVerification = userRoleVerification;
}
@Override
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
//from backend-api requests
callback(ClientCodeNewRequest.class)
.setFunction(this::clientCodeNewFromBackend)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
//from gateway requests
callback(TkrAccountsGatewayRequest.class)
.setFunction(this::clientCodeNewFromGateway)
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_FROM_GATEWAY, callbacks::put);
callback(TkrAccountsGatewayRequest.class)
.setFunction(this::clientCodeNewFromGateway)
.forDestination(Consts.DESTINATION_CLIENT_CODE_UPDATE_FROM_GATEWAY, callbacks::put);
init();
}
private RequestInfoUpdate clientCodeNewFromGateway(BaseRequest<TkrAccountsGatewayRequest> tkrRequest) {
clientCodeFacade.lock();
//валидация запроса
TkrAccountsGatewayRequest gatewayRequest = tkrRequest.getRequestPayload();
SendTkrRequest sendTkrRequest = new SendTkrRequest();
sendTkrRequest.setRequestId(gatewayRequest.getRequestId());
boolean isAnyoneInvalid = false;
Map<TkrAccount, ValidationResult> accountsAfterValidation = new HashMap<>();
for (TkrAccount tkrAccount : gatewayRequest.getAccounts()) {
ValidationResult validationResult = clientCodeValidator.checkGatewayRequest(tkrAccount);
if (!validationResult.isValid()) {
log.debug("Validation failed for tkr.client_code {}", tkrAccount.getClientCode());
isAnyoneInvalid = true;
}
accountsAfterValidation.put(tkrAccount, validationResult);
}
if (isAnyoneInvalid) {
log.debug("Create error request to gateway service");
List<Tkr> tkrs = accountsAfterValidation.entrySet()
.stream()
.map(tkrAccountValidationResultEntry ->
gatewayRequestCreator.crateErrorTkrToGateway(
tkrAccountValidationResultEntry.getKey(),
tkrAccountValidationResultEntry.getValue().errorMsg()
))
.toList();
sendTkrRequest.setTkrs(tkrs);
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
return null;
}
//unwrap запроса
for (Map.Entry<TkrAccount, ValidationResult> entry : accountsAfterValidation.entrySet()) {
ClientCodeNewRequest clientCodeNewRequest = new ClientCodeNewRequest();
TkrAccount tkrAccount = entry.getKey();
ValidationResult validationResult = entry.getValue();
log.debug("Creating new clientCode by tkr account: {}", tkrAccount.getClientCode());
IValidator validator = validationResult.validator();
Company company = validator.getStored(ClientCodeStoreObjects.COMPANY);
Optional<Account> depoAccount = validator.getStored(ClientCodeStoreObjects.DEPO_ACCOUNT);
Long depoAccountId = depoAccount.map(Account::getId).orElse(null);
Map<String, Account> accountByCurrency = validator.getStored(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS);
clientCodeNewRequest.setCompanyId(company.getId());
clientCodeNewRequest.setCode(tkrAccount.getClientCode());
clientCodeNewRequest.setDepoAccountId(depoAccountId);
Account moneyAccount = accountByCurrency.get(CurrencyCode.RUB);
clientCodeNewRequest.setMoneyAccountId(moneyAccount.getId());
List<Long> foreignCurrencyList = accountByCurrency.entrySet()
.stream()
.filter(currencyCodeAccountEntry -> !CurrencyCode.RUB.equalsByKey(currencyCodeAccountEntry.getKey()))
.map(currencyCodeAccountEntry -> currencyCodeAccountEntry.getValue().getId())
.toList();
clientCodeNewRequest.setCurrencyAccountList(foreignCurrencyList);
clientCodeFacade.createClientCode(clientCodeNewRequest, validator);
TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(company.getId(),
moneyAccount.getId(), depoAccountId);
sendTkrRequest.getTkrs().add(gatewayRequestCreator.createTkrGatewayReq(tradingClearingRegistry));
log.debug("Success created new clientCode by tkr account: {}", tkrAccount.getClientCode());
}
kafkaSender.sendRequestToQueue(Consts.ACCOUNTS_TO_GATEWAY, sendTkrRequest);
return null;
}
private RequestInfoUpdate clientCodeNewFromBackend(BaseRequest<ClientCodeNewRequest> clientCodeNewRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(clientCodeNewRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
ClientCodeNewRequest request = clientCodeNewRequest.getRequestPayload();
ValidationResult validationResult = clientCodeValidator.checkBackendNewRequest(request);
if (!validationResult.isValid()) {
return makeErrorResponse(clientCodeNewRequest, validationResult);
}
clientCodeFacade.createClientCode(request, validationResult.validator());
return null;
}
private RequestInfoUpdate makeErrorResponse(BaseRequest<ClientCodeNewRequest> clientCodeNewRequest,
ValidationResult validationResult) {
RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate();
requestInfoUpdate.setId(clientCodeNewRequest.getId());
requestInfoUpdate.setStatus(Status.Error);
validationResult.errorMsg().ifPresent(requestInfoUpdate::setMessage);
return requestInfoUpdate;
}
private TradingClearingRegistry selectTradingClearingRegistry(Long companyId, Long moneyAccountId, Long depoAccountId) {
Map<String, Comparable<?>> query = new HashMap<>();
query.put("companyId", companyId);
query.put("moneyAccountId", moneyAccountId);
query.put("tradingClearingRegistryType", TradingClearingRegistryType.Client_B.getKey());
if (depoAccountId != null) {
query.put("depoAccountId", depoAccountId);
}
Imdg<TradingClearingRegistry> tradingClearingRegistryImdg = imdgProvider
.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
TradingClearingRegistry result = tradingClearingRegistryImdg.getFirstObjectByFieldValues(query);
log.trace("TradingClearingRegistry by: {}; {} found", query, result == null ? "not" : "");
return result;
}
}

View file

@ -0,0 +1,58 @@
package ru.spcex.clearing.account.service.v2.validators;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.account.model.ValidationResult;
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.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class ClientCodeValidator {
private final Logger log = LoggerFactory.getLogger(getClass());
private final UserRoleVerification userRoleVerification;
private final Function<ClientCodeNewRequest, IValidator> clientCodeNewRequestValidator;
private final Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator;
private final Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator;
private final Function<TkrAccount, IValidator> tkrAccountsGatewayValidator;
private final IMessageResolver messageResolver;
public ClientCodeValidator(UserRoleVerification userRoleVerification,
Function<ClientCodeNewRequest, IValidator> clientCodeNewRequestValidator,
Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator,
Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator,
Function<TkrAccount, IValidator> tkrAccountsGatewayValidator,
IMessageResolver messageResolver) {
this.userRoleVerification = userRoleVerification;
this.clientCodeNewRequestValidator = clientCodeNewRequestValidator;
this.clientCodeUpdateRequestValidator = clientCodeUpdateRequestValidator;
this.clientCodeDeleteRequestValidator = clientCodeDeleteRequestValidator;
this.tkrAccountsGatewayValidator = tkrAccountsGatewayValidator;
this.messageResolver = messageResolver;
}
public ValidationResult checkGatewayRequest(TkrAccount gatewayAccountRequest) {
return standardValidation(tkrAccountsGatewayValidator, gatewayAccountRequest);
}
public ValidationResult checkBackendNewRequest(ClientCodeNewRequest clientCodeNewRequest) {
return standardValidation(clientCodeNewRequestValidator, clientCodeNewRequest);
}
private <T> ValidationResult standardValidation(Function<T, IValidator> requestValidator, T request) {
IValidator validator = requestValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
AtomicReference<Optional<String>> errorMsg = new AtomicReference<>();
error.ifPresent(err -> errorMsg.set(Optional.of(messageResolver.resolve(err))));
return new ValidationResult(validator, error, errorMsg.get());
}
}

View file

@ -1,5 +1,7 @@
package ru.spcex.clearing.account.validation;
import java.util.Map;
import java.util.Optional;
import org.springframework.util.StringUtils;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
@ -12,9 +14,6 @@ import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Map;
import java.util.Optional;
public enum AccountValidationRule implements IValidationRule<ImdgValidationContext<BankAccountNewRequest>> {
CompanyPresent() {

View file

@ -0,0 +1,75 @@
package ru.spcex.clearing.account.validation;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public enum BackendClientCodeValidationRule implements IValidationRule<ImdgValidationContext<ClientCodeNewRequest>> {
AllAccountsPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<ClientCodeNewRequest> context) {
ClientCodeNewRequest validatedObject = context.getValidatedObject();
List<Long> ids = validatedObject.getCurrencyAccountList();
if (ids == null || ids.isEmpty()) {
return empty(); // необязательное поле
}
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
for (Long id : ids) {
if (id == null) { // null значения в массиве не ожидаются
return of(AccountError.RequiredFieldEmpty, "accountId");
}
Account byIdObject = imdg.getSingleObjectByID(id);
if (byIdObject == null)
return of(AccountError.AccountNotFound, id, "accountId");
}
return empty();
}
},
TcrIsNotPresentByAccount() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<ClientCodeNewRequest> context) {
ClientCodeNewRequest validatedObject = context.getValidatedObject();
List<Long> currencyIds = validatedObject.getCurrencyAccountList();
Long moneyAccountId = validatedObject.getMoneyAccountId();
Imdg<TradingClearingRegistry> tradingClearingRegistryImdg =
context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg =
context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
TradingClearingRegistry tcrByMoneyAccount = tradingClearingRegistryImdg.getFirstObjectByFieldValues(
Map.of(
"moneyAccountId", moneyAccountId,
"status", Status.Active.getKey()
));
if (tcrByMoneyAccount != null) {
return of(AccountError.TradingClearingRegistryAlreadyExist);
}
for (Long id : currencyIds) {
TradingClearingRegistryList tcrList = tradingClearingRegistryListImdg.getFirstObjectByFieldValues(
Map.of(
"accountId", id,
"status", Status.Active.getKey()
));
if (tcrList != null) {
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed);
}
}
return empty();
}
}
}

View file

@ -0,0 +1,9 @@
package ru.spcex.clearing.account.validation;
public enum ClientCodeStoreObjects {
COMPANY,
MONEY_ACCOUNT,
DEPO_ACCOUNT,
MAPPED_TO_CURRENCY_ACCOUNTS,
TRADING_CLEARING_REGISTRY
}

View file

@ -0,0 +1,160 @@
package ru.spcex.clearing.account.validation;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.util.StringUtils;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgRequest;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.Status;
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;
public enum GatewayClientCodeValidationRule implements IValidationRule<ImdgValidationContext<TkrAccount>> {
CompanyPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
TkrAccount validatedObject = context.getValidatedObject();
Long tradingCode = validatedObject.getTradingCode();
if (tradingCode == null) {
return of(AccountError.RequiredFieldEmpty, "trading_code");
}
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
Company company = companyImdg.getFirstObjectByFieldValues(
Map.of("tradingCode", String.valueOf(tradingCode))
);
if (company == null) {
return of(AccountError.COMPANY_NOT_FOUND_GTW, "trading_code");
}
context.storeObject(ClientCodeStoreObjects.COMPANY, company);
return Optional.empty();
}
},
AllAccountsPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
TkrAccount validatedObject = context.getValidatedObject();
List<MoneyAccountMsgRequest> accountList = validatedObject.getMoneyAccounts();
if (accountList == null || accountList.isEmpty()) {
return of(AccountError.RequiredFieldEmpty, "money_account");
}
List<String> currencies = accountList.stream().map(MoneyAccountMsgRequest::getCurrCode).toList();
if (!currencies.contains(CurrencyCode.RUB.getKey())) {
return of(AccountError.RequiredFieldEmpty, "money_account");
}
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Map<String, Account> accountByCurrency = new HashMap<>();
for (MoneyAccountMsgRequest moneyAccountMsg : accountList) {
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
ImdgPredicate currencyPredicate;
if (!StringUtils.hasText(moneyAccountMsg.getAccount())){
return of(AccountError.RequiredFieldEmpty, "account");
}
ImdgPredicate accountPredicate = predicateBuilder.equals("account", moneyAccountMsg.getAccount());
if (moneyAccountMsg.getCurrCode().equals(CurrencyCode.RUB.getKey())) {
currencyPredicate = predicateBuilder.or(
predicateBuilder.equals("currency", CurrencyCode.RUB.getKey()),
predicateBuilder.isNull("currency")
);
} else {
currencyPredicate = predicateBuilder.equals("currency", moneyAccountMsg.getCurrCode());
}
Account account = imdg.getFirstObjectByPredicate(
predicateBuilder.and(accountPredicate, currencyPredicate)
);
if (account == null) {
return of(AccountError.ACCOUNT_NOT_FOUND_GTW, moneyAccountMsg.getAccount(), "money_account");
}
accountByCurrency.put(account.getCurrency(), account);
}
context.storeObject(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS, accountByCurrency);
return Optional.empty();
}
},
DepoAccountsPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
TkrAccount validatedObject = context.getValidatedObject();
String depoAccountVal = validatedObject.getDepoAccount();
if (!StringUtils.hasText(depoAccountVal)) {
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT, Optional.empty());
return empty();
}
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account depoAccount = imdg.getFirstObjectByFieldValues(
Map.of("account", depoAccountVal)
);
if (depoAccount == null) {
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT, Optional.empty());
return of(AccountError.DepoAccountNotFound, "depo_account");
}
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT, depoAccount);
return Optional.empty();
}
},
TcrIsNotPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
Map<String, Account> accountByCurrency = context.getStoredObject(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS);
Account moneyAccount = accountByCurrency.get(CurrencyCode.RUB.getKey());
if (moneyAccount == null) {
return of(AccountError.AccountNotFound);
}
Imdg<TradingClearingRegistry> imdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry,
TradingClearingRegistry.class);
TradingClearingRegistry tcr = imdg.getFirstObjectByFieldValues(
Map.of(
"moneyAccountId", moneyAccount.getId(),
"status", Status.Active.getKey()
)
);
if (tcr != null) {
return of(AccountError.TradingClearingRegistryAlreadyExist, tcr.getCode(), "code");
}
return Optional.empty();
}
},
TcrListIsNotPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
Map<String, Account> accountByCurrency = context.getStoredObject(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS);
List<Account> currencyAccounts = accountByCurrency.entrySet().stream()
.filter(stringAccountEntry -> !stringAccountEntry.getKey().equals(CurrencyCode.RUB.getKey()))
.map(Map.Entry::getValue).toList();
if (currencyAccounts.isEmpty()) {
return empty();
}
List<String> currencies = currencyAccounts.stream().map(Account::getCurrency).toList();
Imdg<TradingClearingRegistryList> imdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistryList,
TradingClearingRegistryList.class);
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
Collection<TradingClearingRegistryList> tcrList = imdg.getCollectionObjectsByPredicate(
predicateBuilder.and(
predicateBuilder.in("currency", currencies.toArray(new String[0])),
predicateBuilder.equals("status", Status.Active.getKey())
));
if (!tcrList.isEmpty()) {
return of(AccountError.TradingClearingRegistryAlreadyExist, tcrList.iterator().next().getCurrency(), "currency");
}
return Optional.empty();
}
}
}

View file

@ -11,7 +11,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
@ -112,6 +112,11 @@
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
@ -185,7 +190,7 @@
</configuration>
</execution>
<execution>
<!-- Generate Data.sql from META and DATA file
<!-- Generate dictionaries.sql from META and DATA file
command: mvn xml:transform@data -->
<id>data</id>
<goals>
@ -196,13 +201,13 @@
<transformationSet>
<dir>src/main/resources/meta</dir>
<includes>
<include>data.xml</include>
<include>dictionaries.xml</include>
</includes>
<stylesheet>src/main/resources/meta/xsl/data.xsl</stylesheet>
<fileMappers>
<fileMapper
implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>data.sql</targetExtension>
<targetExtension>dictionaries.sql</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>

View file

@ -4,10 +4,13 @@ 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.web.bind.annotation.*;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.registry.*;
@ -18,7 +21,12 @@ 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 ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@ -26,12 +34,17 @@ import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/registries")
public class RegistryController extends AbstractQueueController {
protected final Logger log = LoggerFactory.getLogger(getClass());
private final IStateLoader stateLoader;
private final ImdgPredicateBuilder predicateBuilder;
@Autowired
public RegistryController(IOperator operator, IStateLoader stateLoader) {
public RegistryController(IOperator operator, IStateLoader stateLoader, ImdgProvider imdgProvider) {
super(operator);
this.stateLoader = stateLoader;
this.predicateBuilder = imdgProvider
.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class)
.predicateBuilder();
}
@ApiOperation(value = "get all registries.")
@ -39,9 +52,25 @@ public class RegistryController extends AbstractQueueController {
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_Registry, Registry.class);
// long t1 = System.currentTimeMillis();
ImdgPredicate filter = predicateBuilder.or(
predicateBuilder.equals("registryDesignation", RegistryDesignation.A.getKey()),
predicateBuilder.equals("registryDesignation", RegistryDesignation.D.getKey()),
predicateBuilder.and(
predicateBuilder.or(
predicateBuilder.equals("registryDesignation", RegistryDesignation.O.getKey()),
predicateBuilder.equals("registryDesignation", RegistryDesignation.T.getKey())
),
predicateBuilder.greatEqual("settlementDate", LocalDate.now())
)
);
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_Registry, Registry.class,
filter);
// long t2 = System.currentTimeMillis();
// log.info("Info select and format {} data {}", all.size(), t2 - t1);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
// log.info("Info select and format {} data {}", all.size(), System.currentTimeMillis() - t2);
return response;
}

View file

@ -104,7 +104,7 @@ public class LauncherController extends AbstractQueueController {
if (taskEnum == null) {
throw new NotFound404Exception("task dictionary element with code '" + launcherNew.getTask() + "'");
}
if (!IEnumKey.contains(taskEnum.getCode(), Task.startOfClearing, Task.dbfExport_OUTV, Task.getAllBalance)) {
if (!IEnumKey.contains(taskEnum.getCode(), Task.startOfClearing, Task.dbfExport_OUTV, Task.getAllBalance, Task.createRegistry_GBRR)) {
log.warn(String.format("Task %s not support request with body", taskEnum.getCode()));
} // else В мете эти модели с дополнительными параметрами (OUTV).
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

View file

@ -237,6 +237,19 @@ public class SdfsController extends AbstractQueueController {
return response;
}
@ApiOperation(value = "get all S_DF51")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df51", method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAllSdf51() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(
IMDGDistributedNames.Map_SDf51,
SDf51.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "get all S_DF52")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(value = "s-df52", method = RequestMethod.GET)

View file

@ -50,6 +50,9 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
@ApiModelProperty(value = "SWIFT", example = "ABCDE")
@JsonProperty
private String swiftCode;
@ApiModelProperty(value = "Код SWIFT посредника", example = "ABCDE")
@JsonProperty
private String intermediarySwiftCode;
@Override
public BankAccountNewRequest toRequest() {
@ -65,6 +68,7 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
req.setAccount(this.account);
req.setCompanyId(this.companyId);
req.setSwiftCode(swiftCode);
req.setIntermediarySwiftCode(intermediarySwiftCode);
return req;
}
@ -161,4 +165,12 @@ public class BankAccountNewAction implements IAction<BankAccountNewRequest> {
public void setSwiftCode(String swiftCode) {
this.swiftCode = swiftCode;
}
public String getIntermediarySwiftCode() {
return intermediarySwiftCode;
}
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
}

View file

@ -41,6 +41,9 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
@ApiModelProperty(value = "SWIFT", example = "ABCDE")
@JsonProperty
private String swiftCode;
@ApiModelProperty(value = "Код SWIFT посредника", example = "ABCDE")
@JsonProperty
private String intermediarySwiftCode;
@ApiModelProperty(value = "Номер счета", example = "11111222223333344444")
private String account;
@ -59,6 +62,7 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
req.setTaxRegistrationReasonCode(this.taxRegistrationReasonCode);
req.setAccount(this.account);
req.setSwiftCode(swiftCode);
req.setIntermediarySwiftCode(intermediarySwiftCode);
return req;
}
@ -155,4 +159,12 @@ public class BankAccountUpdateAction implements IAction<BankAccountUpdateRequest
public void setSwiftCode(String swiftCode) {
this.swiftCode = swiftCode;
}
public String getIntermediarySwiftCode() {
return intermediarySwiftCode;
}
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
}

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.backendapi.controller.request.cud.schedule;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@ -9,11 +10,13 @@ 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.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer;
import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalTimeDeserializer;
import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalTimeSerializer;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Collections;
@ -65,6 +68,9 @@ public class LauncherNew implements IAction<Object> {
@ApiModelProperty(value = "Участник получатель", example = "1000")
@JsonProperty
private Long addresseeId;
@ApiModelProperty(value = "Корреспондентский счет", example = "1000")
@JsonProperty
private Long correspondentAccountId;
@ApiModelProperty(value = "Наименование счета получателя", example = "1000")
@JsonProperty
private Long debitLeg_accountId;
@ -78,6 +84,15 @@ public class LauncherNew implements IAction<Object> {
@JsonProperty
public LocalTime fromTime;
@ApiModelProperty(value = "Дата с", example = "2024-01-02")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonProperty
public LocalDate fromDate;
@ApiModelProperty(value = "Дата по", example = "2024-03-02")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonProperty
public LocalDate toDate;
@Override
public Object toRequest() {
LauncherCommandRequest taskRunnerCommandRequest = new LauncherCommandRequest();
@ -99,6 +114,8 @@ public class LauncherNew implements IAction<Object> {
taskRunnerCommandRequest.setDebitLeg_accountId(debitLeg_accountId);
taskRunnerCommandRequest.setFromTime(fromTime);
taskRunnerCommandRequest.setSwiftCode(swiftCode);
taskRunnerCommandRequest.setFromDate(fromDate);
taskRunnerCommandRequest.setToDate(toDate);
return taskRunnerCommandRequest;
}
@ -228,6 +245,14 @@ public class LauncherNew implements IAction<Object> {
this.addresseeId = addresseeId;
}
public Long getCorrespondentAccountId() {
return correspondentAccountId;
}
public void setCorrespondentAccountId(Long correspondentAccountId) {
this.correspondentAccountId = correspondentAccountId;
}
public Long getDebitLeg_accountId() {
return debitLeg_accountId;
}
@ -259,4 +284,20 @@ public class LauncherNew implements IAction<Object> {
public void setFromTime(LocalTime fromTime) {
this.fromTime = fromTime;
}
public LocalDate getFromDate() {
return fromDate;
}
public void setFromDate(LocalDate fromDate) {
this.fromDate = fromDate;
}
public LocalDate getToDate() {
return toDate;
}
public void setToDate(LocalDate toDate) {
this.toDate = toDate;
}
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<meta version="3.11.0.78">
<meta version="3.12.2.93">
<enums>
<allowed id="1" code="ALWD" name="Разрешено"/>
<allowed id="2" code="DEND" name="Запрещено"/>
@ -9,6 +9,7 @@
<section id="1" code="MKR" name="Секция Денежного рынка МКР"/>
<section id="2" code="FOND" name="Фондовая секция"/>
<section id="3" code="CURR" name="Валютная секция"/>
<section id="4" code="MULT" name="Единая"/>
<userRole id="1" code="ADMN" name="Администратор Клиринга МКР"/>
<userRole id="2" code="SPVS" name="Супервайзер Клиринга МКР"/>
<userRole id="3" code="SCRT" name="Администратор безопасности Клиринга МКР"/>
@ -61,7 +62,7 @@
<documentType id="19" code="XCNT" name="Документ о расторжении Договора клиринга"/>
<documentType id="20" code="LICD" name="Документ о дилерской лицензии"/>
<documentType id="21" code="LICT" name="Документ о лицензии по управлению ЦБ"/>
<documentType id="22" code="LICС" name="Документ о лицензии по брокерской деятельности ПФИ (производных финансовых инструментов)"/>
<documentType id="22" code="LICC" name="Документ о лицензии по брокерской деятельности ПФИ (производных финансовых инструментов)"/>
<documentType id="23" code="LICF" name="Документ о лицензии форекс-дилера"/>
<documentType id="24" code="LICM" name="Документ о лицензии на управление инвестиционными фондами, паевыми инвестиционными фондами, негосударственными пенсионными фондами"/>
<companySymbol id="1" code="INN" name="Индивидуальный налоговый номер" shortname="ИНН"/>
@ -75,7 +76,7 @@
<companySymbol id="9" code="OGRN" name="Основной государственный регистрационный номер" shortname="ОГРН"/>
<companySymbol id="10" code="LICD" name="Номер дилерской лицензии" shortname="Дилерская деятельность"/>
<companySymbol id="11" code="LICT" name="Номер лицензии по управлению ЦБ" shortname="Управление ценными бумагами"/>
<companySymbol id="12" code="LICС" name="Номер лицензии по брокерской деятельности ПФИ (производных финансовых инструментов)" shortname="Брокерская деятельность ПФИ"/>
<companySymbol id="12" code="LICC" name="Номер лицензии по брокерской деятельности ПФИ (производных финансовых инструментов)" shortname="Брокерская деятельность ПФИ"/>
<companySymbol id="13" code="LICF" name="Номер лицензии форекс-дилера" shortname="Деятельность форекс-дилера"/>
<companySymbol id="14" code="LICR" name="Номер брокерской лицензии" shortname="Брокерская деятельность"/>
<companySymbol id="15" code="TRDC" name="Код участника торгов" shortname="Биржевой код"/>
@ -96,9 +97,19 @@
<currencyCode id="840" code="USD" name="Доллар США"/>
<currencyCode id="978" code="EUR" name="Евро"/>
<currencyCode id="156" code="CNY" name="Китайский Юань"/>
<currencyCode id="860" code="UZS" name="Узбекский сум"/>
<currencyCode id="398" code="KZT" name="Тенге"/>
<currencyCode id="51" code="AMD" name="Армянский драм"/>
<currencyCode id="417" code="KGS" name="Сом"/>
<currencyCode id="933" code="BYN" name="Белорусский рубль"/>
<currencyPair id="1" code="EUR/RUB" baseCurrency="EUR" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="2" code="USD/RUB" baseCurrency="USD" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="3" code="CNY/RUВ" baseCurrency="CNY" quoteCurrency="RUВ" majorSign="CONV"/>
<currencyPair id="3" code="CNY/RUB" baseCurrency="CNY" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="4" code="UZS/RUB" baseCurrency="UZS" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="6" code="KGS/RUB" baseCurrency="KGS" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="7" code="KZT/RUB" baseCurrency="KZT" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="8" code="BYN/RUB" baseCurrency="BYN" quoteCurrency="RUB" majorSign="CONV"/>
<currencyPair id="9" code="AMD/RUB" baseCurrency="AMD" quoteCurrency="RUB" majorSign="CONV"/>
<instrumentType id="1" code="RATE" name="Инструмент Денежного рынка"/>
<instrumentType id="2" code="CRNC" name="Валюта"/>
<instrumentType id="3" code="EQTY" name="Акция"/>
@ -120,7 +131,7 @@
<tradingClearingRegistryType id="1" code="A" name="Владелец"/>
<tradingClearingRegistryType id="2" code="B" name="Клиентский"/>
<tradingClearingRegistryType id="3" code="C" name="Клиентский"/> <!-- todo был Попечитель -->
<tradingClearingRegistryType id="3" code="C" name="Клиентский"/> <!-- был Попечитель -->
<tradingClearingRegistryType id="4" code="D" name="Доверительный управляющий"/>
<tradingClearingRegistryType id="5" code="E" name="Эмитент"/>
<tradingClearingRegistryType id="6" code="Z" name="К размещению/выкупу"/>
@ -165,36 +176,6 @@
<registryUnit id="5" code="U" name="Невыясненные"/>
<registryUnit id="5" code="I" name="Списания/зачисления"/>
<registryUnit id="7" code="V" name="Выписка"/>
<registryCode id="1" code="AMAT" name="Денежные средства - общие"/>
<registryCode id="2" code="AMAF" name="Денежные средства - свободные"/>
<registryCode id="3" code="AMAB" name="Денежные средства - блокированные"/>
<registryCode id="4" code="TMAT" name="Требования по деньгам"/>
<registryCode id="5" code="OSAT" name="Обязательства по бумагам"/>
<registryCode id="6" code="OMAT" name="Обязательства по деньгам"/>
<registryCode id="7" code="TSAT" name="Требования по бумагам"/>
<registryCode id="8" code="CMAT" name="Рассчитанные требования по деньгам"/>
<registryCode id="9" code="LSAT" name="Рассчитанные обязательства по бумагам"/>
<registryCode id="10" code="LMAT" name="Рассчитанные обязательства по деньгам"/>
<registryCode id="11" code="CSAT" name="Рассчитанные требования по бумагам"/>
<registryCode id="12" code="AMBT" name="Денежные средства клиента - общие"/>
<registryCode id="13" code="AMBF" name="Денежные средства клиента - свободные"/>
<registryCode id="14" code="AMBB" name="Денежные средства клиента - блокированные"/>
<registryCode id="15" code="TMBT" name="Требования по деньгам (кл)"/>
<registryCode id="16" code="OSBT" name="Обязательства по бумагам (кл)"/>
<registryCode id="17" code="OMBT" name="Обязательства по деньгам (кл)"/>
<registryCode id="18" code="TSBT" name="Требования по бумагам (кл)"/>
<registryCode id="19" code="CMBT" name="Рассчитанные требования по деньгам (кл)"/>
<registryCode id="20" code="LSBT" name="Рассчитанные обязательства по бумагам (кл)"/>
<registryCode id="21" code="LMBT" name="Рассчитанные обязательства по деньгам (кл)"/>
<registryCode id="22" code="CSBT" name="Рассчитанные требования по бумагам (кл)"/>
<registryCode id="23" code="DMAT" name="Возврат депозита"/>
<registryCode id="24" code="DMBT" name="Возврат депозита (кл)"/>
<registryCode id="25" code="ASAT" name="Ценные бумаги - общие"/>
<registryCode id="26" code="ASAF" name="Ценные бумаги - свободные"/>
<registryCode id="27" code="ASAB" name="Ценные бумаги - блокированные"/>
<registryCode id="28" code="DMAX" name="Возврат инициатору"/>
<registryCode id="29" code="DMBX" name="Возврат инициатору (кл)"/>
<registryCode id="30" code="DMAU" name="Денежные средства - невыясненные"/>
<registryStatus id="1" code="OK" name="Рассчитано"/>
<registryStatus id="2" code="UNCV" name="Не исполнено"/>
<registryStatus id="3" code="FAIL" name="Не исполнено контрагентом"/>
@ -296,6 +277,7 @@
<sessionType id="7" code="IPOB" name="Первичные торги Bn"/>
<sessionType id="8" code="IPO0" name="Первичные торги B0"/>
<sessionType id="9" code="CURR" name="Валютные торги"/>
<sessionType id="10" code="UNIT" name="Клиринговая сессия Т0"/>
<moneyFlowSide id="1" code="BUY" name="Привлечь"/>
<moneyFlowSide id="2" code="SELL" name="Разместить"/>
<side id="1" code="B" name="Покупка"/>
@ -453,6 +435,11 @@
<errorCode id="5024" code="ACNT" name="Не указан номер счета."/>
<errorCode id="5025" code="ACNT" name="Необходимо указать ДЕПО счет."/>
<errorCode id="5026" code="ACNT" name="Счет %S не валютный."/>
<errorCode id="5027" code="ACNT" name="У компании %s отсутствует категория."/>
<errorCode id="5028" code="ACNT" name="Указанный ТКР не найден в клиринговой системе."/>
<errorCode id="5029" code="ACNT" name="Счет %s не найден в клиринговой системе."/>
<errorCode id="5030" code="ACNT" name="Компания %s не найдена в клиринговой системе."/>
<errorCode id="5031" code="ACNT" name="Для данной валюты в ТКР уже задан счет."/>
<!-- error code for balance-service -->
<errorCode id="5200" code="BLNC" name="Общая ошибка модуля balance-service."/>
<errorCode id="5210" code="BLNC" name="Клиринговая сессия неактивна."/>

View file

@ -1,6 +1,6 @@
{
"version": "3.11.0.88",
"version": "3.12.4.97",
"enums": {
@ -3977,7 +3977,7 @@
"logUpdates": "true",
"table": "client_сode",
"table": "client_code",
"fields": [
{"code": "id",
@ -4231,7 +4231,7 @@
}
,
{"code": "depoAccountId",
"type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account","enabled": false
"type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account"
}
,
{"code": "status",
@ -4539,6 +4539,10 @@
{"code": "securityId",
"type": 1,"dbname": "Идентификатор инструмента","name": "Код инструмента","shortname": "Код инструмента","searchable": false,"sortable": true,"visible": false,"link": "security","linkCode": "shortName"
}
,
{"code": "section",
"type": 12,"dbname": "Код секции","name": "Наименование секции","shortname": "Секция","searchable": true,"sortable": true,"visible": true,"link": "section"
}
]
,"actions":[
{"method":"post",
@ -4603,7 +4607,7 @@
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"confirmation": "securitySymbol,balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
@ -4623,6 +4627,10 @@
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
,
{"code": "securitySymbol",
"type": 2,"length": 255,"dbname": "Код инструмента","name": "Наименование инструмента/валюты","shortname": "Инструмент/валюта","searchable": false,"sortable": false,"visible": false
}
]
}
,
@ -4894,7 +4902,7 @@
,
"bankAccount": {
"name": "Счета вывода средств из ПРЦ",
"name": "Счета вывода средств",
"destination": "accounting/bank-accounts",
@ -4914,7 +4922,7 @@
}
,
{"code": "bankName",
"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": "correspondentAccount",
@ -4968,11 +4976,15 @@
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
,
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление счета вывода средств из ПРЦ",
"name": "Добавление счета вывода средств",
"confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -4988,7 +5000,7 @@
}
,
{"code": "bankName",
"type": 2,"length": 255,"name": "Наименование банка","shortname": "Наименование","required": true
"type": 2,"length": 255,"name": "Наименование компании в банке","shortname": "Наименование компании","required": true
}
,
{"code": "correspondentAccount",
@ -4998,6 +5010,10 @@
{"code": "correspondentAccountName",
"type": 2,"length": 255,"name": "Наименование корреспондентского счета","shortname": "Наименование корр. счета"
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
}
,
{"code": "taxpayerIdentificationNumber",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН"
@ -5010,24 +5026,24 @@
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": false
}
,
{"code": "companyId",
"type": 1,"name": "Компания","shortname": "Компания","link": "company","linkCode": "shortName","visible": false
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": true
}
,
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
}
,
{"method":"put",
"name": "Изменение счета вывода средств из ПРЦ",
"name": "Изменение счета вывода средств",
"confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -5047,7 +5063,7 @@
}
,
{"code": "bankName",
"type": 2,"length": 255,"name": "Наименование банка","shortname": "Наименование"
"type": 2,"length": 255,"name": "Наименование компании в банке","shortname": "Наименование компании"
}
,
{"code": "correspondentAccount",
@ -5057,6 +5073,10 @@
{"code": "correspondentAccountName",
"type": 2,"length": 255,"name": "Наименование корреспондентского счета","shortname": "Наименование корр. счета"
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
}
,
{"code": "taxpayerIdentificationNumber",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН"
@ -5071,18 +5091,18 @@
}
,
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": false
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": true
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
}
,
{"method":"delete",
"name": "Блокировка счета вывода средств из ПРЦ",
"name": "Блокировка счета вывода средств",
"confirmation": "currency,bankIdentificationCode,correspondentAccount,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -5863,15 +5883,19 @@
}
,
{"code": "creditLeg_accountId",
"type": 1,"group": "Отправитель","name": "Наименование счета отправителя","shortname": "Регистр списания","link": "account","linkCode": "account"
"type": 1,"group": "Отправитель","name": "Наименование счета отправителя","shortname": "Регистр списания","link": "account","linkCode": "account","required": true
}
,
{"code": "addresseeId",
"type": 1,"group": "Получатель","name": "Участник получатель","shortname": "Получатель","link": "company","linkCode": "shortName","required": true,"enabled": false
}
,
{"code": "correspondentAccountId",
"type": 1,"group": "Получатель","name": "Корреспондентский счет","shortname": "Корр. счет","link": "bankAccount","linkCode": "correspondentAccountName","linkKeyCode": "id","required": true,"enabled": true
}
,
{"code": "debitLeg_accountId",
"type": 1,"group": "Получатель","name": "Наименование счета получателя","shortname": "Счет получателя","link": "bankAccount","linkCode": "correspondentAccount"
"type": 1,"group": "Получатель","name": "Наименование счета получателя","shortname": "Счет получателя","link": "bankAccount","linkCode": "account"
}
,
{"code": "swiftCode",
@ -5964,111 +5988,27 @@
"fields": []
}
,
{"method":"post",
"destination": "GRRT",
"group": "Формирование реестров",
"name": "Формирование реестра остатков ценных бумаг",
"fields": []
}
,
{"method":"post",
"destination": "GBRR",
"group": "Формирование реестров",
"name": "Формирование реестра остатков денежных средств",
"fields": []
}
,
{"method":"post",
"destination": "ADLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, допущенных к клирингу",
"fields": []
}
,
{"method":"post",
"destination": "CDLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, прошедших процедуру контроля обеспечения",
"fields": []
}
,
{"method":"post",
"destination": "GORR",
"group": "Формирование реестров",
"name": "Формирование реестра распоряжений, направленных расчетной организации",
"fields": []
}
,
{"method":"post",
"destination": "GORD",
"group": "Формирование реестров",
"name": "Формирование реестра распоряжений, направленных расчетному депозитарию",
"fields": []
}
,
{"method":"post",
"destination": "EXLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, исключенных из клирингового пула",
"fields": []
}
,
{"method":"post",
"destination": "LBSR",
"group": "Формирование реестров",
"name": "Формирование реестра учета обязательств",
"name": "Формирование реестров за период",
"fields": [
{"code": "settlementDate",
"type": 6,"name": "Дата","shortname": "Дата"
{"code": "fromDate",
"type": 6,"name": "С дата","shortname": "с"
}
,
{"code": "toDate",
"type": 6,"name": "По дату","shortname": "по"
}
]
}
,
{"method":"post",
"destination": "ECNR",
"group": "Формирование реестров",
"name": "Формирование реестра сделок",
"fields": []
}
,
{"method":"post",
"destination": "GRET",
"group": "Формирование отчетности",
@ -6126,20 +6066,9 @@
"destination": "MTCR",
"group": "Формирование отчетности",
"group": "Обмен с интеграционными модулями",
"name": "Формирование файлов с МТКР",
"fields": []
}
,
{"method":"post",
"destination": "LIMC",
"group": "Обмен с Торговой системой",
"name": "Выгрузка в Торговую систему остатков по валют (отправка lim)",
"name": "Выгрузка ТКР",
"fields": []
}
@ -6536,7 +6465,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -6702,7 +6631,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -6822,7 +6751,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -7250,11 +7179,11 @@
}
,
{"code": "validFromDate",
"type": 6,"name": "Дата начала cессии","shortname": "Дата начала cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата начала сессии","shortname": "Дата начала сессии","searchable": true,"sortable": true
}
,
{"code": "validToDate",
"type": 6,"name": "Дата окончания cессии","shortname": "Дата окончания cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата окончания сессии","shortname": "Дата окончания сессии","searchable": true,"sortable": true
}
,
{"code": "companyId",
@ -7418,11 +7347,11 @@
}
,
{"code": "validFromDate",
"type": 6,"name": "Дата начала cессии","shortname": "Дата начала cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата начала сессии","shortname": "Дата начала сессии","searchable": true,"sortable": true
}
,
{"code": "validToDate",
"type": 6,"name": "Дата окончания cессии","shortname": "Дата окончания cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата окончания сессии","shortname": "Дата окончания сессии","searchable": true,"sortable": true
}
,
{"code": "companyId",
@ -7718,7 +7647,7 @@
}
,
{"code": "creditLeg_accountId",
"type": 1,"dbname": "Идентификатор счета отправителя","name": "Cчет отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true
"type": 1,"dbname": "Идентификатор счета отправителя","name": "Счет отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true
}
,
{"code": "credit_csAccount",
@ -8475,12 +8404,12 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "pay_val",
@ -8565,12 +8494,12 @@
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "pay_val",
@ -9252,6 +9181,10 @@
{"code": "inSDfId",
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
}
,
{"code": "accType",
"type": 3,"name": "Признак счета","shortname": "Признак счета","searchable": true,"sortable": true,"visible": true
}
]
}
@ -9439,24 +9372,24 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Value_date",
"field": "Value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
{"code": "value_date",
"field": "value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_ben",
"field": "Swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
{"code": "swift_ben",
"field": "swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_int",
"field": "Swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
{"code": "swift_int",
"field": "swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
}
]
@ -9649,24 +9582,24 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Value_date",
"field": "Value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
{"code": "value_date",
"field": "value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_ben",
"field": "Swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
{"code": "swift_ben",
"field": "swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_int",
"field": "Swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
{"code": "swift_int",
"field": "swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
}
]
@ -9893,12 +9826,12 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "dt_in",

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.11.0.88">
<meta version="3.12.4.97">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -920,7 +920,7 @@
<clearingDate type="6" name="Текущая дата" shortname="Дата" visible="false" searchable="true" sortable="true" ignore="true"/>
</errorText>
<clientCode name="Коды клиентов компании" destination="client-codes" class="ru.clearing.classes.statics.data.account.ClientCode" logUpdates="true" table="client_сode">
<clientCode name="Коды клиентов компании" destination="client-codes" class="ru.clearing.classes.statics.data.account.ClientCode" logUpdates="true" table="client_code">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<code type="2" length="255" name="Код клиента" shortname="Код клиента" searchable="true" sortable="true" visible="true"/>
@ -980,7 +980,7 @@
<companyId type="1" name="Наименование компании" shortname="Компания" link="company" linkCode="shortName" enabled="false"/>
<code type="2" length="255" name="Код торгово-клирингового регистра" shortname="ТКР" enabled="false"/>
<moneyAccountId type="1" name="Номер денежного счета" shortname="Денежный счет" link="account" linkCode="account" enabled="false"/>
<depoAccountId type="1" name="Номер депозитарного счета" shortname="Депозитарный счет" link="account" linkCode="account" enabled="false"/>
<depoAccountId type="1" name="Номер депозитарного счета" shortname="Депозитарный счет" link="account" linkCode="account"/>
<status type="12" name="Наименование статуса" shortname="Статус" link="serviceStatus" required="true"/>
</put>
<delete name="Блокировка ТКР" confirmation="companyId,code" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
@ -1055,6 +1055,7 @@
<createdAt field="created" 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"/>
<section type="12" dbname="Код секции" name="Наименование секции" shortname="Секция" searchable="true" sortable="true" visible="true" link="section"/>
<actions>
<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"/>
@ -1068,11 +1069,12 @@
<id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/>
<balance type="10" name="Сумма" shortname="Сумма" required="true"/>
</post>
<post name="Идентификация неразмеченных средств" destination="registries/identificationFunds" confirmation="balance,tradingClearingRegistryId" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew">
<post name="Идентификация неразмеченных средств" destination="registries/identificationFunds" confirmation="securitySymbol,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"/>
<securitySymbol type="2" length="255" dbname="Код инструмента" name="Наименование инструмента/валюты" shortname="Инструмент/валюта" searchable="false" sortable="false" visible="false"/>
</post>
<put name="Изменение даты возврата депозита" destination="registries/changeRefundDate" confirmation="contact,contract,refundDate" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ChangeRefundDateActionNew">
<groupId type="1" dbname="Идентификатор группы связанных регистров" name="Идентификатор группы" required="true" enabled="false" visible="false"/>
@ -1137,10 +1139,10 @@
</put>
</actions>
</relation>
<bankAccount name="Счета вывода средств из ПРЦ" destination="accounting/bank-accounts" class="ru.clearing.classes.statics.data.account.BankAccount" logUpdates="true" table="bank_account">
<bankAccount name="Счета вывода средств" destination="accounting/bank-accounts" class="ru.clearing.classes.statics.data.account.BankAccount" logUpdates="true" table="bank_account">
<accountId type="1" dbname="Идентификатор счета" name="Номер счета" shortname="Счет" searchable="true" sortable="true" link="account" ignore="true"/>
<bankIdentificationCode type="2" length="255" name="Банковский идентификационный код (БИК)" shortname="БИК" searchable="true" sortable="true" visible="true"/>
<bankName type="2" length="255" name="Наименование банка" shortname="Наименование" searchable="true" sortable="true" visible="true"/>
<bankName type="2" length="255" name="Наименование компании в банке" shortname="Наименование компании" searchable="true" sortable="true" visible="true"/>
<correspondentAccount type="2" length="255" name="Корреспондентский счет" shortname="Корр. счет" searchable="true" sortable="true" visible="true"/>
<correspondentAccountName type="2" length="255" name="Наименование корреспондентского счета" shortname="Наименование корр. счета" searchable="true" sortable="true" visible="true"/>
<currency type="12" dbname="Код валюты" name="Код валюты" shortname="Валюта" searchable="true" sortable="true" visible="true" link="currencyCode" linkCode="code"/>
@ -1154,34 +1156,37 @@
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<status 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"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
<actions>
<post name="Добавление счета вывода средств из ПРЦ" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction">
<post name="Добавление счета вывода средств" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction">
<currency type="12" name="Код валюты" shortname="Валюта" required="true" link="currencyCode" linkCode="code"/>
<bankIdentificationCode type="2" length="255" name="Банковский идентификационный код (БИК)" shortname="БИК" required="true"/>
<bankName type="2" length="255" name="Наименование банка" shortname="Наименование" required="true"/>
<bankName type="2" length="255" name="Наименование компании в банке" shortname="Наименование компании" required="true"/>
<correspondentAccount type="2" length="255" name="Корреспондентский счет" shortname="Корр. счет"/>
<correspondentAccountName type="2" length="255" name="Наименование корреспондентского счета" shortname="Наименование корр. счета"/>
<swiftCode type="2" length="255" shortname="SWIFT"/>
<taxpayerIdentificationNumber type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН"/>
<taxRegistrationReasonCode type="2" length="255" name="Код причины постановки (КПП)" shortname="КПП"/>
<account type="2" length="50" name="Номер счета" shortname="Счет" required="true"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="false"/>
<companyId type="1" name="Компания" shortname="Компания" link="company" linkCode="shortName" visible="false"/>
<swiftCode type="2" length="255" shortname="SWIFT"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="true"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
</post>
<put name="Изменение счета вывода средств из ПРЦ" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction">
<put name="Изменение счета вывода средств" confirmation="currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="bankAccount" linkCode="id" required="true"/>
<currency type="12" name="Код валюты" shortname="Валюта" link="currencyCode" linkCode="code"/>
<bankIdentificationCode type="2" length="255" name="Банковский идентификационный код (БИК)" shortname="БИК"/>
<bankName type="2" length="255" name="Наименование банка" shortname="Наименование"/>
<bankName type="2" length="255" name="Наименование компании в банке" shortname="Наименование компании"/>
<correspondentAccount type="2" length="255" name="Корреспондентский счет" shortname="Корр. счет"/>
<correspondentAccountName type="2" length="255" name="Наименование корреспондентского счета" shortname="Наименование корр. счета"/>
<swiftCode type="2" length="255" shortname="SWIFT"/>
<taxpayerIdentificationNumber type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН"/>
<taxRegistrationReasonCode type="2" length="255" name="Код причины постановки (КПП)" shortname="КПП"/>
<account type="2" length="50" name="Номер счета" shortname="Счет"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="false"/>
<swiftCode type="2" length="255" shortname="SWIFT"/>
<destination type="2" length="255" name="Назначение платежа" shortname="Назначение платежа" visible="true"/>
<intermediarySwiftCode type="2" length="255" name="Код SWIFT посредника" shortname="SWIFT посредника" searchable="true" sortable="true" visible="true"/>
</put>
<delete name="Блокировка счета вывода средств из ПРЦ" confirmation="currency,bankIdentificationCode,correspondentAccount,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<delete name="Блокировка счета вывода средств" confirmation="currency,bankIdentificationCode,correspondentAccount,taxpayerIdentificationNumber,taxRegistrationReasonCode,account" class="ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction">
<id type="1" name="Идентификатор записи" shortname="ID" link="bankAccount" linkCode="id" required="true"/>
</delete>
</actions>
@ -1361,9 +1366,10 @@
<creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма" required="true"/>
<paymentPurpose type="2" length="255" name="Назначение платежа" shortname="Основание" required="true"/>
<senderId type="1" group="Отправитель" name="Участник отправитель" shortname="Отправитель" link="company" linkCode="shortName" required="true"/>
<creditLeg_accountId type="1" group="Отправитель" name="Наименование счета отправителя" shortname="Регистр списания" link="account" linkCode="account"/>
<creditLeg_accountId type="1" group="Отправитель" name="Наименование счета отправителя" shortname="Регистр списания" link="account" linkCode="account" required="true"/>
<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"/>
<correspondentAccountId type="1" group="Получатель" name="Корреспондентский счет" shortname="Корр. счет" link="bankAccount" linkCode="correspondentAccountName" linkKeyCode="id" required="true" enabled="true" />
<debitLeg_accountId type="1" group="Получатель" name="Наименование счета получателя" shortname="Счет получателя" link="bankAccount" linkCode="account"/>
<swiftCode type="2" length="255" group="Получатель" shortname="SWIFT" enabled="false"/>
</post>
<post destination="GTRD" group="Обмен с Торговой системой" name="Получение сделок из Торговой системы">
@ -1382,24 +1388,9 @@
</post>
<post destination="GREP" group="Формирование отчетности" name="Формирование промежуточной отчетности">
</post>
<post destination="GRRT" group="Формирование реестров" name="Формирование реестра остатков ценных бумаг">
</post>
<post destination="GBRR" group="Формирование реестров" name="Формирование реестра остатков денежных средств">
</post>
<post destination="ADLR" group="Формирование реестров" name="Формирование реестра обязательств, допущенных к клирингу">
</post>
<post destination="CDLR" group="Формирование реестров" name="Формирование реестра обязательств, прошедших процедуру контроля обеспечения">
</post>
<post destination="GORR" group="Формирование реестров" name="Формирование реестра распоряжений, направленных расчетной организации">
</post>
<post destination="GORD" group="Формирование реестров" name="Формирование реестра распоряжений, направленных расчетному депозитарию">
</post>
<post destination="EXLR" group="Формирование реестров" name="Формирование реестра обязательств, исключенных из клирингового пула">
</post>
<post destination="LBSR" group="Формирование реестров" name="Формирование реестра учета обязательств">
<settlementDate type="6" name="Дата" shortname="Дата"/>
</post>
<post destination="ECNR" group="Формирование реестров" name="Формирование реестра сделок">
<post destination="GBRR" group="Формирование реестров" name="Формирование реестров за период">
<fromDate type="6" name="С дата" shortname="с"/>
<toDate type="6" name="По дату" shortname="по"/>
</post>
<post destination="GRET" group="Формирование отчетности" name="Формирование отчетности PFX64/PFX65">
</post>
@ -1411,10 +1402,10 @@
</post>
<post destination="CCLR" group="Клиринг" name="Завершение неудачных клиринговых сессий">
</post>
<post destination="MTCR" group="Формирование отчетности" name="Формирование файлов с МТКР">
</post>
<post destination="LIMC" group="Обмен с Торговой системой" name="Выгрузка в Торговую систему остатков по валют (отправка lim)">
<post destination="MTCR" group="Обмен с интеграционными модулями" name="Выгрузка ТКР">
</post>
<!-- <post destination="LIMC" group="Обмен с Торговой системой" name="Выгрузка в Торговую систему остатков по валют (отправка lim)">-->
<!-- </post>-->
</actions>
</launcher>
<session name="Клиринговые сессии" destination="sessions" historyDestination="history" class="ru.clearing.classes.statics.data.misc.Session" logUpdates="true" table="session">
@ -1508,7 +1499,7 @@
<counterPartyId type="1" dbname="Идентификатор компании-партнера, с которой заключена сделка" name="Наименование компании-партнера, с которой заключена сделка" shortname="Партнер" visible="false" searchable="true" sortable="true" link="company" linkCode="shortName"/>
<counterPartyTradingClearingRegistryId type="1" dbname="Идентификатор торгово-клирингового регистра партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" link="tradingClearingRegistry" linkCode="code" ignore="true"/>
<counterPartyTradingClearingRegistry type="2" length="20" dbname="Торгово-клиринговый регистр партнера" name="Торгово-клиринговый регистр партнера" shortname="ТКР партнера" visible="true" searchable="true" sortable="true" />
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Статус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<id type="1" name="Идентификатор записи" shortname="ID" visible="false" searchable="true" sortable="true"/>
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" visible="false" searchable="true" sortable="true"/>
@ -1547,7 +1538,7 @@
<settlementDate type="6" name="Дата расчетов" shortname="Дата расчетов" visible="true" searchable="true" sortable="true"/>
<settlementCurrency type="12" dbname="Код валюты расчетов по инструменту" name="Валюта расчетов по инструменту" shortname="Валюта" visible="true" searchable="true" sortable="true" link="currencyCode" linkCode="code"/>
<exchangeExecutionMicroseconds type="4" name="Микросекунды заключения сделки в Торговой системе" shortname="Микросекунды заключения сделки" visible="true" searchable="true" sortable="true"/>
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Статус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
</executionFond>
<executionCurrency name="Сделки с валютными инструментами" destination="execution-currency" class="ru.clearing.classes.statics.data.execution.ExecutionCurrency" logUpdates="true" table="execution_currency">
@ -1575,7 +1566,7 @@
<side type="12" dbname="Код направления сделки" name="Направление сделки" shortname="Направление" visible="true" searchable="true" sortable="true" link="side"/>
<currencyCode type="12" name="Код валюты лота" shortname="Код валюты лота" searchable="true" sortable="true" link="currencyCode" linkCode="code"/>
<settlementOrganization type="2" length="255" name="Наименование расчетной организации" shortname="Расчетная организация" searchable="true" sortable="true" visible="true"/>
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Cтатус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<coverageStatus type="12" dbname="Код статуса достаточности обеспечения" name="Статус достаточности обеспечения" shortname="Обеспеченность" searchable="true" sortable="true" link="allowed"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<clearingDate type="6" name="Дата клиринга" shortname="Дата клиринга" visible="false" searchable="true" sortable="true"/>
<id type="1" name="Идентификатор записи" shortname="ID" visible="false" searchable="true" sortable="true"/>
@ -1668,8 +1659,8 @@
<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"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<validFromDate type="6" name="Дата начала cессии" shortname="Дата начала cессии" searchable="true" sortable="true"/>
<validToDate type="6" name="Дата окончания cессии" shortname="Дата окончания cессии" searchable="true" sortable="true"/>
<validFromDate type="6" name="Дата начала сессии" shortname="Дата начала сессии" searchable="true" sortable="true"/>
<validToDate type="6" name="Дата окончания сессии" shortname="Дата окончания сессии" searchable="true" sortable="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<companyFullName type="2" length="255" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" visible="true"/>
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true"/>
@ -1705,8 +1696,8 @@
<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"/>
<sessionId type="1" dbname="Идентификатор клиринговой сессии" name="Клиринговая сессия" shortname="Сессия" visible="true" searchable="true" sortable="true" link="session"/>
<validFromDate type="6" name="Дата начала cессии" shortname="Дата начала cессии" searchable="true" sortable="true"/>
<validToDate type="6" name="Дата окончания cессии" shortname="Дата окончания cессии" searchable="true" sortable="true"/>
<validFromDate type="6" name="Дата начала сессии" shortname="Дата начала сессии" searchable="true" sortable="true"/>
<validToDate type="6" name="Дата окончания сессии" shortname="Дата окончания сессии" searchable="true" sortable="true"/>
<companyId type="1" dbname="Идентификатор компании" name="Наименование компании" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
<companyFullName type="2" name="Полное наименование компании" shortname="Полное наименование компании" searchable="true" sortable="true" length="255" visible="true"/>
<inn type="2" length="255" name="Идентификационный номер налогоплательщика (ИНН)" shortname="ИНН" searchable="true" sortable="true" visible="true"/>
@ -1775,7 +1766,7 @@
<settlementDate type="6" name="Дата расчетов" shortname="Дата расчетов" searchable="true" sortable="true" visible="true"/>
<creditLeg_amount type="10" name="Сумма отправителя" shortname="Сумма отправителя" searchable="true" sortable="true" visible="true"/>
<debitLeg_amount type="10" name="Сумма получателя" shortname="Сумма получателя" searchable="true" sortable="true" visible="true"/>
<creditLeg_accountId type="1" dbname="Идентификатор счета отправителя" name="Cчет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" link="account" ignore="true"/>
<creditLeg_accountId type="1" dbname="Идентификатор счета отправителя" name="Счет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" link="account" ignore="true"/>
<credit_csAccount type="2" length="255" name="Корреспондентский счет отправителя" shortname="Корр. счет отправителя" searchable="true" sortable="true" ignore="true"/>
<creditLeg_account type="2" length="50" name="Счет отправителя" shortname="Счет отправителя" searchable="true" sortable="true" visible="true"/>
<debitLeg_accountId type="1" dbname="Идентификатор счета получателя" name="Счет получателя" shortname="Счет получателя" searchable="true" sortable="true" link="account" ignore="true"/>
@ -1955,8 +1946,8 @@
<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"/>
<Doc_Num field="Doc_Num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Doc_Date field="Doc_Date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_num field="doc_num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_date field="doc_date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<pay_val type="2" length="12" name="Валюта документа" shortname="Валюта" searchable="true" sortable="true" visible="true"/>
</sDf06>
<sDf07 name="ДФ-07 Ответ на запрос по зачислению/списанию денежных средств" destination="s-dfs/s-df07" class="ru.clearing.classes.statics.data.sdf.SDf07" table="s_df_07">
@ -1976,8 +1967,8 @@
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
<inSDfId type="1" name="Идентификатор соответствующей записи из таблицы-источника" shortname="Входящая запись" searchable="true" sortable="true" visible="true"/>
<Doc_Num field="Doc_Num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Doc_Date field="Doc_Date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_num field="doc_num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_date field="doc_date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<pay_val type="2" length="12" name="Валюта документа" shortname="Валюта" searchable="true" sortable="true" visible="true"/>
</sDf07>
<sDf08 name="ДФ-08 Загрузка счетов с остатками" destination="s-dfs/s-df08" class="ru.clearing.classes.statics.data.sdf.SDf08" table="s_df_08">
@ -2130,6 +2121,7 @@
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
<inSDfId type="1" name="Идентификатор соответствующей записи из таблицы-источника" shortname="Входящая запись" searchable="true" sortable="true" visible="true"/>
<accType type="3" name="Признак счета" shortname="Признак счета" searchable="true" sortable="true" visible="true"/>
</sDf53>
<sDf54 name="ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414" destination="s-dfs/s-df54" class="ru.clearing.classes.statics.data.sdf.SDf54" table="s_df_54">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
@ -2175,11 +2167,11 @@
<doc_result type="2" length="2" 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"/>
<Doc_Num field="Doc_Num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Doc_Date field="Doc_Date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Value_date field="Value_date" type="2" length="8" name="Дата валютирования" shortname="Дата валютирования" searchable="true" sortable="true" visible="true"/>
<Swift_ben field="Swift_ben" type="2" length="11" name="Свифт банка бенефициара" shortname="Свифт банка бенефициара" searchable="true" sortable="true" visible="true"/>
<Swift_int field="Swift_int" type="2" length="11" name="Свифт банка посредника" shortname="Свифт банка посредника" searchable="true" sortable="true" visible="true"/>
<doc_num field="doc_num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_date field="doc_date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<value_date field="value_date" type="2" length="8" name="Дата валютирования" shortname="Дата валютирования" searchable="true" sortable="true" visible="true"/>
<swift_ben field="swift_ben" type="2" length="11" name="Свифт банка бенефициара" shortname="Свифт банка бенефициара" searchable="true" sortable="true" visible="true"/>
<swift_int field="swift_int" type="2" length="11" name="Свифт банка посредника" shortname="Свифт банка посредника" searchable="true" sortable="true" visible="true"/>
</sDf54>
<sDf55 name="ДФ-55 Квитанция об обработке ДФ-54" destination="s-dfs/s-df55" class="ru.clearing.classes.statics.data.sdf.SDf55" table="s_df_55">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
@ -2226,11 +2218,11 @@
<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"/>
<Doc_Num field="Doc_Num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Doc_Date field="Doc_Date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Value_date field="Value_date" type="2" length="8" name="Дата валютирования" shortname="Дата валютирования" searchable="true" sortable="true" visible="true"/>
<Swift_ben field="Swift_ben" type="2" length="11" name="Свифт банка бенефициара" shortname="Свифт банка бенефициара" searchable="true" sortable="true" visible="true"/>
<Swift_int field="Swift_int" type="2" length="11" name="Свифт банка посредника" shortname="Свифт банка посредника" searchable="true" sortable="true" visible="true"/>
<doc_num field="doc_num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_date field="doc_date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<value_date field="value_date" type="2" length="8" name="Дата валютирования" shortname="Дата валютирования" searchable="true" sortable="true" visible="true"/>
<swift_ben field="swift_ben" type="2" length="11" name="Свифт банка бенефициара" shortname="Свифт банка бенефициара" searchable="true" sortable="true" visible="true"/>
<swift_int field="swift_int" type="2" length="11" name="Свифт банка посредника" shortname="Свифт банка посредника" searchable="true" sortable="true" visible="true"/>
</sDf55>
<sDf56 name="ДФ-56 Запрос транзакций за период" destination="s-dfs/s-df56" class="ru.clearing.classes.statics.data.sdf.SDf56" table="s_df_56">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
@ -2284,8 +2276,8 @@
<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"/>
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
<Doc_Num field="Doc_Num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<Doc_Date field="Doc_Date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_num field="doc_num" type="2" length="3" name="Номер выгружаемого документа" shortname="Номер выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<doc_date field="doc_date" type="2" length="8" name="Дата выгружаемого документа" shortname="Дата выгружаемого документа" searchable="true" sortable="true" visible="true"/>
<dt_in type="2" length="22" name="Входящий дебетовый остаток" shortname="Входящий дебетовый остаток" searchable="true" sortable="true" visible="true"/>
<kt_in type="2" length="22" name="Входящий кредитовый остаток" shortname="Входящий кредитовый остаток" searchable="true" sortable="true" visible="true"/>
<dt_out type="2" length="22" name="Исходящий дебетовый остаток" shortname="Исходящий дебетовый остаток" searchable="true" sortable="true" visible="true"/>

View file

@ -3623,7 +3623,7 @@
Проверить, что клиринговая сессия активна: session.sessionStatus=ACTV (см. <a href="#enums.sessionStatus">справочник sessionStatus</a>). Иначе вернуть ошибку (5210) "Клиринговая сессия неактивна" <i>(пока актуально только для модуля balance-service)</i>.
* - подставляется цифра соответствующего модуля согласно кодам ошибок из data.xml
* - подставляется цифра соответствующего модуля согласно кодам ошибок из dictionaries.xml
<a name="objects.standardFields"/>

View file

@ -2,7 +2,7 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
<xsl:output version="1.0" method="html" indent="no" encoding="UTF-8"/>
<xsl:variable name="data" select="document('..\data.xml')/meta"/>
<xsl:variable name="data" select="document('..\dictionaries.xml')/meta"/>
<xsl:variable name="metaxsd" select="document('..\meta.xsd')/xs:schema"/>
<xsl:variable name="meta" select="document('..\meta.xml')/meta"/>

View file

@ -2,7 +2,7 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
<xsl:output version="1.0" method="html" indent="no" encoding="UTF-8"/>
<xsl:variable name="data" select="document('..\data.xml')/meta"/>
<xsl:variable name="data" select="document('..\dictionaries.xml')/meta"/>
<xsl:variable name="meta" select="document('..\meta.xml')/meta"/>
<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>

View file

@ -2,7 +2,7 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
<xsl:output version="1.0" method="html" indent="no" encoding="UTF-8"/>
<xsl:variable name="data" select="document('..\data.xml')/meta"/>
<xsl:variable name="data" select="document('..\dictionaries.xml')/meta"/>
<xsl:variable name="metaxsd" select="document('..\meta.xsd')/xs:schema"/>
<xsl:variable name="meta" select="document('..\meta.xml')/meta"/>

View file

@ -0,0 +1,175 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Проверяет словари на опечатки: пустые значения, сочетание кириллицы и латиницы в одном слове.
* dictionaries.xml
* data_initial.xml
* data_register_code.xml
*/
public class DataXmlTest {
private Logger log = LoggerFactory.getLogger(getClass());
@Test
public void testMetaXml() throws IOException {
verifyXML(new File("src/main/resources/meta/meta.xml"));
}
/**
* Проверка XML (data.xml aka dictionaries.xml)
*
* @throws IOException
*/
@Test
public void testDictionariesXml() throws IOException {
verifyXML(new File("src/main/resources/meta/dictionaries.xml"));
}
@Test
public void testDataInitialXml() throws IOException {
verifyXML(new File("src/main/resources/meta/data_initial.xml"));
}
@Test
public void testDataRegisterCodeXml() throws IOException {
verifyXML(new File("src/main/resources/meta/data_register_code.xml"));
}
protected void verifyXML(File xmlFile) throws IOException {
XmlMapper xmlObjectMapper = new XmlMapper();
xmlObjectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
xmlObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Это юнит-тест с внутренними данными, парсинг DTD выключать не обязательно.
Map<String, Object> root = xmlObjectMapper.readValue(xmlFile, Map.class);
Assertions.assertNotNull(root, "Empty XML in file " + xmlFile);
String errors = verifyNode(xmlFile.getName(), root);
Assertions.assertNull(errors, errors);
}
private String verifyNode(String path, Map<String, Object> node) {
for (Map.Entry<String, Object> item : node.entrySet()) {
String name = item.getKey();
if (!verifyText(name)) {
return path + "> node name \"" + name + "\" has error";
}
String thisPath = path + "/" + name;
if (item.getValue() instanceof Map itemValue) {
String error = verifyNode(thisPath, itemValue);
if (error != null)
return error;
} else if (item.getValue() instanceof String text) {
if (!verifyText(text)) {
return thisPath + "> has error in content: \"" + text + "\"";
}
} else if (item.getValue() instanceof List values) {
for (Object o : values) {
if (o instanceof Map itemMap) {
String error = verifyNode(thisPath, itemMap);
if (error != null)
return error;
} else if (o instanceof String oVal) {
if (!verifyText(oVal)) {
return thisPath + "> one of values in node \"" + oVal + "\" has error";
}
} else if (o == null) {
// nothing
} else {
throw new IllegalArgumentException(thisPath + "> Unsupported one of value type " + o.getClass().getSimpleName() + " for verification");
}
}
} else if (item.getValue() == null) {
// nothing
} else {
throw new IllegalArgumentException(thisPath + "> Unsupported value type " + item.getValue().getClass().getSimpleName() + " for verification");
}
}
return null;
}
final char[] CYRILLICS;
final char[] LATINS;
{
CYRILLICS = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя".toCharArray();
LATINS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
Arrays.sort(CYRILLICS);
Arrays.sort(LATINS);
}
/**
* Проверяет смесь кириллицы и латиницы в одном слове
*
* @param text
* @return
*/
boolean verifyText(String text) {
boolean word = false, cyrillic = false, latin = false;
if (text != null) {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
boolean isWhitespace = Character.isWhitespace(c);
boolean isCyrillic = Arrays.binarySearch(CYRILLICS, c) >= 0;
boolean isLatin = Arrays.binarySearch(LATINS, c) >= 0;
assert !(isCyrillic && isLatin);
assert !(isWhitespace && (isCyrillic || isLatin));
if (word && isWhitespace) {
word = false; // слово закончилось
if (cyrillic && latin)
return false; // Смесь кириллицы и латиницы
} else if (!word && !isWhitespace) {
word = true; // новое слово
cyrillic = latin = false;
}
cyrillic |= isCyrillic;
latin |= isLatin;
}
if (cyrillic && latin)
return false; // Смесь кириллицы и латиницы
}
return true;
}
@Test
public void selfTest() {
verifyText(null);
Assertions.assertTrue(verifyText(""));
Assertions.assertTrue(verifyText("A"));
Assertions.assertTrue(verifyText(" A "));
Assertions.assertTrue(verifyText("A call of"));
Assertions.assertTrue(verifyText("The spring of spin winter."));
Assertions.assertTrue(verifyText("Пользователь user текст обычный."));
Assertions.assertTrue(verifyText("АККаунт mixED 102E333C"));
Assertions.assertTrue(verifyText("АКК_аунт mi_xED 10-+*/2E333C"));
Assertions.assertTrue(verifyText("XML"));
Assertions.assertTrue(verifyText("Same sample apple"));
Assertions.assertTrue(verifyText("По tExT кРАям"));
Assertions.assertFalse(verifyText("Пользоватьель userтекст обычный."));
Assertions.assertFalse(verifyText("ХML"));
Assertions.assertFalse(verifyText("XМL"));
Assertions.assertFalse(verifyText("XMЛ"));
Assertions.assertFalse(verifyText(" ХML"));
Assertions.assertFalse(verifyText(" XМL"));
Assertions.assertFalse(verifyText(" XMЛ"));
Assertions.assertFalse(verifyText("ХML "));
Assertions.assertFalse(verifyText("XМL "));
Assertions.assertFalse(verifyText("XMЛ "));
Assertions.assertFalse(verifyText("12XM_Л34"));
Assertions.assertFalse(verifyText("Same sample аррlе"));
Assertions.assertFalse(verifyText("Same samplе apple"));
Assertions.assertFalse(verifyText("Same sample аpple"));
Assertions.assertFalse(verifyText("client_сode"));
}
}

View file

@ -1,6 +1,6 @@
{
"version": "3.11.0.88",
"version": "3.12.4.97",
"enums": {
@ -3977,7 +3977,7 @@
"logUpdates": "true",
"table": "client_сode",
"table": "client_code",
"fields": [
{"code": "id",
@ -4231,7 +4231,7 @@
}
,
{"code": "depoAccountId",
"type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account","enabled": false
"type": 1,"name": "Номер депозитарного счета","shortname": "Депозитарный счет","link": "account","linkCode": "account"
}
,
{"code": "status",
@ -4539,6 +4539,10 @@
{"code": "securityId",
"type": 1,"dbname": "Идентификатор инструмента","name": "Код инструмента","shortname": "Код инструмента","searchable": false,"sortable": true,"visible": false,"link": "security","linkCode": "shortName"
}
,
{"code": "section",
"type": 12,"dbname": "Код секции","name": "Наименование секции","shortname": "Секция","searchable": true,"sortable": true,"visible": true,"link": "section"
}
]
,"actions":[
{"method":"post",
@ -4603,7 +4607,7 @@
"destination": "registries/identificationFunds",
"confirmation": "balance,tradingClearingRegistryId",
"confirmation": "securitySymbol,balance,tradingClearingRegistryId",
"class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.IdentificationFundsActionNew",
@ -4623,6 +4627,10 @@
{"code": "tradingClearingRegistryId",
"type": 1,"name": "Торгово-клиринговый регистр","shortname": "Торгово-клиринговый регистр","link": "tradingClearingRegistry","linkCode": "code","required": true
}
,
{"code": "securitySymbol",
"type": 2,"length": 255,"dbname": "Код инструмента","name": "Наименование инструмента/валюты","shortname": "Инструмент/валюта","searchable": false,"sortable": false,"visible": false
}
]
}
,
@ -4894,7 +4902,7 @@
,
"bankAccount": {
"name": "Счета вывода средств из ПРЦ",
"name": "Счета вывода средств",
"destination": "accounting/bank-accounts",
@ -4914,7 +4922,7 @@
}
,
{"code": "bankName",
"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": "correspondentAccount",
@ -4968,11 +4976,15 @@
{"code": "id",
"type": 1,"name": "Идентификатор записи","shortname": "ID","searchable": true,"sortable": true
}
,
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
,"actions":[
{"method":"post",
"name": "Добавление счета вывода средств из ПРЦ",
"name": "Добавление счета вывода средств",
"confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -4988,7 +5000,7 @@
}
,
{"code": "bankName",
"type": 2,"length": 255,"name": "Наименование банка","shortname": "Наименование","required": true
"type": 2,"length": 255,"name": "Наименование компании в банке","shortname": "Наименование компании","required": true
}
,
{"code": "correspondentAccount",
@ -4998,6 +5010,10 @@
{"code": "correspondentAccountName",
"type": 2,"length": 255,"name": "Наименование корреспондентского счета","shortname": "Наименование корр. счета"
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
}
,
{"code": "taxpayerIdentificationNumber",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН"
@ -5010,24 +5026,24 @@
{"code": "account",
"type": 2,"length": 50,"name": "Номер счета","shortname": "Счет","required": true
}
,
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": false
}
,
{"code": "companyId",
"type": 1,"name": "Компания","shortname": "Компания","link": "company","linkCode": "shortName","visible": false
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": true
}
,
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
}
,
{"method":"put",
"name": "Изменение счета вывода средств из ПРЦ",
"name": "Изменение счета вывода средств",
"confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -5047,7 +5063,7 @@
}
,
{"code": "bankName",
"type": 2,"length": 255,"name": "Наименование банка","shortname": "Наименование"
"type": 2,"length": 255,"name": "Наименование компании в банке","shortname": "Наименование компании"
}
,
{"code": "correspondentAccount",
@ -5057,6 +5073,10 @@
{"code": "correspondentAccountName",
"type": 2,"length": 255,"name": "Наименование корреспондентского счета","shortname": "Наименование корр. счета"
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
}
,
{"code": "taxpayerIdentificationNumber",
"type": 2,"length": 255,"name": "Идентификационный номер налогоплательщика (ИНН)","shortname": "ИНН"
@ -5071,18 +5091,18 @@
}
,
{"code": "destination",
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": false
"type": 2,"length": 255,"name": "Назначение платежа","shortname": "Назначение платежа","visible": true
}
,
{"code": "swiftCode",
"type": 2,"length": 255,"shortname": "SWIFT"
{"code": "intermediarySwiftCode",
"type": 2,"length": 255,"name": "Код SWIFT посредника","shortname": "SWIFT посредника","searchable": true,"sortable": true,"visible": true
}
]
}
,
{"method":"delete",
"name": "Блокировка счета вывода средств из ПРЦ",
"name": "Блокировка счета вывода средств",
"confirmation": "currency,bankIdentificationCode,correspondentAccount,taxpayerIdentificationNumber,taxRegistrationReasonCode,account",
@ -5863,15 +5883,19 @@
}
,
{"code": "creditLeg_accountId",
"type": 1,"group": "Отправитель","name": "Наименование счета отправителя","shortname": "Регистр списания","link": "account","linkCode": "account"
"type": 1,"group": "Отправитель","name": "Наименование счета отправителя","shortname": "Регистр списания","link": "account","linkCode": "account","required": true
}
,
{"code": "addresseeId",
"type": 1,"group": "Получатель","name": "Участник получатель","shortname": "Получатель","link": "company","linkCode": "shortName","required": true,"enabled": false
}
,
{"code": "correspondentAccountId",
"type": 1,"group": "Получатель","name": "Корреспондентский счет","shortname": "Корр. счет","link": "bankAccount","linkCode": "correspondentAccountName","linkKeyCode": "id","required": true,"enabled": true
}
,
{"code": "debitLeg_accountId",
"type": 1,"group": "Получатель","name": "Наименование счета получателя","shortname": "Счет получателя","link": "bankAccount","linkCode": "correspondentAccount"
"type": 1,"group": "Получатель","name": "Наименование счета получателя","shortname": "Счет получателя","link": "bankAccount","linkCode": "account"
}
,
{"code": "swiftCode",
@ -5964,111 +5988,27 @@
"fields": []
}
,
{"method":"post",
"destination": "GRRT",
"group": "Формирование реестров",
"name": "Формирование реестра остатков ценных бумаг",
"fields": []
}
,
{"method":"post",
"destination": "GBRR",
"group": "Формирование реестров",
"name": "Формирование реестра остатков денежных средств",
"fields": []
}
,
{"method":"post",
"destination": "ADLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, допущенных к клирингу",
"fields": []
}
,
{"method":"post",
"destination": "CDLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, прошедших процедуру контроля обеспечения",
"fields": []
}
,
{"method":"post",
"destination": "GORR",
"group": "Формирование реестров",
"name": "Формирование реестра распоряжений, направленных расчетной организации",
"fields": []
}
,
{"method":"post",
"destination": "GORD",
"group": "Формирование реестров",
"name": "Формирование реестра распоряжений, направленных расчетному депозитарию",
"fields": []
}
,
{"method":"post",
"destination": "EXLR",
"group": "Формирование реестров",
"name": "Формирование реестра обязательств, исключенных из клирингового пула",
"fields": []
}
,
{"method":"post",
"destination": "LBSR",
"group": "Формирование реестров",
"name": "Формирование реестра учета обязательств",
"name": "Формирование реестров за период",
"fields": [
{"code": "settlementDate",
"type": 6,"name": "Дата","shortname": "Дата"
{"code": "fromDate",
"type": 6,"name": "С дата","shortname": "с"
}
,
{"code": "toDate",
"type": 6,"name": "По дату","shortname": "по"
}
]
}
,
{"method":"post",
"destination": "ECNR",
"group": "Формирование реестров",
"name": "Формирование реестра сделок",
"fields": []
}
,
{"method":"post",
"destination": "GRET",
"group": "Формирование отчетности",
@ -6126,20 +6066,9 @@
"destination": "MTCR",
"group": "Формирование отчетности",
"group": "Обмен с интеграционными модулями",
"name": "Формирование файлов с МТКР",
"fields": []
}
,
{"method":"post",
"destination": "LIMC",
"group": "Обмен с Торговой системой",
"name": "Выгрузка в Торговую систему остатков по валют (отправка lim)",
"name": "Выгрузка ТКР",
"fields": []
}
@ -6536,7 +6465,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -6702,7 +6631,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -6822,7 +6751,7 @@
}
,
{"code": "coverageStatus",
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Cтатус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
"type": 12,"dbname": "Код статуса достаточности обеспечения","name": "Статус достаточности обеспечения","shortname": "Обеспеченность","searchable": true,"sortable": true,"link": "allowed"
}
,
{"code": "sessionId",
@ -7250,11 +7179,11 @@
}
,
{"code": "validFromDate",
"type": 6,"name": "Дата начала cессии","shortname": "Дата начала cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата начала сессии","shortname": "Дата начала сессии","searchable": true,"sortable": true
}
,
{"code": "validToDate",
"type": 6,"name": "Дата окончания cессии","shortname": "Дата окончания cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата окончания сессии","shortname": "Дата окончания сессии","searchable": true,"sortable": true
}
,
{"code": "companyId",
@ -7418,11 +7347,11 @@
}
,
{"code": "validFromDate",
"type": 6,"name": "Дата начала cессии","shortname": "Дата начала cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата начала сессии","shortname": "Дата начала сессии","searchable": true,"sortable": true
}
,
{"code": "validToDate",
"type": 6,"name": "Дата окончания cессии","shortname": "Дата окончания cессии","searchable": true,"sortable": true
"type": 6,"name": "Дата окончания сессии","shortname": "Дата окончания сессии","searchable": true,"sortable": true
}
,
{"code": "companyId",
@ -7718,7 +7647,7 @@
}
,
{"code": "creditLeg_accountId",
"type": 1,"dbname": "Идентификатор счета отправителя","name": "Cчет отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true
"type": 1,"dbname": "Идентификатор счета отправителя","name": "Счет отправителя","shortname": "Счет отправителя","searchable": true,"sortable": true,"link": "account","ignore": true
}
,
{"code": "credit_csAccount",
@ -8475,12 +8404,12 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "pay_val",
@ -8565,12 +8494,12 @@
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "pay_val",
@ -9252,6 +9181,10 @@
{"code": "inSDfId",
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
}
,
{"code": "accType",
"type": 3,"name": "Признак счета","shortname": "Признак счета","searchable": true,"sortable": true,"visible": true
}
]
}
@ -9439,24 +9372,24 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Value_date",
"field": "Value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
{"code": "value_date",
"field": "value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_ben",
"field": "Swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
{"code": "swift_ben",
"field": "swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_int",
"field": "Swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
{"code": "swift_int",
"field": "swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
}
]
@ -9649,24 +9582,24 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Value_date",
"field": "Value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
{"code": "value_date",
"field": "value_date","type": 2,"length": 8,"name": "Дата валютирования","shortname": "Дата валютирования","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_ben",
"field": "Swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
{"code": "swift_ben",
"field": "swift_ben","type": 2,"length": 11,"name": "Свифт банка бенефициара","shortname": "Свифт банка бенефициара","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Swift_int",
"field": "Swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
{"code": "swift_int",
"field": "swift_int","type": 2,"length": 11,"name": "Свифт банка посредника","shortname": "Свифт банка посредника","searchable": true,"sortable": true,"visible": true
}
]
@ -9893,12 +9826,12 @@
"type": 1,"name": "Идентификатор взаимодействия","shortname": "ID взаимодействия","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Num",
"field": "Doc_Num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_num",
"field": "doc_num","type": 2,"length": 3,"name": "Номер выгружаемого документа","shortname": "Номер выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "Doc_Date",
"field": "Doc_Date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
{"code": "doc_date",
"field": "doc_date","type": 2,"length": 8,"name": "Дата выгружаемого документа","shortname": "Дата выгружаемого документа","searchable": true,"sortable": true,"visible": true
}
,
{"code": "dt_in",

View file

@ -5,7 +5,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -12,7 +12,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<properties>

View file

@ -25,6 +25,7 @@ public class BankAccount extends SpcexObjectBase {
private String taxRegistrationReasonCode;
private String account;
private Long companyId;
private String intermediarySwiftCode;
public Long getAccountId() {
return accountId;
@ -137,4 +138,12 @@ public class BankAccount extends SpcexObjectBase {
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public String getIntermediarySwiftCode() {
return intermediarySwiftCode;
}
public void setIntermediarySwiftCode(String intermediarySwiftCode) {
this.intermediarySwiftCode = intermediarySwiftCode;
}
}

View file

@ -58,6 +58,7 @@ public class Registry extends BusinessObject implements Cloneable {
private Long sessionId;
private String sessionType;
private Long paymentId;
private String section;
public Long getCompanyId() {
return companyId;
@ -417,6 +418,14 @@ public class Registry extends BusinessObject implements Cloneable {
this.paymentId = paymentId;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
@Override
public Registry clone() {
try {

View file

@ -28,8 +28,8 @@ public class SDf06 extends SpcexObjectBase implements WithFileName, WithCurrency
private String fileName;
private Instant generationTime;
private Long generationId;
private String Doc_Num;
private String Doc_Date;
private String doc_num;
private String doc_date;
private String pay_val;
public String getAccount() {
@ -84,16 +84,16 @@ public class SDf06 extends SpcexObjectBase implements WithFileName, WithCurrency
return inn;
}
public void setInn(String inn) {
this.inn = inn;
public void setInn(String value) {
this.inn = value;
}
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
public void setBic(String value) {
this.bic = value;
}
public String getSpec() {
@ -136,18 +136,20 @@ public class SDf06 extends SpcexObjectBase implements WithFileName, WithCurrency
this.generationId = value;
}
public String getDoc_Num() {
return Doc_Num;
}
public void setDoc_Num(String value) {
this.Doc_Num=value;
public String getDoc_num() {
return doc_num;
}
public String getDoc_Date() {
return Doc_Date;
public void setDoc_num(String value) {
this.doc_num = value;
}
public void setDoc_Date(String value) {
this.Doc_Date=value;
public String getDoc_date() {
return doc_date;
}
public void setDoc_date(String value) {
this.doc_date = value;
}
public String getPay_val() {

View file

@ -30,8 +30,8 @@ public class SDf07 extends SpcexObjectBase {
private Instant generationTime;
private Long generationId;
private Long inSDfId;
private String Doc_Num;
private String Doc_Date;
private String doc_num;
private String doc_date;
private String pay_val;
public String getAccount() {
@ -86,16 +86,16 @@ public class SDf07 extends SpcexObjectBase {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
public void setInn(String value) {
this.inn = value;
}
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
public void setBic(String value) {
this.bic = value;
}
public String getSpec() {
@ -126,8 +126,8 @@ public class SDf07 extends SpcexObjectBase {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
public void setFileName(String value) {
this.fileName = value;
}
public Instant getGenerationTime() {
@ -154,20 +154,20 @@ public class SDf07 extends SpcexObjectBase {
this.inSDfId = value;
}
public String getDoc_Num() {
return Doc_Num;
public String getDoc_num() {
return doc_num;
}
public void setDoc_Num(String value) {
this.Doc_Num = value;
public void setDoc_num(String value) {
this.doc_num = value;
}
public String getDoc_Date() {
return Doc_Date;
public String getDoc_date() {
return doc_date;
}
public void setDoc_Date(String value) {
this.Doc_Date = value;
public void setDoc_date(String value) {
this.doc_date = value;
}
public String getPay_val() {

View file

@ -56,11 +56,11 @@ public class SDf54 extends SpcexObjectBase {
private String doc_result;
private Instant generationTime;
private Long generationId;
private String Doc_Num;
private String Doc_Date;
private String Value_date;
private String Swift_ben;
private String Swift_int;
private String doc_num;
private String doc_date;
private String value_date;
private String swift_ben;
private String swift_int;
public String getSeg_type() {
return seg_type;
@ -398,44 +398,44 @@ public class SDf54 extends SpcexObjectBase {
this.generationId = value;
}
public String getDoc_Num() {
return Doc_Num;
public String getDoc_num() {
return doc_num;
}
public void setDoc_Num(String value) {
this.Doc_Num = value;
public void setDoc_num(String value) {
this.doc_num = value;
}
public String getDoc_Date() {
return Doc_Date;
public String getDoc_date() {
return doc_date;
}
public void setDoc_Date(String value) {
this.Doc_Date = value;
public void setDoc_date(String value) {
this.doc_date = value;
}
public String getValue_date() {
return Value_date;
return value_date;
}
public void setValue_date(String value) {
this.Value_date = value;
this.value_date = value;
}
public String getSwift_ben() {
return Swift_ben;
return swift_ben;
}
public void setSwift_ben(String value) {
this.Swift_ben = value;
this.swift_ben = value;
}
public String getSwift_int() {
return Swift_int;
return swift_int;
}
public void setSwift_int(String value) {
this.Swift_int = value;
this.swift_int = value;
}
}

View file

@ -57,11 +57,11 @@ public class SDf55 extends SpcexObjectBase {
private String fileName;
private Instant generationTime;
private Long generationId;
private String Doc_Num;
private String Doc_Date;
private String Value_date;
private String Swift_ben;
private String Swift_int;
private String doc_num;
private String doc_date;
private String value_date;
private String swift_ben;
private String swift_int;
public String getSeg_type() {
return seg_type;
@ -407,44 +407,44 @@ public class SDf55 extends SpcexObjectBase {
this.generationId = value;
}
public String getDoc_Num() {
return Doc_Num;
public String getDoc_num() {
return doc_num;
}
public void setDoc_Num(String value) {
this.Doc_Num = value;
public void setDoc_num(String value) {
this.doc_num = value;
}
public String getDoc_Date() {
return Doc_Date;
public String getDoc_date() {
return doc_date;
}
public void setDoc_Date(String value) {
this.Doc_Date = value;
public void setDoc_date(String value) {
this.doc_date = value;
}
public String getValue_date() {
return Value_date;
return value_date;
}
public void setValue_date(String value) {
this.Value_date = value;
this.value_date = value;
}
public String getSwift_ben() {
return Swift_ben;
return swift_ben;
}
public void setSwift_ben(String value) {
this.Swift_ben = value;
this.swift_ben = value;
}
public String getSwift_int() {
return Swift_int;
return swift_int;
}
public void setSwift_int(String value) {
this.Swift_int = value;
this.swift_int = value;
}
}

View file

@ -13,6 +13,7 @@ import ru.spcex.platform.classes.base.interfaces.WithCurrency;
public class SDf57 extends SpcexObjectBase implements WithCurrency {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
private Instant generationTime;
private Long dbfId;
private String deal_deb;
private String deal_cred;
@ -51,15 +52,22 @@ public class SDf57 extends SpcexObjectBase implements WithCurrency {
private String acc_kr;
private String specif;
private String fileName;
private Instant generationTime;
private Long generationId;
private String Doc_Num;
private String Doc_Date;
private String doc_num;
private String doc_date;
private String dt_in;
private String kt_in;
private String dt_out;
private String kt_out;
public Instant getGenerationTime() {
return generationTime;
}
public void setGenerationTime(Instant value) {
this.generationTime = value;
}
public Long getDbfId() {
return dbfId;
}
@ -364,14 +372,6 @@ public class SDf57 extends SpcexObjectBase implements WithCurrency {
this.fileName = value;
}
public Instant getGenerationTime() {
return generationTime;
}
public void setGenerationTime(Instant value) {
this.generationTime = value;
}
public Long getGenerationId() {
return generationId;
}
@ -380,20 +380,20 @@ public class SDf57 extends SpcexObjectBase implements WithCurrency {
this.generationId = value;
}
public String getDoc_Num() {
return Doc_Num;
public String getDoc_num() {
return doc_num;
}
public void setDoc_Num(String value) {
this.Doc_Num = value;
public void setDoc_num(String value) {
this.doc_num = value;
}
public String getDoc_Date() {
return Doc_Date;
public String getDoc_date() {
return doc_date;
}
public void setDoc_Date(String value) {
this.Doc_Date = value;
public void setDoc_date(String value) {
this.doc_date = value;
}
public String getDt_in() {

View file

@ -6,13 +6,13 @@
<parent>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-parent</artifactId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<artifactId>cleaning-builders</artifactId>
<name>cleaning-builders</name>
<description>Cleaning builders module</description>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<packaging>jar</packaging>
@ -26,7 +26,7 @@
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<scope>compile</scope>
</dependency>
<dependency>

View file

@ -5,7 +5,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -1,19 +1,18 @@
package ru.spcex.clearing.config;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver;
import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer;
import java.util.Locale;
//@Configuration
@Configuration
public class MessagesConfig {
@Bean("validation-error-messages")
@Bean("clearing-messages")
public ResourceBundleMessageSource messages() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages/error");
source.setBasenames("messages/clearing");
source.setUseCodeAsDefaultMessage(true);
source.setDefaultEncoding("utf8");
source.setDefaultLocale(Locale.ROOT);
@ -21,9 +20,12 @@ public class MessagesConfig {
}
@Bean
public IMessageResolver errorResolver(@Qualifier("validation-error-messages") ResourceBundleMessageSource messageBundle) {
SpringPropertiesMessageResolver resolver = new SpringPropertiesMessageResolver(messageBundle);
resolver.setLocale("ru");
public SpringPropertiesLocalizer localizer(
@Qualifier("clearing-messages")
ResourceBundleMessageSource messageBundle
) {
SpringPropertiesLocalizer resolver = new SpringPropertiesLocalizer(messageBundle);
resolver.setDefaultLocale("ru");
return resolver;
}
}

View file

@ -0,0 +1,21 @@
package ru.spcex.clearing.messages;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum ClearingMessage implements IEnumKey {
WithdrawalFreeFromTkr("payment-instruction.purpose.withdrawal.tcr"),
WithdrawalOfFunds("payment-instruction.purpose.withdrawal"),
urgent("sdf54.urgent"),
;
private final String key;
ClearingMessage(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}

View file

@ -116,7 +116,7 @@ public class AnltSearcher {
return new AnltSearch(infoAcc, company, tcr, tcrList, currencyCode);
}
private static final Pattern tcrPattern = Pattern.compile("ТКР.*?([0-9A-Z-]{12})");
private static final Pattern tcrPattern = Pattern.compile("(?:ТКР|TKR|TCR).*?([0-9A-Z-]{12})");
private static String getTkrCodeFromComment(String comment) {
if (TextUtil.isEmpty(comment)) {

View file

@ -45,6 +45,7 @@ import ru.spcex.clearing.session.stage.SecondaryAuctionT0Session;
import ru.spcex.clearing.session.stage.SessionManager;
import ru.spcex.clearing.session.stage.SessionTerminator;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.stage.UnitedSession;
import ru.spcex.clearing.session.stage.impl.BalanceRevise;
import ru.spcex.clearing.statement.StatementServiceV2;
import ru.spcex.platform.enumeration.Task;
@ -65,6 +66,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
private final PrimaryAuctionB0Session primaryAuctionB0Session;
private final IntermediateMkrSession intermediateMkrSession;
private final FinalMkrSession finalMkrSession;
private final UnitedSession unitedSession;
private final ReturnDepositSession returnDepositSession;
private final SessionManager sessionManager;
private final Sdf06Executor sdf06Executor;
@ -83,7 +85,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
PrimaryAuctionBnSession primaryAuctionBnSession,
SecondaryAuctionT0Session secondaryAuctionT0Session,
CurrencySession currencySession,
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, UnitedSession unitedSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
Sdf06Executor sdf06Executor,
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, StatementServiceV2 statementService, SessionTerminator sessionTerminator, PaymentInstructionOutboundService pmtOutboundService) {
super(kafkaQueue, kafkaResponseQueue);
@ -98,6 +100,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
this.primaryAuctionT0Session = primaryAuctionT0Session;
this.intermediateMkrSession = intermediateMkrSession;
this.finalMkrSession = finalMkrSession;
this.unitedSession = unitedSession;
this.returnDepositSession = returnDepositSession;
this.sessionManager = sessionManager;
this.sdf06Executor = sdf06Executor;
@ -153,6 +156,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
primaryAuctionB0Session.continueSession(req);
intermediateMkrSession.continueSession(req);
finalMkrSession.continueSession(req);
unitedSession.continueSession(req);
returnDepositSession.continueSession(req);
})
.forDestination(Consts.CONTINUE_SESSION_BN_FIRST_PART, callbacks::put);
@ -207,7 +211,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
callback(LauncherCommandRequest.class)
.setConsumer(task -> {
balanceRevise.submit(new ru.spcex.clearing.session.stage.Task<>(TaskType.StartRevise, null));
balanceRevise.submit(new ru.spcex.clearing.session.stage.Task<>(TaskType.SDF51, null));
})
.forDestination(Task.getVerification.topic(), callbacks::put);

View file

@ -3,6 +3,7 @@ package ru.spcex.clearing.service;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,6 +16,8 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.messages.ClearingMessage;
import ru.spcex.clearing.util.LocaleUtil;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CompanySymbol;
@ -25,6 +28,7 @@ import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer;
import ru.spcex.platform.utils.number.BigDecimalUtil;
import ru.spcex.platform.utils.time.TimeUtil;
@ -38,9 +42,10 @@ public class Sdf54Creator {
private final Imdg<SDf54> sdf54Imdg;
private final Imdg<BankAccount> bankAccountImdg;
private final ImdgId idGenerator;
private final SpringPropertiesLocalizer resolver;
private static DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
public Sdf54Creator(ImdgProvider imdgProvider) {
public Sdf54Creator(ImdgProvider imdgProvider, SpringPropertiesLocalizer resolver) {
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
@ -48,23 +53,25 @@ public class Sdf54Creator {
this.bankAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
this.sdf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.resolver = resolver;
}
private final static DateTimeFormatter docnmRefFormatter = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
public SDf54 create(PaymentInstruction paymentInstruction) {
public SDf54 create(PaymentInstruction pmt) {
Instant now = Instant.now();
String c_acc_cred = null;
Account anltAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and currency = '%s'"
.formatted(
AccountType.Anlt.getKey(),
Status.Active.getKey(),
paymentInstruction.getCreditLeg_currencyCode()
pmt.getCreditLeg_currencyCode()
));
// c_acc_deb = c_acc_deb == null ? paymentInstruction.getCreditLeg_account() : c_acc_deb;
c_acc_cred = c_acc_cred == null ? paymentInstruction.getDebitLeg_account() : c_acc_cred;
c_acc_cred = c_acc_cred == null ? pmt.getDebitLeg_account() : c_acc_cred;
Locale locale = LocaleUtil.locale(pmt.getCreditLeg_currencyCode(), pmt.getDebitLeg_currencyCode());
SDf54 sDf54 = new SDf54();
sDf54.setId(idGenerator.nextId());
sDf54.setSeg_type("V");
@ -79,7 +86,13 @@ public class Sdf54Creator {
Company prcCmp = companyImdg.getSingleObjectByID(Sender.Prc.getId());
String senderSbankName = "";
if (prcCmp != null) {
senderSbankName = prcCmp.getShortName();
if (LocaleUtil.isRus(locale)) {
senderSbankName = prcCmp.getShortName();
} else if (prcCmp.getProfile() != null) {
senderSbankName = prcCmp.getProfile().getShortNameEng();
} else {
senderSbankName = "";
}
}
SpecifUtil.fillSegmentsBy35Symbols(senderSbankName,
sDf54::setSbanknam1,
@ -105,28 +118,27 @@ public class Sdf54Creator {
if (anltAcc != null) {
sDf54.setAcc_deb(anltAcc.getAccount());
}
Account accDebAcc = accountImdg.getSingleObjectByID(paymentInstruction.getDebitLeg_accountId());
Account accDebAcc = accountImdg.getSingleObjectByID(pmt.getDebitLeg_accountId());
if (accDebAcc == null || !AccountStatus.ACTIVE.equalsByKey(accDebAcc.getStatus())) {
log.warn("paymentInstruction[{}].DebitLeg_accountId={} account not exist or not active.", paymentInstruction.getId(), paymentInstruction.getDebitLeg_accountId());
log.warn("paymentInstruction[{}].DebitLeg_accountId={} account not exist or not active.", pmt.getId(), pmt.getDebitLeg_accountId());
}
BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(paymentInstruction.getDebitLeg_accountId()));
BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(pmt.getDebitLeg_accountId()));
if (bnkAcc != null) {
sDf54.setInn_cred(bnkAcc.getTaxpayerIdentificationNumber());
sDf54.setKpp_cred(bnkAcc.getTaxRegistrationReasonCode());
c_acc_cred = bnkAcc.getCorrespondentAccount();
sDf54.setSwift_ben(bnkAcc.getSwiftCode());
if (!LocaleUtil.isRus(locale)) {
sDf54.setSwift_ben(bnkAcc.getSwiftCode());
sDf54.setSwift_int(bnkAcc.getIntermediarySwiftCode());
}
} else {
log.warn("Bank account not found for DebitLeg_accountId={}", paymentInstruction.getDebitLeg_accountId());
}
sDf54.setDoc_Num(String.valueOf(nextDocNum()));
BankAccount prcBankAcc = bankAccountImdg.getFirstObjectBySQL("companyId = %d".formatted(Sender.Prc.getId()));
if (prcBankAcc != null) {
sDf54.setSwift_int(prcBankAcc.getSwiftCode());
log.warn("Bank account not found for DebitLeg_accountId={}", pmt.getDebitLeg_accountId());
}
sDf54.setDoc_num(String.valueOf(nextDocNum()));
String today = payDateFormatter.format(LocalDate.now());
sDf54.setDoc_Date(today);
sDf54.setDoc_date(today);
sDf54.setValue_date(today);
sDf54.setAcc_kr_1(paymentInstruction.getDebitLeg_account());
sDf54.setAcc_kr_1(pmt.getDebitLeg_account());
{
Account prcCorrAcc = accountImdg.getFirstObjectBySQL("companyId=%d and accountType = '%s' and status = '%s' and currency = '%s'"
@ -134,7 +146,7 @@ public class Sdf54Creator {
Sender.Prc.getId(),
AccountType.Bank.getKey(),
Status.Active.getKey(),
paymentInstruction.getCreditLeg_currencyCode()
pmt.getCreditLeg_currencyCode()
));
if (prcCorrAcc == null) {
log.warn("Account for PRC CORR not found");
@ -144,7 +156,7 @@ public class Sdf54Creator {
}
//**********************
sDf54.setSend_type("срочно");
sDf54.setSend_type(resolver.resolve(ClearingMessage.urgent, locale));
sDf54.setDoc_type("002");
sDf54.setDocnm_ref(docnmRefFormatter.format(TimeUtil.toDateTime(now)));
@ -166,7 +178,15 @@ public class Sdf54Creator {
{
Company company1 = companyImdg.getSingleObjectByID(Sender.One.getId());
if (company1 != null) { // "АО СПВБ" company.shortName[id = 1]
SpecifUtil.fillSegmentsBy35Symbols(company1.getShortName(),
String sclientn;
if (LocaleUtil.isRus(locale)) {
sclientn = company1.getShortName();
} else if (company1.getProfile() != null) {
sclientn = company1.getProfile().getShortNameEng();
} else {
sclientn = "";
}
SpecifUtil.fillSegmentsBy35Symbols(sclientn,
sDf54::setSclientn1,
sDf54::setSclientn2,
sDf54::setSclientn3,
@ -185,13 +205,13 @@ public class Sdf54Creator {
}
}
sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate())));
sDf54.setPay_val(paymentInstruction.getCreditLeg_currencyCode());
String sumDeb = paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : "";
sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(pmt.getPaymentDate())));
sDf54.setPay_val(pmt.getCreditLeg_currencyCode());
String sumDeb = pmt.getDebitLeg_amount() != null ? pmt.getDebitLeg_amount().toString() : "";
sDf54.setSum_deb(BigDecimalUtil.limitDecimalPlaces(sumDeb, 2));
sDf54.setSpecif_1(paymentInstruction.getPaymentPurpose());
sDf54.setSpecif_1(pmt.getPaymentPurpose());
sDf54.setGenerationTime(now);
log.debug("paymentInstruction.id={}, sdf54.id {}", paymentInstruction.getId(), sDf54.getId());
log.debug("paymentInstruction.id={}, sdf54.id {}", pmt.getId(), sDf54.getId());
return sDf54;
}
@ -205,15 +225,15 @@ public class Sdf54Creator {
SDf54 sDf54 = sdf54Imdg.aggregateByMax(
"id", pb.and(
pb.greatEqual("generationTime", TimeUtil.today()),
pb.notNull("Doc_Num")
pb.notNull("doc_num")
)
);
if (sDf54 != null) {
try {
int num = Integer.parseInt(sDf54.getDoc_Num());
int num = Integer.parseInt(sDf54.getDoc_num());
return ++num;
} catch (Throwable e) {
log.error("couldn't parse sdf54.id={} doc_num {}", sDf54.getId(), sDf54.getDoc_Num());
log.error("couldn't parse sdf54.id={} doc_num {}", sDf54.getId(), sDf54.getDoc_num());
return 1;
}
}

View file

@ -1,5 +1,10 @@
package ru.spcex.clearing.service.builder;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.company.Company;
@ -8,28 +13,31 @@ import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.clearing.classes.statics.data.misc.Currency;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf21;
import ru.clearing.classes.statics.data.security.CurrencyPairSecurity;
import ru.clearing.classes.statics.data.security.MoneyMarketSecurity;
import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import ru.spcex.platform.utils.number.BigDecimalUtil;
public class RegistrySecurityBuilder {
private Statement statement;
private Company company;
private Account account;
private RegistryDesignation designation;
private SDf21 sdf21;
private final ImdgProvider imdgProvider;
private final Imdg<ClearingAccount> clearingAccountImdg;
@ -92,19 +100,18 @@ public class RegistrySecurityBuilder {
rgs.setRegistryInstrumentType(RegistryInstrumentType.S.getKey());
AccountType accType = IEnumKey.getEnumByKey(AccountType.class, account.getAccountType());
if (AccountType.Clrn.equals(accType)) {
ClearingAccount accountForStatement = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", statement.getAccountId()));
if (accountForStatement != null) {
rgs.setRegistryCapacity(accountForStatement.getClearingAccountType());
}
} else if (AccountType.Info.equals(accType) || AccountType.Anlt.equals(accType)) {
rgs.setRegistryCapacity(RegistryCapacity.A.getKey());
}
//if (AccountType.Clrn.equals(accType)) {
// ClearingAccount accountForStatement = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", statement.getAccountId()));
// if (accountForStatement != null) {
// rgs.setRegistryCapacity(accountForStatement.getClearingAccountType());
// }
//} else if (AccountType.Info.equals(accType) || AccountType.Anlt.equals(accType)) {
// rgs.setRegistryCapacity(RegistryCapacity.A.getKey());
//}
rgs.setRegistryUnit(RegistryUnit.T.getKey());
rgs.setRegistryCode(RegistryUtil.clearingCode(rgs));
Collection<TradingClearingRegistry> tcrsByAccount = tradingClearingRegistryImdg.getCollectionObjectsByFieldValues(Map.of(
"moneyAccountId", account.getId(),
"depoAccountId", account.getId(),
"companyId", company.getId(),
"status", ServiceStatus.Active.getKey()
));
@ -112,7 +119,9 @@ public class RegistrySecurityBuilder {
TradingClearingRegistry tcr = tcrsByAccount.iterator().next();
rgs.setTradingClearingRegistryId(tcr.getId());
rgs.setTradingClearingRegistry(tcr.getCode());
rgs.setRegistryCapacity(tcr.getTradingClearingRegistryType());
}
rgs.setRegistryCode(RegistryUtil.clearingCode(rgs));
rgs.setRegistryStatus(RegistryStatus.PROC.getKey());
rgs.setSecurityId(statement.getSecurityId());
@ -131,6 +140,7 @@ public class RegistrySecurityBuilder {
rgs.setCreated(Instant.now());
//по дефолту создаем с балансом 0, а потом пересчитываем по необходимости
rgs.setPlanBalance(BigDecimalUtil.parse(sdf21.getCloseBalance()));
rgs.setBalance(BigDecimal.ZERO);
rgs.setDebit(BigDecimal.ZERO);
rgs.setCredit(BigDecimal.ZERO);
@ -154,4 +164,9 @@ public class RegistrySecurityBuilder {
if (currency != null) return currency.getCurrencyCode();
return null;
}
public RegistrySecurityBuilder sdf21(SDf21 sdf21) {
this.sdf21 = sdf21;
return this;
}
}

View file

@ -180,7 +180,7 @@ public class ExecutionCurrencyComponent {
eCurrency.setTradingDate(sTrades.getTradeDate());
eCurrency.setClearingDate(TimeUtil.toLocalDate(now));
eCurrency.setExchangeExecutionId(sTrades.getTradeNum());
eCurrency.setExchangeExecutionTime(sTrades.getTradeDateTime());
eCurrency.setExchangeExecutionTime(TimeUtil.instPlusMicros(sTrades.getTradeDateTime(), sTrades.getTradeTimeMs()));
eCurrency.setExchangeExecutionMicroseconds(sTrades.getTradeDateTime()); // todo проверить это дата+время или нет
eCurrency.setPartyTradingClearingRegistryId(rgstr.getId()); // setTradingClearingRegistryId
eCurrency.setPartyTradingClearingRegistry(rgstr.getCode()); // todo уточнить rgstr.code/strades.account?

View file

@ -183,7 +183,7 @@ public class ExecutionDepositComponent {
eDeposit.setTradingDate(sTrades.getTradeDate());
eDeposit.setClearingDate(TimeUtil.toLocalDate(now));
eDeposit.setExchangeExecutionId(sTrades.getTradeNum());
eDeposit.setExchangeExecutionTime(sTrades.getTradeDateTime());
eDeposit.setExchangeExecutionTime(TimeUtil.instPlusMicros(sTrades.getTradeDateTime(), sTrades.getTradeTimeMs()));
eDeposit.setTradingClearingRegistryId(rgstr.getId());
eDeposit.setMarket(sTrades.getClassCode());
eDeposit.setPrice(sTrades.getPrice());

View file

@ -204,7 +204,7 @@ public class ExecutionFondComponent {
eFond.setTradingDate(sTrades.getTradeDate());
eFond.setClearingDate(TimeUtil.toLocalDate(now));
eFond.setExchangeExecutionId(sTrades.getTradeNum());
eFond.setExchangeExecutionTime(sTrades.getTradeDateTime());
eFond.setExchangeExecutionTime(TimeUtil.instPlusMicros(sTrades.getTradeDateTime(), sTrades.getTradeTimeMs()));
eFond.setTradingClearingRegistryId(rgstr.getId());
//todo можем ли просто переложить sTrades.getClassCode() или все такие искать, одно и тоже же

View file

@ -354,8 +354,8 @@ public class Sdf06Executor {
sDf07.setNumber(sdf06.getNumber());
sDf07.setSpec(sdf06.getSpec());
sDf07.setResult(result);
sDf07.setDoc_Date(sdf06.getDoc_Date());
sDf07.setDoc_Num(sdf06.getDoc_Num());
sDf07.setDoc_date(sdf06.getDoc_date());
sDf07.setDoc_num(sdf06.getDoc_num());
sDf07.setPay_val(sdf06.getPay_val());
return sDf07;
}

View file

@ -1,5 +1,13 @@
package ru.spcex.clearing.service.executors;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
@ -26,7 +34,21 @@ import ru.spcex.clearing.service.model.Result;
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.BalanceDimension;
import ru.spcex.platform.enumeration.InOutDirection;
import ru.spcex.platform.enumeration.InOutSDfType;
import ru.spcex.platform.enumeration.OperationCode;
import ru.spcex.platform.enumeration.OperationStatus;
import ru.spcex.platform.enumeration.RegistryCapacity;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.Sender;
import ru.spcex.platform.enumeration.StatementType;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
@ -36,20 +58,10 @@ import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Pattern;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service
public class Sdf21Executor extends AbstractExecutor<SDf21> {
private final Logger log = LoggerFactory.getLogger(getClass());
@ -193,6 +205,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
rgs.getCredit());
}, () -> {
Registry registry = RegistrySecurityBuilder.builder(imdgProvider)
.sdf21(sdf21)
.statement(stmt)
.company(company)
.account(account)
@ -428,19 +441,6 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
}
}
private static String getTkrCodeFromComment(String comment) {
if (comment == null) {
return null;
}
comment = comment.toUpperCase();
int tcrIndex = comment.indexOf("ТКР");
if (tcrIndex == -1) {
return null;
}
comment = comment.substring(tcrIndex + 3);
return comment.replaceAll("\\s+", "");
}
private static String getContractFromSpecif(String specif) {
if (specif == null) {
return null;

View file

@ -193,6 +193,11 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
boolean sessionIsPresent = sessionImdg.getFirstObjectByFieldValues(Map.of(
"workflowStatus", SessionStatus.ACTV.getKey()
)) != null;
boolean existActiveCurrSession = sessionImdg.getFirstObjectByFieldValues(
Map.of(
"workflowStatus", SessionStatus.ACTV.getKey(),
"sessionType", SessionType.CURR.getKey()
)) != null;
sdf = sdf.stream().sorted(Comparator.comparing(SpcexObjectBase::getId)).toList();
for (SDf57 sdf57 : sdf) {
IValidator validator = sDf57Validator.apply(sdf57);
@ -396,12 +401,15 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
log.trace("stmt.id={} {}.id={} TCR is empty, skipping gateway request",
stmt.getId(), asts.a__t().getRegistryCode(), asts.a__t().getId());
} else {
log.trace("sending gateway request for stmt.id={}", stmt.getId());
Optional<AssetOperationListRequest> gtwReq = gatewayRequest(stmt,
company,
account,
asts.a__t().getTradingClearingRegistry());
gtwReq.ifPresent(r -> kafka.sendRequestToQueue(Consts.ASSET_OPERATION, r));
asts.a__t().getTradingClearingRegistry(),
existActiveCurrSession);
gtwReq.ifPresent(r -> {
log.trace("sending gateway request for stmt.id={}", stmt.getId());
kafka.sendRequestToQueue(Consts.ASSET_OPERATION, r);
});
}
}
return Optional.of(asts);
@ -790,19 +798,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
return LocalDate.parse(payDate, payDateFormatter);
}
private static String getTkrCodeFromComment(String comment) {
if (comment == null) {
return null;
}
comment = comment.toUpperCase();
int tcrIndex = comment.indexOf("ТКР");
if (tcrIndex == -1) {
return null;
}
comment = comment.substring(tcrIndex + 3);
return comment.replaceAll("\\s+", "");
}
private String getContractFromSpecif(String specif) {
if (TextUtil.isEmpty(specif)) {
return null;
@ -839,11 +834,18 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
}
private static final Pattern csBlkd = Pattern.compile(SpecifFlag.CS_BLKD.getKey() + "_(\\d+).*");
private static final String COMMENT_FOR_SKIPPING_SEND_ASSETS_CURR_SESSION = "ПО ИТОГУ КЛИРИНГА";
private Optional<AssetOperationListRequest> gatewayRequest(Statement stmt, Company company, Account account, String tcrCode) {
private Optional<AssetOperationListRequest> gatewayRequest(Statement stmt, Company company, Account account,
String tcrCode, boolean existActiveCurrSession) {
if (AccountType.Anlt.equalsByKey(account.getAccountType())) {
return Optional.empty();
}
String specif = stmt.getComment();
if (existActiveCurrSession && !TextUtil.isEmpty(specif) &&
specif.toUpperCase().contains(COMMENT_FOR_SKIPPING_SEND_ASSETS_CURR_SESSION)) {
return Optional.empty();
}
String tradingCode = company.getTradingCode();
AssetOperationListRequest gatewayRequest = new AssetOperationListRequest();
Currency currency = currencyImdg.getSingleObjectByID(stmt.getSecurityId());
@ -852,7 +854,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
tradingCode,
tcrCode,
currency != null ? currency.getCurrencyCode() : CurrencyCode.RUB.getKey());
String specif = stmt.getComment();
Matcher m;
if (!TextUtil.isEmpty(specif) && (m = csBlkd.matcher(specif)).find()) {
try {

View file

@ -2,6 +2,7 @@ package ru.spcex.clearing.service.payment;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
@ -19,6 +20,7 @@ import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.classes.statics.data.sdf.SDf54;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.messages.ClearingMessage;
import ru.spcex.clearing.notification.NotificationSender;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -39,6 +41,7 @@ import ru.spcex.clearing.service.schedule.TradingTimeService;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.impl.GatewayRequester;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError;
import ru.spcex.clearing.util.LocaleUtil;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.ObjectType;
@ -51,6 +54,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidator;
@ -78,12 +82,14 @@ public class PaymentInstructionOutboundService {
private final TradingTimeService time;
private final GatewayRequester gateway;
private final NotificationSender notification;
private final SpringPropertiesLocalizer resolver;
@Autowired
public PaymentInstructionOutboundService(UserRoleVerification rights,
IMessageResolver msgs,
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, TradingTimeService time, GatewayRequester gateway, NotificationSender notification,
SpringPropertiesLocalizer resolver) {
this.imdgProvider = imdgProvider;
this.rights = rights;
this.msgs = msgs;
@ -95,7 +101,7 @@ public class PaymentInstructionOutboundService {
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
this.sdf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
this.sdf54Creator = new Sdf54Creator(imdgProvider);
this.sdf54Creator = new Sdf54Creator(imdgProvider, resolver);
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.rgsMng = rgsMng;
this.kafkaSender = kafkaSender;
@ -103,6 +109,7 @@ public class PaymentInstructionOutboundService {
this.dmiService = dmiService;
this.time = time;
this.gateway = gateway;
this.resolver = resolver;
this.gateway.setName("PaymentInstructionOutboundService|PI");
this.notification = notification;
}
@ -128,7 +135,10 @@ public class PaymentInstructionOutboundService {
log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}",
accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount);
String purpose = tcr != null ? "Возврат денежных средств, свободных от обязательств с ТКР " + tcr.getCode() + " ." : "Вывод средств.";
Locale locale = LocaleUtil.locale(accDeb);
String purpose = tcr != null ?
resolver.resolve(ClearingMessage.WithdrawalFreeFromTkr, locale, tcr.getCode()) :
resolver.resolve(ClearingMessage.WithdrawalOfFunds, locale);
if (payload.getPaymentPurpose() != null) {
String reqPmtPrpse = payload.getPaymentPurpose();
if (!(reqPmtPrpse.endsWith(".") || reqPmtPrpse.endsWith("!") || reqPmtPrpse.endsWith("?") || reqPmtPrpse.endsWith(";"))) {

View file

@ -1,5 +1,12 @@
package ru.spcex.clearing.service.registry;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -10,24 +17,20 @@ import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.service.AssetTrio;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.CompanyRole;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryStatus;
import static ru.spcex.platform.enumeration.RegistryTradingParams.CM_T;
import static ru.spcex.platform.enumeration.RegistryTradingParams.LM_T;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import static ru.spcex.platform.enumeration.RegistryTradingParams.CM_T;
import static ru.spcex.platform.enumeration.RegistryTradingParams.LM_T;
@Component
public class PaymentStateMarkService {
private final Logger log = LoggerFactory.getLogger(getClass());
@ -49,6 +52,7 @@ public class PaymentStateMarkService {
ImdgPredicate prdct = pb.and(
pb.sql(RegistryCodeSqlBuilder.getInstance(CM_T, LM_T).build()),
pb.equals("sessionId", sessionId),
pb.equals("section", Section.MKR.getKey()),
pb.equals("registryStatus", RegistryStatus.OK.getKey())
);
Collection<Registry> claimsAndLiabilities = rgsImdg.getCollectionObjectsByPredicate(prdct);

View file

@ -2,16 +2,14 @@ package ru.spcex.clearing.service.validation;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.clearing.classes.statics.data.misc.Session;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.SectionDictionary;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
@ -25,32 +23,35 @@ public enum RegistryStep3ValidationRule implements IValidationRule<ImdgValidatio
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<Registry> context) {
Registry validatedObject = context.getValidatedObject();
Supplier<String> sectionFind = () -> {
Imdg<Session> sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class);
Imdg<SectionDictionary> sectionDictionaryImdg = context.obtainMap(IMDGDistributedNames.Map_SectionDictionary, SectionDictionary.class);
Session session = sessionImdg.getSingleObjectByID(validatedObject.getSessionId());
if (session == null) {
return "null";
} else {
SectionDictionary section = sectionDictionaryImdg.getFirstObjectBySQL("code ='" + session.getSection() + "'");
if (section == null) {
return "null";
} else {
return section.getName();
}
}
};
// Supplier<String> sectionFind = () -> {
// Imdg<Session> sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class);
// Imdg<SectionDictionary> sectionDictionaryImdg = context.obtainMap(IMDGDistributedNames.Map_SectionDictionary, SectionDictionary.class);
// Session session = sessionImdg.getSingleObjectByID(validatedObject.getSessionId());
// if (session == null) {
// return "null";
// } else {
// SectionDictionary section = sectionDictionaryImdg.getFirstObjectBySQL("code ='" + session.getSection() + "'");
// if (section == null) {
// return "null";
// } else {
// return section.getName();
// }
// }
// };
if (validatedObject.getCompanyId() == null) {
return of(ClearingError.ClearingUnavailableForCompany, sectionFind.get());
return of(ClearingError.ClearingUnavailableForCompany, validatedObject.getSection());
}
Imdg<Relation> relationImdg = context.obtainMap(IMDGDistributedNames.Map_Relation, Relation.class);
Imdg<Session> sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class);
Session activeSession = sessionImdg.getSingleObjectByID(validatedObject.getSessionId());
String section = validatedObject.getSection();
Section sctn = IEnumKey.getEnumByKey(Section.class, validatedObject.getSection());
if (Section.CURR.equals(sctn)) {
section = Section.MKR.getKey();
}
Relation relation = relationImdg.getFirstObjectByFieldValues(Map.of(
"consumerId", validatedObject.getCompanyId(),
"service", activeSession.getSection()));
"service", section));
if (relation == null || (!ServiceStatus.Active.equalsByKey(relation.getServiceStatus()) && !ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus()))) {
return of(ClearingError.ClearingUnavailableForCompany, sectionFind.get(), validatedObject.getCompanyId());
return of(ClearingError.ClearingUnavailableForCompany, validatedObject.getSection(), validatedObject.getCompanyId());
}
context.storeObject(RegistryValidationStored.Relation, relation);
return empty();

View file

@ -38,6 +38,7 @@ public class SessionManager {
private final IntermediateMkrSession intermediateMkrSession;
private final FinalMkrSession finalMkrSession;
private final ReturnDepositSession returnDepositSession;
private final UnitedSession unitedSession;
private final TradingTimeService time;
public SessionManager(ImdgProvider imdgProvider,
@ -45,7 +46,7 @@ public class SessionManager {
PrimaryAuctionBnSession primaryAuctionBnSession,
PrimaryAuctionB0Session primaryAuctionB0Session,
SecondaryAuctionT0Session secondaryAuctionT0Session, CurrencySession currencySession,
IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, TradingTimeService time) {
IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, UnitedSession unitedSession, TradingTimeService time) {
this.notification = notification;
this.msgs = msgs;
this.primaryAuctionT0Session = primaryAuctionT0Session;
@ -58,6 +59,7 @@ public class SessionManager {
this.returnDepositSession = returnDepositSession;
sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class);
this.unitedSession = unitedSession;
this.time = time;
}
@ -118,6 +120,7 @@ public class SessionManager {
case MEDM -> session = intermediateMkrSession;
case FINL -> session = finalMkrSession;
case XDEP -> session = returnDepositSession;
case UNIT -> session = unitedSession;
}
return session;
}

View file

@ -9,6 +9,7 @@ public enum TaskType implements IEnumKey {
StartRevise("CLR0"),
ContinueRevise("CLR 0_0"),
StartRevisePart1("С0_1"),
SDF51("SDF51"),
/**
* step 1

View file

@ -0,0 +1,338 @@
package ru.spcex.clearing.session.stage;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.execution.ExecutionFond;
import ru.clearing.classes.statics.data.misc.Session;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.session.stage.impl.BalanceRevise;
import ru.spcex.clearing.session.stage.impl.DealsPrepare;
import ru.spcex.clearing.session.stage.impl.EndStageNotification;
import ru.spcex.clearing.session.stage.impl.FinishingSession;
import ru.spcex.clearing.session.stage.impl.FormingPaymentInstructionAssets;
import ru.spcex.clearing.session.stage.impl.FormingRegistersOnOS;
import ru.spcex.clearing.session.stage.impl.InclusionObligations;
import ru.spcex.clearing.session.stage.impl.InspectionObligations;
import ru.spcex.clearing.session.stage.impl.InspectionObligationsDepositReturn;
import ru.spcex.clearing.session.stage.impl.ObligationAdmission;
import ru.spcex.clearing.session.stage.impl.PaymentInfo;
import ru.spcex.clearing.session.stage.impl.RequirementsAndObligationCreationCompound;
import ru.spcex.clearing.session.stage.impl.UnlockResources;
import ru.spcex.clearing.session.stage.impl.compound.CompoundStageDealsPrepare;
import ru.spcex.clearing.session.stage.monitor.SessionMonitor;
import ru.spcex.clearing.session.stage.monitor.SessionMonitorFactory;
import ru.spcex.clearing.session.stage.task.DealsPreparePayload;
import ru.spcex.clearing.session.stage.task.FinishingSessionPayload;
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
import ru.spcex.clearing.session.stage.task.FormingRegistersOnOSPayload;
import ru.spcex.clearing.session.stage.task.InclusionToPoolPayload;
import ru.spcex.clearing.session.stage.task.InspectionPoolPayload;
import ru.spcex.clearing.session.stage.task.RequirementsAndObligationCreationCompoundPayload;
import ru.spcex.clearing.session.stage.task.result.DealsPrepareCompoundResult;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.SessionStatus;
import ru.spcex.platform.enumeration.SessionType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
@Service
//todo эта сессия
public class UnitedSession extends AbstractSession implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final BalanceRevise balanceRevise;
private final DealsPrepare dealsPrepareCurrency;
private final DealsPrepare dealsPrepareTRDT;
private final DealsPrepare dealsPrepareFinal;
private final RequirementsAndObligationCreationCompound requirementsAndObligationCreation;
private final ObligationAdmission obligationsAdmission;
private final InclusionObligations inclusionObligations;
private final InspectionObligationsDepositReturn inspectionObligationsReturn;
private final InspectionObligations inspectionObligations;
private final FormingRegistersOnOS formingRegistersOnOS;
private final FormingPaymentInstructionAssets formingPaymentInstructionAssets;
private final UnlockResources unlockResources;
private final FinishingSession finishingSession;
private final EndStageNotification endStageNotification;
private final Imdg<ExecutionFond> executionFondImdg;
private final Supplier<List<String>> marketCodesTrdt;
private final Supplier<List<String>> marketCodesCurr;
private SessionMonitor firstReviseMonitor;
private SessionMonitor afterPaymentsSdf4And13Monitor;
private SessionMonitor afterPaymentsReviseMonitor;
private SessionMonitor afterReviseErrorMonitor;
public UnitedSession(
ImdgProvider imdgProvider,
BalanceRevise balanceRevise,
ObjectFactory<DealsPrepare> deals,
RequirementsAndObligationCreationCompound requirementsAndObligationCreation,
ObligationAdmission obligationsAdmission,
InclusionObligations inclusionObligations, InspectionObligationsDepositReturn inspectionObligationsReturn,
FormingRegistersOnOS formingRegistersOnOS,
FormingPaymentInstructionAssets formingPaymentInstructionAssets,
UnlockResources unlockResources,
FinishingSession finishingSession,
EndStageNotification endStageNotification,
IMessageResolver messageResolver,
InspectionObligations inspectionObligations,
@Qualifier("marketCodesForCurr") Supplier<List<String>> marketCodesCurr,
@Qualifier("marketCodesForT0") Supplier<List<String>> marketCodesTrdt) {
super(imdgProvider, messageResolver);
this.balanceRevise = balanceRevise;
this.dealsPrepareCurrency = deals.getObject();
this.dealsPrepareTRDT = deals.getObject();
this.dealsPrepareFinal = deals.getObject();
this.requirementsAndObligationCreation = requirementsAndObligationCreation;
this.obligationsAdmission = obligationsAdmission;
this.inclusionObligations = inclusionObligations;
this.inspectionObligationsReturn = inspectionObligationsReturn;
this.formingRegistersOnOS = formingRegistersOnOS;
this.formingPaymentInstructionAssets = formingPaymentInstructionAssets;
this.unlockResources = unlockResources;
this.finishingSession = finishingSession;
this.endStageNotification = endStageNotification;
this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
this.inspectionObligations = inspectionObligations;
this.marketCodesTrdt = marketCodesTrdt;
this.marketCodesCurr = marketCodesCurr;
}
@Override
public void afterPropertiesSet() throws Exception {
{
dealsPrepareCurrency.searchForExecutions(ExecutionType.ExecutionCurrency);
ImdgPredicateBuilder pb = executionFondImdg.predicateBuilder();
dealsPrepareCurrency.addExecutionFondCondition(pb.regex("settlementCode", "^T0.*$"));
dealsPrepareCurrency.addExecutionFondCondition(pb.in("market", marketCodesCurr.get().toArray(new String[0])));
dealsPrepareTRDT.searchForExecutions(ExecutionType.ExecutionFond);
ImdgPredicateBuilder execFondPb = executionFondImdg.predicateBuilder();
dealsPrepareTRDT.addExecutionFondCondition(execFondPb.regex("settlementCode", "^T0.*$"));
dealsPrepareTRDT.addExecutionFondCondition(execFondPb.in("market", marketCodesTrdt.get().toArray(new String[0])));
dealsPrepareFinal.searchForExecutions(ExecutionType.ExecutionDeposit);
dealsPrepareFinal.addExecutionDepositCondition(pb.regex("firstLegSettlementCode", "^T0.*$"));
}
//1 шаг deals prepare вызываем 3 раза с разными параметрами объединяемых сессий
inclusionObligations.setSessionType(sessionType());
inspectionObligationsReturn.setSessionType(sessionType());
inspectionObligations.setSection(section());
inspectionObligations.setSessionType(sessionType());
formingPaymentInstructionAssets.setSessionType(sessionType());
finishingSession.setSection(section());
finishingSession.setSessionType(sessionType());
imdgProvider.waitAvailable();
initSessionIfPresent();
}
@Override
public void runSession(BaseRequest<?> req) {
if (!startSession()) {
return;
}
StageResult<?> submit = balanceRevise.submit(new Task<>(TaskType.StartRevise, null));
if (!submit.success) {
log.error("stage {} error={}", balanceRevise.getClass().getSimpleName(), messageResolver.resolve(submit.error));
endSession();
} else {
log.info("stage BalanceRevise success, waiting for a response from kafka");
this.firstReviseMonitor = SessionMonitorFactory.waitRevise();
}
}
public void continueSession(BaseRequest<?> req) {
try {
if (!isRunning()) {
return;
}
log.info("session is running, stage {}, monitors: {}",
currStage.get(),
logMonitors(firstReviseMonitor, afterPaymentsSdf4And13Monitor, afterPaymentsReviseMonitor));
if (firstReviseMonitor != null && isMonitorPassed(firstReviseMonitor, req.getRequestPayload())) {
firstReviseMonitor = null;
firstPart();
return;
}
if (afterPaymentsSdf4And13Monitor != null && isMonitorPassed(afterPaymentsSdf4And13Monitor, req.getRequestPayload())) {
afterPaymentsSdf4And13Monitor = null;
checkStageAndThrow(TaskType.FormingPaymentInstruction);
finishPart();
return;
}
if (afterReviseErrorMonitor != null && isMonitorPassed(afterReviseErrorMonitor, req.getRequestPayload())) {
afterReviseErrorMonitor = null;
finishPart();
return;
}
//if (afterPaymentsReviseMonitor != null && isMonitorPassed(afterPaymentsReviseMonitor, req.getRequestPayload())) {
// afterPaymentsReviseMonitor = null;
// finishPart();
//}
} catch (StageException e) {
//already logged
}
}
private void firstPart() {
try {
if (!checkStage(TaskType.StartRevise)) {
log.error("cannot continue session, current stage is {}", currStage.get());
throw new StageException();
}
runStage(TaskType.StartRevisePart1, currSession.getId(), balanceRevise);
//stage 1
StageResult<DealsPrepareCompoundResult> dealsPreparationResult;
{
DealsPreparePayload payload = new DealsPreparePayload();
payload.setSessionId(currSession.getId());
dealsPreparationResult = runStage(TaskType.DealsPrepare, payload, new CompoundStageDealsPrepare(
dealsPrepareTRDT, dealsPrepareCurrency, dealsPrepareFinal
));
}
//stage 2
{
RequirementsAndObligationCreationCompoundPayload p;
p = RequirementsAndObligationCreationCompoundPayload.create(dealsPreparationResult.getStageResult());
runStage(TaskType.RequirementsAndObligationsCreate, p, requirementsAndObligationCreation);
}
//stage 3
runStage(TaskType.ObligationsAdmission, currSession.getId(), obligationsAdmission);
//stage 4
{
InclusionToPoolPayload inclusionToPoolPayload = new InclusionToPoolPayload();
inclusionToPoolPayload.setSessionType(currSession.getSessionType());
inclusionToPoolPayload.setSessionId(currSession.getId());
runStage(TaskType.InclusionToPool, inclusionToPoolPayload, inclusionObligations);
}
{
InspectionPoolPayload companyIdPayload = new InspectionPoolPayload();
companyIdPayload.setSessionId(currSession.getId());
companyIdPayload.setProcessedCompanyId(currSession.getCompanyId());
//fixme checks inside the stages
//runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligationsReturn);
runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligations);
}
//stage 6
{
FormingRegistersOnOSPayload payload = new FormingRegistersOnOSPayload();
payload.setSessionId(currSession.getId());
runStage(TaskType.FormingRegistersOnOS, payload, formingRegistersOnOS); //returns Collection<Registry>
}
//stage 7
StageResult<PaymentInfo> paymentResult = null;
{
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
payload.setSessionId(currSession.getId());
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionAssets);
}
if (paymentResult.getStageResult().getPaymentInstructions().isEmpty()) {
log.info("no payment instructions were created");
finishPart();
} else {
this.afterPaymentsSdf4And13Monitor = SessionMonitorFactory.waitStep7Unit(
paymentResult.getStageResult().getSdfTypes()
);
log.info("created {} PaymentInstructions, waiting for {}",
paymentResult.getStageResult().getPaymentInstructions().size(),
this.afterPaymentsSdf4And13Monitor.allConditions());
}
} catch (StageException e) {
//already logged
}
}
public void finishPart() {
try {
//stage 9 continue revision
{
StageResult<Object> reviseRes = runStage(TaskType.AgainRevise, currSession.getId(), balanceRevise, false);
if (!reviseRes.isSuccess()) {
this.afterReviseErrorMonitor = SessionMonitorFactory.waitReviseError(section());
log.warn("{} stage error, created monitor for {}",
TaskType.AgainRevise,
afterReviseErrorMonitor.allConditions());
return;
}
}
//stage 10
{
FinishingSessionPayload payload = new FinishingSessionPayload();
payload.setSessionId(currSession.getId());
payload.setPr("1");
runStage(TaskType.FinishingSession, payload, finishingSession);
}
//stage 11
{
//Убрал этот шаг по требованию Насти, 18.06.2024
//выпадало на строчке EndStageNotification:101
// throw new IllegalArgumentException("Unsupported section " + section);
// EndStageNotificationPayload payload = new EndStageNotificationPayload();
// payload.setSection(currSession.getSection());
// payload.setSessionId(currSession.getId());
// runStage(TaskType.EndStageNotification, payload, endStageNotification);
endSession();
}
} catch (StageException e) {
//already logged
}
}
private void sendSdf56() {
runStage(TaskType.FormingPaymentInstruction, balanceRevise);
this.afterPaymentsReviseMonitor = SessionMonitorFactory.waitRevise();
}
private boolean startSession() {
synchronized (this.currStage) {
if (this.currStage.get() != null) {
log.info("already running session.id={}", this.currSession.getId());
return false;
} else {
TaskType startStatus = TaskType.StartRevise;
Session newSession = new Session();
newSession.setSection(section().getKey());
newSession.setSessionType(sessionType().getKey());
newSession.setSessionStatus(startStatus.getKey());
newSession.setWorkflowStatus(SessionStatus.ACTV.getKey());
newSession.setClearingDate(LocalDate.now());
newSession.setCreated(Instant.now());
//todo companyId/securityId/userId передается из сообщения очереди
sessionImdg.insert(newSession);
currSession = newSession;
log.info("started new session.id={}", this.currSession.getId());
currStage.set(TaskType.StartRevise);
return true;
}
}
}
@Override
protected Section section() {
return Section.MULT;
}
@Override
protected SessionType sessionType() {
return SessionType.UNIT;
}
}

View file

@ -77,6 +77,9 @@ public class BalanceRevise implements ISessionStage {
@Override
public StageResult<?> submit(Task<?> task) {
switch (task.getTaskType()) {
case SDF51 -> {
return sendSdfs51();
}
case StartRevise, FormingPaymentInstruction -> {
LocalTime fromTime = null;
if (task.getData() instanceof LocalTime) {

View file

@ -2,7 +2,9 @@ package ru.spcex.clearing.session.stage.impl;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@ -33,6 +35,7 @@ import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.FinishingSessionPayload;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.enumeration.CoverageStatus;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryStatus;
@ -146,7 +149,7 @@ public class FinishingSession implements ISessionStage {
int allowed = 0;
int notAllowed = 0;
SessionType sessionType = getEnumByKey(SessionType.class, session.getSessionType());
if (IEnumKey.contains(sessionType, SessionType.FINL, SessionType.MEDM)) {
if (IEnumKey.contains(sessionType, SessionType.FINL, SessionType.MEDM, SessionType.UNIT)) {
Collection<ExecutionDeposit> executions = findExecutionDepositBySessionId(sessionId);
log.trace("loaded {} ExecutionDeposits for sessionId {}", executions.size(), sessionId);
for (ExecutionDeposit execution : executions) {
@ -171,7 +174,8 @@ public class FinishingSession implements ISessionStage {
allowed,
notAllowed,
executions.size() - (allowed + notAllowed));
} else if (IEnumKey.contains(sessionType, SessionType.CURR, SessionType.TRDT, SessionType.IPOB, SessionType.IPO0, SessionType.IPOT)) {
}
if (IEnumKey.contains(sessionType, SessionType.CURR, SessionType.TRDT, SessionType.IPOB, SessionType.IPO0, SessionType.IPOT, SessionType.UNIT)) {
Collection<? extends ExecutionCommon> executions = findExecutionFondBySessionId(sessionId, sessionType);
log.trace("loaded {} Executions for sessionId {}", executions.size(), sessionId);
for (ExecutionCommon execution : executions) {
@ -188,7 +192,7 @@ public class FinishingSession implements ISessionStage {
}
execution.setCoverageStatus(toStatus.getKey());
execution.setUpdated(Instant.now());
if (sessionType.equals(SessionType.CURR)) {
if (execution.type().equals(ExecutionType.ExecutionCurrency)) {
executionCurrencyImdg.update((ExecutionCurrency) execution);
} else {
executionFondImdg.update((ExecutionFond) execution);
@ -226,7 +230,7 @@ public class FinishingSession implements ISessionStage {
}
}
sdf05Sender.sendSdf05(pr);
if (Section.FOND.equals(section)) {
if (Section.FOND.equals(section) || Section.MULT.equals(section)) {
sdf14Sender.sendSdf14(sessionId);
}
StageResult<Collection<Registry>> res = new StageResult<>(null, true);
@ -310,16 +314,29 @@ public class FinishingSession implements ISessionStage {
}
protected Collection<? extends ExecutionCommon> findExecutionFondBySessionId(Long sessionId, SessionType sessionType) {
Imdg<? extends ExecutionCommon> excImdg;
if (sessionType.equals(SessionType.CURR)) {
excImdg = executionCurrencyImdg;
if (sessionType.equals(SessionType.UNIT)) {
List<ExecutionCommon> res = new ArrayList<>();
res.addAll(findExecutionFondBySessionId(sessionId, executionCurrencyImdg));
res.addAll(findExecutionFondBySessionId(sessionId, executionFondImdg));
return res;
} else {
excImdg = executionFondImdg;
Imdg<? extends ExecutionCommon> excImdg;
if (sessionType.equals(SessionType.CURR)) {
excImdg = executionCurrencyImdg;
} else {
excImdg = executionFondImdg;
}
return findExecutionFondBySessionId(sessionId, excImdg);
}
}
protected Collection<? extends ExecutionCommon> findExecutionFondBySessionId(
Long sessionId,
Imdg<? extends ExecutionCommon> excImdg) {
ImdgPredicateBuilder pb = excImdg.predicateBuilder();
ImdgPredicate prdct = pb.or(
pb.equals("sessionId", sessionId),
pb.equals("settlementDate", LocalDate.now())
pb.equals("sessionId", sessionId),
pb.equals("settlementDate", LocalDate.now())
);
Collection<? extends ExecutionCommon> result = excImdg.getCollectionObjectsByPredicate(prdct)
.stream()

View file

@ -47,9 +47,11 @@ import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.Allowed;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.enumeration.OperationStatus;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
import ru.spcex.platform.enumeration.RegistryUnit;
@ -161,7 +163,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
private StageResult<?> formingPaymentInstructions(FormingPaymentInstructionPayload payload) {
Long sessionId = payload.getSessionId();
if (SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) {
if (SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType) || SessionType.UNIT.equals(sessionType)) {
dmvSrv.createDmv(sessionId);
}
Collection<Registry> AMBregistries = selectAMBRegistries(sessionId);
@ -252,7 +254,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
.debitLegAccount(debitLegAccount)
.creditLegAccount(creditLegAccount)
.amount(amount)
.currency(SessionType.CURR.equals(sessionType) ? registry.getSecuritySymbol() : null)
.currency(registry.getSecuritySymbol())
.sessionId(sessionId)
.checkBLKD((SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType))
&& !isPositiveBalance ? registry : null)
@ -325,7 +327,8 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
.creditLegAccount(creditLegAccount)
.amount(amount)
.sessionId(sessionId)
.currency(SessionType.CURR.equals(sessionType) ? registry.getSecuritySymbol() : null)
.currency(SessionType.CURR.equals(sessionType) || Section.CURR.equalsByKey(registry.getSection())
? registry.getSecuritySymbol() : null)
.purpose(String.format("Перевод по итогу клиринга по ТКР %s", registry.getTradingClearingRegistry()));
PaymentInstruction paymentInstruction = paymentInstructionBuilder.build();
log.debug("Created paymentInstruction by registry.id: {}", registry.getId());
@ -353,6 +356,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
}
private BigDecimal adjustAmountByReturns(Registry amb, Long sessionId) {//companyid, tcr/account, sessionId, RUB
if (SessionType.UNIT.equals(sessionType)) return BigDecimal.ZERO;
Long companyId = amb.getCompanyId();
Long tradingClearingRegistryId = amb.getTradingClearingRegistryId();
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
@ -399,10 +403,13 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
List<SDf12> sDf12Created = new ArrayList<>();
for (Pair<PaymentInstruction, Registry> pair : formedPaymentInstructions) {
PaymentInstruction paymentInstruction = pair.getFirst();
Registry rgs = pair.getSecond();
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId());
Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId());
if (SessionType.CURR.equals(sessionType)) {
boolean madeStatements = createStatementsIfNeeded(paymentInstruction, pair.getSecond());
if (SessionType.CURR.equals(sessionType) || (rgs != null
&& RegistryInstrumentType.M.equalsByKey(rgs.getRegistryInstrumentType())
&& !CurrencyCode.isRub(rgs.getSecuritySymbol()))) {
boolean madeStatements = statementsWereMade(paymentInstruction, rgs);
if (madeStatements) {
continue;
}
@ -485,16 +492,20 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
return sDf12;
}
private boolean createStatementsIfNeeded(PaymentInstruction pmt, Registry am_b) {
private boolean statementsWereMade(PaymentInstruction pmt, Registry am_b) {
ImdgPredicateBuilder pb = stlmHPropsImdg.predicateBuilder();
String curCode = pmt.getCreditLeg_currencyCode();
boolean noNeedForStatements = stlmHPropsImdg.getFirstObjectByPredicate(
pb.and(
pb.in("currencyCode", curCode),
pb.equals("companyId", Sender.Prc.getId())
)
) != null;
if (noNeedForStatements) return false;
{
SettlementHouseProperties sttHs = stlmHPropsImdg.getFirstObjectByPredicate(
pb.and(
pb.in("currencyCode", curCode),
pb.equals("companyId", Sender.Prc.getId())
)
);
if (sttHs != null) {
return false;
}
}
Supplier<Statement> stmtBldr = () -> {
Statement stmt = new Statement();
stmt.setSenderId(Sender.One.getId());

View file

@ -171,8 +171,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
.cm_t(cm_t)
.tranAcc(tranAcc)
.sessionId(sessionId)
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга")
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга")
.currency(lm_t.getSecuritySymbol())
.build();
Pair.forEach(pmts, paymentInstructionImdg::insert);
@ -231,8 +231,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
.cm_t(cm_t)
.tranAcc(tranAcc)
.sessionId(sessionId)
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга")
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга")
.currency(lm_t.getSecuritySymbol())
.build();
Pair.forEach(pmts, paymentInstructionImdg::insert);

View file

@ -204,8 +204,8 @@ public class FormingPaymentInstructionReturnMkr implements ISessionStage {
.cm_t(cm_t)
.tranAcc(tranAcc)
.sessionId(sessionId)
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга")
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга")
.currency(lm_t.getSecuritySymbol())
.build();
Pair.forEach(pmts, paymentInstructionImdg::insert);

View file

@ -30,6 +30,7 @@ import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.SessionType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
@ -37,6 +38,7 @@ 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.IEnumKey;
import ru.spcex.platform.utils.text.TextUtil;
@Service
@ -115,6 +117,7 @@ public class InclusionObligations implements ISessionStage {
} else {
registryPredicate = prdctBuilder.and(
defaultCondition,
SessionType.UNIT.equals(sessionType) ? prdctBuilder.equals("sessionId", sessionId) : prdctBuilder.alwaysTrue(),
prdctBuilder.equals("registryStatus", RegistryStatus.PROC.getKey())
);
}
@ -126,33 +129,46 @@ public class InclusionObligations implements ISessionStage {
for (Map.Entry<Long, List<Registry>> entrySet : registryByGroupId.entrySet()) {
log.debug("Processing set of registry with groupId: {}", entrySet.getKey());
String rgsSection = null;
for (Registry registry : entrySet.getValue()) {
registry.setRegistryStatus(RegistryStatus.POOL.getKey());
registry.setClearingDate(LocalDate.now());
registry.setSessionId(sessionId);
obtainSessionType(sessionId).ifPresent(st -> registry.setSessionType(st.getKey()));
registryImdg.update(registry);
updateExecutions(sessionId, entrySet.getKey());
if (TextUtil.isEmpty(rgsSection)) {
rgsSection = registry.getSection();
}
}
updateExecutions(sessionId, entrySet.getKey(), rgsSection);
}
return new StageResult(null, true);
}
@SuppressWarnings("unchecked")
private <T extends ExecutionCommon> void updateExecutions(Long sessionId, Long rgsGroupId) {
private <T extends ExecutionCommon> void updateExecutions(Long sessionId, Long rgsGroupId, String rgsSection) {
Instant now = Instant.now();
SessionType ssnTpe = obtainSessionType(sessionId).orElse(null);
if (ssnTpe == null || sessionId == null) {
log.debug("will not update executions#sessionId - couldn't determine session type");
return;
}
Imdg<T> execImdg;
Imdg<T> execImdg = null;
switch (ssnTpe) {
case MEDM, FINL, XDEP -> execImdg = (Imdg<T>) executionDepositImdg;
case IPO0, IPOB, TRDT, IPOT -> execImdg = (Imdg<T>) executionFondImdg;
case CURR -> execImdg = (Imdg<T>) executionCurrImdg;
default -> execImdg = null;
default -> {
//кейс для "общих" сессий (напр. UNIT) в которых сочетаются разные сделки
//смотрим на секцию регистра.
Section section;
if ((section = IEnumKey.getEnumByKey(Section.class, rgsSection)) != null) {
if (section.equals(Section.MKR)) execImdg = (Imdg<T>) executionDepositImdg;
else if (section.equals(Section.FOND)) execImdg = (Imdg<T>) executionFondImdg;
else if (section.equals(Section.CURR)) execImdg = (Imdg<T>) executionCurrImdg;
}
}
}
if (execImdg == null) {
log.warn("couldn't define Execution Type for session {}. Will not update executions#sessionId",
@ -162,10 +178,11 @@ public class InclusionObligations implements ISessionStage {
ImdgPredicateBuilder pb = execImdg.predicateBuilder();
ImdgPredicate prdct = pb.equals("exchangeExecutionId", rgsGroupId);
Collection<T> execs = execImdg.getCollectionObjectsByPredicate(prdct);
Imdg<T> finalExecImdg = execImdg;
execs.forEach(e -> {
e.setUpdated(now);
e.setSessionId(sessionId);
execImdg.update(e);
finalExecImdg.update(e);
});
}

View file

@ -107,7 +107,19 @@ public class InspectionObligations implements ISessionStage {
collect(Collectors.groupingBy(Registry::getGroupId))
.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.sorted((entry1, entry2) -> {
long minId1 = entry1.getValue().stream()
.mapToLong(Registry::getId)
.min()
.orElse(Long.MIN_VALUE);
long minId2 = entry2.getValue().stream()
.mapToLong(Registry::getId)
.min()
.orElse(Long.MIN_VALUE);
return Long.compare(minId1, minId2);
})
.toList();
log.info("found {} ({} groups) registries by sql: {}", registriesToProcess.size(), registriesByGroupSorted.size(), sqlCondition);
@ -123,7 +135,7 @@ public class InspectionObligations implements ISessionStage {
boolean isUncovered = false;
List<CheckResult> checkResults = new ArrayList<>();
for (Registry obligation : obligationsInGroup) {
if ((SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) && RegistryInstrumentType.S.equalsByKey(obligation.getRegistryInstrumentType())) {
if ((SessionType.FINL.equals(sessionType) || SessionType.UNIT.equals(sessionType) || SessionType.MEDM.equals(sessionType)) && RegistryInstrumentType.S.equalsByKey(obligation.getRegistryInstrumentType())) {
checkResults.add(new CheckResult(obligation, false));
continue;
}
@ -156,7 +168,7 @@ public class InspectionObligations implements ISessionStage {
failGroup.run();
continue;
}
if (Section.MKR.equals(section) && mOrS.equals(RegistryInstrumentType.S)) {
if (Section.MKR.equalsByKey(rgs.getSection()) && mOrS.equals(RegistryInstrumentType.S)) {
continue;
}
Optional<Registry> a__t = assets.searchByTcrCompanyAccount(rgs, A__T.type(mOrS));

View file

@ -1,5 +1,12 @@
package ru.spcex.clearing.session.stage.impl;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -18,21 +25,19 @@ import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.InspectionPoolPayload;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.enumeration.RegistryCapacity;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
import ru.spcex.platform.enumeration.RegistryUnit;
import ru.spcex.platform.enumeration.SessionType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@ -205,7 +210,7 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
}
}
if (SessionType.FINL.equals(sessionType)
if ((SessionType.FINL.equals(sessionType) || SessionType.UNIT.equals(sessionType))
&& amfBalance.compareTo(omtBalance) >= 0
&& initiatorV(omtRgs) && gatewayIfNeeded(omtRgs)) {
log.debug("OM*T.id={} -> no DM*X/DM*T(INFO/CLRN) registry found. " +
@ -244,10 +249,12 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
private Optional<Registry> searchAssetByOMT(Registry obligation) {
String sqlCondition = String.format("%s and " +
"tradingClearingRegistryId = '%s' and " +
"companyId = '%s'",
"companyId = '%s' and "+
"securitySymbol = '%s'",
RegistryCodeSqlBuilder.getInstance(AM_F).build(),
obligation.getTradingClearingRegistryId(),
obligation.getCompanyId());
obligation.getCompanyId(),
obligation.getSecuritySymbol());
Registry amf = registryImdg.getFirstObjectBySQL(sqlCondition);
return Optional.ofNullable(amf);
}
@ -262,7 +269,7 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
}
private RegistryStatus registryStatusFailed() {
if (SessionType.FINL.equals(sessionType)) {
if (SessionType.FINL.equals(sessionType) || SessionType.UNIT.equals(sessionType)) {
return RegistryStatus.FAIL;
} else {
return RegistryStatus.MNG;
@ -270,7 +277,7 @@ public class InspectionObligationsDepositReturn implements ISessionStage {
}
private RegistryStatus registryStatusFailed(Registry registry) {
if (SessionType.FINL.equals(sessionType)) {
if (SessionType.FINL.equals(sessionType) || SessionType.UNIT.equals(sessionType)) {
if (equalByRgs(OM_T, registry)) {
return RegistryStatus.UNCV;
} else {

View file

@ -33,6 +33,7 @@ import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
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.ImdgProvider;
@ -195,6 +196,7 @@ public class RegistryCurrBuilder implements IRegistryBuilder {
reg.setGroupId(groupId());
reg.setSessionId(exec.getSessionId());
reg.setSessionType(sessionType());
reg.setSection(Section.CURR.getKey());
return reg;
}

View file

@ -1,5 +1,8 @@
package ru.spcex.clearing.session.stage.impl;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.DepoAccount;
@ -15,14 +18,20 @@ import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.BalanceDimension;
import ru.spcex.platform.enumeration.ISide;
import ru.spcex.platform.enumeration.MoneyFlowSide;
import ru.spcex.platform.enumeration.RegistryCapacity;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
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.ImdgProvider;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
public class RegistryDepoBuilder implements IRegistryBuilder {
private Imdg<Company> companyImdg;
private Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
@ -148,6 +157,7 @@ public class RegistryDepoBuilder implements IRegistryBuilder {
reg.setGroupId(groupId());
reg.setSessionId(exec.getSessionId());
reg.setSessionType(sessionType());
reg.setSection(Section.MKR.getKey());
return reg;
}

View file

@ -1,5 +1,10 @@
package ru.spcex.clearing.session.stage.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.DepoAccount;
@ -16,17 +21,21 @@ import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.BalanceDimension;
import ru.spcex.platform.enumeration.ISide;
import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.enumeration.MoneyFlowSide;
import ru.spcex.platform.enumeration.RegistryCapacity;
import ru.spcex.platform.enumeration.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryInstrumentType;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryUnit;
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.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
public class RegistryFondBuilder implements IRegistryBuilder {
@ -103,19 +112,24 @@ public class RegistryFondBuilder implements IRegistryBuilder {
if ((regDsgn.equals(RegistryDesignation.O) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && side.isSell())) {
isMoney = true;
reg.setAccountId(tcr.getMoneyAccountId());
account = accountImdg.getSingleObjectByID(tcr.getMoneyAccountId());
if (tcr.getMoneyAccountId() != null) {
account = accountImdg.getSingleObjectByID(tcr.getMoneyAccountId());
capacityByAccount = defineCapacityByAccountType(account.getAccountType(), tcr.getMoneyAccountId());
}
reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey());
reg.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme add second leg code branch
Currency currency = currencyImdg.getFirstObjectByFieldValues(Map.of("currencyCode", exec.getSettlementCurrency()));
reg.setSecurityId(currency.getId());
reg.setSecuritySymbol(currency.getCurrencyCode());
capacityByAccount = defineCapacityByAccountType(account.getAccountType(), tcr.getMoneyAccountId());
} else if ((regDsgn.equals(RegistryDesignation.T) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && side.isSell())) {
isMoney = false;
account = accountImdg.getSingleObjectByID(tcr.getDepoAccountId());
reg.setAccountId(tcr.getDepoAccountId());
DepoAccount depoAccount = depoAccountImdg.getFirstObjectByFieldValues(
DepoAccount depoAccount = null;
if (tcr.getDepoAccountId() != null) {
account = accountImdg.getSingleObjectByID(tcr.getDepoAccountId());
depoAccount = depoAccountImdg.getFirstObjectByFieldValues(
Map.of("accountId", tcr.getDepoAccountId()));
}
if (depoAccount != null) {
capacityByAccount = depoAccount.getDepoAccountType();
}
@ -162,6 +176,7 @@ public class RegistryFondBuilder implements IRegistryBuilder {
reg.setGroupId(groupId());
reg.setSessionId(exec.getSessionId());
reg.setSessionType(sessionType());
reg.setSection(Section.FOND.getKey());
return reg;
}

View file

@ -1,7 +1,6 @@
package ru.spcex.clearing.session.stage.impl;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -23,6 +22,8 @@ import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.TaskType;
import static ru.spcex.clearing.util.ComparatorUtil.execIdComparator;
import static ru.spcex.clearing.util.ComparatorUtil.tradeTimeComparator;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.enumeration.ISide;
import ru.spcex.platform.enumeration.MoneyFlowSide;
@ -65,8 +66,8 @@ public class RequirementsAndObligationCreation implements ISessionStage {
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
}
private StageResult<?> createRegisters(List<ExecutionCommon> data) {
data.sort(Comparator.comparing(ExecutionCommon::getExchangeExecutionId));
protected StageResult<?> createRegisters(List<ExecutionCommon> data) {
data.sort(tradeTimeComparator.thenComparing(execIdComparator));
//см. описание к #matchExecutions
for (int i = 0; i < data.size(); ) {
Pair<ExecutionCommon, ExecutionCommon> matched = matchExecutions(data, i);
@ -219,7 +220,7 @@ public class RequirementsAndObligationCreation implements ISessionStage {
* если это не так, передалать на коллекцию Long executionId в правильном порядке
* и для каждого искать мэтч отдельно в Imdg, с сохранением уже обработанных для избежания дублирования
*/
private Pair<ExecutionCommon, ExecutionCommon> matchExecutions(List<ExecutionCommon> data, int i) {
protected Pair<ExecutionCommon, ExecutionCommon> matchExecutions(List<ExecutionCommon> data, int i) {
//if the last execution, then no match
if (i >= data.size() - 1) {
return null;

View file

@ -0,0 +1,96 @@
package ru.spcex.clearing.session.stage.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.stage.task.RequirementsAndObligationCreationCompoundPayload;
import static ru.spcex.clearing.util.ComparatorUtil.execIdComparator;
import static ru.spcex.clearing.util.ComparatorUtil.tradeTimeComparator;
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.collection.Pair;
/**
* LiabilitiesAndClaims
*/
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RequirementsAndObligationCreationCompound extends RequirementsAndObligationCreation {
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
public RequirementsAndObligationCreationCompound(ImdgProvider imdgProvider) {
super(imdgProvider);
}
@SuppressWarnings("unchecked")
@Override
public StageResult<?> submit(Task<?> task) {
if (task.getTaskType() == TaskType.RequirementsAndObligationsCreate) {
return mergeReqsAndClaims((RequirementsAndObligationCreationCompoundPayload) task.getData());
}
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
}
private StageResult<?> mergeReqsAndClaims(RequirementsAndObligationCreationCompoundPayload data) {
List<ExecutionCommon> tmpList = new ArrayList<>(Arrays.asList(new ExecutionCommon[2]));
List<ExecutionCommon> executionFond = data.getExecutionsTrdt();
List<ExecutionCommon> executionCurrency = data.getExecutionsCurrency();
List<ExecutionCommon> executionDeposit = data.getExecutionsFinal();
Stream.of(executionFond, executionCurrency, executionDeposit).forEach(c -> c.sort(tradeTimeComparator.thenComparing(execIdComparator)));
int efs = executionFond.size();
int eds = executionDeposit.size();
int ecs = executionCurrency.size();
int[] ief= {0}, ied= {0}, iec= {0};
while (ief[0] < efs || ied[0] < eds || iec[0] < ecs) {
Pair<ExecutionCommon, ExecutionCommon> pair = getMinTimeExecutions(
safeMatch(executionFond, ief),
safeMatch(executionDeposit, ied),
safeMatch(executionCurrency, iec)
);
if (pair == null) continue;
if (pair.getFirst().type().equals(ExecutionType.ExecutionFond)) ief[0] += 2;
if (pair.getFirst().type().equals(ExecutionType.ExecutionDeposit)) ied[0] += 2;
if (pair.getFirst().type().equals(ExecutionType.ExecutionCurrency)) iec[0] += 2;
pair.map(f -> tmpList.set(0, f), s -> tmpList.set(1, s));
createRegisters(tmpList);
}
return new StageResult<>(null, true);
}
private Pair<ExecutionCommon, ExecutionCommon> safeMatch(List<ExecutionCommon> l, int[] i) {
Pair<ExecutionCommon, ExecutionCommon> pair = matchExecutions(l, i[0]);
if (pair == null) {
i[0]++;
return null;
}
// i[0] += 2;
return pair;
}
private Pair<ExecutionCommon, ExecutionCommon> getMinTimeExecutions(
Pair<ExecutionCommon, ExecutionCommon> fond,
Pair<ExecutionCommon, ExecutionCommon> deposit,
Pair<ExecutionCommon, ExecutionCommon> currency) {
return Stream.of(fond, deposit, currency)
.filter(Objects::nonNull)
.min((p1, p2) -> tradeTimeComparator.compare(p1.getFirst(), p2.getFirst())).orElse(null);
}
}

View file

@ -0,0 +1,34 @@
package ru.spcex.clearing.session.stage.impl.compound;
import java.util.ArrayList;
import java.util.List;
import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
public abstract class CompoundStage<T> implements ISessionStage {
private final List<ISessionStage> stages;
public CompoundStage(ISessionStage... stages) {
this.stages = new ArrayList<>();
this.stages.addAll(List.of(stages));
}
protected abstract Object mapper(List<T> results);
@Override
public StageResult<?> submit(Task<?> task) {
List<Object> innerResults = new ArrayList<>();
for (ISessionStage stage : stages) {
StageResult<?> submit = stage.submit(task);
if (!submit.isSuccess()) {
return submit;
}
innerResults.add(submit.getStageResult());
}
StageResult<Object> result = new StageResult<>(null, true);
result.setStageResult(mapper((List<T>) innerResults));
return result;
}
}

View file

@ -0,0 +1,22 @@
package ru.spcex.clearing.session.stage.impl.compound;
import java.util.List;
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
import ru.spcex.clearing.session.stage.impl.DealsPrepare;
import ru.spcex.clearing.session.stage.task.result.DealsPrepareCompoundResult;
public class CompoundStageDealsPrepare extends CompoundStage<List<ExecutionCommon>> {
public CompoundStageDealsPrepare(DealsPrepare... stages) {
super(stages);
}
@Override
protected Object mapper(List<List<ExecutionCommon>> results) {
DealsPrepareCompoundResult res = new DealsPrepareCompoundResult();
res.setExecutionsTrdt(results.get(0));
res.setExecutionsCurrency(results.get(1));
res.setExecutionsFinal(results.get(2));
return res;
}
}

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.session.stage.monitor;
import java.util.Collection;
import ru.spcex.platform.enumeration.SdfTable;
import ru.spcex.platform.enumeration.Section;
@ -29,7 +30,7 @@ public class SessionMonitorFactory {
.addCondition(new SdfCondition(SdfTable.SDF_01))
.addCondition(new SdfCondition(SdfTable.SDF_57));
}
case FOND -> {
case FOND, MULT -> {
return SessionMonitor.create()
.addCondition(new SdfCondition(SdfTable.SDF_04))
.addCondition(new SdfCondition(SdfTable.SDF_13))
@ -42,6 +43,19 @@ public class SessionMonitorFactory {
}
}
public static SessionMonitor waitStep7Unit(Collection<SdfTable> sdfTypes) {
SessionMonitor monitor = SessionMonitor.create()
.addCondition(new SdfCondition(SdfTable.SDF_04))
.addCondition(new SdfCondition(SdfTable.SDF_01))
.addCondition(new SdfCondition(SdfTable.SDF_57));
if (sdfTypes.stream().anyMatch(t -> t.equals(SdfTable.SDF_12))) {
monitor.addCondition(new SdfCondition(SdfTable.SDF_13));
monitor.addCondition(new SdfCondition(SdfTable.SDF_08));
monitor.addCondition(new SdfCondition(SdfTable.SDF_21));
}
return monitor;
}
public static SessionMonitor waitRevise() {
return SessionMonitor.create()
.addCondition(new SdfCondition(SdfTable.SDF_01))
@ -56,7 +70,7 @@ public class SessionMonitorFactory {
.addCondition(new SdfCondition(SdfTable.SDF_01))
.addCondition(new SdfCondition(SdfTable.SDF_57));
}
case FOND -> {
case FOND, MULT -> {
return SessionMonitor.create()
.addCondition(new SdfCondition(SdfTable.SDF_08))
.addCondition(new SdfCondition(SdfTable.SDF_21))

View file

@ -0,0 +1,43 @@
package ru.spcex.clearing.session.stage.task;
import java.util.List;
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
import ru.spcex.clearing.session.stage.task.result.DealsPrepareCompoundResult;
public class RequirementsAndObligationCreationCompoundPayload {
private List<ExecutionCommon> executionsTrdt;
private List<ExecutionCommon> executionsCurrency;
private List<ExecutionCommon> executionsFinal;
public static RequirementsAndObligationCreationCompoundPayload create(DealsPrepareCompoundResult stageResult) {
RequirementsAndObligationCreationCompoundPayload p = new RequirementsAndObligationCreationCompoundPayload();
p.setExecutionsTrdt(stageResult.getExecutionsTrdt());
p.setExecutionsCurrency(stageResult.getExecutionsCurrency());
p.setExecutionsFinal(stageResult.getExecutionsFinal());
return p;
}
public List<ExecutionCommon> getExecutionsTrdt() {
return executionsTrdt;
}
public void setExecutionsTrdt(List<ExecutionCommon> executionsTrdt) {
this.executionsTrdt = executionsTrdt;
}
public List<ExecutionCommon> getExecutionsCurrency() {
return executionsCurrency;
}
public void setExecutionsCurrency(List<ExecutionCommon> executionsCurrency) {
this.executionsCurrency = executionsCurrency;
}
public List<ExecutionCommon> getExecutionsFinal() {
return executionsFinal;
}
public void setExecutionsFinal(List<ExecutionCommon> executionsFinal) {
this.executionsFinal = executionsFinal;
}
}

View file

@ -0,0 +1,34 @@
package ru.spcex.clearing.session.stage.task.result;
import java.util.List;
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
public class DealsPrepareCompoundResult {
private List<ExecutionCommon> executionsTrdt;
private List<ExecutionCommon> executionsCurrency;
private List<ExecutionCommon> executionsFinal;
public List<ExecutionCommon> getExecutionsTrdt() {
return executionsTrdt;
}
public void setExecutionsTrdt(List<ExecutionCommon> executionsTrdt) {
this.executionsTrdt = executionsTrdt;
}
public List<ExecutionCommon> getExecutionsCurrency() {
return executionsCurrency;
}
public void setExecutionsCurrency(List<ExecutionCommon> executionsCurrency) {
this.executionsCurrency = executionsCurrency;
}
public List<ExecutionCommon> getExecutionsFinal() {
return executionsFinal;
}
public void setExecutionsFinal(List<ExecutionCommon> executionsFinal) {
this.executionsFinal = executionsFinal;
}
}

View file

@ -8,7 +8,7 @@ import ru.spcex.platform.enumeration.SdfTable;
public enum SdfGroup {
// Sdf01And57(SdfTable.SDF_01, SdfTable.SDF_57),
Sdf08And21(SdfTable.SDF_08, SdfTable.SDF_21),
// Sdf08And21(SdfTable.SDF_08, SdfTable.SDF_21),
//------ session groups ------ (4), (1 57), (13), (8 21)
//session_Triple(SdfTable.SDF_04, SdfTable.SDF_01, SdfTable.SDF_57),

View file

@ -118,9 +118,11 @@ public class StatementServiceV2 {
switch (table) {
case SDF_01 -> processSdf01(systemRequest.getRequestPayload());
case SDF_04 -> processSdf04(systemRequest.getRequestPayload());
case SDF_08 -> processSdf08(systemRequest.getRequestPayload());
case SDF_10 -> sdf10Executor.execute(systemRequest);
case SDF_13 -> processSdf13(systemRequest.getRequestPayload());
case SDF_20 -> sdf20Executor.execute(systemRequest);
case SDF_21 -> processSdf21(systemRequest.getRequestPayload());
case SDF_55 -> sdf55Executor.execute(systemRequest);
case SDF_57 -> processSdf57(systemRequest.getRequestPayload());
default -> log.error("unknown table {}", table);
@ -148,9 +150,9 @@ public class StatementServiceV2 {
log.debug("find full set of SDF requests: {}", fullGroup.stream()
.map(stReq -> stReq.getTable().getKey() + " generationId=" + stReq.getGroupId())
.collect(TextUtil.join));
if (sdfGroup.get() == SdfGroup.Sdf08And21) {
processSdf08And21(find(SdfTable.SDF_08, fullGroup), find(SdfTable.SDF_21, fullGroup));
}
// if (sdfGroup.get() == SdfGroup.Sdf08And21) {
// processSdf08And21(find(SdfTable.SDF_08, fullGroup), find(SdfTable.SDF_21, fullGroup));
// }
// else if (sdfGroup.get() == SdfGroup.Sdf01And57) {
// processSdf01Parent(find(SdfTable.SDF_01, fullGroup), find(SdfTable.SDF_57, fullGroup));
// }
@ -164,9 +166,9 @@ public class StatementServiceV2 {
// processSdf08And21(find(SdfTable.SDF_08, fullGroup), find(SdfTable.SDF_21, fullGroup));
// processSdf01And57(find(SdfTable.SDF_01, fullGroup), find(SdfTable.SDF_57, fullGroup));
//}
else {
throw new IllegalStateException("not implemented");
}
// else {
throw new IllegalStateException("not implemented");
// }
}
private static StatementRequest find(SdfTable table, Collection<StatementRequest> reqs) {
@ -177,27 +179,6 @@ public class StatementServiceV2 {
return first.get();
}
/**
* fromAccService передается когда пришел ответ от account-service
* в этом случае: по key находим пару в которой сохранен sdf57 запрос и частично выполненный sdf01
* вместо старого sdf01 запроса выполняем новый пришедший от account-service
*/
private void processSdf08And21(StatementRequest sdf08, StatementRequest sdf21) {
Result sdf08Res = processSdf08(sdf08);
removeFirstWithSameTableAndGroupId(sdf08);
if (sdf08Res.getAccountRequests().size() > 0) {
log.info("sdf08 execution wasn't complete, waiting for an answer from account-service");
return;
}
//затем sdf21
processSdf21(sdf21);
removeFirstWithSameTableAndGroupId(sdf21);
//fixme ревизия для бумаг reviser.doRevise(pair.getFirst().getGroupId());
SessionContinueEvent continueSessionBn = new SessionContinueEvent(SdfTable.SDF_08, SdfTable.SDF_21);
kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn);
log.info("pair sdf08/sdf21 processed successfully");
}
private void processSdf04(StatementRequest statementRequest) {
Imdg<SDf04> sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf04, SDf04.class);
Collection<? extends SpcexObjectBase> sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of(
@ -304,36 +285,45 @@ public class StatementServiceV2 {
}
private Result processSdf08(StatementRequest statementRequest) {
private void processSdf08(StatementRequest sdf08) {
Imdg<SDf08> sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf08, SDf08.class);
Collection<SDf08> sdfGroup;
if (statementRequest.getAccountCreationResults().size() == 0) {
if (sdf08.getAccountCreationResults().isEmpty()) {
sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of(
"generationId", statementRequest.getGroupId()));
"generationId", sdf08.getGroupId()));
} else {
sdfGroup = statementRequest.getAccountCreationResults()
sdfGroup = sdf08.getAccountCreationResults()
.stream()
.filter(part -> part.getErrorCode() == null)
.map(part -> sdfImdg.getSingleObjectByID(part.getSdfId()))
.collect(Collectors.toList());
}
Result res = sdf08Executor.execute(sdfGroup, statementRequest);
if (res.getAccountRequests().size() != 0) {
AccountSdf01Request createAccsReq = StatementService.createAccountsRequest(statementRequest.getGroupId(),
res.getAccountRequests(),
res.getChildGenerationId());
Result sdf08Res = sdf08Executor.execute(sdfGroup, sdf08);
if (!sdf08Res.getAccountRequests().isEmpty()) {
AccountSdf01Request createAccsReq = StatementService.createAccountsRequest(sdf08.getGroupId(),
sdf08Res.getAccountRequests(),
sdf08Res.getChildGenerationId());
kafkaSender.sendRequestToQueue(Consts.ACCOUNT_NEW_SDF08, createAccsReq);
} else if (sdf08Executor.isNeedToSendCommand()) {
sdf08Executor.sendCommand(kafkaSender, res);
sdf08Executor.sendCommand(kafkaSender, sdf08Res);
}
removeFirstWithSameTableAndGroupId(sdf08);
if (!sdf08Res.getAccountRequests().isEmpty()) {
log.info("sdf08 execution wasn't complete, waiting for an answer from account-service");
} else {
log.info("sdf08 execution was complete.");
}
return res;
}
private void processSdf21(StatementRequest statementRequest) {
private void processSdf21(StatementRequest sdf21) {
Imdg<SDf21> sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf21, SDf21.class);
Collection<SDf21> sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of(
"generationId", statementRequest.getGroupId()));
Result res = sdf21Executor.execute(sdfGroup, statementRequest);
"generationId", sdf21.getGroupId()));
Result res = sdf21Executor.execute(sdfGroup, sdf21);
removeFirstWithSameTableAndGroupId(sdf21);
SessionContinueEvent continueSessionBn = new SessionContinueEvent(SdfTable.SDF_08, SdfTable.SDF_21);
kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn);
log.info("sdf21 processed successfully");
}

View file

@ -0,0 +1,13 @@
package ru.spcex.clearing.util;
import java.util.Comparator;
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
public class ComparatorUtil {
public static final Comparator<ExecutionCommon> tradeTimeComparator
= Comparator.comparing(ExecutionCommon::getExchangeExecutionTime);
public static final Comparator<ExecutionCommon> execIdComparator
= Comparator.comparing(ExecutionCommon::getExchangeExecutionId);
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.util;
import java.util.Locale;
import ru.clearing.classes.statics.data.account.Account;
import ru.spcex.platform.enumeration.CurrencyCode;
public class LocaleUtil {
private static final Locale ru = new Locale("ru");
private static final Locale eng = new Locale("eng");
public static boolean isRus(Locale locale) {
return ru.equals(locale);
}
public static Locale locale(Account acc) {
if (CurrencyCode.isRubDefault(acc.getCurrency())) {
return ru;
} else {
return eng;
}
}
public static Locale locale(String... currencyCode) {
for (String s : currencyCode) {
if (!CurrencyCode.isRubDefault(s)) {
return eng;
}
}
return ru;
}
}

View file

@ -0,0 +1,3 @@
payment-instruction.purpose.withdrawal.tcr=Debt free cash withdrawal from TKR {0}.
payment-instruction.purpose.withdrawal=Debt free cash withdrawal.
sdf54.urgent=urgent

View file

@ -0,0 +1,3 @@
payment-instruction.purpose.withdrawal.tcr=Возврат средств, свободных от обязательств с ТКР {0}.
payment-instruction.purpose.withdrawal=Вывод средств.
sdf54.urgent=срочно

View file

@ -8,12 +8,12 @@
<name>clearing-validation</name>
<description>Clearing-module, dependency version of platform-utils</description>
<packaging>jar</packaging>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<properties>
@ -35,13 +35,13 @@
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>dictionary</artifactId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<scope>compile</scope>
</dependency>
<dependency>

View file

@ -1,5 +1,8 @@
package ru.spcex.clearing.validation.common;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
@ -10,10 +13,6 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ValidationException;
import ru.spcex.platform.utils.validation.IValidator;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
public class ValidationHelper {
private final static Logger log = LoggerFactory.getLogger(ValidationHelper.class);

View file

@ -5,7 +5,7 @@
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -7,12 +7,12 @@
<artifactId>db-scripts</artifactId>
<name>db-scripts</name>
<description>db-scripts for PostgreSQL</description>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-3.11.0.0</version>
<version>SPCEX-3.12.7</version>
</parent>
<build>

View file

@ -1,4 +1,4 @@
-- DB version: 3.11.0.83
-- DB version: 3.12.0.91
/* Dictionaries */
-- allowed - Справочник признаков допустимости использования объектов
@ -2054,7 +2054,7 @@ GRANT ALL PRIVILEGES ON TABLE TRADING_CLEARING_REGISTRY_LIST_HISTORY TO clearing
-- registry - Регистр активов, обязательств и требований УК
DROP TABLE IF EXISTS REGISTRY;
CREATE TABLE REGISTRY(COMPANY_ID bigint, TRADING_CODE varchar(255), CLEARING_CODE varchar(255), SHORT_NAME varchar(255), FULL_NAME varchar(255), ACCOUNT_ID bigint, ACCOUNT_TYPE varchar(4), ACCOUNT varchar(50), REGISTRY_DESIGNATION varchar(4), REGISTRY_INSTRUMENT_TYPE varchar(4), REGISTRY_CAPACITY varchar(4), REGISTRY_UNIT varchar(4), REGISTRY_CODE varchar(4), TRADING_CLEARING_REGISTRY_ID bigint, TRADING_CLEARING_REGISTRY varchar(50), REGISTRY_STATUS varchar(4), SECURITY_SYMBOL varchar(255), BALANCE numeric(72,18), OPEN_BALANCE numeric(72,18), CLOSE_BALANCE numeric(72,18), CREDIT numeric(72,18), DEBIT numeric(72,18), SETTLED_CREDIT numeric(72,18), SETTLED_DEBIT numeric(72,18), CHECK_BALANCE numeric(72,18), DIFF_BALANCE numeric(72,18), PLAN_BALANCE numeric(72,18), BALANCE_DIMENSION varchar(4), SETTLEMENT_DATE date, SETTLEMENT_CODE varchar(12), TRADING_DATE date, CLEARING_DATE date, REFUND_DATE date, VALUE_DATE date, PRICE numeric(72,18), CONTRACT varchar(255), COUNTER_PARTY_ID bigint, COMMENT varchar(255), PARENT_ID bigint, GROUP_ID bigint, SESSION_ID bigint, SESSION_TYPE varchar(4), PAYMENT_ID bigint, ID bigint PRIMARY KEY, CREATED_AT timestamp, UPDATED_AT timestamp, SECURITY_ID bigint);
CREATE TABLE REGISTRY(COMPANY_ID bigint, TRADING_CODE varchar(255), CLEARING_CODE varchar(255), SHORT_NAME varchar(255), FULL_NAME varchar(255), ACCOUNT_ID bigint, ACCOUNT_TYPE varchar(4), ACCOUNT varchar(50), REGISTRY_DESIGNATION varchar(4), REGISTRY_INSTRUMENT_TYPE varchar(4), REGISTRY_CAPACITY varchar(4), REGISTRY_UNIT varchar(4), REGISTRY_CODE varchar(4), TRADING_CLEARING_REGISTRY_ID bigint, TRADING_CLEARING_REGISTRY varchar(50), REGISTRY_STATUS varchar(4), SECURITY_SYMBOL varchar(255), BALANCE numeric(72,18), OPEN_BALANCE numeric(72,18), CLOSE_BALANCE numeric(72,18), CREDIT numeric(72,18), DEBIT numeric(72,18), SETTLED_CREDIT numeric(72,18), SETTLED_DEBIT numeric(72,18), CHECK_BALANCE numeric(72,18), DIFF_BALANCE numeric(72,18), PLAN_BALANCE numeric(72,18), BALANCE_DIMENSION varchar(4), SETTLEMENT_DATE date, SETTLEMENT_CODE varchar(12), TRADING_DATE date, CLEARING_DATE date, REFUND_DATE date, VALUE_DATE date, PRICE numeric(72,18), CONTRACT varchar(255), COUNTER_PARTY_ID bigint, COMMENT varchar(255), PARENT_ID bigint, GROUP_ID bigint, SESSION_ID bigint, SESSION_TYPE varchar(4), PAYMENT_ID bigint, ID bigint PRIMARY KEY, CREATED_AT timestamp, UPDATED_AT timestamp, SECURITY_ID bigint, SECTION varchar(4));
COMMENT ON TABLE REGISTRY IS 'Регистр активов, обязательств и требований УК';
COMMENT ON COLUMN REGISTRY.COMPANY_ID IS 'Идентификатор участника (linked to company)';
@ -2151,12 +2151,14 @@ COMMENT ON COLUMN REGISTRY.UPDATED_AT IS 'Дата и время изменен
COMMENT ON COLUMN REGISTRY.SECURITY_ID IS 'Идентификатор инструмента (linked to security)';
COMMENT ON COLUMN REGISTRY.SECTION IS 'Код секции (linked to section)';
GRANT ALL PRIVILEGES ON TABLE REGISTRY TO clearing;
-- History log of registry - Регистр активов, обязательств и требований УК
DROP TABLE IF EXISTS REGISTRY_HISTORY;
CREATE TABLE REGISTRY_HISTORY(REGISTRY_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), COMPANY_ID bigint, TRADING_CODE varchar(255), CLEARING_CODE varchar(255), SHORT_NAME varchar(255), FULL_NAME varchar(255), ACCOUNT_ID bigint, ACCOUNT_TYPE varchar(4), ACCOUNT varchar(50), REGISTRY_DESIGNATION varchar(4), REGISTRY_INSTRUMENT_TYPE varchar(4), REGISTRY_CAPACITY varchar(4), REGISTRY_UNIT varchar(4), REGISTRY_CODE varchar(4), TRADING_CLEARING_REGISTRY_ID bigint, TRADING_CLEARING_REGISTRY varchar(50), REGISTRY_STATUS varchar(4), SECURITY_SYMBOL varchar(255), BALANCE numeric(72,18), OPEN_BALANCE numeric(72,18), CLOSE_BALANCE numeric(72,18), CREDIT numeric(72,18), DEBIT numeric(72,18), SETTLED_CREDIT numeric(72,18), SETTLED_DEBIT numeric(72,18), CHECK_BALANCE numeric(72,18), DIFF_BALANCE numeric(72,18), PLAN_BALANCE numeric(72,18), BALANCE_DIMENSION varchar(4), SETTLEMENT_DATE date, SETTLEMENT_CODE varchar(12), TRADING_DATE date, CLEARING_DATE date, REFUND_DATE date, VALUE_DATE date, PRICE numeric(72,18), CONTRACT varchar(255), COUNTER_PARTY_ID bigint, COMMENT varchar(255), PARENT_ID bigint, GROUP_ID bigint, SESSION_ID bigint, SESSION_TYPE varchar(4), PAYMENT_ID bigint, ID bigint PRIMARY KEY, CREATED_AT timestamp, UPDATED_AT timestamp, SECURITY_ID bigint);
CREATE TABLE REGISTRY_HISTORY(REGISTRY_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), COMPANY_ID bigint, TRADING_CODE varchar(255), CLEARING_CODE varchar(255), SHORT_NAME varchar(255), FULL_NAME varchar(255), ACCOUNT_ID bigint, ACCOUNT_TYPE varchar(4), ACCOUNT varchar(50), REGISTRY_DESIGNATION varchar(4), REGISTRY_INSTRUMENT_TYPE varchar(4), REGISTRY_CAPACITY varchar(4), REGISTRY_UNIT varchar(4), REGISTRY_CODE varchar(4), TRADING_CLEARING_REGISTRY_ID bigint, TRADING_CLEARING_REGISTRY varchar(50), REGISTRY_STATUS varchar(4), SECURITY_SYMBOL varchar(255), BALANCE numeric(72,18), OPEN_BALANCE numeric(72,18), CLOSE_BALANCE numeric(72,18), CREDIT numeric(72,18), DEBIT numeric(72,18), SETTLED_CREDIT numeric(72,18), SETTLED_DEBIT numeric(72,18), CHECK_BALANCE numeric(72,18), DIFF_BALANCE numeric(72,18), PLAN_BALANCE numeric(72,18), BALANCE_DIMENSION varchar(4), SETTLEMENT_DATE date, SETTLEMENT_CODE varchar(12), TRADING_DATE date, CLEARING_DATE date, REFUND_DATE date, VALUE_DATE date, PRICE numeric(72,18), CONTRACT varchar(255), COUNTER_PARTY_ID bigint, COMMENT varchar(255), PARENT_ID bigint, GROUP_ID bigint, SESSION_ID bigint, SESSION_TYPE varchar(4), PAYMENT_ID bigint, ID bigint PRIMARY KEY, CREATED_AT timestamp, UPDATED_AT timestamp, SECURITY_ID bigint, SECTION varchar(4));
COMMENT ON TABLE REGISTRY_HISTORY IS 'История изменений таблицы registry';
COMMENT ON COLUMN REGISTRY_HISTORY.REGISTRY_ID IS 'Идентификатор записи в таблице REGISTRY';
COMMENT ON COLUMN REGISTRY_HISTORY.EVENT_TIME IS 'Дата и время изменения';
@ -2257,6 +2259,8 @@ COMMENT ON COLUMN REGISTRY_HISTORY.UPDATED_AT IS 'Дата и время изм
COMMENT ON COLUMN REGISTRY_HISTORY.SECURITY_ID IS 'Идентификатор инструмента (linked to security)';
COMMENT ON COLUMN REGISTRY_HISTORY.SECTION IS 'Код секции (linked to section)';
GRANT ALL PRIVILEGES ON TABLE REGISTRY_HISTORY TO clearing;
-- account - Счета
@ -2373,10 +2377,10 @@ COMMENT ON COLUMN RELATION_HISTORY.UPDATED_AT IS 'Дата-время измен
GRANT ALL PRIVILEGES ON TABLE RELATION_HISTORY TO clearing;
-- bankAccount - Счета вывода средств из ПРЦ
-- bankAccount - Счета вывода средств
DROP TABLE IF EXISTS BANK_ACCOUNT;
CREATE TABLE BANK_ACCOUNT(ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY);
COMMENT ON TABLE BANK_ACCOUNT IS 'Счета вывода средств из ПРЦ';
CREATE TABLE BANK_ACCOUNT(ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255));
COMMENT ON TABLE BANK_ACCOUNT IS 'Счета вывода средств';
COMMENT ON COLUMN BANK_ACCOUNT.ACCOUNT_ID IS 'Идентификатор счета (linked to account)';
@ -2408,12 +2412,14 @@ COMMENT ON COLUMN BANK_ACCOUNT.COMPANY_ID IS 'Идентификатор ком
COMMENT ON COLUMN BANK_ACCOUNT.ID IS 'Идентификатор записи';
COMMENT ON COLUMN BANK_ACCOUNT.INTERMEDIARY_SWIFT_CODE IS 'Код SWIFT посредника';
GRANT ALL PRIVILEGES ON TABLE BANK_ACCOUNT TO clearing;
-- History log of bankAccount - Счета вывода средств из ПРЦ
-- History log of bankAccount - Счета вывода средств
DROP TABLE IF EXISTS BANK_ACCOUNT_HISTORY;
CREATE TABLE BANK_ACCOUNT_HISTORY(BANK_ACCOUNT_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY);
CREATE TABLE BANK_ACCOUNT_HISTORY(BANK_ACCOUNT_ID BIGINT NOT NULL, EVENT_TIME timestamp, EVENT_USER_ID BIGINT, EVENT_TYPE VARCHAR(4), ACCOUNT_ID bigint, BANK_IDENTIFICATION_CODE varchar(255), BANK_NAME varchar(255), CORRESPONDENT_ACCOUNT varchar(255), CORRESPONDENT_ACCOUNT_NAME varchar(255), CURRENCY varchar(4), DESTINATION varchar(255), IBAN varchar(255), INTERNATIONAL_TRANSFER_SIGN varchar(4), SWIFT_CODE varchar(255), TAXPAYER_IDENTIFICATION_NUMBER varchar(255), TAX_REGISTRATION_REASON_CODE varchar(255), ACCOUNT varchar(50), COMPANY_ID bigint, ID bigint PRIMARY KEY, INTERMEDIARY_SWIFT_CODE varchar(255));
COMMENT ON TABLE BANK_ACCOUNT_HISTORY IS 'История изменений таблицы bankAccount';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.BANK_ACCOUNT_ID IS 'Идентификатор записи в таблице BANK_ACCOUNT';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.EVENT_TIME IS 'Дата и время изменения';
@ -2450,6 +2456,8 @@ COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.COMPANY_ID IS 'Идентификатор
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.ID IS 'Идентификатор записи';
COMMENT ON COLUMN BANK_ACCOUNT_HISTORY.INTERMEDIARY_SWIFT_CODE IS 'Код SWIFT посредника';
GRANT ALL PRIVILEGES ON TABLE BANK_ACCOUNT_HISTORY TO clearing;
-- informationAccount - Регистр КС
@ -4100,7 +4108,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF05 TO clearing;
-- sDf06 - ДФ-06 Запрос на зачисление/списание денежных средств
DROP TABLE IF EXISTS S_DF06;
CREATE TABLE S_DF06(ID bigint PRIMARY KEY, ACCOUNT varchar(20), SUM numeric(72,18), MARKET varchar(1), TYPE varchar(255), DEAL varchar(10), CLIENT_N varchar(255), INN varchar(255), BIC varchar(255), SPEC varchar(255), NUMBER numeric(72,18), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, _DOC__NUM varchar(3), _DOC__DATE varchar(8), PAY_VAL varchar(12));
CREATE TABLE S_DF06(ID bigint PRIMARY KEY, ACCOUNT varchar(20), SUM numeric(72,18), MARKET varchar(1), TYPE varchar(255), DEAL varchar(10), CLIENT_N varchar(255), INN varchar(255), BIC varchar(255), SPEC varchar(255), NUMBER numeric(72,18), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, DOC_NUM varchar(3), DOC_DATE varchar(8), PAY_VAL varchar(12));
COMMENT ON TABLE S_DF06 IS 'ДФ-06 Запрос на зачисление/списание денежных средств';
COMMENT ON COLUMN S_DF06.ID IS 'Идентификатор записи';
@ -4131,9 +4139,9 @@ COMMENT ON COLUMN S_DF06.GENERATION_TIME IS 'Дата и время обрабо
COMMENT ON COLUMN S_DF06.GENERATION_ID IS 'Идентификатор взаимодействия';
COMMENT ON COLUMN S_DF06._DOC__NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF06.DOC_NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF06._DOC__DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF06.DOC_DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF06.PAY_VAL IS 'Валюта документа';
@ -4141,7 +4149,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF06 TO clearing;
-- sDf07 - ДФ-07 Ответ на запрос по зачислению/списанию денежных средств
DROP TABLE IF EXISTS S_DF07;
CREATE TABLE S_DF07(ID bigint PRIMARY KEY, ACCOUNT varchar(20), SUM numeric(72,18), MARKET varchar(1), TYPE varchar(255), DEAL varchar(10), CLIENT_N varchar(255), INN varchar(255), BIC varchar(255), SPEC varchar(255), NUMBER numeric(72,18), RESULT numeric(72,18), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, IN_S_DF_ID bigint, _DOC__NUM varchar(3), _DOC__DATE varchar(8), PAY_VAL varchar(12));
CREATE TABLE S_DF07(ID bigint PRIMARY KEY, ACCOUNT varchar(20), SUM numeric(72,18), MARKET varchar(1), TYPE varchar(255), DEAL varchar(10), CLIENT_N varchar(255), INN varchar(255), BIC varchar(255), SPEC varchar(255), NUMBER numeric(72,18), RESULT numeric(72,18), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, IN_S_DF_ID bigint, DOC_NUM varchar(3), DOC_DATE varchar(8), PAY_VAL varchar(12));
COMMENT ON TABLE S_DF07 IS 'ДФ-07 Ответ на запрос по зачислению/списанию денежных средств';
COMMENT ON COLUMN S_DF07.ID IS 'Идентификатор записи';
@ -4176,9 +4184,9 @@ COMMENT ON COLUMN S_DF07.GENERATION_ID IS 'Идентификатор взаим
COMMENT ON COLUMN S_DF07.IN_S_DF_ID IS 'Идентификатор соответствующей записи из таблицы-источника';
COMMENT ON COLUMN S_DF07._DOC__NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF07.DOC_NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF07._DOC__DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF07.DOC_DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF07.PAY_VAL IS 'Валюта документа';
@ -4495,7 +4503,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF52 TO clearing;
-- sDf53 - ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)
DROP TABLE IF EXISTS S_DF53;
CREATE TABLE S_DF53(ID bigint PRIMARY KEY, ACC_NAME varchar(30), ACCOUNT varchar(25), DEAL varchar(4), DATE varchar(8), STATUS bigint, RESULT varchar(255), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, IN_S_DF_ID bigint, ACC_TYPE varchar(3));
CREATE TABLE S_DF53(ID bigint PRIMARY KEY, ACC_NAME varchar(30), ACCOUNT varchar(25), DEAL varchar(4), DATE varchar(8), STATUS bigint, RESULT varchar(255), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, IN_S_DF_ID bigint, ACC_TYPE bigint);
COMMENT ON TABLE S_DF53 IS 'ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)';
COMMENT ON COLUMN S_DF53.ID IS 'Идентификатор записи';
@ -4526,7 +4534,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF53 TO clearing;
-- sDf54 - ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414
DROP TABLE IF EXISTS S_DF54;
CREATE TABLE S_DF54(ID bigint PRIMARY KEY, SEG_TYPE varchar(1), DOC_TYPE varchar(4), DOCNM_REF varchar(16), DOCNMPREV varchar(16), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(12), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), OP_ORDER varchar(1), PAY_DATE varchar(8), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR_1 varchar(35), SPECIF_1 varchar(255), SEND_TYPE varchar(10), DOC_RESULT varchar(2), GENERATION_TIME timestamp, GENERATION_ID bigint, _DOC__NUM varchar(3), _DOC__DATE varchar(8), _VALUE_DATE varchar(8), _SWIFT_BEN varchar(11), _SWIFT_INT varchar(11));
CREATE TABLE S_DF54(ID bigint PRIMARY KEY, SEG_TYPE varchar(1), DOC_TYPE varchar(4), DOCNM_REF varchar(16), DOCNMPREV varchar(16), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(12), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), OP_ORDER varchar(1), PAY_DATE varchar(8), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR_1 varchar(35), SPECIF_1 varchar(255), SEND_TYPE varchar(10), DOC_RESULT varchar(2), GENERATION_TIME timestamp, GENERATION_ID bigint, DOC_NUM varchar(3), DOC_DATE varchar(8), VALUE_DATE varchar(8), SWIFT_BEN varchar(11), SWIFT_INT varchar(11));
COMMENT ON TABLE S_DF54 IS 'ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414';
COMMENT ON COLUMN S_DF54.ID IS 'Идентификатор записи';
@ -4615,21 +4623,21 @@ COMMENT ON COLUMN S_DF54.GENERATION_TIME IS 'Дата и время создан
COMMENT ON COLUMN S_DF54.GENERATION_ID IS 'Идентификатор взаимодействия';
COMMENT ON COLUMN S_DF54._DOC__NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF54.DOC_NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF54._DOC__DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF54.DOC_DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF54._VALUE_DATE IS 'Дата валютирования';
COMMENT ON COLUMN S_DF54.VALUE_DATE IS 'Дата валютирования';
COMMENT ON COLUMN S_DF54._SWIFT_BEN IS 'Свифт банка бенефициара';
COMMENT ON COLUMN S_DF54.SWIFT_BEN IS 'Свифт банка бенефициара';
COMMENT ON COLUMN S_DF54._SWIFT_INT IS 'Свифт банка посредника';
COMMENT ON COLUMN S_DF54.SWIFT_INT IS 'Свифт банка посредника';
GRANT ALL PRIVILEGES ON TABLE S_DF54 TO clearing;
-- sDf55 - ДФ-55 Квитанция об обработке ДФ-54
DROP TABLE IF EXISTS S_DF55;
CREATE TABLE S_DF55(ID bigint PRIMARY KEY, SEG_TYPE varchar(1), DOC_TYPE varchar(4), DOCNM_REF varchar(16), DOCNMPREV varchar(16), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(12), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), OP_ORDER varchar(1), PAY_DATE varchar(8), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR_1 varchar(35), SPECIF_1 varchar(255), SEND_TYPE varchar(10), DOC_RESULT varchar(2), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, _DOC__NUM varchar(3), _DOC__DATE varchar(8), _VALUE_DATE varchar(8), _SWIFT_BEN varchar(11), _SWIFT_INT varchar(11));
CREATE TABLE S_DF55(ID bigint PRIMARY KEY, SEG_TYPE varchar(1), DOC_TYPE varchar(4), DOCNM_REF varchar(16), DOCNMPREV varchar(16), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(12), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), OP_ORDER varchar(1), PAY_DATE varchar(8), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR_1 varchar(35), SPECIF_1 varchar(255), SEND_TYPE varchar(10), DOC_RESULT varchar(2), FILE_NAME varchar(255), GENERATION_TIME timestamp, GENERATION_ID bigint, DOC_NUM varchar(3), DOC_DATE varchar(8), VALUE_DATE varchar(8), SWIFT_BEN varchar(11), SWIFT_INT varchar(11));
COMMENT ON TABLE S_DF55 IS 'ДФ-55 Квитанция об обработке ДФ-54';
COMMENT ON COLUMN S_DF55.ID IS 'Идентификатор записи';
@ -4720,15 +4728,15 @@ COMMENT ON COLUMN S_DF55.GENERATION_TIME IS 'Дата и время обрабо
COMMENT ON COLUMN S_DF55.GENERATION_ID IS 'Идентификатор взаимодействия';
COMMENT ON COLUMN S_DF55._DOC__NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF55.DOC_NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF55._DOC__DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF55.DOC_DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF55._VALUE_DATE IS 'Дата валютирования';
COMMENT ON COLUMN S_DF55.VALUE_DATE IS 'Дата валютирования';
COMMENT ON COLUMN S_DF55._SWIFT_BEN IS 'Свифт банка бенефициара';
COMMENT ON COLUMN S_DF55.SWIFT_BEN IS 'Свифт банка бенефициара';
COMMENT ON COLUMN S_DF55._SWIFT_INT IS 'Свифт банка посредника';
COMMENT ON COLUMN S_DF55.SWIFT_INT IS 'Свифт банка посредника';
GRANT ALL PRIVILEGES ON TABLE S_DF55 TO clearing;
@ -4757,7 +4765,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF56 TO clearing;
-- sDf57 - ДФ-57 Список транзакций о списании/зачислении за период по всем счетам (ТБС и КС)
DROP TABLE IF EXISTS S_DF57;
CREATE TABLE S_DF57(GENERATION_TIME timestamp, ID bigint PRIMARY KEY, DBF_ID bigint, DEAL_DEB varchar(4), DEAL_CRED varchar(4), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(35), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), PAY_DATE varchar(8), EXT_DATE varchar(255), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR varchar(35), SPECIF varchar(255), FILE_NAME varchar(255), GENERATION_ID bigint, _DOC__NUM varchar(3), _DOC__DATE varchar(8), DT_IN varchar(22), KT_IN varchar(22), DT_OUT varchar(22), KT_OUT varchar(22));
CREATE TABLE S_DF57(GENERATION_TIME timestamp, ID bigint PRIMARY KEY, DBF_ID bigint, DEAL_DEB varchar(4), DEAL_CRED varchar(4), SBANKCODE varchar(12), C_ACC_DEB varchar(35), SBANKNAM1 varchar(35), SBANKNAM2 varchar(35), SBANKNAM3 varchar(35), SBANKNAM4 varchar(35), SBANKNAM5 varchar(35), RBANKCODE varchar(35), C_ACC_CRED varchar(35), RBANKNAM1 varchar(35), RBANKNAM2 varchar(35), RBANKNAM3 varchar(35), RBANKNAM4 varchar(35), RBANKNAM5 varchar(35), OP_TYPE varchar(2), PAY_DATE varchar(8), EXT_DATE varchar(255), PAY_VAL varchar(12), SUM_DEB varchar(22), SCLIENTN1 varchar(35), SCLIENTN2 varchar(35), SCLIENTN3 varchar(35), SCLIENTN4 varchar(35), INN_DEB varchar(12), KPP_DEB varchar(9), ACC_DEB varchar(35), RCLIENTN1 varchar(35), RCLIENTN2 varchar(35), RCLIENTN3 varchar(35), RCLIENTN4 varchar(35), INN_CRED varchar(12), KPP_CRED varchar(9), ACC_KR varchar(35), SPECIF varchar(255), FILE_NAME varchar(255), GENERATION_ID bigint, DOC_NUM varchar(3), DOC_DATE varchar(8), DT_IN varchar(22), KT_IN varchar(22), DT_OUT varchar(22), KT_OUT varchar(22));
COMMENT ON TABLE S_DF57 IS 'ДФ-57 Список транзакций о списании/зачислении за период по всем счетам (ТБС и КС)';
COMMENT ON COLUMN S_DF57.GENERATION_TIME IS 'Дата и время создания записи';
@ -4842,9 +4850,9 @@ COMMENT ON COLUMN S_DF57.FILE_NAME IS 'Наименование входящег
COMMENT ON COLUMN S_DF57.GENERATION_ID IS 'Идентификатор взаимодействия';
COMMENT ON COLUMN S_DF57._DOC__NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF57.DOC_NUM IS 'Номер выгружаемого документа';
COMMENT ON COLUMN S_DF57._DOC__DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF57.DOC_DATE IS 'Дата выгружаемого документа';
COMMENT ON COLUMN S_DF57.DT_IN IS 'Входящий дебетовый остаток';
@ -5098,4 +5106,4 @@ GRANT ALL PRIVILEGES ON TABLE S_CROSS_RATE TO clearing;
-- Data types
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.11') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.12') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION

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