<commit_before>﻿using System.Linq;
using System.Threading.Tasks;
using SFA.DAS.EAS.Domain.Data.Repositories;
using SFA.DAS.EAS.Domain.Interfaces;
using SFA.DAS.NLog.Logger;

namespace SFA.DAS.EAS.Account.Worker.Jobs
{
    public class PaymentIntegrityCheckerJob : IJob
    {
        private readonly IPaymentService _paymentService;
        private readonly IEmployerAccountRepository _employerAccountRepository;
        private readonly IDasLevyRepository _levyRepository;
        private readonly ILog _logger;

        public PaymentIntegrityCheckerJob(
            IPaymentService paymentService,
            IEmployerAccountRepository employerAccountRepository,
            IDasLevyRepository levyRepository,
            ILog logger)
        {
            _paymentService = paymentService;
            _employerAccountRepository = employerAccountRepository;
            _levyRepository = levyRepository;
            _logger = logger;
        }

        public async Task Run()
        {
            var accounts = (await _employerAccountRepository.GetAllAccounts()).ToArray();

            _logger.Info($"Found {accounts.Length} to check payments for");

            var periodEnds = (await _levyRepository.GetAllPeriodEnds()).ToArray();

            _logger.Info($"Found {periodEnds.Length} period ends to process payments for");


            for (var periodEndIndex = 0; periodEndIndex < periodEnds.Length; periodEndIndex++)
            {
                var periodEnd = periodEnds[periodEndIndex];

                _logger.Info($"Processing payments for period end {periodEnd.Id} ({periodEndIndex + 1}/{periodEnds.Length})");

                for (var accountIndex = 0; accountIndex < accounts.Length; accountIndex++)
                {
                    var account = accounts[accountIndex];

                    try
                    {
                        _logger.Info($"Processing payments for account {account.Id} ({accountIndex + 1}/{accounts.Length})");

                    var expectedPayments = await _paymentService.GetAccountPayments(periodEnd.PeriodEndId, account.Id);

                        var actualPayments =
                        (await _levyRepository.GetAccountPaymentsByPeriodEnd(account.Id, periodEnd.PeriodEndId))
                            .ToArray();

                        var expectedPaymentsTotal = expectedPayments.Sum(x => x.Amount);
                        var actualPaymentsTotal = actualPayments.Sum(x => x.Amount);

                        var paymentMissing = actualPaymentsTotal != expectedPaymentsTotal;

                        //If the totals add up we check to see if all the payments are correct
                        //just in case a duplicate or incorrect record has the same amount as a correct one
                        if (!paymentMissing)
                        {
                            paymentMissing = expectedPayments.Except(actualPayments).Any();
                        }

                        if (paymentMissing)
                        {<commit_msg>Order period ends to be processed by newest first<commit_after>﻿using System.Linq;
using System.Threading.Tasks;
using SFA.DAS.EAS.Domain.Data.Repositories;
using SFA.DAS.EAS.Domain.Interfaces;
using SFA.DAS.NLog.Logger;

namespace SFA.DAS.EAS.Account.Worker.Jobs
{
    public class PaymentIntegrityCheckerJob : IJob
    {
        private readonly IPaymentService _paymentService;
        private readonly IEmployerAccountRepository _employerAccountRepository;
        private readonly IDasLevyRepository _levyRepository;
        private readonly ILog _logger;

        public PaymentIntegrityCheckerJob(
            IPaymentService paymentService,
            IEmployerAccountRepository employerAccountRepository,
            IDasLevyRepository levyRepository,
            ILog logger)
        {
            _paymentService = paymentService;
            _employerAccountRepository = employerAccountRepository;
            _levyRepository = levyRepository;
            _logger = logger;
        }

        public async Task Run()
        {
            var accounts = (await _employerAccountRepository.GetAllAccounts()).ToArray();

            _logger.Info($"Found {accounts.Length} to check payments for");

            var periodEnds = await _levyRepository.GetAllPeriodEnds();

            var orderedPeriodEnds = periodEnds.OrderByDescending(pe => pe.CalendarPeriodYear)
                .ThenByDescending(pe => pe.CalendarPeriodMonth).ToArray();

            _logger.Info($"Found {orderedPeriodEnds.Length} period ends to process payments for");


            for (var periodEndIndex = 0; periodEndIndex < orderedPeriodEnds.Length; periodEndIndex++)
            {
                var periodEnd = orderedPeriodEnds[periodEndIndex];

                _logger.Info($"Processing payments for period end {periodEnd.Id} ({periodEndIndex + 1}/{orderedPeriodEnds.Length})");

                for (var accountIndex = 0; accountIndex < accounts.Length; accountIndex++)
                {
                    var account = accounts[accountIndex];

                    try
                    {
                        _logger.Info($"Processing payments for account {account.Id} ({accountIndex + 1}/{accounts.Length})");

                    var expectedPayments = await _paymentService.GetAccountPayments(periodEnd.PeriodEndId, account.Id);

                        var actualPayments =
                        (await _levyRepository.GetAccountPaymentsByPeriodEnd(account.Id, periodEnd.PeriodEndId))
                            .ToArray();

                        var expectedPaymentsTotal = expectedPayments.Sum(x => x.Amount);
                        var actualPaymentsTotal = actualPayments.Sum(x => x.Amount);

                        var paymentMissing = actualPaymentsTotal != expectedPaymentsTotal;

                        //If the totals add up we check to see if all the payments are correct
                        //just in case a duplicate or incorrect record has the same amount as a correct one
                        if (!paymentMissing)
                        {
                            paymentMissing = expectedPayments.Except(actualPayments).Any();
                        }

                        if (paymentMissing)
                        {
{'fraction_non_alphanumeric': 0.07240393775801841, 'fraction_numerical': 0.0012702445220704986, 'mean_word_length': 1.9614480488951576, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6816132', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1453, 'n_words': 358}