using Azure.Storage.Blobs; using Microsoft.Extensions.Configuration; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; 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 IConfiguration _configuration; public ApplicantService(DatabaseContext context, IMapper mapper, ILogger logger, IUserService userService,IConfiguration configuration) { _context = context; _mapper = mapper; _logger = logger; _userService = userService; _configuration = configuration; } public ApplicantService(DatabaseContext context, IMapper mapper, ILogger logger) { _context = context; _mapper = mapper; _logger = logger; } 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 GetCV("638077305621281656.pdf"); _logger.LogInformation($"Applicant with id = {id} mapped successfully"); return result; } public async Task GetApplicantWithSelectionProcessesById(int 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) throw new EntityNotFoundException("Applicant not found"); 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); string blobstorageconnection = _configuration.GetValue("BlobConnectionString"); CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(blobstorageconnection); CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference( _configuration.GetValue("BlobContainerName")); CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); await using (var data = request.PdfFile.OpenReadStream()) { await blockBlob.UploadFromStreamAsync(data); } _logger.LogInformation("Start applying for ad"); _logger.LogInformation("Find ad by id"); var ad = await _context.Ads.Where(x => x.Id == request.AdId).FirstOrDefaultAsync(); 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(); var user = await _userService.GetFirst(); 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); } await _context.AddRangeAsync(res); await _context.SaveChangesAsync(); _logger.LogInformation($"Saving applicant in database"); _logger.LogInformation($"Applicant saved in database"); } public async Task> GetOptions() { var res = await _context.Applicants.ToListAsync(); return _mapper.Map>(res); } public async Task> InitializeProcess(ApplicantProcessRequestDTO model) { var applicant = await _context.Applicants.Include(n => n.SelectionProcesses).Where(n=> n.ApplicantId ==model.ApplicantId).FirstOrDefaultAsync(); if (applicant == null) 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 }); await _context.SaveChangesAsync(); return new ServiceResponseDTO { Data = true }; } public async Task GetCV(string fileName) { CloudBlockBlob blockBlob; await using (MemoryStream memoryStream = new()) { string blobstorageconnection = _configuration.GetValue("BlobConnectionString"); CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(blobstorageconnection); CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(_configuration.GetValue("BlobContainerName")); blockBlob = cloudBlobContainer.GetBlockBlobReference(fileName); await blockBlob.DownloadToStreamAsync(memoryStream); Stream blobStream = blockBlob.OpenReadAsync().Result; return ConvertToBase64(blobStream); } } private static string ConvertToBase64(Stream stream) { byte[] bytes; using (var memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); bytes = memoryStream.ToArray(); } string base64 = Convert.ToBase64String(bytes); return base64; } //public async Task CreateApplicant(ApplicantCreateDto applicantCreateDto) //{ // var applicant = _mapper.Map(applicantCreateDto); // await _context.Applicants.AddAsync(applicant); // await _context.SaveChangesAsync(); //} //public async Task UpdateApplicant(int id, ApplicantUpdateDto applicantUpdateDto) //{ // var applicant = await _context.Applicants.FindAsync(id); // if (applicant is null) // throw new EntityNotFoundException("Applicant not found"); // _mapper.Map(applicantUpdateDto, applicant); // _context.Entry(applicant).State = EntityState.Modified; // await _context.SaveChangesAsync(); //} } }