diff --git a/AsbCloudApp/Data/DailyReport/BhaDto.cs b/AsbCloudApp/Data/DailyReport/BhaDto.cs index 43d5e45f..b39ba11c 100644 --- a/AsbCloudApp/Data/DailyReport/BhaDto.cs +++ b/AsbCloudApp/Data/DailyReport/BhaDto.cs @@ -3,8 +3,8 @@ /// /// блок КНБК /// - public class BhaDto - { + public class BhaDto : ItemInfoDto + { /// /// КНБК описание /// diff --git a/AsbCloudApp/Data/DailyReport/HeadDto.cs b/AsbCloudApp/Data/DailyReport/HeadDto.cs index 400d8211..e32dd63c 100644 --- a/AsbCloudApp/Data/DailyReport/HeadDto.cs +++ b/AsbCloudApp/Data/DailyReport/HeadDto.cs @@ -4,8 +4,8 @@ namespace AsbCloudApp.Data.DailyReport /// /// блок заголовка /// - public class HeadDto - { + public class HeadDto : ItemInfoDto + { /// /// название скважины /// diff --git a/AsbCloudApp/Data/DailyReport/ItemInfoDto.cs b/AsbCloudApp/Data/DailyReport/ItemInfoDto.cs new file mode 100644 index 00000000..ac27a385 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/ItemInfoDto.cs @@ -0,0 +1,25 @@ +using System; + +namespace AsbCloudApp.Data.DailyReport +{ + /// + /// хранение дополнительной информации о записи + /// + public class ItemInfoDto + { + /// + /// пользователь, внесший изменения + /// + public int? IdUser { get; set; } + + /// + /// имя пользователя, внесшего изменения + /// + public string? UserName { get; set; } + + /// + /// дата последнего обновления + /// + public DateTimeOffset? LastUpdateDate { get; set; } + } +} diff --git a/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs b/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs index 55f34e1c..ff08eb2f 100644 --- a/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs +++ b/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs @@ -3,7 +3,7 @@ /// /// блок безметражные работы /// - public class NoDrillingDto + public class NoDrillingDto : ItemInfoDto { /// /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию diff --git a/AsbCloudApp/Data/DailyReport/OperationStatDto.cs b/AsbCloudApp/Data/DailyReport/OperationStatDto.cs new file mode 100644 index 00000000..03a84801 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/OperationStatDto.cs @@ -0,0 +1,13 @@ +namespace AsbCloudApp.Data.DailyReport +{ + /// + /// Статистика по операции + /// + public class OperationStatDto + { + /// + /// Глубина забоя + /// + public double Depth { get; set; } + } +} diff --git a/AsbCloudApp/Data/DailyReport/SaubDto.cs b/AsbCloudApp/Data/DailyReport/SaubDto.cs index 00a86398..b59ef9ff 100644 --- a/AsbCloudApp/Data/DailyReport/SaubDto.cs +++ b/AsbCloudApp/Data/DailyReport/SaubDto.cs @@ -5,7 +5,7 @@ namespace AsbCloudApp.Data.DailyReport /// /// блок САУБ /// - public class SaubDto + public class SaubDto : ItemInfoDto { /// /// Режимы бурения в роторе diff --git a/AsbCloudApp/Data/DailyReport/SignDto.cs b/AsbCloudApp/Data/DailyReport/SignDto.cs index fe0a6e67..f6726bb7 100644 --- a/AsbCloudApp/Data/DailyReport/SignDto.cs +++ b/AsbCloudApp/Data/DailyReport/SignDto.cs @@ -3,8 +3,8 @@ /// /// блок подписи /// - public class SignDto - { + public class SignDto : ItemInfoDto + { /// /// ФИО Мастера буровой /// diff --git a/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs b/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs index 061f2ab6..55db7850 100644 --- a/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs +++ b/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs @@ -1,119 +1,17 @@ -namespace AsbCloudApp.Data.DailyReport +using System.Collections.Generic; + +namespace AsbCloudApp.Data.DailyReport { - /// - /// блок баланса времени - /// - public class TimeBalanceDto - { - /// - /// Бурение - /// - public string Drilling { get; set; } = string.Empty; - - /// - /// Промывка - /// - public string Flushing { get; set; } = string.Empty; + /// + /// Блок баланса времени + /// + public class TimeBalanceDto : ItemInfoDto + { /// - /// Наращивание + /// Статистика по операциям /// - public string Building { get; set; } = string.Empty; - - /// - /// Проработка - /// - public string Elaboration { get; set; } = string.Empty; - - /// - /// Расширка - /// - public string Extension { get; set; } = string.Empty; - - /// - /// Ремонт - /// - public string Repair { get; set; } = string.Empty; - - /// - /// КНБК - /// - public string Knbk { get; set; } = string.Empty; - - /// - /// СПО - /// - public string Spo { get; set; } = string.Empty; - - /// - /// ПЗР - /// - public string Pzr { get; set; } = string.Empty; - - /// - /// ПВО - /// - public string Pvo { get; set; } = string.Empty; - - /// - /// ПГР - /// - public string Pgr { get; set; } = string.Empty; - - /// - /// ГИС - /// - public string Gis { get; set; } = string.Empty; - - /// - /// ОЗЦ - /// - public string Ozc { get; set; } = string.Empty; - - /// - /// Тех. работы - /// - public string EngineeringWorks { get; set; } = string.Empty; - - /// - /// Снятие замера - /// - public string TakingMeasure { get; set; } = string.Empty; - - /// - /// Цементирование - /// - public string Cementing { get; set; } = string.Empty; - - /// - /// Простой - /// - public string Simple { get; set; } = string.Empty; - - /// - /// НПВ - /// - public string Npv { get; set; } = string.Empty; - - /// - /// Проработка перед наращиванием - /// - public string ElaborationBeforeBuilding { get; set; } = string.Empty; - - /// - /// Шаблонировка перед наращиванием - /// - public string TemplatingBeforeBuilding { get; set; } = string.Empty; - - /// - /// Промывка перед наращиванием - /// - public string FlushingBeforeBuilding { get; set; } = string.Empty; - - /// - /// Статический замер телесистемы - /// - public string StaticSurveying { get; set; } = string.Empty; + public IEnumerable? OperationsStat { get; set; } } } diff --git a/AsbCloudApp/Services/IDailyReportService.cs b/AsbCloudApp/Services/IDailyReportService.cs index 7d5d29f9..3943e86c 100644 --- a/AsbCloudApp/Services/IDailyReportService.cs +++ b/AsbCloudApp/Services/IDailyReportService.cs @@ -22,23 +22,15 @@ namespace AsbCloudApp.Services /// Task> GetListAsync(int idWell, DateTime? v1, DateTime? v2, CancellationToken cancellationToken); - /// - /// получить из БД или генерировать данные для суточного рапорта за указанную дату - /// - /// - /// - /// - /// - Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token); - /// /// Добавить новый рапорт /// /// /// + /// /// /// - Task AddAsync(int idWell, DateTime startDate, CancellationToken token = default); + Task AddAsync(int idWell, DateTime startDate, int idUser, CancellationToken token = default); /// /// изменить данные для суточного рапорта @@ -62,12 +54,11 @@ namespace AsbCloudApp.Services /// /// изменить блок данных для суточного рапорта /// - /// /// - /// + /// /// /// /// - Task UpdateBlockAsync(int idWell, DateTime date, Tdto dto, CancellationToken token); + Task UpdateBlockAsync(int idWell, DateTime startDate, ItemInfoDto dto, CancellationToken token); } } diff --git a/AsbCloudDb/Model/DailyReport/Bha.cs b/AsbCloudDb/Model/DailyReport/Bha.cs index 92c5c9b8..b1765c19 100644 --- a/AsbCloudDb/Model/DailyReport/Bha.cs +++ b/AsbCloudDb/Model/DailyReport/Bha.cs @@ -1,6 +1,6 @@ namespace AsbCloudDb.Model.DailyReport { - public class Bha + public class Bha : ItemInfo { /// /// КНБК описание diff --git a/AsbCloudDb/Model/DailyReport/Head.cs b/AsbCloudDb/Model/DailyReport/Head.cs index 16ef0fc1..42f6f857 100644 --- a/AsbCloudDb/Model/DailyReport/Head.cs +++ b/AsbCloudDb/Model/DailyReport/Head.cs @@ -1,7 +1,7 @@ using System; namespace AsbCloudDb.Model.DailyReport { - public class Head + public class Head : ItemInfo { /// /// название скважины diff --git a/AsbCloudDb/Model/DailyReport/ItemInfo.cs b/AsbCloudDb/Model/DailyReport/ItemInfo.cs new file mode 100644 index 00000000..bf579080 --- /dev/null +++ b/AsbCloudDb/Model/DailyReport/ItemInfo.cs @@ -0,0 +1,17 @@ +using System; + +namespace AsbCloudDb.Model +{ + public class ItemInfo + { + /// + /// пользователь, внесший изменения + /// + public int? IdUser { get; set; } + + /// + /// дата последнего обновления блока + /// + public DateTimeOffset? LastUpdateDate { get; set; } + } +} diff --git a/AsbCloudDb/Model/DailyReport/NoDrilling.cs b/AsbCloudDb/Model/DailyReport/NoDrilling.cs index ef203694..c1a3b604 100644 --- a/AsbCloudDb/Model/DailyReport/NoDrilling.cs +++ b/AsbCloudDb/Model/DailyReport/NoDrilling.cs @@ -1,6 +1,6 @@ namespace AsbCloudDb.Model.DailyReport { - public class NoDrilling + public class NoDrilling : ItemInfo { /// /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию diff --git a/AsbCloudDb/Model/DailyReport/Saub.cs b/AsbCloudDb/Model/DailyReport/Saub.cs index 7399f148..43202677 100644 --- a/AsbCloudDb/Model/DailyReport/Saub.cs +++ b/AsbCloudDb/Model/DailyReport/Saub.cs @@ -1,8 +1,6 @@ -using System.Collections.Generic; - -namespace AsbCloudDb.Model.DailyReport +namespace AsbCloudDb.Model.DailyReport { - public class Saub + public class Saub : ItemInfo { /// /// Режимы бурения в роторе @@ -98,7 +96,6 @@ namespace AsbCloudDb.Model.DailyReport /// МСП /// public string MspSection { get; set; } = string.Empty; - } } diff --git a/AsbCloudDb/Model/DailyReport/Sign.cs b/AsbCloudDb/Model/DailyReport/Sign.cs index 78271fe9..1b443348 100644 --- a/AsbCloudDb/Model/DailyReport/Sign.cs +++ b/AsbCloudDb/Model/DailyReport/Sign.cs @@ -1,6 +1,6 @@ namespace AsbCloudDb.Model.DailyReport { - public class Sign + public class Sign : ItemInfo { /// /// ФИО Мастера буровой diff --git a/AsbCloudDb/Model/DailyReport/TimeBalance.cs b/AsbCloudDb/Model/DailyReport/TimeBalance.cs index ee8c19f7..db9a9ffc 100644 --- a/AsbCloudDb/Model/DailyReport/TimeBalance.cs +++ b/AsbCloudDb/Model/DailyReport/TimeBalance.cs @@ -1,6 +1,6 @@ namespace AsbCloudDb.Model.DailyReport { - public class TimeBalance + public class TimeBalance : ItemInfo { /// /// Бурение diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index 2fdae738..fa012334 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -1,5 +1,8 @@ -using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DailyReport; using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudDb.Model.DailyReport; @@ -18,13 +21,22 @@ namespace AsbCloudInfrastructure.Services.DailyReport public class DailyReportService : IDailyReportService { private readonly IAsbCloudDbContext db; + private readonly IUserRepository userRepository; + private readonly IWellOperationRepository wellOperationRepository; private readonly IWellService wellService; private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel(); - public DailyReportService(IAsbCloudDbContext db, IWellService wellService) + public DailyReportService( + IAsbCloudDbContext db, + IWellService wellService, + IUserRepository userRepository, + IWellOperationRepository wellOperationRepository) { this.db = db; this.wellService = wellService; + this.userRepository = userRepository; + this.wellOperationRepository = wellOperationRepository; + } public async Task> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token) @@ -54,21 +66,58 @@ namespace AsbCloudInfrastructure.Services.DailyReport query = query.Where(d => d.StartDate <= endDateOnly); } - var entities = await query - .OrderByDescending(e => e.StartDate) - .ToListAsync(token); - return entities.Select(r => Convert(r)); + var entities = await query.OrderByDescending(e => e.StartDate).ToListAsync(token); + + var request = new WellOperationRequest() + { + IdWell = idWell, + OperationType = WellOperation.IdOperationTypeFact, + }; + + var factOperations = await wellOperationRepository.GetAsync(request, token); + + var dtos = entities.Select(Convert); + var result = await Task.WhenAll(dtos.Select(i => BindDataToDtoAsync(i, factOperations, token))); + return result; } - public async Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) + /// + /// Заполнение DTO-модели необходимыми данными + /// + /// + /// + /// + /// + private async Task BindDataToDtoAsync(DailyReportDto dto, IEnumerable factOperations, CancellationToken token) { - var dateOnly = DateTime.SpecifyKind(date.Date, DateTimeKind.Utc); - var dailyReportDto = await GetOrDefaultAsync(idWell, dateOnly, token); - dailyReportDto ??= await MakeDefaultDailyReportAsync(idWell, dateOnly, token); - return dailyReportDto; + var blocks = new ItemInfoDto[] { + dto.Head, + dto.Bha, + dto.NoDrilling, + dto.Saub, + dto.Sign, + dto.TimeBalance + }; + + foreach (var block in blocks) + { + if (block.IdUser is not null) + { + var userDto = await userRepository.GetOrDefaultAsync(block.IdUser.Value, token); + if (userDto is not null) + block.UserName = string.Format("{0} {1} {2}", userDto.Surname, userDto.Name, userDto.Patronymic); + } + } + + dto.TimeBalance.OperationsStat = (factOperations + .Where(o => DateOnly.FromDateTime(o.DateStart) == dto.StartDate) + .GroupBy(o => o.IdCategory) + .Select(g => new OperationStatDto() { Depth = g.Sum(o => o.DepthEnd - o.DepthStart) })); + + return dto; } - public async Task AddAsync(int idWell, DateTime startDate, CancellationToken token = default) + public async Task AddAsync(int idWell, DateTime startDate, int idUser, CancellationToken token = default) { var well = wellService.GetOrDefault(idWell); if (well is null || well.Timezone is null) @@ -97,6 +146,8 @@ namespace AsbCloudInfrastructure.Services.DailyReport ClusterName = well?.Cluster ?? String.Empty, Customer = customer?.Caption ?? String.Empty, Contractor = contractor?.Caption ?? String.Empty, + IdUser = idUser, + LastUpdateDate = DateTimeOffset.Now, } } }; @@ -123,14 +174,15 @@ namespace AsbCloudInfrastructure.Services.DailyReport return result; } - public async Task UpdateBlockAsync(int idWell, DateTime date, Tdto dto, CancellationToken token) + public async Task UpdateBlockAsync(int idWell, DateTime startDate, ItemInfoDto dto, CancellationToken token) { - var startDateOnly = DateOnly.FromDateTime(date); + var startDateOnly = DateOnly.FromDateTime(startDate); var entity = await db.DailyReports.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == startDateOnly, token); if (entity is null) return 0; + dto.LastUpdateDate = DateTimeOffset.Now; if (dto is HeadDto headDto) entity.Info.Head = headDto.Adapt(); if (dto is BhaDto bhaDto) @@ -174,39 +226,6 @@ namespace AsbCloudInfrastructure.Services.DailyReport return dto; } - private async Task MakeDefaultDailyReportAsync(int idWell, DateTime date, CancellationToken token) - { - var well = await wellService.GetOrDefaultAsync(idWell, token); - - var dto = new DailyReportDto() - { - Head = new HeadDto() - { - ReportDate = date.Date, - WellName = well?.Caption ?? "", - ClusterName = well?.Cluster ?? "", - }, - Bha = await GetPrevOrNewBhaAsync(idWell, date, token) - }; - return dto; - } - - private async Task GetPrevOrNewBhaAsync(int idWell, DateTime date, CancellationToken token) - { - var dateOffset = date.Date; - var entity = await db.DailyReports - .Where(x => x.IdWell == idWell) - .OrderByDescending(x => x.StartDate) - .FirstOrDefaultAsync(r => r.StartDate.Year <= dateOffset.Year && - r.StartDate.DayOfYear <= dateOffset.DayOfYear, token); - - if (entity is null) - return new BhaDto(); - - var dto = Convert(entity); - return dto.Bha; - } - private static DailyReportDto Convert(AsbCloudDb.Model.DailyReport.DailyReport entity) { var dto = entity.Info.Adapt(); diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index ae6868a1..11b5c17a 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Repositories; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -20,11 +21,16 @@ namespace AsbCloudWebApi.Controllers { private readonly IDailyReportService dailyReportService; private readonly IWellService wellService; + private readonly IWellOperationRepository operationRepository; - public DailyReportController(IDailyReportService dailyReportService, IWellService wellService) + public DailyReportController( + IDailyReportService dailyReportService, + IWellService wellService, + IWellOperationRepository operationRepository) { this.dailyReportService = dailyReportService; this.wellService = wellService; + this.operationRepository = operationRepository; } /// @@ -44,22 +50,6 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } - /// - /// Получить из БД или генерировать набор данных для формирования рапорта на новую дату. - /// - /// - /// - /// - /// - [HttpGet("{date}")] - //[Permission] - [ProducesResponseType(typeof(DailyReportDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetOrGenerateAsync(int idWell, [Required] DateTime date, CancellationToken token = default) - { - var dto = await dailyReportService.GetOrGenerateAsync(idWell, date, token); - return Ok(dto); - } - /// /// Создание суточного рапорта /// @@ -72,9 +62,13 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task AddAsync(int idWell, [Required] DateTime startDate, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + try { - var result = await dailyReportService.AddAsync(idWell, startDate, token); + var result = await dailyReportService.AddAsync(idWell, startDate, (int)idUser, token); return Ok(result); } catch (Exception ex) @@ -97,6 +91,11 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateHeadAsync(int idWell, [Required] DateTime date, [Required] HeadDto dto, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + + dto.IdUser = idUser; var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); return Ok(result); } @@ -113,6 +112,11 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateBhaAsync(int idWell, [Required] DateTime date, [Required] BhaDto dto, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + + dto.IdUser = idUser; var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); return Ok(result); } @@ -129,25 +133,15 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateNoDrillingAsync(int idWell, [Required] DateTime date, [Required] NoDrillingDto dto, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + + dto.IdUser = idUser; var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); return Ok(result); } - /// - /// Сохранение изменений набора данных для формирования рапорта (баланс времени) - /// - /// - /// - /// - /// - /// - [HttpPut("{date}/timeBalance")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task UpdateTimeBalanceAsync(int idWell, [Required] DateTime date, [Required] TimeBalanceDto dto, CancellationToken token = default) - { - var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); - return Ok(result); - } /// /// Сохранение изменений набора данных для формирования рапорта (САУБ) @@ -161,6 +155,11 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateSaubAsync(int idWell, [Required] DateTime date, [Required] SaubDto dto, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + + dto.IdUser = idUser; var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); return Ok(result); } @@ -177,6 +176,11 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateSignAsync(int idWell, [Required] DateTime date, [Required] SignDto dto, CancellationToken token = default) { + var idUser = User.GetUserId(); + if (idUser is null) + return Forbid(); + + dto.IdUser = idUser; var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); return Ok(result); }