public When_ReferralEmailService_Is_Called_To_Send_Employer_Email_With_No_Opportunity_Item_Ids()
        {
            var datetimeProvider = Substitute.For <IDateTimeProvider>();

            _backgroundProcessHistoryRepository = Substitute.For <IRepository <BackgroundProcessHistory> >();

            var mapper = Substitute.For <IMapper>();
            var opportunityItemRepository = Substitute.For <IRepository <OpportunityItem> >();

            _emailService          = Substitute.For <IEmailService>();
            _opportunityRepository = Substitute.For <IOpportunityRepository>();

            _backgroundProcessHistoryRepository.GetSingleOrDefaultAsync(
                Arg.Any <Expression <Func <BackgroundProcessHistory, bool> > >()).Returns(new BackgroundProcessHistory
            {
                Id          = 1,
                ProcessType = BackgroundProcessType.EmployerReferralEmail.ToString(),
                Status      = BackgroundProcessHistoryStatus.Pending.ToString()
            });

            _opportunityRepository
            .GetEmployerReferralsAsync(
                Arg.Any <int>(), Arg.Any <IEnumerable <int> >())
            .Returns(new ValidEmployerReferralDtoBuilder()
                     .AddSecondaryContact()
                     .Build());

            var functionLogRepository = Substitute.For <IRepository <FunctionLog> >();

            var referralEmailService = new ReferralEmailService(mapper, datetimeProvider, _emailService,
                                                                _opportunityRepository, opportunityItemRepository, _backgroundProcessHistoryRepository, functionLogRepository);

            referralEmailService.SendEmployerReferralEmailAsync(1, new List <int>(), 1, "system").GetAwaiter().GetResult();
        }
        public async Task SendEmployerReferralEmailAsync(int opportunityId, IEnumerable <int> itemIds, int backgroundProcessHistoryId, string username)
        {
            if (await GetBackgroundProcessHistoryDataAsync(backgroundProcessHistoryId) == null)
            {
                await _functionLogRepository.CreateAsync(new FunctionLog
                {
                    ErrorMessage = $"Background Processing History not found or not pending for id {backgroundProcessHistoryId} for employer referral emails",
                    FunctionName = nameof(ReferralEmailService),
                    RowNumber    = -1
                });

                return;
            }

            try
            {
                var itemIdList       = itemIds.ToList();
                var employerReferral = await _opportunityRepository.GetEmployerReferralsAsync(opportunityId, itemIdList);

                if (employerReferral == null || !itemIdList.Any())
                {
                    await _functionLogRepository.CreateAsync(new FunctionLog
                    {
                        ErrorMessage = $"No referral found or no opportunity item ids when retrieving employer referral for opportunity id {opportunityId} with {itemIdList.Count} items",
                        FunctionName = nameof(ReferralEmailService),
                        RowNumber    = -1
                    });
                }
                else
                {
                    var sb     = new StringBuilder();
                    var tokens = new Dictionary <string, string>
                    {
                        { "employer_contact_name", employerReferral.PrimaryContact.ToTitleCase() },
                        { "employer_business_name", employerReferral.CompanyName.ToTitleCase() },
                        { "employer_contact_number", employerReferral.Phone },
                        { "employer_contact_email", employerReferral.Email }
                    };

                    foreach (var data in employerReferral.WorkplaceDetails.OrderBy(dto => dto.WorkplaceTown))
                    {
                        var placements = GetNumberOfPlacements(data.PlacementsKnown, data.Placements);

                        sb.AppendLine($"# {data.WorkplaceTown} {data.WorkplacePostcode}");
                        sb.AppendLine($"* Job role: {data.JobRole}");
                        sb.AppendLine($"* Students wanted: {placements}");

                        var count = 1;
                        foreach (var providerAndVenue in data.ProviderAndVenueDetails)
                        {
                            sb.AppendLine(
                                $"* {count.ToOrdinalWords().ToTitleCase()} provider selected: {providerAndVenue.CustomisedProviderDisplayName}");
                            sb.Append("Primary contact: ");
                            sb.AppendLine(FormatContactDetails(providerAndVenue.PrimaryContact,
                                                               providerAndVenue.PrimaryContactPhone, providerAndVenue.PrimaryContactEmail));

                            if (!string.IsNullOrWhiteSpace(providerAndVenue.SecondaryContact))
                            {
                                sb.AppendLine(
                                    $"Secondary contact: {FormatContactDetails(providerAndVenue.SecondaryContact, providerAndVenue.SecondaryContactPhone, providerAndVenue.SecondaryContactEmail)}");
                            }

                            count++;
                        }

                        sb.AppendLine("");
                    }

                    tokens.Add("placements_list", sb.ToString());

                    await SendEmailAsync(EmailTemplateName.EmployerReferralV5, opportunityId, employerReferral.Email,
                                         tokens, employerReferral.CreatedBy);
                }

                await UpdateBackgroundProcessHistoryAsync(backgroundProcessHistoryId,
                                                          employerReferral != null && itemIdList.Any()? 1 : 0,
                                                          BackgroundProcessHistoryStatus.Complete, username);
            }
            catch (Exception ex)
            {
                var errorMessage = $"Error sending employer referral emails. {ex.Message} " +
                                   $"Opportunity id {opportunityId}";

                await UpdateBackgroundProcessHistoryAsync(backgroundProcessHistoryId,
                                                          1,
                                                          BackgroundProcessHistoryStatus.Error, username, errorMessage);
            }
        }