using static Diligent.WebAPI.Data.Entities.Applicant; namespace Diligent.WebAPI.Business.Services { public class ApplicantService : IApplicantService { private readonly DatabaseContext _context; private readonly IMapper _mapper; private readonly ILogger _logger; private readonly IUserService _userService; private readonly IFileService _fileService; private readonly IAdService _adService; public ApplicantService(DatabaseContext context, IMapper mapper, ILogger logger, IUserService userService,IFileService fileService,IAdService adService) { _context = context; _mapper = mapper; _logger = logger; _userService = userService; _fileService = fileService; _adService = adService; } public async Task> GetFilteredApplicants(ApplicantFilterDto applicantFilterDto) { _logger.LogInformation("Start getting filtered applicants"); _logger.LogInformation("Getting data from DB and filter"); var filteredApplicants = (await _context.Applicants .Include(c => c.Ads) .Include(x => x.TechnologyApplicants) .ThenInclude(x => x.Technology).ToListAsync()) .FilterApplicants(applicantFilterDto); int totalNumberOfItems = filteredApplicants.Count; _logger.LogInformation($"Got {totalNumberOfItems} applicants"); filteredApplicants = PaginationExtension.ApplyPagging(filteredApplicants, new Pagination { CurrentPage = applicantFilterDto.CurrentPage, PageSize = applicantFilterDto.PageSize }); _logger.LogInformation($"Return list of applicants"); return new QueryResultDto { Items = _mapper.Map>(filteredApplicants), Total = totalNumberOfItems }; } public async Task GetById(int id) { _logger.LogInformation($"Start searching Applicant with id = {id}"); var applicant = await _context.Applicants .Include(x => x.Ads) .ThenInclude(x => x.Technologies) .Include(x => x.TechnologyApplicants) .ThenInclude(x => x.Technology) .Include(x => x.Comments) .ThenInclude(t => t.User) .FirstOrDefaultAsync(x => x.ApplicantId == id); if (applicant is null) { _logger.LogError($"Applicant with id = {id} not found"); throw new EntityNotFoundException("Applicant not found"); } _logger.LogInformation($"Mapping Applicant with id = {id}"); var result = _mapper.Map(applicant); result.CV = await _fileService.GetCV("638077305621281656.pdf"); _logger.LogInformation($"Applicant with id = {id} mapped successfully"); return result; } public async Task GetApplicantWithSelectionProcessesById(int id) { _logger.LogInformation($"Start searching Applicant with id = {id}"); var applicant = await _context.Applicants .Include(a => a.SelectionProcesses).ThenInclude(sp => sp.SelectionLevel) .Include(a => a.SelectionProcesses).ThenInclude(sp => sp.Scheduler) .FirstOrDefaultAsync(a => a.ApplicantId == id); if (applicant is null) { _logger.LogError($"Applicant with id = {id} not found"); throw new EntityNotFoundException("Applicant not found"); } _logger.LogInformation($"Applicant with id = {id} mapped successfully"); return _mapper.Map(applicant); } public async Task DeleteApplicant(int id) { _logger.LogInformation($"Start searching Applicant with id = {id}"); var applicant = await _context.Applicants.FindAsync(id); if (applicant is null) { _logger.LogError($"Applicant with id = {id} not found"); throw new EntityNotFoundException("Applicant not found"); } _logger.LogInformation($"Removing Applicant with id = {id}"); _context.Applicants.Remove(applicant); var result = _context.SaveChangesAsync(); _logger.LogInformation($"Applicant with id = {id} is removed successfully"); await result; } public async Task> GetAllAdsApplicants(ApplicantFilterDto applicantFilterDto) { _logger.LogInformation("Start getting filtered applicants"); _logger.LogInformation("Getting data from DB and filter"); var adsApplicants = (await _context.Ads .Include(a => a.Applicants) .ThenInclude(a => a.TechnologyApplicants) .ThenInclude(a => a.Technology) .ToListAsync()) .FilterAdApplicants(applicantFilterDto); _logger.LogInformation($"Got {adsApplicants.Count} ads"); var result = _mapper.Map>(adsApplicants); return result; } public async Task ApplyForAd(ApplyForAdRequestDto request) { string fileName = string.Format(@"{0}.pdf", DateTime.Now.Ticks); _logger.LogInformation($"Start uploading CV of applicant on Azure Blob storage"); await _fileService.UploadCV(fileName, request.PdfFile); _logger.LogInformation($"CV uploaded on Azure Blob storage"); _logger.LogInformation("Start applying for ad"); _logger.LogInformation("Find ad by id"); var ad = await _adService.GetByIdEntityAsync(request.AdId); if (ad == null) { _logger.LogError($"Ad with {request.AdId} not found"); throw new EntityNotFoundException("Ad not found in database"); } _logger.LogInformation($"Find sent technologies from FE in database"); var technologies = await _context.Technologies.Where(x => request.TechnologiesIds.Contains(x.TechnologyId)).ToListAsync(); _logger.LogInformation($"Create applicant instance with sent data"); Applicant applicant = new() { FirstName = request.FirstName, LastName = request.LastName, Position = ad.Title, DateOfApplication = DateTime.Now, CV = fileName, Email = request.Email, PhoneNumber = request.PhoneNumber, GithubLink = request.GithubLink, LinkedlnLink = request.LinkedinLink, BitBucketLink = request.BitBucketLink, Experience = request.Experience, //TypeOfEmployment = (EmploymentTypes)Enum.Parse(typeof(EmploymentTypes), ad.EmploymentType, true), TypeOfEmployment = ad.EmploymentType == EmploymentTypes.Intership ? TypesOfEmployment.Intership : TypesOfEmployment.Posao, Comments = new(), Ads = new List { ad }, SelectionProcesses = new(), TechnologyApplicants = new(), ApplicationChannel = "Putem sajta" }; _logger.LogInformation($"Saving applicant in database"); await _context.Applicants.AddAsync(applicant); var res = await _context.SaveChangesAsync(); _logger.LogInformation($"Applicant saved in database"); _logger.LogInformation($"Saving TechnologyApplicants in database"); for (int i = 0; i < technologies.Count; i++) { await _context.ApplicantTechnologies.AddAsync(new TechnologyApplicant { Applicant = applicant, ApplicantId = applicant.ApplicantId, Technology = technologies[i], TechnologyId = technologies[i].TechnologyId }); } await _context.SaveChangesAsync(); _logger.LogInformation($"TechnologyApplicants saved in database"); } public async Task ImportApplicant(List requests) { _logger.LogInformation($"Create applicant instance with sent data"); var res = new List(); _logger.LogInformation($"Get first user from database"); var user = await _userService.GetFirst(); _logger.LogInformation($"User succesufully fetched from database"); foreach (var request in requests) { Applicant applicant = new Applicant { FirstName = request.FirstName ?? "", LastName = request.LastName ?? "", CV = request.CV ?? "", Email = request.Email ?? "", PhoneNumber = request.PhoneNumber ?? "", GithubLink = request.GithubLink ?? "", LinkedlnLink = request.LinkedlnLink ?? "", BitBucketLink = request.BitBucketLink ?? "", Position = "", DateOfApplication = request.DateOfApplication, TypeOfEmployment = request.TypeOfEmployment == "Praksa" ? TypesOfEmployment.Intership : TypesOfEmployment.Posao, Experience = request.Experience, ApplicationChannel = request.ApplicationChannel ?? "Putem sajta", // MORA DA SE UVEDE KO JE DAO KOMENTAR DA LI DA STAVIMO DA JE DANIJELA SVIMA STAVILA KOMENTARE ILI ?? Comments = new List { new Comment { User = user, Content = request.Comment } }, Ads = new List { request.Ad }, SelectionProcesses = new(), TechnologyApplicants = new() }; res.Add(applicant); } _logger.LogInformation($"Saving applicants in database"); await _context.AddRangeAsync(res); await _context.SaveChangesAsync(); _logger.LogInformation($"Applicants saved in database"); } public async Task> GetOptions() { _logger.LogInformation($"Start getting all applicants from database"); var res = await _context.Applicants.ToListAsync(); _logger.LogInformation($"Got {res.Count} applicants"); return _mapper.Map>(res); } public async Task> InitializeProcess(ApplicantProcessRequestDTO model) { _logger.LogInformation($"Start searching Applicant with id = {model.ApplicantId}"); var applicant = await _context.Applicants.Include(n => n.SelectionProcesses).Where(n=> n.ApplicantId ==model.ApplicantId).FirstOrDefaultAsync(); if (applicant == null) { _logger.LogError($"Applicant with id = {model.ApplicantId} not found"); return new ServiceResponseDTO { IsError = true, ErrorMessage = "Applicant does not exist." }; } applicant.SelectionProcesses.Add(new SelectionProcess { Name = StringGenerator.GenerateRandomPassword(), SchedulerId = model.SchedulerId, SelectionLevelId = 1, Status = model.Appointment != null ? "Zakazan" : "Čeka na zakazivanje", Date = model.Appointment }); _logger.LogInformation($"Saving selection processes in database"); await _context.SaveChangesAsync(); _logger.LogInformation($"Selecetion processes saved in database"); return new ServiceResponseDTO { Data = true }; } } }