diff --git a/AsbCloudApp/Data/PlannedTrajectoryDto.cs b/AsbCloudApp/Data/PlannedTrajectoryDto.cs index 52da8983..cf36bc6b 100644 --- a/AsbCloudApp/Data/PlannedTrajectoryDto.cs +++ b/AsbCloudApp/Data/PlannedTrajectoryDto.cs @@ -19,11 +19,11 @@ namespace AsbCloudApp.Data /// /// Дата загрузки /// - public DateTimeOffset UpdateDate { get; set; } + public DateTime UpdateDate { get; set; } /// /// ИД пользователя /// - public double IdUser { get; set; } + public int IdUser { get; set; } /// /// Глубина по стволу /// diff --git a/AsbCloudApp/Services/IPlannedTrajectoryImportService.cs b/AsbCloudApp/Services/IPlannedTrajectoryImportService.cs index e3013704..92e878f6 100644 --- a/AsbCloudApp/Services/IPlannedTrajectoryImportService.cs +++ b/AsbCloudApp/Services/IPlannedTrajectoryImportService.cs @@ -35,8 +35,8 @@ namespace AsbCloudApp.Services /// /// /// - /// Очистить старые координаты перед импортом (если файл проходит валидацию) - Task ImportAsync(int idWell, int idUser, Stream stream, CancellationToken token, bool deleteWellOperationsBeforeImport = false); + /// Очистить старые координаты перед импортом (если файл проходит валидацию) + Task ImportAsync(int idWell, int idUser, Stream stream, CancellationToken token, bool deletePlannedTrajectoryBeforeImport = false); } #nullable disable } diff --git a/AsbCloudApp/Services/IPlannedTrajectoryService.cs b/AsbCloudApp/Services/IPlannedTrajectoryService.cs index f225635d..573d53b5 100644 --- a/AsbCloudApp/Services/IPlannedTrajectoryService.cs +++ b/AsbCloudApp/Services/IPlannedTrajectoryService.cs @@ -18,40 +18,32 @@ namespace AsbCloudApp.Services /// /// /// - Task> GetOrDefaultAsync(int idWell, CancellationToken token); + Task> GetAsync(int idWell, CancellationToken token); /// /// Добавить строки с координатами - /// - /// - /// + /// /// /// /// - Task AddRangeAsync(int idWell, int idUser, - IEnumerable plannedTrajectoryRows, CancellationToken token); + Task AddRangeAsync(IEnumerable plannedTrajectoryRows, CancellationToken token); /// /// Добавить одну строку с координатами - /// - /// - /// + /// /// /// /// - Task AddAsync(int idWell, int idUser, - PlannedTrajectoryDto plannedTrajectoryRow, CancellationToken token); + Task AddAsync(PlannedTrajectoryDto plannedTrajectoryRow, CancellationToken token); /// /// Обновить строку с координатами - /// - /// - /// + /// /// /// /// /// - Task UpdateAsync(int idWell, int idUser, int idRow, PlannedTrajectoryDto row, + Task UpdateAsync(int idRow, PlannedTrajectoryDto row, CancellationToken token); /// @@ -68,7 +60,7 @@ namespace AsbCloudApp.Services /// /// /// - Task DeleteAllByIdWellAsync(int idWell, CancellationToken token); + Task DeleteByIdWellAsync(int idWell, CancellationToken token); } #nullable disable } diff --git a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryImportService.cs b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryImportService.cs index 014da8a3..0165b54d 100644 --- a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryImportService.cs +++ b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryImportService.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using ClosedXML.Excel; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -19,6 +20,8 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory private readonly IWellService wellService; private readonly IPlannedTrajectoryService plannedTrajectoryService; + private const string templateFileName = "PlannedTrajectoryTemplate.xlsx"; + private const string usingTemplateFile = "AsbCloudInfrastructure.Services.PlannedTrajectoryService"; private const string sheetNamePlannedTrajectory = "Плановая траектория"; private const int headerRowsCount = 2; private const int ColumnWellboreDepth = 1; @@ -47,7 +50,9 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory public Stream GetTemplateFile() { var stream = System.Reflection.Assembly.GetExecutingAssembly() - .GetManifestResourceStream("AsbCloudInfrastructure.Services.PlannedTrajectoryService.PlannedTrajectoryTemplate.xlsx"); + .GetManifestResourceStream($"{usingTemplateFile}.{templateFileName}"); + if (stream is null) + throw new Exception($"Область {usingTemplateFile} не содержит файла с названием {templateFileName}"); return stream; } @@ -59,9 +64,7 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory public async Task ExportAsync(int idWell, CancellationToken token) { - var plannedTrajectorys = await plannedTrajectoryService.GetOrDefaultAsync(idWell, token); - if (!plannedTrajectorys.Any()) - return null; + var plannedTrajectorys = await plannedTrajectoryService.GetAsync(idWell, token); return MakeExelFileStream(plannedTrajectorys); } @@ -69,32 +72,34 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory { using Stream ecxelTemplateStream = GetTemplateFile(); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); - AddOperationsToWorkbook(workbook, plannedTrajectories); + AddPlannedTrajecoryToWorkbook(workbook, plannedTrajectories); MemoryStream memoryStream = new MemoryStream(); workbook.SaveAs(memoryStream, new SaveOptions { }); memoryStream.Seek(0, SeekOrigin.Begin); return memoryStream; } - private static void AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable plannedTrajectories) + private static void AddPlannedTrajecoryToWorkbook(XLWorkbook workbook, IEnumerable plannedTrajectories) { if (plannedTrajectories.Any()) { var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory); - AddOperationsToSheet(sheet, plannedTrajectories); + if (sheet is null) + throw new FileFormatException($"Лист с именем {sheetNamePlannedTrajectory} отсутствует, либо имеет некорректное название"); + AddPlannedTrajecoryToSheet(sheet, plannedTrajectories); } } - private static void AddOperationsToSheet(IXLWorksheet sheet, IEnumerable plannedTrajectories) + private static void AddPlannedTrajecoryToSheet(IXLWorksheet sheet, IEnumerable plannedTrajectories) { var rowList = plannedTrajectories.ToList(); for (int i = 0; i < rowList.Count; i++) { var row = sheet.Row(1 + i + headerRowsCount); - AddOperationToRow(row, rowList[i]); + AddCoordinatesToRow(row, rowList[i]); } } - private static void AddOperationToRow(IXLRow row, PlannedTrajectoryDto trajectory) + private static void AddCoordinatesToRow(IXLRow row, PlannedTrajectoryDto trajectory) { row.Cell(ColumnWellboreDepth).Value = trajectory.WellboreDepth; row.Cell(ColumnZenithAngle).Value = trajectory.ZenithAngle; @@ -120,17 +125,17 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory foreach (var row in trajectoryRows) row.IdWell = idWell; - var rowsCount = await SavePlannedTrajectoryAsync(idWell, idUser, trajectoryRows, token, deletePrevRows); + var rowsCount = await SavePlannedTrajectoryAsync(idWell,trajectoryRows, token, deletePrevRows); return rowsCount; } - private async Task SavePlannedTrajectoryAsync(int idWell, int idUser, IEnumerable newRows, CancellationToken token, bool deletePrevRow = false) + private async Task SavePlannedTrajectoryAsync(int idWell, IEnumerable newRows, CancellationToken token, bool deletePrevRow = false) { if (deletePrevRow) { - await plannedTrajectoryService.DeleteAllByIdWellAsync(idWell, token); + await plannedTrajectoryService.DeleteByIdWellAsync(idWell, token); } - var rowsCount = await plannedTrajectoryService.AddRangeAsync(idWell, idUser, newRows, token); + var rowsCount = await plannedTrajectoryService.AddRangeAsync(newRows, token); return rowsCount; } @@ -157,7 +162,7 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory var count = sheet.RowsUsed().Count() - headerRowsCount; if (count > 1024) - throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество операций."); + throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк."); if (count <= 0) throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой"); diff --git a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryService.cs b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryService.cs index 1d5fcad3..54335204 100644 --- a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryService.cs +++ b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryService.cs @@ -22,20 +22,18 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory this.db = db; this.wellService = wellService; } - public async Task AddRangeAsync(int idWell, int idUser,IEnumerable plannedTrajectoryRows, CancellationToken token) - { - var timezone = wellService.GetTimezone(idWell); + public async Task AddRangeAsync(IEnumerable plannedTrajectoryRows, CancellationToken token) + { var entitys = plannedTrajectoryRows - .Select(e => Convert(e, timezone, idWell, idUser)); + .Select(e => Convert(e)); db.PlannedTrajectorys.AddRange(entitys); return await db.SaveChangesAsync(token) .ConfigureAwait(false); } - public async Task AddAsync(int idWell, int idUser, PlannedTrajectoryDto plannedTrajectoryRow, CancellationToken token) - { - var timezone = wellService.GetTimezone(idWell); - var entity = Convert(plannedTrajectoryRow, timezone, idWell, idUser); + public async Task AddAsync(PlannedTrajectoryDto plannedTrajectoryRow, CancellationToken token) + { + var entity = Convert(plannedTrajectoryRow); db.PlannedTrajectorys.Add(entity); return await db.SaveChangesAsync(token) .ConfigureAwait(false); @@ -51,21 +49,20 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory .ConfigureAwait(false); } - public async Task DeleteAllByIdWellAsync(int idWell, CancellationToken token) + public async Task DeleteByIdWellAsync(int idWell, CancellationToken token) { var query = db.PlannedTrajectorys - .AsNoTracking() .Where(e => e.IdWell == idWell); - var ids = await query - .Select(r => r.IdWell) - .ToListAsync(token); - var result = await DeleteRangeAsync(ids, token); + db.PlannedTrajectorys.RemoveRange(query); + return await db.SaveChangesAsync(token) + .ConfigureAwait(false); } - public async Task> GetOrDefaultAsync(int idWell, CancellationToken token) + public async Task> GetAsync(int idWell, CancellationToken token) { var well = wellService.GetOrDefault(idWell); + var timezone = wellService.GetTimezone(idWell); if (well is null || well.Timezone is null) throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell)); var query = db.PlannedTrajectorys @@ -79,36 +76,42 @@ namespace AsbCloudInfrastructure.Services.PlannedTrajectory return result; } - public async Task UpdateAsync(int idWell, int idUser, int idRow, PlannedTrajectoryDto row, CancellationToken token) - { - var timezone = wellService.GetTimezone(idWell); - var entity = row.Adapt(); - entity.IdWell = idWell; - entity.Id = idUser; - entity.UpdateDate = DateTime.Today.ToUtcDateTimeOffset(timezone.Hours); - entity.IdUser = idUser; + public async Task UpdateAsync(int idRow, PlannedTrajectoryDto row, CancellationToken token) + { + var entity = Convert(row, idRow); db.PlannedTrajectorys.Update(entity); return await db.SaveChangesAsync(token) .ConfigureAwait(false); } - private static PlannedTrajectoryDto Convert(AsbCloudDb.Model.PlannedTrajectory entity) + private PlannedTrajectoryDto Convert(AsbCloudDb.Model.PlannedTrajectory entity) { - var dto = entity.Adapt(); + var timezone = wellService.GetTimezone(entity.IdWell); + var dto = entity.Adapt(); + dto.UpdateDate = entity.UpdateDate.ToRemoteDateTime(timezone.Hours); return dto; } - private static AsbCloudDb.Model.PlannedTrajectory Convert(PlannedTrajectoryDto dto, SimpleTimezoneDto timezone, int idWell, int idUser) - { + private AsbCloudDb.Model.PlannedTrajectory Convert(PlannedTrajectoryDto dto) + { + var timezone = wellService.GetTimezone(dto.IdWell); var entity = dto.Adapt(); - entity.IdWell = idWell; - entity.Id = default; - entity.UpdateDate = DateTime.Today.ToUtcDateTimeOffset(timezone.Hours); - entity.IdUser = idUser; + entity.IdWell = dto.IdWell; + entity.Id = 0; + entity.UpdateDate = DateTime.Now.ToUtcDateTimeOffset(timezone.Hours); + entity.IdUser = dto.IdUser; + return entity; + } + private AsbCloudDb.Model.PlannedTrajectory Convert(PlannedTrajectoryDto dto, int idRow) + { + var timezone = wellService.GetTimezone(dto.IdWell); + var entity = dto.Adapt(); + entity.IdWell = dto.IdWell; + entity.Id = idRow; + entity.UpdateDate = DateTime.Now.ToUtcDateTimeOffset(timezone.Hours); + entity.IdUser = dto.IdUser; return entity; } - - } #nullable disable } diff --git a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryTemplate.xlsx b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryTemplate.xlsx index a8756796..68fd9cc2 100644 Binary files a/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryTemplate.xlsx and b/AsbCloudInfrastructure/Services/PlannedTrajectoryService/PlannedTrajectoryTemplate.xlsx differ diff --git a/AsbCloudWebApi/Controllers/PlannedTrajectoryController.cs b/AsbCloudWebApi/Controllers/PlannedTrajectoryController.cs index 61250cda..c4e65f2f 100644 --- a/AsbCloudWebApi/Controllers/PlannedTrajectoryController.cs +++ b/AsbCloudWebApi/Controllers/PlannedTrajectoryController.cs @@ -72,7 +72,7 @@ namespace AsbCloudWebApi.Controllers /// Коллекция из одного файла xlsx /// Удалить операции перед импортом = 1, если фал валидный /// Токен отмены задачи - /// + /// количество успешно записанных строк в БД [HttpPost] [Permission] [Route("import/{options}")] @@ -81,20 +81,14 @@ namespace AsbCloudWebApi.Controllers int options = 0, CancellationToken token = default) { - int? idCompany = User.GetCompanyId(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); - if (idCompany is null || idUser is null) + if (!await CanUserAccessToWellAsync(idWell, + token).ConfigureAwait(false)) return Forbid(); - - if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) - return Forbid(); - if (files.Count < 1) return BadRequest("нет файла"); - var file = files[0]; if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") return BadRequest("Требуется xlsx файл."); @@ -102,13 +96,13 @@ namespace AsbCloudWebApi.Controllers try { - var result = plannedTrajectoryImportService.ImportAsync(idWell, idUser.Value, stream, token,(options & 1) > 0); - return Ok(result); + var result = plannedTrajectoryImportService.ImportAsync(idWell, idUser.Value, stream, token, (options & 1) > 0); + return Ok(result); } catch (FileFormatException ex) { return BadRequest(ex.Message); - } + } } /// @@ -123,16 +117,10 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetRows([FromRoute] int idWell, CancellationToken token = default) { - int? idCompany = User.GetCompanyId(); - - if (idCompany is null) + if (!await CanUserAccessToWellAsync(idWell, + token).ConfigureAwait(false)) return Forbid(); - - if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) - return Forbid(); - - var result = plannedTrajectoryService.GetOrDefaultAsync(idWell,token); + var result = plannedTrajectoryService.GetAsync(idWell, token); return Ok(result); } @@ -142,8 +130,9 @@ namespace AsbCloudWebApi.Controllers /// /// /// - /// + /// количество успешно записанных строк в БД [HttpPost] + [Route("addRow")] [Permission] [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] public async Task AddRowAsync(int idWell, [FromBody] PlannedTrajectoryDto row, @@ -154,7 +143,9 @@ namespace AsbCloudWebApi.Controllers int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); - var result = await plannedTrajectoryService.AddAsync(idWell, idUser.Value, row, token) + row.IdUser = idUser.Value; + row.IdWell = idWell; + var result = await plannedTrajectoryService.AddAsync(row, token) .ConfigureAwait(false); return Ok(result); } @@ -165,11 +156,12 @@ namespace AsbCloudWebApi.Controllers /// /// /// - /// + /// количество успешно записанных строк в БД [HttpPost] + [Route("addRangeRows")] [Permission] - [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] - public async Task AddRowAsync(int idWell, [FromBody] IEnumerable rows, + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task AddRangeRowsAsync(int idWell, [FromBody] IEnumerable rows, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) @@ -177,7 +169,12 @@ namespace AsbCloudWebApi.Controllers int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); - var result = await plannedTrajectoryService.AddRangeAsync(idWell, idUser.Value, rows, token) + foreach (var item in rows) + { + item.IdUser = idUser.Value; + item.IdWell = idWell; + } + var result = await plannedTrajectoryService.AddRangeAsync(rows, token) .ConfigureAwait(false); return Ok(result); } @@ -189,21 +186,23 @@ namespace AsbCloudWebApi.Controllers /// /// /// - /// + /// количество успешно обновленных строк в БД [HttpPut("{idRow}")] [Permission] [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateRowAsync(int idWell, int idRow, [FromBody] PlannedTrajectoryDto row, CancellationToken token = default) - { + { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); - var result = await plannedTrajectoryService.UpdateAsync(idWell, idUser.Value, idRow, row, token) + row.IdUser = idUser.Value; + row.IdWell = idWell; + var result = await plannedTrajectoryService.UpdateAsync(idRow, row, token) .ConfigureAwait(false); - return Ok(result); + return Ok(result); } /// @@ -212,8 +211,8 @@ namespace AsbCloudWebApi.Controllers /// /// /// - /// - [HttpDelete("{idOperation}")] + /// количество успешно удаленных строк из БД + [HttpDelete("{idRow}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task DeleteRowAsync(int idWell, int idRow, CancellationToken token = default) @@ -233,7 +232,7 @@ namespace AsbCloudWebApi.Controllers int? idCompany = User.GetCompanyId(); return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); - } - + } } +#nullable disable }