| "</a>" + | "</a>" + | ||||
| "</div>"; | "</div>"; | ||||
| } | } | ||||
| public static string SuccessfulStep(string message, string pattern, string date) | |||||
| { | |||||
| return "<div style=\"font-family: sans-serif\">" + | |||||
| "<div style=\"font-family: sans-serif; text-align: center; \">" + | |||||
| "<h2 style=\"color: #017397;\">" + pattern + "</h2>" + | |||||
| "</div>" + | |||||
| "<div style=\"padding: 0.25rem 2rem 0 2rem\">" + | |||||
| "<p style=\"color: #017397;\">Poštovani,</p >" + | |||||
| "</div>" + | |||||
| "<div style=\"padding: 0 13rem 0 4rem; \">" + | |||||
| "<p style=\"color: #017397;\">" + message + " " + date + "</p>" + | |||||
| "</div>" + "<div style=\"padding: 0 2rem; \">" + | |||||
| "<p style=\"color: #017397;\">Srdačan pozdrav,<br>Diligent HR Team</p>" + | |||||
| "</div>" + | |||||
| "</div>"; | |||||
| } | |||||
| //public static string ScheduleInterview(string pattern, string message) | |||||
| //{ | |||||
| // Dictionary<string, string> Patterns = new Dictionary<string, string> | |||||
| // { | |||||
| // { "Neuspesan korak", $"<div><p>Neuspesan korak: {message}</p></div>" }, | |||||
| // { "Uspesan korak", SuccessfulStep(message, pattern) } | |||||
| // }; | |||||
| // return Patterns[pattern]; | |||||
| //} | |||||
| } | } | ||||
| } | } |
| CreateMap<Applicant, ApplicantViewDto>(); | CreateMap<Applicant, ApplicantViewDto>(); | ||||
| CreateMap<Applicant, AdApplicantViewDto>(); | CreateMap<Applicant, AdApplicantViewDto>(); | ||||
| CreateMap<Applicant, ApplicantScheduleViewDto>(); | CreateMap<Applicant, ApplicantScheduleViewDto>(); | ||||
| CreateMap<Applicant, PatternApplicantViewDto>(); | |||||
| #endregion | #endregion | ||||
| #region DTOs to Models | #region DTOs to Models |
| { | { | ||||
| #region DTO to Model | #region DTO to Model | ||||
| CreateMap<SelectionProcessCreateDto, SelectionProcess>(); | CreateMap<SelectionProcessCreateDto, SelectionProcess>(); | ||||
| CreateMap<SelectionProcessUpdateStatusDto, SelectionProcess>(); | |||||
| #endregion | #endregion | ||||
| #region Model to DTO | #region Model to DTO |
| Task<List<PatternResponseDto>> GetFilteredPatternsAsync(FilterPatternDto filterPatternDto); | Task<List<PatternResponseDto>> GetFilteredPatternsAsync(FilterPatternDto filterPatternDto); | ||||
| Task<List<PatternApplicantViewDto>> GetCorrespondingPatternApplicants(int id); | |||||
| Task CreateAsync(PatternCreateDto patternCreateDto); | Task CreateAsync(PatternCreateDto patternCreateDto); | ||||
| Task<ScheduleInterviewResponseDto?> ScheduleIntrviewAsync(ScheduleInterviewDto scheduleInterviewDto); | |||||
| Task UpdateAsync(PatternUpdateDto patternUpdateDto, int id); | Task UpdateAsync(PatternUpdateDto patternUpdateDto, int id); | ||||
| Task DeleteAsync(int id); | Task DeleteAsync(int id); |
| Task<List<SelectionProcessResposneDto>> GetAllAsync(); | Task<List<SelectionProcessResposneDto>> GetAllAsync(); | ||||
| Task<bool> FinishSelectionProcess(SelectionProcessCreateDto model); | Task<bool> FinishSelectionProcess(SelectionProcessCreateDto model); | ||||
| Task<List<SelectionLevelInfoDto>> GetCountByLevels(List<string> statuses); | Task<List<SelectionLevelInfoDto>> GetCountByLevels(List<string> statuses); | ||||
| Task UpdateSelectionProcessStatusAsync(int id, SelectionProcessUpdateStatusDto selectionProcessUpdateStatusDto); | |||||
| } | } | ||||
| } | } |
| private readonly IMapper _mapper; | private readonly IMapper _mapper; | ||||
| private readonly ISelectionLevelService _selectionLevelService; | private readonly ISelectionLevelService _selectionLevelService; | ||||
| private readonly ILogger<PatternService> _logger; | private readonly ILogger<PatternService> _logger; | ||||
| private readonly IEmailer _emailer; | |||||
| private readonly ISelectionProcessService _selectionProcessService; | |||||
| public PatternService(DatabaseContext context, IMapper mapper, ISelectionLevelService selectionLevelService, ILogger<PatternService> logger) | |||||
| public PatternService(DatabaseContext context, IMapper mapper, ISelectionLevelService selectionLevelService, ILogger<PatternService> logger, IEmailer emailer, ISelectionProcessService selectionProcessService) | |||||
| { | { | ||||
| _context = context; | _context = context; | ||||
| _mapper = mapper; | _mapper = mapper; | ||||
| _selectionLevelService = selectionLevelService; | _selectionLevelService = selectionLevelService; | ||||
| _logger = logger; | _logger = logger; | ||||
| _emailer = emailer; | |||||
| _selectionProcessService = selectionProcessService; | |||||
| } | } | ||||
| public async Task<List<PatternResponseDto>> GetAllAsync() | public async Task<List<PatternResponseDto>> GetAllAsync() | ||||
| return result; | return result; | ||||
| } | } | ||||
| public async Task<List<PatternApplicantViewDto>> 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<List<PatternApplicantViewDto>>(selectionProcessesApplicants); | |||||
| _logger.LogInformation($"Pattern applicants mapped successfully"); | |||||
| return applicants; | |||||
| } | |||||
| public async Task CreateAsync(PatternCreateDto patternCreateDto) | public async Task CreateAsync(PatternCreateDto patternCreateDto) | ||||
| { | { | ||||
| _logger.LogInformation($"Start creating Pattern"); | _logger.LogInformation($"Start creating Pattern"); | ||||
| await result; | await result; | ||||
| } | } | ||||
| public async Task<ScheduleInterviewResponseDto?> ScheduleIntrviewAsync(ScheduleInterviewDto scheduleInterviewDto) | |||||
| { | |||||
| _logger.LogInformation($"Start scheduling interview"); | |||||
| List<string> 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<string> { 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) | public async Task UpdateAsync(PatternUpdateDto patternUpdateDto, int id) | ||||
| { | { | ||||
| _logger.LogInformation($"Start updating Pattern"); | _logger.LogInformation($"Start updating Pattern"); |
| return resMapped; | return resMapped; | ||||
| } | } | ||||
| public async Task UpdateSelectionProcessStatusAsync(int id, SelectionProcessUpdateStatusDto selectionProcessUpdateStatusDto) | |||||
| { | |||||
| _logger.LogInformation($"Start searching Ad with id = {id}"); | |||||
| var selectionProcess = await _context.SelectionProcesses.FindAsync(id); | |||||
| if (selectionProcess is null) | |||||
| { | |||||
| _logger.LogError($"Selection process with id = {id} not found"); | |||||
| throw new EntityNotFoundException("Selection process not found"); | |||||
| } | |||||
| _logger.LogInformation($"Mapping Selection process with id = {id}"); | |||||
| _mapper.Map(selectionProcessUpdateStatusDto, selectionProcess); | |||||
| _logger.LogInformation($"Selection process with id = {id} mapped successfully"); | |||||
| _context.Entry(selectionProcess).State = EntityState.Modified; | |||||
| var result = _context.SaveChangesAsync(); | |||||
| _logger.LogInformation($"Selection process saved to DB"); | |||||
| await result; | |||||
| } | |||||
| } | } | ||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.DTOs.Applicant | |||||
| { | |||||
| public class PatternApplicantViewDto | |||||
| { | |||||
| public int ApplicantId { get; set; } | |||||
| public string FirstName { get; set; } | |||||
| public string LastName { get; set; } | |||||
| public string Email { get; set; } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.DTOs.Pattern | |||||
| { | |||||
| public class ScheduleInterviewDto | |||||
| { | |||||
| public List<string> Emails { get; set; } | |||||
| public int PatternId { get; set; } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.DTOs.Pattern | |||||
| { | |||||
| public class ScheduleInterviewResponseDto | |||||
| { | |||||
| public List<string> NotSentEmails { get; set; } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.DTOs.SelectionProcess | |||||
| { | |||||
| public class SelectionProcessUpdateStatusDto | |||||
| { | |||||
| public string Status { get; set; } | |||||
| } | |||||
| } |
| public async Task<IActionResult> GetFilteredPatterns([FromQuery] FilterPatternDto request) => | public async Task<IActionResult> GetFilteredPatterns([FromQuery] FilterPatternDto request) => | ||||
| Ok(await _patternService.GetFilteredPatternsAsync(request)); | Ok(await _patternService.GetFilteredPatternsAsync(request)); | ||||
| [HttpGet("corresponding-pattern-applicants/{id}")] | |||||
| public async Task<IActionResult> GetFilteredPatterns([FromRoute] int id) => | |||||
| Ok(await _patternService.GetCorrespondingPatternApplicants(id)); | |||||
| [HttpPost] | [HttpPost] | ||||
| public async Task<IActionResult> Create([FromBody] PatternCreateDto request) | public async Task<IActionResult> Create([FromBody] PatternCreateDto request) | ||||
| { | { | ||||
| return StatusCode((int)HttpStatusCode.Created); | return StatusCode((int)HttpStatusCode.Created); | ||||
| } | } | ||||
| [HttpPost("schedule-interview")] | |||||
| public async Task<IActionResult> ScheduleInterview([FromBody] ScheduleInterviewDto request) | |||||
| { | |||||
| var result = await _patternService.ScheduleIntrviewAsync(request); | |||||
| return Ok(result); | |||||
| } | |||||
| [HttpPut("{id}")] | [HttpPut("{id}")] | ||||
| public async Task<IActionResult> Update([FromBody]PatternUpdateDto request, [FromRoute]int id) | public async Task<IActionResult> Update([FromBody]PatternUpdateDto request, [FromRoute]int id) | ||||
| { | { |