account-service http://jira.mfd.msk:8088/browse/CLS-553 account с типом INFO

This commit is contained in:
AKurakin 2023-09-29 20:02:36 +03:00
parent 4f2daf06d8
commit f36286e14b
14 changed files with 159 additions and 77 deletions

View file

@ -59,10 +59,14 @@ public class AccountValidationConfig {
),
FieldRequiredSpecificRule.instance("account",
CorrespondentAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty,
AccountError.AccountFieldNotSet,
false,
accountValue -> {
if (accountValue.isBlank())
return new EnumMessage(AccountError.RequiredFieldEmpty, "account");
if ((accountValue == null || accountValue.isBlank()) && AccountType.Info.equalsByKey(context.getValidatedObject().getAccountType())) {
return null;
}
if (accountValue == null || accountValue.isBlank())
return new EnumMessage(AccountError.AccountFieldNotSet, "account");
Imdg<Account> accountImdg = context.obtainMap(
IMDGDistributedNames.Map_Account, Account.class
);

View file

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

View file

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

View file

@ -55,6 +55,8 @@ public class AccountService extends QueueConsumer implements InitializingBean {
private final IMessageResolver messageResolver;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final AccountHelper accountHelper;
private final InformationAccountService informationAccountService;
private final Function<CorrespondentAccountNewRequest, IValidator> accountNewRequestValidator;
private final Function<CorrespondentAccountUpdateRequest, IValidator> accountUpdateRequestValidator;
private final Function<CommonIdRequest, IValidator> accountBlockRequestValidator;
@ -67,6 +69,8 @@ public class AccountService extends QueueConsumer implements InitializingBean {
IMessageResolver messageResolver,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
AccountHelper accountHelper,
InformationAccountService informationAccountService,
@Qualifier("correspondentAccountNewRequestValidator")
Function<CorrespondentAccountNewRequest, IValidator> accountNewRequestValidator,
@Qualifier("correspondentAccountUpdateRequestValidator")
@ -74,6 +78,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
@Qualifier("correspondentAccountBlockRequestValidator")
Function<CommonIdRequest, IValidator> accountBlockRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.accountHelper = accountHelper;
this.imdgProvider = imdgProvider;
this.accountMap = imdgProvider.getImdg(
IMDGDistributedNames.Map_Account, Account.class
@ -88,6 +93,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
this.messageResolver = messageResolver;
this.userRoleVerification = userRoleVerification;
this.validationHelper = validationHelper;
this.informationAccountService = informationAccountService;
this.accountNewRequestValidator = accountNewRequestValidator;
this.accountUpdateRequestValidator = accountUpdateRequestValidator;
this.accountBlockRequestValidator = accountBlockRequestValidator;
@ -128,6 +134,12 @@ public class AccountService extends QueueConsumer implements InitializingBean {
Account account = new Account();
account.setCompanyId(req.getCompanyId());
account.setAccount(req.getAccount());
if (AccountType.Info.equalsByKey(req.getAccountType())) {
Long infoSequenceId = informationAccountService.accountNextId();
String accountValue = informationAccountService.generateInfoAccount(infoSequenceId);
log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue);
account.setAccount(accountValue);
}
account.setAccountType(req.getAccountType());
if (req.getStatus() == null) {
account.setStatus(WorkflowStatus.Active.getKey());
@ -138,7 +150,7 @@ public class AccountService extends QueueConsumer implements InitializingBean {
account.setCreated(now);
account.setUpdated(now);
requestInfoUpdate = fillAccountFromRelation(account, userRequest.getId(), false);
requestInfoUpdate = accountHelper.fillAccountFromRelation(account, userRequest.getId(), false);
if (requestInfoUpdate != null) return requestInfoUpdate;
Long newId = null;
@ -306,60 +318,6 @@ public class AccountService extends QueueConsumer implements InitializingBean {
return null;
}
/**
* Заполняет поля relationId и companyId из соответствующей записи Relation
*
* @param requestId Идентификатор запроса для вывода лога
*/
public RequestInfoUpdate fillAccountFromRelation(Account account, Long requestId, boolean checkClearingMemberCategory) {
Long companyId = account.getCompanyId();
Collection<Relation> relations;
ImdgPredicateBuilder relationPredicateBuilder = relationMap.predicateBuilder();
ImdgPredicate finalRelationPredicate;
if (checkClearingMemberCategory) {
ImdgPredicateBuilder clearingMemberCategoryPredicateBuilder = clearingMemberCategoryMap.predicateBuilder();
ImdgPredicate companyIdEquals = clearingMemberCategoryPredicateBuilder.equals("companyId", companyId);
Collection<ClearingMemberCategory> clearingMemberCategories = clearingMemberCategoryMap.getCollectionObjectsByPredicate(companyIdEquals);
if (clearingMemberCategories.isEmpty())
return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, "(any)");
if (clearingMemberCategories.size() > 1)
log.warn("ClearingMemberCategory for companyId {} contains multiply elements, use first", companyId);
ClearingMemberCategory clearingMemberCategory = clearingMemberCategories.iterator().next();
ImdgPredicate consumerIdPredicate = relationPredicateBuilder.equals("consumerId", companyId);
ImdgPredicate servicePredicate;
String clearingCategoryValue = clearingMemberCategory.getClearingMemberCategory();
if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.B, ClearingCategory.I, ClearingCategory.V)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.MKR.getKey());
} else if (IEnumKey.contains(clearingCategoryValue, ClearingCategory.F, ClearingCategory.C)) {
servicePredicate = relationPredicateBuilder.equals("service", ru.spcex.platform.enumeration.Service.FOND.getKey());
} else {
log.info("ClearingCategoryNotFound with clearingCategoryValue={} not implemented. Do not search Relation.", clearingCategoryValue);
return null;
//return makeError(requestId, AccountError.ClearingCategoryNotFound, companyId, clearingCategoryValue + " (case not implemented)");
}
finalRelationPredicate = relationPredicateBuilder.and(consumerIdPredicate, servicePredicate);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
} else {
finalRelationPredicate = relationPredicateBuilder.equals("consumerId", companyId);
relations = relationMap.getCollectionObjectsByPredicate(finalRelationPredicate);
}
if (relations.isEmpty()) {
//return makeError(requestId, AccountError.WrongFieldValue, "companyId", finalRelationPredicate.toString());
log.info("Relation not found: {}", finalRelationPredicate.toString());
return null;
}
if (relations.size() > 1)
log.warn("Relation for consumerId {} contains multiply elements, use first", companyId);
Relation relation = relations.iterator().next();
account.setRelationId(relation.getId());
return null;
}
private RequestInfoUpdate makeError(Long reqId, AccountError accountError, Object... args) {
String errMsg = messageResolver.resolve(new EnumMessage(accountError, args));
return new RequestInfoUpdate()

View file

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

View file

@ -60,7 +60,7 @@ import java.util.function.Function;
public class ClearingAccountService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KafkaSender kafkaSender;
private final AccountService accountService;
private final AccountHelper accountService;
private final SDFProcessService sdfProcessService;
private final ValidationHelper validationHelper;
private final ImdgProvider imdgProvider;
@ -81,7 +81,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
public ClearingAccountService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaResponseQueue,
KafkaSender kafkaSender,
AccountService accountService,
AccountHelper accountService,
SDFProcessService sdfProcessService,
ValidationHelper validationHelper,
ImdgProvider imdgProvider,

View file

@ -44,7 +44,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
private final KafkaSender kafkaSender;
private final ValidationHelper validationHelper;
private final ImdgProvider imdgProvider;
private final AccountService accountService;
private final AccountHelper accountService;
private final Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator;
public DepoAccountService(Consumer<String, Object> kafkaQueue,
@ -52,7 +52,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea
KafkaSender kafkaSender,
ValidationHelper validationHelper,
ImdgProvider imdgProvider,
AccountService accountService,
AccountHelper accountService,
@Qualifier("depoAccountNewRequestValidator")
Function<DepoAccountNewRequest, IValidator> depoAccountNewRequestValidator) {
super(kafkaQueue, kafkaProducer);

View file

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

View file

@ -23,6 +23,7 @@ import ru.clearing.platform.dictionary.AccountTypeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.spcex.clearing.account.config.BeanConfiguration;
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
import ru.spcex.clearing.account.config.validation.InformationAccountValidationConfig;
import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -64,6 +65,9 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
ValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
InformationAccountService.class,
InformationAccountValidationConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
class AccountServiceTest {
@ -209,8 +213,16 @@ class AccountServiceTest {
waitingSendAndCheckRecord(0L, mockProducer);
Account resultUpdating = accountImdg.getSingleObjectByID(accountId);
existAccount.setUpdated(resultUpdating.getUpdated());
ACCOUNT_MATCHER.assertMatch(resultUpdating, existAccount);
Account expectAccount = new Account();
expectAccount.setId(existAccount.getId());
expectAccount.setAccount(account);
expectAccount.setAccountType(AccountType.Corr.getKey());
expectAccount.setStatus(ServiceStatus.Closed.getKey());
expectAccount.setCompanyId(companyId);
expectAccount.setCreated(existAccount.getCreated());
expectAccount.setUpdated(resultUpdating.getUpdated());
expectAccount.setStatus(ServiceStatus.Active.getKey());
ACCOUNT_MATCHER.assertMatch(resultUpdating, expectAccount);
accountImdg.delete(resultUpdating);
}

View file

@ -55,7 +55,7 @@ import static ru.spcex.clearing.test.TestUtils.*;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
AccountService.class,
AccountHelper.class,
BankAccountService.class,
ValidationConfig.class,
BankAccountValidationConfig.class,

View file

@ -52,7 +52,7 @@ import static ru.spcex.clearing.test.TestUtils.*;
ValidationConfig.class,
ClearingAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
ClearingAccountService.class,
SDFProcessService.class,
ImdgTestConfig.class,

View file

@ -50,7 +50,7 @@ import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
ValidationConfig.class,
DepoAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
DepoAccountService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})

View file

@ -53,7 +53,7 @@ import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew;
ValidationConfig.class,
InformationAccountValidationConfig.class,
AccountValidationConfig.class,
AccountService.class,
AccountHelper.class,
InformationAccountService.class,
ImdgTestConfig.class,
KafkaTestConfig.class})

View file

@ -103,8 +103,9 @@ class SDFProcessServiceTest {
void parseSdf52Status() {
Assertions.assertEquals(AccountStatus.BLOCKED, sdfProcessService.parseSdf52Status(0L));
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(1L));
Assertions.assertEquals(AccountStatus.ACTIVE, sdfProcessService.parseSdf52Status(3L));
Assertions.assertEquals(AccountStatus.CLOSE, sdfProcessService.parseSdf52Status(2L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(3L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(4705211956118233163L));
Assertions.assertEquals(null, sdfProcessService.parseSdf52Status(null));
}
}