using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; 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; public class FileRepository : IFileRepository { private readonly IQueryable dbSetConfigured; private readonly IAsbCloudDbContext db; public FileRepository(IAsbCloudDbContext db) { this.db = db; this.dbSetConfigured = db.Files .Include(f => f.Author) .ThenInclude(u => u!.Company) .ThenInclude(c => c.CompanyType) .Include(f => f.FileMarks) .ThenInclude(m => m.User) .Include(f => f.Well); } private IQueryable BuildQuery(FileRequest request) { var query = dbSetConfigured .Where(e => e.IdWell == request.IdWell); if (request.IdCategory is not null) query = query.Where(x => x.IdCategory == request.IdCategory); if (request.IsDeleted is not null) query = query.Where(x => x.IsDeleted == request.IsDeleted); if (request.CompanyNamePart is not null) query = query.Where(e => e.Author != null && e.Author.Company.Caption.ToLower().Contains(request.CompanyNamePart.ToLower())); if (request.FileNamePart is not null) query = query.Where(e => e.Name.ToLower().Contains(request.FileNamePart.ToLower())); if (request.Begin is not null) { var beginUtc = request.Begin.Value.ToUniversalTime(); query = query.Where(e => e.UploadDate >= beginUtc); } if (request.End is not null) { var endUtc = request.End.Value.ToUniversalTime(); query = query.Where(e => e.UploadDate <= endUtc); } if (request?.SortFields?.Any() == true) { query = query.SortBy(request.SortFields); } else query = query .OrderBy(o => o.UploadDate); return query; } public async Task> GetInfosAsync(FileRequest request, CancellationToken token) { var query = BuildQuery(request); var entities = await query .SkipTake(request.Skip, request.Take) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var dtos = entities.Select(e => Convert(e)); return dtos; } public async Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token = default) { var skip = request.Skip ?? 0; var take = request.Take ?? 32; var query = BuildQuery(request); var result = new PaginationContainer() { Skip = skip, Take = take, Count = await query.CountAsync(token), }; if (result.Count == 0) return result; var entities = await query .SkipTake(skip, take) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); result.Items = entities.Select(e => Convert(e)); return result; } public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) { var result = Enumerable.Empty(); var entities = await dbSetConfigured .AsNoTracking() .Where(f => idsFile.Contains(f.Id)) .ToListAsync(token) .ConfigureAwait(false); if (entities is not null) result = entities.Select(entity => Convert(entity)); return result; } public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) { var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false); if (fileInfo is null) return 0; fileInfo.IsDeleted = true; return await db.SaveChangesAsync(token).ConfigureAwait(false); } public async Task> DeleteAsync(IEnumerable ids, CancellationToken token) { var query = dbSetConfigured .Where(f => ids.Contains(f.Id)); var files = await query.ToListAsync(token); var filesDtos = files.Select(x => Convert(x)); db.Files.RemoveRange(query); await db.SaveChangesAsync(token).ConfigureAwait(false); return filesDtos; } public async Task GetByMarkId(int idMark, CancellationToken token) { var entity = await dbSetConfigured .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) .ConfigureAwait(false); FileInfoDto dto = Convert(entity!); return dto; } public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) { var fileMark = await db.FileMarks .FirstOrDefaultAsync(m => m.IdFile == fileMarkDto.IdFile && m.IdMarkType == fileMarkDto.IdMarkType && m.IdUser == idUser && m.IsDeleted == false, token) .ConfigureAwait(false); if (fileMark is not null) return 0; var newFileMark = fileMarkDto.Adapt(); newFileMark.Id = default; newFileMark.DateCreated = DateTimeOffset.UtcNow; newFileMark.IdUser = idUser; newFileMark.User = null!; db.FileMarks.Add(newFileMark); return await db.SaveChangesAsync(token); } public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) { var fileMarkQuery = db.FileMarks .Where(m => idsMarks.Contains(m.Id)); foreach (var fileMark in fileMarkQuery) fileMark.IsDeleted = true; return await db.SaveChangesAsync(token); } public async Task> GetAllAsync(CancellationToken token) => await dbSetConfigured.AsNoTracking() .Select(x => Convert(x)) .ToListAsync(token) .ConfigureAwait(false); public async Task GetOrDefaultAsync(int id, CancellationToken token) { var entity = await dbSetConfigured .AsNoTracking() .FirstOrDefaultAsync(f => f.Id == id, token) .ConfigureAwait(false); if (entity is null) return null; var dto = Convert(entity); return dto; } public FileInfoDto? GetOrDefault(int id) { var entity = dbSetConfigured .AsNoTracking() .FirstOrDefault(f => f.Id == id); if (entity is null) return null; var dto = Convert(entity); return dto; } public async Task InsertAsync(FileInfoDto newItem, CancellationToken token) { var fileInfo = new FileInfo() { IdWell = newItem.IdWell, IdAuthor = newItem.IdAuthor, IdCategory = newItem.IdCategory, Name = newItem.Name, UploadDate = DateTimeOffset.UtcNow, IsDeleted = false, Size = newItem.Size, }; var entry = db.Files.Add(fileInfo); await db.SaveChangesAsync(token).ConfigureAwait(false); return entry.Entity.Id; } public Task InsertRangeAsync(IEnumerable newItems, CancellationToken token) { throw new NotImplementedException(); } public Task UpdateAsync(FileInfoDto item, CancellationToken token) { throw new NotImplementedException(); } public Task DeleteAsync(int id, CancellationToken token) { throw new NotImplementedException(); } private static FileInfoDto Convert(FileInfo entity) { var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; return Convert(entity, timezoneOffset); } private static FileInfoDto Convert(FileInfo entity, double timezoneOffset) { var dto = entity.Adapt(); dto.UploadDate = entity.UploadDate.ToOffset(TimeSpan.FromHours(timezoneOffset)); dto.FileMarks = entity.FileMarks.Select(m => { var mark = m.Adapt(); mark.DateCreated = m.DateCreated.ToOffset(TimeSpan.FromHours(timezoneOffset)); return mark; }); return dto; } }