using Hcs.WebApp.Data.Hcs; using Microsoft.EntityFrameworkCore; namespace Hcs.WebApp.BackgroundServices.CampaignManagers { public class ExportSupplyContractsManager_15_7_0_1( IServiceScopeFactory scopeFactory, OperationExecutionState operationExecutionState, ResultGetState resultGetState, DataParsingState dataParsingState, Campaign campaign) : ManagerBase(scopeFactory, operationExecutionState, resultGetState, dataParsingState, campaign) { private enum Step { Start = 0, ExecutionWait = 1, ResultWait = 2, RepeatCheck = 3, End = 4 } protected override int StepCount => Enum.GetValues(typeof(Step)).Length; public override async Task ProcessAsync() { switch ((Step)campaign.Step) { case Step.Start: await DoStartStepAsync(); break; case Step.ExecutionWait: await DoExecutionWaitStepAsync(); break; case Step.ResultWait: await DoResultWaitStepAsync(); break; case Step.RepeatCheck: await DoRepeatCheckStepAsync(); break; } } private async Task DoStartStepAsync() { DateTime startedAt = default; IEnumerable? operations = null; using var context = HeadquartersService.GetNewContext(); var executionStrategy = context.Database.CreateExecutionStrategy(); await executionStrategy.ExecuteAsync(async () => { using var transaction = await context.Database.BeginTransactionAsync(); try { startedAt = DateTime.Now; await HeadquartersService.SetCampaignStartedAsync(context, campaign.Id, startedAt); await ProgressStepAsync(context, (int)Step.ExecutionWait); operations = await HeadquartersService.InitiateOperationsAsync(context, 1, campaign.Id, Operation.OperationType.HouseManagement_ExportSupplyResourceContractData_15_7_0_1); await transaction.CommitAsync(); } catch { transaction?.Rollback(); throw; } }); if (operations != null) { foreach (var operation in operations) { operationExecutionState.EnqueueOperation(operation); } } State = IManager.ManagerState.Started; InvokeOnCampaignStarted(startedAt); } private async Task DoExecutionWaitStepAsync() { if (operationExecutionState.HasCampaignOperation(campaign.Id)) return; await ProgressStepAsync((int)Step.ResultWait); var operations = await HeadquartersService.GetOperationsAsync(campaign.Id); foreach (var operation in operations) { if (!string.IsNullOrEmpty(operation.MessageGuid)) { resultGetState.EnqueueOperation(operation); } } } private async Task DoResultWaitStepAsync() { if (resultGetState.HasCampaignOperation(campaign.Id)) return; await ProgressStepAsync((int)Step.RepeatCheck); } private async Task DoRepeatCheckStepAsync() { if (operationExecutionState.HasCampaignOperation(campaign.Id)) { await ProgressStepAsync((int)Step.ExecutionWait); return; } if (resultGetState.HasCampaignOperation(campaign.Id)) { await ProgressStepAsync((int)Step.ResultWait); return; } var operations = await HeadquartersService.GetNotExecutedRemoteOperationsAsync(campaign.Id); if (operations.Any()) { foreach (var operation in operations) { operationExecutionState.EnqueueOperation(operation); } await ProgressStepAsync((int)Step.ExecutionWait); return; } DateTime endedAt = default; using var context = HeadquartersService.GetNewContext(); var executionStrategy = context.Database.CreateExecutionStrategy(); await executionStrategy.ExecuteAsync(async () => { using var transaction = await context.Database.BeginTransactionAsync(); try { await ProgressStepAsync(context, (int)Step.End); endedAt = DateTime.Now; await HeadquartersService.SetCampaignEndedAsync(context, campaign.Id, endedAt); await transaction.CommitAsync(); } catch { transaction?.Rollback(); throw; } }); State = IManager.ManagerState.Ended; InvokeOnCampaignEnded(endedAt, string.Empty); } } }