ReturnDepositSession state machine config

This commit is contained in:
ialbert 2025-07-03 19:11:55 +03:00
parent 6756a65485
commit 61c7fb537f
4 changed files with 275 additions and 1 deletions

View file

@ -0,0 +1,213 @@
package ru.spcex.clearing.config.state_machine_2.specific;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.function.Supplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import ru.clearing.classes.statics.data.misc.Session;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.state.DataEnum;
import ru.spcex.clearing.session.state.SsnEvent;
import ru.spcex.clearing.session.state.action.CreateSessionAction;
import ru.spcex.clearing.session.state.action.DiscardRegistriesAction;
import ru.spcex.clearing.session.state.action.EndStageNotificationAction;
import ru.spcex.clearing.session.state.action.FinishingSessionAction;
import ru.spcex.clearing.session.state.action.FormingPaymentInstructionDepositReturnAction;
import ru.spcex.clearing.session.state.action.InclusionToPoolAction;
import ru.spcex.clearing.session.state.action.InspectionObligationsDepositReturnAction;
import ru.spcex.clearing.session.state.action.ObligationAdmissionAction;
import ru.spcex.clearing.session.state.action.RequirementAndObligationCreationAction;
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.PaymentsWereCreatedListGuard;
import ru.spcex.clearing.session.state.guard.PaymentsWereNotCreatedListGuard;
import ru.spcex.clearing.session.state.guard.SdfGuard;
import ru.spcex.clearing.session.state.guard.SdfGuardExtractorAfterAssets;
import ru.spcex.clearing.session.state.guard.StashedRegistriesPresentGuard;
import ru.spcex.clearing.session.state.listener.MachineMonitoringListener;
import static ru.spcex.clearing.util.StateMachineUtil.chain;
import static ru.spcex.clearing.util.StateMachineUtil.guardCheckCtxForFlag;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.Section;
import ru.spcex.platform.enumeration.SessionType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@Configuration("returnDepositSessionStateMachineConfig")
@EnableStateMachineFactory(name = "XDEP")
public class ReturnDepositSessionStateMachineConfig
extends EnumStateMachineConfigurerAdapter<TaskType, SsnEvent> {
private final Imdg<Session> sessionImdg;
private final Sdf56Action sendSdf56Action;
private final ReviseStage1Action reviseStage1Action;
private final RequirementAndObligationCreationAction reqAndOblAction;
private final ObligationAdmissionAction obligationAdmissionAction;
private final InclusionToPoolAction inclusionToPoolAction;
private final InspectionObligationsDepositReturnAction inspectionObligationsDepositReturnAction;
private final FormingPaymentInstructionDepositReturnAction formingPaymentInstructionDepositReturnAction;
private final FinishingSessionAction finishingSessionAction;
private final EndStageNotificationAction endStageNotificationAction;
private final SaveRegistriesAndContinueAction obligationAdmissionContinueAction;
private final DiscardRegistriesAction discardOblAdmStash =
new DiscardRegistriesAction(DataEnum.obligationAdmissionStashedRgs);
private final StashedRegistriesPresentGuard oblAdmGuard = new StashedRegistriesPresentGuard(
DataEnum.obligationAdmissionStashedRgs
);
private final Guard<TaskType, SsnEvent> reviseSuccessGuard = guardCheckCtxForFlag(DataEnum.againReviseSuccess);
private final SessionType SESSION_TYPE = SessionType.XDEP;
@Autowired
public ReturnDepositSessionStateMachineConfig(
ImdgProvider imdgProvider,
Sdf56Action sendSdf56Action,
ReviseStage1Action reviseStage1Action,
@Qualifier("requirementAndObligationCreationAction")
RequirementAndObligationCreationAction reqAndOblAction,
ObligationAdmissionAction obligationAdmissionAction,
InclusionToPoolAction inclusionToPoolAction,
FinishingSessionAction finishingSessionAction, EndStageNotificationAction endStageNotificationAction, SaveRegistriesAndContinueAction obligationAdmissionContinueAction, @Qualifier("marketCodesForBn") Supplier<List<String>> marketCodes, InspectionObligationsDepositReturnAction inspectionObligationsDepositReturnAction, FormingPaymentInstructionDepositReturnAction formingPaymentInstructionDepositReturnAction
) {
this.sendSdf56Action = sendSdf56Action;
this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class);
this.obligationAdmissionContinueAction = obligationAdmissionContinueAction;
this.reviseStage1Action = reviseStage1Action;
this.reqAndOblAction = reqAndOblAction;
this.obligationAdmissionAction = obligationAdmissionAction;
this.inclusionToPoolAction = inclusionToPoolAction;
this.inspectionObligationsDepositReturnAction = inspectionObligationsDepositReturnAction;
this.formingPaymentInstructionDepositReturnAction = formingPaymentInstructionDepositReturnAction;
this.finishingSessionAction = finishingSessionAction;
this.endStageNotificationAction = endStageNotificationAction;
this.finishingSessionAction.setPr("4");
this.obligationAdmissionContinueAction.setDataEnum(DataEnum.obligationAdmissionStashedRgs);
Imdg<Registry> rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
ImdgPredicateBuilder rgsPb = rgsImdg.predicateBuilder();
this.inclusionToPoolAction.addRegistryCondition(
rgsPb.and(
rgsPb.or(
rgsPb.equals("registryStatus", RegistryStatus.PROC.getKey()),
rgsPb.equals("registryStatus", RegistryStatus.MNG.getKey())
),
rgsPb.less("valueDate", LocalDate.now())
)
);
//stages settings:
}
@Override
public void configure(StateMachineStateConfigurer<TaskType, SsnEvent> states) throws Exception {
states
.withStates()
.initial(TaskType.StartRevise, chain(
new CreateSessionAction(sessionImdg, SESSION_TYPE, Section.MKR),
sendSdf56Action))
.states(new HashSet<>(Arrays.asList(
TaskType.StartRevise,
TaskType.StartRevisePart1,
TaskType.DealsPrepare,
TaskType.RequirementsAndObligationsCreate,
TaskType.InclusionToPool,
TaskType.InspectionObligations,
TaskType.FormingRegistersOnOS,
TaskType.FormingPaymentInstruction,
TaskType.FinishingSession,
TaskType.EndStageNotification,
TaskType.PSEUDO_waitSdfAfterPaymentInstructions
)))
.end(TaskType.EndStageNotification);
}
@Override
public void configure(StateMachineTransitionConfigurer<TaskType, SsnEvent> transitions) throws Exception {
transitions
.withExternal()
.event(SsnEvent.SDF_57)
.source(TaskType.StartRevise).target(TaskType.StartRevisePart1)
.action(reviseStage1Action)
.and()
.withExternal()
.source(TaskType.StartRevisePart1).target(TaskType.InclusionToPool)
.action(inclusionToPoolAction)
.and()
.withExternal()
.source(TaskType.InclusionToPool).target(TaskType.InspectionObligations)
.action(inspectionObligationsDepositReturnAction)
.and()
.withExternal()
.source(TaskType.InspectionObligations).target(TaskType.FormingPaymentInstruction)
.action(formingPaymentInstructionDepositReturnAction)
.and()
.withExternal()
.source(TaskType.FinishingSession)
.target(TaskType.EndStageNotification)
.action(endStageNotificationAction);
sourceFormingPaymentInstruction(transitions);
sourcePseudoWaitSdfAfterPaymentInstructions(transitions);
}
private void sourceFormingPaymentInstruction(StateMachineTransitionConfigurer<TaskType, SsnEvent> transitions) throws Exception {
transitions
//если не создалось paymentInstruction'ов
.withExternal()
.source(TaskType.FormingPaymentInstruction)
.target(TaskType.FinishingSession)
.guard(new PaymentsWereNotCreatedListGuard(FormingPaymentInstructionDepositReturnAction.key))
.action(finishingSessionAction)
.and()
//если создались paymentInstruction, переходим в режим ожидания
.withExternal()
.source(TaskType.FormingPaymentInstruction)
.target(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.guard(new PaymentsWereCreatedListGuard(FormingPaymentInstructionDepositReturnAction.key));
}
private void sourcePseudoWaitSdfAfterPaymentInstructions(StateMachineTransitionConfigurer<TaskType, SsnEvent> transitions) throws Exception {
transitions
.withExternal()
.source(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.target(TaskType.FinishingSession)
.guard(new SdfGuard(SdfGuardExtractorAfterAssets.instance))
.action(finishingSessionAction);
for (var event: EnumSet.of(SsnEvent.SDF_01, SsnEvent.SDF_57, SsnEvent.SDF_04)) {
transitions
.withInternal()
.source(TaskType.PSEUDO_waitSdfAfterPaymentInstructions)
.event(event)
.action(SdfReceivedAction.instance);
}
}
@Override
public void configure(StateMachineConfigurationConfigurer<TaskType, SsnEvent> config) throws Exception {
StateMachineListenerAdapter<TaskType, SsnEvent> loggingChangeStateListener
= new MachineMonitoringListener(SESSION_TYPE.getKey());
config
.withConfiguration()
.machineId(SESSION_TYPE.getKey())
.listener(loggingChangeStateListener);
}
}

View file

@ -59,6 +59,7 @@ public class FormingPaymentInstructionDepositReturnAction extends AbstractSessio
private final KafkaSender kafkaSender;
private final Sdf03Creator sdf03Creator;
private final RegistryManager rgsMng;
public static final DataEnum key = DataEnum.paymentsWereCreatedDepositReturn;
@Autowired
public FormingPaymentInstructionDepositReturnAction(ImdgProvider imdgProvider,
@ -211,7 +212,7 @@ public class FormingPaymentInstructionDepositReturnAction extends AbstractSessio
}
}
sendSdfs(pmtCreated);
ctx.getExtendedState().getVariables().put(DataEnum.paymentsWereCreatedDepositReturn, pmtCreated);
ctx.getExtendedState().getVariables().put(key, pmtCreated);
}

View file

@ -0,0 +1,30 @@
package ru.spcex.clearing.session.state.guard;
import java.util.List;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.guard.Guard;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.state.DataEnum;
import ru.spcex.clearing.session.state.SsnEvent;
public class PaymentsWereCreatedListGuard implements Guard<TaskType, SsnEvent> {
public static final PaymentsWereCreatedListGuard instance = new PaymentsWereCreatedListGuard();
private DataEnum key = DataEnum.paymentsWereCreatedDepositReturn;
private PaymentsWereCreatedListGuard() {
}
public PaymentsWereCreatedListGuard(final DataEnum key) {
this.key = key;
}
@Override
public boolean evaluate(StateContext<TaskType, SsnEvent> ctx) {
@SuppressWarnings("unchecked")
List<PaymentInstruction> pmts = ctx.getExtendedState().get(key, List.class);
return pmts != null && !pmts.isEmpty();
}
}

View file

@ -0,0 +1,30 @@
package ru.spcex.clearing.session.state.guard;
import java.util.List;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.guard.Guard;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.spcex.clearing.session.stage.TaskType;
import ru.spcex.clearing.session.state.DataEnum;
import ru.spcex.clearing.session.state.SsnEvent;
public class PaymentsWereNotCreatedListGuard implements Guard<TaskType, SsnEvent> {
public static final PaymentsWereNotCreatedListGuard instance = new PaymentsWereNotCreatedListGuard();
private DataEnum key = DataEnum.paymentsWereCreatedDepositReturn;
private PaymentsWereNotCreatedListGuard() {
}
public PaymentsWereNotCreatedListGuard(final DataEnum key) {
this.key = key;
}
@Override
public boolean evaluate(StateContext<TaskType, SsnEvent> ctx) {
@SuppressWarnings("unchecked")
List<PaymentInstruction> pmts = ctx.getExtendedState().get(key, List.class);
return pmts == null || pmts.isEmpty();
}
}