diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/state_machine_2/specific/ReturnDepositSessionStateMachineConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/state_machine_2/specific/ReturnDepositSessionStateMachineConfig.java new file mode 100644 index 000000000..2d693e0e9 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/state_machine_2/specific/ReturnDepositSessionStateMachineConfig.java @@ -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 { + + private final Imdg 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 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> 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 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 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 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 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 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 config) throws Exception { + StateMachineListenerAdapter loggingChangeStateListener + = new MachineMonitoringListener(SESSION_TYPE.getKey()); + config + .withConfiguration() + .machineId(SESSION_TYPE.getKey()) + .listener(loggingChangeStateListener); + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/FormingPaymentInstructionDepositReturnAction.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/FormingPaymentInstructionDepositReturnAction.java index 435fdc133..1363ea677 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/FormingPaymentInstructionDepositReturnAction.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/FormingPaymentInstructionDepositReturnAction.java @@ -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); } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereCreatedListGuard.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereCreatedListGuard.java new file mode 100644 index 000000000..afa773bba --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereCreatedListGuard.java @@ -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 { + + 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 ctx) { + @SuppressWarnings("unchecked") + List pmts = ctx.getExtendedState().get(key, List.class); + return pmts != null && !pmts.isEmpty(); + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereNotCreatedListGuard.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereNotCreatedListGuard.java new file mode 100644 index 000000000..f82243095 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/guard/PaymentsWereNotCreatedListGuard.java @@ -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 { + + 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 ctx) { + @SuppressWarnings("unchecked") + List pmts = ctx.getExtendedState().get(key, List.class); + return pmts == null || pmts.isEmpty(); + } +}