public CommitmentModel MapToCommitment(PaymentCreatedMessage paymentCreatedMessage) { var model = new CommitmentModel { EmployerAccountId = paymentCreatedMessage.EmployerAccountId, ApprenticeshipId = paymentCreatedMessage.ApprenticeshipId, LearnerId = paymentCreatedMessage.Uln, StartDate = paymentCreatedMessage.EarningDetails.StartDate, PlannedEndDate = paymentCreatedMessage.EarningDetails.PlannedEndDate, ActualEndDate = null, CompletionAmount = paymentCreatedMessage.EarningDetails.CompletionAmount, MonthlyInstallment = paymentCreatedMessage.EarningDetails.MonthlyInstallment, NumberOfInstallments = (short)paymentCreatedMessage.EarningDetails.TotalInstallments, ProviderId = paymentCreatedMessage.Ukprn, ProviderName = paymentCreatedMessage.ProviderName, ApprenticeName = paymentCreatedMessage.ApprenticeName, CourseName = paymentCreatedMessage.CourseName, CourseLevel = paymentCreatedMessage.CourseLevel, SendingEmployerAccountId = paymentCreatedMessage.SendingEmployerAccountId, FundingSource = FundingSourceConverter.ConvertToPaymentsFundingSource(paymentCreatedMessage.FundingSource), HasHadPayment = true, UpdatedDateTime = DateTime.UtcNow }; return(model); }
public void SetUp() { PaymentCreatedMessage = new PaymentCreatedMessage { EmployerAccountId = 1, SendingEmployerAccountId = 1, Amount = 100, ApprenticeshipId = 1, CollectionPeriod = new Application.Payments.Messages.NamedCalendarPeriod { Id = Guid.NewGuid().ToString("D"), Month = 1, Year = 2018 }, EarningDetails = new EarningDetails { StartDate = DateTime.Today, PlannedEndDate = DateTime.Today.AddMonths(14), CompletionAmount = 240, CompletionStatus = 1, MonthlyInstallment = 87.27m, TotalInstallments = 12, EndpointAssessorId = "EA-Id1", ActualEndDate = DateTime.MinValue }, ProviderName = "test provider", ApprenticeName = "test apprentice", CourseName = "test cource", CourseLevel = 1, Id = Guid.NewGuid().ToString("D"), Ukprn = 2, FundingSource = FundingSourceConverter.ConvertToApiFundingSource(FundingSource.Levy) }; }
public PaymentModel MapToPayment(PaymentCreatedMessage paymentCreatedMessage) { return(new PaymentModel { ExternalPaymentId = paymentCreatedMessage.Id, EmployerAccountId = paymentCreatedMessage.EmployerAccountId, SendingEmployerAccountId = paymentCreatedMessage.SendingEmployerAccountId, ProviderId = paymentCreatedMessage.Ukprn, LearnerId = paymentCreatedMessage.Uln, Amount = paymentCreatedMessage.Amount, CollectionPeriod = new Models.Payments.CalendarPeriod { // Id = paymentCreatedMessage.CollectionPeriod.Id, Month = paymentCreatedMessage.CollectionPeriod.Month, Year = paymentCreatedMessage.CollectionPeriod.Year }, DeliveryPeriod = new Models.Payments.CalendarPeriod { Month = paymentCreatedMessage.DeliveryPeriod.Month, Year = paymentCreatedMessage.DeliveryPeriod.Year }, ApprenticeshipId = paymentCreatedMessage.ApprenticeshipId, ReceivedTime = DateTime.UtcNow, FundingSource = FundingSourceConverter.ConvertToPaymentsFundingSource(paymentCreatedMessage.FundingSource) }); }
public async Task Handle(PaymentCreatedMessage message, string allowProjectionsEndpoint) { if (message.EarningDetails == null) { throw new InvalidOperationException($"Invalid payment created message. Earning details is null so cannot create commitment data. Employer account: {message.EmployerAccountId}, payment id: {message.Id}"); } _telemetry.AddEmployerAccountId(message.EmployerAccountId); _telemetry.AddProperty("Payment Id", message.Id); _telemetry.AddProperty("Apprenticeship Id", message.ApprenticeshipId.ToString()); var stopwatch = new Stopwatch(); stopwatch.Start(); var commitment = await _repository.Get(message.EmployerAccountId, message.ApprenticeshipId); var commitmentModel = _paymentMapper.MapToCommitment(message); if (!commitment.RegisterCommitment(commitmentModel)) { _logger.Info($"Not storing the employer commitment. Employer: {message.EmployerAccountId}, ApprenticeshipId: {message.ApprenticeshipId}, payment id: {message.Id}"); return; } _logger.Info($"Now storing the employer commitment. Employer: {message.EmployerAccountId}, ApprenticeshipId: {message.ApprenticeshipId}, payment id: {message.Id}"); await _repository.Store(commitment); _logger.Info($"Finished adding the employer commitment. Employer: {message.EmployerAccountId}, ApprenticeshipId: {message.ApprenticeshipId}, payment id: {message.Id}"); _queueService.SendMessageWithVisibilityDelay(message, allowProjectionsEndpoint); stopwatch.Stop(); _telemetry.TrackDuration("Stored Commitment", stopwatch.Elapsed); }
public void Then_An_Invalid_Operation_Exception_Is_Thrown_If_The_Message_Is_Not_Valid() { //Arrange var message = new PaymentCreatedMessage(); //Act Assert.ThrowsAsync <InvalidOperationException>(async() => await _handler.Handle(message, _allowProjectionQueueName)); }
public static async Task <PaymentCreatedMessage> Run( [ServiceBusTrigger("LevyPeriod", "mysubscription", AccessRights.Manage)] PaymentCreatedMessage paymentCreatedMessage, ExecutionContext executionContext, TraceWriter writer) { return(await FunctionRunner.Run <PaymentEventServiceBusFunction, PaymentCreatedMessage>(writer, executionContext, async (container, logger) => { logger.Info($"Added {nameof(PaymentCreatedMessage)} to queue: {QueueNames.PaymentValidator}, for EmployerAccountId: {paymentCreatedMessage?.EmployerAccountId}"); return await Task.FromResult(paymentCreatedMessage); })); }
public async Task <IEnumerable <long> > AllowedEmployerAccountIds(PaymentCreatedMessage paymentCreatedMessage) { _logger.Info($"Now checking if projections can be generated for payment events: {paymentCreatedMessage.EmployerAccountId}, {paymentCreatedMessage.Id}"); if (!_applicationConfiguration.AllowTriggerProjections) { _logger.Warn("Triggering of projections is disabled."); return(new List <long>()); } var employerAccountIds = new List <long>(); if (await IsEmployerAccountIdAllowed(paymentCreatedMessage.EmployerAccountId)) { _logger.Info($"Enough time has elapsed since last received payment and commitment to allow projections to be generated for employer {paymentCreatedMessage.EmployerAccountId}."); if (!await _auditService.RecordRunOfProjections(paymentCreatedMessage.EmployerAccountId, nameof(ProjectionSource.PaymentPeriodEnd))) { _logger.Info($"Triggering of payment projections for employer {paymentCreatedMessage.EmployerAccountId} has already been started."); } else { employerAccountIds.Add(paymentCreatedMessage.EmployerAccountId); } } else { _logger.Info($"Cannot allow projections for employer {paymentCreatedMessage.EmployerAccountId}. Not enough time has elapsed since last payment or commitment received."); } if (paymentCreatedMessage.SendingEmployerAccountId != 0 && paymentCreatedMessage.EmployerAccountId != paymentCreatedMessage.SendingEmployerAccountId) { if (await IsSendingEmployerAccountIdAllowed(paymentCreatedMessage.SendingEmployerAccountId)) { employerAccountIds.Add(paymentCreatedMessage.SendingEmployerAccountId); if (!await _auditService.RecordRunOfProjections(paymentCreatedMessage.SendingEmployerAccountId, nameof(ProjectionSource.PaymentPeriodEnd))) { _logger.Info($"Triggering of payment projections for employer {paymentCreatedMessage.SendingEmployerAccountId} has already been started."); } else { employerAccountIds.Add(paymentCreatedMessage.SendingEmployerAccountId); } } else { _logger.Info($"Cannot allow projections for employer {paymentCreatedMessage.SendingEmployerAccountId}. Not enough time has elapsed since last payment or commitment received."); } } return(employerAccountIds); }
public static async Task Run( [QueueTrigger(QueueNames.CommitmentProcessor)]PaymentCreatedMessage paymentCreatedMessage, ExecutionContext executionContext, TraceWriter writer) { await FunctionRunner.Run<PaymentEventStoreCommitmentFunction>(writer, executionContext, async (container, logger) => { logger.Debug($"Storing commitment. Account: {paymentCreatedMessage.EmployerAccountId}, apprenticeship id: {paymentCreatedMessage.ApprenticeshipId}"); var handler = container.GetInstance<StoreCommitmentHandler>(); await handler.Handle(paymentCreatedMessage, QueueNames.AllowProjection); logger.Info($"Stored commitment. Apprenticeship id: {paymentCreatedMessage.ApprenticeshipId}"); }); }
public static async Task Run( [QueueTrigger(QueueNames.PaymentNoCommitmentProcessor)] PaymentCreatedMessage paymentCreatedMessage, ExecutionContext executionContext, TraceWriter writer) { await FunctionRunner.Run <PaymentEventNoCommitmentStorePaymentFunction>(writer, executionContext, async (container, logger) => { logger.Debug($"Storing the payment. Employer: {paymentCreatedMessage.EmployerAccountId}, apprenticeship: {paymentCreatedMessage.ApprenticeshipId}."); var handler = container.GetInstance <ProcessEmployerPaymentHandler>(); logger.Debug("Resolved handler"); await handler.Handle(paymentCreatedMessage, string.Empty); logger.Info($"Finished storing payment. Employer: {paymentCreatedMessage.EmployerAccountId}, apprenticeship: {paymentCreatedMessage.ApprenticeshipId}."); }); }
public static PaymentCreatedMessage Run( [QueueTrigger(QueueNames.PaymentValidatorNoCommitment)] PaymentCreatedMessage paymentCreatedMessage, ExecutionContext executionContext, TraceWriter writer) { return(FunctionRunner.Run <PaymentEventNoCommitmentValidatorFunction, PaymentCreatedMessage>(writer, executionContext, (container, logger) => { var validationResults = container.GetInstance <PastPaymentEventSuperficialValidator>().Validate(paymentCreatedMessage); if (!validationResults.IsValid) { logger.Warn($"Past payment event failed superficial validation. Employer: {paymentCreatedMessage.EmployerAccountId} apprenticeship: {paymentCreatedMessage.ApprenticeshipId}, Errors:{validationResults.ToJson()}"); return null; } logger.Info($"Validated past {nameof(PaymentCreatedMessage)} for EmployerAccountId: {paymentCreatedMessage.EmployerAccountId} fundingSource:{paymentCreatedMessage.FundingSource}"); return paymentCreatedMessage; })); }
public async Task Handle(PaymentCreatedMessage paymentCreatedMessage, string allowProjectionsEndpoint) { _telemetry.AddEmployerAccountId(paymentCreatedMessage.EmployerAccountId); _telemetry.AddProperty("Payment Id", paymentCreatedMessage.Id); var stopwatch = new Stopwatch(); stopwatch.Start(); var employerPayment = _mapper.MapToPayment(paymentCreatedMessage); _logger.Debug($"Now storing the employer payment. Employer: {employerPayment.EmployerAccountId}, Payment Id: {employerPayment.ExternalPaymentId}, Collection period: {employerPayment.CollectionPeriod.Year} - {employerPayment.CollectionPeriod.Month}, Delivery period: {employerPayment.DeliveryPeriod.Year} - {employerPayment.DeliveryPeriod.Month}"); var payment = await _repository.Get(paymentCreatedMessage.EmployerAccountId, paymentCreatedMessage.Id); payment.RegisterPayment(employerPayment); await _repository.StorePayment(payment); _logger.Info($"Finished adding the employer payment. Employer: {employerPayment.EmployerAccountId}, Payment Id: {employerPayment.ExternalPaymentId}, Collection period: {employerPayment.CollectionPeriod.Year} - {employerPayment.CollectionPeriod.Month}, Delivery period: {employerPayment.DeliveryPeriod.Year} - {employerPayment.DeliveryPeriod.Month}"); stopwatch.Stop(); _telemetry.TrackDuration("Store Payment", stopwatch.Elapsed); _telemetry.TrackEvent("Stored Payment"); }
public static async Task Run( [QueueTrigger(QueueNames.AllowProjection)] PaymentCreatedMessage paymentCreatedMessage, [Queue(QueueNames.GenerateProjections)] ICollector <GenerateAccountProjectionCommand> collector, ExecutionContext executionContext, TraceWriter writer) { await FunctionRunner.Run <PaymentEventStorePaymentFunction>(writer, executionContext, async (container, logger) => { logger.Info("Getting payment declaration handler from container."); var handler = container.GetInstance <AllowAccountProjectionsHandler>(); if (handler == null) { throw new InvalidOperationException($"Failed to get payment handler from container."); } var allowedEmployerAccounts = (await handler.AllowedEmployerAccountIds(paymentCreatedMessage)).ToList(); if (allowedEmployerAccounts.Any()) { foreach (var allowedEmployerAccount in allowedEmployerAccounts) { logger.Info($"Now sending message to trigger the account projections for employer '{allowedEmployerAccount}', period: {paymentCreatedMessage.CollectionPeriod?.Id}, {paymentCreatedMessage.CollectionPeriod?.Month}"); var projectionSource = paymentCreatedMessage.ProjectionSource == ProjectionSource.Commitment ? paymentCreatedMessage.ProjectionSource : ProjectionSource.PaymentPeriodEnd; collector.Add(new GenerateAccountProjectionCommand { EmployerAccountId = allowedEmployerAccount, ProjectionSource = projectionSource, }); } } else { logger.Info($"Cannot generate the projections, still handling payment events. Employer: {paymentCreatedMessage.EmployerAccountId}"); } }); }
public void Arrange() { PaymentCreatedMessage = new PaymentCreatedMessage { EmployerAccountId = 1, SendingEmployerAccountId = 1, Amount = 100, ApprenticeshipId = 1, CollectionPeriod = new Application.Payments.Messages.NamedCalendarPeriod { Id = Guid.NewGuid().ToString("D"), Month = 1, Year = 2018 }, ProviderName = "test provider", ApprenticeName = "test apprentice", CourseName = "test course", CourseLevel = 1, Id = Guid.NewGuid().ToString("D"), Ukprn = 2, FundingSource = FundingSourceConverter.ConvertToApiFundingSource(FundingSource.Levy) }; }
public void Arrange() { _message = new PaymentCreatedMessage { EmployerAccountId = ExpectedEmployerAccountId, ApprenticeshipId = ExpectedApprenticeshipId, EarningDetails = new EarningDetails() }; _commitmentModel = new CommitmentModel { EmployerAccountId = ExpectedEmployerAccountId, CompletionAmount = 100 }; _employerCommitment = new EmployerCommitment(_commitmentModel); _employerCommitmentRepostiory = new Mock <IEmployerCommitmentRepository>(); _logger = new Mock <ILog>(); _paymentMapper = new Mock <IPaymentMapper>(); _paymentMapper.Setup(x => x.MapToCommitment(It.Is <PaymentCreatedMessage>(c => c.EmployerAccountId.Equals(ExpectedEmployerAccountId)))) .Returns(_commitmentModel); _employerCommitmentRepostiory.Setup(x => x.Get(ExpectedEmployerAccountId, ExpectedApprenticeshipId)) .ReturnsAsync(_employerCommitment); _queueServiceMock = new Mock <IQueueService>(); _handler = new Application.Commitments.Handlers.StoreCommitmentHandler( _employerCommitmentRepostiory.Object, _logger.Object, _paymentMapper.Object, new Mock <ITelemetry>().Object, new Apprenticeship.Mapping.ApprenticeshipMapping(), _queueServiceMock.Object); }