using Diligent.WebAPI.Contracts.DTOs.Pattern; namespace Diligent.WebAPI.Business.Services { public class PatternService : IPatternService { private readonly DatabaseContext _context; private readonly IMapper _mapper; private readonly ISelectionLevelService _selectionLevelService; private readonly ILogger _logger; private readonly IEmailer _emailer; private readonly ISelectionProcessService _selectionProcessService; public PatternService(DatabaseContext context, IMapper mapper, ISelectionLevelService selectionLevelService, ILogger logger, IEmailer emailer, ISelectionProcessService selectionProcessService) { _context = context; _mapper = mapper; _selectionLevelService = selectionLevelService; _logger = logger; _emailer = emailer; _selectionProcessService = selectionProcessService; } public async Task> GetAllAsync() { _logger.LogInformation("Start getting all Patterns"); _logger.LogInformation("Getting data from DB"); var fromDb = await _context.Patterns.Include(x => x.SelectionLevel).ToListAsync(); _logger.LogInformation($"Received {fromDb.Count} patterns from db."); _logger.LogInformation($"Mapping received patterns to PatternResponseDto"); var result = _mapper.Map>(fromDb); _logger.LogInformation($"Patterns has been mapped and received to client: {result.Count} mapped patterns"); return result; } public async Task GetByIdAsync(int id) { _logger.LogInformation($"Start searching Pattern with id = {id}"); var pattern = await _context.Patterns.Include(x => x.SelectionLevel).Where(x => x.Id == id).FirstOrDefaultAsync(); if (pattern is null) { _logger.LogError($"Pattern with id = {id} not found"); throw new EntityNotFoundException("Pattern not found"); } _logger.LogInformation($"Mapping Pattern with id = {id}"); PatternResponseDto result = _mapper.Map(pattern); _logger.LogInformation($"Pattern with id = {id} mapped successfully"); return result; } public async Task> GetFilteredPatternsAsync(FilterPatternDto filterPatternDto) { _logger.LogInformation($"Start getting all filtered Patterns"); _logger.LogInformation("Getting data from DB"); var filteredPatterns = await _context.Patterns.Include(x => x.SelectionLevel).ToListAsync(); _logger.LogInformation($"Received {filteredPatterns.Count} patterns from db."); _logger.LogInformation($"Mapping received patterns to PatternResponseDto"); List result = _mapper.Map>(filteredPatterns.FilterApplicants(filterPatternDto)); _logger.LogInformation($"Patterns has been mapped and received to client: {result.Count} mapped patterns"); return result; } public async Task> GetCorrespondingPatternApplicants(int id) { _logger.LogInformation($"Start getting corresponding pattern applicants"); _logger.LogInformation($"Getting pattern from database by id"); var pattern = await _context.Patterns.Include(x => x.SelectionLevel).ThenInclude(y => y.SelectionProcesses).ThenInclude(z => z.Applicant).Where(x => x.Id == id).FirstOrDefaultAsync(); if(pattern == null) { _logger.LogError($"Pattern with id = {id} not found"); throw new EntityNotFoundException("Pattern not found"); } _logger.LogInformation($"Select applicants from selection processes with status \"Čeka na zakazivanje\""); var selectionProcessesApplicants = pattern.SelectionLevel.SelectionProcesses.Where(x => x.Status == "Čeka na zakazivanje").Select(x => x.Applicant).ToList(); _logger.LogInformation($"Mapping Pattern applicants"); var applicants = _mapper.Map>(selectionProcessesApplicants); _logger.LogInformation($"Pattern applicants mapped successfully"); return applicants; } public async Task CreateAsync(PatternCreateDto patternCreateDto) { _logger.LogInformation($"Start creating Pattern"); _logger.LogInformation($"Check is Pattern in database"); var patternExists = await _context.Patterns.Include(x => x.SelectionLevel).Where(x => x.Title == patternCreateDto.Title && x.SelectionLevelId == patternCreateDto.SelectionLevelId).FirstOrDefaultAsync(); if (patternExists is not null) { _logger.LogError($"Pattern already exists in database"); throw new EntityNotFoundException("Pattern already exists in database"); } _logger.LogInformation($"Pattern is not in database"); _logger.LogInformation($"Mapping PatternCreateDto to model"); var pattern = _mapper.Map(patternCreateDto); _logger.LogInformation($"Pattern mapped successfully"); _logger.LogInformation($"Start searching SelectionLevel with id = {patternCreateDto.SelectionLevelId}"); var selectionLevel = await _selectionLevelService.GetByIdEntity(patternCreateDto.SelectionLevelId); if(selectionLevel == null) { _logger.LogError($"SelectionLevel with id = {patternCreateDto.SelectionLevelId} not found"); throw new EntityNotFoundException("Selection level not found"); } _logger.LogInformation($"Add founded SelectionLevel to pattern"); pattern.SelectionLevel = selectionLevel; await _context.AddAsync(pattern); _logger.LogInformation($"Saving Ad to db..."); var result = _context.SaveChangesAsync(); _logger.LogInformation($"Saved Ad to db..."); await result; } public async Task ScheduleIntrviewAsync(ScheduleInterviewDto scheduleInterviewDto) { _logger.LogInformation($"Start scheduling interview"); List NotSentEmails = new(); _logger.LogInformation("Getting pattern from DB by id"); var pattern = await _context.Patterns.Include(x => x.SelectionLevel).ThenInclude(y => y.SelectionProcesses).ThenInclude(z => z.Applicant).Where(x => x.Id == scheduleInterviewDto.PatternId).FirstOrDefaultAsync(); if (pattern == null) { _logger.LogError($"Pattern with id = {scheduleInterviewDto.PatternId} not found"); throw new EntityNotFoundException("Pattern not found"); } _logger.LogInformation("Pattern found in DB"); for (int i = 0; i < scheduleInterviewDto.Emails.Count; i++) { var to = new List { scheduleInterviewDto.Emails[i] }; _logger.LogInformation("Select process where status is \"Čeka na zakazivanje\""); var selectionProcesses = pattern.SelectionLevel.SelectionProcesses.Where(x => x.Status == "Čeka na zakazivanje" && x.Applicant.Email == scheduleInterviewDto.Emails[i]).FirstOrDefault(); if(selectionProcesses != null) { _logger.LogInformation("Selection process is not null"); _logger.LogInformation("Selection process status changing to \"Zakazan\""); await _selectionProcessService.UpdateSelectionProcessStatusAsync(selectionProcesses.Id, new SelectionProcessUpdateStatusDto { Status = "Zakazan" }); _logger.LogInformation("Sending pattern to selected emails on frontend"); await _emailer.SendEmailAsync(to, "Schedule interview", HTMLHelper.SuccessfulStep(pattern.Message, pattern.Title, String.Format("{0:M/d/yyyy}", selectionProcesses.Date)), isHtml: true); } else { _logger.LogInformation("Selection process not found in database"); NotSentEmails.Add(scheduleInterviewDto.Emails[i] + " ne postoji u bazi sa statusom \"Čeka na zakazivanje\" "); continue; } } if(NotSentEmails.Count() > 0) { _logger.LogInformation("List of not set emails are not empty"); _logger.LogInformation("Returning list of not sent emails"); return new ScheduleInterviewResponseDto { NotSentEmails = NotSentEmails }; } _logger.LogInformation("List of not sent email is empty. Return null..."); return null; } public async Task UpdateAsync(PatternUpdateDto patternUpdateDto, int id) { _logger.LogInformation($"Start updating Pattern"); _logger.LogInformation($"Check is Pattern in database"); var patternExists = await _context.Patterns.Include(x => x.SelectionLevel).Where(x => x.Title == patternUpdateDto.Title && x.SelectionLevelId == patternUpdateDto.SelectionLevelId).FirstOrDefaultAsync(); if (patternExists is not null) { _logger.LogError($"Pattern already exists in database"); throw new EntityNotFoundException("Pattern already exists in database"); } _logger.LogInformation($"Start searching Pattern with id = {id}"); var pattern = await _context.Patterns.Where(x => x.Id == id).FirstOrDefaultAsync(); if (pattern is null) { _logger.LogError($"Pattern with id = {id} not found"); throw new EntityNotFoundException("Pattern not found"); } _logger.LogInformation($"Mapping Pattern with id = {id}"); _mapper.Map(patternUpdateDto, pattern); _logger.LogInformation($"Pattern with id = {id} mapped successfully"); _logger.LogInformation($"Start searching SelectionLevel with id = {patternUpdateDto.SelectionLevelId}"); var selectionLevel = await _selectionLevelService.GetByIdEntity(patternUpdateDto.SelectionLevelId); if (selectionLevel == null) { _logger.LogError($"SelectionLevel with id = {patternUpdateDto.SelectionLevelId} not found"); throw new EntityNotFoundException("Selection level not found"); } _logger.LogInformation($"Add founded SelectionLevel to pattern"); pattern.SelectionLevel = selectionLevel; _context.Entry(pattern).State = EntityState.Modified; var result = _context.SaveChangesAsync(); _logger.LogInformation($"Pattern saved to DB"); await result; } public async Task DeleteAsync(int id) { _logger.LogInformation($"Start searching Pattern with id = {id}"); var pattern = await _context.Patterns.FindAsync(id); if (pattern is null) { _logger.LogError($"Pattern with id = {id} not found"); throw new EntityNotFoundException("Pattern not found"); } _context.Patterns.Remove(pattern); var result = _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); await result; } } }