Добавление бурильщика и графика работы. Покрытие тестами.

This commit is contained in:
Lyudmila Romanova 2022-05-22 21:18:43 +05:00
parent 192cf8e5b9
commit 7bc977ada6
15 changed files with 624 additions and 2 deletions

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsbCloudApp.Data
{
/// <summary>
/// Описание данных графика работ
/// </summary>
public class ScheduleDto : IId
{
/// <summary>
/// Идентификатор в БД
/// </summary>
public int Id { get; set; }
/// <summary>
/// Идентификатор бурильщика
/// </summary>
public int IdDriller { get; set; }
/// <summary>
/// Идентификатор скважины
/// </summary>
public int IdWell { get; set; }
/// <summary>
/// Начало смены
/// </summary>
public DateTimeOffset ShiftStart { get; set; }
/// <summary>
/// Конец смены
/// </summary>
public DateTimeOffset ShiftEnd { get; set; }
/// <summary>
/// Начало бурения
/// </summary>
public DateTimeOffset DrillStart { get; set; }
/// <summary>
/// Конец бурения
/// </summary>
public DateTimeOffset DrillEnd { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using AsbCloudApp.Data;
namespace AsbCloudApp.Services
{
public interface IDrillerService : ICrudService<DrillerDto>
{
}
}

View File

@ -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<ScheduleDto>
{
Task<IEnumerable<ScheduleDto>> GetSchedule(int idWell,DateTimeOffset dateStart, DateTimeOffset dateEnd, CancellationToken token = default);
}
}

View File

@ -15,7 +15,6 @@ namespace AsbCloudDb.Model
public virtual DbSet<DetectedOperation> DetectedOperations => Set<DetectedOperation>();
public virtual DbSet<DrillFlowChart> DrillFlowChart => Set<DrillFlowChart>();
public virtual DbSet<DrillingProgramPart> DrillingProgramParts => Set<DrillingProgramPart>();
public virtual DbSet<Driller> Drillers => Set<Driller>();
public virtual DbSet<DrillParams> DrillParams => Set<DrillParams>();
public virtual DbSet<FileCategory> FileCategories => Set<FileCategory>();
public virtual DbSet<FileInfo> Files => Set<FileInfo>();
@ -45,6 +44,8 @@ namespace AsbCloudDb.Model
public virtual DbSet<WellOperationCategory> WellOperationCategories => Set<WellOperationCategory>();
public virtual DbSet<WellSectionType> WellSectionTypes => Set<WellSectionType>();
public virtual DbSet<WellType> WellTypes => Set<WellType>();
public virtual DbSet<Driller> Drillers => Set<Driller>();
public virtual DbSet<ScheduleItem> Schedule => Set<ScheduleItem>();
// WITS
public DbSet<WITS.Record1> Record1 => Set<WITS.Record1>();

View File

@ -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("Идентификатор")]

View File

@ -43,6 +43,8 @@ namespace AsbCloudDb.Model
DbSet<WellOperationCategory> WellOperationCategories { get; }
DbSet<WellSectionType> WellSectionTypes { get; }
DbSet<WellType> WellTypes { get; }
DbSet<Driller> Drillers { get; }
DbSet<ScheduleItem> Schedule { get; }
DbSet<Record1> Record1 { get; }
DbSet<Record7> Record7 { get; }

View File

@ -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; }
}
}

View File

@ -87,6 +87,8 @@ namespace AsbCloudInfrastructure
services.AddTransient<IScheduleReportService, ScheduleReportService>();
services.AddTransient<IDailyReportService, DailyReportService>();
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
services.AddTransient<IDrillerService, DrillerService>();
services.AddTransient<IScheduleService, ScheduleService>();
// admin crud services:
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>(); // может быть включен в сервис TelemetryService

View File

@ -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<DrillerDto, Driller>, IDrillerService
{
private IAsbCloudDbContext context;
public DrillerService(IAsbCloudDbContext db, CacheDb cacheDb) : base(db, cacheDb)
{
context= db;
}
public override async Task<int> DeleteAsync(int id, CancellationToken dto)
{
var result = await Cache.RemoveAsync(o => o.Id == id);
return result;
}
public override async Task<IEnumerable<DrillerDto>> GetAllAsync(CancellationToken token)
{
return await base.GetAllAsync(token);
}
public override async Task<DrillerDto> 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<int> InsertAsync(DrillerDto dto, CancellationToken token)
{
var entity = Convert(dto);
var result = await Cache.InsertAsync(entity, token);
return result.Id;
}
public override async Task<int> UpdateAsync(int id, DrillerDto dto, CancellationToken token)
{
var entity = Convert(dto);
var result = await Cache.UpsertAsync(entity, token);
return result;
}
}
}

View File

@ -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<ScheduleDto, ScheduleItem>, IScheduleService
{
private IAsbCloudDbContext context;
public ScheduleService(IAsbCloudDbContext db, CacheDb cacheDb) : base(db, cacheDb)
{
context= db;
}
public override async Task<int> DeleteAsync(int id, CancellationToken dto)
{
var result = await Cache.RemoveAsync(o => o.Id == id);
return result;
}
public override async Task<IEnumerable<ScheduleDto>> GetAllAsync(CancellationToken token)
{
return await base.GetAllAsync(token);
}
public override async Task<ScheduleDto> 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<IEnumerable<ScheduleDto>> 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<int> InsertAsync(ScheduleDto dto, CancellationToken token)
{
var entity = Convert(dto);
var result = await Cache.InsertAsync(entity, token);
return result.Id;
}
public override async Task<int> UpdateAsync(int id, ScheduleDto dto, CancellationToken token)
{
var entity = Convert(dto);
var result = await Cache.UpsertAsync(entity, token);
return result;
}
}
}

View File

@ -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);
}
}
}

View File

@ -8,6 +8,7 @@ using AsbCloudApp.Services;
using Moq;
using Xunit;
using AsbCloudApp.Data.SAUB;
using AsbCloudInfrastructure.Services.SAUB;
namespace AsbCloudWebApi.Tests.ServicesTests;

View File

@ -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);
}
}
}

View File

@ -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;
}
/// <summary>
///Добавить бурильщика
/// </summary>
/// <param name="value">Объект, описывающий бурильщика</param>
/// <param name="token"></param>
/// <returns>Идентификатор добавленого бурильщика</returns>
[HttpPost]
public async Task<ActionResult<int>> InsertAsync([FromBody] DrillerDto value, CancellationToken token = default)
{
var result = await drillerService.InsertAsync(value, token).ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Получить весь список бурильщиков
/// </summary>
/// <param name="token"></param>
/// <returns>Список бурильщиков</returns>
[HttpGet]
public async Task<ActionResult<int>> GetAllAsync(CancellationToken token = default)
{
var result = await drillerService.GetAllAsync(token);
return Ok(result);
}
/// <summary>
/// Получить бурильщика по идентификатору
/// </summary>
/// <param name="DrillerId">Идентификатор</param>
/// <param name="token"></param>
/// <returns>Объект, описывающий бурильщика</returns>
[HttpGet("{DrillerId}")]
public async Task<IActionResult> GetAsync(int DrillerId, CancellationToken token = default)
{
var driller = await drillerService.GetAsync(DrillerId, token)
.ConfigureAwait(false);
return Ok(driller);
}
/// <summary>
/// Обновить данные о бурильщике
/// </summary>
/// <param name="DrillerId">Идентификатор</param>
/// <param name="dto">Объект с измененными данными</param>
/// <param name="token"></param>
/// <returns>Количество измененых записей</returns>
[HttpPut("{DrillerId}")]
public async Task<IActionResult> UpdateAsync(int DrillerId, DrillerDto dto,
CancellationToken token = default)
{
var result = await drillerService.UpdateAsync(DrillerId, dto, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Удалить бурильщика
/// </summary>
/// <param name="DrillerId">Идентификатор бурильщика</param>
/// <param name="token"></param>
/// <returns>Количество удаленных записей</returns>
[HttpDelete("{DrillerId}")]
public async Task<ActionResult<int>> DeleteAsync(int DrillerId, CancellationToken token = default)
{
var result = await drillerService.DeleteAsync(DrillerId, token)
.ConfigureAwait(false);
return Ok(result);
}
}
}

View File

@ -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;
}
/// <summary>
/// Добавить запись графика работы
/// </summary>
/// <param name="value">Объект-запись</param>
/// <param name="token"></param>
/// <returns>Идентификатор добавленой записи</returns>
[HttpPost]
public async Task<ActionResult<int>> InsertAsync([FromBody] ScheduleDto value, CancellationToken token = default)
{
var result = await scheduleService.InsertAsync(value, token).ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Получить все записи графика
/// </summary>
/// <param name="token"></param>
/// <returns>Список записей графика</returns>
[HttpGet("all")]
public async Task<ActionResult<int>> GetAllAsync(CancellationToken token = default)
{
var result = await scheduleService.GetAllAsync(token);
return Ok(result);
}
/// <summary>
/// Получить список записей графика для конкретной скважины
/// </summary>
/// <param name="idWell">Идентификатор скважины</param>
/// <param name="dateStart">Начало периода</param>
/// <param name="dateEnd">Конец периода</param>
/// <param name="token"></param>
/// <returns>Список записей графика</returns>
[HttpGet]
public async Task<ActionResult<int>> GetScheduleAsync(int idWell, DateTimeOffset dateStart, DateTimeOffset dateEnd, CancellationToken token = default)
{
var result = await scheduleService.GetSchedule(idWell,dateStart,dateEnd, token);
return Ok(result);
}
/// <summary>
/// Обновить график
/// </summary>
/// <param name="ScheduleId">Идентификатор записи</param>
/// <param name="dto">Элемент графика</param>
/// <param name="token"></param>
/// <returns>Количнство обновленных записей</returns>
[HttpPut("{ScheduleId}")]
public async Task<IActionResult> UpdateAsync(int ScheduleId, ScheduleDto dto,
CancellationToken token = default)
{
var result = await scheduleService.UpdateAsync(ScheduleId, dto, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Удалить запись из графика
/// </summary>
/// <param name="ScheduleId">Идентификатор записи</param>
/// <param name="token"></param>
/// <returns></returns>
[HttpDelete("{ScheduleId}")]
public async Task<ActionResult<int>> DeleteAsync(int ScheduleId, CancellationToken token = default)
{
var result = await scheduleService.DeleteAsync(ScheduleId, token)
.ConfigureAwait(false);
return Ok(result);
}
}
}