SDF57 xdep time check -> restriction only for auto launch

сессия шаг 7 по возврату депозитов
This commit is contained in:
ialbert 2023-10-03 18:56:55 +03:00
parent 934b9babd3
commit 9e009307f4
4 changed files with 79 additions and 44 deletions

View file

@ -44,6 +44,7 @@ public class PaymentInstructionBuilderFinalMkrDeals {
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");
private String purpose; private String purpose;
private String lmtPurpose = null;
public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) { public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider); return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider);
@ -86,6 +87,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
return this; return this;
} }
public PaymentInstructionBuilderFinalMkrDeals paymentPurposeLmt(String purpose) {
this.lmtPurpose = purpose;
return this;
}
public Pair<PaymentInstruction, PaymentInstruction> build() { public Pair<PaymentInstruction, PaymentInstruction> build() {
PaymentInstruction payment1; PaymentInstruction payment1;
@ -128,7 +134,11 @@ public class PaymentInstructionBuilderFinalMkrDeals {
payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate())); payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
payment1.setPaymentPurpose(purpose); if (lmtPurpose != null) {
payment1.setPaymentPurpose(lmtPurpose);
} else {
payment1.setPaymentPurpose(purpose);
}
payment1.setSettlementDate(lm_t.getSettlementDate()); payment1.setSettlementDate(lm_t.getSettlementDate());

View file

@ -19,6 +19,7 @@ import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.classes.statics.data.statement.Statement; import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.notification.NotificationSender;
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.StatementRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest;
@ -93,13 +94,14 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
private final TradingTimeService timeService; private final TradingTimeService timeService;
private final KafkaSender kafka; private final KafkaSender kafka;
private final AssetTBFProcessing assets; private final AssetTBFProcessing assets;
private final NotificationSender notification;
private final Pattern pattern = Pattern.compile("№.*"); private final Pattern pattern = Pattern.compile("№.*");
public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator, public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator,
LoggingService errorLogger, LoggingService errorLogger,
ImdgProvider imdgProvider, ImdgProvider imdgProvider,
IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver, DmiService dmiService, TradingTimeService timeService, IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver, DmiService dmiService, TradingTimeService timeService,
@Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets) { @Qualifier("kafkaSenderWithoutRequestInfo") KafkaSender kafka, AssetTBFProcessing assets, NotificationSender notification) {
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
@ -121,6 +123,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
this.timeService = timeService; this.timeService = timeService;
this.kafka = kafka; this.kafka = kafka;
this.assets = assets; this.assets = assets;
this.notification = notification;
} }
//todo доделать контроль sdf01 и sdf57 //todo доделать контроль sdf01 и sdf57
@ -442,11 +445,16 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
statementCred.map(stmt -> new StmtCmpAcc(stmt, companyCred, accountCred)).ifPresent(registersUpdate); statementCred.map(stmt -> new StmtCmpAcc(stmt, companyCred, accountCred)).ifPresent(registersUpdate);
} }
if (sessionIsNeededFlag.get()) { if (sessionIsNeededFlag.get()) {
result.setSessionWasStarted(true); if (!timeService.timeForXdep()) {
LauncherCommandRequest sessionTask = new LauncherCommandRequest(); EnumMessage err = new EnumMessage(ClearingError.XdepTimeIntervalNotMatch);
sessionTask.setSection(Section.MKR.getKey()); notification.sendNotification(ObjectType.session, messageResolver.resolve(err), Priority.HIGH);
sessionTask.setSessionType(SessionType.XDEP.getKey()); } else {
kafka.sendRequestToQueue(Task.startOfClearing.topic(), sessionTask); result.setSessionWasStarted(true);
LauncherCommandRequest sessionTask = new LauncherCommandRequest();
sessionTask.setSection(Section.MKR.getKey());
sessionTask.setSessionType(SessionType.XDEP.getKey());
kafka.sendRequestToQueue(Task.startOfClearing.topic(), sessionTask);
}
} }
return result; return result;
} }

View file

@ -79,25 +79,20 @@ public class SessionManager {
if (session != null) { if (session != null) {
//checkActive //checkActive
checkAllowSessionStart(sessionType); checkAllowSessionStart();
session.runSession(baseRequest); session.runSession(baseRequest);
} }
} }
protected void checkAllowSessionStart(SessionType sessionType) throws ValidationException { protected void checkAllowSessionStart() throws ValidationException {
EnumMessage err = null; EnumMessage err = null;
if (sessionType.equals(SessionType.XDEP) && !time.timeForXdep()) { Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of(
log.warn("cannot launch {} reason: time interval not matched", sessionType); "workflowStatus", SessionStatus.ACTV.getKey()
err = new EnumMessage(ClearingError.XdepTimeIntervalNotMatch); ));
} else { if (existActiveSession != null) {
Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of( log.warn("Can not start new session, cause exist active session.id={}", existActiveSession.getId());
"workflowStatus", SessionStatus.ACTV.getKey() err = new EnumMessage(ClearingError.ActiveSessionIsPresent, String.valueOf(existActiveSession.getId()));
));
if (existActiveSession != null) {
log.warn("Can not start new session, cause exist active session.id={}", existActiveSession.getId());
err = new EnumMessage(ClearingError.ActiveSessionIsPresent, String.valueOf(existActiveSession.getId()));
}
} }
if (err != null) { if (err != null) {
notification.sendNotification(ObjectType.session, msgs.resolve(err), Priority.HIGH); notification.sendNotification(ObjectType.session, msgs.resolve(err), Priority.HIGH);

View file

@ -7,6 +7,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.Registry;
@ -58,6 +59,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
private final ImdgProvider imdgProvider; private final ImdgProvider imdgProvider;
private final ImdgId idGenerator; private final ImdgId idGenerator;
private final Imdg<Registry> registryImdg; private final Imdg<Registry> registryImdg;
private final Imdg<BankAccount> bankAccImdg;
private final Imdg<ru.clearing.classes.statics.data.misc.Currency> currImdg;
private final Imdg<PaymentInstruction> paymentInstructionImdg; private final Imdg<PaymentInstruction> paymentInstructionImdg;
private final Imdg<Security> securityImdg; private final Imdg<Security> securityImdg;
private final Imdg<Account> accountImdg; private final Imdg<Account> accountImdg;
@ -81,6 +84,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class); this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class);
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class); this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
this.bankAccImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, ru.clearing.classes.statics.data.misc.Currency.class);
this.sdf03Creator = sdf03Creator; this.sdf03Creator = sdf03Creator;
this.rgsMng = rgsMng; this.rgsMng = rgsMng;
} }
@ -102,6 +107,13 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
private StageResult formingPaymentInstruction(Long sessionId) { private StageResult formingPaymentInstruction(Long sessionId) {
Instant now = Instant.now(); Instant now = Instant.now();
Account tranAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
if (tranAcc == null) {
return new StageResult<>(
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()),
false);
}
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(LM_T,CM_T, LS_T, CS_T); RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(LM_T,CM_T, LS_T, CS_T);
String registryCodeCondition = registryCodeSqlBuilder.build(); String registryCodeCondition = registryCodeSqlBuilder.build();
@ -128,15 +140,15 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
Optional<Registry> lmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(LM_T, rgs)).findFirst(); Optional<Registry> lmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(LM_T, rgs)).findFirst();
Optional<Registry> cmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(CM_T, rgs)).findFirst(); Optional<Registry> cmtO = groupRgs.stream().filter(rgs -> RegistryManager.equalsByCode(CM_T, rgs)).findFirst();
if (lmtO.isEmpty() || cmtO.isEmpty()) { if (lmtO.isEmpty() || cmtO.isEmpty()) {
log.error("LM*T or CM*T not found for group {}", entry.getKey()); log.error("groupId {} LM*T or CM*T not found", entry.getKey());
continue; continue;
} }
Registry lm_t = lmtO.get(); //obligation by money Registry lm_t = lmtO.get(); //obligation by money
Registry cm_t = cmtO.get(); Registry cm_t = cmtO.get();
Optional<Registry> dmx = rgsMng.searchDmxByCounterPartyNotOk(lm_t); Optional<Registry> dmx = rgsMng.searchDmxByCounterPartyNotOk(lm_t);
if (dmx.isPresent()) { if (dmx.isPresent()) {
log.debug("LM*T#id={}, DM*X#id={} found, no action needed for group {}, skipping liability", log.debug("groupId {} LM*T#id={}, DM*X#id={} found, no action needed, skipping liability",
lm_t.getId(), dmx.get().getId(), lm_t.getGroupId()); lm_t.getGroupId(), lm_t.getId(), dmx.get().getId());
dmx.get().setRegistryStatus(RegistryStatus.OK.getKey()); dmx.get().setRegistryStatus(RegistryStatus.OK.getKey());
setUpdatedStoreInImdg(dmx.get(), now); setUpdatedStoreInImdg(dmx.get(), now);
continue; continue;
@ -144,25 +156,35 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
Optional<Registry> dmtInfo = rgsMng.searchDmtInfoNotOk(lm_t); Optional<Registry> dmtInfo = rgsMng.searchDmtInfoNotOk(lm_t);
if (dmtInfo.isPresent()) { if (dmtInfo.isPresent()) {
BigDecimal balance = safeBD(lm_t.getBalance()).add(safeBD(cm_t.getBalance())); //fixme???? log.debug("groupId {} LM*T#id={}, DM*T(INFO)#id={} found",
PaymentInstruction payInstr = createPaymentInstruction(List.of(lm_t, cm_t), balance, sessionId); lm_t.getGroupId(), lm_t.getId(), dmtInfo.get().getId());
lm_t.setPaymentId(payInstr.getId()); Pair<PaymentInstruction, PaymentInstruction> pmts = PaymentInstructionBuilderFinalMkrDeals.builder(imdgProvider)
.lm_t(lm_t)
.cm_t(cm_t)
.tranAcc(tranAcc)
.sessionId(sessionId)
.paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry())
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
.build();
Pair.forEach(pmts, paymentInstructionImdg::insert);
Pair.forEach(pmts, pmtCreated::add);
lm_t.setPaymentId(pmts.getFirst().getId());
cm_t.setPaymentId(pmts.getSecond().getId());
lm_t.setUpdated(Instant.now()); lm_t.setUpdated(Instant.now());
cm_t.setUpdated(Instant.now());
registryImdg.update(lm_t); registryImdg.update(lm_t);
registryImdg.update(cm_t);
dmtInfo.get().setRegistryStatus(RegistryStatus.OK.getKey()); dmtInfo.get().setRegistryStatus(RegistryStatus.OK.getKey());
setUpdatedStoreInImdg(dmtInfo.get(), now); setUpdatedStoreInImdg(dmtInfo.get(), now);
log.debug("groupId {} LM*T#id={} CM*T#id={} created PmtInst.id={} and PmtInst.id={}",
lm_t.getGroupId(), lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId());
continue; continue;
} }
Optional<Registry> dmtClnr = rgsMng.searchDmtClrnNotOk(lm_t); Optional<Registry> dmtClnr = rgsMng.searchDmtClrnNotOk(lm_t);
if (dmtClnr.isPresent()) { if (dmtClnr.isPresent()) {
Account tranAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'" log.debug("groupId {} {}#id={} found",
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey())); lm_t.getGroupId(), dmtClnr.get().getRegistryCode(), dmtClnr.get().getId());
if (tranAcc == null) {
return new StageResult<>(
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()),
false);
}
{ {
//изменение активов - блокируем средства беред отправкой sdf'ов //изменение активов - блокируем средства беред отправкой sdf'ов
Optional<Registry> amfO = rgsMng.findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), lm_t.getSecuritySymbol(), AM_F); Optional<Registry> amfO = rgsMng.findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), lm_t.getSecuritySymbol(), AM_F);
@ -177,21 +199,21 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
ambO.map(Registry::getId).orElse(null), ambO.map(Registry::getId).orElse(null),
receiverAmtO.map(Registry::getId).orElse(null) receiverAmtO.map(Registry::getId).orElse(null)
); );
amfO.ifPresent(amf -> { //amfO.ifPresent(amf -> {
amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance()))); // amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amf, now); // setUpdatedStoreInImdg(amf, now);
}); //});
payerAmtO.ifPresent(amt -> { payerAmtO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance()))); amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amt, now); setUpdatedStoreInImdg(amt, now);
}); });
ambO.ifPresent(amb -> { //ambO.ifPresent(amb -> {
amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance()))); // amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amb, now); // setUpdatedStoreInImdg(amb, now);
}); //});
receiverAmtO.ifPresent(amt -> { receiverAmtO.ifPresent(amt -> {
// у отправителя и получателя одинаково, см. в FormingPaymentInstruction // у отправителя и получателя одинаково, см. в FormingPaymentInstruction
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance()))); amt.setSettledCredit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance())));
setUpdatedStoreInImdg(amt, now); setUpdatedStoreInImdg(amt, now);
}); });
} }
@ -204,8 +226,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
.build(); .build();
paymentInstructionImdg.insert(pmts.getFirst()); paymentInstructionImdg.insert(pmts.getFirst());
paymentInstructionImdg.insert(pmts.getSecond()); paymentInstructionImdg.insert(pmts.getSecond());
log.debug("LM*T#id={}, CM*T#id={} found, PaymentInstruction id={} and id={} created", log.debug("groupId {} LM*T#id={}, CM*T#id={} found, PaymentInstruction id={} and id={} created",
lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId()); lm_t.getGroupId(), lm_t.getId(), cm_t.getId(), pmts.getFirst().getId(), pmts.getSecond().getId());
pmtCreated.add(pmts.getFirst()); pmtCreated.add(pmts.getFirst());
pmtCreated.add(pmts.getSecond()); pmtCreated.add(pmts.getSecond());
dmtClnr.get().setRegistryStatus(RegistryStatus.OK.getKey()); dmtClnr.get().setRegistryStatus(RegistryStatus.OK.getKey());