public async Task <IActionResult> Index(PublishApprenticeshipsViewModel vm)
        {
            PublishCompleteViewModel CompleteVM = new PublishCompleteViewModel();

            int?sUKPRN = Session.GetInt32("UKPRN");
            int UKPRN;

            if (!sUKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }
            else
            {
                UKPRN = sUKPRN ?? 0;
            }

            CompleteVM.NumberOfCoursesPublished = vm.NumberOfApprenticeships;

            await _cosmosDbQueryDispatcher.ExecuteQuery(new UpdateApprenticeshipStatusesByProviderUkprn
            {
                ProviderUkprn = UKPRN,
                CurrentStatus = ApprenticeshipStatus.MigrationPending | ApprenticeshipStatus.MigrationReadyToGoLive,
                NewStatus     = ApprenticeshipStatus.Archived
            });

            //Archive any existing courses
            await _cosmosDbQueryDispatcher.ExecuteQuery(new UpdateApprenticeshipStatusesByProviderUkprn
            {
                ProviderUkprn = UKPRN,
                CurrentStatus = ApprenticeshipStatus.Live,
                NewStatus     = ApprenticeshipStatus.Archived
            });

            // Publish courses
            await _cosmosDbQueryDispatcher.ExecuteQuery(new UpdateApprenticeshipStatusesByProviderUkprn
            {
                ProviderUkprn = UKPRN,
                CurrentStatus = ApprenticeshipStatus.BulkUploadReadyToGoLive,
                NewStatus     = ApprenticeshipStatus.Live
            });

            CompleteVM.Mode = PublishMode.BulkUpload;

            return(RedirectToAction("Complete", "Apprenticeships", new { CompleteVM }));
        }
        public async Task <IActionResult> Index(PublishApprenticeshipsViewModel vm)
        {
            PublishCompleteViewModel CompleteVM = new PublishCompleteViewModel();

            int?sUKPRN = Session.GetInt32("UKPRN");
            int UKPRN;

            if (!sUKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }
            else
            {
                UKPRN = sUKPRN ?? 0;
            }

            CompleteVM.NumberOfCoursesPublished = vm.NumberOfApprenticeships;
            await _apprenticeshipService.ChangeApprenticeshipStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.MigrationPending, (int)RecordStatus.Archived);

            await _apprenticeshipService.ChangeApprenticeshipStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.MigrationReadyToGoLive, (int)RecordStatus.Archived);

            //Archive any existing courses
            var resultArchivingCourses = await _apprenticeshipService.ChangeApprenticeshipStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.Live, (int)RecordStatus.Archived);

            if (resultArchivingCourses.IsSuccess)
            {
                // Publish courses
                var resultPublishBulkUploadedCourses = await _apprenticeshipService.ChangeApprenticeshipStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.BulkUploadReadyToGoLive, (int)RecordStatus.Live);

                CompleteVM.Mode = PublishMode.BulkUpload;
                if (resultPublishBulkUploadedCourses.IsSuccess)
                {
                    return(RedirectToAction("Complete", "Apprenticeships", new { CompleteVM }));
                }
                else
                {
                    return(RedirectToAction("Index", "Home", new { errmsg = "Publish All BulkUpload-PublishCourses Error" }));
                }
            }
            else
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Publish All BulkUpload-ArchiveCourses Error" }));
            }
        }
        public async Task <IActionResult> Index(PublishViewModel vm)
        {
            PublishCompleteViewModel CompleteVM = new PublishCompleteViewModel();

            int?sUKPRN = Session.GetInt32("UKPRN");
            int UKPRN;

            if (!sUKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }
            else
            {
                UKPRN = sUKPRN ?? 0;
            }

            CompleteVM.NumberOfCoursesPublished = vm.NumberOfCoursesInFiles;

            switch (vm.PublishMode)
            {
            case PublishMode.Migration:

                // Publish migrated courses directly, NO archiving
                var resultPublishMigratedCourses = await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.MigrationReadyToGoLive, (int)RecordStatus.Live);

                CompleteVM.Mode = PublishMode.Migration;
                if (resultPublishMigratedCourses.IsSuccess)
                {
                    return(View("Complete", CompleteVM));
                }
                else
                {
                    return(RedirectToAction("Index", "Home", new { errmsg = "Publish All Migration-PublishCourses Error" }));
                }

            case PublishMode.BulkUpload:

                await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.MigrationPending, (int)RecordStatus.Archived);

                await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.MigrationReadyToGoLive, (int)RecordStatus.Archived);

                //Archive any existing courses
                var resultArchivingCourses = await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.Live, (int)RecordStatus.Archived);

                if (resultArchivingCourses.IsSuccess)
                {
                    // Publish courses
                    var resultPublishBulkUploadedCourses = await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.BulkUploadReadyToGoLive, (int)RecordStatus.Live);

                    CompleteVM.Mode = PublishMode.BulkUpload;
                    if (resultPublishBulkUploadedCourses.IsSuccess)
                    {
                        return(View("Complete", CompleteVM));
                    }
                    else
                    {
                        return(RedirectToAction("Index", "Home", new { errmsg = "Publish All BulkUpload-PublishCourses Error" }));
                    }
                }
                else
                {
                    return(RedirectToAction("Index", "Home", new { errmsg = "Publish All BulkUpload-ArchiveCourses Error" }));
                }

            default:
                return(RedirectToAction("Index", "Home", new { errmsg = "Publish All BulkUpload/Migration Error" }));
            }
        }
        public IActionResult PublishYourFile(PublishYourFileViewModel model)
        {
            int?sUKPRN = _session.GetInt32("UKPRN");
            int UKPRN;

            if (!sUKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }
            else
            {
                UKPRN = sUKPRN ?? 0;
            }

            // COUR-1864
            // Offload this long running activity to a background task.
            // @See:  https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2&tabs=visual-studio

            // Find the provider and flag it as "publish in progress" outside of the queue otherwise the time lag is too great and
            // the UI displays incorrect info

            // Flag the provider as "publish in progress".
            var provider = FindProvider(UKPRN);

            if (null == provider)
            {
                throw new Exception($"Failed to find provider with UK PRN {UKPRN}");
            }
            if (null == provider.BulkUploadStatus)
            {
                provider.BulkUploadStatus = new BulkUploadStatus();
            }
            provider.BulkUploadStatus.PublishInProgress = true;
            var flagProviderResult = _providerService.UpdateProviderDetails(provider).Result;

            if (!flagProviderResult.IsSuccess)
            {
                throw new Exception($"Failed to set the 'publish in progress' flag for provider with UK PRN {UKPRN}.");
            }

            // Now queue the background work to publish the courses.
            _queue.QueueBackgroundWorkItem(async token =>
            {
                var guid           = Guid.NewGuid().ToString();
                var tag            = $"bulk upload publish for provider {UKPRN} for {model.NumberOfCourses} courses.";
                var startTimestamp = DateTime.UtcNow;

                try
                {
                    _logger.LogInformation($"{startTimestamp.ToString("yyyyMMddHHmmss")} Starting background worker {guid} for {tag}");

                    // Publish the bulk-uploaded courses.

                    var resultArchivingCourses = await _courseService.ArchiveCoursesExceptBulkUploadReadytoGoLive(UKPRN, (int)RecordStatus.Archived);
                    if (resultArchivingCourses.IsSuccess)
                    {
                        var resultGoingLive = await _courseService.ChangeCourseRunStatusesForUKPRNSelection(UKPRN, (int)RecordStatus.BulkUploadReadyToGoLive, (int)RecordStatus.Live);
                        if (resultGoingLive.IsSuccess)
                        {
                            // Clear the provider "publish in progress" flag.
                            provider.BulkUploadStatus.PublishInProgress = false;
                            var unflagProviderResult = await _providerService.UpdateProviderDetails(provider);

                            if (!unflagProviderResult.IsSuccess)
                            {
                                throw new Exception($"Failed to clear the 'publish in progress' flag for provider with UK PRN {UKPRN}.");
                            }
                        }
                        // @ToDo: ELSE failure here means we need a manual way to clear the flag
                    }
                    // @ToDo: ELSE failure here means we need a manual way to clear the flag

                    var finishTimestamp = DateTime.UtcNow;
                    _logger.LogInformation($"{finishTimestamp.ToString("yyyyMMddHHmmss")} background worker {guid} finished successfully for {tag}");
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Failed to publish courses from the background worker {guid} for {tag}", ex);
                }

                _logger.LogInformation($"Queued Background Task {guid} is complete.");
            });

            // @ToDo: we'll reach here before the above background task has completed, so need some UI work
            var vm = new PublishCompleteViewModel()
            {
                NumberOfCoursesPublished = model.NumberOfCourses,
                Mode = PublishMode.BulkUpload,
                BackgroundPublishInProgress = provider.BulkUploadStatus.PublishInProgress
            };
            double totalmins = Math.Max(2, (model.NumberOfCourses * _bulkUploadService.BulkUploadSecondsPerRecord / 60));

            vm.BackgroundPublishMinutes = (int)Math.Round(totalmins, 0, MidpointRounding.AwayFromZero);
            return(View("../PublishCourses/InProgress", vm));
        }