public void BuildPaymentInfoDictionary_MixedCaseLearnRefNumber()
        {
            var paymentInfo = new AppsCoInvestmentPaymentsInfo()
            {
                Payments = new List <PaymentInfo>()
                {
                    new PaymentInfo()
                    {
                        LearnerReferenceNumber = "MiXeD",
                    },
                    new PaymentInfo()
                    {
                        LearnerReferenceNumber = "mixed",
                    },
                    new PaymentInfo()
                    {
                        LearnerReferenceNumber = "MIXED",
                    }
                }
            };

            var builder = new AppsCoInvestmentContributionsModelBuilder(new AppsCoInvestmentRecordKeyEqualityComparer(), null);

            var result = builder.BuildPaymentInfoDictionary(paymentInfo);

            var key = new AppsCoInvestmentRecordKey("MIXED", null, 0, 0, 0, 0);

            result.Should().HaveCount(1);

            result.TryGetValue(key, out var check);

            check.Should().NotBeNull();
            check.Count.Should().Be(3);
        }
Example #2
0
 // BR2
 public bool FilterReportRows(AppsCoInvestmentPaymentsInfo paymentInfo, AppsCoInvestmentRulebaseInfo rulebaseInfo, AppsCoInvestmentILRInfo ilrInfo, AppsCoInvestmentRecordKey recordKey)
 {
     return
         (EmployerCoInvestmentPaymentFilter(paymentInfo, recordKey.LearnerReferenceNumber) ||
          CompletionPaymentFilter(paymentInfo, recordKey.LearnerReferenceNumber) ||
          PMRAppFinRecordFilter(ilrInfo, recordKey.LearnerReferenceNumber) ||
          NonZeroCompletionEarningsFilter(rulebaseInfo, recordKey.LearnerReferenceNumber));
 }
        public async Task <AppsCoInvestmentPaymentsInfo> GetPaymentsInfoForAppsCoInvestmentReportAsync(int ukPrn, CancellationToken cancellationToken)
        {
            var appsCoInvestmentPaymentsInfo = new AppsCoInvestmentPaymentsInfo
            {
                UkPrn    = ukPrn,
                Payments = new List <PaymentInfo>()
            };

            cancellationToken.ThrowIfCancellationRequested();
            using (IDASPaymentsContext context = _dasPaymentsContextFactory())
            {
                appsCoInvestmentPaymentsInfo.Payments =
                    await context.Payments
                    .Where(p =>
                           p.Ukprn == ukPrn &&
                           p.AcademicYear <= Generics.AcademicYear &&
                           (p.FundingSource == AppsCoInvestmentFundingType ||
                            _appsCoInvestmentTransactionTypes.Contains(p.TransactionType)))
                    .Select(payment =>
                            new PaymentInfo()
                {
                    FundingSource            = payment.FundingSource,
                    TransactionType          = payment.TransactionType,
                    AcademicYear             = payment.AcademicYear,
                    CollectionPeriod         = payment.CollectionPeriod,
                    ContractType             = payment.ContractType,
                    DeliveryPeriod           = payment.DeliveryPeriod,
                    LearnerReferenceNumber   = payment.LearnerReferenceNumber,
                    LearnerUln               = payment.LearnerUln,
                    LearningAimFrameworkCode = payment.LearningAimFrameworkCode,
                    LearningAimPathwayCode   = payment.LearningAimPathwayCode,
                    LearningAimProgrammeType = payment.LearningAimProgrammeType,
                    LearningAimReference     = payment.LearningAimReference,
                    LearningAimStandardCode  = payment.LearningAimStandardCode,
                    LearningStartDate        = payment.LearningStartDate,
                    UkPrn  = payment.Ukprn,
                    Amount = payment.Amount,
                    PriceEpisodeIdentifier    = payment.PriceEpisodeIdentifier,
                    SfaContributionPercentage = payment.SfaContributionPercentage,
                    ApprenticeshipId          = payment.ApprenticeshipId,
                }).ToListAsync(cancellationToken);
            }

            return(appsCoInvestmentPaymentsInfo);
        }
Example #4
0
        public async Task <AppsCoInvestmentPaymentsInfo> GetPaymentsInfoForAppsCoInvestmentReportAsync(int ukPrn, CancellationToken cancellationToken)
        {
            var appsCoInvestmentPaymentsInfo = new AppsCoInvestmentPaymentsInfo
            {
                UkPrn    = ukPrn,
                Payments = new List <PaymentInfo>()
            };

            cancellationToken.ThrowIfCancellationRequested();
            List <Payment> paymentsList;

            using (IDASPaymentsContext context = _dasPaymentsContextFactory())
            {
                paymentsList = await context.Payments.Where(x => x.Ukprn == ukPrn &&
                                                            x.FundingSource == FundingSource &&
                                                            TransactionTypes.Contains(x.TransactionType)).ToListAsync(cancellationToken);
            }

            foreach (var payment in paymentsList)
            {
                var paymentInfo = new PaymentInfo
                {
                    FundingSource            = payment.FundingSource,
                    TransactionType          = payment.TransactionType,
                    AcademicYear             = payment.AcademicYear,
                    CollectionPeriod         = payment.CollectionPeriod,
                    ContractType             = payment.ContractType,
                    DeliveryPeriod           = payment.DeliveryPeriod,
                    LearnerReferenceNumber   = payment.LearnerReferenceNumber,
                    LearnerUln               = payment.LearnerUln,
                    LearningAimFrameworkCode = payment.LearningAimFrameworkCode,
                    LearningAimPathwayCode   = payment.LearningAimPathwayCode,
                    LearningAimProgrammeType = payment.LearningAimProgrammeType,
                    LearningAimReference     = payment.LearningAimReference,
                    LearningAimStandardCode  = payment.LearningAimStandardCode
                };

                appsCoInvestmentPaymentsInfo.Payments.Add(paymentInfo);
            }

            return(appsCoInvestmentPaymentsInfo);
        }
Example #5
0
 public bool EmployerCoInvestmentPaymentFilter(AppsCoInvestmentPaymentsInfo paymentsInfo, string learnRefNumber)
 {
     return(paymentsInfo.Payments?.Any(p => p.FundingSource == 3 && p.LearnerReferenceNumber.CaseInsensitiveEquals(learnRefNumber)) ?? false);
 }
Example #6
0
 public bool CompletionPaymentFilter(AppsCoInvestmentPaymentsInfo paymentsInfo, string learnRefNumber)
 {
     return(paymentsInfo.Payments?.Any(p => p.TransactionType == 3 && p.LearnerReferenceNumber.CaseInsensitiveEquals(learnRefNumber)) ?? false);
 }
Example #7
0
        // BR1
        public IEnumerable <string> GetRelevantLearners(AppsCoInvestmentILRInfo ilrInfo, AppsCoInvestmentPaymentsInfo paymentsInfo)
        {
            var fm36learners = ilrInfo
                               .Learners?
                               .Where(l =>
                                      l.LearningDeliveries?
                                      .Any(ld => ld.FundModel == 36)
                                      ?? false);

            var pmrLearnRefNumbers = fm36learners
                                     .Where(l =>
                                            l.LearningDeliveries?
                                            .Any(ld => ld.AppFinRecords?.Any(afr => afr.AFinType == "PMR") ?? false)
                                            ?? false)
                                     .Select(l => l.LearnRefNumber).ToList()
                                     ?? Enumerable.Empty <string>();

            var fm36LearnRefNumbers = new HashSet <string>(fm36learners.Select(l => l.LearnRefNumber), StringComparer.OrdinalIgnoreCase);

            var paymentLearnRefNumbers = paymentsInfo
                                         .Payments
                                         .Where(p => p.FundingSource == _fundingSource && fm36LearnRefNumbers.Contains(p.LearnerReferenceNumber))
                                         .Select(p => p.LearnerReferenceNumber).ToList();

            return(pmrLearnRefNumbers.Union(paymentLearnRefNumbers));
        }
Example #8
0
        public IEnumerable <AppsCoInvestmentContributionsModel> BuildModel(
            AppsCoInvestmentILRInfo appsCoInvestmentIlrInfo,
            AppsCoInvestmentRulebaseInfo appsCoInvestmentRulebaseInfo,
            AppsCoInvestmentPaymentsInfo appsCoInvestmentPaymentsInfo,
            List <AppsCoInvestmentRecordKey> paymentsAppsCoInvestmentUniqueKeys,
            List <AppsCoInvestmentRecordKey> ilrAppsCoInvestmentUniqueKeys,
            IDictionary <long, string> apprenticeshipIdLegalEntityNameDictionary,
            long jobId,
            int ukprn)
        {
            string errorMessage;

            if (appsCoInvestmentIlrInfo == null || appsCoInvestmentIlrInfo.Learners == null)
            {
                errorMessage = "Error: BuildModel() - AppsCoInvestmentILRInfo is null, no data has been retrieved from the ILR1920 data store.";
                _logger.LogInfo(errorMessage, jobIdOverride: jobId);

                throw new Exception(errorMessage);
            }

            if (appsCoInvestmentRulebaseInfo == null)
            {
                errorMessage = "Error: BuildModel() - AppsCoInvestmentRulebaseInfo is null, no data has been retrieved from the ILR1920 data store.";
                _logger.LogInfo(errorMessage, jobIdOverride: jobId);

                throw new Exception(errorMessage);
            }

            if (appsCoInvestmentPaymentsInfo == null)
            {
                errorMessage = "Error: BuildModel() - appsCoInvestmentPaymentsInfo is null, no data has been retrieved from the Payments data store.";
                _logger.LogInfo(errorMessage, jobIdOverride: jobId);

                throw new Exception(errorMessage);
            }

            var paymentsDictionary = BuildPaymentInfoDictionary(appsCoInvestmentPaymentsInfo);
            var learnerDictionary  = BuildLearnerDictionary(appsCoInvestmentIlrInfo);

            var relevantLearnRefNumbers = GetRelevantLearners(appsCoInvestmentIlrInfo, appsCoInvestmentPaymentsInfo).ToList();

            var uniqueKeys = UnionKeys(relevantLearnRefNumbers, ilrAppsCoInvestmentUniqueKeys, paymentsAppsCoInvestmentUniqueKeys).ToList();

            return(uniqueKeys
                   .Where(r => FilterReportRows(appsCoInvestmentPaymentsInfo, appsCoInvestmentRulebaseInfo, appsCoInvestmentIlrInfo, r))
                   .Select(record =>
            {
                var paymentRecords = GetPaymentInfosForRecord(paymentsDictionary, record).ToList();
                var learner = GetLearnerForRecord(learnerDictionary, record);
                var learningDelivery = GetLearningDeliveryForRecord(learner, record);
                var filteredPaymentRecords = FundingSourceAndTransactionTypeFilter(paymentRecords).ToList();
                var rulebaseLearningDelivery = GetRulebaseLearningDelivery(appsCoInvestmentRulebaseInfo, learningDelivery);
                var completedPaymentRecordsInCurrentYear = paymentRecords.Where(p => p.AcademicYear == Generics.AcademicYear && p.TransactionType == 2).ToList();
                var totalsByPeriodDictionary = BuildCoinvestmentPaymentsPerPeriodDictionary(filteredPaymentRecords);
                var earliestPaymentInfo = GetEarliestPaymentInfo(paymentRecords);

                string legalEntityName = null;

                if (earliestPaymentInfo != null && earliestPaymentInfo.ApprenticeshipId.HasValue)
                {
                    apprenticeshipIdLegalEntityNameDictionary.TryGetValue(earliestPaymentInfo.ApprenticeshipId.Value, out legalEntityName);
                }

                var totalDueCurrentYear = totalsByPeriodDictionary.Sum(d => d.Value);
                var totalDuePreviousYear = filteredPaymentRecords.Where(p => p.AcademicYear < 1920).Sum(p => p.Amount);
                var totalCollectedCurrentYear = GetTotalPMRBetweenDates(learningDelivery, _academicYearStart, _nextAcademicYearStart);
                var totalCollectedPreviousYear = GetTotalPMRBetweenDates(learningDelivery, null, _academicYearStart);

                var model = new AppsCoInvestmentContributionsModel
                {
                    Ukprn = ukprn,
                    LearnRefNumber = record.LearnerReferenceNumber,
                    UniqueLearnerNumber = GetUniqueOrEmpty(paymentRecords, p => p.LearnerUln),
                    LearningStartDate = record.LearningStartDate,
                    ProgType = record.LearningAimProgrammeType,
                    StandardCode = record.LearningAimStandardCode,
                    FrameworkCode = record.LearningAimFrameworkCode,
                    ApprenticeshipPathway = record.LearningAimPathwayCode,
                    SoftwareSupplierAimIdentifier = learningDelivery?.SWSupAimId,
                    LearningDeliveryFAMTypeApprenticeshipContractType = GetUniqueOrEmpty(paymentRecords, p => p.ContractType),
                    EmployerIdentifierAtStartOfLearning = learner?.LearnerEmploymentStatus.Where(w => w.DateEmpStatApp <= record.LearningStartDate).OrderByDescending(o => o.DateEmpStatApp).FirstOrDefault()?.EmpId,
                    EmployerNameFromApprenticeshipService = legalEntityName,
                    EmployerCoInvestmentPercentage = GetEmployerCoInvestmentPercentage(filteredPaymentRecords),
                    ApplicableProgrammeStartDate = rulebaseLearningDelivery?.AppAdjLearnStartDate,
                    TotalPMRPreviousFundingYears = totalCollectedPreviousYear,
                    TotalCoInvestmentDueFromEmployerInPreviousFundingYears = totalDuePreviousYear,
                    TotalPMRThisFundingYear = totalCollectedCurrentYear,
                    TotalCoInvestmentDueFromEmployerThisFundingYear = totalDueCurrentYear,
                    PercentageOfCoInvestmentCollected = GetPercentageOfInvestmentCollected(totalDueCurrentYear, totalDuePreviousYear, totalCollectedCurrentYear, totalCollectedPreviousYear),
                    LDM356Or361 = HasLdm356Or361(learningDelivery) ? "Yes" : "No",
                    CompletionEarningThisFundingYear = CalculateCompletionEarningsThisFundingYear(learningDelivery, appsCoInvestmentRulebaseInfo),
                    CompletionPaymentsThisFundingYear = completedPaymentRecordsInCurrentYear.Sum(r => r.Amount),
                    CoInvestmentDueFromEmployerForAugust = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 1),
                    CoInvestmentDueFromEmployerForSeptember = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 2),
                    CoInvestmentDueFromEmployerForOctober = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 3),
                    CoInvestmentDueFromEmployerForNovember = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 4),
                    CoInvestmentDueFromEmployerForDecember = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 5),
                    CoInvestmentDueFromEmployerForJanuary = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 6),
                    CoInvestmentDueFromEmployerForFebruary = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 7),
                    CoInvestmentDueFromEmployerForMarch = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 8),
                    CoInvestmentDueFromEmployerForApril = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 9),
                    CoInvestmentDueFromEmployerForMay = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 10),
                    CoInvestmentDueFromEmployerForJune = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 11),
                    CoInvestmentDueFromEmployerForJuly = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 12),
                    CoInvestmentDueFromEmployerForR13 = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 13),
                    CoInvestmentDueFromEmployerForR14 = GetPeriodisedValueFromDictionaryForPeriod(totalsByPeriodDictionary, 14)
                };

                return model;
            })
                   .Where(row => !IsExcludedRow(row))
                   .OrderBy(l => l.LearnRefNumber)
                   .ThenBy(t => t.LearningDeliveryFAMTypeApprenticeshipContractType));
        }
Example #9
0
 public IDictionary <AppsCoInvestmentRecordKey, List <PaymentInfo> > BuildPaymentInfoDictionary(AppsCoInvestmentPaymentsInfo paymentsInfo)
 {
     return(paymentsInfo
            .Payments
            .GroupBy(
                p => new AppsCoInvestmentRecordKey(p.LearnerReferenceNumber, p.LearningStartDate, p.LearningAimProgrammeType, p.LearningAimStandardCode, p.LearningAimFrameworkCode, p.LearningAimPathwayCode), _appsCoInvestmentEqualityComparer)
            .ToDictionary(k => k.Key, v => v.ToList(), _appsCoInvestmentEqualityComparer));
 }