示例#1
0
        public CoursesService(
            //ILogger log,
            ICosmosDbHelper cosmosDbHelper,
            SearchServiceWrapper searchServiceWrapper,
            IOptions <ProviderServiceSettings> providerServiceSettings,
            IOptions <VenueServiceSettings> venueServiceSettings,
            IOptions <SearchServiceSettings> searchServiceSettings,
            IOptions <QualificationServiceSettings> qualServiceSettings,
            IOptions <CosmosDbCollectionSettings> settings,
            IOptions <CourseServiceSettings> courseServiceSettings)
        {
            //Throw.IfNull(log, nameof(log));
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(searchServiceWrapper, nameof(searchServiceWrapper));
            Throw.IfNull(settings, nameof(settings));
            Throw.IfNull(providerServiceSettings, nameof(providerServiceSettings));
            Throw.IfNull(venueServiceSettings, nameof(venueServiceSettings));
            Throw.IfNull(qualServiceSettings, nameof(qualServiceSettings));
            Throw.IfNull(searchServiceSettings, nameof(searchServiceSettings));

            //_log = log;
            _cosmosDbHelper          = cosmosDbHelper;
            _settings                = settings.Value;
            _providerServiceSettings = providerServiceSettings.Value;
            _venueServiceSettings    = venueServiceSettings.Value;
            _qualServiceSettings     = qualServiceSettings.Value;
            _searchServiceSettings   = searchServiceSettings.Value;
            _courseServiceSettings   = courseServiceSettings.Value;
            _searchServiceWrapper    = searchServiceWrapper;
        }
 public ApprenticeshipMigrationReportService(
     ICosmosDbHelper cosmosDbHelper,
     IOptions <CosmosDbCollectionSettings> settings)
 {
     _cosmosDbHelper = cosmosDbHelper;
     _settings       = settings.Value;
 }
        public CourseMigrationReportService(ICosmosDbHelper cosmosDbHelper, IOptions<CosmosDbCollectionSettings> settings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(settings, nameof(settings));

            _cosmosDbHelper = cosmosDbHelper;
            _settings = settings.Value;
        }
 public FeChoiceService(
     ICosmosDbHelper cosmosDbHelper,
     IOptions <CosmosDbSettings> cosmosDbSettings,
     IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings) : this(cosmosDbHelper, cosmosDbSettings.Value, cosmosDbCollectionSettings.Value)
 {
     Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
     Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
     Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));
 }
示例#5
0
 public SectorSubjectAreaTier1Service(
     ICosmosDbHelper cosmosDbHelper,
     IOptions <CosmosDbSettings> cosmosDbSettings,
     IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings) : this(cosmosDbHelper, cosmosDbSettings.Value, cosmosDbCollectionSettings.Value)
 {
     Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
     Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
     Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));
 }
 public ApprenticeshipFrameworkService(
     ICosmosDbHelper cosmosDbHelper,
     IOptions <CosmosDbSettings> cosmosDbSettings,
     IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings) : this(cosmosDbHelper, cosmosDbSettings.Value, cosmosDbCollectionSettings.Value)
 {
     Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
     Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
     Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));
 }
 public CourseAuditService(IOptions <SearchServiceSettings> searchServiceSettings, IOptions <VenueServiceSettings> venueServiceSettings,
                           IOptions <ProviderServiceSettings> providerServiceSettings, ICosmosDbHelper cosmosDbHelper, CosmosDbCollectionSettings settings, CosmosDbSettings cosmosDbSettings)
 {
     _searchServiceSettings   = searchServiceSettings.Value;
     _venueServiceSettings    = venueServiceSettings.Value;
     _providerServiceSettings = providerServiceSettings.Value;
     _cosmosDbHelper          = cosmosDbHelper;
     _settings         = settings;
     _cosmosDbSettings = cosmosDbSettings;
 }
示例#8
0
        public ApprenticeshipServiceWrapper(IOptions <ApprenticeshipServiceSettings> settings, ICosmosDbHelper cosmosDbHelper,
                                            IOptions <CosmosDbSettings> cosmosDbSettings,
                                            IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings)
        {
            Throw.IfNull(settings, nameof(settings));
            _settings = settings.Value;

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings.Value;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings.Value;
        }
示例#9
0
        public StandardSectorCodeService(
            ICosmosDbHelper cosmosDbHelper,
            CosmosDbSettings cosmosDbSettings,
            CosmosDbCollectionSettings cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings;
        }
        public ApprenticeshipCollectionService(
            ICosmosDbHelper cosmosDbHelper,
            IOptions <CosmosDbSettings> cosmosDbSettings,
            IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings.Value;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings.Value;
        }
        public FeChoiceService(
            ICosmosDbHelper cosmosDbHelper,
            CosmosDbSettings cosmosDbSettings,
            CosmosDbCollectionSettings cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings;
        }
        public MigrationReportCollectionService(
            ICosmosDbHelper cosmosDbHelper,
            IOptions <CosmosDbSettings> cosmosDbSettings,
            IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings.Value;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings.Value;
        }
示例#13
0
        public SectorSubjectAreaTier1Service(
            ICosmosDbHelper cosmosDbHelper,
            CosmosDbSettings cosmosDbSettings,
            CosmosDbCollectionSettings cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings;
        }
        public ApprenticeshipFrameworkService(
            ICosmosDbHelper cosmosDbHelper,
            CosmosDbSettings cosmosDbSettings,
            CosmosDbCollectionSettings cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings;
        }
        public VenueCollectionService(
            ICosmosDbHelper cosmosDbHelper,
            IOptions <CosmosDbSettings> cosmosDbSettings,
            IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _cosmosDbSettings           = cosmosDbSettings.Value;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings.Value;
            _documentClient             = _cosmosDbHelper.GetClient();
        }
示例#16
0
        public ProviderCollectionService(
            ICosmosDbHelper cosmosDbHelper,
            IOptions <CosmosDbSettings> cosmosDbSettings,
            IOptions <CosmosDbCollectionSettings> cosmosDbCollectionSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(cosmosDbSettings, nameof(cosmosDbSettings));
            Throw.IfNull(cosmosDbCollectionSettings, nameof(cosmosDbCollectionSettings));

            _cosmosDbHelper             = cosmosDbHelper;
            _client                     = cosmosDbHelper.GetClient();
            _cosmosDbSettings           = cosmosDbSettings.Value;
            _cosmosDbCollectionSettings = cosmosDbCollectionSettings.Value;
        }
示例#17
0
 public ApprenticeshipService(
     ICosmosDbHelper cosmosDbHelper,
     IOptions <CosmosDbCollectionSettings> cosmosSettings,
     IDASHelper DASHelper,
     IProviderServiceClient providerServiceClient,
     IReferenceDataServiceClient referenceDataServiceClient,
     TelemetryClient telemetryClient)
 {
     _cosmosDbHelper             = cosmosDbHelper ?? throw new ArgumentNullException(nameof(cosmosDbHelper));
     _cosmosSettings             = cosmosSettings?.Value ?? throw new ArgumentNullException(nameof(cosmosSettings));
     _DASHelper                  = DASHelper ?? throw new ArgumentNullException(nameof(DASHelper));
     _providerServiceClient      = providerServiceClient ?? throw new ArgumentNullException(nameof(providerServiceClient));
     _referenceDataServiceClient = referenceDataServiceClient ?? throw new ArgumentNullException(nameof(referenceDataServiceClient));
     _telemetryClient            = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient));
 }
示例#18
0
 public static async Task Run(
     [TimerTrigger("%MigrationReportSchedule%")] TimerInfo myTimer,
     ILogger log,
     [Inject] IConfigurationRoot configuration,
     [Inject] ICosmosDbHelper cosmosDbHelper,
     [Inject] IBlobStorageHelper blobHelper,
     [Inject] IProviderCollectionService providerCollectionService,
     [Inject] ICourseCollectionService courseCollectionService,
     [Inject] IApprenticeshipCollectionService apprenticeshipCollectionService,
     [Inject] IMigrationReportCollectionService migrationReportCollectionService)
 {
     await new MigrationReportGeneratorService().Run(
         log, configuration, cosmosDbHelper, blobHelper, providerCollectionService, courseCollectionService,
         apprenticeshipCollectionService, migrationReportCollectionService
         );
 }
        public ApprenticeshipService(
            ICosmosDbHelper cosmosDbHelper,
            ITribalHelper tribalHelper,
            IOptions <CosmosDbCollectionSettings> settings,
            IOptions <ProviderServiceSettings> providerServiceSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(tribalHelper, nameof(tribalHelper));
            Throw.IfNull(settings, nameof(settings));
            Throw.IfNull(providerServiceSettings, nameof(providerServiceSettings));

            _cosmosDbHelper          = cosmosDbHelper;
            _tribalHelper            = tribalHelper;
            _settings                = settings.Value;
            _providerServiceSettings = providerServiceSettings.Value;
        }
        public OnlineCoursesService(
            ICosmosDbHelper cosmosDbHelper,
            OnlineCourseSearchServiceWrapper courseSearchServiceWrapper,
            IOptions <ProviderServiceSettings> providerServiceSettings,
            IOptions <VenueServiceSettings> venueServiceSettings,
            IOptions <SearchServiceSettings> searchServiceSettings,
            IOptions <QualificationServiceSettings> qualServiceSettings,
            IOptions <CosmosDbCollectionSettings> settings,
            IOptions <CourseServiceSettings> courseServiceSettings)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(courseSearchServiceWrapper, nameof(courseSearchServiceWrapper));
            Throw.IfNull(settings, nameof(settings));
            Throw.IfNull(providerServiceSettings, nameof(providerServiceSettings));
            Throw.IfNull(venueServiceSettings, nameof(venueServiceSettings));
            Throw.IfNull(qualServiceSettings, nameof(qualServiceSettings));
            Throw.IfNull(searchServiceSettings, nameof(searchServiceSettings));

            _courseSearchServiceWrapper = courseSearchServiceWrapper;
        }
        public static async Task Run(
            string input,          // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] ILoggerFactory loggerFactory
            )
        {
            var    logger             = loggerFactory.CreateLogger(typeof(DeleteInvalidVenues));
            var    databaseId         = configuration["CosmosDbSettings:DatabaseId"];
            var    venueCollectionId  = "venues";
            var    documentClient     = cosmosDbHelper.GetClient();
            var    venueCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, venueCollectionId);
            var    deleteCount        = 0;
            string continuation       = null;

            do
            {
                var feedOptions = new FeedOptions()
                {
                    RequestContinuation = continuation
                };

                var queryResponse = await documentClient.CreateDocumentQuery <Venue>(venueCollectionUri, feedOptions)
                                    .Where(p => p.Latitude == null || p.Longitude == null)
                                    .AsDocumentQuery()
                                    .ExecuteNextAsync <Venue>();

                foreach (var ven in queryResponse)
                {
                    var item = UriFactory.CreateDocumentUri(databaseId, venueCollectionId, ven.ID);
                    await documentClient.DeleteDocumentAsync(item);

                    deleteCount++;
                    logger.LogInformation($"Deleted venue: {ven.VenueID}");
                }
                continuation = queryResponse.ResponseContinuation;
            }while (continuation != null);

            Console.WriteLine($"Deleted {deleteCount} venues with missing lat/long.");
            logger.LogError($"Deleted {deleteCount} venues with missing lat/long.");
        }
        public static async Task Run(
            string input,                              // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] ILoggerFactory loggerFactory,
            [Inject] IApprenticeshipCollectionService apprenticeshipCollectionService)
        {
            var databaseId = configuration["CosmosDbSettings:DatabaseId"];
            var apprenticeshipCollectionId = "apprenticeship";
            var documentClient             = cosmosDbHelper.GetClient();
            var logger    = loggerFactory.CreateLogger(typeof(ArchivePendingApprenticeships));
            int count     = 0;
            var updatedBy = "ArchivePendingApprenticeships";

            var queryResponse = await apprenticeshipCollectionService.GetArchivedApprenticeshipsAsync();

            foreach (var doc in queryResponse)
            {
                //mark every location as arhived regardless of their status
                foreach (var loc in doc.ApprenticeshipLocations)
                {
                    loc.RecordStatus = CourseDirectory.Models.Enums.RecordStatus.Archived;
                    loc.UpdatedBy    = updatedBy;
                    loc.UpdatedDate  = DateTime.UtcNow;
                }

                doc.UpdatedBy   = updatedBy;
                doc.UpdatedDate = DateTime.UtcNow;

                var documentLink = UriFactory.CreateDocumentUri(databaseId, apprenticeshipCollectionId, doc.id.ToString());
                await documentClient.ReplaceDocumentAsync(documentLink, doc);

                count++;
            }

            logger.LogInformation($"Archived {count} Apprenticeships");
            Console.WriteLine($"Archived {count} Apprenticeships");
        }
        public CoursesService(
            ICosmosDbHelper cosmosDbHelper,
            ISearchServiceWrapper searchServiceWrapper,
            IOptions <SearchServiceSettings> searchServiceSettings,
            IOptions <CosmosDbCollectionSettings> settings,
            ProviderServiceWrapper providerServiceWrapper,
            QualificationServiceWrapper qualificationServiceWrapper,
            VenueServiceWrapper venueServiceWrapper,
            FeChoiceServiceWrapper feChoiceServiceWrapper)
        {
            Throw.IfNull(cosmosDbHelper, nameof(cosmosDbHelper));
            Throw.IfNull(searchServiceWrapper, nameof(searchServiceWrapper));
            Throw.IfNull(settings, nameof(settings));
            Throw.IfNull(searchServiceSettings, nameof(searchServiceSettings));

            _cosmosDbHelper              = cosmosDbHelper;
            _settings                    = settings.Value;
            _searchServiceSettings       = searchServiceSettings.Value;
            _searchServiceWrapper        = searchServiceWrapper;
            _providerServiceWrapper      = providerServiceWrapper;
            _qualificationServiceWrapper = qualificationServiceWrapper;
            _venueServiceWrapper         = venueServiceWrapper;
            _feChoiceServiceWrapper      = feChoiceServiceWrapper;
        }
示例#24
0
 public CourseReportGenerationService(ICosmosDbHelper cosmosDbHelper, CosmosDbCollectionSettings settings)
 {
     _cosmosDbHelper = cosmosDbHelper;
     _settings       = settings;
 }
示例#25
0
        public static async Task Run(
            string input,  // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] IBlobStorageHelper blobHelper,
            [Inject] ILoggerFactory loggerFactory)
        {
            var whitelistFileName          = "ProviderWhiteList.txt";
            var venuesCollectionId         = "venues";
            var coursesCollectionId        = "courses";
            var apprenticeshipCollectionId = "apprenticeship";
            var blobContainer  = configuration["BlobStorageSettings:Container"];
            var databaseId     = configuration["CosmosDbSettings:DatabaseId"];
            var documentClient = cosmosDbHelper.GetClient();
            var updatedBy      = "ArchiveVenues";
            var logger         = loggerFactory.CreateLogger(typeof(ArchiveCourses));
            var whitelist      = await GetProviderWhiteList();

            var venueCollectionUri          = UriFactory.CreateDocumentCollectionUri(databaseId, venuesCollectionId);
            var coursesCollectionUri        = UriFactory.CreateDocumentCollectionUri(databaseId, coursesCollectionId);
            var apprenticeshipCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, apprenticeshipCollectionId);
            var totalArchived = 0;
            var totalCoursesReferencingOldVenue      = 0;
            var totalApprenticeshipReferenceoldVenue = 0;

            using (var logStream = new MemoryStream())
                using (var logStreamWriter = new StreamWriter(logStream))
                    using (var logCsvWriter = new CsvWriter(logStreamWriter, CultureInfo.InvariantCulture))
                    {
                        // archived venues
                        logCsvWriter.WriteField("UKPRN");
                        logCsvWriter.WriteField("Archived VenueId");
                        logCsvWriter.WriteField("Archived Venue Name");
                        logCsvWriter.WriteField("Archived Venue Address1");
                        logCsvWriter.WriteField("New VenueId");
                        logCsvWriter.WriteField("New Venue Name");
                        logCsvWriter.WriteField("New Venue Address1");
                        logCsvWriter.WriteField("Course Run Id");
                        logCsvWriter.WriteField("ApprenticeshipLocation Id");
                        logCsvWriter.WriteField("Message");
                        logCsvWriter.WriteField("Type");

                        logCsvWriter.NextRecord();

                        foreach (var ukprn in whitelist)
                        {
                            try
                            {
                                int totalArchivedForProvider = 0;
                                var allVenuesForProvider     = await GetVenues(ukprn);

                                var allCoursesForProvider = await GetCourses(ukprn);

                                var allApprenticeshipsForProvider = await GetApprenticeships(ukprn);

                                //identify duplicates
                                var comp         = new VenueEqualityComparer();
                                var uniqueGroups = allVenuesForProvider.GroupBy(x => x, comp);

                                //archive duplicate venues
                                foreach (var item in uniqueGroups)
                                {
                                    //tribal venues & trival locations when venues were migrated, both locations and & venues from tribal
                                    //were migrated as seperate records even though the address was the same. The below attempts to merge the two.
                                    var migratedVenues      = item.ToList().Where(x => x.CreatedBy == "VenueMigrator" && x.UpdatedBy != updatedBy); //expecting more than one here.
                                    var tribalLocationVenue = migratedVenues.FirstOrDefault(x => x.LocationId != null);                             //Migrated Location
                                    var tribalVenue         = migratedVenues.FirstOrDefault(x => x.VenueID != 0);                                   //Migrated Venue
                                    var currentVenue        = MergeVenue(tribalLocationVenue, tribalVenue, out string venueType);

                                    //If there is no current venue, it means that either the venue was created by a previous migration
                                    //e.g. CreatedBy != VenueMigrator and all Venues must be Archived
                                    //OR
                                    //the Archiver has already archived this group e.g. UpdatedBy == "ArchiveVenues" and therefore we skip changing
                                    //this record to archived, as the duplicates have already been removed.
                                    if (currentVenue == null)
                                    {
                                        var venuesNotMigratedByMigrationProcess = item.ToList();
                                        foreach (var archivingVenue in venuesNotMigratedByMigrationProcess)
                                        {
                                            //only archive venues that haven't already been processed by archiveVenues function
                                            if (archivingVenue.UpdatedBy != updatedBy)
                                            {
                                                await ArchiveVenue(archivingVenue, ukprn);

                                                logCsvWriter.WriteField(ukprn);
                                                logCsvWriter.WriteField(archivingVenue.ID);
                                                logCsvWriter.WriteField(archivingVenue.VenueName);
                                                logCsvWriter.WriteField($"{archivingVenue.Address1},{archivingVenue.Address2}, {archivingVenue.PostCode}");
                                                logCsvWriter.WriteField("");
                                                logCsvWriter.WriteField("");
                                                logCsvWriter.WriteField("");
                                                logCsvWriter.WriteField("");
                                                logCsvWriter.WriteField(""); //ApprenticeshipLocationId
                                                logCsvWriter.WriteField($"All old Venues archived, there were {venuesNotMigratedByMigrationProcess.Count()} duplicate Venues.");
                                                logCsvWriter.WriteField("Venue");
                                                logCsvWriter.NextRecord();
                                            }
                                        }

                                        //continue to next ukprn as per the above logic
                                        continue;
                                    }

                                    var nonCurrentVenues = item.ToList().Where(x => x.ID != currentVenue.ID).ToList(); // All venues that will be archived

                                    //if there is a location venue & venue, add venue to list of non current venues
                                    //and update the currentVenue to indicate it has been merged.
                                    if (venueType == "Both")
                                    {
                                        nonCurrentVenues.Add(tribalVenue);

                                        await ReplaceMergedREcord(currentVenue);
                                    }

                                    //courses that have course runs with old venue references.
                                    var courseRunsOldVenue = allCoursesForProvider.Where(p => p.CourseRuns.Any(x => nonCurrentVenues.Where(y => Guid.Parse(y.ID) == x.VenueId).Count() > 0)).ToList();
                                    totalCoursesReferencingOldVenue += courseRunsOldVenue.Count();

                                    //apprenticeships that have locations with old venue refe
                                    var apprenticeshipsOldVenue = allApprenticeshipsForProvider.Where(p => p.ApprenticeshipLocations.Any(x => nonCurrentVenues.Where(y => Guid.Parse(y.ID) == x.LocationGuidId).Count() > 0)).ToList();
                                    totalApprenticeshipReferenceoldVenue += apprenticeshipsOldVenue.Count();

                                    Console.WriteLine($"Archiving {nonCurrentVenues.Count()} - {ukprn} - {currentVenue.Address1}");

                                    //handle archiving venue
                                    foreach (var archivingVenue in nonCurrentVenues)
                                    {
                                        await ArchiveVenue(archivingVenue, ukprn);

                                        logCsvWriter.WriteField(ukprn);
                                        logCsvWriter.WriteField(archivingVenue.ID);
                                        logCsvWriter.WriteField(archivingVenue.VenueName);
                                        logCsvWriter.WriteField($"{archivingVenue.Address1},{archivingVenue.Address2}, {archivingVenue.PostCode}");
                                        logCsvWriter.WriteField(currentVenue.ID);
                                        logCsvWriter.WriteField(currentVenue.VenueName);
                                        logCsvWriter.WriteField($"{currentVenue.Address1},{currentVenue.Address2}, {currentVenue.PostCode}");
                                        logCsvWriter.WriteField("");
                                        logCsvWriter.WriteField(""); //ApprenticeshipLocationId
                                        logCsvWriter.WriteField($"There were {nonCurrentVenues.Count()} duplicate Venues");
                                        logCsvWriter.WriteField("Venue");
                                        logCsvWriter.NextRecord();

                                        totalArchived++;
                                        totalArchivedForProvider++;

                                        //update courses that reference old venues
                                        foreach (var course in courseRunsOldVenue)
                                        {
                                            //update venue to point at new venue.
                                            course.CourseRuns.Where(p => nonCurrentVenues.Any(y => Guid.Parse(y.ID) == p.VenueId))
                                            .ToList()
                                            .ForEach(x =>
                                            {
                                                //update course instance
                                                x.VenueId   = Guid.Parse(currentVenue.ID);
                                                x.UpdatedBy = updatedBy;

                                                //log change
                                                logCsvWriter.WriteField(ukprn);
                                                logCsvWriter.WriteField(archivingVenue.ID);
                                                logCsvWriter.WriteField(archivingVenue.VenueName);
                                                logCsvWriter.WriteField($"{archivingVenue.Address1},{archivingVenue.Address2}, {archivingVenue.PostCode}");
                                                logCsvWriter.WriteField(currentVenue.ID);
                                                logCsvWriter.WriteField(currentVenue.VenueName);
                                                logCsvWriter.WriteField($"{currentVenue.Address1},{currentVenue.Address2}, {currentVenue.PostCode}");
                                                logCsvWriter.WriteField(x.CourseInstanceId);
                                                logCsvWriter.WriteField("");                                      //ApprenticeshipLocationId
                                                logCsvWriter.WriteField($"There were {nonCurrentVenues.Count()} duplicate Venues");
                                                logCsvWriter.WriteField("Course");
                                                logCsvWriter.NextRecord();
                                            });

                                            //update venue to reference currentVenue
                                            var coursedocumentLink = UriFactory.CreateDocumentUri(databaseId, coursesCollectionId, course.id.ToString());
                                            await documentClient.ReplaceDocumentAsync(coursedocumentLink, course, new RequestOptions()
                                            {
                                                PartitionKey = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                                            });
                                        }

                                        //update courses that reference old venues
                                        foreach (var apprenticeship in apprenticeshipsOldVenue)
                                        {
                                            //update venue to point at new venue for locations
                                            apprenticeship.ApprenticeshipLocations.Where(p => nonCurrentVenues.Any(y => Guid.Parse(y.ID) == p.LocationGuidId))
                                            .ToList()
                                            .ForEach(x =>
                                            {
                                                //update apprenticeship location
                                                x.LocationGuidId = Guid.Parse(currentVenue.ID);
                                                x.UpdatedBy      = updatedBy;
                                                x.LocationId     = currentVenue.LocationId;

                                                //log change
                                                logCsvWriter.WriteField(ukprn);
                                                logCsvWriter.WriteField(archivingVenue.ID);
                                                logCsvWriter.WriteField(archivingVenue.VenueName);
                                                logCsvWriter.WriteField($"{archivingVenue.Address1},{archivingVenue.Address2}, {archivingVenue.PostCode}");
                                                logCsvWriter.WriteField(currentVenue.ID);
                                                logCsvWriter.WriteField(currentVenue.VenueName);
                                                logCsvWriter.WriteField($"{currentVenue.Address1},{currentVenue.Address2}, {currentVenue.PostCode}");
                                                logCsvWriter.WriteField("");                                                           //Course Instance
                                                logCsvWriter.WriteField(x.Id);
                                                logCsvWriter.WriteField($"There were {nonCurrentVenues.Count()} duplicate Venues");
                                                logCsvWriter.WriteField("Apprenticeship");
                                                logCsvWriter.NextRecord();
                                            });


                                            //update apprenticeship to reference currentvenue
                                            var apprenticeshipDocumentLink = UriFactory.CreateDocumentUri(databaseId, apprenticeshipCollectionId, apprenticeship.id.ToString());
                                            await documentClient.ReplaceDocumentAsync(apprenticeshipDocumentLink, apprenticeship, new RequestOptions());
                                        }
                                    }
                                }
                                Console.WriteLine($"Archived {totalArchivedForProvider} Venues for {ukprn}");
                                logger.LogInformation($"Archived {totalArchivedForProvider} Venues for {ukprn}");
                            }
                            catch (Exception e)
                            {
                                logger.LogError(e.Message);
                            }
                        }

                        // Upload log CSV to blob storage
                        {
                            logStreamWriter.Flush();

                            logStream.Seek(0L, SeekOrigin.Begin);

                            var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference("ArchivedVenues");
                            await blob.UploadFromStreamAsync(logStream);
                        }
                    }


            Console.WriteLine($"Total Course runs that reference an old venue: {totalCoursesReferencingOldVenue}");
            Console.WriteLine($"Total Apparenticeships that reference an old Venue {totalApprenticeshipReferenceoldVenue}");
            Console.WriteLine($"Total Archived Venues {totalArchived}");

            async Task ArchiveVenue(Venue archivingVenue, int ukprn)
            {
                //archive venue
                archivingVenue.Status      = VenueStatus.Archived;
                archivingVenue.UpdatedBy   = updatedBy;
                archivingVenue.DateUpdated = DateTime.Now;
                var documentLink = UriFactory.CreateDocumentUri(databaseId, venuesCollectionId, archivingVenue.ID.ToString());
                await documentClient.ReplaceDocumentAsync(documentLink, archivingVenue, new RequestOptions());
            }

            async Task ReplaceMergedREcord(Venue mergedRecord)
            {
                //archive venue
                mergedRecord.UpdatedBy   = updatedBy;
                mergedRecord.DateUpdated = DateTime.Now;
                var documentLink = UriFactory.CreateDocumentUri(databaseId, venuesCollectionId, mergedRecord.ID.ToString());
                await documentClient.ReplaceDocumentAsync(documentLink, mergedRecord, new RequestOptions());
            }

            Venue MergeVenue(Venue locationVenue, Venue venue, out string selectedVenue)
            {
                //default to first none null venue, location is chosen first.
                var ven = locationVenue ?? venue;

                if (locationVenue != null && venue != null)
                {
                    selectedVenue = "Both";
                }
                else if (locationVenue == null && venue != null)
                {
                    selectedVenue = "Venue";
                }
                else if (locationVenue != null && venue == null)
                {
                    selectedVenue = "Location";
                }
                else
                {
                    selectedVenue = "None";
                }

                //if there are two venues, one with a venue id & one with a location id.
                //merge them.
                if (locationVenue != null && venue != null)
                {
                    ven.VenueID = venue.VenueID;
                }

                return(ven);
            }

            async Task <List <Course> > GetCourses(int ukprn)
            {
                var courses = new List <Course>();
                //Get all courses
                string continuation = null;

                do
                {
                    var feedOptions = new FeedOptions()
                    {
                        RequestContinuation = continuation,
                        PartitionKey        = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                    };

                    var queryResponse = await documentClient.CreateDocumentQuery <Course>(coursesCollectionUri, feedOptions)
                                        .Where(p => p.ProviderUKPRN == ukprn && p.CourseStatus != CourseDirectory.Models.Enums.RecordStatus.Archived)
                                        .AsDocumentQuery()
                                        .ExecuteNextAsync <Course>();

                    courses.AddRange(queryResponse.ToList());

                    continuation = queryResponse.ResponseContinuation;
                }while (continuation != null);
                return(courses);
            }

            async Task <List <Venue> > GetVenues(int ukprn)
            {
                var    venues       = new List <Venue>();
                string continuation = null;

                do
                {
                    var feedOptions = new FeedOptions()
                    {
                        RequestContinuation = continuation
                    };

                    var queryResponse = await documentClient.CreateDocumentQuery <Venue>(venueCollectionUri, feedOptions)
                                        .Where(p => p.UKPRN == ukprn && p.Status == VenueStatus.Live)
                                        .AsDocumentQuery()
                                        .ExecuteNextAsync <Venue>();

                    venues.AddRange(queryResponse.ToList());

                    continuation = queryResponse.ResponseContinuation;
                }while (continuation != null);
                return(venues);
            }

            async Task <List <Apprenticeship> > GetApprenticeships(int ukprn)
            {
                var    apprenticeships = new List <Apprenticeship>();
                string continuation    = null;

                //get all apprenticeships for provider
                do
                {
                    var feedOptions = new FeedOptions()
                    {
                        RequestContinuation = continuation,
                        PartitionKey        = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                    };

                    //try/catch required as there are Apprenticeship records that are not valid (venueId is null in cosmos).
                    try
                    {
                        var queryResponse = await documentClient.CreateDocumentQuery <Apprenticeship>(apprenticeshipCollectionUri, feedOptions)
                                            .Where(p => p.ProviderUKPRN == ukprn && p.RecordStatus != CourseDirectory.Models.Enums.RecordStatus.Archived)
                                            .AsDocumentQuery()
                                            .ExecuteNextAsync <Apprenticeship>();

                        apprenticeships.AddRange(queryResponse);
                        continuation = queryResponse.ResponseContinuation;
                    }
                    catch (Exception)
                    {
                        continuation = null;
                    }
                }while (continuation != null);

                return(apprenticeships);
            }

            async Task <ISet <int> > GetProviderWhiteList()
            {
                var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference(whitelistFileName);

                var ms = new MemoryStream();
                await blob.DownloadToStreamAsync(ms);

                ms.Seek(0L, SeekOrigin.Begin);

                var    results = new HashSet <int>();
                string line;

                using (var reader = new StreamReader(ms))
                {
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        var ukprn = int.Parse(line);
                        results.Add(ukprn);
                    }
                }

                return(results);
            }
        }
        public static async Task Run(
            string input,  // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] IBlobStorageHelper blobHelper,
            [Inject] ILoggerFactory loggerFactory)
        {
            var cosmosDbClient             = cosmosDbHelper.GetClient();
            var databaseId                 = configuration["CosmosDbSettings:DatabaseId"];
            var apprenticeshipCollectionId = "apprenticeship";
            var whitelistFileName          = "ProviderWhiteList.txt";
            var blobContainer              = configuration["BlobStorageSettings:Container"];
            var whitelist = await GetProviderWhiteList();

            var logFileName       = $"SetRadiusToTen-{DateTime.Now.ToString("dd-MM-yy HHmm")}";
            var apprenticehipsUri = UriFactory.CreateDocumentCollectionUri(databaseId, apprenticeshipCollectionId);
            var logger            = loggerFactory.CreateLogger(typeof(SetApprenticeshipLocationRadiusToTen));

            using (var logStream = new MemoryStream())
                using (var logStreamWriter = new StreamWriter(logStream))
                    using (var logCsvWriter = new CsvWriter(logStreamWriter, CultureInfo.InvariantCulture))
                    {
                        logCsvWriter.WriteField("ApprenticeshoId");
                        logCsvWriter.WriteField("ApprenticeshipLocationId");
                        logCsvWriter.NextRecord();

                        try
                        {
                            foreach (var ukprn in whitelist)
                            {
                                string continuation = null;
                                do
                                {
                                    var feedOptions = new FeedOptions()
                                    {
                                        RequestContinuation = continuation,
                                        PartitionKey        = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                                    };
                                    var queryResponse = await cosmosDbClient.CreateDocumentQuery <Apprenticeship>(apprenticehipsUri, feedOptions)
                                                        .Where(p => p.ProviderUKPRN == ukprn)
                                                        .AsDocumentQuery()
                                                        .ExecuteNextAsync <Apprenticeship>();

                                    foreach (var doc in queryResponse)
                                    {
                                        foreach (var loc in doc.ApprenticeshipLocations)
                                        {
                                            if (loc.Radius == 10)
                                            {
                                                loc.Radius    = 30;
                                                loc.UpdatedBy = nameof(SetApprenticeshipLocationRadiusToTen);

                                                logCsvWriter.WriteField(doc.id);
                                                logCsvWriter.WriteField(loc.Id);
                                                logCsvWriter.NextRecord();
                                            }
                                        }

                                        if (doc.ApprenticeshipLocations.Any(x => x.UpdatedBy == nameof(SetApprenticeshipLocationRadiusToTen)))
                                        {
                                            doc.UpdatedBy = nameof(SetApprenticeshipLocationRadiusToTen);
                                            var documentLink = UriFactory.CreateDocumentUri(databaseId, apprenticeshipCollectionId, doc.id.ToString());
                                            await cosmosDbClient.ReplaceDocumentAsync(documentLink, doc, new RequestOptions()
                                            {
                                                PartitionKey = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                                            });
                                        }
                                    }
                                    continuation = queryResponse.ResponseContinuation;
                                } while (continuation != null);
                            }
                        } catch (Exception e)
                        {
                            logger.LogError(e.Message);
                        }

                        // Upload log CSV to blob storage
                        {
                            logStreamWriter.Flush();

                            logStream.Seek(0L, SeekOrigin.Begin);

                            var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference(logFileName);
                            await blob.UploadFromStreamAsync(logStream);
                        }
                    }

            async Task <ISet <int> > GetProviderWhiteList()
            {
                var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference(whitelistFileName);

                var ms = new MemoryStream();
                await blob.DownloadToStreamAsync(ms);

                ms.Seek(0L, SeekOrigin.Begin);

                var    results = new HashSet <int>();
                string line;

                using (var reader = new StreamReader(ms))
                {
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        var ukprn = int.Parse(line);
                        results.Add(ukprn);
                    }
                }
                return(results);
            }
        }
示例#27
0
        public static async Task Run(
            string input,  // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] IBlobStorageHelper blobHelper,
            [Inject] ILoggerFactory loggerFactory,
            [Inject] IBlobStorageHelper blobhelper)
        {
            var whitelistFileName      = "ProviderWhiteList.txt";
            var pendingCoursesFileName = $"CoursesWithNoCostOrCostDecription-{DateTime.Now.ToString("dd-MM-yy HHmm")}";
            var blobContainer          = configuration["BlobStorageSettings:Container"];
            var outputContainer        = blobhelper.GetBlobContainer(configuration["BlobStorageSettings:Container"]);
            var databaseId             = configuration["CosmosDbSettings:DatabaseId"];
            var coursesCollectionId    = "courses";
            var documentClient         = cosmosDbHelper.GetClient();
            var result = new List <MigrationPendingCourseRunResult>();

            var    coursesCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, coursesCollectionId);
            var    logger       = loggerFactory.CreateLogger(typeof(ArchiveCourses));
            string continuation = null;
            int    count        = 0;

            var whitelist = await GetProviderWhiteList();

            foreach (var ukprn in whitelist)
            {
                do
                {
                    var feedOptions = new FeedOptions()
                    {
                        RequestContinuation       = continuation,
                        EnableCrossPartitionQuery = true,
                        PartitionKey = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                    };

                    //find courses that do not have a cost desciption or cost.
                    var queryResponse = await documentClient.CreateDocumentQuery <Course>(coursesCollectionUri, feedOptions)
                                        .Where(p => p.CourseRuns.Any(x => x.Cost == null && (x.CostDescription == "" || x.CostDescription == null)) &&
                                               (p.CourseStatus == RecordStatus.Live || p.CourseStatus == RecordStatus.MigrationPendingAndLive))
                                        .AsDocumentQuery()
                                        .ExecuteNextAsync <Course>();

                    //update course run to be migration pending.
                    foreach (var doc in queryResponse)
                    {
                        var currentStatus = doc.CourseStatus;

                        //Course instance id that caused the course to go to migration pending.
                        var message = string.Join("\n", doc.CourseRuns.Where(x => x.Cost == null && (x.CostDescription == "" || x.CostDescription == null))
                                                  .ToList()
                                                  .Select(x => $"Course Instance {x.CourseInstanceId} Invalid"));

                        doc.CourseRuns.Where(x => x.Cost == null && (x.CostDescription == "" || x.CostDescription == null))
                        .ToList()
                        .ForEach(x => x.RecordStatus = CourseDirectory.Models.Enums.RecordStatus.MigrationPending);


                        var documentLink = UriFactory.CreateDocumentUri(databaseId, coursesCollectionId, doc.id.ToString());
                        await documentClient.ReplaceDocumentAsync(documentLink, doc, new RequestOptions()
                        {
                            PartitionKey = new Microsoft.Azure.Documents.PartitionKey(ukprn)
                        });

                        result.Add(new MigrationPendingCourseRunResult {
                            CourseId = doc.CourseId, StatusId = doc.CourseStatus, Message = message
                        });

                        count++;
                    }
                    continuation = queryResponse.ResponseContinuation;
                } while (continuation != null);
            }

            //Log Results to blob storage
            var resultsObjBytes = GetResultAsByteArray(result);

            await WriteResultsToBlobStorage(resultsObjBytes);


            logger.LogInformation($"{count} courses Have been made pending");

            async Task <ISet <int> > GetProviderWhiteList()
            {
                var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference(whitelistFileName);

                var ms = new MemoryStream();
                await blob.DownloadToStreamAsync(ms);

                ms.Seek(0L, SeekOrigin.Begin);

                var    results = new HashSet <int>();
                string line;

                using (var reader = new StreamReader(ms))
                {
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        var ukprn = int.Parse(line);
                        results.Add(ukprn);
                    }
                }

                return(results);
            }

            async Task WriteResultsToBlobStorage(byte[] data)
            {
                await blobhelper.UploadFile(outputContainer, pendingCoursesFileName, data);
            }

            byte[] GetResultAsByteArray(IList <MigrationPendingCourseRunResult> ob)
            {
                using (var memoryStream = new System.IO.MemoryStream())
                {
                    using (var streamWriter = new System.IO.StreamWriter(memoryStream))
                        using (var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture))
                        {
                            csvWriter.WriteRecords <MigrationPendingCourseRunResult>(ob);
                            csvWriter.Flush();
                        }

                    return(memoryStream.ToArray());
                }
            }
        }
示例#28
0
        public static async Task Run(
            string input,                              // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] IBlobStorageHelper blobHelper,
            [Inject] ILoggerFactory loggerFactory,
            [Inject] IBlobStorageHelper blobhelper)
        {
            var blobContainer               = configuration["BlobStorageSettings:Container"];
            var outputContainer             = blobhelper.GetBlobContainer(configuration["BlobStorageSettings:Container"]);
            var databaseId                  = configuration["CosmosDbSettings:DatabaseId"];
            var apprenticeshipCollectionId  = "apprenticeship";
            var documentClient              = cosmosDbHelper.GetClient();
            var apprenticeshipCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, apprenticeshipCollectionId);
            var logger    = loggerFactory.CreateLogger(typeof(ArchiveOldMigratedApprenticeships));
            int count     = 0;
            var updatedBy = "ArchiveOldMigratedApprenticeships";


            string continuation = null;

            do
            {
                var feedOptions = new FeedOptions()
                {
                    RequestContinuation       = continuation,
                    EnableCrossPartitionQuery = true
                };

                //try/catch required as there are Apprenticeship records that are not valid (venueId is null in cosmos).
                try
                {
                    var queryResponse = await documentClient.CreateDocumentQuery <Apprenticeship>(apprenticeshipCollectionUri, feedOptions)
                                        .Where(p => p.CreatedBy == "DFC – Apprenticeship Migration Tool")
                                        .AsDocumentQuery()
                                        .ExecuteNextAsync <Apprenticeship>();

                    foreach (var doc in queryResponse)
                    {
                        if (doc.RecordStatus.HasFlag(CourseDirectory.Models.Enums.RecordStatus.MigrationPending) || doc.RecordStatus == CourseDirectory.Models.Enums.RecordStatus.Live)
                        {
                            //mark every location as arhived
                            foreach (var loc in doc.ApprenticeshipLocations)
                            {
                                loc.RecordStatus = CourseDirectory.Models.Enums.RecordStatus.Archived;
                                loc.UpdatedBy    = updatedBy;
                            }
                            doc.UpdatedBy = updatedBy;

                            var documentLink = UriFactory.CreateDocumentUri(databaseId, apprenticeshipCollectionId, doc.id.ToString());
                            await documentClient.ReplaceDocumentAsync(documentLink, doc, new RequestOptions());

                            count++;
                        }
                    }
                    continuation = queryResponse.ResponseContinuation;
                }
                catch (Exception)
                {
                    continuation = null;
                }
            }while (continuation != null);

            logger.LogInformation($"Archived {count} Apprenticeships");
            Console.WriteLine($"Archived {count} Apprenticeships");
        }
 public DfcReportService(ICosmosDbHelper cosmosDbHelper, IOptions <CosmosDbCollectionSettings> settings)
 {
     _cosmosDbHelper = cosmosDbHelper;
     _settings       = settings.Value;
 }
        public static async Task Run(
            string input,  // Work around https://github.com/Azure/azure-functions-vs-build-sdk/issues/168
            [Inject] IConfigurationRoot configuration,
            [Inject] ICosmosDbHelper cosmosDbHelper,
            [Inject] IBlobStorageHelper blobHelper,
            [Inject] ILoggerFactory loggerFactory,
            [Inject] IUkrlpApiService ukrlpApiService)
        {
            var blobContainer         = configuration["BlobStorageSettings:Container"];
            var databaseId            = configuration["CosmosDbSettings:DatabaseId"];
            var coursesCollectionId   = "courses";
            var providerCollectionId  = "ukrlp";
            var documentClient        = cosmosDbHelper.GetClient();
            var coursesCollectionUri  = UriFactory.CreateDocumentCollectionUri(databaseId, coursesCollectionId);
            var providerCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, providerCollectionId);
            var logger      = loggerFactory.CreateLogger(typeof(ArchiveCourses));
            var count       = 0;
            var logFileName = $"CoursesWithMissingLarsCodes";

            string continuation = null;

            using (var logStream = new MemoryStream())
                using (var logStreamWriter = new StreamWriter(logStream))
                    using (var logCsvWriter = new CsvWriter(logStreamWriter, CultureInfo.InvariantCulture))
                    {
                        // Log CSV headers
                        logCsvWriter.WriteField("UKPRN");
                        logCsvWriter.WriteField("ProviderName");
                        logCsvWriter.WriteField("CourseId");
                        logCsvWriter.WriteField("Provider course ID");
                        logCsvWriter.WriteField("Course name");
                        logCsvWriter.WriteField("Start date");
                        logCsvWriter.WriteField("Cost");
                        logCsvWriter.WriteField("Cost description");
                        logCsvWriter.WriteField("Delivery mode");
                        logCsvWriter.WriteField("Attendance mode");
                        logCsvWriter.NextRecord();

                        do
                        {
                            try
                            {
                                var feedOptions = new FeedOptions()
                                {
                                    RequestContinuation       = continuation,
                                    EnableCrossPartitionQuery = true
                                };

                                var queryResponse = await documentClient.CreateDocumentQuery <Course>(coursesCollectionUri, feedOptions)
                                                    .Where(p => (p.LearnAimRef == null || p.QualificationCourseTitle == null) && p.CourseStatus != CourseDirectory.Models.Enums.RecordStatus.Archived)
                                                    .AsDocumentQuery()
                                                    .ExecuteNextAsync <Course>();

                                foreach (var doc in queryResponse)
                                {
                                    var providers = ukrlpApiService.GetAllProviders(new List <string> {
                                        doc.ProviderUKPRN.ToString()
                                    });
                                    var provider = providers.FirstOrDefault();

                                    foreach (var courserun in doc.CourseRuns)
                                    {
                                        logCsvWriter.WriteField(doc.ProviderUKPRN);
                                        logCsvWriter.WriteField(provider?.ProviderName);
                                        logCsvWriter.WriteField(courserun.CourseInstanceId);
                                        logCsvWriter.WriteField(doc.CourseId);
                                        logCsvWriter.WriteField(courserun.CourseName);
                                        logCsvWriter.WriteField(courserun.StartDate);
                                        logCsvWriter.WriteField(courserun.Cost);
                                        logCsvWriter.WriteField(courserun.CostDescription);
                                        logCsvWriter.WriteField(courserun.DeliveryMode);
                                        logCsvWriter.WriteField(courserun.AttendancePattern);
                                        logCsvWriter.NextRecord();

                                        courserun.RecordStatus = CourseDirectory.Models.Enums.RecordStatus.Archived;
                                        count++;
                                    }

                                    count++;
                                    var documentLink = UriFactory.CreateDocumentUri(databaseId, coursesCollectionId, doc.id.ToString());
                                    await documentClient.ReplaceDocumentAsync(documentLink, doc, new RequestOptions()
                                    {
                                        PartitionKey = new Microsoft.Azure.Documents.PartitionKey(doc.ProviderUKPRN)
                                    });
                                }
                                continuation = queryResponse.ResponseContinuation;
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                logger.LogError(e.Message);
                                continuation = null;
                            }
                        }while (continuation != null);

                        // Upload log CSV to blob storage
                        {
                            logStreamWriter.Flush();

                            logStream.Seek(0L, SeekOrigin.Begin);

                            var blob = blobHelper.GetBlobContainer(blobContainer).GetBlockBlobReference(logFileName);
                            await blob.UploadFromStreamAsync(logStream);
                        }
                    }

            Console.WriteLine($"{count} courses have been archived");
        }