using System; using System.Collections.Generic; using System.IO; using System.Linq; using AsbCloudApp.Data; using AsbCloudApp.Data.WellOperationImport; using AsbCloudApp.Repositories; using AsbCloudApp.Services.WellOperationImport; namespace AsbCloudInfrastructure.Services.WellOperationImport; public class WellOperationImportService : IWellOperationImportService { private readonly IWellOperationRepository wellOperationRepository; private static readonly DateTime dateLimitMin = new(2001, 1, 1, 0, 0, 0); private static readonly DateTime dateLimitMax = new(2099, 1, 1, 0, 0, 0); private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366); public WellOperationImportService(IWellOperationRepository wellOperationRepository) { this.wellOperationRepository = wellOperationRepository; } public IEnumerable Import(int idWell, int idUser, int idType, SheetDto sheet) { var validationErrors = new List(); var sections = wellOperationRepository.GetSectionTypes(); var categories = wellOperationRepository.GetCategories(false); var wellOperations = new List(); foreach (var row in sheet.Rows) { try { var section = sections.FirstOrDefault(s => string.Equals(s.Caption, row.Section, StringComparison.CurrentCultureIgnoreCase)); if (section is null) throw new FileFormatException($"Лист '{sheet.Name}'. В строке '{row.Number}' не удалось определить секцию"); var category = categories.FirstOrDefault(c => string.Equals(c.Name, row.Category, StringComparison.CurrentCultureIgnoreCase)); if (category is null) throw new FileFormatException($"Лист '{sheet.Name}'. В строке '{row.Number}' не удалось определить операцию"); if (row.DepthStart is not (>= 0d and <= 20_000d)) throw new FileFormatException( $"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная глубина на начало операции"); if (row.DepthEnd is not (>= 0d and <= 20_000d)) throw new FileFormatException( $"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная глубина на конец операции"); if (row.Date < dateLimitMin && row.Date > dateLimitMax) throw new FileFormatException( $"Лист '{sheet.Name}'. Строка '{row.Number}' неправильно получена дата начала операции"); if (wellOperations.LastOrDefault()?.DateStart > row.Date) throw new FileFormatException( $"Лист '{sheet.Name}' строка '{row.Number}' дата позднее даты предыдущей операции"); if (row.Duration is not (>= 0d and <= 240d)) throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции"); wellOperations.Add(new WellOperationDto { IdWell = idWell, IdUser = idUser, IdType = idType, IdWellSectionType = section.Id, IdCategory = category.Id, CategoryInfo = row.CategoryInfo, DepthStart = row.DepthStart, DepthEnd = row.DepthEnd, DateStart = row.Date, DurationHours = row.Duration, Comment = row.Comment }); } catch (FileFormatException ex) { validationErrors.Add(ex.Message); } } if (wellOperations.Any() && wellOperations.Min(o => o.DateStart) - wellOperations.Max(o => o.DateStart) > drillingDurationLimitMax) validationErrors.Add($"Лист {sheet.Name} содержит диапазон дат больше {drillingDurationLimitMax}"); if (validationErrors.Any()) throw new FileFormatException(string.Join("\r\n", validationErrors)); return wellOperations; } }