예제 #1
0
        private decimal AdjustForUnderOrOverPayment(ReProfileContext context)
        {
            decimal carryOverAmount = 0;

            ReProfileRequest reProfileRequest = context.Request;

            IProfilePeriod[] orderedRefreshProfilePeriods = new YearMonthOrderedProfilePeriods <IProfilePeriod>(context.ProfileResult.DeliveryProfilePeriods)
                                                            .ToArray();
            IExistingProfilePeriod[] orderedExistingProfilePeriods = new YearMonthOrderedProfilePeriods <IExistingProfilePeriod>(reProfileRequest.ExistingPeriods)
                                                                     .ToArray();

            // get the last profile period paid
            IExistingProfilePeriod existingProfilePeriod = orderedExistingProfilePeriods.LastOrDefault(_ => _.IsPaid);

            // the variation pointer is the index of the next period after the last paid profile period
            int variationPointerIndex = existingProfilePeriod == null ? 0 : Array.IndexOf(orderedExistingProfilePeriods, existingProfilePeriod) + 1;

            decimal previousFundingLineValuePaid = orderedExistingProfilePeriods.Take(variationPointerIndex).Sum(_ => _.GetProfileValue());
            decimal latestFundingLineValuePaid   = orderedRefreshProfilePeriods.Take(variationPointerIndex).Sum(_ => _.GetProfileValue());
            decimal latestFundingLineValue       = reProfileRequest.FundingLineTotal;

            decimal fundingChange      = latestFundingLineValuePaid - previousFundingLineValuePaid;
            decimal latestPeriodAmount = (int)(latestFundingLineValue / orderedRefreshProfilePeriods.Length);

            AdjustPeriodsForFundingAlreadyReleased(variationPointerIndex,
                                                   orderedExistingProfilePeriods,
                                                   orderedRefreshProfilePeriods);

            if (fundingChange < 0)
            {
                if (AdjustingPeriodsForOverPaymentLeavesRemainder(variationPointerIndex,
                                                                  latestPeriodAmount,
                                                                  orderedExistingProfilePeriods,
                                                                  orderedRefreshProfilePeriods,
                                                                  out decimal remainingOverPayment))
                {
                    carryOverAmount = remainingOverPayment;
                }
            }
            else if (fundingChange > 0)
            {
                AdjustPeriodsForUnderPayment(variationPointerIndex,
                                             latestPeriodAmount,
                                             orderedExistingProfilePeriods,
                                             orderedRefreshProfilePeriods);
            }
            else
            {
                AdjustPeriodsForNoTotalAllocationChange(variationPointerIndex,
                                                        latestPeriodAmount,
                                                        orderedExistingProfilePeriods,
                                                        orderedRefreshProfilePeriods,
                                                        out carryOverAmount);
            }

            return(carryOverAmount);
        }
예제 #2
0
 private static DistributionPeriods[] MapIntoDistributionPeriods(ReProfileContext context)
 {
     return(context.ProfileResult.DeliveryProfilePeriods.GroupBy(_ => _.DistributionPeriod)
            .Select(_ => new DistributionPeriods
     {
         Value = _.Sum(dp => dp.ProfileValue),
         DistributionPeriodCode = _.Key
     })
            .ToArray());
 }
예제 #3
0
        public ReProfileStrategyResult ReProfile(ReProfileContext context)
        {
            decimal carryOverAmount = AdjustForUnderOrOverPayment(context);

            //TODO; put this change under test for the distribution periods stuff
            return(new ReProfileStrategyResult
            {
                DistributionPeriods = MapIntoDistributionPeriods(context),
                DeliveryProfilePeriods = context.ProfileResult.DeliveryProfilePeriods,
                CarryOverAmount = carryOverAmount
            });
        }
예제 #4
0
        public void SetUp()
        {
            _context = new ReProfileContext();

            _year  = NewRandomYear();
            _month = NewRandomMonth();

            _context = new ReProfileContext
            {
                Request       = new ReProfileRequest(),
                ProfileResult = new AllocationProfileResponse()
            };

            _reProfiling = new ReProfileDsgFundingLine();
        }
        public async Task <ActionResult <ReProfileResponse> > ReProfile(ReProfileRequest reProfileRequest)
        {
            FundingStreamPeriodProfilePattern profilePattern = await _profilePatternService.GetProfilePattern(reProfileRequest.FundingStreamId,
                                                                                                              reProfileRequest.FundingPeriodId,
                                                                                                              reProfileRequest.FundingLineCode,
                                                                                                              reProfileRequest.ProfilePatternKey);

            if (profilePattern == null)
            {
                return(new NotFoundObjectResult("Profile pattern not found"));
            }

            if (profilePattern.ReProfilingConfiguration == null || !profilePattern.ReProfilingConfiguration.ReProfilingEnabled)
            {
                return(new BadRequestObjectResult("Re-profiling is not enabled or has not been configured"));
            }

            IReProfilingStrategy strategy = GetReProfilingStrategy(reProfileRequest, profilePattern);

            if (strategy == null)
            {
                return(new BadRequestObjectResult("Re-profiling is not enabled for this scenario or the strategy was not found"));
            }

            ReProfileContext context = CreateReProfilingContext(reProfileRequest, profilePattern);

            ReProfileStrategyResult strategyResult = strategy.ReProfile(context);

            VerifyProfileAmountsReturnedMatchRequestedFundingLineValue(reProfileRequest, strategyResult);

            return(new ReProfileResponse
            {
                DeliveryProfilePeriods = strategyResult.DeliveryProfilePeriods,
                DistributionPeriods = strategyResult.DistributionPeriods,
                ProfilePatternDisplayName = profilePattern.ProfilePatternDisplayName,
                ProfilePatternKey = profilePattern.ProfilePatternKey,
                CarryOverAmount = strategyResult.CarryOverAmount
            });
        }