public async Task ProvideAsync()
        {
            var connectionString = ConfigurationManager.AppSettings["EasDbConnectionString"];
            var ukprn            = 10006341;

            DbContextOptions <EasContext> options = new DbContextOptionsBuilder <EasContext>()
                                                    .UseSqlServer(connectionString)
                                                    .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;

            IEasdbContext context = new EasContext(options);

            Func <IEasdbContext> easContext = () => context;

            var reportContextMock = new Mock <IReportServiceContext>();

            reportContextMock.Setup(rcm => rcm.Ukprn).Returns(ukprn);

            var stopWatch = new Stopwatch();
            var service   = NewService(easContext);

            stopWatch.Start();
            await service.ProvideAsync(reportContextMock.Object, CancellationToken.None);

            stopWatch.Stop();

            _testOutputHelper.WriteLine($"Elapsed Time: {stopWatch.Elapsed}");
        }
        public static ContainerBuilder BuildContainer(IServiceFabricConfigurationService serviceFabricConfigurationService)
        {
            var statelessServiceConfiguration = serviceFabricConfigurationService.GetConfigSectionAsStatelessServiceConfiguration();

            var easServiceConfiguration       = serviceFabricConfigurationService.GetConfigSectionAs <EasServiceConfiguration>("EasServiceConfiguration");
            var fcsServiceConfiguration       = serviceFabricConfigurationService.GetConfigSectionAs <FcsServiceConfiguration>("FcsServiceConfiguration");
            var postcodesServiceConfiguration = serviceFabricConfigurationService.GetConfigSectionAs <PostcodesServiceConfiguration>("PostcodesServiceConfiguration");

            var azureStorageFileServiceConfiguration = new AzureStorageFileServiceConfiguration()
            {
                ConnectionString = easServiceConfiguration.AzureBlobConnectionString,
            };

            var container = new ContainerBuilder();

            container.RegisterModule(new StatelessServiceModule(statelessServiceConfiguration));
            container.RegisterModule <SerializationModule>();
            container.RegisterModule(new IOModule(azureStorageFileServiceConfiguration));
            container.RegisterModule <EASBaseModule>();
            container.RegisterModule <EASServicesModule>();
            container.RegisterModule <DataServicesModule>();
            container.RegisterModule <ValidationModule>();
            container.RegisterModule <ReportsModule>();

            container.RegisterInstance(easServiceConfiguration).As <IEasServiceConfiguration>();

            container.Register(c =>
            {
                DbContextOptions <EasContext> options = new DbContextOptionsBuilder <EasContext>().UseSqlServer(easServiceConfiguration.EasdbConnectionString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
                EasContext easdbContext = new EasContext(options);
                return(easdbContext);
            }).As <IEasdbContext>().InstancePerDependency();

            container.Register(c =>
            {
                DbContextOptions <FcsContext> options = new DbContextOptionsBuilder <FcsContext>().UseSqlServer(fcsServiceConfiguration.FcsConnectionString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
                var fcsContext = new FcsContext(options);
                return(fcsContext);
            }).As <IFcsContext>().InstancePerDependency();

            container.Register(c =>
            {
                DbContextOptions <PostcodesContext> options = new DbContextOptionsBuilder <PostcodesContext>().UseSqlServer(postcodesServiceConfiguration.PostcodesConnectionString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
                var postcodesContext = new PostcodesContext(options);
                return(postcodesContext);
            }).As <IPostcodesContext>().InstancePerDependency();

            return(container);
        }
        [InlineData("EASDATA-10003909-20200816-100004.csv", 10003909, 62, 1508)] // all combinations

        public async Task ProcessEASFile(string filename, int ukPrn, int expectedSubmissionValuesCount, int expectedValidationErrorsCount)
        {
            var connString = ConfigurationManager.AppSettings["EasdbConnectionString"];
            DbContextOptions <EasContext> options = new DbContextOptionsBuilder <EasContext>().UseSqlServer(connString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
            EasContext easdbContext = new EasContext(options);
            List <EasSubmissionValue> easSubmissionValues = new List <EasSubmissionValue>();
            List <ValidationError>    validationErrors    = new List <ValidationError>();
            var easContextMessage = BuildEasJobContextMessage(filename, ukPrn, 0);
            var builder           = new ContainerBuilder();

            _output.WriteLine(connString);
            CleanUp(ukPrn.ToString(), easdbContext);
            DIComposition.RegisterTypes(builder);
            var container = builder.Build();

            EntryPoint entryPoint = new EntryPoint(
                new SeriLogger(new ApplicationLoggerSettings(), new Logging.ExecutionContext(), null),
                container.Resolve <IValidationService>(),
                container.Resolve <IReportingController>());


            var tasks = container.Resolve <IList <IEasServiceTask> >();

            var result = await entryPoint.CallbackAsync(easContextMessage, CancellationToken.None, tasks);

            var easSubmission = easdbContext.EasSubmissions.FirstOrDefault(x => x.Ukprn == ukPrn.ToString());

            if (easSubmission != null)
            {
                easSubmissionValues = easdbContext.EasSubmissionValues.Where(x => x.SubmissionId == easSubmission.SubmissionId).ToList();
            }

            var sourceFile = easdbContext.SourceFiles.FirstOrDefault(x => x.Ukprn == ukPrn.ToString());

            if (sourceFile != null)
            {
                validationErrors = easdbContext.ValidationErrors.Where(x => x.SourceFileId == sourceFile.SourceFileId).ToList();
            }

            Assert.Equal(expectedSubmissionValuesCount, easSubmissionValues.Count);
            Assert.Equal(expectedValidationErrorsCount, validationErrors.Count);
        }
        private static void CleanUp(string ukPrn, EasContext easdbContext)
        {
            var previousEasSubmissions = easdbContext.EasSubmissions.Where(x => x.Ukprn == ukPrn).ToList();

            foreach (var easSubmission in previousEasSubmissions)
            {
                SqlParameter id = new SqlParameter("@SubmissionId", easSubmission.SubmissionId);
                easdbContext.Database.ExecuteSqlCommand(
                    "Delete from Eas_Submission_Values where Submission_Id = @SubmissionId", id);
                easdbContext.Database.ExecuteSqlCommand(
                    "Delete from Eas_Submission where Submission_Id = @SubmissionId", id);
            }

            var previousSourceFiles = easdbContext.SourceFiles.Where(x => x.Ukprn == ukPrn).ToList();

            foreach (var sourceFile in previousSourceFiles)
            {
                SqlParameter id = new SqlParameter("@SubmissionId", sourceFile.SourceFileId);
                easdbContext.Database.ExecuteSqlCommand(
                    "Delete from ValidationError where SourceFileId = @SubmissionId", id);
                easdbContext.Database.ExecuteSqlCommand(
                    "Delete from sourceFile where SourceFileId = @SubmissionId", id);
            }
        }
        public async Task PersistEasSubmissionData()
        {
            var connString = ConfigurationManager.AppSettings["EasdbConnectionString"];

            _output.WriteLine(connString);

            DbContextOptions <EasContext> options = new DbContextOptionsBuilder <EasContext>().UseSqlServer(connString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
            EasContext easDbContext = new EasContext(options);

            var submissionId      = Guid.NewGuid();
            var easSubmissionList = new List <EasSubmission>
            {
                new EasSubmission
                {
                    CollectionPeriod   = 7,
                    SubmissionId       = submissionId,
                    Ukprn              = "10023139",
                    ProviderName       = "Milton Keynes College",
                    UpdatedOn          = DateTime.Now,
                    DeclarationChecked = true,
                    UpdatedBy          = "John Smith",
                    NilReturn          = false
                },

                new EasSubmission
                {
                    CollectionPeriod   = 8,
                    SubmissionId       = submissionId,
                    Ukprn              = "10023139",
                    ProviderName       = "Milton Keynes College",
                    UpdatedOn          = DateTime.Now,
                    DeclarationChecked = true,
                    UpdatedBy          = "John Smith",
                    NilReturn          = false
                }
            };

            var easSubmissionValuesList = new List <EasSubmissionValue>
            {
                new EasSubmissionValue
                {
                    CollectionPeriod = 7,
                    SubmissionId     = submissionId,
                    PaymentId        = 5,
                    PaymentValue     = (decimal)12.22,
                    DevolvedAreaSoF  = 110
                },

                new EasSubmissionValue
                {
                    CollectionPeriod = 8,
                    SubmissionId     = submissionId,
                    PaymentId        = 2,
                    PaymentValue     = (decimal)21.22
                }
            };

            EasSubmissionService easSubmissionService = new EasSubmissionService(easDbContext, new SeriLogger(new ApplicationLoggerSettings(), new ExecutionContext(), null));
            await easSubmissionService.PersistEasSubmissionAsync(easSubmissionList, easSubmissionValuesList, 10023139, CancellationToken.None);

            var easSubmissions = await easSubmissionService.GetEasSubmissions(submissionId, CancellationToken.None);

            var submission = easSubmissions.FirstOrDefault();

            Assert.NotNull(easSubmissions);
            Assert.NotNull(submission);
            Assert.NotEmpty(easSubmissions);
            Assert.Equal(submissionId, submission.SubmissionId);
            Assert.Equal(7, submission.CollectionPeriod);
            Assert.Equal("10023139", submission.Ukprn);
            Assert.Equal("Milton Keynes College", submission.ProviderName);
            Assert.True(submission.DeclarationChecked);
            Assert.Equal("John Smith", submission.UpdatedBy);
            Assert.False(submission.NilReturn);

            var easSubmissionValueFirst = submission.EasSubmissionValues.ElementAt(0);

            Assert.Equal(submissionId, easSubmissionValueFirst.SubmissionId);
            Assert.Equal(7, easSubmissionValueFirst.CollectionPeriod);
            Assert.Equal(5, easSubmissionValueFirst.PaymentId);
            Assert.Equal((decimal)12.22, easSubmissionValueFirst.PaymentValue);
            Assert.Equal(110, easSubmissionValueFirst.DevolvedAreaSoF);

            var secondEasSubmission      = easSubmissions[1];
            var easSubmissionValueSecond = secondEasSubmission.EasSubmissionValues.ElementAt(0);

            Assert.Equal(8, easSubmissionValueSecond.CollectionPeriod);
            Assert.Equal(2, easSubmissionValueSecond.PaymentId);
            Assert.Equal((decimal)21.22, easSubmissionValueSecond.PaymentValue);
            //Assert.Equal(null, easSubmissionValueSecond.DevolvedAreaSoF);
        }
            public static void RegisterTypes(ContainerBuilder builder)
            {
                Mock <IFCSDataService> fcsDataServiceMock = new Mock <IFCSDataService>();

                fcsDataServiceMock.Setup(x => x.GetContractsForProviderAsync(It.IsAny <int>(), CancellationToken.None)).ReturnsAsync(
                    new List <ContractAllocation>()
                {
                    new ContractAllocation {
                        FundingStreamPeriodCode = "APPS2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "LEVY1799", StartDate = new DateTime(2019, 01, 01), EndDate = new DateTime(2020, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "NONLEVY2020", StartDate = new DateTime(2019, 01, 01), EndDate = new DateTime(2020, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "16-18NLAP2019", StartDate = new DateTime(2019, 01, 01), EndDate = new DateTime(2020, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "ANLAP2019", StartDate = new DateTime(2019, 01, 01), EndDate = new DateTime(2020, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "16-18TRN2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "AEBC-ASCL2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "AEBC-19TRN2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "AEB-AS2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "AEB-19TRN2021", StartDate = new DateTime(2020, 01, 01), EndDate = new DateTime(2021, 12, 31)
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "ALLB2021", StartDate = new DateTime(2020, 01, 01), EndDate = null
                    },
                    new ContractAllocation {
                        FundingStreamPeriodCode = "ALLBC2021", StartDate = new DateTime(2020, 01, 01)
                    }
                });
                fcsDataServiceMock.Setup(x => x.GetDevolvedContractsForProviderAsync(It.IsAny <int>(), CancellationToken.None)).ReturnsAsync(
                    new Dictionary <string, IEnumerable <DevolvedContract> >()
                {
                    {
                        "WMCA", new List <DevolvedContract>
                        {
                            new DevolvedContract {
                                McaglashortCode = "WMCA", EffectiveFrom = new DateTime(2020, 01, 01), EffectiveTo = new DateTime(2021, 07, 31)
                            }
                        } as IEnumerable <DevolvedContract>
                    }
                } as IReadOnlyDictionary <string, IEnumerable <DevolvedContract> >);

                Mock <IPostcodesDataService> postcodesDataServiceMock = new Mock <IPostcodesDataService>();

                postcodesDataServiceMock.Setup(x => x.GetMcaShortCodesForSofCodesAsync(It.IsAny <IEnumerable <int> >(), CancellationToken.None)).ReturnsAsync(
                    new Dictionary <int, string>()
                {
                    { 110, "GMCA" },
                    { 111, "LCRCA" },
                    { 112, "WMCA" },
                    { 113, "WECA" },
                    { 114, "TVCA" },
                    { 115, "CPCA" },
                    { 116, "London" },
                    { 117, "NTCA" },
                } as IReadOnlyDictionary <int, string>);

                Mock <IDateTimeProvider> dateTimeProviderMock = new Mock <IDateTimeProvider>();

                dateTimeProviderMock.Setup(x => x.GetNowUtc()).Returns(new DateTime(2020, 11, 01, 10, 10, 10));
                dateTimeProviderMock.Setup(x => x.ConvertUkToUtc(It.IsAny <DateTime>())).Returns <DateTime>(d => d);
                dateTimeProviderMock.Setup(x => x.ConvertUkToUtc(It.IsAny <string>(), It.IsAny <string>())).Returns(new DateTime(2020, 11, 01, 10, 10, 10));

                Mock <IStreamableKeyValuePersistenceService> storage = new Mock <IStreamableKeyValuePersistenceService>();
                var connString = ConfigurationManager.AppSettings["EasdbConnectionString"];

                builder.RegisterInstance(fcsDataServiceMock.Object).As <IFCSDataService>();
                builder.RegisterInstance(postcodesDataServiceMock.Object).As <IPostcodesDataService>();
                builder.RegisterInstance(dateTimeProviderMock.Object).As <IDateTimeProvider>();
                builder.RegisterType <JsonSerializationService>().As <IJsonSerializationService>();
                builder.RegisterType <XmlSerializationService>().As <IXmlSerializationService>();
                //builder.Register(c =>
                //        new AzureStorageConfig("DefaultEndpointsProtocol=https;AccountName=test;AccountKey=test;EndpointSuffix=core.windows.net", "test"))
                //    .As<IAzureStorageKeyValuePersistenceServiceConfig>().SingleInstance();
                builder.Register(c =>
                {
                    var loggerOptions = new LoggerOptions()
                    {
                        LoggerConnectionString = ConfigurationManager.AppSettings["EasdbConnectionString"]
                    };
                    return(new ApplicationLoggerSettings
                    {
                        ApplicationLoggerOutputSettingsCollection = new List <IApplicationLoggerOutputSettings>()
                        {
                            new MsSqlServerApplicationLoggerOutputSettings()
                            {
                                MinimumLogLevel = LogLevel.Verbose,
                                ConnectionString = loggerOptions.LoggerConnectionString
                            },
                            new ConsoleApplicationLoggerOutputSettings()
                            {
                                MinimumLogLevel = LogLevel.Verbose
                            }
                        }
                    });
                }).As <IApplicationLoggerSettings>().SingleInstance();

                builder.RegisterType <Logging.ExecutionContext>().As <IExecutionContext>().InstancePerLifetimeScope();
                builder.RegisterType <SerilogLoggerFactory>().As <ISerilogLoggerFactory>().InstancePerLifetimeScope();
                builder.RegisterType <SeriLogger>().As <ILogger>().InstancePerLifetimeScope();

                builder.RegisterType <ValidationTask>().As <IEasServiceTask>();
                builder.RegisterType <StorageTask>().As <IEasServiceTask>();
                builder.RegisterType <ReportingTask>().As <IEasServiceTask>();

                builder.RegisterType <EasValidationService>().As <IValidationService>();
                builder.RegisterType <FileValidationService>().As <IFileValidationService>();
                builder.RegisterType <ValidationErrorBuilder>().As <IValidationErrorBuilder>();
                builder.RegisterType <ValidationErrorLoggerService>().As <IValidationErrorLoggerService>();
                builder.RegisterType <EASFileDataProviderService>().As <IEASFileDataProviderService>();
                builder.Register(c =>
                {
                    DbContextOptions <EasContext> options = new DbContextOptionsBuilder <EasContext>().UseSqlServer(connString).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options;
                    EasContext easdbContext = new EasContext(options);
                    return(easdbContext);
                }).As <IEasdbContext>().InstancePerDependency();

                builder.Register(c => new EasConfig
                {
                    EasdbConnectionString = connString
                }).As <IEasServiceConfiguration>();

                builder.RegisterType <EasPaymentService>().As <IEasPaymentService>();
                builder.RegisterType <EasSubmissionService>().As <IEasSubmissionService>();
                builder.RegisterType <FundingLineContractTypeMappingDataService>().As <IFundingLineContractTypeMappingDataService>();
                builder.RegisterType <ValidationErrorRetrievalService>().As <IValidationErrorRetrievalService>();
                builder.RegisterType <ValidationErrorRuleService>().As <IValidationErrorRuleService>();
                builder.RegisterType <FileDataCache>().As <IFileDataCache>().SingleInstance();
                builder.RegisterType <FileDataCacheService>().As <IFileDataCacheService>();
                builder.RegisterType <DictionaryKeyValuePersistenceService>().As <IKeyValuePersistenceService>().SingleInstance();
                builder.RegisterType <ViolationReport>().As <IValidationReport>();
                builder.RegisterType <FundingReport>().As <IModelReport>();
                builder.RegisterType <ValidationResultReport>().As <IValidationResultReport>();
                builder.RegisterType <ReportingController>().As <IReportingController>();
                builder.RegisterType <FundingLineContractTypeMappingDataService>().As <IFundingLineContractTypeMappingDataService>();
                builder.RegisterType <EasValidationService>().As <IValidationService>();
                builder.RegisterType <EntryPoint>().WithAttributeFiltering().InstancePerLifetimeScope();
                builder.RegisterType <FileNameService>().As <IFileNameService>();
                builder.RegisterType <CsvFileService>().As <ICsvFileService>();
                builder.RegisterType <ZipService>().As <IZipService>();
                builder.RegisterType <FileServiceStub>().As <IFileService>();
                builder.RegisterType <BulkInsert>().As <IBulkInsert>();

                builder.Register(c =>
                {
                    var fcsContext = new FcsContext();

//                    fcsContext.Configuration.AutoDetectChangesEnabled = false;

                    return(fcsContext);
                }).As <IFcsContext>().InstancePerDependency();

                builder.Register(c =>
                {
                    var postcodesContext = new PostcodesContext();
                    return(postcodesContext);
                }).As <IPostcodesContext>().InstancePerDependency();
            }