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); }
public Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); PublishedProviderVersion priorState = providerVariationContext.PriorState; if (priorState == null || priorState.Provider.Status == Closed || providerVariationContext.UpdatedProvider.Status != Closed || !providerVariationContext.UpdatedProvider.Successor.IsNullOrWhitespace()) { return(Task.CompletedTask); } if (providerVariationContext.UpdatedTotalFunding != priorState.TotalFunding) { providerVariationContext.RecordErrors("Unable to run Closure variation as TotalFunding has changed during the refresh funding"); return(Task.CompletedTask); } providerVariationContext.QueueVariationChange(new ZeroRemainingProfilesChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ZeroInitialPaymentProfilesChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ReAdjustFundingValuesForProfileValuesChange(providerVariationContext)); return(Task.CompletedTask); }
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); }
protected ProfileVariationPointerChange(ProviderVariationContext variationContext, string changeName) : base(variationContext) { Guard.IsNullOrWhiteSpace(changeName, nameof(changeName)); _changeName = changeName; }
public async Task TracksConfiguredPropertiesForVariationReasons(ProviderVariationContext variationContext, VariationReason[] expectedVariationReasons) { expectedVariationReasons ??= new VariationReason[0]; await _metadataVariationStrategy.DetermineVariations(variationContext, null); variationContext .VariationReasons .OrderBy(_ => _) .Should() .BeEquivalentTo(expectedVariationReasons.OrderBy(_ => _)); if (expectedVariationReasons.AnyWithNullCheck()) { variationContext.QueuedChanges .FirstOrDefault() .Should() .BeOfType <MetaDataVariationsChange>(); } else { variationContext.QueuedChanges .Should() .BeNullOrEmpty(); } }
protected async Task <PublishedProvider> GetOrCreateSuccessorProvider(ProviderVariationContext providerVariationContext, string successorId) { return(providerVariationContext.GetPublishedProviderRefreshState(successorId) ?? providerVariationContext.AddMissingProvider(await _providerService.CreateMissingPublishedProviderForPredecessor( providerVariationContext.PublishedProvider, successorId, providerVariationContext.ProviderVersionId))); }
public async Task ExecutesVariationStrategiesSpecifiedInSuppliedFundingVariationsAndReturnsVariationResult( FundingVariation[] fundingVariations) { IEnumerable <ProfileVariationPointer> variationPointers = ArraySegment <ProfileVariationPointer> .Empty; PublishedProvider existingPublishedProvider = NewPublishedProvider(); Provider updatedProvider = NewApiProvider(); decimal updatedTotalFunding = new RandomNumberBetween(0, 1000); IDictionary <string, PublishedProviderSnapShots> allPublishedProviderSnapShots = new Dictionary <string, PublishedProviderSnapShots>(); IDictionary <string, PublishedProvider> allPublishedProviderRefreshStates = new Dictionary <string, PublishedProvider>(); string providerVersionId = NewRandomString(); ProviderVariationContext providerVariationContext = await _factory.CreateRequiredVariationChanges(existingPublishedProvider, updatedTotalFunding, updatedProvider, fundingVariations, allPublishedProviderSnapShots, allPublishedProviderRefreshStates, variationPointers, providerVersionId); providerVariationContext .UpdatedTotalFunding .Should() .Be(updatedTotalFunding); providerVariationContext .ReleasedState .Should() .BeSameAs(existingPublishedProvider.Released); providerVariationContext .UpdatedProvider .Should() .BeSameAs(updatedProvider); providerVariationContext .ProviderVersionId .Should() .BeSameAs(providerVersionId); Received.InOrder(() => { foreach (FundingVariation fundingVariation in fundingVariations.OrderBy(_ => _.Order)) { _variationStrategyServiceLocator.GetService(fundingVariation.Name); _variationStrategy.DetermineVariations(Arg.Is <ProviderVariationContext>( ctx => ctx.UpdatedTotalFunding == updatedTotalFunding && ReferenceEquals(ctx.ReleasedState, existingPublishedProvider.Released) && ctx.ProviderId == existingPublishedProvider.Current.ProviderId && ReferenceEquals(ctx.UpdatedProvider, updatedProvider) && ReferenceEquals(ctx.AllPublishedProviderSnapShots, allPublishedProviderSnapShots) && ReferenceEquals(ctx.AllPublishedProvidersRefreshStates, allPublishedProviderRefreshStates) && ctx.ProviderVersionId == providerVersionId), fundingVariation.FundingLineCodes); } }); }
public void Run(ProviderVariationContext providerVariationContext) { string priorValue = (string)_priorStateAccessor.GetValue(providerVariationContext.PriorState.Provider); string currentValue = (string)_updatedStateAccessor.GetValue(providerVariationContext.UpdatedProvider); if (priorValue != currentValue) { providerVariationContext.AddVariationReasons(_variationReason); } }
public async Task AddsVariationContextsToBeAppliedLater() { ProviderVariationContext contextOne = NewVariationContext(); ProviderVariationContext contextTwo = NewVariationContext(); GivenTheVariationContextWasAdded(contextOne); AndTheVariationContextWasAdded(contextTwo); await WhenTheVariationsAreApplied(); await ThenTheVariationsWereApplied(contextOne); await AndTheVariationsWereApplied(contextTwo); }
private static ProviderVariationContext NewProviderVariationContext(Action <ProviderVariationContextBuilder> setUp = null) { ProviderVariationContextBuilder variationContextBuilder = new ProviderVariationContextBuilder(); setUp?.Invoke(variationContextBuilder); ProviderVariationContext providerVariationContext = variationContextBuilder.Build(); providerVariationContext.AllPublishedProviderSnapShots = AsDictionary(new PublishedProviderSnapShots(providerVariationContext.PublishedProvider)); providerVariationContext.AllPublishedProvidersRefreshStates = AsDictionary(providerVariationContext.PublishedProvider); return(providerVariationContext); }
public async Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); Provider updatedProvider = providerVariationContext.UpdatedProvider; string successorId = updatedProvider.Successor; PublishedProviderVersion priorState = providerVariationContext.PriorState; if (priorState == null || priorState.Provider.Status == Closed || updatedProvider.Status != Closed || successorId.IsNullOrWhitespace()) { return; } if (providerVariationContext.UpdatedTotalFunding != priorState.TotalFunding) { providerVariationContext.RecordErrors("Unable to run Closure with Successor variation as TotalFunding has changed during the refresh funding"); return; } PublishedProvider successorProvider = await GetOrCreateSuccessorProvider(providerVariationContext, successorId); if (successorProvider == null) { providerVariationContext.RecordErrors($"Unable to run Closure with Successor variation as could not locate or create a successor provider with id:{successorId}"); return; } string providerId = providerVariationContext.ProviderId; if (successorProvider.HasPredecessor(providerId)) { return; } providerVariationContext.SuccessorRefreshState = successorProvider.Current; successorProvider.AddPredecessor(providerId); providerVariationContext.QueueVariationChange(new TransferRemainingProfilesToSuccessorChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ReAdjustSuccessorFundingValuesForProfileValueChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ZeroRemainingProfilesChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ReAdjustFundingValuesForProfileValuesChange(providerVariationContext)); }
public ProviderVariationContext Build() { ProviderVariationContext providerVariationContext = new ProviderVariationContext { UpdatedProvider = _currentState, PublishedProvider = _publishedProvider, UpdatedTotalFunding = _updatedTotalFunding }; if (_errors?.Any() == true) { providerVariationContext.ErrorMessages.AddRange(_errors); } return(providerVariationContext); }
public async Task <IDictionary <string, PublishedProvider> > PrepareVariedProviders(decimal?updatedTotalFunding, IDictionary <string, PublishedProvider> allPublishedProviderRefreshStates, PublishedProvider existingPublishedProvider, Provider updatedProvider, IEnumerable <FundingVariation> variations, IEnumerable <ProfileVariationPointer> variationPointers, string snapshotId, string specificationProviderVersionId) { Guard.ArgumentNotNull(updatedTotalFunding, nameof(updatedTotalFunding)); Guard.ArgumentNotNull(allPublishedProviderRefreshStates, nameof(allPublishedProviderRefreshStates)); Guard.ArgumentNotNull(existingPublishedProvider, nameof(existingPublishedProvider)); Guard.ArgumentNotNull(updatedProvider, nameof(updatedProvider)); bool shouldRunVariations = variations.AnyWithNullCheck() && !string.IsNullOrWhiteSpace(snapshotId); _logger.Verbose($"Variations enabled = {shouldRunVariations}"); if (!shouldRunVariations || !_snapshots.TryGetValue(snapshotId, out IDictionary <string, PublishedProviderSnapShots> publishedProviderSnapshots)) { return(null); } _logger.Verbose($"Number of snapshot providers = {publishedProviderSnapshots.Count}"); ProviderVariationContext variationContext = await _detectProviderVariations.CreateRequiredVariationChanges(existingPublishedProvider, updatedTotalFunding, updatedProvider, variations, publishedProviderSnapshots, allPublishedProviderRefreshStates, variationPointers, specificationProviderVersionId); if (variationContext.HasVariationChanges) { _applyProviderVariations.AddVariationContext(variationContext); if (variationContext.NewProvidersToAdd.Any()) { return(variationContext.NewProvidersToAdd.ToDictionary(_ => _.Current.ProviderId)); } } return(null); }
public Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); PublishedProviderVersion priorState = providerVariationContext.PriorState; if (priorState == null || priorState.Provider.Status == Closed || providerVariationContext.UpdatedProvider.Status == Closed) { return(Task.CompletedTask); } providerVariationContext.QueueVariationChange(new AdjustDsgProfilesForUnderOverPaymentChange(providerVariationContext)); providerVariationContext.QueueVariationChange(new ReAdjustFundingValuesForProfileValuesChange(providerVariationContext)); return(Task.CompletedTask); }
public Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { if (providerVariationContext.PriorState == null || providerVariationContext.UpdatedProvider == null) { return(Task.CompletedTask); } foreach (VariationCheck variationCheck in VariationChecks) { variationCheck.Run(providerVariationContext); } if (providerVariationContext.VariationReasons.AnyWithNullCheck()) { providerVariationContext.QueueVariationChange(new MetaDataVariationsChange(providerVariationContext)); } return(Task.CompletedTask); }
public Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); PublishedProviderVersion priorState = providerVariationContext.PriorState; if (priorState == null || priorState.Provider.Status == Closed || providerVariationContext.UpdatedProvider.Status == Closed || providerVariationContext.UpdatedTotalFunding == priorState.TotalFunding) { return(Task.CompletedTask); } providerVariationContext.AddVariationReasons(VariationReason.FundingUpdated); providerVariationContext.QueueVariationChange(new MetaDataVariationsChange(providerVariationContext)); return(Task.CompletedTask); }
private bool HasNoCarryOverChanges(PublishedProviderVersion priorState, PublishedProviderVersion refreshState, ProviderVariationContext providerVariationContext) { bool hasNoCarryOverChanges = true; foreach (ProfilingCarryOver carryOver in priorState.CarryOvers ?? ArraySegment <ProfilingCarryOver> .Empty) { ProfilingCarryOver latestCustomProfile = refreshState.CarryOvers?.SingleOrDefault(_ => _.FundingLineCode == carryOver.FundingLineCode); if ((latestCustomProfile?.Amount).GetValueOrDefault() != carryOver.Amount) { providerVariationContext.AddAffectedFundingLineCode(carryOver.FundingLineCode); hasNoCarryOverChanges = false; } } return(hasNoCarryOverChanges); }
public Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); PublishedProviderVersion priorState = providerVariationContext.PriorState; PublishedProviderVersion refreshState = providerVariationContext.RefreshState; if (priorState == null || providerVariationContext.ReleasedState == null || priorState.Provider.Status == Closed || providerVariationContext.UpdatedProvider.Status == Closed || HasNoProfilingChanges(priorState, refreshState, providerVariationContext) || HasNoPaidPeriods(providerVariationContext, priorState)) { return(Task.CompletedTask); } providerVariationContext.QueueVariationChange(new ReProfileVariationChange(providerVariationContext)); return(Task.CompletedTask); }
public async Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes) { Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext)); Provider updatedProvider = providerVariationContext.UpdatedProvider; string successorId = updatedProvider.Successor; PublishedProviderVersion priorState = providerVariationContext.PriorState; if (priorState == null || priorState.Provider.Status == Closed || updatedProvider.Status != Closed || successorId.IsNullOrWhitespace()) { return; } PublishedProvider successorProvider = await GetOrCreateSuccessorProvider(providerVariationContext, successorId); if (successorProvider == null) { providerVariationContext.RecordErrors( $"Unable to run Pupil Number Successor variation as could not locate or create a successor provider with id:{successorId}"); return; } string providerId = providerVariationContext.ProviderId; providerVariationContext.SuccessorRefreshState = successorProvider.Current; successorProvider.AddPredecessor(providerId); providerVariationContext.QueueVariationChange(new MovePupilNumbersToSuccessorChange(providerVariationContext)); }
public async Task <ProviderVariationContext> CreateRequiredVariationChanges(PublishedProvider existingPublishedProvider, decimal?updatedTotalFunding, Provider provider, IEnumerable <FundingVariation> variations, IDictionary <string, PublishedProviderSnapShots> allPublishedProviderSnapShots, IDictionary <string, PublishedProvider> allPublishedProviderRefreshStates, IEnumerable <ProfileVariationPointer> variationPointers, string providerVersionId) { Guard.ArgumentNotNull(existingPublishedProvider, nameof(existingPublishedProvider)); Guard.ArgumentNotNull(updatedTotalFunding, nameof(updatedTotalFunding)); Guard.ArgumentNotNull(provider, nameof(provider)); Guard.ArgumentNotNull(variations, nameof(variations)); Guard.ArgumentNotNull(allPublishedProviderRefreshStates, nameof(allPublishedProviderRefreshStates)); Guard.ArgumentNotNull(allPublishedProviderSnapShots, nameof(allPublishedProviderSnapShots)); ProviderVariationContext providerVariationContext = new ProviderVariationContext { PublishedProvider = existingPublishedProvider, UpdatedProvider = provider, UpdatedTotalFunding = updatedTotalFunding, AllPublishedProviderSnapShots = allPublishedProviderSnapShots, AllPublishedProvidersRefreshStates = allPublishedProviderRefreshStates, ProviderVersionId = providerVersionId, VariationPointers = variationPointers }; foreach (FundingVariation configuredVariation in variations.OrderBy(_ => _.Order)) { IVariationStrategy variationStrategy = _variationStrategyServiceLocator.GetService(configuredVariation.Name); await variationStrategy.DetermineVariations(providerVariationContext, configuredVariation.FundingLineCodes); } return(providerVariationContext); }
public MetaDataVariationsChange(ProviderVariationContext variationContext) : base(variationContext) { }
private async Task AndTheVariationsWereApplied(ProviderVariationContext variationContext) { await ThenTheVariationsWereApplied(variationContext); }
public void SetUp() { _variationContext = new ProviderVariationContext(); _applyProviderVariations = Substitute.For <IApplyProviderVariations>(); }
protected override bool HasNoProfilingChanges(PublishedProviderVersion priorState, PublishedProviderVersion refreshState, ProviderVariationContext providerVariationContext) => base.HasNoProfilingChanges(priorState, refreshState, providerVariationContext) && HasNoCarryOverChanges(priorState, refreshState, providerVariationContext);
protected VariationChange(ProviderVariationContext variationContext) { Guard.ArgumentNotNull(variationContext, nameof(variationContext)); VariationContext = variationContext; }
public ReAdjustFundingValuesForProfileValuesChange(ProviderVariationContext variationContext) : base(variationContext) { }
public ReProfileVariationChange(ProviderVariationContext variationContext) : base(variationContext) { }
public ZeroInitialPaymentProfilesChange(ProviderVariationContext variationContext) : base(variationContext) { }
public ZeroAllProfiles(ProviderVariationContext variationContext) : base(variationContext) { }
public void ProviderVariationContextTestBaseSetUp() { _queuedChangeIndex = 0; VariationContext = NewVariationContext(); }