using AsbCloudApp.Data; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Repository { #nullable enable /// /// сервис по работе с faq-вопросами /// public class FaqRepository : IFaqRepository { private readonly IAsbCloudDbContext db; private readonly IWellService wellService; public FaqRepository(IAsbCloudDbContext db, IWellService wellService) { this.db = db; this.wellService = wellService; } public async Task> GetAsync(FaqRequest request, CancellationToken token) { var query = db.FAQs .Where(o => o.IdWell == request.IdWell); if (request.IsFrequently) { query = query.Where(o => o.IsFrequently); } if (request.HasAnswer) { query = query.Where(o => !string.IsNullOrEmpty(o.Answer)); } if (!request.IncludeDeleted) { query = query.Where(o => o.State != Faq.StateDeleted); } var entities = query.Select(o => new FaqDto() { Id = o.Id, Question = o.Question, Answer = o.Answer, CounterQuestion = o.CounterQuestion, IsFrequently = o.IsFrequently, State = o.State, DateCreatedQuestion = o.DateCreatedQuestion, }); if (request.SortFields?.Any() == true) { entities = entities.SortBy(request.SortFields); } else { entities = entities.OrderByDescending(e => e.DateCreatedQuestion); }; var result = await entities.AsNoTracking() .ToArrayAsync(token) .ConfigureAwait(false); return result; } public async Task InsertAsync(FaqDto faqDto, CancellationToken token) { var entity = faqDto.Adapt(); entity.DateCreatedQuestion = entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; entity.CounterQuestion = 0; entity.State = Faq.StateOpened; db.FAQs.Add(entity); await db.SaveChangesAsync(token).ConfigureAwait(false); return entity.Id; } public async Task MergeAsync(IEnumerable sourceIds, bool mergeTexts, CancellationToken token) { var sourceFaqs = db.FAQs.Where(e => sourceIds.Contains(e.Id)).ToArray(); if (sourceFaqs.Count() < 2) throw new ArgumentInvalidException("Questions with target ids don't exist", nameof(sourceIds)); if (sourceFaqs.Select(e => e.IdWell).Distinct().Count() > 1) throw new ArgumentInvalidException("Questions with different idWell are not merged", nameof(sourceIds)); var newFaq = new Faq() { CounterQuestion = sourceFaqs.Sum(e => e.CounterQuestion), State = 0, IsFrequently = sourceFaqs.Any(e => e.IsFrequently), IdAuthorQuestion = sourceFaqs.Last().IdAuthorQuestion, DateCreatedQuestion = DateTimeOffset.UtcNow, DateLastEditedQuestion = DateTimeOffset.UtcNow, IdWell = sourceFaqs.Last().IdWell, Answer = mergeTexts == true ? string.Join(Environment.NewLine, sourceFaqs.Select(e => e.Answer)) : sourceFaqs.Last().Answer, Question = mergeTexts == true ? string.Join(Environment.NewLine, sourceFaqs.Select(e => e.Question)) : sourceFaqs.Last().Question, }; db.FAQs.Add(newFaq); await db.SaveChangesAsync(token).ConfigureAwait(false); if (newFaq.Id == 0) throw new ArgumentInvalidException("Error creating new question", nameof(newFaq)); foreach (var sourceFaq in sourceFaqs) { sourceFaq.IdReplacementQuestion = newFaq.Id; sourceFaq.State = Faq.StateDeleted; } await db.SaveChangesAsync(token).ConfigureAwait(false); return newFaq.Id; } public async Task UpdateAsync(FaqDto dto, CancellationToken token) { var entity = dto.Adapt(); entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; db.FAQs.Update(entity); return await db.SaveChangesAsync(token) .ConfigureAwait(false); } public async Task MarkAsDeletedAsync(int idWell, int id, CancellationToken token) { var entity = db.FAQs.FirstOrDefault(e => e.Id == id); if (entity is null) throw new ArgumentInvalidException("Question doesn't exist", nameof(id)); if (entity.IdWell != idWell) throw new ArgumentInvalidException("Question's well and idWell don't match", nameof(idWell)); entity.State = Faq.StateDeleted; entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; return await db.SaveChangesAsync(token) .ConfigureAwait(false); } } #nullable disable }