new version services [account-service]

This commit is contained in:
etreschenkov 2024-06-07 17:12:25 +03:00
parent 6b2290e0cf
commit ed3a6d31f0
5 changed files with 250 additions and 157 deletions

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.account.config.validation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.errors.AccountError;
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.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.enumeration.CompanySymbol;
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;
@ -93,121 +97,6 @@ public class ClientCodeValidationConfig {
};
}
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 + "}";
}
}
public static class ExistCompanyByUuid<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, String> symbolCodeGetter;
public ExistCompanyByUuid(String fieldName, Function<R, String> symbolCodeGetter) {
this.fieldName = fieldName;
this.symbolCodeGetter = symbolCodeGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String symbolCodeValue = symbolCodeGetter.apply(validatedObject);
if (!StringUtils.hasText(symbolCodeValue)) {
return of(AccountError.RequiredFieldEmpty, fieldName);
}
Imdg<CompanySymbols> imdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
CompanySymbols companySymbols = imdg.getFirstObjectByFieldValues(
Map.of(
"companySymbol", CompanySymbol.UUID.getKey(),
"companySymbolValue", symbolCodeValue
)
);
if (companySymbols == null) { // null значения в массиве не ожидаются
return of(AccountError.COMPANY_NOT_FOUND_GTW, fieldName);
}
return Optional.empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
public static class ExistAccountByValue<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, List<MoneyAccountMsgRequest>> accountsListValueGetter;
public ExistAccountByValue(String fieldName, Function<R, List<MoneyAccountMsgRequest>> accountsListValueGetter) {
this.fieldName = fieldName;
this.accountsListValueGetter = accountsListValueGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
List<MoneyAccountMsgRequest> accountList = accountsListValueGetter.apply(validatedObject);
if (accountList == null || accountList.isEmpty()) {
return of(AccountError.RequiredFieldEmpty, fieldName);
}
Imdg<Account> imdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
for (MoneyAccountMsgRequest moneyAccountMsg : accountList) {
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
ImdgPredicate currencyPredicate;
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(), fieldName);
}
}
return Optional.empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
@Bean("clientCodeUpdateRequestValidator")
public Function<ClientCodeUpdateRequest, IValidator> clientCodeUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return clientCodeUpdateRequest -> {
@ -303,8 +192,216 @@ public class ClientCodeValidationConfig {
new ExistCompanyByUuid<>("companySymbolValue",
TkrAccount::getCompanyId),
new ExistAccountByValue<>("account",
TkrAccount::getMoneyAccounts)
TkrAccount::getMoneyAccounts),
new ExistDepoAccountByValue<>("depo_account",
TkrAccount::getDepoAccount),
new ExistTcrByCode<>("tcr_code",
TkrAccount::getTkrCode)
);
};
}
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 + "}";
}
}
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>> {
String fieldName;
Function<R, String> symbolCodeGetter;
public ExistCompanyByUuid(String fieldName, Function<R, String> symbolCodeGetter) {
this.fieldName = fieldName;
this.symbolCodeGetter = symbolCodeGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String symbolCodeValue = symbolCodeGetter.apply(validatedObject);
if (!StringUtils.hasText(symbolCodeValue)) {
return of(AccountError.RequiredFieldEmpty, fieldName);
}
Imdg<CompanySymbols> imdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
CompanySymbols companySymbols = imdg.getFirstObjectByFieldValues(
Map.of(
"companySymbol", CompanySymbol.UUID.getKey(),
"companySymbolValue", symbolCodeValue
)
);
if (companySymbols == null) {
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();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
public static class ExistAccountByValue<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, List<MoneyAccountMsgRequest>> accountsListValueGetter;
public ExistAccountByValue(String fieldName, Function<R, List<MoneyAccountMsgRequest>> accountsListValueGetter) {
this.fieldName = fieldName;
this.accountsListValueGetter = accountsListValueGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
List<MoneyAccountMsgRequest> accountList = accountsListValueGetter.apply(validatedObject);
if (accountList == null || accountList.isEmpty()) {
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);
Map<String, Account> accountByCurrency = new HashMap<>();
for (MoneyAccountMsgRequest moneyAccountMsg : accountList) {
ImdgPredicateBuilder predicateBuilder = imdg.predicateBuilder();
ImdgPredicate currencyPredicate;
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(), fieldName);
}
accountByCurrency.put(account.getCurrency(), account);
}
context.storeObject(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS, accountByCurrency);
return Optional.empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
public static class ExistDepoAccountByValue<R> implements IValidationRule<ImdgValidationContext<R>> {
String fieldName;
Function<R, String> depoAccountGetter;
public ExistDepoAccountByValue(String fieldName, Function<R, String> accountsListValueGetter) {
this.fieldName = fieldName;
this.depoAccountGetter = depoAccountGetter;
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String depoAccountVal = depoAccountGetter.apply(validatedObject);
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.DEPO_ACCOUNT_NOT_FOUND_GTW, fieldName);
}
context.storeObject(ClientCodeStoreObjects.DEPO_ACCOUNT, depoAccount);
return Optional.empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}
}

View file

@ -29,6 +29,8 @@ public enum AccountError implements IErrorEnumId {
TCR_NOT_FOUND_GTW(5028L),
ACCOUNT_NOT_FOUND_GTW(5029L),
COMPANY_NOT_FOUND_GTW(5030L),
TCR_ALREADY_EXIST_GTW(5031L),
DEPO_ACCOUNT_NOT_FOUND_GTW(5032L),
TradingClearingRegistryNotFound(3022L),
CurrencyNotFound(1016L),
;

View file

@ -30,28 +30,24 @@ 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) {
Imdg<TradingClearingRegistry> tradingClearingRegistryImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
);
Imdg<DepoAccount> depoAccountImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_DepoAccount, DepoAccount.class
);
Imdg<ClearingAccount> clearingAccountImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
);
Imdg<Company> companyImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_Company, Company.class
);
Long id = tradingClearingRegistryImdg.nextIDSequenceFor();
TradingClearingRegistry tradingClearingRegistry = new TradingClearingRegistry();
tradingClearingRegistry.setId(id);

View file

@ -24,10 +24,18 @@ 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;
}
@ -36,20 +44,10 @@ public class TradingClearingRegistryListFacade {
Account account;
}
public List<Long> createTradingClearingRegistryList(TradingClearingRegistryListNewRequest request,
Stored stored) {
Imdg<TradingClearingRegistry> tradingClearingRegistryImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
);
Imdg<TradingClearingRegistryList> tradingClearingRegistryListImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class
);
Imdg<Account> accountImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_Account, Account.class
);
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByID(request.getTradingClearingRegistryId());
Instant now = Instant.now();
List<Long> newIds = new ArrayList<>();

View file

@ -114,7 +114,7 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali
Company company = validator.getStored(ClientCodeStoreObjects.COMPANY);
Optional<Account> depoAccount = validator.getStored(ClientCodeStoreObjects.DEPO_ACCOUNT);
Long depoAccountId = depoAccount.map(Account::getId).orElse(null);
Map<CurrencyCode, Account> accountByCurrency = validator.getStored(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS);
Map<String, Account> accountByCurrency = validator.getStored(ClientCodeStoreObjects.MAPPED_TO_CURRENCY_ACCOUNTS);
clientCodeNewRequest.setCompanyId(company.getId());
clientCodeNewRequest.setCode(tkrAccount.getClientCode());
@ -124,7 +124,7 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali
List<Long> foreignCurrencyList = accountByCurrency.entrySet()
.stream()
.filter(currencyCodeAccountEntry -> CurrencyCode.RUB != currencyCodeAccountEntry.getKey())
.filter(currencyCodeAccountEntry -> !CurrencyCode.RUB.equalsByKey(currencyCodeAccountEntry.getKey()))
.map(currencyCodeAccountEntry -> currencyCodeAccountEntry.getValue().getId())
.toList();
clientCodeNewRequest.setCurrencyAccountList(foreignCurrencyList);