protected override void MakeAdjustmentsFromProfileVariationPointer(ProfileVariationPointer variationPointer) { FundingLine closedFundingLine = RefreshState.FundingLines? .SingleOrDefault(_ => _.FundingLineCode == variationPointer.FundingLineId); FundingLine successorFundingLine = SuccessorRefreshState?.FundingLines? .SingleOrDefault(_ => _.FundingLineCode == variationPointer.FundingLineId); if (closedFundingLine == null || successorFundingLine == null) { throw new ArgumentOutOfRangeException(nameof(variationPointer), $"Did not locate a funding line for variation pointer with fundingLineId {variationPointer.FundingLineId}"); } ProfilePeriod[] orderedClosedProfilePeriods = new YearMonthOrderedProfilePeriods(closedFundingLine) .ToArray(); ProfilePeriod[] orderedSuccessorProfilePeriods = new YearMonthOrderedProfilePeriods(successorFundingLine) .ToArray(); int variationPointerIndex = GetProfilePeriodIndexForVariationPoint(variationPointer, orderedClosedProfilePeriods); for (int profilePeriod = variationPointerIndex; profilePeriod < orderedClosedProfilePeriods.Length; profilePeriod++) { ProfilePeriod successorProfilePeriod = orderedSuccessorProfilePeriods[profilePeriod]; successorProfilePeriod.ProfiledValue = successorProfilePeriod.ProfiledValue + orderedClosedProfilePeriods[profilePeriod].ProfiledValue; } }
public async Task SetProfileVariationPointer() { string specificationId = NewRandomString(); ProfileVariationPointer model = new ProfileVariationPointer(); await AssertPutRequest($"{specificationId}/profilevariationpointer", HttpStatusCode.OK, () => _client.SetProfileVariationPointer(specificationId, model)); }
protected int GetProfilePeriodIndexForVariationPoint(ProfileVariationPointer variationPointer, ProfilePeriod[] profilePeriods) { int variationPointerIndex = profilePeriods.IndexOf(_ => _.Occurrence == variationPointer.Occurrence && _.Year == variationPointer.Year && _.TypeValue == variationPointer.TypeValue); if (variationPointerIndex == -1) { throw new ArgumentOutOfRangeException(nameof(variationPointer), $"Did not locate profile period corresponding to variation pointer for funding line id {variationPointer.FundingLineId}"); } return(variationPointerIndex); }
private bool IsProfileTotalPaid( ProfileVariationPointer profileVariationPointer, ProfileTotal profileTotal) { if (profileVariationPointer == null) { return(false); } if (profileTotal.Year > profileVariationPointer.Year || (profileTotal.Year == profileVariationPointer.Year && MonthNumberFor(profileTotal.TypeValue) >= MonthNumberFor(profileVariationPointer.TypeValue))) { return(false); } return(true); }
public async Task <ReProfileRequest> BuildReProfileRequest(string specificationId, string fundingStreamId, string fundingPeriodId, string providerId, string fundingLineCode, string profilePatternKey, ProfileConfigurationType configurationType, decimal?fundingLineTotal = null) { Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId)); Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId)); Guard.IsNullOrWhiteSpace(fundingPeriodId, nameof(fundingPeriodId)); Guard.IsNullOrWhiteSpace(providerId, nameof(providerId)); Guard.IsNullOrWhiteSpace(fundingLineCode, nameof(fundingLineCode)); ProfileVariationPointer profileVariationPointer = await GetProfileVariationPointerForFundingLine(specificationId, fundingLineCode, fundingStreamId); ProfilePeriod[] orderedProfilePeriodsForFundingLine = await GetOrderedProfilePeriodsForFundingLine(fundingStreamId, fundingPeriodId, providerId, fundingLineCode); int paidUpToIndex = GetProfilePeriodIndexForVariationPointer(profileVariationPointer, orderedProfilePeriodsForFundingLine); IEnumerable <ExistingProfilePeriod> existingProfilePeriods = BuildExistingProfilePeriods(orderedProfilePeriodsForFundingLine, paidUpToIndex); decimal existingFundingLineTotal = orderedProfilePeriodsForFundingLine.Sum(_ => _.ProfiledValue); return(new ReProfileRequest { ProfilePatternKey = profilePatternKey, ConfigurationType = configurationType, FundingLineCode = fundingLineCode, FundingPeriodId = fundingPeriodId, FundingStreamId = fundingStreamId, FundingLineTotal = fundingLineTotal.GetValueOrDefault(existingFundingLineTotal), ExistingFundingLineTotal = existingFundingLineTotal, ExistingPeriods = existingProfilePeriods }); }
private void ZeroProfilesFromVariationPoint(ProfileVariationPointer variationPointer) { FundingLine fundingLine = RefreshState.FundingLines? .SingleOrDefault(_ => _.FundingLineCode == variationPointer.FundingLineId); if (fundingLine == null) { throw new ArgumentOutOfRangeException(nameof(variationPointer), $"Did not locate a funding line for variation pointer with fundingLineId {variationPointer.FundingLineId}"); } ProfilePeriod[] orderedProfilePeriods = new YearMonthOrderedProfilePeriods(fundingLine) .ToArray(); int variationPointerIndex = GetProfilePeriodIndexForVariationPoint(variationPointer, orderedProfilePeriods); for (int profilePeriod = variationPointerIndex; profilePeriod < orderedProfilePeriods.Length; profilePeriod++) { orderedProfilePeriods[profilePeriod].ProfiledValue = 0; } }
private async Task <ValidatedApiResponse <HttpStatusCode> > WhenTheSpecificationProfileVariationPointerSet(string specificationId, ProfileVariationPointer profileVariationPointer) { return(await _client.SetProfileVariationPointer(specificationId, profileVariationPointer)); }
protected abstract void MakeAdjustmentsFromProfileVariationPointer(ProfileVariationPointer variationPointer);
public Task <HttpStatusCode> SetProfileVariationPointer(string specificationId, ProfileVariationPointer profileVariationPointer) { throw new NotImplementedException(); }
protected override void MakeAdjustmentsFromProfileVariationPointer(ProfileVariationPointer variationPointer) { ZeroProfilesFromVariationPoint(variationPointer); }
protected override void MakeAdjustmentsFromProfileVariationPointer(ProfileVariationPointer variationPointer) { PublishedProvider previousSnapshot = VariationContext.GetPublishedProviderOriginalSnapShot(ProviderId); if (previousSnapshot == null) { return; } string fundingLineId = variationPointer.FundingLineId; FundingLine latestFundingLine = RefreshState.FundingLines? .SingleOrDefault(_ => _.FundingLineCode == fundingLineId); FundingLine previousFundingLine = previousSnapshot.Current?.FundingLines? .SingleOrDefault(_ => _.FundingLineCode == fundingLineId); if (latestFundingLine == null || previousFundingLine == null) { RecordErrors($"Did not locate all funding lines for variation pointer with fundingLineId {fundingLineId}"); return; } if (latestFundingLine.Value == null && previousFundingLine.Value == null) { return; } ProfilePeriod[] orderedRefreshProfilePeriods = new YearMonthOrderedProfilePeriods(latestFundingLine) .ToArray(); ProfilePeriod[] orderedSnapShotProfilePeriods = new YearMonthOrderedProfilePeriods(previousFundingLine) .ToArray(); int variationPointerIndex = GetProfilePeriodIndexForVariationPoint(variationPointer, orderedRefreshProfilePeriods); decimal previousFundingLineValuePaid = orderedSnapShotProfilePeriods.Take(variationPointerIndex).Sum(_ => _.ProfiledValue); decimal latestFundingLineValuePaid = orderedRefreshProfilePeriods.Take(variationPointerIndex).Sum(_ => _.ProfiledValue); decimal latestFundingLineValue = latestFundingLine.Value.GetValueOrDefault(); decimal fundingChange = latestFundingLineValuePaid - previousFundingLineValuePaid; decimal latestPeriodAmount = (int)(latestFundingLineValue / orderedRefreshProfilePeriods.Length); AdjustPeriodsForFundingAlreadyReleased(variationPointerIndex, orderedSnapShotProfilePeriods, orderedRefreshProfilePeriods); if (fundingChange < 0) { if (AdjustingPeriodsForOverPaymentLeavesRemainder(variationPointerIndex, latestPeriodAmount, orderedSnapShotProfilePeriods, orderedRefreshProfilePeriods, out decimal remainingOverPayment)) { if (remainingOverPayment > 0) { RefreshState.AddCarryOver(fundingLineId, ProfilingCarryOverType.DSGReProfiling, remainingOverPayment); } } } else if (fundingChange > 0) { AdjustPeriodsForUnderPayment(variationPointerIndex, latestPeriodAmount, orderedSnapShotProfilePeriods, orderedRefreshProfilePeriods); } else { AdjustPeriodsForNoTotalAllocationChange(variationPointerIndex, latestPeriodAmount, orderedSnapShotProfilePeriods, orderedRefreshProfilePeriods, fundingLineId); } }
public async Task <HttpStatusCode> SetProfileVariationPointer(string specificationId, ProfileVariationPointer profileVariationPointer) { Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId)); Guard.ArgumentNotNull(profileVariationPointer, nameof(profileVariationPointer)); return(await PutAsync($"{UrlRoot}/{specificationId}/profilevariationpointer", profileVariationPointer)); }
public async Task <IActionResult> GetPublishedProviderProfileTotalsForSpecificationForProviderForFundingLine( string specificationId, string providerId, string fundingStreamId, string fundingLineCode) { Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId)); Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId)); Guard.IsNullOrWhiteSpace(fundingLineCode, nameof(fundingLineCode)); Guard.IsNullOrWhiteSpace(providerId, nameof(providerId)); PublishedProviderVersion latestPublishedProviderVersion = await _resilience.ExecuteAsync(() => _publishedFunding.GetLatestPublishedProviderVersionBySpecificationId( specificationId, fundingStreamId, providerId)); if (latestPublishedProviderVersion == null) { return(new NotFoundResult()); } IEnumerable <ProfileVariationPointer> profileVariationPointers = await _specificationService.GetProfileVariationPointers(specificationId); TemplateMetadataDistinctFundingLinesContents templateMetadataDistinctFundingLinesContents = await _policiesService.GetDistinctTemplateMetadataFundingLinesContents( fundingStreamId, latestPublishedProviderVersion.FundingPeriodId, latestPublishedProviderVersion.TemplateVersion); IEnumerable <FundingStreamPeriodProfilePattern> fundingStreamPeriodProfilePatterns = await _profilingService.GetProfilePatternsForFundingStreamAndFundingPeriod( latestPublishedProviderVersion.FundingStreamId, latestPublishedProviderVersion.FundingPeriodId); (string profilePatternKey, string profilePatternName, string profilePatternDescription) = GetProfilePatternDetails(fundingLineCode, latestPublishedProviderVersion, fundingStreamPeriodProfilePatterns); FundingLineProfile fundingLineProfile = new FundingLineProfile { FundingLineCode = fundingLineCode, FundingLineName = templateMetadataDistinctFundingLinesContents?.FundingLines? .FirstOrDefault(_ => _.FundingLineCode == fundingLineCode)?.Name, ProfilePatternKey = profilePatternKey, ProfilePatternName = profilePatternName, ProfilePatternDescription = profilePatternDescription, ProviderId = latestPublishedProviderVersion.ProviderId, UKPRN = latestPublishedProviderVersion.Provider.UKPRN, ProviderName = latestPublishedProviderVersion.Provider.Name, CarryOverAmount = latestPublishedProviderVersion.GetCarryOverTotalForFundingLine(fundingLineCode) ?? 0 }; ProfileVariationPointer currentProfileVariationPointer = profileVariationPointers?.SingleOrDefault(_ => _.FundingStreamId == fundingStreamId && _.FundingLineId == fundingLineCode); ProfileTotal[] profileTotals = new PaymentFundingLineProfileTotals(latestPublishedProviderVersion, fundingLineCode) .ToArray(); fundingLineProfile.TotalAllocation = latestPublishedProviderVersion .FundingLines .Where(_ => _.Type == FundingLineType.Payment) .SingleOrDefault(_ => _.FundingLineCode == fundingLineCode) ?.Value; fundingLineProfile.ProfileTotalAmount = profileTotals.Sum(_ => _.Value); FundingDate fundingDate = await _policiesService.GetFundingDate( fundingStreamId, latestPublishedProviderVersion.FundingPeriodId, fundingLineCode); for (int index = 0; index < profileTotals.Count(); index++) { ProfileTotal profileTotal = profileTotals[index]; profileTotal.InstallmentNumber = index + 1; profileTotal.IsPaid = IsProfileTotalPaid(currentProfileVariationPointer, profileTotal); profileTotal.ActualDate = fundingDate?.Patterns?.SingleOrDefault(_ => _.Occurrence == profileTotal.Occurrence && _.Period == profileTotal.TypeValue && _.PeriodYear == profileTotal.Year)?.PaymentDate; } fundingLineProfile.AmountAlreadyPaid = profileTotals.Where(_ => _.IsPaid).Sum(_ => _.Value); fundingLineProfile.RemainingAmount = fundingLineProfile.TotalAllocation - fundingLineProfile.AmountAlreadyPaid; foreach (ProfileTotal profileTotal in profileTotals.Where(_ => !_.IsPaid)) { profileTotal.ProfileRemainingPercentage = fundingLineProfile.TotalAllocation.HasValue && fundingLineProfile.TotalAllocation > 0 ? profileTotal.Value / (fundingLineProfile.TotalAllocation - fundingLineProfile.AmountAlreadyPaid) * 100 : 0; } fundingLineProfile.ProfileTotals = profileTotals; fundingLineProfile.LastUpdatedDate = latestPublishedProviderVersion.GetLatestFundingLineDate(fundingLineCode); fundingLineProfile.LastUpdatedUser = latestPublishedProviderVersion.GetLatestFundingLineUser(fundingLineCode); return(new OkObjectResult(fundingLineProfile)); }