diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 3b480e2d..3bff8ee2 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -28,6 +28,7 @@ using AsbCloudApp.Services.AutoGeneratedDailyReports; using AsbCloudApp.Services.Notifications; using AsbCloudDb.Model.Manuals; using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports; +using AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment; namespace AsbCloudInfrastructure { @@ -119,6 +120,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -147,6 +149,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/Repository/ProcessMapWellboreDevelopmentRepository.cs b/AsbCloudInfrastructure/Repository/ProcessMapWellboreDevelopmentRepository.cs new file mode 100644 index 00000000..36bb7a0f --- /dev/null +++ b/AsbCloudInfrastructure/Repository/ProcessMapWellboreDevelopmentRepository.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMap; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; + +namespace AsbCloudInfrastructure.Repository; + +public class ProcessMapWellboreDevelopmentRepository : + CrudWellRelatedRepositoryBase, + IProcessMapWellboreDevelopmentRepository +{ + private readonly IWellService wellService; + + public ProcessMapWellboreDevelopmentRepository(IAsbCloudDbContext context, IWellService wellService) : base(context) + { + this.wellService = wellService; + } + + public async Task> GetAllAsync(int idWell, DateTime? updateFrom, + CancellationToken cancellationToken) + { + var query = dbContext.ProcessMapWellboreDevelopments + .Where(p => p.IdWell == idWell); + + if (updateFrom.HasValue) + { + var timezone = wellService.GetTimezone(idWell); + var updateFromUtc = updateFrom.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(p => p.LastUpdate >= updateFromUtc); + } + + var entities = await query + .OrderBy(p => p.DepthStart) + .ThenBy(p => p.Id) + .ToArrayAsync(cancellationToken); + + return entities.Select(Convert); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapWellboreDevelopment/ProcessMapWellboreDevelopmentService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapWellboreDevelopment/ProcessMapWellboreDevelopmentService.cs new file mode 100644 index 00000000..85cc15e0 --- /dev/null +++ b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapWellboreDevelopment/ProcessMapWellboreDevelopmentService.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMap; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; + +namespace AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment; + +public class ProcessMapWellboreDevelopmentService : IProcessMapWellboreDevelopmentService +{ + private readonly ITelemetryService telemetryService; + private readonly IWellService wellService; + private readonly IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository; + + public ProcessMapWellboreDevelopmentService(ITelemetryService telemetryService, + IWellService wellService, + IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository) + { + this.telemetryService = telemetryService; + this.wellService = wellService; + this.processMapWellboreDevelopmentRepository = processMapWellboreDevelopmentRepository; + } + + public async Task InsertAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken) + { + var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken); + + if (well is null) + throw new ArgumentInvalidException($"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует", + nameof(processMapWellboreDevelopment.IdWell)); + + if (processMapWellboreDevelopment.DepthStart > processMapWellboreDevelopment.DepthEnd) + throw new ArgumentInvalidException("Значение стартовой глубины не может превышать конечную глубину", + nameof(processMapWellboreDevelopment.DepthStart)); + + processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow; + + return await processMapWellboreDevelopmentRepository.InsertAsync(processMapWellboreDevelopment, cancellationToken); + } + + public async Task UpdateAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken) + { + var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken); + + if (well is null) + throw new ArgumentInvalidException($"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует", + nameof(processMapWellboreDevelopment.IdWell)); + + if (processMapWellboreDevelopment.DepthStart > processMapWellboreDevelopment.DepthEnd) + throw new ArgumentInvalidException("Значение стартовой глубины не может превышать конечную глубину", + nameof(processMapWellboreDevelopment.DepthStart)); + + processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow; + + var result = await processMapWellboreDevelopmentRepository.UpdateAsync(processMapWellboreDevelopment, cancellationToken); + + if (result == ICrudRepository.ErrorIdNotFound) + throw new ArgumentInvalidException($"Проработки с Id: {processMapWellboreDevelopment.Id} не существует", + nameof(processMapWellboreDevelopment.Id)); + + return result; + } + + public async Task> GetByTelemetryAsync(string uid, DateTime updateFrom, + CancellationToken cancellationToken) + { + var idWell = telemetryService.GetIdWellByTelemetryUid(uid); + + if (!idWell.HasValue) + throw new ArgumentInvalidException($"Неправильный телеметрии. Uid: {uid}", nameof(uid)); + + return await processMapWellboreDevelopmentRepository.GetAllAsync(idWell.Value, updateFrom, cancellationToken); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs b/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs new file mode 100644 index 00000000..5c9945b6 --- /dev/null +++ b/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMap; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Mvc; +using System; + +namespace AsbCloudWebApi.Controllers; + +/// +/// Проработка скважины +/// +public class ProcessMapWellboreDevelopmentController : CrudWellRelatedController +{ + private readonly IUserRepository userRepository; + private readonly IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService; + + public ProcessMapWellboreDevelopmentController(IWellService wellService, + IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository, + IUserRepository userRepository, + IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService) + : base(wellService, processMapWellboreDevelopmentRepository) + { + this.userRepository = userRepository; + this.processMapWellboreDevelopmentService = processMapWellboreDevelopmentService; + } + + /// + /// Добавить запись проработки + /// + /// + /// + /// + /// + public override async Task> InsertAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token) + { + await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, token); + + return await processMapWellboreDevelopmentService.InsertAsync(value, token); + } + + /// + /// Обновить запись проработки + /// + /// + /// + /// + public override async Task> UpdateAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token) + { + await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, token); + + return await processMapWellboreDevelopmentService.UpdateAsync(value, token); + } + + /// + /// Возвращает проработки по uid телеметрии + /// + /// Уникальный ключ телеметрии + /// Необязательный параметр. Начальная дата + /// + /// + [HttpGet("telemetry/{uid}")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetByUidAsync(string uid, DateTime updateFrom, CancellationToken cancellationToken) + { + var dto = await processMapWellboreDevelopmentService.GetByTelemetryAsync(uid, + updateFrom, cancellationToken); + + return Ok(dto); + } + + private async Task AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(int idWell, CancellationToken cancellationToken) + { + var idUser = User.GetUserId(); + + if (!idUser.HasValue) + throw new ForbidException("Неизвестный пользователь"); + + var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) ?? + throw new ForbidException($"Скважины с {idWell} не существует"); + + if (well.IdState == 2 && !userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell")) + throw new ForbidException("Недостаточно прав для редактирования проработки"); + } +} \ No newline at end of file