diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java index baf8ebc54..4681150dc 100644 --- a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java +++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java @@ -72,6 +72,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Account); addImdg.accept(IMDGDistributedNames.Map_Company); addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); + addImdg.accept(IMDGDistributedNames.Map_AccountBalance); return new ValidatorImpl<>(context, Sdf16ValidationRule.CompanyPresent, ExistClrnAccountValidationRule.AccountPresent, diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ExistClrnAccountValidationRule.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ExistClrnAccountValidationRule.java index 322bdc7c2..5b1e1739f 100644 --- a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ExistClrnAccountValidationRule.java +++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ExistClrnAccountValidationRule.java @@ -19,6 +19,9 @@ public enum ExistClrnAccountValidationRule implements IValidationRule validate(ImdgValidationContext context) { WithAccount withAccount = context.getValidatedObject(); + if (withAccount.getAccount() == null) { + return of(BalanceError.AccountNotPresent); + } Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); Account account = accountImdg.getSingleObjectByFieldValues(Map.of("account", withAccount.getAccount(), "accountType", AccountType.Clrn.getKey())); diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java index 33e62153e..29feac545 100644 --- a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java @@ -5,10 +5,12 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.apache.kafka.clients.consumer.OffsetResetStrategy; import org.apache.kafka.clients.producer.MockProducer; import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.common.serialization.StringSerializer; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; +import ru.spcex.clearing.platform.messaging.serialization.JsonSerializer; @Configuration public class KafkaTestConfig { @@ -21,6 +23,6 @@ public class KafkaTestConfig { @Bean public Producer createTestProducer() { - return new MockProducer<>(); + return new MockProducer<>(true, new StringSerializer(), new JsonSerializer()); } } diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java index 38d80174a..3e027c8c6 100644 --- a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java @@ -12,6 +12,7 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.sdf.SDf02; import ru.clearing.classes.statics.data.sdf.SDf10; +import ru.clearing.classes.statics.data.sdf.SDf17; import ru.clearing.classes.statics.data.statement.Statement; import ru.spcex.clearing.balance.config.*; import ru.spcex.clearing.balance.utils.MatcherFactory; @@ -33,6 +34,7 @@ import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFields AccountBalanceService.class, Sdf01Executor.class, Sdf09Executor.class, + Sdf16Executor.class, LoggingService.class, MessagesConfig.class, ValidationConfig.class, @@ -59,6 +61,7 @@ public abstract class AbstractServiceTest { protected ImdgHazelcast statementImdg; protected ImdgHazelcast sdf02Imdg; protected ImdgHazelcast sdf10Imdg; + protected ImdgHazelcast sdf17Imdg; protected ImdgHazelcast accountBalanceImdg; @Autowired @Qualifier("hazelcastServiceTest") @@ -73,6 +76,7 @@ public abstract class AbstractServiceTest { statementImdg = (ImdgHazelcast) hazelcast.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); sdf02Imdg = (ImdgHazelcast) hazelcast.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); sdf10Imdg = (ImdgHazelcast) hazelcast.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class); + sdf17Imdg = (ImdgHazelcast) hazelcast.getImdg(IMDGDistributedNames.Map_SDf17, SDf17.class); accountBalanceImdg = (ImdgHazelcast) hazelcast.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); companyMap = companyImdg.getMap(); companySymbolsMap = companySymbolsImdg.getMap(); diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/Sdf16ExecutorTest.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/Sdf16ExecutorTest.java new file mode 100644 index 000000000..7276950be --- /dev/null +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/Sdf16ExecutorTest.java @@ -0,0 +1,274 @@ +package ru.spcex.clearing.balance.service; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.sdf.SDf16; +import ru.clearing.classes.statics.data.sdf.SDf17; +import ru.clearing.classes.statics.data.statement.Statement; +import ru.spcex.clearing.balance.errors.BalanceError; +import ru.spcex.clearing.balance.utils.MatcherFactory; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.utils.enumeration.EnumMessage; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFieldsComparator; + +class Sdf16ExecutorTest extends AbstractServiceTest { + private static final MatcherFactory.Matcher SDF_17_MATCHER = usingIgnoringFieldsComparator("created", "comment", "outSDfId", "generationTime", "generationId", "id"); + + private final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy"); + private final Long ID = 3L; + private final String acc = "323456789"; + @Autowired + Sdf16Executor sdf16Executor; + private SDf16 sdf16; + private StatementRequest statementRequest; + + @PostConstruct + void init() { + super.init(); + sdf16 = getTestSdf16(); + statementRequest = new StatementRequest(); + } + + /** + * {@link Sdf16Executor#execute(Collection collection, StatementRequest statementRequest)}
+ * Тест проверяет генерацию сущностей {@link Result}, {@link Statement}, {@link SDf17}
+ * Входные параметры:
+ * accountId - {@link StatementRequest}: new StatementRequest()
+ * addresseeId - {@link Collection}
+ * addresseeId - {@link SDf16}
+ * {@link SDf16#market} - "U"
+ * {@link SDf16#account} - "123456789"
+ * {@link SDf16#inn} - 987654321
+ * {@link SDf16#sum} - 1700
+ * {@link SDf16#type} - "t"
+ * {@link SDf16#bic} - new BigDecimal(1000389238)
+ * {@link SDf16#spec} - "134"
+ * {@link SDf16#number} - new BigDecimal(234232343)
+ */ + @Test + void execute() { + //check create statement, SDf17 and AccountBalance + Company company = getTestCompany(); + companyMap.put(addresseeIdNew, company); + + CompanySymbols companySymbols = getTestCompanySymbols(); + companySymbolsMap.put(addresseeIdNew, companySymbols); + + Account account = getTestAccount(ID, acc); + accountMap.put(accountIdNew, account); + + Result predictableResult = new Result(); + predictableResult.setGenerationId(ID); + Statement predictableStatement = getTestStatement(currentId.getAndIncrement(), company, account, sdf16); + predictableStatement.setOperationStatus(OperationStatus.Executed.getKey()); + SDf17 predictableSdf17 = getTestSdf17(currentId.getAndIncrement(), sdf16, ID); + predictableStatement.setOutSDfId(predictableSdf17.getId()); + AccountResult predictableNewResult = getTestAccountResult(currentId.getAndIncrement(), account, company); + + Result result = sdf16Executor.execute(Collections.singletonList(sdf16), statementRequest); + Statement resultStatement = statementImdg.getSingleObjectByFieldValues(Map.of("account", acc)); + SDf17 resultSdf17 = sdf17Imdg.getSingleObjectByFieldValues(Map.of("account", acc)); + AccountBalance resultAccountBalance = accountBalanceImdg.getSingleObjectByFieldValues(Map.of("account", acc)); + + RESULT_MATCHER.assertMatch(result, predictableResult); + STATEMENT_MATCHER.assertMatch(resultStatement, predictableStatement); + SDF_17_MATCHER.assertMatch(resultSdf17, predictableSdf17); + ACCOUNT_BALANCE_MATCHER.assertMatch(resultAccountBalance, predictableNewResult.getAccount()); + } + + /** + * {@link Sdf16Executor#execute(Collection collection, StatementRequest statementRequest)}
+ * Тест проверяет валидацию
+ * Входные параметры:
+ * accountId - {@link StatementRequest}: new StatementRequest()
+ * addresseeId - {@link Collection}
+ * addresseeId - {@link SDf16}
+ * {@link SDf16#market} - "U"
+ * {@link SDf16#account} - "123456789"
+ * {@link SDf16#inn} - 987654321
+ * {@link SDf16#sum} - 1700
+ * {@link SDf16#type} - "t"
+ * {@link SDf16#bic} - new BigDecimal(1000389238)
+ * {@link SDf16#spec} - "134"
+ * {@link SDf16#number} - new BigDecimal(234232343)
+ */ + @Test + void validatedExecute() { + //CompanyNotFound + companyMap.delete(addresseeIdNew); + checkError(new EnumMessage(BalanceError.CompanyNotFound)); + + Company company = getTestCompany(); + companyMap.put(addresseeIdNew, company); + companySymbolsMap.delete(addresseeIdNew); + checkError(new EnumMessage(BalanceError.CompanyNotFound)); + + CompanySymbols companySymbols = getTestCompanySymbols(); + companySymbolsMap.put(addresseeIdNew, companySymbols); + sdf16.setInn(null); + checkError(new EnumMessage(BalanceError.CompanyNotFound)); + + //AccountNotPresent + sdf16.setInn(inn); + accountMap.delete(accountIdNew); + checkErrorAccountNotPresent(company); + + //AccountNotPresent + Account account = new Account(); + account.setAccount(null); + account.setAccountType(AccountType.Clrn.getKey()); + account.setAccountStatus(Status.Active.getKey()); + accountMap.put(accountIdNew, account); + checkErrorAccountNotPresent(company); + + //AccountNotPresent + account = getTestAccount(ID, acc); + accountMap.put(accountIdNew, account); + sdf16.setAccount(null); + checkErrorAccountNotPresent(company); + + //WrongMarket + sdf16.setAccount(acc); + sdf16.setMarket(null); + checkError(new EnumMessage(BalanceError.WrongMarket)); + + //BalanceNotEnough + sdf16.setMarket("U"); + sdf16.setSum(null); + checkError(new EnumMessage(BalanceError.BalanceNotEnough)); + + //BalanceNotEnough + sdf16.setSum(new BigDecimal(-1700)); + AccountBalance balance = accountBalanceImdg.getSingleObjectByFieldValues(Map.of("account", sdf16.getAccount(), + "accountType", AccountType.Clrn.getKey())); + if (balance != null) accountBalanceImdg.delete(balance); + else balance = getTestAccountBalance(ID, account, company); + checkError(new EnumMessage(BalanceError.BalanceNotEnough)); + + //BalanceNotEnough + balance.setFreeBalanceAmount(new BigDecimal(999)); + accountBalanceImdg.insert(balance); + checkError(new EnumMessage(BalanceError.BalanceNotEnough)); + + balance.setFreeBalanceAmount(amountNew); + accountBalanceImdg.insert(balance); + } + + private void checkError(EnumMessage enumMessage) { + SDf17 predictableSdf17 = getTestErrorSdf17(sdf16, enumMessage, ID); + Result result = sdf16Executor.execute(Collections.singletonList(sdf16), statementRequest); + Collection resultsSdf17 = sdf17Imdg.getCollectionObjectsByFieldValues(Map.of("account", acc)); + SDf17 resultSdf17 = resultsSdf17.stream().max((entry1, entry2) -> entry1.getId() > entry2.getId() ? 1 : -1).get(); + SDF_17_MATCHER.assertMatch(resultSdf17, predictableSdf17); + } + + protected Statement getTestStatement(Long id, Company company, Account account, SDf16 sdf16) { + Statement statement = new Statement(); + statement.setId(id); + statement.setAddresseeId(company.getId()); + statement.setSenderId(Sender.Prc.getId()); + statement.setCreated(Instant.now()); + statement.setClearingDate(LocalDate.now()); + statement.setStatementType(StatementType.incr.getKey()); + statement.setAccountId(account.getId()); + statement.setAccount(sdf16.getAccount()); + statement.setInOutDirection(InOutDirection.in.getKey()); + statement.setAmount(sdf16.getSum()); + statement.setCashMovementCurrencyCode(CurrencyCode.RUB.getKey()); + statement.setOperationStatus(OperationStatus.Pending.getKey()); + statement.setInSDfId(sdf16.getId()); + statement.setInOutSDfType(InOutSDfType.type16.getKey()); + statementImdg.insert(statement); + return statement; + } + + private SDf17 getTestSdf17(Long id, SDf16 sdf, Long generationIdForGroup) { + SDf17 successSdf = new SDf17(); + successSdf.setId(id); + successSdf.setAccount(sdf.getAccount()); + successSdf.setSum(sdf.getSum()); + successSdf.setMarket(sdf.getMarket()); + successSdf.setType(sdf.getType()); + successSdf.setInn(sdf.getInn()); + successSdf.setBic(sdf.getBic()); + successSdf.setSpec(sdf.getSpec()); + successSdf.setNumber(sdf.getNumber()); + successSdf.setGenerationId(generationIdForGroup); + successSdf.setGenerationTime(Instant.now()); + successSdf.setInSDf16Id(sdf.getId()); + successSdf.setResult(new BigDecimal(0)); + return successSdf; + } + + private SDf16 getTestSdf16() { + SDf16 sdf16 = new SDf16(); + sdf16.setId(ID); + sdf16.setMarket("U"); + sdf16.setAccount(acc); + sdf16.setInn(inn); + sdf16.setSum(amountNew); + sdf16.setType("t"); + sdf16.setBic(new BigDecimal(1000389238)); + sdf16.setSpec("134"); + sdf16.setNumber(new BigDecimal(234232343)); + return sdf16; + } + + private SDf17 getTestErrorSdf17(SDf16 sdf, EnumMessage error, Long generationIdForGroup) { + SDf17 errorSdf = new SDf17(); + errorSdf.setId(ID); + errorSdf.setAccount(sdf.getAccount()); + errorSdf.setSum(sdf.getSum()); + errorSdf.setMarket(sdf.getMarket()); + errorSdf.setType(sdf.getType()); + errorSdf.setInn(sdf.getInn()); + errorSdf.setBic(sdf.getBic()); + errorSdf.setSpec(sdf.getSpec()); + errorSdf.setNumber(sdf.getNumber()); + errorSdf.setResult(obtainResultNum(error)); + errorSdf.setGenerationId(generationIdForGroup); + errorSdf.setGenerationTime(Instant.now()); + errorSdf.setInSDf16Id(sdf.getId()); + return errorSdf; + } + + private void checkErrorAccountNotPresent(Company company) { + Result predictableResult = new Result(); + predictableResult.getAccountRequests().add(createAccountRequestPart(sdf16.getId(), sdf16.getAccount(), company.getId())); + Result result = sdf16Executor.execute(Collections.singletonList(sdf16), statementRequest); + RESULT_MATCHER.assertMatch(result, predictableResult); + } + + private AccountSdfRequestPart createAccountRequestPart(Long sdf16Id, String account, Long companyId) { + AccountSdfRequestPart req = new AccountSdfRequestPart(); + req.setAccount(account); + req.setCompanyId(companyId); + req.setAccountType(AccountType.Clrn.getKey()); + req.setSdfId(sdf16Id); + return req; + } + + private BigDecimal obtainResultNum(EnumMessage error) { + if (BalanceError.AccountNotPresent.equalsById(error.getSubject().getId())) + return new BigDecimal(1); + if (BalanceError.BalanceNotEnough.equalsById(error.getSubject().getId())) + return new BigDecimal(1); + return new BigDecimal(9); + } +} \ No newline at end of file