public async Task SendEmailNotification(Jobs.Model.Job job)
        {
            try
            {
                var template = await _emailTemplateManager.GetTemplate(job.JobId, job.Status, job.JobType, job.DateTimeSubmittedUtc);

                if (!string.IsNullOrEmpty(template))
                {
                    var personalisation = new Dictionary <string, dynamic>();

                    var submittedAt = _dateTimeProvider.ConvertUtcToUk(job.DateTimeSubmittedUtc);
                    personalisation.Add("JobId", job.JobId);
                    personalisation.Add("Name", job.SubmittedBy);
                    personalisation.Add("DateTimeSubmitted", string.Concat(submittedAt.ToString("hh:mm tt"), " on ", submittedAt.ToString("dddd dd MMMM yyyy")));

                    await _emailNotifier.SendEmail(job.NotifyEmail, template, personalisation);

                    _logger.LogInfo($"Sent email for jobId : {job.JobId}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Sending email failed for job {job.JobId}", ex, jobIdOverride: job.JobId);
            }
        }
        public async Task <bool> UpdateJob(Jobs.Model.Job job)
        {
            if (job == null)
            {
                throw new ArgumentNullException();
            }

            using (IJobQueueDataContext context = _contextFactory())
            {
                Job entity = await context.Job.SingleOrDefaultAsync(x => x.JobId == job.JobId);

                if (entity == null)
                {
                    throw new ArgumentException($"Job id {job.JobId} does not exist");
                }

                bool statusChanged = entity.Status != (short)job.Status;

                JobConverter.Convert(job, entity);
                entity.DateTimeUpdatedUtc = _dateTimeProvider.GetNowUtc();
                context.Entry(entity).Property("RowVersion").OriginalValue = job.RowVersion == null ? null : Convert.FromBase64String(job.RowVersion);
                context.Entry(entity).State = EntityState.Modified;

                if (job.Status == JobStatusType.Ready)
                {
                    context.JobSubmission.Add(new JobSubmission()
                    {
                        DateTimeUtc = _dateTimeProvider.GetNowUtc(),
                        JobId       = job.JobId
                    });
                }

                try
                {
                    await context.SaveChangesAsync();

                    if (statusChanged)
                    {
                        await SendEmailNotification(job);
                    }

                    return(true);
                }
                catch (DbUpdateConcurrencyException exception)
                {
                    throw new Exception(
                              "Save failed. Job details have been changed. Reload the job object and try save again");
                }
            }
        }
        public async Task <Jobs.Model.Job> GetJobById(long jobId)
        {
            if (jobId == 0)
            {
                throw new ArgumentException("Job id can not be 0");
            }

            using (IJobQueueDataContext context = _contextFactory())
            {
                var entity = await context.Job.SingleOrDefaultAsync(x => x.JobId == jobId);

                if (entity == null)
                {
                    throw new ArgumentException($"Job id {jobId} does not exist");
                }

                var job = new Jobs.Model.Job();
                JobConverter.Convert(entity, job);
                return(job);
            }
        }
        public async Task <long> AddJob(Jobs.Model.Job job)
        {
            if (job == null)
            {
                throw new ArgumentNullException();
            }

            using (IJobQueueDataContext context = _contextFactory())
            {
                var entity = new Job
                {
                    DateTimeSubmittedUtc = _dateTimeProvider.GetNowUtc(),
                    JobType            = (short)job.JobType,
                    Priority           = job.Priority,
                    Status             = (short)job.Status,
                    SubmittedBy        = job.SubmittedBy,
                    NotifyEmail        = job.NotifyEmail,
                    CrossLoadingStatus = (await IsCrossLoadingEnabled(job.JobType)) ? (short)JobStatusType.Ready : (short?)null
                };
                context.Job.Add(entity);
                context.SaveChanges();
                return(entity.JobId);
            }
        }