Beispiel #1
0
        private async Task GenerateCalculations(SpecGeneratorConfiguration configuration, Specification specification)
        {
            int totalCalculations = 0;

            if (configuration.NumberOfCalculations > 0)
            {
                totalCalculations = configuration.NumberOfCalculations;
            }

            List <Policy> policies = new List <Policy>(specification.Policies);

            List <AllocationLine> allocationLines = new List <AllocationLine>();

            _logger.Information("Generating {totalCalculations} calculations across {Count} policies", totalCalculations, policies.Count);

            foreach (FundingStream fundingStream in specification.FundingStreams)
            {
                foreach (AllocationLine allocationLine in fundingStream.AllocationLines)
                {
                    allocationLines.Add(allocationLine);
                }
            }

            IEnumerable <string> allocationLineNames = allocationLines.Select(a => a.Name);

            _logger.Information("Creating calculations in the following Allocation Lines {allocationLineNames}", allocationLineNames);

            for (int i = 0; i < totalCalculations; i++)
            {
                Policy         policy         = policies[i % policies.Count];
                AllocationLine allocationLine = allocationLines[i % allocationLines.Count];

                CalculationCreateModel calculationCreateModel = new CalculationCreateModel()
                {
                    SpecificationId  = specification.Id,
                    PolicyId         = policy.Id,
                    AllocationLineId = allocationLine.Id,
                    CalculationType  = CalculationSpecificationType.Funding,
                    Description      = "SpecGenerator",
                    Name             = $"{specification.Name} - Calculation {i + 1}",
                    IsPublic         = false,
                };

                await _specsClient.CreateCalculation(calculationCreateModel);
            }
        }
        public async Task <IActionResult> OnPostAsync(string specificationId)
        {
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));

            Specification specification = await GetSpecification(specificationId);

            if (!await _authorizationHelper.DoesUserHavePermission(User, specification, SpecificationActionTypes.CanEditSpecification))
            {
                return(new ForbidResult());
            }

            if (!string.IsNullOrWhiteSpace(CreateCalculationViewModel.Name))
            {
                ApiResponse <Calculation> existingCalculationResponse = await _specsClient
                                                                        .GetCalculationBySpecificationIdAndCalculationName(specificationId, CreateCalculationViewModel.Name);

                if (existingCalculationResponse.StatusCode != HttpStatusCode.NotFound)
                {
                    this.ModelState.AddModelError($"{nameof(CreateCalculationViewModel)}.{nameof(CreateCalculationViewModel.Name)}", ValidationMessages.CalculationNameAlreadyExists);
                }
            }

            if (CreateCalculationViewModel.CalculationType == "Funding" && string.IsNullOrWhiteSpace(CreateCalculationViewModel.AllocationLineId))
            {
                this.ModelState.AddModelError($"{nameof(CreateCalculationViewModel)}.{nameof(CreateCalculationViewModel.AllocationLineId)}", ValidationMessages.CalculationAllocationLineRequired);
            }

            if (!ModelState.IsValid)
            {
                SpecificationName = specification.Name;
                SpecificationId   = specificationId;
                FundingPeriodName = specification.FundingPeriod.Name;
                FundingPeriodId   = specification.FundingPeriod.Id;

                return(await PopulateForm(specification));
            }

            CalculationCreateModel calculation = _mapper.Map <CalculationCreateModel>(CreateCalculationViewModel);

            calculation.SpecificationId = specificationId;

            ValidatedApiResponse <Calculation> newCalculationResponse = await _specsClient.CreateCalculation(calculation);

            if (newCalculationResponse.StatusCode == HttpStatusCode.OK)
            {
                Calculation newCalculation = newCalculationResponse.Content;

                return(Redirect($"/specs/policies/{specificationId}?operationType=CalculationCreated&operationId={newCalculation.Id}"));
            }
            else if (newCalculationResponse.StatusCode == HttpStatusCode.BadRequest)
            {
                newCalculationResponse.AddValidationResultErrors(ModelState);

                SpecificationName = specification.Name;
                SpecificationId   = specificationId;
                FundingPeriodName = specification.FundingPeriod.Name;
                FundingPeriodId   = specification.FundingPeriod.Id;

                return(await PopulateForm(specification));
            }
            else
            {
                throw new InvalidOperationException($"Unable to create calculation specifications. Status Code = {newCalculationResponse.StatusCode}");
            }
        }
        public void OnPostAsync_GivenCalculationDoesNotAlreadyExistButSavingIsNotOK_InvalidOperationException()
        {
            //Arrange
            CreateCalculationViewModel viewModel = new CreateCalculationViewModel
            {
                Name = "any name"
            };

            Specification specification = CreateSpecification();

            IEnumerable <Reference> allocationLines = new[]
            {
                new Reference
                {
                    Id   = "alloc-id",
                    Name = "alloc-name"
                }
            };

            CalculationCreateModel createModel = new CalculationCreateModel
            {
                SpecificationId = specificationId
            };

            IMapper mapper = CreateMapper();

            mapper
            .Map <CalculationCreateModel>(Arg.Is(viewModel))
            .Returns(createModel);

            ApiResponse <Calculation> calcApiRespnse = new ApiResponse <Calculation>(HttpStatusCode.NotFound);

            ValidatedApiResponse <Calculation> newCalcApiResponse = new ValidatedApiResponse <Calculation>(HttpStatusCode.InternalServerError, new Calculation
            {
                Id = "new-calc-id",
            });

            newCalcApiResponse.ModelState = new Dictionary <string, IEnumerable <string> >();

            ISpecsApiClient specsClient = CreateSpecsApiClient();

            specsClient
            .GetCalculationBySpecificationIdAndCalculationName(Arg.Is(specificationId), Arg.Is(viewModel.Name))
            .Returns(calcApiRespnse);

            specsClient
            .CreateCalculation(Arg.Is(createModel))
            .Returns(newCalcApiResponse);

            List <FundingStream> fundingStreams = new List <FundingStream>();

            fundingStreams.Add(new FundingStream
            {
                Id = fundingStreamId,
                AllocationLines = new List <AllocationLine>()
                {
                    new AllocationLine()
                    {
                        Id   = "al1",
                        Name = "Allocation Line 1",
                    }
                }
            });

            ApiResponse <IEnumerable <FundingStream> > fundingStreamResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams);

            specsClient
            .GetFundingStreamsForSpecification(Arg.Is(specification.Id))
            .Returns(fundingStreamResponse);

            specsClient
            .GetBaselineCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(new ApiResponse <IEnumerable <CalculationCurrentVersion> >(HttpStatusCode.OK, Enumerable.Empty <CalculationCurrentVersion>()));

            specsClient.GetSpecification(Arg.Is(specificationId))
            .Returns(new ApiResponse <Specification>(HttpStatusCode.OK, specification));

            CreateCalculationPageModel pageModel = CreatePageModel(specsClient, mapper);

            pageModel.PageContext = new PageContext();

            pageModel.CreateCalculationViewModel = viewModel;

            //Act
            Func <Task> test = async() => await pageModel.OnPostAsync(specificationId);

            //Assert
            test
            .Should()
            .ThrowExactly <InvalidOperationException>();
        }
        public async Task OnPostAsync_GivenCalculationDoesNotAlreadyExist_ReturnsRedirect()
        {
            //Arrange
            CreateCalculationViewModel viewModel = new CreateCalculationViewModel
            {
                Name = "any name"
            };

            Specification specification = CreateSpecification();

            IEnumerable <Reference> allocationLines = new[]
            {
                new Reference
                {
                    Id   = "alloc-id",
                    Name = "alloc-name"
                }
            };

            CalculationCreateModel createModel = new CalculationCreateModel
            {
                SpecificationId = specificationId
            };

            IMapper mapper = CreateMapper();

            mapper
            .Map <CalculationCreateModel>(Arg.Is(viewModel))
            .Returns(createModel);

            ApiResponse <Calculation> calcApiRespnse = new ApiResponse <Calculation>(HttpStatusCode.NotFound);

            ValidatedApiResponse <Calculation> newCalcApiResponse = new ValidatedApiResponse <Calculation>(HttpStatusCode.OK, new Calculation
            {
                Id = "new-calc-id"
            });

            ISpecsApiClient specsClient = CreateSpecsApiClient();

            specsClient
            .GetCalculationBySpecificationIdAndCalculationName(Arg.Is(specificationId), Arg.Is(viewModel.Name))
            .Returns(calcApiRespnse);

            specsClient
            .CreateCalculation(Arg.Is(createModel))
            .Returns(newCalcApiResponse);

            CreateCalculationPageModel pageModel = CreatePageModel(specsClient, mapper);

            pageModel.PageContext = new PageContext();

            pageModel.CreateCalculationViewModel = viewModel;

            //Act
            IActionResult result = await pageModel.OnPostAsync(specificationId);

            //Assert
            result
            .Should()
            .NotBeNull();

            result
            .Should()
            .BeAssignableTo <RedirectResult>();

            RedirectResult redirectResult = result as RedirectResult;

            redirectResult
            .Url
            .Should()
            .Be($"/specs/policies/{specificationId}?operationType=CalculationCreated&operationId=new-calc-id");
        }