DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs

263 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.DailyReport
{
#nullable enable
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,
IUserRepository userRepository,
IWellOperationRepository wellOperationRepository)
{
this.db = db;
this.wellService = wellService;
this.userRepository = userRepository;
this.wellOperationRepository = wellOperationRepository;
}
public async Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token)
{
var well = wellService.GetOrDefault(idWell);
if (well is null || well.Timezone is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var query = db.DailyReports.Where(r => r.IdWell == idWell);
DateOnly ExtractDate(DateTime dateTime)
{
var dateTimeOffset = dateTime.ToUtcDateTimeOffset(well!.Timezone.Hours);
var date = new DateOnly(dateTimeOffset.Year, dateTimeOffset.Month, dateTimeOffset.Day);
return date;
}
if (begin is not null)
{
var beginDateOnly = ExtractDate(begin.Value);
query = query.Where(d => d.StartDate >= beginDateOnly);
}
if (end is not null)
{
var endDateOnly = ExtractDate(end.Value);
query = query.Where(d => d.StartDate <= endDateOnly);
}
var entities = await query.OrderByDescending(e => e.StartDate).ToListAsync(token);
var dtos = entities.Select(Convert).ToList();
var factOperationsForDtos = await getFactOperationsForDailyReportAsync(idWell, token);
foreach (var dto in dtos)
{
dto.TimeBalance.OperationsStat = (factOperationsForDtos
.Where(o => DateOnly.FromDateTime(o.DateStart) == dto.StartDate)
.GroupBy(o => o.IdCategory)
.Select(g => new OperationStatDto() { Depth = g.Sum(o => o.DepthEnd - o.DepthStart) }));
await SetUserNamesToDailyReportDtoAsync(dto, token);
}
return dtos;
}
/// <summary>
/// получение фактических операций для суточного рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
private async Task<IEnumerable<WellOperationDto>> getFactOperationsForDailyReportAsync(int idWell, CancellationToken token)
{
var request = new WellOperationRequest()
{
IdWell = idWell,
OperationType = WellOperation.IdOperationTypeFact,
};
var factOperations = await wellOperationRepository.GetAsync(request, token);
return factOperations;
}
/// <summary>
/// Заполнение DTO-модели данными о пользователях
/// </summary>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
private async Task<DailyReportDto> SetUserNamesToDailyReportDtoAsync(DailyReportDto dto, CancellationToken token)
{
var blocks = new ItemInfoDto[] {
dto.Head,
dto.Bha,
dto.NoDrilling,
dto.TimeBalance,
dto.Saub,
dto.Sign
};
foreach (var block in blocks)
{
if (block.IdUser is not null)
{
var user = await userRepository.GetOrDefaultAsync(block.IdUser.Value, token);
block.UserName = user is not null
? string.Format("{0} {1} {2}", user.Surname, user.Name, user.Patronymic)
: String.Empty;
}
}
return dto;
}
public async Task<int> AddAsync(int idWell, DateTime startDate, int idUser, CancellationToken token = default)
{
var well = wellService.GetOrDefault(idWell);
if (well is null || well.Timezone is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var startDateOnly = DateOnly.FromDateTime(startDate);
var entity = await db.DailyReports
.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == startDateOnly, token);
if (entity is not null)
throw new Exception($"daily report on {startDateOnly} already exists");
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
var contractor = well.Companies.FirstOrDefault(company => company.IdCompanyType == 2);
entity = new AsbCloudDb.Model.DailyReport.DailyReport
{
IdWell = idWell,
StartDate = startDateOnly,
Info = new DailyReportInfo()
{
Head = new Head()
{
ReportDate = startDate.Date,
WellName = well.Caption,
ClusterName = well?.Cluster ?? String.Empty,
Customer = customer?.Caption ?? String.Empty,
Contractor = contractor?.Caption ?? String.Empty,
IdUser = idUser,
LastUpdateDate = DateTimeOffset.Now,
}
}
};
db.DailyReports.Add(entity);
var result = await db.SaveChangesAsync(token);
return result;
}
public async Task<int> UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token)
{
var dateOffset = date.Date;
var entity = await db.DailyReports
.FirstOrDefaultAsync(r => r.IdWell == idWell &&
r.StartDate.Year == dateOffset.Year &&
r.StartDate.DayOfYear == dateOffset.DayOfYear
, token);
if (entity is null)
return 0;
entity.Info = Convert(dto);
db.DailyReports.Update(entity);
var result = await db.SaveChangesAsync(token);
return result;
}
public async Task<int> UpdateBlockAsync(int idWell, DateTime startDate, ItemInfoDto dto, CancellationToken token)
{
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<Head>();
if (dto is BhaDto bhaDto)
entity.Info.Bha = bhaDto.Adapt<Bha>();
if (dto is NoDrillingDto noDrillingDto)
entity.Info.NoDrilling = noDrillingDto.Adapt<NoDrilling>();
if (dto is TimeBalanceDto timeBalanceDto)
entity.Info.TimeBalance = timeBalanceDto.Adapt<TimeBalance>();
if (dto is SaubDto saubDto)
entity.Info.Saub = saubDto.Adapt<Saub>();
if (dto is SignDto signDto)
entity.Info.Sign = signDto.Adapt<Sign>();
db.DailyReports.Update(entity);
var result = await db.SaveChangesAsync(token);
return result;
}
public async Task<Stream?> MakeReportAsync(int idWell, DateTime date, CancellationToken token = default)
{
var dailyReportDto = await GetOrDefaultAsync(idWell, date, token);
if (dailyReportDto is null)
return null;
var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto);
return memoryStream;
}
private async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateTime date, CancellationToken token)
{
var dateOffset = date.Date;
var entity = await db.DailyReports
.FirstOrDefaultAsync(r => r.IdWell == idWell &&
r.StartDate.Year == dateOffset.Year &&
r.StartDate.DayOfYear == dateOffset.DayOfYear
, token);
if (entity is null)
return null;
var dto = Convert(entity);
return dto;
}
private static DailyReportDto Convert(AsbCloudDb.Model.DailyReport.DailyReport entity)
{
var dto = entity.Info.Adapt<DailyReportDto>();
dto.StartDate = entity.StartDate;
return dto;
}
private static DailyReportInfo Convert(DailyReportDto dto)
{
var entity = dto.Adapt<DailyReportInfo>();
entity.Head.ReportDate = dto.Head.ReportDate.Date.Date;
return entity;
}
}
#nullable disable
}