diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java index bbb557877..97125a334 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java @@ -48,6 +48,7 @@ public class AccountValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Account); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_AccountTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", CorrespondentAccountNewRequest::getCompanyId, @@ -106,6 +107,15 @@ public class AccountValidationConfig { return DictionaryPresentRule.DICTIONARY_NOT_FOUND_DECORATOR_2.decorator(causeEmpty, errorCode, fieldName, fieldValue); } ), + + DictionaryPresentRule.instance("currency", + CorrespondentAccountNewRequest::getCurrency, + IMDGDistributedNames.Map_CurrencyCodeDictionary, + ServiceStatusDictionary.class, + null, + AccountError.DictionaryNotFound, + false + ), new SameAccountValidationRule<>(AccountType.Corr, CorrespondentAccountNewRequest::getAccount) ); }; diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/InformationAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/InformationAccountValidationConfig.java index 11431002d..19e917a56 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/InformationAccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/InformationAccountValidationConfig.java @@ -38,6 +38,7 @@ public class InformationAccountValidationConfig { addImdg.accept(IMDGDistributedNames.Map_InformationAccount); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_AccountTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary); addImdg.accept(IMDGDistributedNames.Map_Account); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", @@ -59,6 +60,10 @@ public class InformationAccountValidationConfig { DictionaryPresentRule.instance("accountType", InformationAccountNewRequest::getAccountType, IMDGDistributedNames.Map_AccountTypeDictionary, AccountTypeDictionary.class, AccountError.RequiredFieldEmpty, AccountError.DictionaryNotFound, false), + DictionaryPresentRule.instance("currency", InformationAccountNewRequest::getCurrency, + IMDGDistributedNames.Map_CurrencyCodeDictionary, ServiceStatusDictionary.class, + null, AccountError.DictionaryNotFound,false + ), new SameAccountValidationRule<>(AccountType.Info, InformationAccountNewRequest::getAccount) ); }; diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java index 3d47a3de6..351ae727b 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java @@ -129,18 +129,20 @@ public class AccountService extends QueueConsumer implements InitializingBean { if (requestInfoUpdate != null) return requestInfoUpdate; CorrespondentAccountNewRequest req = userRequest.getRequestPayload(); + String currency = req.getCurrency() == null ? CurrencyCode.RUB.getKey() : req.getCurrency(); Instant now = Instant.now(); Account account = new Account(); account.setCompanyId(req.getCompanyId()); account.setAccount(req.getAccount()); if (AccountType.Info.equalsByKey(req.getAccountType())) { - Long infoSequenceId = informationAccountService.accountNextId(); + Long infoSequenceId = informationAccountService.accountNextId(currency); String accountValue = informationAccountService.generateInfoAccount(infoSequenceId); log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue); account.setAccount(accountValue); } account.setAccountType(req.getAccountType()); + account.setCurrency(currency); if (req.getStatus() == null) { account.setStatus(WorkflowStatus.Active.getKey()); log.trace("Status not set in request. Use default: {}", account.getStatus()); @@ -198,10 +200,11 @@ public class AccountService extends QueueConsumer implements InitializingBean { infoAcc.setAccountId(account.getId()); Account firstAccountAntl = accountMap.getFirstObjectByFieldValues(Map.of( "companyId", Sender.One.getId(), - "accountType", AccountType.Anlt.getKey() + "accountType", AccountType.Anlt.getKey(), + "currency", account.getCurrency() )); if (firstAccountAntl == null) { - log.warn("Can not find 1 ANTL account for fill information ClearingAccountId."); + log.warn("Can not find 1 ANTL {} account for fill information ClearingAccountId.", account.getCurrency()); } else { infoAcc.setClearingAccountId(firstAccountAntl.getId()); } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java index 26e273f76..91274aa2f 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java @@ -16,7 +16,6 @@ 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.InformationAccountNewRequest; -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.QueueConsumer; @@ -26,6 +25,7 @@ import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.CurrencyCode; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; @@ -40,6 +40,7 @@ import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Collection; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; @@ -63,7 +64,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali * Кэш-счётчик сквозных номеров счетов. * См. accountNextId() */ - protected AtomicLong infoCounter; + protected Map infoCounterByCurrency = new HashMap<>(); @Autowired public InformationAccountService(Consumer kafkaQueue, @@ -115,15 +116,17 @@ public class InformationAccountService extends QueueConsumer implements Initiali if (requestInfoUpdate != null) return requestInfoUpdate; InformationAccountNewRequest req = userRequest.getRequestPayload(); + String currency = req.getCurrency() == null ? CurrencyCode.RUB.getKey() : req.getCurrency(); //userRequest.getRequestPayload().getCurrency(); Long newId = informationAccountImdg.nextIDSequenceFor(); - Long infoSequenceId = accountNextId(); + Long infoSequenceId = accountNextId(currency); String accountValue = generateInfoAccount(infoSequenceId); log.trace("New info-account id={}, sequenceId={}, account={}", newId, infoSequenceId, accountValue); ImdgPredicateBuilder accountPredicateBuilder = accountImdg.predicateBuilder(); ImdgPredicate companyIdPredicate = accountPredicateBuilder.equals("companyId", 1L); - ImdgPredicate accountTypePredicate = accountPredicateBuilder.equals("accountType", AccountType.Anlt.getKey()); + ImdgPredicate accountTypePredicate = accountPredicateBuilder.and(accountPredicateBuilder.equals("accountType", AccountType.Anlt.getKey()), + accountPredicateBuilder.equals("currency", currency)); ImdgPredicate andPredicate = accountPredicateBuilder.and(companyIdPredicate, accountTypePredicate); Collection accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate); if (accountsAnlt.isEmpty()) { @@ -209,8 +212,11 @@ public class InformationAccountService extends QueueConsumer implements Initiali } + String currency = userRequest.getRequestPayload().getCurrency(); + if (currency == null) + currency = CurrencyCode.RUB.getKey(); Long newId = informationAccountImdg.nextIDSequenceFor(); - Long infoSequenceId = accountNextId(); // требуется последовательность n+1 + Long infoSequenceId = accountNextId(currency); // требуется последовательность n+1 String accountValue = generateInfoAccount(infoSequenceId); log.trace("New info-account id={}, sequenceId={}, account={}", newId, infoSequenceId, accountValue); @@ -218,7 +224,8 @@ public class InformationAccountService extends QueueConsumer implements Initiali { ImdgPredicate andPredicate = pb.and( pb.equals("companyId", 1L), - pb.equals("accountType", AccountType.Anlt.getKey()) + pb.equals("accountType", AccountType.Anlt.getKey()), + pb.equals("currency", currency) ); Collection accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate); if (accountsAnlt.isEmpty()) { @@ -302,13 +309,20 @@ public class InformationAccountService extends QueueConsumer implements Initiali /** * Сквозной номер инфо-счетов * + * @param * @return infoCounter++ */ - public synchronized Long accountNextId() { + public synchronized Long accountNextId(String currency) { + if (currency == null) + currency = CurrencyCode.RUB.getKey(); // default + AtomicLong infoCounter = infoCounterByCurrency.get(currency); if (infoCounter == null) synchronized (this) { if (infoCounter == null) { log.debug("Init account-information counter."); - Collection allInfoAcc = accountImdg.getCollectionObjectsByFieldValues(Map.of("accountType", AccountType.Info.getKey())); + Collection allInfoAcc = accountImdg.getCollectionObjectsByFieldValues(Map.of( + "accountType", AccountType.Info.getKey(), + "currency", currency + )); if (allInfoAcc.isEmpty()) { infoCounter = new AtomicLong(1); log.debug("No account information on map. n={}", infoCounter.get()); @@ -341,6 +355,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali if (parsedCount == 0 && lastAccount != null) log.debug("Last unparseable account: {}", lastAccount); } + infoCounterByCurrency.put(currency, infoCounter); } } return infoCounter.incrementAndGet(); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index 6a68bef1e..76a8b6039 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -401,7 +401,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini if (sId.length() > 5) sId = sId.substring(sId.length() - 5); code += sId; - return code; // 12 имволов + return code; // 12 символов } public RequestInfoUpdate tradingClearingRegistryUpdate(BaseRequest userRequest) { diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java index 6fa633e59..1cdc637a4 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java @@ -124,6 +124,7 @@ class InformationAccountServiceTest { Account accountAnlt = new Account(); accountAnlt.setAccountType(AccountType.Anlt.getKey()); accountAnlt.setCompanyId(1L); + accountAnlt.setCurrency("RUB"); anltAccountId = accountImdg.insert(accountAnlt); new TestObjectCreator(hazelcastServiceTest).createUserAdmin(1000L); @@ -134,6 +135,7 @@ class InformationAccountServiceTest { InformationAccountNewRequest InformationAccountNewRequest = new InformationAccountNewRequest(); InformationAccountNewRequest.setCompanyId(companyId); InformationAccountNewRequest.setAccount(account); + InformationAccountNewRequest.setCurrency(null); String jsonString = getJsonStringForNew(InformationAccountNewRequest, 0L); @@ -178,11 +180,13 @@ class InformationAccountServiceTest { Account account = new Account(); account.setId(120L); account.setAccountType(AccountType.Info.getKey()); + account.setCurrency(CurrencyCode.RUB.getKey()); account.setCompanyId(10L); account.setAccount("39911810000000127000"); accountImdg.insert(account); InformationAccount accountInfo = new InformationAccount(); accountInfo.setId(121L); + account.setCurrency(CurrencyCode.RUB.getKey()); accountInfo.setAccountId(account.getId()); accountInfo.setCompanyId(account.getCompanyId()); accountInfoImdg.insert(accountInfo); @@ -190,9 +194,17 @@ class InformationAccountServiceTest { UserRoleVerification userRoleVerification = Mockito.mock(UserRoleVerification.class); InformationAccountService infoAccSvc=new InformationAccountService(null,null,null, null, userRoleVerification, hazelcastServiceTest, null, null, null, null); - Long n = infoAccSvc.accountNextId(); + Long n = infoAccSvc.accountNextId(null); Assertions.assertEquals(13L, n); - n = infoAccSvc.accountNextId(); + n = infoAccSvc.accountNextId(null); Assertions.assertEquals(14L, n); + + // Другие валюты + n = infoAccSvc.accountNextId(CurrencyCode.RUB.getKey()); + Assertions.assertEquals(15L, n); + n = infoAccSvc.accountNextId("CNY"); + Assertions.assertEquals(2L, n); + n = infoAccSvc.accountNextId("CNY"); + Assertions.assertEquals(3L, n); } } \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountInformationNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountInformationNewAction.java index 79041f21f..d7dd2b37d 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountInformationNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountInformationNewAction.java @@ -17,6 +17,9 @@ public class AccountInformationNewAction implements IAction { @ApiModelProperty(value = "Наименование типа счета", example = "CLRN") @JsonProperty private String accountType; + @ApiModelProperty(value = "Код валюты", example = "RUB") + @JsonProperty + private String currency; @Override public AccountNewRequest toRequest() { @@ -37,6 +40,7 @@ public class AccountNewAction implements IAction { req.setAccount(this.account); req.setStatus(this.status); req.setAccountType(this.accountType); + req.setCurrency(this.currency); return req; } @@ -77,4 +81,12 @@ public class AccountNewAction implements IAction { public void setAccountType(String accountType) { this.accountType = accountType; } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } } diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.json b/clearing-parent/backend-api/src/main/resources/meta/meta.json index 590401157..feb804d5d 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.json +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.json @@ -1,6 +1,6 @@ { - "version": "3.11.0.83", + "version": "3.11.0.84", "enums": { @@ -4764,6 +4764,10 @@ {"code": "accountType", "type": 12,"name": "Наименование типа счета","shortname": "Тип","link": "accountType","required": true,"visible": false } + , + {"code": "currency", + "type": 12,"name": "Код валюты","shortname": "Валюта","visible": true,"link": "currencyCode","linkCode": "code" + } ] } , diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index 43d9be490..745b3af62 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -1,6 +1,6 @@ - + @@ -1105,6 +1105,7 @@ + diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java index 374e4b980..8792b191a 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java @@ -2,45 +2,6 @@ package ru.spcex.clearing.platform.messaging.domain.cud.account; import com.fasterxml.jackson.annotation.JsonProperty; -public class AccountNewRequest { - @JsonProperty - public Long companyId; - @JsonProperty - public String account; - @JsonProperty - public String status; - @JsonProperty - public String accountType; - - public Long getCompanyId() { - return companyId; - } - - public void setCompanyId(Long companyId) { - this.companyId = companyId; - } - - public String getAccount() { - return account; - } - - public void setAccount(String account) { - this.account = account; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getAccountType() { - return accountType; - } - - public void setAccountType(String accountType) { - this.accountType = accountType; - } +@Deprecated +public class AccountNewRequest extends CorrespondentAccountNewRequest { } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountUpdateRequest.java index a3e5406e1..f68a8f6ad 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountUpdateRequest.java @@ -2,55 +2,7 @@ package ru.spcex.clearing.platform.messaging.domain.cud.account; import com.fasterxml.jackson.annotation.JsonProperty; -public class AccountUpdateRequest { - @JsonProperty - public Long id; - @JsonProperty - public Long companyId; - @JsonProperty - public String account; - @JsonProperty - public String status; - @JsonProperty - public String accountType; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getCompanyId() { - return companyId; - } - - public void setCompanyId(Long companyId) { - this.companyId = companyId; - } - - public String getAccount() { - return account; - } - - public void setAccount(String account) { - this.account = account; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getAccountType() { - return accountType; - } - - public void setAccountType(String accountType) { - this.accountType = accountType; - } +@Deprecated +public class AccountUpdateRequest extends CorrespondentAccountUpdateRequest{ } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/CorrespondentAccountNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/CorrespondentAccountNewRequest.java index dc33c7dbe..d27ab05a0 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/CorrespondentAccountNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/CorrespondentAccountNewRequest.java @@ -15,6 +15,9 @@ public class CorrespondentAccountNewRequest { @JsonProperty public String accountType; + @JsonProperty + public String currency; + public Long getCompanyId() { return companyId; } @@ -46,4 +49,12 @@ public class CorrespondentAccountNewRequest { public void setAccountType(String accountType) { this.accountType = accountType; } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/InformationAccountNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/InformationAccountNewRequest.java index 045cc8ebf..b1997fc06 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/InformationAccountNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/InformationAccountNewRequest.java @@ -12,6 +12,9 @@ public class InformationAccountNewRequest { @JsonProperty private String status; + @JsonProperty + private String currency; + @JsonProperty private String accountType; @@ -39,6 +42,14 @@ public class InformationAccountNewRequest { this.status = status; } + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + public String getAccountType() { return accountType; }