예제 #1
0
        public virtual async Task <OrchestratorResponse <FinanceDashboardViewModel> > Index(GetAccountFinanceOverviewQuery query)
        {
            var accountTask = _accountApiClient.GetAccount(query.AccountId);

            _logger.Info("After GetAccount call");
            var getAccountFinanceOverviewTask = _mediator.SendAsync(query);

            var account = await accountTask;

            var getAccountFinanceOverview = await getAccountFinanceOverviewTask;

            _logger.Info($"account : {account}  getAccountFinanceOverview: {getAccountFinanceOverview} ");
            _logger.Info($" account.ApprenticeshipEmployerType: {account.ApprenticeshipEmployerType}  AccountHashedId: {query.AccountHashedId} CurrentLevyFunds: {getAccountFinanceOverview.CurrentFunds} ");

            var viewModel = new OrchestratorResponse <FinanceDashboardViewModel>
            {
                Data = new FinanceDashboardViewModel
                {
                    IsLevyEmployer        = (ApprenticeshipEmployerType)Enum.Parse(typeof(ApprenticeshipEmployerType), account.ApprenticeshipEmployerType, true) == ApprenticeshipEmployerType.Levy,
                    AccountHashedId       = query.AccountHashedId,
                    CurrentLevyFunds      = getAccountFinanceOverview.CurrentFunds,
                    ExpiringFunds         = getAccountFinanceOverview.ExpiringFundsAmount,
                    ExpiryDate            = getAccountFinanceOverview.ExpiringFundsExpiryDate,
                    TotalSpendForLastYear = getAccountFinanceOverview.TotalSpendForLastYear,
                    FundingExpected       = getAccountFinanceOverview.FundsIn,
                    AvailableFunds        = getAccountFinanceOverview.FundsIn - getAccountFinanceOverview.FundsOut,
                    ProjectedSpend        = getAccountFinanceOverview.FundsOut
                }
            };

            _logger.Info($"viewModel : {viewModel}");

            return(viewModel);
        }
        public async Task <string> GetEmployerAccountPublicHashedIdAsync(long accountId)
        {
            try
            {
                var account = await _accountApiClient.GetAccount(accountId);

                return(account.HashedAccountId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Failed to retrieve account information for account Id: {accountId}");
                throw;
            }
        }
        public async Task <GetTransactionsDownloadResponse> Handle(GetTransactionsDownloadQuery message)
        {
            var endDate = message.EndDate.ToDate();
            var endDateBeginningOfNextMonth = new DateTime(endDate.Year, endDate.Month, 1).AddMonths(1);
            var transactions = await _transactionRepository.GetAllTransactionDetailsForAccountByDate(message.AccountId, message.StartDate, endDateBeginningOfNextMonth);

            if (!transactions.Any())
            {
                throw new ValidationException("There are no transactions in the date range");
            }

            var accountResponse = await _accountApiClient.GetAccount(message.AccountId);

            var apprenticeshipEmployerTypeEnum = (ApprenticeshipEmployerType)Enum.Parse(typeof(ApprenticeshipEmployerType), accountResponse.ApprenticeshipEmployerType, true);

            foreach (var transaction in transactions)
            {
                GenerateTransactionDescription(transaction);
            }

            var fileFormatter = _transactionsFormatterFactory.GetTransactionsFormatterByType(
                message.DownloadFormat.Value,
                apprenticeshipEmployerTypeEnum);

            return(new GetTransactionsDownloadResponse
            {
                FileData = fileFormatter.GetFileData(transactions),
                FileExtension = fileFormatter.FileExtension,
                MimeType = fileFormatter.MimeType
            });
        }
예제 #4
0
        public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken())
        {
            _logger.LogInformation("Pinging Accounts API");

            try
            {
                var timer = Stopwatch.StartNew();
                await _apiClient.GetAccount(1);

                timer.Stop();

                var durationString = timer.Elapsed.ToHumanReadableString();

                _logger.LogInformation($"Account API ping successful and took {durationString}");

                return(HealthCheckResult.Healthy(HealthCheckResultDescription,
                                                 new Dictionary <string, object> {
                    { "Duration", durationString }
                }));
            }
            catch (RestHttpClientException e)
            {
                _logger.LogWarning($"Account API ping failed : [Code: {e.StatusCode}] - {e.ReasonPhrase}");
                return(HealthCheckResult.Unhealthy(HealthCheckResultDescription, e));
            }
        }
예제 #5
0
        protected override async Task Handle(ProcessFullyApprovedCohortCommand request, CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Handling ProcessFullyApprovedCohortCommand for Cohort {request.CohortId}");

            var account = await _accountApiClient.GetAccount(request.AccountId);

            var apprenticeshipEmployerType = account.ApprenticeshipEmployerType.ToEnum <ApprenticeshipEmployerType>();

            _logger.LogInformation($"Account {request.AccountId} is of type {apprenticeshipEmployerType}");

            var creationDate = DateTime.UtcNow;

            await _db.Value.ProcessFullyApprovedCohort(request.CohortId, request.AccountId, apprenticeshipEmployerType);

            var events = await _db.Value.Apprenticeships
                         .Where(a => a.Cohort.Id == request.CohortId)
                         .Select(a => new ApprenticeshipCreatedEvent
            {
                ApprenticeshipId = a.Id,
                CreatedOn        = creationDate,
                AgreedOn         = a.Cohort.EmployerAndProviderApprovedOn.Value,
                AccountId        = a.Cohort.EmployerAccountId,
                AccountLegalEntityPublicHashedId = a.Cohort.AccountLegalEntity.PublicHashedId,
                AccountLegalEntityId             = a.Cohort.AccountLegalEntity.Id,
                LegalEntityName  = a.Cohort.AccountLegalEntity.Name,
                ProviderId       = a.Cohort.ProviderId,
                TransferSenderId = a.Cohort.TransferSenderId,
                ApprenticeshipEmployerTypeOnApproval = apprenticeshipEmployerType,
                Uln           = a.Uln,
                TrainingType  = a.ProgrammeType.Value,
                TrainingCode  = a.CourseCode,
                StartDate     = a.StartDate.Value,
                EndDate       = a.EndDate.Value,
                PriceEpisodes = a.PriceHistory
                                .Select(p => new PriceEpisode
                {
                    FromDate = p.FromDate,
                    ToDate   = p.ToDate,
                    Cost     = p.Cost
                })
                                .ToArray()
            })
                         .ToListAsync(cancellationToken);

            _logger.LogInformation($"Created {events.Count} ApprenticeshipCreatedEvent(s) for Cohort {request.CohortId}");

            var tasks = events.Select(e =>
            {
                _logger.LogInformation($"Emitting ApprenticeshipCreatedEvent for Apprenticeship {e.ApprenticeshipId}");
                return(_eventPublisher.Publish(e));
            });

            await Task.WhenAll(tasks);

            if (request.ChangeOfPartyRequestId.HasValue)
            {
                await Task.WhenAll(EmitChangeOfPartyEvents(request, events));
            }
        }
예제 #6
0
        private async Task <IEnumerable <string> > GetPayeSchemesForAccount(long employerAccountId)
        {
            _logger.Info($"Getting PAYE schemes for account {employerAccountId} to perform employment check");
            var account = await _accountApiClient.GetAccount(employerAccountId);

            var payeSchemes = account.PayeSchemes.Select(x => x.Id);

            return(payeSchemes);
        }
        public async Task <Account> GetAccount(long accountId)
        {
            var account = await _client.GetAccount(accountId);

            var response = new Account
            {
                Id = account.AccountId,
                ApprenticeshipEmployerType = account.ApprenticeshipEmployerType.ToEnum <ApprenticeshipEmployerType>()
            };

            return(response);
        }
        public async Task <IEnumerable <Email> > GetEmails()
        {
            var alertSummaries = await _apprenticeshipRepository.GetEmployerApprenticeshipAlertSummary();

            _logger.Info($"Found {alertSummaries.Count} employer summary records.");

            var distinctAccountIdsFromAlert =
                alertSummaries
                .Select(m => m.EmployerAccountId)
                .Distinct()
                .ToList();

            var distinctAccountsTasks =
                distinctAccountIdsFromAlert
                .Select(x => _retryPolicy.ExecuteAndCaptureAsync(() => _accountApi.GetAccount(x)))
                .ToList();

            var userPerAccountTasks =
                distinctAccountIdsFromAlert
                .Select(ToUserModel)
                .ToList();

            await Task.WhenAll(distinctAccountsTasks);

            await Task.WhenAll(userPerAccountTasks);

            var accounts = distinctAccountsTasks
                           .Select(x => x.Result)
                           .Where(x => x.Outcome == OutcomeType.Successful)
                           .Select(x => x.Result).ToList();

            // Only accountIds where user in DB
            var accountIds = accounts.Select(m => m.AccountId);

            var accountsWithUsers = userPerAccountTasks
                                    .Select(x => x.Result)
                                    .Where(u => u.Users != null)
                                    .Where(x => accountIds.Contains(x.AccountId));

            return(accountsWithUsers.SelectMany(m =>
            {
                var account = accounts.FirstOrDefault(a => a.AccountId == m.AccountId);
                var alert = alertSummaries.Single(sum => sum.EmployerAccountId == m.AccountId);

                return m.Users
                .Where(u => u.CanReceiveNotifications)
                .Where(u => u.Role == "Owner" || u.Role == "Transactor")
                .Select(userModel => MapToEmail(userModel, alert, account.HashedAccountId, account.DasAccountName));
            }
                                                ));
        }
예제 #9
0
        public async Task <IEnumerable <Email> > GetEmails()
        {
            var transferRequests = await _commitmentRepository.GetPendingTransferRequests();

            _logger.Info($"Found {transferRequests.Count} pending transfer requests");

            var distinctEmployerAccountIds = transferRequests.Select(x => x.SendingEmployerAccountId)
                                             .Distinct()
                                             .ToList();

            var distinctAccountsTasks =
                distinctEmployerAccountIds
                .Select(x => _retryPolicy.ExecuteAndCaptureAsync(() => _accountApi.GetAccount(x)))
                .ToList();

            var userPerAccountTasks =
                distinctEmployerAccountIds
                .Select(ToUserModel)
                .ToList();

            await Task.WhenAll(distinctAccountsTasks);

            await Task.WhenAll(userPerAccountTasks);

            var accounts = distinctAccountsTasks
                           .Select(x => x.Result)
                           .Where(x => x.Outcome == OutcomeType.Successful)
                           .Select(x => x.Result).ToList();

            // Only accountIds where user in DB
            var accountIds = accounts.Select(m => m.AccountId);

            var accountsWithUsers = userPerAccountTasks
                                    .Select(x => x.Result)
                                    .Where(u => u.Users != null && accountIds.Contains(u.AccountId))
                                    .ToList();

            return(transferRequests.SelectMany(transferRequest =>
            {
                var account = accounts.Single(a => a.AccountId == transferRequest.SendingEmployerAccountId);

                var users = accountsWithUsers.Where(a => a.AccountId == account.AccountId)
                            .SelectMany(a => a.Users)
                            .Where(u => u.CanReceiveNotifications &&
                                   (u.Role == "Owner" || u.Role == "Transactor"));

                return (users.Select(userModel =>
                                     MapToEmail(userModel, transferRequest, account.HashedAccountId, account.DasAccountName)));
            }));
        }
        public async Task <Models.Balance.BalanceModel> GetAccountBalance(long accountId)
        {
            var startTime = DateTime.UtcNow;
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var hashedAccountId = _hashingService.HashValue(accountId);
            var account         = await _accountApiClient.GetAccount(hashedAccountId);

            stopwatch.Stop();
            _telemetry.TrackDependency(DependencyType.ApiCall, "GetAccountBalance", startTime, stopwatch.Elapsed, true);
            return(new Models.Balance.BalanceModel
            {
                EmployerAccountId = accountId,
                RemainingTransferBalance = account.RemainingTransferAllowance,
                TransferAllowance = account.StartingTransferAllowance,
                Amount = account.Balance
            });
        }
        private async Task <IEnumerable <Core.Models.Account> > GetAccountSearchDetails(IEnumerable <AccountWithBalanceViewModel> accounts)
        {
            var accountsWithDetails = new List <Core.Models.Account>();

            foreach (var account in accounts)
            {
                try
                {
                    var accountViewModel = await _accountApiClient.GetAccount(account.AccountHashId);

                    var accountWithDetails = await GetAdditionalFields(accountViewModel, AccountFieldsSelection.PayeSchemes);

                    accountsWithDetails.Add(accountWithDetails);
                }
                catch (Exception e)
                {
                    _logger.Error(e, $"Exception while retrieving details for account ID {account.AccountHashId}");
                }
            }

            return(accountsWithDetails);
        }
        public async Task <bool> HasProviderGotEmployersPermissionAsync(long ukprn, string accountHashedId, string accountLegalEntityPublicHashedId, OperationType operation)
        {
            var accountDetails = await _accountApiClient.GetAccount(accountHashedId);

            var permittedLegalEntities = await GetProviderPermissionsforEmployer(ukprn, accountDetails.PublicHashedAccountId, operation);

            if (permittedLegalEntities.Any() == false)
            {
                return(false);
            }

            var accountId = await _employerAccountProvider.GetEmployerAccountPublicHashedIdAsync(permittedLegalEntities.First().AccountId);

            var allLegalEntities = (await _employerAccountProvider.GetLegalEntitiesConnectedToAccountAsync(accountId)).ToList();

            var hasPermission = permittedLegalEntities.Join(allLegalEntities,
                                                            ple => ple.AccountLegalEntityPublicHashedId,
                                                            ale => ale.AccountLegalEntityPublicHashedId,
                                                            (ple, ale) => ale)
                                .Any(l => l.AccountLegalEntityPublicHashedId == accountLegalEntityPublicHashedId);

            return(hasPermission);
        }
 public async Task <AccountDetailViewModel> GetAccount(string hashedAccountId)
 {
     return(await _inner.GetAccount(hashedAccountId));
 }
예제 #14
0
        public virtual async Task <OrchestratorResponse <AccountDashboardViewModel> > GetAccount(string hashedAccountId, string externalUserId)
        {
            try
            {
                var apiGetAccountTask = _accountApiClient.GetAccount(hashedAccountId);

                var accountResponseTask = _mediator.SendAsync(new GetEmployerAccountByHashedIdQuery
                {
                    HashedAccountId = hashedAccountId,
                    UserId          = externalUserId
                });

                var userRoleResponseTask = GetUserAccountRole(hashedAccountId, externalUserId);

                var userResponseTask = _mediator.SendAsync(new GetTeamMemberQuery
                {
                    HashedAccountId = hashedAccountId,
                    TeamMemberId    = externalUserId
                });

                var accountStatsResponseTask = _mediator.SendAsync(new GetAccountStatsQuery
                {
                    HashedAccountId = hashedAccountId,
                    ExternalUserId  = externalUserId
                });

                var agreementsResponseTask = _mediator.SendAsync(new GetAccountEmployerAgreementsRequest
                {
                    HashedAccountId = hashedAccountId,
                    ExternalUserId  = externalUserId
                });

                await Task.WhenAll(apiGetAccountTask, accountStatsResponseTask, userRoleResponseTask, userResponseTask, accountStatsResponseTask, agreementsResponseTask).ConfigureAwait(false);

                var accountResponse        = accountResponseTask.Result;
                var userRoleResponse       = userRoleResponseTask.Result;
                var userResponse           = userResponseTask.Result;
                var accountStatsResponse   = accountStatsResponseTask.Result;
                var agreementsResponse     = agreementsResponseTask.Result;
                var accountDetailViewModel = apiGetAccountTask.Result;

                var apprenticeshipEmployerType = (ApprenticeshipEmployerType)Enum.Parse(typeof(ApprenticeshipEmployerType), accountDetailViewModel.ApprenticeshipEmployerType, true);

                var tasksResponse = await _mediator.SendAsync(new GetAccountTasksQuery
                {
                    AccountId                  = accountResponse.Account.Id,
                    ExternalUserId             = externalUserId,
                    ApprenticeshipEmployerType = apprenticeshipEmployerType
                });

                var pendingAgreements = agreementsResponse.EmployerAgreements.Where(a => a.HasPendingAgreement && !a.HasSignedAgreement).Select(a => new PendingAgreementsViewModel {
                    HashedAgreementId = a.Pending.HashedAgreementId
                }).ToList();
                var tasks      = tasksResponse?.Tasks.Where(t => t.ItemsDueCount > 0 && t.Type != "AgreementToSign").ToList() ?? new List <AccountTask>();
                var showWizard = userResponse.User.ShowWizard && userRoleResponse.UserRole == Role.Owner;

                var viewModel = new AccountDashboardViewModel
                {
                    Account                = accountResponse.Account,
                    UserRole               = userRoleResponse.UserRole,
                    HashedUserId           = externalUserId,
                    UserFirstName          = userResponse.User.FirstName,
                    OrganisationCount      = accountStatsResponse?.Stats?.OrganisationCount ?? 0,
                    PayeSchemeCount        = accountStatsResponse?.Stats?.PayeSchemeCount ?? 0,
                    TeamMemberCount        = accountStatsResponse?.Stats?.TeamMemberCount ?? 0,
                    TeamMembersInvited     = accountStatsResponse?.Stats?.TeamMembersInvited ?? 0,
                    ShowWizard             = showWizard,
                    ShowAcademicYearBanner = _currentDateTime.Now < new DateTime(2017, 10, 20),
                    Tasks                      = tasks,
                    HashedAccountId            = hashedAccountId,
                    RequiresAgreementSigning   = pendingAgreements.Count(),
                    SignedAgreementCount       = agreementsResponse.EmployerAgreements.Count(x => x.HasSignedAgreement),
                    PendingAgreements          = pendingAgreements,
                    ApprenticeshipEmployerType = apprenticeshipEmployerType,
                    AgreementInfo              = _mapper.Map <AccountDetailViewModel, AgreementInfoViewModel>(accountDetailViewModel)
                };

                //note: ApprenticeshipEmployerType is already returned by GetEmployerAccountHashedQuery, but we need to transition to calling the api instead.
                // we could blat over the existing flag, but it's much nicer to store the enum (as above) rather than a byte!
                //viewModel.Account.ApprenticeshipEmployerType = (byte) ((ApprenticeshipEmployerType) Enum.Parse(typeof(ApprenticeshipEmployerType), apiGetAccountTask.Result.ApprenticeshipEmployerType, true));

                return(new OrchestratorResponse <AccountDashboardViewModel>
                {
                    Status = HttpStatusCode.OK,
                    Data = viewModel
                });
            }
            catch (UnauthorizedAccessException ex)
            {
                return(new OrchestratorResponse <AccountDashboardViewModel>
                {
                    Status = HttpStatusCode.Unauthorized,
                    Exception = ex
                });
            }
            catch (System.Net.Http.HttpRequestException ex)
            {
                return(new OrchestratorResponse <AccountDashboardViewModel>
                {
                    Status = HttpStatusCode.InternalServerError,
                    Exception = new ResourceNotFoundException($"An error occured whilst trying to retrieve account: {hashedAccountId}", ex)
                });
            }
            catch (Exception ex)
            {
                return(new OrchestratorResponse <AccountDashboardViewModel>
                {
                    Status = HttpStatusCode.InternalServerError,
                    Exception = ex
                });
            }
        }