Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
bebb114bea
17 changed files with 972 additions and 144 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.spcex.clearing.account.config.validation;
|
package ru.spcex.clearing.account.config.validation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -13,8 +14,10 @@ import ru.clearing.classes.statics.data.account.Account;
|
||||||
import ru.clearing.classes.statics.data.account.ClientCode;
|
import ru.clearing.classes.statics.data.account.ClientCode;
|
||||||
import ru.clearing.classes.statics.data.company.Company;
|
import ru.clearing.classes.statics.data.company.Company;
|
||||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||||
|
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||||
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
|
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
|
||||||
import ru.spcex.clearing.account.errors.AccountError;
|
import ru.spcex.clearing.account.errors.AccountError;
|
||||||
|
import ru.spcex.clearing.account.validation.ClientCodeStoreObjects;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
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.ClientCodeNewRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest;
|
||||||
|
|
@ -27,6 +30,7 @@ import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
import ru.spcex.platform.enumeration.CompanySymbol;
|
import ru.spcex.platform.enumeration.CompanySymbol;
|
||||||
import ru.spcex.platform.enumeration.CurrencyCode;
|
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.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||||
|
|
@ -50,45 +54,149 @@ public class ClientCodeValidationConfig {
|
||||||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
|
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
|
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
|
||||||
return new ValidatorImpl<>(context,
|
return new ValidatorImpl<>(context,
|
||||||
FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, AccountError.RequiredFieldEmpty),
|
FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, AccountError.RequiredFieldEmpty),
|
||||||
IdPresentRule.instance("companyId",
|
IdPresentRule.instance("companyId",
|
||||||
ClientCodeNewRequest::getCompanyId,
|
ClientCodeNewRequest::getCompanyId,
|
||||||
IMDGDistributedNames.Map_Company,
|
IMDGDistributedNames.Map_Company,
|
||||||
Company.class,
|
Company.class,
|
||||||
AccountError.RequiredFieldEmpty,
|
AccountError.RequiredFieldEmpty,
|
||||||
AccountError.CompanyNotFound),
|
AccountError.CompanyNotFound),
|
||||||
|
|
||||||
IdPresentRule.instance("moneyAccountId",
|
IdPresentRule.instance("moneyAccountId",
|
||||||
ClientCodeNewRequest::getMoneyAccountId,
|
ClientCodeNewRequest::getMoneyAccountId,
|
||||||
IMDGDistributedNames.Map_Account,
|
IMDGDistributedNames.Map_Account,
|
||||||
Account.class,
|
Account.class,
|
||||||
AccountError.RequiredFieldEmpty,
|
AccountError.RequiredFieldEmpty,
|
||||||
AccountError.AccountNotFound,
|
AccountError.AccountNotFound,
|
||||||
false,
|
false,
|
||||||
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
|
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
|
||||||
? null : AccountError.AccountNotFound
|
? null : AccountError.AccountNotFound
|
||||||
),
|
),
|
||||||
IdPresentRule.instance("depoAccountId",
|
IdPresentRule.instance("depoAccountId",
|
||||||
ClientCodeNewRequest::getDepoAccountId,
|
ClientCodeNewRequest::getDepoAccountId,
|
||||||
IMDGDistributedNames.Map_Account,
|
IMDGDistributedNames.Map_Account,
|
||||||
Account.class,
|
Account.class,
|
||||||
AccountError.RequiredFieldEmpty,
|
AccountError.RequiredFieldEmpty,
|
||||||
AccountError.AccountNotFound,
|
AccountError.AccountNotFound,
|
||||||
false,
|
false,
|
||||||
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
|
acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId())
|
||||||
? null : AccountError.AccountNotFound
|
? null : AccountError.AccountNotFound
|
||||||
),
|
),
|
||||||
new ExistAllCurrencyAccountId<>("currencyAccountList",
|
new ExistAllCurrencyAccountId<>("currencyAccountList",
|
||||||
ClientCodeNewRequest::getCurrencyAccountList
|
ClientCodeNewRequest::getCurrencyAccountList
|
||||||
),
|
),
|
||||||
|
|
||||||
DictionaryPresentRule.instance("stauts",
|
DictionaryPresentRule.instance("stauts",
|
||||||
ClientCodeNewRequest::getStatus,
|
ClientCodeNewRequest::getStatus,
|
||||||
IMDGDistributedNames.Map_ServiceStatusDictionary,
|
IMDGDistributedNames.Map_ServiceStatusDictionary,
|
||||||
ServiceStatusDictionary.class,
|
ServiceStatusDictionary.class,
|
||||||
AccountError.RequiredFieldEmpty,
|
AccountError.RequiredFieldEmpty,
|
||||||
AccountError.DictionaryNotFound,
|
AccountError.DictionaryNotFound,
|
||||||
false)
|
false)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("clientCodeUpdateRequestValidator")
|
||||||
|
public Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
|
return clientCodeUpdateRequest -> {
|
||||||
|
ImdgValidationContext<ClientCodeUpdateRequest> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(clientCodeUpdateRequest);
|
||||||
|
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_ClientCode);
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_Company);
|
||||||
|
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
|
||||||
|
),
|
||||||
|
|
||||||
|
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,
|
||||||
|
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
|
||||||
|
),
|
||||||
|
new ExistAllCurrencyAccountId<>("currencyAccountList",
|
||||||
|
ClientCodeUpdateRequest::getCurrencyAccountList
|
||||||
|
),
|
||||||
|
|
||||||
|
DictionaryPresentRule.instance("stauts",
|
||||||
|
ClientCodeUpdateRequest::getStatus,
|
||||||
|
IMDGDistributedNames.Map_ServiceStatusDictionary,
|
||||||
|
ServiceStatusDictionary.class,
|
||||||
|
AccountError.RequiredFieldEmpty,
|
||||||
|
AccountError.DictionaryNotFound,
|
||||||
|
false)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("clientCodeDeleteRequestValidator")
|
||||||
|
public Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
|
return companyDeleteRequest -> {
|
||||||
|
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(companyDeleteRequest);
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("tkrAccountsGatewayValidator")
|
||||||
|
public Function<TkrAccount, IValidator> tkrAccountsGatewayValidator(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_CompanySymbols);
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_Account);
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
|
||||||
|
return new ValidatorImpl<>(context,
|
||||||
|
new ExistCompanyByUuid<>("companySymbolValue",
|
||||||
|
TkrAccount::getCompanyId),
|
||||||
|
new ExistAccountByValue<>("account",
|
||||||
|
TkrAccount::getMoneyAccounts),
|
||||||
|
new ExistDepoAccountByValue<>("depo_account",
|
||||||
|
TkrAccount::getDepoAccount),
|
||||||
|
new ExistTcrByCode<>("tcr_code",
|
||||||
|
TkrAccount::getTkrCode)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +218,7 @@ public class ClientCodeValidationConfig {
|
||||||
return empty(); // необязательное поле
|
return empty(); // необязательное поле
|
||||||
}
|
}
|
||||||
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
for (Long id:ids) {
|
for (Long id : ids) {
|
||||||
if (id == null) { // null значения в массиве не ожидаются
|
if (id == null) { // null значения в массиве не ожидаются
|
||||||
return of(AccountError.RequiredFieldEmpty, fieldName);
|
return of(AccountError.RequiredFieldEmpty, fieldName);
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +236,43 @@ public class ClientCodeValidationConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ExistTcrByCode<R> implements IValidationRule<ImdgValidationContext<R>> {
|
||||||
|
String fieldName;
|
||||||
|
Function<R, String> codeGetter;
|
||||||
|
|
||||||
|
public ExistTcrByCode(String fieldName, Function<R, String> codeGetter) {
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
this.codeGetter = codeGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
|
||||||
|
R validatedObject = context.getValidatedObject();
|
||||||
|
String tcrCode = codeGetter.apply(validatedObject);
|
||||||
|
if (!StringUtils.hasText(tcrCode)) {
|
||||||
|
return of(AccountError.RequiredFieldEmpty, fieldName);
|
||||||
|
}
|
||||||
|
Imdg<TradingClearingRegistry> imdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry,
|
||||||
|
TradingClearingRegistry.class);
|
||||||
|
|
||||||
|
TradingClearingRegistry tcr = imdg.getFirstObjectByFieldValues(
|
||||||
|
Map.of(
|
||||||
|
"code", tcrCode,
|
||||||
|
"status", Status.Active.getKey()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (tcr != null) {
|
||||||
|
return of(AccountError.TCR_ALREADY_EXIST_GTW, fieldName);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String ruleName() {
|
||||||
|
return getClass().getSimpleName() + "{" + fieldName + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ExistCompanyByUuid<R> implements IValidationRule<ImdgValidationContext<R>> {
|
public static class ExistCompanyByUuid<R> implements IValidationRule<ImdgValidationContext<R>> {
|
||||||
String fieldName;
|
String fieldName;
|
||||||
Function<R, String> symbolCodeGetter;
|
Function<R, String> symbolCodeGetter;
|
||||||
|
|
@ -151,9 +296,17 @@ public class ClientCodeValidationConfig {
|
||||||
"companySymbolValue", symbolCodeValue
|
"companySymbolValue", symbolCodeValue
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (companySymbols == null) { // null значения в массиве не ожидаются
|
if (companySymbols == null) {
|
||||||
return of(AccountError.COMPANY_NOT_FOUND_GTW, fieldName);
|
return of(AccountError.COMPANY_NOT_FOUND_GTW, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
|
||||||
|
Company company = companyImdg.getSingleObjectByID(companySymbols.getCompanyId());
|
||||||
|
if (company == null) {
|
||||||
|
return of(AccountError.COMPANY_NOT_FOUND_GTW, fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.storeObject(ClientCodeStoreObjects.COMPANY, company);
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +332,12 @@ public class ClientCodeValidationConfig {
|
||||||
if (accountList == null || accountList.isEmpty()) {
|
if (accountList == null || accountList.isEmpty()) {
|
||||||
return of(AccountError.RequiredFieldEmpty, fieldName);
|
return of(AccountError.RequiredFieldEmpty, fieldName);
|
||||||
}
|
}
|
||||||
|
List<String> currencies = accountList.stream().map(MoneyAccountMsgRequest::getCurrCode).toList();
|
||||||
|
if (!currencies.contains(CurrencyCode.RUB.getKey())) {
|
||||||
|
return of(AccountError.RequiredFieldEmpty, fieldName);
|
||||||
|
}
|
||||||
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
Map<String, Account> accountByCurrency = new HashMap<>();
|
||||||
for (MoneyAccountMsgRequest moneyAccountMsg : accountList) {
|
for (MoneyAccountMsgRequest moneyAccountMsg : accountList) {
|
||||||
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
|
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
|
||||||
ImdgPredicate currencyPredicate;
|
ImdgPredicate currencyPredicate;
|
||||||
|
|
@ -198,7 +356,9 @@ public class ClientCodeValidationConfig {
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
return of(AccountError.ACCOUNT_NOT_FOUND_GTW, moneyAccountMsg.getAccount(), fieldName);
|
return of(AccountError.ACCOUNT_NOT_FOUND_GTW, moneyAccountMsg.getAccount(), fieldName);
|
||||||
}
|
}
|
||||||
|
accountByCurrency.put(account.getCurrency(), account);
|
||||||
}
|
}
|
||||||
|
context.storeObject(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS, accountByCurrency);
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,103 +368,40 @@ public class ClientCodeValidationConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("clientCodeUpdateRequestValidator")
|
public static class ExistDepoAccountByValue<R> implements IValidationRule<ImdgValidationContext<R>> {
|
||||||
public Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
String fieldName;
|
||||||
return clientCodeUpdateRequest -> {
|
Function<R, String> depoAccountGetter;
|
||||||
ImdgValidationContext<ClientCodeUpdateRequest> context = new ImdgValidationContext<>();
|
|
||||||
context.setValidatedObject(clientCodeUpdateRequest);
|
|
||||||
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
|
||||||
addImdg.accept(IMDGDistributedNames.Map_ClientCode);
|
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Company);
|
|
||||||
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
|
|
||||||
),
|
|
||||||
|
|
||||||
FieldRequiredRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, AccountError.RequiredFieldEmpty),
|
public ExistDepoAccountByValue(String fieldName, Function<R, String> accountsListValueGetter) {
|
||||||
IdPresentRule.instance("companyId",
|
this.fieldName = fieldName;
|
||||||
ClientCodeUpdateRequest::getCompanyId,
|
this.depoAccountGetter = depoAccountGetter;
|
||||||
IMDGDistributedNames.Map_Company,
|
}
|
||||||
Company.class,
|
|
||||||
AccountError.RequiredFieldEmpty,
|
|
||||||
AccountError.CompanyNotFound),
|
|
||||||
|
|
||||||
IdPresentRule.instance("moneyAccountId",
|
@Override
|
||||||
ClientCodeUpdateRequest::getMoneyAccountId,
|
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
|
||||||
IMDGDistributedNames.Map_Account,
|
R validatedObject = context.getValidatedObject();
|
||||||
Account.class,
|
String depoAccountVal = depoAccountGetter.apply(validatedObject);
|
||||||
AccountError.RequiredFieldEmpty,
|
if (!StringUtils.hasText(depoAccountVal)) {
|
||||||
AccountError.AccountNotFound,
|
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT,Optional.empty());
|
||||||
true,
|
return empty();
|
||||||
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",
|
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
ClientCodeUpdateRequest::getStatus,
|
Account depoAccount = imdg.getFirstObjectByFieldValues(
|
||||||
IMDGDistributedNames.Map_ServiceStatusDictionary,
|
Map.of("account", depoAccountVal)
|
||||||
ServiceStatusDictionary.class,
|
|
||||||
AccountError.RequiredFieldEmpty,
|
|
||||||
AccountError.DictionaryNotFound,
|
|
||||||
false)
|
|
||||||
);
|
);
|
||||||
};
|
if (depoAccount == null) {
|
||||||
}
|
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT,Optional.empty());
|
||||||
|
return of(AccountError.DEPO_ACCOUNT_NOT_FOUND_GTW, fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean("clientCodeDeleteRequestValidator")
|
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT, depoAccount);
|
||||||
public Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
return Optional.empty();
|
||||||
return companyDeleteRequest -> {
|
}
|
||||||
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
|
|
||||||
context.setValidatedObject(companyDeleteRequest);
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean("tkrAccountsGatewayValidator")
|
@Override
|
||||||
public Function<TkrAccount, IValidator> tkrAccountsGatewayValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
public String ruleName() {
|
||||||
return tkrGatewayRequest -> {
|
return getClass().getSimpleName() + "{" + fieldName + "}";
|
||||||
ImdgValidationContext<TkrAccount> context = new ImdgValidationContext<>();
|
}
|
||||||
context.setValidatedObject(tkrGatewayRequest);
|
|
||||||
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
|
||||||
addImdg.accept(IMDGDistributedNames.Map_CompanySymbols);
|
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Account);
|
|
||||||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
|
|
||||||
return new ValidatorImpl<>(context,
|
|
||||||
new ExistCompanyByUuid<>("companySymbolValue",
|
|
||||||
TkrAccount::getCompanyId),
|
|
||||||
new ExistAccountByValue<>("account",
|
|
||||||
TkrAccount::getMoneyAccounts)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ public enum AccountError implements IErrorEnumId {
|
||||||
TCR_NOT_FOUND_GTW(5028L),
|
TCR_NOT_FOUND_GTW(5028L),
|
||||||
ACCOUNT_NOT_FOUND_GTW(5029L),
|
ACCOUNT_NOT_FOUND_GTW(5029L),
|
||||||
COMPANY_NOT_FOUND_GTW(5030L),
|
COMPANY_NOT_FOUND_GTW(5030L),
|
||||||
|
TCR_ALREADY_EXIST_GTW(5031L),
|
||||||
|
DEPO_ACCOUNT_NOT_FOUND_GTW(5032L),
|
||||||
TradingClearingRegistryNotFound(3022L),
|
TradingClearingRegistryNotFound(3022L),
|
||||||
CurrencyNotFound(1016L),
|
CurrencyNotFound(1016L),
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -134,9 +134,10 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
|
||||||
callback(ClientCodeNewRequest.class)
|
callback(ClientCodeNewRequest.class)
|
||||||
.setFunction(this::clientCodeNew)
|
.setFunction(this::clientCodeNew)
|
||||||
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
|
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put);
|
||||||
callback(TkrAccountsGatewayRequest.class)
|
//note переехало в ClientCodeMessageListener[новая версия сервиса]
|
||||||
.setFunction(this::clientCodeNewFromGateway)
|
// callback(TkrAccountsGatewayRequest.class)
|
||||||
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_FROM_GATEWAY, callbacks::put);
|
// .setFunction(this::clientCodeNewFromGateway)
|
||||||
|
// .forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_FROM_GATEWAY, callbacks::put);
|
||||||
callback(ClientCodeNewRequest.class)
|
callback(ClientCodeNewRequest.class)
|
||||||
.setFunction(this::clientCodeNewFromApiUmCompany)
|
.setFunction(this::clientCodeNewFromApiUmCompany)
|
||||||
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, callbacks::put);
|
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, callbacks::put);
|
||||||
|
|
@ -513,7 +514,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean
|
||||||
query.put("depoAccountId", depoAccountId);
|
query.put("depoAccountId", depoAccountId);
|
||||||
}
|
}
|
||||||
TradingClearingRegistry result = tradingClearingRegistryMap.getFirstObjectByFieldValues(query);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
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.account.validation.ClientCodeStoreObjects;
|
||||||
|
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 = validator.getStored(ClientCodeStoreObjects.TRADING_CLEARING_REGISTRY);
|
||||||
|
if (tradingClearingRegistry == null) {
|
||||||
|
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 lock(){
|
||||||
|
// tradingClearingRegistryFacade.lock()
|
||||||
|
// tradingClearingRegistryListFacade.lock()
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlock(){
|
||||||
|
// tradingClearingRegistryFacade.lock()
|
||||||
|
// tradingClearingRegistryListFacade.lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
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.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
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.sender.KafkaSender;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public ClientCodeMessageListener(Consumer<String, Object> kafkaQueue,
|
||||||
|
Producer<String, Object> kafkaProducer,
|
||||||
|
KafkaSender kafkaSender,
|
||||||
|
ImdgProvider imdgProvider,
|
||||||
|
ClientCodeFacade clientCodeFacade,
|
||||||
|
ClientCodeValidator clientCodeValidator,
|
||||||
|
GatewayRequestCreator gatewayRequestCreator) {
|
||||||
|
super(kafkaQueue, kafkaProducer);
|
||||||
|
this.kafkaSender = kafkaSender;
|
||||||
|
this.imdgProvider = imdgProvider;
|
||||||
|
this.clientCodeFacade = clientCodeFacade;
|
||||||
|
this.clientCodeValidator = clientCodeValidator;
|
||||||
|
this.gatewayRequestCreator = gatewayRequestCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
imdgProvider.waitAvailable();
|
||||||
|
|
||||||
|
callback(TkrAccountsGatewayRequest.class)
|
||||||
|
.setFunction(this::clientCodeNewFromGateway)
|
||||||
|
.forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_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 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
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.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 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(Function<ClientCodeNewRequest, IValidator> clientCodeNewRequestValidator,
|
||||||
|
Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator,
|
||||||
|
Function<CommonDeleteRequest, IValidator> clientCodeDeleteRequestValidator,
|
||||||
|
Function<TkrAccount, IValidator> tkrAccountsGatewayValidator,
|
||||||
|
IMessageResolver messageResolver) {
|
||||||
|
this.clientCodeNewRequestValidator = clientCodeNewRequestValidator;
|
||||||
|
this.clientCodeUpdateRequestValidator = clientCodeUpdateRequestValidator;
|
||||||
|
this.clientCodeDeleteRequestValidator = clientCodeDeleteRequestValidator;
|
||||||
|
this.tkrAccountsGatewayValidator = tkrAccountsGatewayValidator;
|
||||||
|
this.messageResolver = messageResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationResult checkGatewayRequest(TkrAccount gatewayAccountRequest) {
|
||||||
|
IValidator validator = tkrAccountsGatewayValidator.apply(gatewayAccountRequest);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -9176,6 +9176,10 @@
|
||||||
{"code": "inSDfId",
|
{"code": "inSDfId",
|
||||||
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
|
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
|
||||||
}
|
}
|
||||||
|
,
|
||||||
|
{"code": "accType",
|
||||||
|
"type": 3,"name": "Признак счета","shortname": "Признак счета","searchable": true,"sortable": true,"visible": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2117,6 +2117,7 @@
|
||||||
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
|
<generationTime type="4" name="Дата и время создания записи" shortname="Дата и время создания" searchable="true" sortable="true" visible="true"/>
|
||||||
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
|
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
|
||||||
<inSDfId type="1" name="Идентификатор соответствующей записи из таблицы-источника" shortname="Входящая запись" 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>
|
</sDf53>
|
||||||
<sDf54 name="ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414" destination="s-dfs/s-df54" class="ru.clearing.classes.statics.data.sdf.SDf54" table="s_df_54">
|
<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"/>
|
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="false"/>
|
||||||
|
|
|
||||||
|
|
@ -9176,6 +9176,10 @@
|
||||||
{"code": "inSDfId",
|
{"code": "inSDfId",
|
||||||
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
|
"type": 1,"name": "Идентификатор соответствующей записи из таблицы-источника","shortname": "Входящая запись","searchable": true,"sortable": true,"visible": true
|
||||||
}
|
}
|
||||||
|
,
|
||||||
|
{"code": "accType",
|
||||||
|
"type": 3,"name": "Признак счета","shortname": "Признак счета","searchable": true,"sortable": true,"visible": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4503,7 +4503,7 @@ GRANT ALL PRIVILEGES ON TABLE S_DF52 TO clearing;
|
||||||
|
|
||||||
-- sDf53 - ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)
|
-- sDf53 - ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)
|
||||||
DROP TABLE IF EXISTS S_DF53;
|
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);
|
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 TABLE S_DF53 IS 'ДФ-53 Квитанция о получении информации о состоянии счета (блокировка/разблокировка/закрытие/открытие)';
|
||||||
|
|
||||||
COMMENT ON COLUMN S_DF53.ID IS 'Идентификатор записи';
|
COMMENT ON COLUMN S_DF53.ID IS 'Идентификатор записи';
|
||||||
|
|
@ -4528,6 +4528,8 @@ COMMENT ON COLUMN S_DF53.GENERATION_ID IS 'Идентификатор взаим
|
||||||
|
|
||||||
COMMENT ON COLUMN S_DF53.IN_S_DF_ID IS 'Идентификатор соответствующей записи из таблицы-источника';
|
COMMENT ON COLUMN S_DF53.IN_S_DF_ID IS 'Идентификатор соответствующей записи из таблицы-источника';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN S_DF53.ACC_TYPE IS 'Признак счета';
|
||||||
|
|
||||||
GRANT ALL PRIVILEGES ON TABLE S_DF53 TO clearing;
|
GRANT ALL PRIVILEGES ON TABLE S_DF53 TO clearing;
|
||||||
|
|
||||||
-- sDf54 - ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414
|
-- sDf54 - ДФ-54 Вывод свободных средств для инициаторов категории В с клирингового счета 30414
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import java.util.List;
|
||||||
import com.jcraft.jsch.ChannelSftp;
|
import com.jcraft.jsch.ChannelSftp;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
|
|
@ -27,15 +26,9 @@ import ru.spcex.clearing.dbf.importer.config.settings.ImportDBFServiceSettings;
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SFTPConfig {
|
public class SFTPConfig {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
private final ImportDBFServiceSettings settings;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SFTPConfig(ImportDBFServiceSettings settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
|
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory(ImportDBFServiceSettings settings) {
|
||||||
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
|
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
|
||||||
factory.setHost(settings.getStore().getSftpIn().getServerIp());
|
factory.setHost(settings.getStore().getSftpIn().getServerIp());
|
||||||
factory.setPort(settings.getStore().getSftpIn().getServerPort());
|
factory.setPort(settings.getStore().getSftpIn().getServerPort());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package ru.spcex.platform.classes.base.interfaces;
|
||||||
|
|
||||||
|
public interface IClearingFacade {
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
//something about store objects?
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue