namespace Diligent.WebAPI.Business.Services { public class AdService : IAdService { private readonly ILogger _logger; private readonly DatabaseContext _context; private readonly IMapper _mapper; private readonly ITechnologyService _technologyService; public AdService(DatabaseContext context, IMapper mapper, ITechnologyService technologyService, ILogger logger) { _logger = logger; _context = context; _mapper = mapper; _technologyService = technologyService; } public async Task> GetAllAsync() { _logger.LogInformation("Start getting all Ads"); var today = DateTime.Now; _logger.LogInformation("Getting data from DB"); var fromDb = await _context.Ads.Include(x => x.Technologies).Where(x => x.ExpiredAt > today).ToListAsync(); _logger.LogInformation($"Received {fromDb.Count} ads from db."); _logger.LogInformation($"Mapping received ads to AdResponseDto"); var result = _mapper.Map>(fromDb); _logger.LogInformation($"Ads has been mapped and received to client: {result.Count} mapped ads"); return result; } public async Task> GetAllWithCountAsync() { _logger.LogInformation("Start getting all Ads with applicants count"); var today = DateTime.Now; _logger.LogInformation("Getting data from database"); var res = _mapper.Map>(await _context.Ads.Include(x => x.Applicants).Where(x => x.ExpiredAt > today).ToListAsync()); _logger.LogInformation($"Received {res.Count} ads with their counts"); return res; } public async Task GetByIdAsync(int id) { _logger.LogInformation($"Start searching Ad with id = {id}"); var ad = await _context.Ads.FindAsync(id); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } _logger.LogInformation($"Mapping Ad with id = {id}"); AdResponseDto result = _mapper.Map(ad); _logger.LogInformation($"Ad with id = {id} mapped successfully"); return result; } public async Task GetAdDetailsByIdAsync(int id) { _logger.LogInformation($"Start finding Ad with id = {id} with applicants"); var ad = await _context.Ads.Include(x => x.Applicants).Where(x => x.Id == id).FirstOrDefaultAsync(); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } _logger.LogInformation($"Mapping Ad with id = {id}"); AdDetailsResponseDto result = _mapper.Map(ad); _logger.LogInformation($"Ad with id = {id} mapped successfully"); return result; } public async Task> GetArchiveAds() { _logger.LogInformation("Start getting all Archived Ads"); var today = DateTime.Now; _logger.LogInformation("Getting data from DB"); var archiveAds = await _context.Ads.Where(x => x.ExpiredAt < today).ToListAsync(); _logger.LogInformation($"Received {archiveAds.Count} ads from db."); _logger.LogInformation($"Mapping received ads to AdResponseDto"); List result = _mapper.Map>(archiveAds); _logger.LogInformation($"Ads has been mapped and received to client: {result.Count} mapped ads"); return result; } public async Task> GetFilteredAdsAsync(AdFilterDto filters) { _logger.LogInformation($"Start getting all filtered Ads"); var today = DateTime.Now; _logger.LogInformation("Getting data from DB"); var filteredAds = await _context.Ads.Include(x => x.Technologies).Where(x => x.ExpiredAt > today).ToListAsync(); _logger.LogInformation($"Received {filteredAds.Count} ads from db."); _logger.LogInformation($"Mapping received ads to AdResponseDto"); List result = _mapper.Map>(filteredAds.Filter(filters)); _logger.LogInformation($"Ads has been mapped and received to client: {result.Count} mapped ads"); return result; } public async Task CreateAsync(AdCreateDto adCreateDto) { _logger.LogInformation($"Start creating Ad"); var ad = _mapper.Map(adCreateDto); _logger.LogInformation($"Ad created successfully"); _logger.LogInformation($"Start adding technologies to Ad"); for (int i = 0; i < adCreateDto.TechnologiesIds.Count; i++) { var technology = await _technologyService.GetEntityByIdAsync(adCreateDto.TechnologiesIds[i]); ad.Technologies.Add(technology); _logger.LogInformation($"Technology with id {technology.TechnologyId} added to Ad"); } _logger.LogInformation($"Finished adding techonologies"); await _context.Ads.AddAsync(ad); _logger.LogInformation($"Saving Ad to db..."); var result = _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); await result; } public async Task UpdateAsync(int id, AdUpdateDto adUpdateDto) { _logger.LogInformation($"Start searching Ad with id = {id}"); var ad = await _context.Ads.FindAsync(id); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } _logger.LogInformation($"Mapping Ad with id = {id}"); _mapper.Map(adUpdateDto, ad); _logger.LogInformation($"Ad with id = {id} mapped successfully"); _context.Entry(ad).State = EntityState.Modified; var result = _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); await result; } public async Task ArchiveAdAsync(int id) { _logger.LogInformation($"Start searching Ad with id = {id}"); var ad = await _context.Ads.FindAsync(id); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } _logger.LogInformation($"Change ad expired time"); ad.ExpiredAt = DateTime.Now; _logger.LogInformation($"Ad expired time changed successfully"); _context.Entry(ad).State = EntityState.Modified; var result = _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); await result; } public async Task DeleteAsync(int id) { _logger.LogInformation($"Start searching Ad with id = {id}"); var ad = await _context.Ads.FindAsync(id); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } _context.Ads.Remove(ad); var result = _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); await result; } public async Task ImportAsync(AdCreateDto adCreateDto) { _logger.LogInformation($"Start importing Ad"); var ad = _mapper.Map(adCreateDto); _logger.LogInformation($"Ad imported successfully"); await _context.Ads.AddAsync(ad); _logger.LogInformation($"Saving Ad to db..."); await _context.SaveChangesAsync(); _logger.LogInformation($"Ad saved to DB"); return ad; } public async Task GetByIdEntityAsync(int id) { _logger.LogInformation($"Start searching Ad with id = {id}"); var ad = await _context.Ads.FindAsync(id); if (ad is null) { _logger.LogError($"Ad with id = {id} not found"); throw new EntityNotFoundException("Ad not found"); } return ad; } } }