Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
psemenkov 2023-06-08 18:02:30 +03:00
commit c62e99fd7d
25 changed files with 888 additions and 369 deletions

View file

@ -100,9 +100,6 @@ public class AccountService extends QueueConsumer implements InitializingBean {
@Override @Override
public void afterPropertiesSet() { public void afterPropertiesSet() {
callback(AccountSdf01Request.class)
.setFunction(this::accountNewSdf01)
.forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put);
callback(CorrespondentAccountNewRequest.class) callback(CorrespondentAccountNewRequest.class)
.setFunction(this::accountCorrespondentNew) .setFunction(this::accountCorrespondentNew)
.forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_NEW, callbacks::put); .forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_NEW, callbacks::put);
@ -234,50 +231,6 @@ public class AccountService extends QueueConsumer implements InitializingBean {
return null; return null;
} }
@Deprecated
public RequestInfoUpdate accountNewSdf01(BaseRequest<AccountSdf01Request> userRequest) {
log.debug("AccountSdf01Request received");
AccountSdf01Request req = userRequest.getRequestPayload();
List<AccountSdfToStatementRequestPart> accountToStatement = new ArrayList<>();
for (AccountSdfRequestPart accountReq : req.getAccounts()) {
Account account = new Account();
account.setAccount(accountReq.getAccount());
account.setCompanyId(accountReq.getCompanyId());
account.setAccountType(accountReq.getAccountType());
account.setStatus(WorkflowStatus.Active.getKey());
account.setCreated(Instant.now());
account.setUpdated(account.getCreated());
accountMap.insert(account);
AccountSdfToStatementRequestPart responsePart = responsePart(accountReq.getSdfId());
accountToStatement.add(responsePart);
}
sendStatementRequestBack(req.getGroupingSdf01Id(), accountToStatement);
log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size());
return null;
}
public void accountUpdateWithBrake(BaseRequest<AccountSdf01Request> userRequest) {
}
public AccountSdfToStatementRequestPart responsePart(Long sdf01Id) {
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(sdf01Id);
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
return responsePart;
}
@Deprecated
public void sendStatementRequestBack(Long groupingSdf01Id, List<AccountSdfToStatementRequestPart> results) {
StatementRequest request = new StatementRequest();
request.setGroupId(groupingSdf01Id);
request.setAccountCreationResults(results);
log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request);
}
/** /**
* Заполняет поля relationId и companyId из соответствующей записи Relation * Заполняет поля relationId и companyId из соответствующей записи Relation

View file

@ -16,6 +16,10 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter; import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
@ -24,7 +28,9 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.SdfTable;
import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction; import ru.spcex.platform.imdg.api.ImdgTransaction;
@ -34,6 +40,8 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@ -61,9 +69,9 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
IMessageResolver messageResolver, IMessageResolver messageResolver,
RequestHelper requestHelper, RequestHelper requestHelper,
@Qualifier("clearingAccountNewRequestValidator") @Qualifier("clearingAccountNewRequestValidator")
Function<ClearingAccountNewRequest, IValidator> clearingAccountNewRequestValidator, Function<ClearingAccountNewRequest, IValidator> clearingAccountNewRequestValidator,
@Qualifier("clearingAccountUpdateRequestValidator") @Qualifier("clearingAccountUpdateRequestValidator")
Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator) { Function<ClearingAccountUpdateRequest, IValidator> clearingAccountUpdateRequestValidator) {
super(kafkaQueue, kafkaResponseQueue); super(kafkaQueue, kafkaResponseQueue);
this.kafkaSender = kafkaSender; this.kafkaSender = kafkaSender;
this.accountService = accountService; this.accountService = accountService;
@ -85,6 +93,10 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
callback(ClearingAccountUpdateRequest.class) callback(ClearingAccountUpdateRequest.class)
.setFunction(this::clearingAccountUpdate) .setFunction(this::clearingAccountUpdate)
.forDestination(Consts.DESTINATION_CLEARING_ACCOUNT_UPDATE, callbacks::put); .forDestination(Consts.DESTINATION_CLEARING_ACCOUNT_UPDATE, callbacks::put);
callback(AccountSdf01Request.class)
.setFunction(this::accountNewSdf01)
.forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put);
init(); init();
} }
@ -174,4 +186,101 @@ public class ClearingAccountService extends QueueConsumer implements Initializin
return null; return null;
} }
public RequestInfoUpdate accountNewSdf01(BaseRequest<AccountSdf01Request> userRequest) {
log.debug("AccountSdf01Request received, id={}", userRequest.getId());
AccountSdf01Request req = userRequest.getRequestPayload();
List<AccountSdfToStatementRequestPart> accountToStatement = new ArrayList<>();
ImdgTransaction imdgTransaction = imdgProvider.newTransaction();
List<TradingClearingRegistryNewRequest> toTCRRequests = new ArrayList<>();
boolean txOk = false;
imdgTransaction.beginTransaction();
try {
accountsLoop:
for (AccountSdfRequestPart accountReq : req.getAccounts()) {
Instant now = Instant.now();
Account account = new Account();
account.setAccount(accountReq.getAccount());
account.setAccountType(AccountType.Clrn.getKey());
account.setStatus(ServiceStatus.Active.getKey());
account.setCompanyId(accountReq.getCompanyId());
account.setCreated(now);
account.setUpdated(now);
RequestInfoUpdate requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true);
if (requestInfoUpdate != null) {
log.warn("Error fill new account from relation. {}", /*account.getId(),*/ requestInfoUpdate.getMessage());
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(AccountError.ClearingCategoryNotFound.getId()); // see accountService.fillAccountFromRelation
responsePart.setErrorText(requestInfoUpdate.getMessage());
accountToStatement.add(responsePart);
continue accountsLoop;
}
}
Long clearingAccountId = -1L;
Long accountId = -1L;
ClearingAccount clearingAccount = null;
accountId = accountImdg.insert(account);
clearingAccount = new ClearingAccount();
clearingAccount.setCompanyId(accountReq.getCompanyId());
clearingAccount.setAccountId(accountId);
clearingAccount.setClearingAccountType(accountReq.getAccountType());
clearingAccountId = clearingAccountImdg.insert(clearingAccount);
log.trace("New account {}, clearingAccount {} was created.", accountId, clearingAccountId);
{
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest();
request.setMoneyAccountId(accountId);
request.setCompanyId(clearingAccount.getCompanyId());
toTCRRequests.add(request);
}
{
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(accountReq.getSdfId());
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
accountToStatement.add(responsePart);
}
}
txOk = true;
} finally {
if (txOk) {
imdgTransaction.commitTransaction();
} else {
log.debug("failed insert, new clearing accounts. Request id={}", userRequest.getId());
imdgTransaction.rollbackTransaction();
}
}
if (txOk) {
log.debug("Sending {} messages of TradingClearingRegistryNewRequest", toTCRRequests.size());
for (TradingClearingRegistryNewRequest tcrReq : toTCRRequests) {
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW,
LogFormatter.toStringWrapper(tcrReq));
Long kafkaId = kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, tcrReq);
log.trace("successfully send request {} to kafka: new clearing account MoneyAccountId {}, DepoAccountId {}",
kafkaId, tcrReq.getMoneyAccountId(), tcrReq.getDepoAccountId());
}
}
sendStatementRequestBack(req.getGroupingSdf01Id(), accountToStatement);
log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size());
return null;
}
public void sendStatementRequestBack(Long groupingSdf01Id, List<AccountSdfToStatementRequestPart> results) {
StatementRequest request = new StatementRequest();
request.setGroupId(groupingSdf01Id);
request.setAccountCreationResults(results);
request.setTable(SdfTable.SDF_01); // по нему запрос получили
log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request);
}
} }

View file

@ -20,10 +20,11 @@ import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts; 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.ClientCodeNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequest; import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest;
import ru.spcex.clearing.platform.messaging.serialization.LogFormatter; import ru.spcex.clearing.platform.messaging.serialization.LogFormatter;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
@ -34,8 +35,6 @@ import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; 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.IMessageResolver; import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
@ -64,6 +63,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
private final Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator; private final Function<TradingClearingRegistryUpdateRequest, IValidator> tradingClearingRegistryUpdateRequestValidator;
private final RequestHelper requestHelper; private final RequestHelper requestHelper;
private final Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryNewRequestValidator; private final Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryNewRequestValidator;
private final Function<TradingClearingRegistryNewRequest, IValidator> tradingClearingRegistryAutoNewRequestValidator;
private final Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator; private final Function<CommonIdRequest, IValidator> tradingClearingRegistryBlockRequestValidator;
private final IMessageResolver messageResolver; private final IMessageResolver messageResolver;
@ -90,7 +90,6 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
this.validationHelper = validationHelper; this.validationHelper = validationHelper;
this.userRoleVerification = userRoleVerification; this.userRoleVerification = userRoleVerification;
this.requestHelper = requestHelper; this.requestHelper = requestHelper;
this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator;
this.tradingClearingRegistryImdg = imdgProvider.getImdg( this.tradingClearingRegistryImdg = imdgProvider.getImdg(
IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
); );
@ -100,6 +99,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator;
this.tradingClearingRegistryAutoNewRequestValidator = tradingClearingRegistryNewRequestValidator; // без relation.
this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator;
this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator; this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator;
this.messageResolver = messageResolver; this.messageResolver = messageResolver;
@ -127,7 +128,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate; if (requestInfoUpdate != null) return requestInfoUpdate;
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryNewRequestValidator); requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryAutoNewRequestValidator);
if (requestInfoUpdate != null) return requestInfoUpdate; if (requestInfoUpdate != null) return requestInfoUpdate;
TradingClearingRegistryNewRequest req = userRequest.getRequestPayload(); TradingClearingRegistryNewRequest req = userRequest.getRequestPayload();
@ -162,64 +163,6 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
req.getCompanyId()); req.getCompanyId());
} }
} }
Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", req.getCompanyId()));
if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) {
TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (registry != null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.getId());
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
} else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(relation.getService())) {
if (AccountType.Info.equalsByKey(accountMain.getStatus())) {
TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of(
"companyId", req.getCompanyId(),
"tradingClearingRegistryType", TradingClearingRegistryPurpose.M.getKey()
));
if (registry != null) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.getId());
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
} else if (AccountType.Clrn.equalsByKey(accountMain.getStatus())) {
ImdgPredicateBuilder imdgPredicateBuilder = tradingClearingRegistryImdg.predicateBuilder();
ImdgPredicate predicate = imdgPredicateBuilder.and(
imdgPredicateBuilder.equals("companyId", req.getCompanyId()),
imdgPredicateBuilder.or(
imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.M.getKey()),
imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.C.getKey())
)
);
Collection<TradingClearingRegistry> registry = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(predicate);
if (!registry.isEmpty()) {
return requestHelper.makeErrorResponse(userRequest,
AccountError.TradingClearingRegistryAlreadyExist,
req.getCompanyId(),
registry.iterator().next().getId());
}
DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId()));
if (depoAccountForCheck == null) {
return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId());
}
} else if (AccountType.Depo.equalsByKey(accountMain.getStatus())) {
InformationAccount infoAccountForCheck = informationAccountImdg.getSingleObjectByFieldValues(
Map.of("companyId", req.getCompanyId())
);
ClearingAccount clearingAccountForCheck = clearingAccountImdg.getSingleObjectByFieldValues(
Map.of("companyId", req.getCompanyId())
);
if (infoAccountForCheck == null && clearingAccountForCheck == null)
return requestHelper.makeErrorResponse(userRequest, AccountError.MoneyAccountNotFound, req.getCompanyId());
}
}
List<String> activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); List<String> activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey());
String status = null; String status = null;
@ -425,24 +368,18 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini
* clearing-service сообщение на открытие клиринговых регистров; * clearing-service сообщение на открытие клиринговых регистров;
*/ */
protected void sendNotificationToClearingSvc(TradingClearingRegistry tradingClearingRegistry) { protected void sendNotificationToClearingSvc(TradingClearingRegistry tradingClearingRegistry) {
TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); CreateRegistryRequest request = new CreateRegistryRequest();
request.setTradingClearingRegistryType(tradingClearingRegistry.getTradingClearingRegistryType());
request.setCompanyId(tradingClearingRegistry.getCompanyId()); request.setCompanyId(tradingClearingRegistry.getCompanyId());
request.setMoneyAccountId(tradingClearingRegistry.getMoneyAccountId()); log.debug("Send message to kafka \"{}\": {}", Consts.REGISTRY_NEW, LogFormatter.toStringWrapper(request));
request.setDepoAccountId(tradingClearingRegistry.getDepoAccountId()); kafkaSender.sendRequestToQueue(Consts.REGISTRY_NEW, request);
request.setStatus(tradingClearingRegistry.getStatus());
log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, LogFormatter.toStringWrapper(request));
kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request);
} }
/** /**
* todo report-service сообщение на формирование уведомления о создании нового ТКР * report-service сообщение на формирование уведомления о создании нового ТКР
*/ */
protected void sendNotificationToReportSvc(TradingClearingRegistry tradingClearingRegistry) { protected void sendNotificationToReportSvc(TradingClearingRegistry tradingClearingRegistry) {
log.debug("Todo report destination: new TCR (не реализовано)"); NotificationRequest request = new NotificationRequest();
// ReportRequest request = new ReportRequest(); request.setConsumerId(tradingClearingRegistry.getCompanyId());
// request.setReportId(ReportType.NEW_TRADING_CLEARING_REGISTRY); log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_NOTIFICATION_NTCR, LogFormatter.toStringWrapper(request));
// request.setTradingClearingRegistryId(tradingClearingRegistry.getId()); kafkaSender.sendRequestToQueue(Consts.CREATE_NOTIFICATION_NTCR, request);
// log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_REPORT_FOR_TCR, LogFormatter.toStringWrapper(request));
// kafkaSender.sendRequestToQueue(Consts.CREATE_REPORT_FOR_TCR, request);
} }
} }

View file

@ -70,7 +70,6 @@ class AccountServiceTest {
public static final MatcherFactory.Matcher<Account> ACCOUNT_MATCHER = usingIgnoringFieldsComparator(); public static final MatcherFactory.Matcher<Account> ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
public static final MatcherFactory.Matcher<RequestInfo> REQUEST_INFO_MATCHER_MATCHER = usingIgnoringFieldsComparator("created"); public static final MatcherFactory.Matcher<RequestInfo> REQUEST_INFO_MATCHER_MATCHER = usingIgnoringFieldsComparator("created");
private static final int PARTITION = 0; private static final int PARTITION = 0;
private static final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01;
private static final String account = "123456789123"; private static final String account = "123456789123";
private static final Long companyId = 0L; private static final Long companyId = 0L;
private static final Long relationId = 0L; private static final Long relationId = 0L;
@ -247,76 +246,4 @@ class AccountServiceTest {
accountImdg.delete(resultBlock); accountImdg.delete(resultBlock);
} }
/**
* {@link AccountService#accountNewSdf01(BaseRequest)}<br>
* Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link AccountSdf01Request}:<br>
* {@link AccountSdfRequestPart#setSdfId} - текущий Id<br>
* {@link AccountSdfRequestPart#setAccount} - 123456789123<br>
* {@link AccountSdfRequestPart#setCompanyId} - текущий Id<br>
* {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id<br>
* {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)<br>
*/
@Test
void accountSdf01New() throws InterruptedException {
//ARRANGE
Long firstID = currentID.getAndIncrement();
Long secondID = currentID.getAndIncrement();
AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
accountSdfRequestPart.setSdfId(firstID);
accountSdfRequestPart.setAccount(account);
accountSdfRequestPart.setCompanyId(firstID);
AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
accountSdf01Request.setGroupingSdf01Id(firstID);
accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
BaseRequest<AccountSdf01Request> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(accountSdf01Request);
baseNewRequest.setId(firstID);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(firstID);
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
List<AccountSdfToStatementRequestPart> accountToStatement = Collections.singletonList(responsePart);
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(firstID);
statementRequest.setAccountCreationResults(accountToStatement);
BaseRequest<Object> baseRequest = new BaseRequest<>();
baseRequest.setId(secondID);
baseRequest.setActionType(ActionType.SYSTEM);
baseRequest.setRequestPayload(statementRequest);
Account predictableAccount = new Account();
predictableAccount.setAccount(account);
predictableAccount.setCompanyId(firstID);
RequestInfo predictableRequestInfo = new RequestInfo();
predictableRequestInfo.setId(secondID);
predictableRequestInfo.setStatus(Status.Processing);
//KAFKA
addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(2))
.send(producerRecord.capture());
//todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError
ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
//ASSERT
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account));
predictableAccount.setId(accountResult.getId());
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
accountImdg.delete(accountResult);
}
} }

View file

@ -1,5 +1,7 @@
package ru.spcex.clearing.account.service; package ru.spcex.clearing.account.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.MockConsumer; import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer; import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.Producer;
@ -26,23 +28,35 @@ import ru.spcex.clearing.account.config.validation.ClearingAccountValidationConf
import ru.spcex.clearing.account.config.validation.ValidationConfig; import ru.spcex.clearing.account.config.validation.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory; import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.test.TestObjectCreator; import ru.spcex.clearing.test.TestObjectCreator;
import ru.spcex.clearing.test.config.ImdgTestConfig; import ru.spcex.clearing.test.config.ImdgTestConfig;
import ru.spcex.clearing.test.config.KafkaTestConfig; import ru.spcex.clearing.test.config.KafkaTestConfig;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.test.TestUtils.*; import static ru.spcex.clearing.test.TestUtils.*;
import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { @ContextConfiguration(classes = {
@ -224,4 +238,77 @@ class ClearingAccountServiceTest {
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount); ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
} }
// /**
// * {@link ClearingAccountService#accountNewSdf01(BaseRequest)}<br>
// * Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.<br>
// * Входной запрос {@link AccountSdf01Request}:<br>
// * {@link AccountSdfRequestPart#setSdfId} - текущий Id<br>
// * {@link AccountSdfRequestPart#setAccount} - 123456789123<br>
// * {@link AccountSdfRequestPart#setCompanyId} - текущий Id<br>
// * {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id<br>
// * {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)<br>
// */
// @Test
// void accountSdf01New() throws InterruptedException {
// //ARRANGE
// Long firstID = currentID.getAndIncrement();
// Long secondID = currentID.getAndIncrement();
// AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
// accountSdfRequestPart.setSdfId(firstID);
// accountSdfRequestPart.setAccount(account);
// accountSdfRequestPart.setCompanyId(firstID);
// AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
// accountSdf01Request.setGroupingSdf01Id(firstID);
// accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
// BaseRequest<AccountSdf01Request> baseNewRequest = new BaseRequest<>();
// baseNewRequest.setRequestPayload(accountSdf01Request);
// baseNewRequest.setId(firstID);
// baseNewRequest.setActionType(ActionType.NEW);
// String jsonBaseNewRequest;
// ObjectMapper objectMapper = new ObjectMapper();
// try {
// jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
// } catch (JsonProcessingException e) {
// throw new RuntimeException(e);
// }
//
// AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
// responsePart.setSdfId(firstID);
// responsePart.setErrorCode(null);
// responsePart.setErrorText(null);
// List<AccountSdfToStatementRequestPart> accountToStatement = Collections.singletonList(responsePart);
// StatementRequest statementRequest = new StatementRequest();
// statementRequest.setGroupId(firstID);
// statementRequest.setAccountCreationResults(accountToStatement);
//
// BaseRequest<Object> baseRequest = new BaseRequest<>();
// baseRequest.setId(secondID);
// baseRequest.setActionType(ActionType.SYSTEM);
// baseRequest.setRequestPayload(statementRequest);
//
// Account predictableAccount = new Account();
// predictableAccount.setAccount(account);
// predictableAccount.setCompanyId(firstID);
//
// RequestInfo predictableRequestInfo = new RequestInfo();
// predictableRequestInfo.setId(secondID);
// predictableRequestInfo.setStatus(Status.Processing);
//
// //KAFKA
// final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01;
// addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest);
//
// //waiting for kafka producer send message (finale event)
// verify(producer, timeout(30_000L).times(2))
// .send(producerRecord.capture());
// //todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError
//
// ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
//
// //ASSERT
// Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account));
// predictableAccount.setId(accountResult.getId());
// ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
// accountImdg.delete(accountResult);
// }
} }

View file

@ -1,15 +1,15 @@
package ru.spcex.clearing.service; package ru.spcex.clearing.service;
public class SpecifUtil { public class SpecifUtil {
public static String[] splitPaymentPurpose(String paymentPurpose) { public static String[] split5SegmentsBy35Symbols(String str) {
if (paymentPurpose == null || paymentPurpose.length() < 1) return new String[0]; if (str == null || str.length() < 1) return new String[0];
int specifSize = divisionRoundUp(paymentPurpose.length(), 35); int size = divisionRoundUp(str.length(), 35);
specifSize = Math.min(specifSize, 6); size = Math.min(size, 6);
String[] res = new String[specifSize]; String[] res = new String[size];
for (int i = 0; i < res.length; i++) { for (int i = 0; i < res.length; i++) {
int startIndex = i * 35; int startIndex = i * 35;
int endIndex = Math.min(35 * (i + 1), paymentPurpose.length()); int endIndex = Math.min(35 * (i + 1), str.length());
res[i] = paymentPurpose.substring(startIndex, endIndex); res[i] = str.substring(startIndex, endIndex);
} }
return res; return res;
} }

View file

@ -68,11 +68,13 @@ public class StatementService extends QueueConsumer implements InitializingBean
} }
private void process(BaseRequest<StatementRequest> systemRequest) { private void process(BaseRequest<StatementRequest> systemRequest) {
log.debug("Receiving StatementRequest id={}", systemRequest.getId());
StatementRequest statementRequest = systemRequest.getRequestPayload(); StatementRequest statementRequest = systemRequest.getRequestPayload();
SdfTable table = statementRequest.getTable(); SdfTable table = statementRequest.getTable();
Optional<Long> completePairKey = saveRequest(statementRequest); Optional<Long> completePairKey = saveRequest(statementRequest);
if (completePairKey.isPresent()) { if (completePairKey.isPresent()) {
boolean doSomeone = false;
if (List.of(SdfTable.SDF_01, SdfTable.SDF_57).contains(table)) { if (List.of(SdfTable.SDF_01, SdfTable.SDF_57).contains(table)) {
{ {
//всегда сначала обработаем sdf57 //всегда сначала обработаем sdf57
@ -86,6 +88,7 @@ public class StatementService extends QueueConsumer implements InitializingBean
ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest();
kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn); kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn);
pairOfSdfRequest.remove(key); pairOfSdfRequest.remove(key);
doSomeone = true;
} }
} else if (List.of(SdfTable.SDF_08, SdfTable.SDF_04).contains(table)) { } else if (List.of(SdfTable.SDF_08, SdfTable.SDF_04).contains(table)) {
if (table == SdfTable.SDF_08) { if (table == SdfTable.SDF_08) {
@ -94,6 +97,7 @@ public class StatementService extends QueueConsumer implements InitializingBean
Pair<StatementRequest, StatementRequest> pair = pairOfSdfRequest.get(key); Pair<StatementRequest, StatementRequest> pair = pairOfSdfRequest.get(key);
processSdf08(pair.getFirst()); processSdf08(pair.getFirst());
pairOfSdfRequest.remove(key); pairOfSdfRequest.remove(key);
doSomeone = true;
} }
} else if (table == SdfTable.SDF_04) { } else if (table == SdfTable.SDF_04) {
{ {
@ -101,9 +105,14 @@ public class StatementService extends QueueConsumer implements InitializingBean
Pair<StatementRequest, StatementRequest> pair = pairOfSdfRequest.get(key); Pair<StatementRequest, StatementRequest> pair = pairOfSdfRequest.get(key);
processSdf04(pair.getFirst()); processSdf04(pair.getFirst());
pairOfSdfRequest.remove(key); pairOfSdfRequest.remove(key);
doSomeone = true;
} }
} }
} }
if (!doSomeone) {
log.warn("No operation for request.id={}; statementRequest GroupId={}, table={}",
systemRequest.getId(), statementRequest.getGroupId(), statementRequest.getTable());
}
} }
} }

View file

@ -22,8 +22,11 @@ import java.time.format.DateTimeFormatter;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
public class PaymentInstructionBuilderFinalMkr { /**
private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderFinalMkr.class); * Builder для кейса итоговой сессии МКР, 7 шаг, кейс - по сделкам
*/
public class PaymentInstructionBuilderFinalMkrDeals {
private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderFinalMkrDeals.class);
private Registry cm_t; private Registry cm_t;
@ -40,38 +43,38 @@ public class PaymentInstructionBuilderFinalMkr {
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy"); private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
public static PaymentInstructionBuilderFinalMkr builder(ImdgProvider imdgProvider) { public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderFinalMkr(imdgProvider); return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider);
} }
private PaymentInstructionBuilderFinalMkr(ImdgProvider imdgProvider) { private PaymentInstructionBuilderFinalMkrDeals(ImdgProvider imdgProvider) {
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
} }
public PaymentInstructionBuilderFinalMkr lm_t(Registry lm_t) { public PaymentInstructionBuilderFinalMkrDeals lm_t(Registry lm_t) {
this.lm_t = lm_t; this.lm_t = lm_t;
return this; return this;
} }
public PaymentInstructionBuilderFinalMkr cm_t(Registry cm_t) { public PaymentInstructionBuilderFinalMkrDeals cm_t(Registry cm_t) {
this.cm_t = cm_t; this.cm_t = cm_t;
return this; return this;
} }
public PaymentInstructionBuilderFinalMkr tranAcc(Account account) { public PaymentInstructionBuilderFinalMkrDeals tranAcc(Account account) {
this.tranAccount = account; this.tranAccount = account;
return this; return this;
} }
public PaymentInstructionBuilderFinalMkr sessionId(Long sessionId) { public PaymentInstructionBuilderFinalMkrDeals sessionId(Long sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
return this; return this;
} }
public PaymentInstructionBuilderFinalMkr amount(BigDecimal amount) { public PaymentInstructionBuilderFinalMkrDeals amount(BigDecimal amount) {
this.amount = amount; this.amount = amount;
return this; return this;
} }
@ -83,30 +86,38 @@ public class PaymentInstructionBuilderFinalMkr {
Instant now = Instant.now(); Instant now = Instant.now();
String symbolPRC = selectSymbolValue(Sender.Prc.getId(), CompanySymbol.BIC); // 2 "НКО АО ПРЦ" String symbolPRC = selectSymbolValue(Sender.Prc.getId(), CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
String tranBic;
{ // record 1 { // record 1
payment1 = new PaymentInstruction(); payment1 = new PaymentInstruction();
payment1.setCreated(now); payment1.setCreated(now);
payment1.setClearingDate(TimeUtil.toLocalDate(now)); payment1.setClearingDate(TimeUtil.toLocalDate(now));
payment1.setSenderId(lm_t.getCompanyId()); payment1.setSenderId(lm_t.getCompanyId());
payment1.setAddresseeId(Sender.One.getId()); payment1.setAddresseeId(Sender.One.getId());
String symbol1 = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC); {
if (symbol1 == null) { tranBic = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC);
log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId()); if (tranBic == null) {
} else { log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId());
payment1.setAdresseeBic(symbol1); } else {
payment1.setAdresseeBic(tranBic);
}
} }
{
Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId()); // 2 "НКО АО ПРЦ" Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId()); // 2 "НКО АО ПРЦ"
String companyPRCName = null; if (companyPRC == null) {
if (companyPRC == null) { log.warn("Company.id={} not found", Sender.Prc.getId());
log.warn("Company.id={} not found", Sender.Prc.getId()); } else {
} else { payment1.setPayeeBankName(companyPRC.getShortName());
companyPRCName = companyPRC.getShortName(); payment1.setAddresseeBankName(companyPRC.getShortName());
}
}
{
String payeeBic = selectSymbolValue(payment1.getSenderId(), CompanySymbol.BIC);
if (payeeBic == null) {
log.warn("payeeBic by senderId={} not found", payment1.getSenderId());
} else {
payment1.setPayeeBic(payeeBic);
}
} }
payment1.setPayeeBankName(companyPRCName);
payment1.setPayeeBic(symbolPRC);
payment1.setAddresseeBankName(companyPRCName);
payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate())); payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
@ -132,11 +143,8 @@ public class PaymentInstructionBuilderFinalMkr {
payment1.setCredit_csAccount(null); payment1.setCredit_csAccount(null);
{ {
Account acc1 = selectAccount(payment1.getAddresseeId(), AccountType.Corr, Status.Active, Allowed.ALLOWED); payment1.setDebitLeg_accountId(tranAccount.getId());
if (acc1 != null) { payment1.setDebitLeg_account(tranAccount.getAccount());
payment1.setDebitLeg_accountId(acc1.getId());
payment1.setDebitLeg_account(acc1.getAccount());
}
} }
payment1.setDebit_csAccount(null); payment1.setDebit_csAccount(null);
@ -144,6 +152,11 @@ public class PaymentInstructionBuilderFinalMkr {
payment1.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey()); payment1.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey());
payment1.setTransactionStatus(TransactionStatus.stld.getKey()); payment1.setTransactionStatus(TransactionStatus.stld.getKey());
payment1.setDocumentNumber(nextDocumentNumber(lm_t, payment1)); payment1.setDocumentNumber(nextDocumentNumber(lm_t, payment1));
payment1.setCreditLeg_direction(InOutDirection.out.getKey());
payment1.setDebitLeg_direction(InOutDirection.in.getKey());
payment1.setCreditLeg_securityId(lm_t.getSecurityId());
payment1.setDebitLeg_securityId(lm_t.getSecurityId());
payment1.setSessionId(sessionId);
} }
//**************** //****************
@ -152,7 +165,7 @@ public class PaymentInstructionBuilderFinalMkr {
payment2.setCreated(now); payment2.setCreated(now);
payment2.setClearingDate(TimeUtil.toLocalDate(now)); payment2.setClearingDate(TimeUtil.toLocalDate(now));
payment2.setSenderId(Sender.One.getId()); // СПВБ payment2.setSenderId(Sender.One.getId()); // СПВБ
payment2.setAddresseeId(lm_t.getCompanyId()); payment2.setAddresseeId(cm_t.getCompanyId());
String symbol2 = selectSymbolValue(payment2.getAddresseeId(), CompanySymbol.BIC); String symbol2 = selectSymbolValue(payment2.getAddresseeId(), CompanySymbol.BIC);
if (symbol2 == null) { if (symbol2 == null) {
log.warn("CompanySymbols BIC not found for companyId={}", payment2.getAddresseeId()); log.warn("CompanySymbols BIC not found for companyId={}", payment2.getAddresseeId());
@ -166,7 +179,7 @@ public class PaymentInstructionBuilderFinalMkr {
payment2.setPayeeBankName(companyPRC.getShortName()); payment2.setPayeeBankName(companyPRC.getShortName());
payment2.setAddresseeBankName(companyPRC.getShortName()); payment2.setAddresseeBankName(companyPRC.getShortName());
} }
payment2.setPayeeBic(symbolPRC); payment2.setAdresseeBic(tranBic);
payment2.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate())); payment2.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
payment2.setPaymentPurpose("Размещение депозита " + lm_t.getContract()); payment2.setPaymentPurpose("Размещение депозита " + lm_t.getContract());
payment2.setSettlementDate(lm_t.getSettlementDate()); payment2.setSettlementDate(lm_t.getSettlementDate());
@ -189,6 +202,13 @@ public class PaymentInstructionBuilderFinalMkr {
payment2.setDebit_csAccount(null); payment2.setDebit_csAccount(null);
payment2.setTransactionStatus(TransactionStatus.stld.getKey()); payment2.setTransactionStatus(TransactionStatus.stld.getKey());
payment2.setDocumentNumber(nextDocumentNumber(cm_t, payment2)); payment2.setDocumentNumber(nextDocumentNumber(cm_t, payment2));
payment2.setCreditLeg_direction(InOutDirection.out.getKey());
payment2.setDebitLeg_direction(InOutDirection.in.getKey());
payment2.setCreditLeg_currencyCode(CurrencyCode.RUB.getKey());
payment2.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey());
payment2.setCreditLeg_securityId(lm_t.getSecurityId());
payment2.setDebitLeg_securityId(lm_t.getSecurityId());
payment2.setSessionId(sessionId);
} }
return new Pair<>(payment1, payment2); return new Pair<>(payment1, payment2);
} }
@ -234,7 +254,7 @@ public class PaymentInstructionBuilderFinalMkr {
Account account = accountImdg.getSingleObjectByFieldValues(Map.of( Account account = accountImdg.getSingleObjectByFieldValues(Map.of(
"companyId", companyId, "companyId", companyId,
"accountType", accountType.getKey(), "accountType", accountType.getKey(),
"accountStatus", accountStatus.getKey(), "status", accountStatus.getKey(),
"processingSign", processingSign.getKey() "processingSign", processingSign.getKey()
)); ));
if (account == null) { if (account == null) {

View file

@ -77,7 +77,7 @@ public class Sdf03Builder {
sDf03.setPay_val("RUR"); sDf03.setPay_val("RUR");
sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : null); sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : null);
//37 sp_code varchar(2) Код назначения платежа //37 sp_code varchar(2) Код назначения платежа
String[] splitPaymentPurpose = SpecifUtil.splitPaymentPurpose(paymentInstruction.getPaymentPurpose()); String[] splitPaymentPurpose = SpecifUtil.split5SegmentsBy35Symbols(paymentInstruction.getPaymentPurpose());
for (int i = 0; i < splitPaymentPurpose.length; i++) { for (int i = 0; i < splitPaymentPurpose.length; i++) {
String specif = splitPaymentPurpose[i]; String specif = splitPaymentPurpose[i];
if (i == 0) { if (i == 0) {

View file

@ -111,8 +111,12 @@ public class Sdf01Executor extends AbstractExecutor<SDf01> {
//на данном шаге company существует -> getId ok //на данном шаге company существует -> getId ok
//формируем пакетный запрос на добавление account //формируем пакетный запрос на добавление account
//ответ придет в этот же метод, process //ответ придет в этот же метод, process
result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); if (company == null) {
log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); log.warn("account {} for sdf01.id={} not found. Can not send request for creation, cause company not found too", sdf01.getAccount(), sdf01.getId());
} else {
result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), sdf01.getAcc_type(), company.getId()));
log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId());
}
continue; continue;
} else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { } else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId());
@ -182,11 +186,11 @@ public class Sdf01Executor extends AbstractExecutor<SDf01> {
return stmt; return stmt;
} }
private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, Long companyId) { private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, String accountType, Long companyId) {
AccountSdfRequestPart req = new AccountSdfRequestPart(); AccountSdfRequestPart req = new AccountSdfRequestPart();
req.setAccount(account); req.setAccount(account);
req.setCompanyId(companyId); req.setCompanyId(companyId);
req.setAccountType(AccountType.Clrn.getKey()); req.setAccountType(accountType);
req.setSdfId(sdf01Id); req.setSdfId(sdf01Id);
return req; return req;
} }

View file

@ -99,8 +99,14 @@ public class Sdf08Executor extends AbstractExecutor<SDf08> {
Account account = validator.getStored(ValidationStored.Sdf08Account); Account account = validator.getStored(ValidationStored.Sdf08Account);
if (statementRequest.getAccountCreationResults().size() == 0 if (statementRequest.getAccountCreationResults().size() == 0
&& ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { && ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
result.getAccountRequests().add(createAccountRequestPart(sdf08.getId(), sdf08.getDepoCode(), account.getCompanyId())); Company company = validator.getStored(ValidationStored.Sdf08Company);
log.info("account {} for sdf08.id={} not found - send request for creation", sdf08.getDepoCode(), sdf08.getId()); Long companyId = company == null ? null : company.getId(); // account == null сегда, т.к. кейс AccountNotPresent
if (companyId == null) {
log.warn("account {} for sdf08.id={} not found. Can not send request for creation, cause company not found too", sdf08.getDepoCode(), sdf08.getId());
} else {
result.getAccountRequests().add(createAccountRequestPart(sdf08.getId(), sdf08.getDepoCode(), companyId));
log.info("account {} for sdf08.id={} not found - send request for creation", sdf08.getDepoCode(), sdf08.getId());
}
continue; continue;
} else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { } else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf08.getId()); log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf08.getId());

View file

@ -94,8 +94,12 @@ public class SdfLegacyExecutor extends AbstractExecutor<SDf01> {
//на данном шаге company существует -> getId ok //на данном шаге company существует -> getId ok
//формируем пакетный запрос на добавление account //формируем пакетный запрос на добавление account
//ответ придет в этот же метод, process //ответ придет в этот же метод, process
result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); if (company == null) {
log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); log.warn("account {} for sdf01.id={} not found. Can not send request for creation, cause company not found too", sdf01.getAccount(), sdf01.getId());
} else {
result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId()));
log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId());
}
continue; continue;
} else if (ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { } else if (ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId());

View file

@ -40,7 +40,8 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
private final InclusionObligations inclusionObligations; private final InclusionObligations inclusionObligations;
private final InspectionObligations inspectionObligations; private final InspectionObligations inspectionObligations;
private final FormingRegistersOnOS formingRegistersOnOS; private final FormingRegistersOnOS formingRegistersOnOS;
private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction; private final FormingPaymentInstructionReturnMkr formingPaymentInstructionReturn;
private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDeals;
private final UnlockResources unlockResources; private final UnlockResources unlockResources;
private final FinishingSession finishingSession; private final FinishingSession finishingSession;
private final EndStageNotification endStageNotification; private final EndStageNotification endStageNotification;
@ -58,7 +59,7 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
ObligationAdmission obligationsAdmission, ObligationAdmission obligationsAdmission,
InclusionObligations inclusionObligations, InclusionObligations inclusionObligations,
FormingRegistersOnOS formingRegistersOnOS, FormingRegistersOnOS formingRegistersOnOS,
FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction, FormingPaymentInstructionReturnMkr formingPaymentInstructionReturn, FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDeals,
UnlockResources unlockResources, UnlockResources unlockResources,
FinishingSession finishingSession, FinishingSession finishingSession,
EndStageNotification endStageNotification, EndStageNotification endStageNotification,
@ -72,7 +73,8 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
this.obligationsAdmission = obligationsAdmission; this.obligationsAdmission = obligationsAdmission;
this.inclusionObligations = inclusionObligations; this.inclusionObligations = inclusionObligations;
this.formingRegistersOnOS = formingRegistersOnOS; this.formingRegistersOnOS = formingRegistersOnOS;
this.formingPaymentInstruction = formingPaymentInstruction; this.formingPaymentInstructionReturn = formingPaymentInstructionReturn;
this.formingPaymentInstructionDeals = formingPaymentInstructionDeals;
this.unlockResources = unlockResources; this.unlockResources = unlockResources;
this.finishingSession = finishingSession; this.finishingSession = finishingSession;
this.endStageNotification = endStageNotification; this.endStageNotification = endStageNotification;
@ -170,12 +172,22 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
//stage 6 //stage 6
runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection<Registry> runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection<Registry>
//stage 7 //stage 7
StageResult<Collection<PaymentInstruction>> paymentResult = null;
StageResult<Collection<PaymentInstruction>> returnsPayment = null;
{ {
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload(); FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
payload.setSessionId(currSession.getId()); payload.setSessionId(currSession.getId());
//stage 7 //stage 7
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstruction); returnsPayment = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionReturn);
}
StageResult<Collection<PaymentInstruction>> paymentResult = null;
{
FormingPaymentInstructionDealsMkrPayload payload = new FormingPaymentInstructionDealsMkrPayload();
payload.setSessionId(currSession.getId());
payload.setPaymentInstructionReturns(returnsPayment.getStageResult());
//stage 7
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionDeals);
} }
if (paymentResult != null && paymentResult.getStageResult().isEmpty()) { if (paymentResult != null && paymentResult.getStageResult().isEmpty()) {
runStage(TaskType.FormingPaymentInstruction, balanceRevise); runStage(TaskType.FormingPaymentInstruction, balanceRevise);

View file

@ -17,13 +17,13 @@ import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkr; import ru.spcex.clearing.service.SpecifUtil;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkrDeals;
import ru.spcex.clearing.session.stage.ISessionStage; import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult; import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task; import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload; import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionDealsMkrPayload;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgId;
@ -43,9 +43,10 @@ import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static ru.spcex.platform.enumeration.RegistryTradingParams.CM_T; import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
import static ru.spcex.platform.enumeration.RegistryTradingParams.LM_T; import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service @Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@ -81,10 +82,10 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
@Override @Override
public StageResult<?> submit(Task<?> task) { public StageResult<?> submit(Task<?> task) {
FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData(); FormingPaymentInstructionDealsMkrPayload payload = (FormingPaymentInstructionDealsMkrPayload) task.getData();
switch (task.getTaskType()) { switch (task.getTaskType()) {
case FormingPaymentInstruction -> { case FormingPaymentInstruction -> {
return formingPaymentInstructions(payload.getSessionId()); return formingPaymentInstructions(payload.getSessionId(), payload.getPaymentInstructionReturns());
} }
default -> { default -> {
throw new IllegalStateException("Unknown task type: " + task.getTaskType()); throw new IllegalStateException("Unknown task type: " + task.getTaskType());
@ -112,9 +113,10 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
* регистр LMAT кто переводит деньги (registry.account)<br> * регистр LMAT кто переводит деньги (registry.account)<br>
* в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет * в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет
*/ */
private StageResult<?> formingPaymentInstructions(Long sessionId) { private StageResult<?> formingPaymentInstructions(Long sessionId, Collection<PaymentInstruction> paymentInstructionReturns) {
Collection<Registry> registries = selectRegistries(); Collection<Registry> registries = selectRegistries();
log.debug("found registries.size() = {}", registries.size()); log.debug("found registries.size() = {}", registries.size());
//клиринговый счет, через который будут проводиться сделки
Account tranAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'" Account tranAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey())); .formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
if (tranAcc == null) { if (tranAcc == null) {
@ -123,6 +125,7 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
false); false);
} }
log.debug("found tranAcc.id = {}", tranAcc.getId()); log.debug("found tranAcc.id = {}", tranAcc.getId());
//группируем регистры по groupId
Map<Long, List<Registry>> groups = registries Map<Long, List<Registry>> groups = registries
.stream() .stream()
.collect(Collectors.groupingBy(Registry::getGroupId)); .collect(Collectors.groupingBy(Registry::getGroupId));
@ -135,20 +138,54 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
.filter(rgs -> equalsByRegistry(rgsCode, rgs)) .filter(rgs -> equalsByRegistry(rgsCode, rgs))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
Registry rgsCmt = findByCode.apply(CM_T); //интересуют обязательства и требования по деньгам
Registry rgsLmt = findByCode.apply(LM_T); Registry cm_t = findByCode.apply(CM_T);
if (rgsCmt == null || rgsLmt == null) { Registry lm_t = findByCode.apply(LM_T);
log.error("groupId {} cmt_t {} lm_t {} - both must be present", groupId, rgsCmt, rgsLmt); if (cm_t == null || lm_t == null) {
log.error("groupId {} cmt_t {} lm_t {} - both must be present", groupId, cm_t, lm_t);
continue; continue;
} }
log.debug("generating payment instruction for groupId {} cmt_t {} lm_t {}", {
//изменение активов - блокируем средства беред отправкой sdf'ов
Optional<Registry> amfO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_F);
Optional<Registry> payerAmtO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_T);
Optional<Registry> ambO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_B);
Optional<Registry> receiverAmtO = findRelatedAsset(cm_t.getTradingClearingRegistryId(), cm_t.getCompanyId(), AM_B);
log.debug("changing A* registers based on LM_T {} and CM_T {} found AM*F.id={}, AM*T.id={}, AM*B.id={}, AM*B.id={}",
lm_t.getId(),
cm_t.getId(),
amfO.map(Registry::getId).orElse(null),
payerAmtO.map(Registry::getId).orElse(null),
ambO.map(Registry::getId).orElse(null),
receiverAmtO.map(Registry::getId).orElse(null)
);
Instant now = Instant.now();
amfO.ifPresent(amf -> {
amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amf, now);
});
payerAmtO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
ambO.ifPresent(amb -> {
amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amb, now);
});
receiverAmtO.ifPresent(amt -> {
// у отправителя и получателя одинаково, см. в FormingPaymentInstruction
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
}
log.trace("generating payment instruction for groupId {} cmt_t {} lm_t {}",
groupId, groupId,
rgsCmt.getId(), cm_t.getId(),
rgsLmt.getId()); lm_t.getId());
Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkr Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkrDeals
.builder(imdgProvider) .builder(imdgProvider)
.cm_t(rgsCmt) .cm_t(cm_t)
.lm_t(rgsLmt) .lm_t(lm_t)
.tranAcc(tranAcc) .tranAcc(tranAcc)
.sessionId(sessionId) .sessionId(sessionId)
.build(); .build();
@ -156,29 +193,46 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
paymentInstructionImdg.insert(pmtInstr); paymentInstructionImdg.insert(pmtInstr);
allPaymentInstructions.add(pmtInstr); allPaymentInstructions.add(pmtInstr);
}); });
log.debug("generated PaymentInstructions for groupId {}: pmtInstr1.id={} pmtInstr2.id={}", log.trace("generated PaymentInstructions for groupId {}: pmtInstr1.id={} pmtInstr2.id={}",
groupId, groupId,
pmtInstrs.getFirst().getId(), pmtInstrs.getFirst().getId(),
pmtInstrs.getSecond().getId()); pmtInstrs.getSecond().getId());
} }
sendSdfs(allPaymentInstructions);
log.debug("PaymentInstructions return size {}, PaymentInstructions deals size {}. sending SDF03",
paymentInstructionReturns.size(),
allPaymentInstructions.size());
List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), allPaymentInstructions.stream()).toList();
sendSdfs(returnsAndDeals);
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true); StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
stageResult.setStageResult(allPaymentInstructions); stageResult.setStageResult(returnsAndDeals);
return stageResult; return stageResult;
} }
private void setUpdatedStoreInImdg(Registry rgs, Instant now) {
rgs.setUpdated(now);
registryImdg.update(rgs);
}
private Optional<Registry> findRelatedAsset(Long tradingClearingRegistryId, Long companyId, RegistryTradingParams rgsCode) {
ImdgPredicateBuilder rgsPrdBldr = registryImdg.predicateBuilder();
RegistryCodeSqlBuilder codeSql = RegistryCodeSqlBuilder.getInstance(rgsCode);
ImdgPredicate assetCondition = rgsPrdBldr.and(
rgsPrdBldr.equals("tradingClearingRegistryId", tradingClearingRegistryId),
rgsPrdBldr.equals("companyId", companyId),
rgsPrdBldr.sql(codeSql.build())
);
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(assetCondition));
}
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) { private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
List<SDf03> sDf03Created = new ArrayList<>(); List<SDf03> sDf03Created = new ArrayList<>();
List<SDf12> sDf12Created = new ArrayList<>();
for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { for (PaymentInstruction paymentInstruction : formedPaymentInstructions) {
Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId());
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId());
if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && if (List.of(AccountType.Corr, AccountType.Clrn, AccountType.Tran, AccountType.Anlt)
List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { .contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) {
sDf03Created.add(newSDf03(paymentInstruction)); sDf03Created.add(newSDf03(paymentInstruction));
} else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) &&
AccountType.Depo.equalsByKey(account.getAccountType())) {
sDf12Created.add(newSDf12(paymentInstruction));
} }
} }
@ -194,31 +248,6 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
exportToFileRequest.setSdfGroupId(sdf03GroupId); exportToFileRequest.setSdfGroupId(sdf03GroupId);
kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest);
} }
Long sdf12GroupId = null;
Long maxTxNumber = 1L;
if (!sDf12Created.isEmpty()) {
sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId();
ImdgPredicateBuilder predicateBuilder = sDf12Imdg.predicateBuilder();
ImdgPredicate notEmptyTransactionNum = predicateBuilder.not(predicateBuilder.equals("transaction_number", ""));
Long maxId = sDf12Imdg.aggregateLongMax("id", notEmptyTransactionNum);
if (maxId != null) {
SDf12 sDf12 = sDf12Imdg.getSingleObjectByID(maxId);
maxTxNumber = Long.parseLong(sDf12.getTransactionNumber()) + 1;
}
}
for (SDf12 sDf12 : sDf12Created) {
sDf12.setGenerationId(sdf03GroupId);
sDf12.setTransactionNumber(maxTxNumber.toString());
sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size()));
sDf12Imdg.insert(sDf12);
}
if (sdf12GroupId != null) {
SwtExporterRequest swtExporterRequest = new SwtExporterRequest();
swtExporterRequest.setType("SDF_12");
kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest);
}
} }
private SDf03 newSDf03(PaymentInstruction paymentInstruction) { private SDf03 newSDf03(PaymentInstruction paymentInstruction) {
@ -241,11 +270,24 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
senderSbankName = company.getShortName(); senderSbankName = company.getShortName();
} }
} }
sDf03.setSbanknam1(senderSbankName); String[] bnkNmeParts = SpecifUtil.split5SegmentsBy35Symbols(senderSbankName);
sDf03.setSbanknam2(senderSbankName); for (int i = 0; i < bnkNmeParts.length; i++) {
sDf03.setSbanknam3(senderSbankName); if (i == 0) {
sDf03.setSbanknam4(senderSbankName); sDf03.setSbanknam1(bnkNmeParts[i]);
sDf03.setSbanknam5(senderSbankName); }
if (i == 1) {
sDf03.setSbanknam2(bnkNmeParts[i]);
}
if (i == 2) {
sDf03.setSbanknam3(bnkNmeParts[i]);
}
if (i == 3) {
sDf03.setSbanknam4(bnkNmeParts[i]);
}
if (i == 4) {
sDf03.setSbanknam5(bnkNmeParts[i]);
}
}
sDf03.setC_acc_cred(paymentInstruction.getDebitLeg_account()); sDf03.setC_acc_cred(paymentInstruction.getDebitLeg_account());

View file

@ -0,0 +1,343 @@
package ru.spcex.clearing.session.stage.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
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.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.sdf.SDf03;
import ru.clearing.classes.statics.data.sdf.SDf12;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilder;
import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
import ru.spcex.platform.enumeration.*;
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.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.time.TimeUtil;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.*;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FormingPaymentInstructionReturnMkr implements ISessionStage {
private final Logger log = LoggerFactory.getLogger(getClass());
//todo remove (set all in single method setImdg(provider -> setImdg1();setIdGenerator();...)
private ImdgProvider imdgProvider;
private ImdgId idGenerator;
private Imdg<Registry> registryImdg;
private Imdg<PaymentInstruction> paymentInstructionImdg;
private Imdg<Security> securityImdg;
private Imdg<Account> accountImdg;
private Imdg<Company> companyImdg;
private Imdg<SDf03> sDf03Imdg;
private Imdg<SDf12> sDf12Imdg;
private KafkaSender kafkaSender;
@Autowired
public FormingPaymentInstructionReturnMkr(ImdgProvider imdgProvider,
KafkaSender kafkaSender) {
this.kafkaSender = kafkaSender;
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class);
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
}
@Override
public StageResult submit(Task<?> task) {
FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData();
switch (task.getTaskType()) {
case FormingPaymentInstruction -> {
return formingPaymentInstruction(payload.getSessionId());
}
default -> {
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
}
}
}
private StageResult formingPaymentInstruction(Long sessionId) {
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(LM_T, CM_T);
String registryCodeCondition = registryCodeSqlBuilder.build();
Collection<Registry> rgsAll = registryImdg.getCollectionObjectsBySQL(registryCodeCondition)
.stream()
.filter(rgs -> rgs.getValueDate() != null)
.filter(rgs -> rgs.getSettlementDate() != null)
.filter(rgs -> rgs.getSettlementDate().isAfter(rgs.getValueDate()))
.toList();
log.debug("LM*T and CM*T size = {}", rgsAll.size());
List<Registry> obligationsByMoney = rgsAll.stream()
.filter(registry -> equalsByRegistry(LM_T, registry))
.toList();
log.debug("changing assets by LM*T");
//изменяем активы по обязательствам по деньгам (LM_T)
for (Registry obligationByMoney : obligationsByMoney) {
String sql = String.format("tradingClearingRegistryId = %s and companyId = %s",
obligationByMoney.getTradingClearingRegistryId(), obligationByMoney.getCompanyId());
Collection<Registry> relatedRegistries = registryImdg.getCollectionObjectsBySQL(sql);
for (Registry relatedRegistry : relatedRegistries) {
if (equalsByRegistry(AM_F, relatedRegistry)) {
relatedRegistry.setBalance(safeBD(relatedRegistry.getBalance()).subtract(safeBD(obligationByMoney.getBalance())));
} else if (equalsByRegistry(AM_T, relatedRegistry)) {
relatedRegistry.setSettledDebit(safeBD(relatedRegistry.getSettledDebit()).add(safeBD(obligationByMoney.getBalance())));
} else if (equalsByRegistry(AM_B, relatedRegistry)) {
relatedRegistry.setBalance(safeBD(relatedRegistry.getBalance()).add(safeBD(obligationByMoney.getBalance())));
}
registryImdg.update(relatedRegistry);
}
}
log.debug("changing assets by CM*T");
List<Registry> requirementsByMoney = rgsAll.stream()
.filter(registry -> equalsByRegistry(CM_T, registry))
.toList();
//изменяем активы по требованиям по деньгам CM_T
for (Registry requirementByMoney : requirementsByMoney) {
String sql = String.format("tradingClearingRegistryId = %s and companyId = %s",
requirementByMoney.getTradingClearingRegistryId(), requirementByMoney.getCompanyId());
Collection<Registry> relatedRegistries = registryImdg.getCollectionObjectsBySQL(sql);
for (Registry relatedRegistry : relatedRegistries) {
if (equalsByRegistry(AM_T, relatedRegistry)) {
relatedRegistry.setSettledDebit(safeBD(relatedRegistry.getSettledDebit()).add(safeBD(requirementByMoney.getBalance())));
}
registryImdg.update(relatedRegistry);
}
}
List<PaymentInstruction> formedPaymentInstructions = new ArrayList<>();
List<Registry> allLiabilities = rgsAll
.stream()
.filter(registry -> RegistryDesignation.L.equalsByKey(registry.getRegistryDesignation()))
.toList();
//todo сортировка if needed
for (int i = 0; i < allLiabilities.size(); i++) {
Registry lm_t = allLiabilities.get(i);
if (lm_t == null) continue;
LinkedList<Registry> relatedRegistries = new LinkedList<>();
relatedRegistries.add(lm_t);
for (int j = i + 1; j < allLiabilities.size(); j++) {
Registry related = allLiabilities.get(j);
if (related == null) continue;
if (registriesOfTheSameAgents(lm_t, related)) {
relatedRegistries.add(related);
allLiabilities.set(j, null);
}
}
log.trace("LM*T.id={} return group size {}", lm_t.getId(), relatedRegistries.size());
BigDecimal sumBalance = relatedRegistries.stream().map(Registry::getBalance).reduce(BigDecimal.ZERO, BigDecimal::add);
log.trace("LM*T.id={} sumBalance={}", lm_t.getId(), sumBalance);
List<Registry> builderList = new ArrayList<>();
builderList.add(lm_t);
rgsAll.stream()
.filter(rgs -> rgs.getGroupId().equals(lm_t.getGroupId()))
.filter(rgs -> RegistryDesignation.C.equalsByKey(rgs.getRegistryDesignation()))
.findFirst()
.ifPresent(builderList::add);
PaymentInstruction paymentInstruction = createPaymentInstruction(builderList, sumBalance, sessionId);
formedPaymentInstructions.add(paymentInstruction);
paymentInstructionImdg.insert(paymentInstruction);
log.trace("LM*T.id={} created paymentInstruction.id={}", lm_t.getId(), paymentInstruction.getId());
builderList.forEach(registry -> {
registry.setPaymentId(paymentInstruction.getId());
registry.setUpdated(Instant.now());
registryImdg.update(registry);
});
}
//sdf отправляют
//sendSdfs(formedPaymentInstructions);
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult(null, true);
stageResult.setStageResult(formedPaymentInstructions);
return stageResult;
}
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
List<SDf03> sDf03Created = new ArrayList<>();
List<SDf12> sDf12Created = new ArrayList<>();
for (PaymentInstruction paymentInstruction : formedPaymentInstructions) {
Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId());
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId());
if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) &&
List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) {
sDf03Created.add(newSDf03(paymentInstruction));
} else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) &&
AccountType.Depo.equalsByKey(account.getAccountType())) {
sDf12Created.add(newSDf12(paymentInstruction));
}
}
Long sdf03GroupId = !sDf03Created.isEmpty() ? imdgProvider.getImdgIdGenerator().nextId() : null;
for (SDf03 sDf03 : sDf03Created) {
sDf03.setGenerationId(sdf03GroupId);
sDf03Imdg.insert(sDf03);
}
if (sdf03GroupId != null) {
ExportToFileRequest exportToFileRequest = new ExportToFileRequest();
exportToFileRequest.setNameOfTable("DF-03");
exportToFileRequest.setSdfGroupId(sdf03GroupId);
kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest);
}
Long sdf12GroupId = null;
Long maxTxNumber = 1L;
if (!sDf12Created.isEmpty()) {
sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId();
ImdgPredicateBuilder predicateBuilder = sDf12Imdg.predicateBuilder();
ImdgPredicate notEmptyTransactionNum = predicateBuilder.not(predicateBuilder.equals("transaction_number", ""));
Long maxId = sDf12Imdg.aggregateLongMax("id", notEmptyTransactionNum);
if (maxId != null) {
SDf12 sDf12 = sDf12Imdg.getSingleObjectByID(maxId);
maxTxNumber = Long.parseLong(sDf12.getTransactionNumber()) + 1;
}
}
for (SDf12 sDf12 : sDf12Created) {
sDf12.setGenerationId(sdf03GroupId);
sDf12.setTransactionNumber(maxTxNumber.toString());
sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size()));
sDf12Imdg.insert(sDf12);
}
if (sdf12GroupId != null) {
SwtExporterRequest swtExporterRequest = new SwtExporterRequest();
swtExporterRequest.setType("SDF_12");
kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest);
}
}
private PaymentInstruction createPaymentInstruction(List<Registry> registries, BigDecimal balance, Long sessionId) {
PaymentInstructionBuilder paymentInstructionBuilder = PaymentInstructionBuilder.builder(imdgProvider, registries)
.sessionId(sessionId)
.amount(balance);
return paymentInstructionBuilder.build();
}
private SDf03 newSDf03(PaymentInstruction paymentInstruction) {
log.debug("creating sdf03");
SDf03 sDf03 = new SDf03();
sDf03.setId(idGenerator.nextId());
sDf03.setSeg_type("S");
sDf03.setDoc_type("002");
String strId = paymentInstruction.getId().toString();
String strIdCut = strId.length() > 16 ? strId.substring(strId.length() - 16) : strId;
sDf03.setDocnm_ref(strIdCut);
sDf03.setC_acc_deb(paymentInstruction.getCreditLeg_account());
String senderSbankName = "";
if (paymentInstruction.getSenderId().equals(1L)) {
senderSbankName = paymentInstruction.getPayeeBankName();
} else {
Company company = companyImdg.getSingleObjectByID(paymentInstruction.getSenderId());
if (company != null) {
senderSbankName = company.getShortName();
}
}
sDf03.setSbanknam1(senderSbankName);
sDf03.setSbanknam2(senderSbankName);
sDf03.setSbanknam3(senderSbankName);
sDf03.setSbanknam4(senderSbankName);
sDf03.setSbanknam5(senderSbankName);
sDf03.setC_acc_cred(paymentInstruction.getDebitLeg_account());
String addresseeSbankName = "";
if (paymentInstruction.getAddresseeId().equals(1L)) {
addresseeSbankName = paymentInstruction.getAddresseeBankName();
} else {
Company company = companyImdg.getSingleObjectByID(paymentInstruction.getAddresseeId());
if (company != null) {
addresseeSbankName = company.getShortName();
}
}
sDf03.setRbanknam1(addresseeSbankName);
sDf03.setRbanknam2(addresseeSbankName);
sDf03.setRbanknam3(addresseeSbankName);
sDf03.setRbanknam4(addresseeSbankName);
sDf03.setRbanknam5(addresseeSbankName);
sDf03.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate())));
sDf03.setPay_val("RUR");
sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : "");
sDf03.setSpecif_1(paymentInstruction.getPaymentPurpose());
sDf03.setGenerationTime(Instant.now());
sDf03.setPaymentInstructionId(paymentInstruction.getId());
log.debug("successfully processed, new id {}", sDf03.getId());
return sDf03;
}
private SDf12 newSDf12(PaymentInstruction paymentInstruction) {
log.debug("creating sdf12");
SDf12 sDf12 = new SDf12();
sDf12.setId(idGenerator.nextId());
sDf12.setOutDocument(sDf12.getId().toString());
sDf12.setDirection("DELFREE");
sDf12.setQuantity(paymentInstruction.getCreditLeg_amount().toString());
sDf12.setSecurityCode(paymentInstruction.getCreditLeg_securityId().toString());
sDf12.setDepoCodeSender(paymentInstruction.getCreditLeg_account());
sDf12.setDepoCodeAdressee(paymentInstruction.getDebitLeg_account());
// sDf12.setTransactionNumber();
sDf12.setGenerationTime(Instant.now());
return sDf12;
}
private BigDecimal safeBD(BigDecimal value) {
return value != null ? value : BigDecimal.ZERO;
}
DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
private boolean registriesOfTheSameAgents(Registry rgs1, Registry rgs2) {
return Objects.equals(rgs1.getSecurityId(), rgs2.getSecurityId())
&& Objects.equals(rgs1.getTradingClearingRegistryId(), rgs2.getTradingClearingRegistryId())
&& Objects.equals(rgs1.getCompanyId(), rgs2.getCompanyId())
&& Objects.equals(rgs1.getCounterPartyId(), rgs2.getCounterPartyId());
}
private static boolean equalsByRegistry(RegistryTradingParams code, Registry rgs) {
return code.equalByRegistry(
IEnumKey.getEnumByKey(RegistryDesignation.class, rgs.getRegistryDesignation()),
IEnumKey.getEnumByKey(RegistryInstrumentType.class, rgs.getRegistryInstrumentType()),
IEnumKey.getEnumByKey(RegistryCapacity.class, rgs.getRegistryCapacity()),
IEnumKey.getEnumByKey(RegistryUnit.class, rgs.getRegistryUnit())
);
}
}

View file

@ -0,0 +1,29 @@
package ru.spcex.clearing.session.stage.task;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import java.util.Collection;
public class FormingPaymentInstructionDealsMkrPayload {
private Long sessionId;
/**
* для МКР итоговой сессии SDF будет отправляться по 1. возвратам 2. сделкам
* соотв. поле нужно чтобы передать сделанные пейменты из пункта 1 в 2
*/
private Collection<PaymentInstruction> paymentInstructionReturns;
public Long getSessionId() {
return sessionId;
}
public void setSessionId(Long sessionId) {
this.sessionId = sessionId;
}
public Collection<PaymentInstruction> getPaymentInstructionReturns() {
return paymentInstructionReturns;
}
public void setPaymentInstructionReturns(Collection<PaymentInstruction> paymentInstructionReturns) {
this.paymentInstructionReturns = paymentInstructionReturns;
}
}

View file

@ -15,7 +15,7 @@ class SpecifUtilTest {
public void testSplit() { public void testSplit() {
{ {
//40 symbols //40 symbols
String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789012345678901234567890123456789"); String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789012345678901234567890123456789");
Assertions.assertEquals(2, splitted.length); Assertions.assertEquals(2, splitted.length);
Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]);
Assertions.assertEquals("56789", splitted[1]); Assertions.assertEquals("56789", splitted[1]);
@ -23,27 +23,27 @@ class SpecifUtilTest {
{ {
//40 symbols //40 symbols
String[] splitted = SpecifUtil.splitPaymentPurpose("01234567890123456789012345678901234"); String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("01234567890123456789012345678901234");
Assertions.assertEquals(1, splitted.length); Assertions.assertEquals(1, splitted.length);
Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]);
} }
{ {
//10 symbols //10 symbols
String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789"); String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789");
Assertions.assertEquals(1, splitted.length); Assertions.assertEquals(1, splitted.length);
Assertions.assertEquals("0123456789", splitted[0]); Assertions.assertEquals("0123456789", splitted[0]);
} }
{ {
//0 symbols //0 symbols
String[] splitted = SpecifUtil.splitPaymentPurpose(""); String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("");
Assertions.assertEquals(0, splitted.length); Assertions.assertEquals(0, splitted.length);
} }
{ {
//80 symbols //80 symbols
String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789012345678901234567890123456789" + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789012345678901234567890123456789" +
"0123456789012345678901234567890123456789"); "0123456789012345678901234567890123456789");
Assertions.assertEquals(3, splitted.length); Assertions.assertEquals(3, splitted.length);
Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]);
@ -53,7 +53,7 @@ class SpecifUtilTest {
{ {
//maximum symbols //maximum symbols
String[] splitted = SpecifUtil.splitPaymentPurpose("01234567890123456789012345678912345" + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("01234567890123456789012345678912345" +
"01234567890123456789012345678912345" + "01234567890123456789012345678912345" +
"01234567890123456789012345678912345" + "01234567890123456789012345678912345" +
"01234567890123456789012345678912345" + "01234567890123456789012345678912345" +

View file

@ -3,7 +3,7 @@ package ru.spcex.clearing.session.stage.util;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals;
class RegistryUtilTest { class RegistryUtilTest {

View file

@ -4,13 +4,14 @@ import ru.clearing.classes.statics.data.sdf.SDf52;
import ru.spcex.clearing.dbf.importer.logic.data.enums.ETable; import ru.spcex.clearing.dbf.importer.logic.data.enums.ETable;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;
public class SDf52Table extends AbstractTable<SDf52> { public class SDf52Table extends AbstractTable<SDf52> {
private static final String PREFIX = ETable.DF_52.name(); private static final String PREFIX = ETable.DF_52.name();
private static final Class<SDf52> CLAZZ = SDf52.class; private static final Class<SDf52> CLAZZ = SDf52.class;
private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf57; private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf52;
public SDf52Table() { public SDf52Table() {
super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); super(PREFIX, CLAZZ, NAME_OF_HZ_MAP);
@ -23,7 +24,8 @@ public class SDf52Table extends AbstractTable<SDf52> {
result.setAcc_name((String) entity[1]); result.setAcc_name((String) entity[1]);
result.setDeal((String) entity[2]); result.setDeal((String) entity[2]);
result.setDate((String) entity[3]); result.setDate((String) entity[3]);
result.setStatus((Long) entity[4]); BigDecimal status = (BigDecimal) entity[4];
result.setStatus(status != null ? status.longValue() : null);
result.setFileName(filename); result.setFileName(filename);
result.setGenerationTime(Instant.now()); result.setGenerationTime(Instant.now());
result.setGenerationId(fileId); result.setGenerationId(fileId);

View file

@ -10,7 +10,7 @@ public class SDf55Table extends AbstractTable<SDf55> {
private static final String PREFIX = ETable.DF_55.name(); private static final String PREFIX = ETable.DF_55.name();
private static final Class<SDf55> CLAZZ = SDf55.class; private static final Class<SDf55> CLAZZ = SDf55.class;
private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf57; private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf55;
public SDf55Table() { public SDf55Table() {
super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); super(PREFIX, CLAZZ, NAME_OF_HZ_MAP);
@ -22,41 +22,43 @@ public class SDf55Table extends AbstractTable<SDf55> {
result.setSeg_type((String) entity[0]); result.setSeg_type((String) entity[0]);
result.setDoc_type((String) entity[1]); result.setDoc_type((String) entity[1]);
result.setDocnm_ref((String) entity[2]); result.setDocnm_ref((String) entity[2]);
result.setDocnmprev((String) entity[4]); result.setDocnmprev((String) entity[3]);
result.setSbankcode((String) entity[5]); result.setSbankcode((String) entity[4]);
result.setC_acc_deb((String) entity[6]); result.setC_acc_deb((String) entity[5]);
result.setSbanknam1((String) entity[7]); result.setSbanknam1((String) entity[6]);
result.setSbanknam2((String) entity[8]); result.setSbanknam2((String) entity[7]);
result.setSbanknam3((String) entity[9]); result.setSbanknam3((String) entity[8]);
result.setSbanknam4((String) entity[10]); result.setSbanknam4((String) entity[9]);
result.setSbanknam5((String) entity[11]); result.setSbanknam5((String) entity[10]);
result.setRbankcode((String) entity[12]); result.setRbankcode((String) entity[11]);
result.setC_acc_cred((String) entity[13]); result.setC_acc_cred((String) entity[12]);
result.setRbanknam1((String) entity[14]); result.setRbanknam1((String) entity[13]);
result.setRbanknam2((String) entity[15]); result.setRbanknam2((String) entity[14]);
result.setRbanknam3((String) entity[16]); result.setRbanknam3((String) entity[15]);
result.setRbanknam4((String) entity[17]); result.setRbanknam4((String) entity[16]);
result.setRbanknam5((String) entity[18]); result.setRbanknam5((String) entity[17]);
result.setOp_type((String) entity[19]); result.setOp_type((String) entity[18]);
result.setOp_order((String) entity[19]);
result.setPay_date((String) entity[20]); result.setPay_date((String) entity[20]);
// result.setExt_date((String) entity[21]); result.setPay_val((String) entity[21]);
result.setPay_val((String) entity[22]); result.setSum_deb((String) entity[22]);
result.setSum_deb((String) entity[23]); result.setSclientn1((String) entity[23]);
result.setSclientn1((String) entity[24]); result.setSclientn2((String) entity[24]);
result.setSclientn2((String) entity[25]); result.setSclientn3((String) entity[25]);
result.setSclientn3((String) entity[26]); result.setSclientn4((String) entity[26]);
result.setSclientn4((String) entity[27]); result.setInn_deb((String) entity[27]);
result.setInn_deb((String) entity[28]); result.setKpp_deb((String) entity[28]);
result.setKpp_deb((String) entity[29]); result.setAcc_deb((String) entity[29]);
result.setAcc_deb((String) entity[30]); result.setRclientn1((String) entity[30]);
result.setRclientn1((String) entity[31]); result.setRclientn2((String) entity[31]);
result.setRclientn2((String) entity[32]); result.setRclientn3((String) entity[32]);
result.setRclientn3((String) entity[33]); result.setRclientn4((String) entity[33]);
result.setRclientn4((String) entity[34]); result.setInn_cred((String) entity[34]);
// result.setInn_cred((String) entity[]); result.setKpp_cred((String) entity[35]);
// result.setKpp_cred((String) entity[]); result.setAcc_kr_1((String) entity[36]);
// result.setAcc_kr((String) entity[]); result.setSpecif_1((String) entity[37]);
// result.setSpecif((String) entity[36]); result.setSend_type((String) entity[38]);
result.setDoc_result((String) entity[39]);
result.setFileName(filename); result.setFileName(filename);
result.setGenerationTime(Instant.now()); result.setGenerationTime(Instant.now());
result.setGenerationId(fileId); result.setGenerationId(fileId);

View file

@ -8,6 +8,7 @@ import ru.spcex.clearing.gatewayapi.config.deserializers.InstantDeserializer;
import ru.spcex.clearing.gatewayapi.config.serializers.InstantSerializer; import ru.spcex.clearing.gatewayapi.config.serializers.InstantSerializer;
import java.time.Instant; import java.time.Instant;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
public class InboundRequest { public class InboundRequest {
@ -52,7 +53,7 @@ public class InboundRequest {
@ApiModelProperty( @ApiModelProperty(
value = "Контент", example = "null" value = "Контент", example = "null"
) )
private String content = null; private Map<String, Object> content = null;
public UUID getId() { public UUID getId() {
@ -86,4 +87,12 @@ public class InboundRequest {
public void setSection(String section) { public void setSection(String section) {
this.section = section; this.section = section;
} }
public Map<String, Object> getContent() {
return content;
}
public void setContent(Map<String, Object> content) {
this.content = content;
}
} }

View file

@ -14,7 +14,9 @@ import ru.spcex.clearing.gatewayapi.config.GatewayApiSettings;
import ru.spcex.clearing.gatewayapi.config.InboundServerSettings; import ru.spcex.clearing.gatewayapi.config.InboundServerSettings;
import ru.spcex.clearing.gatewayapi.request.InboundRequest; import ru.spcex.clearing.gatewayapi.request.InboundRequest;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.GatewayTaskRequest; import ru.spcex.clearing.platform.messaging.domain.cud.gateway.GatewayTaskRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.LimExportedRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
@ -23,6 +25,7 @@ import ru.spcex.platform.enumeration.Task;
import java.time.Instant; import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -48,19 +51,22 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
callback(GatewayTaskRequest.class) callback(GatewayTaskRequest.class)
.setFunction(this::requestOnDemandCompany) .setConsumer(this::requestOnDemandCompany)
.forDestination(Task.loadParty_LOCM.topic(), callbacks::put); .forDestination(Task.loadParty_LOCM.topic(), callbacks::put);
callback(GatewayTaskRequest.class) callback(GatewayTaskRequest.class)
.setFunction(this::requestOnDemandSecurity) .setConsumer(this::requestOnDemandSecurity)
.forDestination(Task.loadIssue_LOSC.topic(), callbacks::put); .forDestination(Task.loadIssue_LOSC.topic(), callbacks::put);
callback(LimExportedRequest.class)
.setConsumer(this::requestOnLimit)
.forDestination(Consts.LIM_EXPORTED, callbacks::put);
init(); init();
} }
public RequestInfoUpdate requestOnDemandCompany(BaseRequest<GatewayTaskRequest> userRequest) { public void requestOnDemandCompany(BaseRequest<GatewayTaskRequest> userRequest) {
log.debug("LOCM task received"); log.debug("LOCM task received");
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate; if (requestInfoUpdate != null) return;
logUnknownProperties(userRequest); logUnknownProperties(userRequest);
@ -77,14 +83,35 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
String response = restTemplate.postForObject(url, request, String.class); String response = restTemplate.postForObject(url, request, String.class);
log.debug("LOCM task complete, response: {}", response); log.debug("LOCM task complete, response: {}", response);
return null;
} }
public RequestInfoUpdate requestOnDemandSecurity(BaseRequest<GatewayTaskRequest> userRequest) { public void requestOnLimit(BaseRequest<LimExportedRequest> userRequest) {
LimExportedRequest exportedRequest = userRequest.getRequestPayload();
String url = formingInboundUrl(inboundServerSettings.getPathLOCM());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
InboundRequest inboundRequest = new InboundRequest();
inboundRequest.setId(UUID.randomUUID());
inboundRequest.setType("FILL_LIMITS");
inboundRequest.setSection(Section.FOND.getKey());
inboundRequest.setDatetime(Instant.now());
Map<String, Object> content = new HashMap<>();
content.put("file", exportedRequest.getLimFileName());
inboundRequest.setContent(content);
HttpEntity<InboundRequest> request = new HttpEntity<>(inboundRequest, httpHeaders);
String response = restTemplate.postForObject(url, request, String.class);
log.debug("LOCM task complete, response: {}", response);
}
public void requestOnDemandSecurity(BaseRequest<GatewayTaskRequest> userRequest) {
log.debug("LOSC task received"); log.debug("LOSC task received");
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
if (requestInfoUpdate != null) return requestInfoUpdate; if (requestInfoUpdate != null) return;
logUnknownProperties(userRequest); logUnknownProperties(userRequest);
@ -107,7 +134,7 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
response = restTemplate.postForObject(url, request, String.class); response = restTemplate.postForObject(url, request, String.class);
log.debug("LOCM task 2/2 complete (MKR section), response: {}", response); log.debug("LOCM task 2/2 complete (MKR section), response: {}", response);
return null; // return null;
} }
private String formingInboundUrl(String path) { private String formingInboundUrl(String path) {

View file

@ -85,7 +85,6 @@ public interface Consts {
String CREATE_REPORT_FOR_PERIOD = "create-report-for-period"; String CREATE_REPORT_FOR_PERIOD = "create-report-for-period";
String CREATE_REPORT_FOR_REGISTRY = "create-report-for-registry"; String CREATE_REPORT_FOR_REGISTRY = "create-report-for-registry";
@Deprecated
String ACCOUNT_NEW_SDF01 = "account-new-sdf01"; String ACCOUNT_NEW_SDF01 = "account-new-sdf01";
String DESTINATION_RELATION_NEW = "relation-new"; String DESTINATION_RELATION_NEW = "relation-new";
@ -100,7 +99,7 @@ public interface Consts {
String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update"; String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update";
String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete";
String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; // todo check buplicate REGISTRY_NEW? String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; // не путать с REGISTRY_NEW
String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new";
String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update";
String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block";

View file

@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List; import java.util.List;
@Deprecated
public class AccountSdf01Request { public class AccountSdf01Request {
private Long groupingSdf01Id; private Long groupingSdf01Id;

View file

@ -2,7 +2,6 @@ package ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
@Deprecated
public class AccountSdfRequestPart { public class AccountSdfRequestPart {
@JsonProperty @JsonProperty
private Long sdfId; private Long sdfId;