Esempio n. 1
0
        private bool HasNoPaidPeriods(ProviderVariationContext providerVariationContext,
                                      PublishedProviderVersion priorState)
        {
            foreach (ProfileVariationPointer variationPointer in providerVariationContext.VariationPointers ?? ArraySegment <ProfileVariationPointer> .Empty)
            {
                FundingLine fundingLine = priorState?.FundingLines.SingleOrDefault(_ => _.FundingLineCode == variationPointer.FundingLineId);

                if (fundingLine == null)
                {
                    continue;
                }

                YearMonthOrderedProfilePeriods periods = new YearMonthOrderedProfilePeriods(fundingLine);

                int variationPointerIndex = periods.IndexOf(_ => _.Occurrence == variationPointer.Occurrence &&
                                                            _.Type.ToString() == variationPointer.PeriodType &&
                                                            _.Year == variationPointer.Year &&
                                                            _.TypeValue == variationPointer.TypeValue);

                if (variationPointerIndex > 0)
                {
                    return(false);
                }
            }

            return(true);
        }
        protected virtual bool HasNoProfilingChanges(PublishedProviderVersion priorState,
                                                     PublishedProviderVersion refreshState,
                                                     ProviderVariationContext providerVariationContext)
        {
            IDictionary <string, FundingLine> latestFundingLines =
                refreshState.FundingLines.Where(_ => _.Type == FundingLineType.Payment)
                .ToDictionary(_ => _.FundingLineCode);

            bool hasNoProfilingChanges = true;

            foreach (FundingLine previousFundingLine in priorState.FundingLines.Where(_ => _.Type == FundingLineType.Payment &&
                                                                                      _.Value.HasValue &&
                                                                                      ExtraFundingLinePredicate(refreshState, _)))
            {
                string fundingLineCode = previousFundingLine.FundingLineCode;

                if (!latestFundingLines.TryGetValue(fundingLineCode, out FundingLine latestFundingLine))
                {
                    continue;
                }

                ProfilePeriod[] priorProfiling  = new YearMonthOrderedProfilePeriods(previousFundingLine).ToArray();
                ProfilePeriod[] latestProfiling = new YearMonthOrderedProfilePeriods(latestFundingLine).ToArray();

                if (!priorProfiling.Select(AsLiteral)
                    .SequenceEqual(latestProfiling.Select(AsLiteral)))
                {
                    providerVariationContext.AddAffectedFundingLineCode(fundingLineCode);

                    hasNoProfilingChanges = false;
                }
            }

            return(hasNoProfilingChanges);
        }
        public void ProjectsDistributionPeriodsAndProfilePeriodsOrderedByYearThenProfilePeriodMonthThenOccurence_ExampleOne()
        {
            ProfilePeriod lastPeriod   = NewProfilePeriod(2, 2021, "December");
            ProfilePeriod firstPeriod  = NewProfilePeriod(0, 2020, "December");
            ProfilePeriod secondPeriod = NewProfilePeriod(1, 2020, "December");
            ProfilePeriod thirdPeriod  = NewProfilePeriod(0, 2021, "January");

            FundingLine fundingLine = NewFundingLine(_ => _.WithDistributionPeriods(NewDistributionPeriod(
                                                                                        dp => dp.WithProfilePeriods(thirdPeriod, secondPeriod)),
                                                                                    NewDistributionPeriod(dp => dp.WithProfilePeriods(lastPeriod, firstPeriod))));

            ProfilePeriod[] orderedProfilePeriods = new YearMonthOrderedProfilePeriods(fundingLine)
                                                    .ToArray();

            orderedProfilePeriods[0]
            .Should()
            .BeSameAs(firstPeriod);

            orderedProfilePeriods[1]
            .Should()
            .BeSameAs(secondPeriod);

            orderedProfilePeriods[2]
            .Should()
            .BeSameAs(thirdPeriod);

            orderedProfilePeriods[3]
            .Should()
            .BeSameAs(lastPeriod);
        }
        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;
            }
        }
Esempio n. 5
0
        private void AndTheFundingLinePeriodAmountsShouldBe(params decimal[] expectedAmounts)
        {
            DeliveryProfilePeriod[] orderedProfilePeriods = new YearMonthOrderedProfilePeriods <DeliveryProfilePeriod>(_result?.DeliveryProfilePeriods).ToArray();

            orderedProfilePeriods
            .Length
            .Should()
            .Be(expectedAmounts.Length);

            for (int amount = 0; amount < expectedAmounts.Length; amount++)
            {
                orderedProfilePeriods[amount]
                .GetProfileValue()
                .Should()
                .Be(expectedAmounts[amount], "Profiled value at index {0} should match expected value", amount);
            }
        }
        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;
            }
        }
Esempio n. 7
0
        private void AndTheFundingLinePeriodAmountsShouldBe(params decimal[] expectedAmounts)
        {
            FundingLine fundingLine = VariationContext.RefreshState.FundingLines.SingleOrDefault(_ => _.FundingLineCode == _fundingLineCode);

            fundingLine
            .Should()
            .NotBeNull();

            ProfilePeriod[] orderedProfilePeriods = new YearMonthOrderedProfilePeriods(fundingLine).ToArray();

            orderedProfilePeriods
            .Length
            .Should()
            .Be(expectedAmounts.Length);

            for (int amount = 0; amount < expectedAmounts.Length; amount++)
            {
                orderedProfilePeriods[amount]
                .ProfiledValue
                .Should()
                .Be(expectedAmounts[amount], "Profiled value at index {0} should match expected value", amount);
            }
        }
        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);
            }
        }