using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudApp.Services.WellOperationImport; using AsbCloudInfrastructure.Services.WellOperationImport.Constants; using ClosedXML.Excel; namespace AsbCloudInfrastructure.Services.WellOperationImport; public class WellOperationExportService : IWellOperationExportService { private readonly IWellOperationRepository wellOperationRepository; private readonly IWellService wellService; private readonly IWellOperationImportTemplateService wellOperationImportTemplateService; public WellOperationExportService(IWellOperationRepository wellOperationRepository, IWellService wellService, IWellOperationImportTemplateService wellOperationImportTemplateService) { this.wellOperationRepository = wellOperationRepository; this.wellService = wellService; this.wellOperationImportTemplateService = wellOperationImportTemplateService; } public async Task ExportAsync(int idWell, CancellationToken cancellationToken) { var operations = await wellOperationRepository.GetAsync(new WellOperationRequest() { IdWell = idWell }, cancellationToken); var timezone = wellService.GetTimezone(idWell); return await MakeExcelFileStreamAsync(operations, timezone.Hours, cancellationToken); } private async Task MakeExcelFileStreamAsync(IEnumerable operations, double timezoneOffset, CancellationToken cancellationToken) { using Stream ecxelTemplateStream = wellOperationImportTemplateService.GetExcelTemplateStream(); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); await AddOperationsToWorkbook(workbook, operations, timezoneOffset, cancellationToken); var memoryStream = new MemoryStream(); workbook.SaveAs(memoryStream, new SaveOptions { }); memoryStream.Seek(0, SeekOrigin.Begin); return memoryStream; } private async Task AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable operations, double timezoneOffset, CancellationToken cancellationToken) { var planOperations = operations.Where(o => o.IdType == 0); if (planOperations.Any()) { var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == DefaultTemplateInfo.SheetNamePlan); if (sheetPlan is not null) await AddOperationsToSheetAsync(sheetPlan, planOperations, timezoneOffset, cancellationToken); } var factOperations = operations.Where(o => o.IdType == 1); if (factOperations.Any()) { var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == DefaultTemplateInfo.SheetNameFact); if (sheetFact is not null) await AddOperationsToSheetAsync(sheetFact, factOperations, timezoneOffset, cancellationToken); } } private async Task AddOperationsToSheetAsync(IXLWorksheet sheet, IEnumerable operations, double timezoneOffset, CancellationToken cancellationToken) { var operationsToArray = operations.ToArray(); var sections = wellOperationRepository.GetSectionTypes(); var categories = wellOperationRepository.GetCategories(false); for (int i = 0; i < operationsToArray.Length; i++) { var row = sheet.Row(1 + i + DefaultTemplateInfo.HeaderRowsCount); AddOperationToRow(row, operationsToArray[i], sections, categories, timezoneOffset); } } private static void AddOperationToRow(IXLRow row, WellOperationDto operation, IEnumerable sections, IEnumerable categories, double timezoneOffset) { row.Cell(DefaultTemplateInfo.ColumnSection).Value = sections.First(s => s.Id == operation.IdWellSectionType).Caption; row.Cell(DefaultTemplateInfo.ColumnCategory).Value = categories.First(o => o.Id == operation.IdCategory).Name; row.Cell(DefaultTemplateInfo.ColumnCategoryInfo).Value = operation.CategoryInfo; row.Cell(DefaultTemplateInfo.ColumnDepthStart).Value = operation.DepthStart; row.Cell(DefaultTemplateInfo.ColumnDepthEnd).Value = operation.DepthEnd; row.Cell(DefaultTemplateInfo.ColumnDate).Value = new DateTimeOffset(operation.DateStart).ToRemoteDateTime(timezoneOffset); row.Cell(DefaultTemplateInfo.ColumnDuration).Value = operation.DurationHours; row.Cell(DefaultTemplateInfo.ColumnComment).Value = operation.Comment; } }