Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

ApplicantService.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. using Azure.Storage.Blobs;
  2. using Microsoft.Extensions.Configuration;
  3. using Microsoft.WindowsAzure.Storage;
  4. using Microsoft.WindowsAzure.Storage.Blob;
  5. using static Diligent.WebAPI.Data.Entities.Applicant;
  6. namespace Diligent.WebAPI.Business.Services
  7. {
  8. public class ApplicantService : IApplicantService
  9. {
  10. private readonly DatabaseContext _context;
  11. private readonly IMapper _mapper;
  12. private readonly ILogger<ApplicantService> _logger;
  13. private readonly IUserService _userService;
  14. private readonly IConfiguration _configuration;
  15. public ApplicantService(DatabaseContext context, IMapper mapper, ILogger<ApplicantService> logger,
  16. IUserService userService,IConfiguration configuration)
  17. {
  18. _context = context;
  19. _mapper = mapper;
  20. _logger = logger;
  21. _userService = userService;
  22. _configuration = configuration;
  23. }
  24. public ApplicantService(DatabaseContext context, IMapper mapper, ILogger<ApplicantService> logger)
  25. {
  26. _context = context;
  27. _mapper = mapper;
  28. _logger = logger;
  29. }
  30. public async Task<QueryResultDto<ApplicantViewDto>> GetFilteredApplicants(ApplicantFilterDto applicantFilterDto)
  31. {
  32. _logger.LogInformation("Start getting filtered applicants");
  33. _logger.LogInformation("Getting data from DB and filter");
  34. var filteredApplicants = (await _context.Applicants
  35. .Include(c => c.Ads)
  36. .Include(x => x.TechnologyApplicants)
  37. .ThenInclude(x => x.Technology).ToListAsync())
  38. .FilterApplicants(applicantFilterDto);
  39. int totalNumberOfItems = filteredApplicants.Count;
  40. _logger.LogInformation($"Got {totalNumberOfItems} applicants");
  41. filteredApplicants = PaginationExtension.ApplyPagging(filteredApplicants, new Pagination
  42. {
  43. CurrentPage = applicantFilterDto.CurrentPage,
  44. PageSize = applicantFilterDto.PageSize
  45. });
  46. _logger.LogInformation($"Return list of applicants");
  47. return new QueryResultDto<ApplicantViewDto>
  48. {
  49. Items = _mapper.Map<List<ApplicantViewDto>>(filteredApplicants),
  50. Total = totalNumberOfItems
  51. };
  52. }
  53. public async Task<ApplicantViewDto> GetById(int id)
  54. {
  55. _logger.LogInformation($"Start searching Applicant with id = {id}");
  56. var applicant = await _context.Applicants
  57. .Include(x => x.Ads)
  58. .ThenInclude(x => x.Technologies)
  59. .Include(x => x.TechnologyApplicants)
  60. .ThenInclude(x => x.Technology)
  61. .Include(x => x.Comments)
  62. .ThenInclude(t => t.User)
  63. .FirstOrDefaultAsync(x => x.ApplicantId == id);
  64. if (applicant is null)
  65. {
  66. _logger.LogError($"Applicant with id = {id} not found");
  67. throw new EntityNotFoundException("Applicant not found");
  68. }
  69. _logger.LogInformation($"Mapping Applicant with id = {id}");
  70. var result = _mapper.Map<ApplicantViewDto>(applicant);
  71. result.CV = await GetCV("638077305621281656.pdf");
  72. _logger.LogInformation($"Applicant with id = {id} mapped successfully");
  73. return result;
  74. }
  75. public async Task<ApplicantViewDto> GetApplicantWithSelectionProcessesById(int id)
  76. {
  77. var applicant = await _context.Applicants
  78. .Include(a => a.SelectionProcesses).ThenInclude(sp => sp.SelectionLevel)
  79. .Include(a => a.SelectionProcesses).ThenInclude(sp => sp.Scheduler)
  80. .FirstOrDefaultAsync(a => a.ApplicantId == id);
  81. if (applicant is null)
  82. throw new EntityNotFoundException("Applicant not found");
  83. return _mapper.Map<ApplicantViewDto>(applicant);
  84. }
  85. public async Task DeleteApplicant(int id)
  86. {
  87. _logger.LogInformation($"Start searching Applicant with id = {id}");
  88. var applicant = await _context.Applicants.FindAsync(id);
  89. if (applicant is null)
  90. {
  91. _logger.LogError($"Applicant with id = {id} not found");
  92. throw new EntityNotFoundException("Applicant not found");
  93. }
  94. _logger.LogInformation($"Removing Applicant with id = {id}");
  95. _context.Applicants.Remove(applicant);
  96. var result = _context.SaveChangesAsync();
  97. _logger.LogInformation($"Applicant with id = {id} is removed successfully");
  98. await result;
  99. }
  100. public async Task<List<AdApplicantsViewDto>> GetAllAdsApplicants(ApplicantFilterDto applicantFilterDto)
  101. {
  102. _logger.LogInformation("Start getting filtered applicants");
  103. _logger.LogInformation("Getting data from DB and filter");
  104. var adsApplicants = (await _context.Ads
  105. .Include(a => a.Applicants)
  106. .ThenInclude(a => a.TechnologyApplicants)
  107. .ThenInclude(a => a.Technology)
  108. .ToListAsync())
  109. .FilterAdApplicants(applicantFilterDto);
  110. _logger.LogInformation($"Got {adsApplicants.Count} ads");
  111. var result = _mapper.Map<List<AdApplicantsViewDto>>(adsApplicants);
  112. return result;
  113. }
  114. public async Task ApplyForAd(ApplyForAdRequestDto request)
  115. {
  116. string fileName = string.Format(@"{0}.pdf", DateTime.Now.Ticks);
  117. string blobstorageconnection = _configuration.GetValue<string>("BlobConnectionString");
  118. CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(blobstorageconnection);
  119. CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
  120. CloudBlobContainer container = blobClient.GetContainerReference(
  121. _configuration.GetValue<string>("BlobContainerName"));
  122. CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
  123. await using (var data = request.PdfFile.OpenReadStream())
  124. {
  125. await blockBlob.UploadFromStreamAsync(data);
  126. }
  127. _logger.LogInformation("Start applying for ad");
  128. _logger.LogInformation("Find ad by id");
  129. var ad = await _context.Ads.Where(x => x.Id == request.AdId).FirstOrDefaultAsync();
  130. if (ad == null)
  131. {
  132. _logger.LogError($"Ad with {request.AdId} not found");
  133. throw new EntityNotFoundException("Ad not found in database");
  134. }
  135. _logger.LogInformation($"Find sent technologies from FE in database");
  136. var technologies = await _context.Technologies.Where(x => request.TechnologiesIds.Contains(x.TechnologyId)).ToListAsync();
  137. _logger.LogInformation($"Create applicant instance with sent data");
  138. Applicant applicant = new()
  139. {
  140. FirstName = request.FirstName,
  141. LastName = request.LastName,
  142. Position = ad.Title,
  143. DateOfApplication = DateTime.Now,
  144. CV = fileName,
  145. Email = request.Email,
  146. PhoneNumber = request.PhoneNumber,
  147. GithubLink = request.GithubLink,
  148. LinkedlnLink = request.LinkedinLink,
  149. BitBucketLink = request.BitBucketLink,
  150. Experience = request.Experience,
  151. //TypeOfEmployment = (EmploymentTypes)Enum.Parse(typeof(EmploymentTypes), ad.EmploymentType, true),
  152. TypeOfEmployment = ad.EmploymentType == EmploymentTypes.Intership ? TypesOfEmployment.Intership : TypesOfEmployment.Posao,
  153. Comments = new(),
  154. Ads = new List<Ad> { ad },
  155. SelectionProcesses = new(),
  156. TechnologyApplicants = new(),
  157. ApplicationChannel = "Putem sajta"
  158. };
  159. _logger.LogInformation($"Saving applicant in database");
  160. await _context.Applicants.AddAsync(applicant);
  161. var res = await _context.SaveChangesAsync();
  162. _logger.LogInformation($"Applicant saved in database");
  163. _logger.LogInformation($"Saving TechnologyApplicants in database");
  164. for (int i = 0; i < technologies.Count; i++)
  165. {
  166. await _context.ApplicantTechnologies.AddAsync(new TechnologyApplicant { Applicant = applicant, ApplicantId = applicant.ApplicantId, Technology = technologies[i], TechnologyId = technologies[i].TechnologyId });
  167. }
  168. await _context.SaveChangesAsync();
  169. _logger.LogInformation($"TechnologyApplicants saved in database");
  170. }
  171. public async Task ImportApplicant(List<ApplicantImportDto> requests)
  172. {
  173. _logger.LogInformation($"Create applicant instance with sent data");
  174. var res = new List<Applicant>();
  175. var user = await _userService.GetFirst();
  176. foreach (var request in requests) {
  177. Applicant applicant = new Applicant
  178. {
  179. FirstName = request.FirstName ?? "",
  180. LastName = request.LastName ?? "",
  181. CV = request.CV ?? "",
  182. Email = request.Email ?? "",
  183. PhoneNumber = request.PhoneNumber ?? "",
  184. GithubLink = request.GithubLink ?? "",
  185. LinkedlnLink = request.LinkedlnLink ?? "",
  186. BitBucketLink = request.BitBucketLink ?? "",
  187. Position = "",
  188. DateOfApplication = request.DateOfApplication,
  189. TypeOfEmployment = request.TypeOfEmployment == "Praksa" ? TypesOfEmployment.Intership : TypesOfEmployment.Posao,
  190. Experience = request.Experience,
  191. ApplicationChannel = request.ApplicationChannel ?? "Putem sajta",
  192. // MORA DA SE UVEDE KO JE DAO KOMENTAR DA LI DA STAVIMO DA JE DANIJELA SVIMA STAVILA KOMENTARE ILI ??
  193. Comments = new List<Comment>
  194. {
  195. new Comment
  196. {
  197. User = user,
  198. Content = request.Comment
  199. }
  200. },
  201. Ads = new List<Ad> { request.Ad },
  202. SelectionProcesses = new(),
  203. TechnologyApplicants = new()
  204. };
  205. res.Add(applicant);
  206. }
  207. await _context.AddRangeAsync(res);
  208. await _context.SaveChangesAsync();
  209. _logger.LogInformation($"Saving applicant in database");
  210. _logger.LogInformation($"Applicant saved in database");
  211. }
  212. public async Task<List<ApplicantOptionsDTO>> GetOptions()
  213. {
  214. var res = await _context.Applicants.ToListAsync();
  215. return _mapper.Map<List<ApplicantOptionsDTO>>(res);
  216. }
  217. public async Task<ServiceResponseDTO<object>> InitializeProcess(ApplicantProcessRequestDTO model)
  218. {
  219. var applicant = await _context.Applicants.Include(n => n.SelectionProcesses).Where(n=> n.ApplicantId ==model.ApplicantId).FirstOrDefaultAsync();
  220. if (applicant == null)
  221. return new ServiceResponseDTO<object>
  222. {
  223. IsError = true,
  224. ErrorMessage = "Applicant does not exist."
  225. };
  226. applicant.SelectionProcesses.Add(new SelectionProcess
  227. {
  228. Name = StringGenerator.GenerateRandomPassword(),
  229. SchedulerId = model.SchedulerId,
  230. SelectionLevelId = 1,
  231. Status = model.Appointment != null ? "Zakazan" : "Čeka na zakazivanje",
  232. Date = model.Appointment
  233. });
  234. await _context.SaveChangesAsync();
  235. return new ServiceResponseDTO<object>
  236. {
  237. Data = true
  238. };
  239. }
  240. public async Task<string> GetCV(string fileName)
  241. {
  242. CloudBlockBlob blockBlob;
  243. await using (MemoryStream memoryStream = new())
  244. {
  245. string blobstorageconnection = _configuration.GetValue<string>("BlobConnectionString");
  246. CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(blobstorageconnection);
  247. CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
  248. CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(_configuration.GetValue<string>("BlobContainerName"));
  249. blockBlob = cloudBlobContainer.GetBlockBlobReference(fileName);
  250. await blockBlob.DownloadToStreamAsync(memoryStream);
  251. Stream blobStream = blockBlob.OpenReadAsync().Result;
  252. return ConvertToBase64(blobStream);
  253. }
  254. }
  255. private static string ConvertToBase64(Stream stream)
  256. {
  257. byte[] bytes;
  258. using (var memoryStream = new MemoryStream())
  259. {
  260. stream.CopyTo(memoryStream);
  261. bytes = memoryStream.ToArray();
  262. }
  263. string base64 = Convert.ToBase64String(bytes);
  264. return base64;
  265. }
  266. //public async Task CreateApplicant(ApplicantCreateDto applicantCreateDto)
  267. //{
  268. // var applicant = _mapper.Map<Applicant>(applicantCreateDto);
  269. // await _context.Applicants.AddAsync(applicant);
  270. // await _context.SaveChangesAsync();
  271. //}
  272. //public async Task UpdateApplicant(int id, ApplicantUpdateDto applicantUpdateDto)
  273. //{
  274. // var applicant = await _context.Applicants.FindAsync(id);
  275. // if (applicant is null)
  276. // throw new EntityNotFoundException("Applicant not found");
  277. // _mapper.Map(applicantUpdateDto, applicant);
  278. // _context.Entry(applicant).State = EntityState.Modified;
  279. // await _context.SaveChangesAsync();
  280. //}
  281. }
  282. }