diff --git a/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportService.cs b/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportService.cs index b22ce6ff..40e69dd8 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportService.cs @@ -18,9 +18,19 @@ namespace AsbCloudInfrastructure.Services.WellOperationService private readonly IOperationsStatService operationsStatService; private readonly IWellService wellService; const string sheetNameSchedule = "Сетевой график"; + const string sheetNameSchedulePlan = "План"; + const string sheetNameScheduleFact = "Факт"; + const string sheetNameSchedulePrediction = "Прогноз"; const string sheetNameTvd = "ГГД"; const int maxChartsToWrap = 88; + private enum sheduleMode + { + plan, + fact, + predict + }; + public ScheduleReportService(IOperationsStatService operationsStatService, IWellService wellService) { this.operationsStatService = operationsStatService; @@ -47,6 +57,176 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } private static void FillScheduleSheetToWorkbook(XLWorkbook workbook, IEnumerable> tvd, WellDto well) + { + FillScheduleSheet(workbook, tvd, well); + + var tvdList = tvd.ToList(); + var plans = tvd + .Where(t => t.Plan is not null) + .Select(t => t.Plan!) + .OrderBy(t => t.DateStart) + .ToList(); + FillCurrentScheduleSheetToWorkbook(workbook, plans, well, sheduleMode.plan); + + var facts = tvd + .Where(t => t.Fact is not null) + .Select(t => t.Fact!) + .OrderBy(t => t.DateStart) + .ToList(); + FillCurrentScheduleSheetToWorkbook(workbook, facts, well, sheduleMode.fact); + + var predictions = tvd + .Where(t => t.Predict is not null) + .Select(t => t.Predict!) + .OrderBy(t => t.DateStart) + .ToList(); + FillCurrentScheduleSheetToWorkbook(workbook, predictions, well, sheduleMode.predict); + + } + + private static void FillCurrentScheduleSheetToWorkbook(XLWorkbook workbook, List tvdList, WellDto well, sheduleMode mode) + { + var sheetName = GetSheetName(mode); + var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName); + if (sheet is null) + return; + + const int headerRowsCount = 6; + const int rowTitle = 3; + + const int columnRowNumber = 2; + const int columnCaption = 3; + const int columnWellDepthStart = 4; + const int columnWellDepthEnd = 5; + const int columnDeltaWellDepthPerDay = 6; + const int columnDuration = 7; + const int columnDateStart = 8; + const int columnDateEnd = 9; + const int columnGuilty = 10; + const int columnNpt = 11; + + var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}"; + sheet.Row(rowTitle).Cell(3).Value = subTitle; + + DateTime lastFactDate = default; + var lastFactI = 0; + + int i = 0; + for (; i < tvdList.Count; i++) + { + var tvdItem = tvdList[i]; + if (tvdItem is null) + continue; + + if (i == 86) + { + ; + } + + var row = sheet.Row(1 + i + headerRowsCount); + + SetCell(row, columnRowNumber, $"{1 + i}"); + SetCell(row, columnCaption, $"{tvdItem.CategoryName} {tvdItem.CategoryInfo}".Trim()); + + SetCell(row, columnWellDepthStart, tvdItem.DepthStart); + + SetCell(row, columnWellDepthEnd, tvdItem.DepthEnd); + + SetCell(row, columnDeltaWellDepthPerDay, null); + if (mode == sheduleMode.fact) + { + var fact = tvdItem; + if (lastFactDate == default) + lastFactDate = fact.DateStart; + + if (i > 0 && fact.DateStart.DayOfYear != lastFactDate.DayOfYear) + { + var daylyOperations = tvdList + .Where(t => t.DateStart >= lastFactDate && t.DateStart < fact.DateStart); + if (daylyOperations.Any()) + { + var depthDayStart = daylyOperations.Min(o => o.DepthStart); + var depthDayEnd = daylyOperations.Max(o => o.DepthEnd); + var delta = depthDayEnd - depthDayStart; + SetCell(sheet.Row(1 + lastFactI + headerRowsCount), columnDeltaWellDepthPerDay, delta); + lastFactDate = fact.DateStart; + } + } + lastFactI = i; + } + + SetCell(row, columnDuration, tvdItem.DurationHours); + + SetCell(row, columnDateStart, tvdItem.DateStart); + + SetCell(row, columnDateEnd, tvdItem.DateStart.AddHours(tvdItem.DurationHours)); + + if (mode == sheduleMode.fact && WellOperationCategory.NonProductiveTimeSubIds.Contains(tvdItem.IdCategory)) + { + SetCell(row, columnGuilty, tvdItem.Comment); + SetCell(row, columnNpt, tvdItem.DurationHours); + row.Row(columnRowNumber, columnNpt).Style.Fill.BackgroundColor = XLColor.Red; + } + else + { + SetCell(row, columnGuilty, null); + SetCell(row, columnNpt, null); + } + } + + var rowNumSummary = 1 + i + headerRowsCount; + var rowNumStart = 1 + headerRowsCount; + var rowNumEnd = i + headerRowsCount; + + string MakeRangeFunction(string funcName, int column) + => $"={funcName}({GetColunmLetter(column)}{rowNumStart}:{GetColunmLetter(column)}{rowNumEnd})"; + + IXLCell AddRangeFormula(IXLRow row, string funcName, int column) + { + var cell = row.Cell(column); + cell.FormulaA1 = MakeRangeFunction(funcName, column); + return cell; + } + + var rowSummary = sheet.Row(rowNumSummary); + rowSummary.Style.Font.Bold = true; + rowSummary.Cell(columnCaption).Value = "Итого:"; + + AddRangeFormula(rowSummary, "sum", columnDeltaWellDepthPerDay); + AddRangeFormula(rowSummary, "sum", columnDuration); + var cell = AddRangeFormula(rowSummary, "max", columnDateEnd); + SetDateTime(cell); + SetDateTime(cell); + AddRangeFormula(rowSummary, "sum", columnNpt); + SetBorder(rowSummary.Cells(true).Style); + + var rowSummary2 = sheet.Row(rowNumSummary + 1); + rowSummary2.DataType = XLDataType.Number; + rowSummary2.Style.NumberFormat.Format = "0,00"; + rowSummary2.Cell(columnCaption).Value = "в сутках:"; + rowSummary2.Cell(columnDuration).FormulaA1 = $"={GetColunmLetter(columnDuration)}{rowNumSummary}/24"; + SetNumber(rowSummary2.Cell(columnDuration)); + rowSummary2.Cell(columnNpt).FormulaA1 = $"={GetColunmLetter(columnNpt)}{rowNumSummary}/24"; + SetNumber(rowSummary2.Cell(columnNpt)); + SetBorder(rowSummary2.Cells(true).Style); + } + + private static string GetSheetName(sheduleMode mode) + { + switch (mode) + { + case sheduleMode.plan: + return sheetNameSchedulePlan; + case sheduleMode.fact: + return sheetNameScheduleFact; + case sheduleMode.predict: + return sheetNameSchedulePrediction; + default: + return sheetNameSchedule; + } + } + + private static void FillScheduleSheet(XLWorkbook workbook, IEnumerable> tvd, WellDto well) { var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule); if (sheet is null) @@ -98,6 +278,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService var row = sheet.Row(1 + i + headerRowsCount); + if (i == 86) + { + ; + } + SetCell(row, columnRowNumber, $"{1 + i}"); SetCell(row, columnCaption, $"{operation.CategoryName} {operation.CategoryInfo}".Trim()); diff --git a/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportTemplate.xlsx index 5f86498d..53b8ce5b 100644 Binary files a/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportTemplate.xlsx and b/AsbCloudInfrastructure/Services/WellOperationService/ScheduleReportTemplate.xlsx differ diff --git a/AsbCloudWebApi/appsettings.json b/AsbCloudWebApi/appsettings.json index 629f10c8..ac0acc5b 100644 --- a/AsbCloudWebApi/appsettings.json +++ b/AsbCloudWebApi/appsettings.json @@ -7,10 +7,10 @@ } }, "ConnectionStrings": { - "DefaultConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True", - "DebugConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True", + "DefaultConnection": "Host=localhost;Database=postgres3;Username=postgres;Password=q;Persist Security Info=True", + "DebugConnection": "Host=localhost;Database=postgres3;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True", "ServerConnection": "Host=192.168.1.70;Database=postgres;Username=postgres;Password=q;Persist Security Info=True", - "LocalConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True" + "LocalConnection": "Host=localhost;Database=postgres3;Username=postgres;Password=q;Persist Security Info=True" }, "AllowedHosts": "*", //"userLimits": {