forked from ddrilling/AsbCloudServer
160 lines
5.6 KiB
C#
160 lines
5.6 KiB
C#
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
|
||
/// <summary>
|
||
/// сервис по работе с faq-вопросами
|
||
/// </summary>
|
||
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<IEnumerable<FaqDto>> 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<int> InsertAsync(FaqDto faqDto, CancellationToken token)
|
||
{
|
||
var entity = faqDto.Adapt<Faq>();
|
||
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<int> MergeAsync(IEnumerable<int> 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<int> UpdateAsync(FaqDto dto, CancellationToken token)
|
||
{
|
||
var entity = dto.Adapt<Faq>();
|
||
entity.DateLastEditedQuestion = DateTimeOffset.UtcNow;
|
||
db.FAQs.Update(entity);
|
||
return await db.SaveChangesAsync(token)
|
||
.ConfigureAwait(false);
|
||
}
|
||
|
||
public async Task<int> 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
|
||
}
|