diff --git a/AsbCloudApp/Data/ScheduleItemDto.cs b/AsbCloudApp/Data/ScheduleItemDto.cs new file mode 100644 index 00000000..1e849452 --- /dev/null +++ b/AsbCloudApp/Data/ScheduleItemDto.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudApp.Data +{ + /// + /// Описание данных графика работ + /// + public class ScheduleDto : IId + { + /// + /// Идентификатор в БД + /// + public int Id { get; set; } + + /// + /// Идентификатор бурильщика + /// + public int IdDriller { get; set; } + + /// + /// Идентификатор скважины + /// + public int IdWell { get; set; } + + /// + /// Начало смены + /// + public DateTimeOffset ShiftStart { get; set; } + + /// + /// Конец смены + /// + public DateTimeOffset ShiftEnd { get; set; } + + /// + /// Начало бурения + /// + public DateTimeOffset DrillStart { get; set; } + + /// + /// Конец бурения + /// + public DateTimeOffset DrillEnd { get; set; } + } +} diff --git a/AsbCloudApp/Services/IDrillerService.cs b/AsbCloudApp/Services/IDrillerService.cs new file mode 100644 index 00000000..505eba3f --- /dev/null +++ b/AsbCloudApp/Services/IDrillerService.cs @@ -0,0 +1,9 @@ +using AsbCloudApp.Data; + +namespace AsbCloudApp.Services +{ + public interface IDrillerService : ICrudService + { + + } +} diff --git a/AsbCloudApp/Services/IScheduleService.cs b/AsbCloudApp/Services/IScheduleService.cs new file mode 100644 index 00000000..e4234ac6 --- /dev/null +++ b/AsbCloudApp/Services/IScheduleService.cs @@ -0,0 +1,13 @@ +using AsbCloudApp.Data; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ + public interface IScheduleService : ICrudService + { + Task> GetSchedule(int idWell,DateTimeOffset dateStart, DateTimeOffset dateEnd, CancellationToken token = default); + } +} diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index 582b86b3..d5066196 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -15,7 +15,6 @@ namespace AsbCloudDb.Model public virtual DbSet DetectedOperations => Set(); public virtual DbSet DrillFlowChart => Set(); public virtual DbSet DrillingProgramParts => Set(); - public virtual DbSet Drillers => Set(); public virtual DbSet DrillParams => Set(); public virtual DbSet FileCategories => Set(); public virtual DbSet Files => Set(); @@ -45,6 +44,8 @@ namespace AsbCloudDb.Model public virtual DbSet WellOperationCategories => Set(); public virtual DbSet WellSectionTypes => Set(); public virtual DbSet WellTypes => Set(); + public virtual DbSet Drillers => Set(); + public virtual DbSet Schedule => Set(); // WITS public DbSet Record1 => Set(); diff --git a/AsbCloudDb/Model/Driller.cs b/AsbCloudDb/Model/Driller.cs index d99ece0a..9d675e8c 100644 --- a/AsbCloudDb/Model/Driller.cs +++ b/AsbCloudDb/Model/Driller.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace AsbCloudDb.Model { [Table("t_driller"), Comment("Бурильщик")] - public class Driller + public class Driller: IId { [Key] [Column("id"),Comment("Идентификатор")] diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index e31c6852..f7f1f128 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -43,6 +43,8 @@ namespace AsbCloudDb.Model DbSet WellOperationCategories { get; } DbSet WellSectionTypes { get; } DbSet WellTypes { get; } + DbSet Drillers { get; } + DbSet Schedule { get; } DbSet Record1 { get; } DbSet Record7 { get; } diff --git a/AsbCloudDb/Model/ScheduleItem.cs b/AsbCloudDb/Model/ScheduleItem.cs new file mode 100644 index 00000000..6e381af5 --- /dev/null +++ b/AsbCloudDb/Model/ScheduleItem.cs @@ -0,0 +1,43 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudDb.Model +{ + [Table("t_schedule"), Comment("График работы бурильщика")] + public class ScheduleItem: IId + { + [Key] + [Column("id"),Comment("Идентификатор")] + public int Id { get; set; } + + [Column("id_driller"), Comment("Идентификатор бурильщика")] + public int IdDriller { get; set; } + + [Column("id_well"), Comment("Идентификатор скважины")] + public int IdWell { get; set; } + + [Column("shift_start"), Comment("Начало смены")] + public DateTimeOffset ShiftStart { get; set; } + + [Column("shift_end"), Comment("Конец смены")] + public DateTimeOffset ShiftEnd { get; set; } + + [Column("drill_start"), Comment("Начало бурение")] + public DateTimeOffset DrillStart { get; set; } + + [Column("drill_end"), Comment("Конец бурения")] + public DateTimeOffset DrillEnd { get; set; } + + [ForeignKey(nameof(IdDriller))] + public virtual Driller Driller { get; set; } + + [ForeignKey(nameof(IdWell))] + public virtual Well well { get; set; } + } +} diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 49b6dce6..629ac726 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -87,6 +87,8 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); // admin crud services: services.AddTransient, CrudServiceBase>(); // может быть включен в сервис TelemetryService diff --git a/AsbCloudInfrastructure/Services/DrillerService.cs b/AsbCloudInfrastructure/Services/DrillerService.cs new file mode 100644 index 00000000..03846c1e --- /dev/null +++ b/AsbCloudInfrastructure/Services/DrillerService.cs @@ -0,0 +1,59 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services +{ + public class DrillerService : CrudCacheServiceBase, IDrillerService + { + + private IAsbCloudDbContext context; + + public DrillerService(IAsbCloudDbContext db, CacheDb cacheDb) : base(db, cacheDb) + { + context= db; + } + + public override async Task DeleteAsync(int id, CancellationToken dto) + { + var result = await Cache.RemoveAsync(o => o.Id == id); + return result; + } + + public override async Task> GetAllAsync(CancellationToken token) + { + return await base.GetAllAsync(token); + } + + public override async Task GetAsync(int id, CancellationToken token) + { + var res= await Cache.FirstOrDefaultAsync(o=>o.Id==id,token) + .ConfigureAwait(false); + if (res is null) + return null; + var dto = Convert(res); + return dto; + } + + public override async Task InsertAsync(DrillerDto dto, CancellationToken token) + { + var entity = Convert(dto); + var result = await Cache.InsertAsync(entity, token); + return result.Id; + } + + public override async Task UpdateAsync(int id, DrillerDto dto, CancellationToken token) + { + var entity = Convert(dto); + var result = await Cache.UpsertAsync(entity, token); + return result; + } + + + } +} diff --git a/AsbCloudInfrastructure/Services/ScheduleService.cs b/AsbCloudInfrastructure/Services/ScheduleService.cs new file mode 100644 index 00000000..d260264a --- /dev/null +++ b/AsbCloudInfrastructure/Services/ScheduleService.cs @@ -0,0 +1,69 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services +{ + public class ScheduleService : CrudCacheServiceBase, IScheduleService + { + + private IAsbCloudDbContext context; + + public ScheduleService(IAsbCloudDbContext db, CacheDb cacheDb) : base(db, cacheDb) + { + context= db; + } + + public override async Task DeleteAsync(int id, CancellationToken dto) + { + var result = await Cache.RemoveAsync(o => o.Id == id); + return result; + } + + public override async Task> GetAllAsync(CancellationToken token) + { + return await base.GetAllAsync(token); + } + + public override async Task GetAsync(int id, CancellationToken token) + { + var res= await Cache.FirstOrDefaultAsync(o=>o.Id==id,token) + .ConfigureAwait(false); + if (res is null) + return null; + var dto = Convert(res); + return dto; + } + + public async Task> GetSchedule(int idWell, DateTimeOffset dateStart, DateTimeOffset dateEnd, CancellationToken token = default) + { + var entires=await Cache.WhereAsync(o=>o.IdWell==idWell + &&o.ShiftStart<=dateStart + &&o.ShiftEnd<=dateEnd).ConfigureAwait(false); + var res = entires?.Select(Convert); + return res; + } + + public override async Task InsertAsync(ScheduleDto dto, CancellationToken token) + { + var entity = Convert(dto); + var result = await Cache.InsertAsync(entity, token); + return result.Id; + } + + public override async Task UpdateAsync(int id, ScheduleDto dto, CancellationToken token) + { + var entity = Convert(dto); + var result = await Cache.UpsertAsync(entity, token); + return result; + } + + + } +} diff --git a/AsbCloudWebApi.Tests/ServicesTests/DrillerServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DrillerServiceTest.cs new file mode 100644 index 00000000..2b5e378d --- /dev/null +++ b/AsbCloudWebApi.Tests/ServicesTests/DrillerServiceTest.cs @@ -0,0 +1,95 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services; +using AsbCloudInfrastructure.Services.Cache; +using Moq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace AsbCloudWebApi.Tests.ServicesTests +{ + public class DrillerServiceTest + { + private readonly AsbCloudDbContext context; + private readonly CacheDb cacheDb; + private DrillerDto drillerObj = new DrillerDto + { + Id = 0, + Name = "Тестовый", + Patronymic = "Тест", + Surname = "Тестович" + }; + + public DrillerServiceTest() + { + context = TestHelpter.MakeTestContext(); + cacheDb = new CacheDb(); + context.SaveChanges(); + } + + ~DrillerServiceTest() + { + } + + [Fact] + public async Task GetListAsync_count() + { + var service = new DrillerService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(drillerObj, CancellationToken.None); + id = await service.InsertAsync(drillerObj, CancellationToken.None); + id = await service.InsertAsync(drillerObj, CancellationToken.None); + + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(newCount, 3); + } + + [Fact] + public async Task InsertAsync_returns_id() + { + var service = new DrillerService(context, cacheDb); + var id = await service.InsertAsync(drillerObj, CancellationToken.None); + Assert.NotEqual(0, id); + } + + [Fact] + public async Task UpdateAsync_not_add_if_exists() + { + var service = new DrillerService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(drillerObj, CancellationToken.None); + var oldCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + + //Обновляем + drillerObj.Id = id; + drillerObj.Name = "Исправлено"; + await service.UpdateAsync(id, drillerObj, CancellationToken.None); + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(newCount, oldCount); + } + + [Fact] + public async Task DeleteAsync_decrement_count() + { + var service = new DrillerService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(drillerObj, CancellationToken.None); + var oldCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + + //Удаляем его + await service.DeleteAsync(id, CancellationToken.None); + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(newCount, oldCount-1); + } + + + } +} diff --git a/AsbCloudWebApi.Tests/ServicesTests/EventServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/EventServiceTest.cs index ff03239e..f82aaff7 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/EventServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/EventServiceTest.cs @@ -8,6 +8,7 @@ using AsbCloudApp.Services; using Moq; using Xunit; using AsbCloudApp.Data.SAUB; +using AsbCloudInfrastructure.Services.SAUB; namespace AsbCloudWebApi.Tests.ServicesTests; diff --git a/AsbCloudWebApi.Tests/ServicesTests/ScheduleServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/ScheduleServiceTest.cs new file mode 100644 index 00000000..d9122da8 --- /dev/null +++ b/AsbCloudWebApi.Tests/ServicesTests/ScheduleServiceTest.cs @@ -0,0 +1,95 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services; +using AsbCloudInfrastructure.Services.Cache; +using Moq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace AsbCloudWebApi.Tests.ServicesTests +{ + public class ScheduleServiceTest + { + private readonly AsbCloudDbContext context; + private readonly CacheDb cacheDb; + private ScheduleDto entity = new ScheduleDto + { + ShiftStart = DateTime.Parse("2022-05-16T10:00:00"), + ShiftEnd = DateTime.Parse("2022-05-16T18:00:00"), + DrillStart = DateTime.Parse("2022-05-16T10:00:00"), + DrillEnd = DateTime.Parse("2022-05-16T18:00:00") + }; + + public ScheduleServiceTest() + { + context = TestHelpter.MakeTestContext(); + cacheDb = new CacheDb(); + context.SaveChanges(); + } + + ~ScheduleServiceTest() + { + } + + [Fact] + public async Task GetListAsync_count() + { + var service = new ScheduleService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(entity, CancellationToken.None); + id = await service.InsertAsync(entity, CancellationToken.None); + id = await service.InsertAsync(entity, CancellationToken.None); + + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(3, newCount); + } + + [Fact] + public async Task InsertAsync_returns_id() + { + var service = new ScheduleService(context, cacheDb); + var id = await service.InsertAsync(entity, CancellationToken.None); + Assert.NotEqual(0, id); + } + + [Fact] + public async Task UpdateAsync_not_add_if_exists() + { + var service = new ScheduleService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(entity, CancellationToken.None); + var oldCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + + //Обновляем + entity.Id = id; + entity.DrillEnd = entity.DrillEnd.AddHours(-3); + await service.UpdateAsync(id, entity, CancellationToken.None); + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(newCount, oldCount); + } + + [Fact] + public async Task DeleteAsync_decrement_count() + { + var service = new ScheduleService(context, cacheDb); + + ///Добавляем элемент + var id = await service.InsertAsync(entity, CancellationToken.None); + var oldCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + + //Удаляем его + await service.DeleteAsync(id, CancellationToken.None); + var newCount = (await service.GetAllAsync(CancellationToken.None)).Count(); + Assert.Equal(newCount, oldCount-1); + } + + + } +} diff --git a/AsbCloudWebApi/Controllers/AdminDrillerController.cs b/AsbCloudWebApi/Controllers/AdminDrillerController.cs new file mode 100644 index 00000000..b31ddd27 --- /dev/null +++ b/AsbCloudWebApi/Controllers/AdminDrillerController.cs @@ -0,0 +1,91 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Controllers +{ + [Route("api/admin/driller")] + [ApiController] + [Authorize] + public class AdminDrillerController : ControllerBase + { + private readonly IDrillerService drillerService; + public AdminDrillerController(IDrillerService drillerService) + { + this.drillerService = drillerService; + } + + /// + ///Добавить бурильщика + /// + /// Объект, описывающий бурильщика + /// + /// Идентификатор добавленого бурильщика + [HttpPost] + public async Task> InsertAsync([FromBody] DrillerDto value, CancellationToken token = default) + { + var result = await drillerService.InsertAsync(value, token).ConfigureAwait(false); + return Ok(result); + } + + /// + /// Получить весь список бурильщиков + /// + /// + /// Список бурильщиков + [HttpGet] + public async Task> GetAllAsync(CancellationToken token = default) + { + var result = await drillerService.GetAllAsync(token); + return Ok(result); + } + + /// + /// Получить бурильщика по идентификатору + /// + /// Идентификатор + /// + /// Объект, описывающий бурильщика + [HttpGet("{DrillerId}")] + public async Task GetAsync(int DrillerId, CancellationToken token = default) + { + var driller = await drillerService.GetAsync(DrillerId, token) + .ConfigureAwait(false); + return Ok(driller); + } + + /// + /// Обновить данные о бурильщике + /// + /// Идентификатор + /// Объект с измененными данными + /// + /// Количество измененых записей + [HttpPut("{DrillerId}")] + public async Task UpdateAsync(int DrillerId, DrillerDto dto, + CancellationToken token = default) + { + var result = await drillerService.UpdateAsync(DrillerId, dto, token) + .ConfigureAwait(false); + return Ok(result); + + } + + /// + /// Удалить бурильщика + /// + /// Идентификатор бурильщика + /// + /// Количество удаленных записей + [HttpDelete("{DrillerId}")] + public async Task> DeleteAsync(int DrillerId, CancellationToken token = default) + { + var result = await drillerService.DeleteAsync(DrillerId, token) + .ConfigureAwait(false); + return Ok(result); + } + } +} diff --git a/AsbCloudWebApi/Controllers/AdminScheduleController.cs b/AsbCloudWebApi/Controllers/AdminScheduleController.cs new file mode 100644 index 00000000..05f9db7b --- /dev/null +++ b/AsbCloudWebApi/Controllers/AdminScheduleController.cs @@ -0,0 +1,93 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Controllers +{ + [Route("api/admin/schedule")] + [ApiController] + [Authorize] + public class AdminScheduleController : ControllerBase + { + private readonly IScheduleService scheduleService; + public AdminScheduleController(IScheduleService service) + { + this.scheduleService = service; + } + + /// + /// Добавить запись графика работы + /// + /// Объект-запись + /// + /// Идентификатор добавленой записи + [HttpPost] + public async Task> InsertAsync([FromBody] ScheduleDto value, CancellationToken token = default) + { + var result = await scheduleService.InsertAsync(value, token).ConfigureAwait(false); + return Ok(result); + } + + /// + /// Получить все записи графика + /// + /// + /// Список записей графика + [HttpGet("all")] + public async Task> GetAllAsync(CancellationToken token = default) + { + var result = await scheduleService.GetAllAsync(token); + return Ok(result); + } + + /// + /// Получить список записей графика для конкретной скважины + /// + /// Идентификатор скважины + /// Начало периода + /// Конец периода + /// + /// Список записей графика + [HttpGet] + public async Task> GetScheduleAsync(int idWell, DateTimeOffset dateStart, DateTimeOffset dateEnd, CancellationToken token = default) + { + var result = await scheduleService.GetSchedule(idWell,dateStart,dateEnd, token); + return Ok(result); + } + + /// + /// Обновить график + /// + /// Идентификатор записи + /// Элемент графика + /// + /// Количнство обновленных записей + [HttpPut("{ScheduleId}")] + public async Task UpdateAsync(int ScheduleId, ScheduleDto dto, + CancellationToken token = default) + { + var result = await scheduleService.UpdateAsync(ScheduleId, dto, token) + .ConfigureAwait(false); + return Ok(result); + + } + + /// + /// Удалить запись из графика + /// + /// Идентификатор записи + /// + /// + [HttpDelete("{ScheduleId}")] + public async Task> DeleteAsync(int ScheduleId, CancellationToken token = default) + { + var result = await scheduleService.DeleteAsync(ScheduleId, token) + .ConfigureAwait(false); + return Ok(result); + } + } +}