Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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