using System; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Mapster; using AsbCloudApp.Services; using AsbCloudDb.Model; using System.Collections.Generic; using AsbCloudApp.Data.DailyReport; using AsbCloudApp.Requests; using AsbCloudInfrastructure.Services.DetectOperations; using AsbCloudApp.Data.DetectedOperation; namespace AsbCloudInfrastructure.Services.DailyReport { #nullable enable public class DailyReportService : IDailyReportService { private readonly IAsbCloudDbContext db; private readonly IWellService wellService; private readonly IDetectedOperationService detectedOperationService; private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel(); public DailyReportService(IAsbCloudDbContext db, IWellService wellService, IDetectedOperationService detectedOperationService) { this.db = db; this.wellService = wellService; this.detectedOperationService = detectedOperationService; } public async Task> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token) { var query = db.DailyReports.Where(r => r.IdWell == idWell); if (begin is not null) query = query.Where(d => d.StartDate >= begin.Value.Date); if (end is not null) query = query.Where(d => d.StartDate <= end.Value.Date); var entities = await query .ToListAsync(token); return entities.Select(r => Convert(r)); } public async Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) { var dailyReportDto = await GetAsync(idWell, date, token); if (dailyReportDto is null) dailyReportDto = await MakeDefaultDailyReportAsync(idWell, date, token); return dailyReportDto; } public async Task AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default) { var info = Convert(dto); var entity = new AsbCloudDb.Model.DailyReport.DailyReport { IdWell = idWell, StartDate = info.Head.ReportDate, Info = info }; db.DailyReports.Add(entity); var result = await db.SaveChangesAsync(token); return result; } public async Task 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 MakeReportAsync(int idWell, DateTime date, CancellationToken token = default) { var dailyReportDto = await GetAsync(idWell, date, token); if (dailyReportDto is null) return null; var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto); return memoryStream; } private async Task GetAsync(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 async Task MakeDefaultDailyReportAsync(int idWell, DateTime date, CancellationToken token) { var well = await wellService.GetOrDefaultAsync(idWell, token); var detectedOperations = await detectedOperationService.GetOperationsStatAsync(new DetectedOperationRequest { IdWell = idWell, GtDate = date.Date, LtDate = date.Date.AddDays(1) }, token); var dto = new DailyReportDto() { Head = new HeadDto() { ReportDate = date.Date, WellName = well?.Caption ?? "", ClusterName = well?.Cluster ?? "", }, TimeBalance = detectedOperations is null ? new TimeBalanceDto() { } : GetTimeBalanceDto(detectedOperations), }; return dto; } private TimeBalanceDto GetTimeBalanceDto(IEnumerable stat) { var dto = stat is null ? new TimeBalanceDto() { } : new TimeBalanceDto() { Drilling = $"{FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.IdOperationRotor)) + FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.IdOperationSlide))}", Flushing = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationFlushing)).ToString(), Building = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.IdOperationSlipsTime)).ToString(), Elaboration = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationElaboration)).ToString(), ElaborationBeforeBuilding = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationElaborationBeforeBuilding)).ToString(), TemplatingBeforeBuilding = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationTemplatingBeforeBuilding)).ToString(), FlushingBeforeBuilding = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationFlushingBeforeBuilding)).ToString(), StaticSurveying = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationStaticSurveying)).ToString(), Gis = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationGis)).ToString(), Ozc = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationOzc)).ToString(), Cementing = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationCementing)).ToString(), Npv = FormatOperationValue(stat.FirstOrDefault(x => x.IdCategory == DetectedOperationService.idOperationNpv)).ToString(), }; return dto; } private double FormatOperationValue(DetectedOperationStatDto? operationStat) { return operationStat is not null ? Math.Round(operationStat.MinutesTotal / 60, 2) : 0; } private static DailyReportDto Convert(AsbCloudDb.Model.DailyReport.DailyReport entity) { var dto = entity.Info.Adapt(); dto.Head.ReportDate = entity.StartDate.Date; return dto; } private static DailyReportInfo Convert(DailyReportDto dto) { var entity = dto.Adapt(); entity.Head.ReportDate = dto.Head.ReportDate.Date.Date; return entity; } } #nullable disable }