currency session fix

This commit is contained in:
ialbert 2025-07-04 12:32:25 +03:00
parent 767347dbed
commit bc8c030714
6 changed files with 117 additions and 25 deletions

View file

@ -1,11 +1,10 @@
package ru.spcex.clearing.config.state_machine_2.specific;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachineFactory;
@ -35,11 +34,13 @@ import ru.spcex.clearing.session.state.action.RequirementAndObligationCreationAc
import ru.spcex.clearing.session.state.action.ReviseStage1Action;
import ru.spcex.clearing.session.state.action.SaveRegistriesAndContinueAction;
import ru.spcex.clearing.session.state.action.Sdf56Action;
import ru.spcex.clearing.session.state.action.SdfReceivedAction;
import ru.spcex.clearing.session.state.guard.PaymentsWereCreatedGuard;
import ru.spcex.clearing.session.state.guard.PaymentsWereNotCreatedGuard;
import ru.spcex.clearing.session.state.guard.SdfGuard;
import ru.spcex.clearing.session.state.guard.SdfGuardExtractorAfterAgainRevise;
import ru.spcex.clearing.session.state.guard.SdfGuardExtractorAfterAssets;
import ru.spcex.clearing.session.state.guard.SdfGuardUtil;
import ru.spcex.clearing.session.state.guard.SdfSetGuard;
import ru.spcex.clearing.session.state.guard.StashedRegistriesPresentGuard;
import ru.spcex.clearing.session.state.listener.MachineMonitoringListener;
import static ru.spcex.clearing.util.StateMachineUtil.*;
@ -53,7 +54,6 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@Configuration("intermediateMkrSessionStateMachineFactoryConfig")
@EnableStateMachineFactory(name = "CURR")
public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigurerAdapter<TaskType, SsnEvent> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<Session> sessionImdg;
private final Sdf56Action sendSdf56Action;
private final ReviseStage1Action reviseStage1Action;
@ -66,7 +66,6 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
private final AgainReviseStage3Action againRevise;
private final FinishingSessionAction finishingSessionAction;
private final EndStageNotificationAction endStageNotificationAction;
private final Imdg<ExecutionCurrency> executionCurrencyImdg;
private final SaveRegistriesAndContinueAction obligationAdmissionContinueAction;
private final DiscardRegistriesAction discardOblAdmStash =
new DiscardRegistriesAction(DataEnum.obligationAdmissionStashedRgs);
@ -74,7 +73,8 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
DataEnum.obligationAdmissionStashedRgs
);
private final Guard<TaskType, SsnEvent> reviseSuccessGuard = guardCheckCtxForFlag(DataEnum.againReviseSuccess);
private final SessionType SESSION_TYPE = SessionType.MEDM;
private final SessionType SESSION_TYPE = SessionType.CURR;
private final Section SECTION = Section.CURR;
public CurrencySessionStateMachineConfig(ImdgProvider imdgProvider,
Sdf56Action sendSdf56Action,
@ -93,7 +93,6 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
Supplier<List<String>> marketCodes,
SaveRegistriesAndContinueAction obligationAdmissionContinueAction) {
this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class);
this.executionCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionCurrency, ExecutionCurrency.class);
this.sendSdf56Action = sendSdf56Action;
this.reviseStage1Action = reviseStage1Action;
this.dealsPrepareAction = dealsPrepare;
@ -108,6 +107,7 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
this.obligationAdmissionContinueAction = obligationAdmissionContinueAction;
this.finishingSessionAction.setPr("1");
Imdg<ExecutionCurrency> executionCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionCurrency, ExecutionCurrency.class);
dealsPrepareAction.searchForExecutions(ExecutionType.ExecutionCurrency);
ImdgPredicateBuilder execFondPb = executionCurrencyImdg.predicateBuilder();
dealsPrepareAction.addExecutionCurrencyCondition(execFondPb.regex("settlementCode", "^T0.*$"));
@ -120,7 +120,7 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
states
.withStates()
.initial(TaskType.StartRevise, chain(
new CreateSessionAction(sessionImdg, SessionType.MEDM, Section.MKR),
new CreateSessionAction(sessionImdg, SESSION_TYPE, SECTION),
sendSdf56Action))
.states(new HashSet<>(Arrays.asList(
TaskType.StartRevise,
@ -167,12 +167,6 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
.source(TaskType.InspectionObligations).target(TaskType.FormingPaymentInstruction)
.action(formingPaymentInstructionAssetsAction)
.and()
.withExternal()
.source(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.target(TaskType.AgainRevise)
.guard(new SdfGuard(SdfGuardExtractorAfterAssets.instance))
.action(againRevise)
.and()
.withExternal()
.source(TaskType.PSEUDO_waitSdfAfterAgainRevise)
.target(TaskType.AgainRevise)
@ -186,6 +180,7 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
sourceObligationAdmission(transitions);
sourcePseudoAfterOAError(transitions);
sourceFormingPaymentInstruction(transitions);
sourcePseudoWaitSdfAfterPaymentInstructions(transitions);
sourceAgainRevise(transitions);
}
@ -231,6 +226,23 @@ public class CurrencySessionStateMachineConfig extends EnumStateMachineConfigure
.guard(PaymentsWereCreatedGuard.instance);
}
private void sourcePseudoWaitSdfAfterPaymentInstructions(StateMachineTransitionConfigurer<TaskType, SsnEvent> transitions) throws Exception {
EnumSet<SsnEvent> sdfs = SdfGuardUtil.bySectionAfter7Step(SECTION);
transitions
.withExternal()
.source(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.target(TaskType.AgainRevise)
.guard(new SdfSetGuard(sdfs))
.action(againRevise);
for (var event : sdfs) {
transitions
.withInternal()
.source(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.event(event)
.action(SdfReceivedAction.instance);
}
}
private void sourceAgainRevise(StateMachineTransitionConfigurer<TaskType, SsnEvent> transitions) throws Exception {
transitions
.withExternal()

View file

@ -4,6 +4,9 @@ public enum SsnEvent {
SDF_01,
SDF_57,
SDF_04,
SDF_13,
SDF_08,
SDF_21,
PAUSE,
CONTINUE,
REPEAT

View file

@ -56,10 +56,10 @@ import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
public class FormingPaymentInstructionSecuritiesAction extends AbstractSessionActionForOkErrorHandling {
private final Logger log = LoggerFactory.getLogger(getClass());
private ImdgProvider imdgProvider;
private Imdg<Registry> registryImdg;
private Imdg<PaymentInstruction> paymentInstructionImdg;
private Imdg<Account> accountImdg;
private final ImdgProvider imdgProvider;
private final Imdg<Registry> registryImdg;
private final Imdg<PaymentInstruction> paymentInstructionImdg;
private final Imdg<Account> accountImdg;
private final RegistryManager rgsMng;
private final Sdf03And12Sender sdf03And12Sender;

View file

@ -1,6 +1,5 @@
package ru.spcex.clearing.session.state.guard;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.Function;
@ -8,7 +7,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.statemachine.StateContext;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.stage.impl.PaymentInfo;
import ru.spcex.clearing.session.state.DataEnum;
import ru.spcex.clearing.session.state.SsnEvent;
import ru.spcex.platform.enumeration.SdfTable;
@ -26,11 +24,11 @@ public class SdfGuardExtractorAfterAssets implements Function<StateContext<TaskT
if (section == null) {
throw new IllegalStateException("section is null");
}
PaymentInfo pmts = ctx.getExtendedState().get(DataEnum.paymentInfo, PaymentInfo.class);
if (pmts == null || pmts.getPaymentInstructions().isEmpty()) {
log.warn("SdfGuard defined, but no DataEnum.paymentInfo present in extended state");
return Collections.emptySet();
}
// PaymentInfo pmts = ctx.getExtendedState().get(DataEnum.paymentInfo, PaymentInfo.class);
// if (pmts == null || pmts.getPaymentInstructions().isEmpty()) {
// log.warn("SdfGuard defined, but no DataEnum.paymentInfo present in extended state");
// return Collections.emptySet();
// }
switch (section) {
case MKR -> {
return EnumSet.of(

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.session.state.guard;
import java.util.EnumSet;
import ru.spcex.clearing.session.state.SsnEvent;
import ru.spcex.platform.enumeration.Section;
public class SdfGuardUtil {
public static EnumSet<SsnEvent> bySectionAfter7Step(Section section) {
switch (section) {
case MKR -> {
return EnumSet.of(
SsnEvent.SDF_04,
SsnEvent.SDF_01,
SsnEvent.SDF_57
);
}
case FOND, MULT -> {
return EnumSet.of(
SsnEvent.SDF_04,
SsnEvent.SDF_13,
SsnEvent.SDF_08,
SsnEvent.SDF_21,
SsnEvent.SDF_01,
SsnEvent.SDF_57
);
}
default -> throw new IllegalStateException("unknown wait conditions for section " + section);
}
}
}

View file

@ -0,0 +1,48 @@
package ru.spcex.clearing.session.state.guard;
import java.util.EnumSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.statemachine.ExtendedState;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.guard.Guard;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.state.SsnEvent;
public class SdfSetGuard implements Guard<TaskType, SsnEvent> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final EnumSet<SsnEvent> sdfs;
public SdfSetGuard(SsnEvent first, SsnEvent... rest) {
this.sdfs = EnumSet.of(first, rest);
}
public SdfSetGuard(EnumSet<SsnEvent> sdfs) {
this.sdfs = sdfs;
}
@Override
public boolean evaluate(StateContext<TaskType, SsnEvent> ctx) {
ExtendedState state = ctx.getExtendedState();
Function<SsnEvent, Boolean> was = sdf -> state.get(sdf.name(), Object.class) != null;
boolean everySdfConditionMet = sdfs
.stream()
.allMatch(was::apply);
if (everySdfConditionMet) {
log.info("all of {} conditions were met", sdfs);
sdfs.forEach(sdf -> state.getVariables().remove(sdf.name()));
return true;
} else {
log.info("conditions: {}",
sdfs
.stream()
.map(sdf -> "%s: %s".formatted(sdf.name(), was.apply(sdf) ? "received" : "waiting"))
.collect(Collectors.joining(";", "[", "]"))
);
return false;
}
}
}