Example #1
0
        public void TestDataLockEventToDataLockStatusChangedEventMap()
        {
            var dataLockEvent = new PayableEarningEvent
            {
                Learner = new Learner {
                    Uln = 1, ReferenceNumber = "2"
                },
                LearningAim = new LearningAim {
                    FrameworkCode = 3
                },
                AgreementId      = "4",
                CollectionPeriod = new CollectionPeriod {
                    AcademicYear = 1, Period = 2
                },
                EventId = Guid.NewGuid()
            };

            var changedToFailEvent = new DataLockStatusChangedToFailed
            {
                TransactionTypesAndPeriods = new Dictionary <TransactionType, List <EarningPeriod> > {
                    { TransactionType.Balancing, new List <EarningPeriod> {
                          new EarningPeriod {
                              Period = 1
                          }, new EarningPeriod {
                              Period = 2
                          }
                      } }
                },
                EventId = Guid.NewGuid()
            };

            Mapper.Map(dataLockEvent, changedToFailEvent);

            changedToFailEvent.Learner.Should().NotBeNull();
            changedToFailEvent.Learner.Uln.Should().Be(1);
            changedToFailEvent.LearningAim.Should().NotBeNull();
            changedToFailEvent.LearningAim.FrameworkCode.Should().Be(3);
            changedToFailEvent.CollectionPeriod.Should().NotBeNull();
            changedToFailEvent.CollectionPeriod.AcademicYear.Should().Be(1);
            changedToFailEvent.EventId.Should().Be(changedToFailEvent.EventId);
            changedToFailEvent.TransactionTypesAndPeriods.Should().NotBeNull();
            changedToFailEvent.TransactionTypesAndPeriods.Should().NotBeEmpty();
        }
        public async Task <List <DataLockStatusChanged> > ProcessDataLockFailure(DataLockEvent dataLockEvent)
        {
            var result          = new List <DataLockStatusChanged>();
            var changedToFailed = new DataLockStatusChangedToFailed
            {
                TransactionTypesAndPeriods = new Dictionary <TransactionType, List <EarningPeriod> >()
            };
            var changedToPassed = new DataLockStatusChangedToPassed
            {
                TransactionTypesAndPeriods = new Dictionary <TransactionType, List <EarningPeriod> >()
            };
            var failureChanged = new DataLockFailureChanged
            {
                TransactionTypesAndPeriods = new Dictionary <TransactionType, List <EarningPeriod> >()
            };
            var failuresToDelete = new List <long>();
            var failuresToRecord = new List <DataLockFailureEntity>();

            var newFailuresGroupedByTypeAndPeriod = GetFailuresGroupedByTypeAndPeriod(dataLockEvent);

            using (var scope = TransactionScopeFactory.CreateSerialisableTransaction())
            {
                var oldFailures = await dataLockFailureRepository.GetFailures(
                    dataLockEvent.Ukprn,
                    dataLockEvent.Learner.ReferenceNumber,
                    dataLockEvent.LearningAim.FrameworkCode,
                    dataLockEvent.LearningAim.PathwayCode,
                    dataLockEvent.LearningAim.ProgrammeType,
                    dataLockEvent.LearningAim.StandardCode,
                    dataLockEvent.LearningAim.Reference,
                    dataLockEvent.CollectionYear
                    ).ConfigureAwait(false);

                var fullListOfKeys = newFailuresGroupedByTypeAndPeriod.Keys
                                     .Concat(oldFailures.Select(f => (f.TransactionType, f.DeliveryPeriod)))
                                     .Distinct()
                                     .ToList();

                foreach (var key in fullListOfKeys)
                {
                    var transactionType = key.Item1;
                    var period          = key.Item2;

                    if (!newFailuresGroupedByTypeAndPeriod.TryGetValue(key, out var newPeriod))
                    {
                        paymentLogger.LogWarning(
                            $"Earning does not have transaction type {transactionType} for period {period} which is present in DataLockFailure. UKPRN {dataLockEvent.Ukprn}, LearnRefNumber: {dataLockEvent.Learner.ReferenceNumber}");
                        continue;
                    }

                    var oldFailureEntity = oldFailures.FirstOrDefault(f =>
                                                                      f.TransactionType == transactionType && f.DeliveryPeriod == period);
                    var oldFailure = oldFailureEntity?.EarningPeriod.DataLockFailures;
                    var newFailure = newPeriod?.DataLockFailures;

                    var statusChange = dataLockStatusService.GetStatusChange(oldFailure, newFailure);

                    switch (statusChange)
                    {
                    case DataLockStatusChange.ChangedToFailed:
                        AddTypeAndPeriodToEvent(changedToFailed, transactionType, newPeriod, dataLockEvent);
                        failuresToRecord.Add(CreateEntity(dataLockEvent, transactionType, period, newPeriod));
                        break;

                    case DataLockStatusChange.ChangedToPassed:
                        AddTypeAndPeriodToEvent(changedToPassed, transactionType, newPeriod, dataLockEvent);
                        failuresToDelete.Add(oldFailureEntity.Id);
                        break;

                    case DataLockStatusChange.FailureChanged:
                        AddTypeAndPeriodToEvent(failureChanged, transactionType, newPeriod, dataLockEvent);
                        failuresToRecord.Add(CreateEntity(dataLockEvent, transactionType, period, newPeriod));
                        failuresToDelete.Add(oldFailureEntity.Id);
                        break;
                    }
                }

                if (changedToFailed.TransactionTypesAndPeriods.Count > 0)
                {
                    result.Add(changedToFailed);
                }

                if (changedToPassed.TransactionTypesAndPeriods.Count > 0)
                {
                    result.Add(changedToPassed);
                }

                if (failureChanged.TransactionTypesAndPeriods.Count > 0)
                {
                    result.Add(failureChanged);
                }

                foreach (var dataLockStatusChanged in result)
                {
                    mapper.Map(dataLockEvent, dataLockStatusChanged);
                }

                await dataLockFailureRepository.ReplaceFailures(failuresToDelete, failuresToRecord,
                                                                dataLockEvent.EarningEventId, dataLockEvent.EventId).ConfigureAwait(false);

                scope.Complete();

                paymentLogger.LogDebug(
                    $"Deleted {failuresToDelete.Count} old DL failures, created {failuresToRecord.Count} new for UKPRN {dataLockEvent.Ukprn} Learner Ref {dataLockEvent.Learner.ReferenceNumber} on R{dataLockEvent.CollectionPeriod.Period:00}");

                return(result);
            }
        }