public async Task <TripOnRouteWithStationsDto> TripWithStationsByRouteIdAndTripId(int routeId, int tripId)
        {
            var sqlRTripsOnRoute  = new TripsOnRouteRepository(_logger);
            var sqlRTrips         = new TripsRepository(_logger);
            var sqlRStationOnTrip = new StantionOnTripsRepository(_logger);
            var sqlRStation       = new StantionsRepository(_logger);
            var result            = new TripOnRouteWithStationsDto();

            var tripOnRoute = await sqlRTripsOnRoute.ByRouteIdAndTripId(routeId, tripId);

            if (tripOnRoute == null)
            {
                throw new ValidationException("Элемент не найден");
            }
            result.Id      = tripOnRoute.Id;
            result.RouteId = tripOnRoute.Id;
            result.TripId  = tripId;

            //result.TripWithDateTimeStations = new TripWithDateTimeStations();
            result.TripWithDateTimeStations = _mapper.Map <Trip, TripWithDateTimeStations>(await sqlRTrips.ById(tripId));
            var stations = await sqlRStationOnTrip.ByTripId(tripId);

            result.TripWithDateTimeStations.StantionOnTripsWithStringTime = new List <StationOnTripWithStringDateTime>();
            foreach (var stantion in stations)
            {
                var toAdd = _mapper.Map <StantionOnTrip, StationOnTripWithStringDateTime>(stantion);
                toAdd.InTimeString  = stantion.InTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                toAdd.OutTimeString = stantion.OutTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                toAdd.Stantion      = await sqlRStation.ById(toAdd.StantionId);

                result.TripWithDateTimeStations.StantionOnTripsWithStringTime.Add(toAdd);
            }

            return(result);
        }
        private async Task CheckTimelineUsing(int routeId, int tripId)
        {
            var sqlRStationsOnTrip = new StantionOnTripsRepository(_logger);
            //Берем станки трипа для добавления
            var tripToAddStations = await sqlRStationsOnTrip.ByTripId(tripId);

            tripToAddStations = tripToAddStations.OrderBy(x => x.UpdateDate).ToList();
            var tripToAddStartTime = tripToAddStations.First().OutTime;
            var tripToAddEndTime   = tripToAddStations.Last().InTime;

            if (tripToAddStartTime > tripToAddEndTime)
            {
                tripToAddEndTime = tripToAddEndTime.AddDays(1);
            }
            var service  = new ScheduleCycleService(_logger, _mapper);
            var sqlRoute = new RoutesRepository(_logger);
            var route    = await sqlRoute.ById(routeId);

            if (route?.TurnoverId == null)
            {
                throw Error.CommonError;
            }
            var routesWithTimelinePaging = await service.GetRoutesWithTimeline((int)route.TurnoverId, 0, int.MaxValue, route.Id);

            var timeLines = routesWithTimelinePaging.Data.First().TimeLines;

            foreach (var timeline in timeLines)
            {
                if ((tripToAddStartTime >= timeline.StarTime || tripToAddEndTime >= timeline.StarTime) &&
                    (tripToAddStartTime <= timeline.EndTime || tripToAddEndTime <= timeline.EndTime))
                {
                    throw new ValidationException(Error.UsedTimeRange);
                }
            }

            //var trips = (await sqlRTripOnRoutes.ByRouteId(routeId)).Where(x => x.TripId != tripId);
            //foreach (var trip in trips)
            //{
            //    var stations = await sqlRStations.ByTripId(trip.TripId);
            //    stations = stations.OrderBy(x => x.InTime).ToList();

            //    var tripStartTime = stations.First().InTime;
            //    var tripEndTime = stations.Last().OutTime;

            //    if (!(tripToAddStartTime < tripStartTime && tripToAddEndTime < tripStartTime || tripToAddStartTime > tripEndTime && tripToAddEndTime > tripEndTime))
            //        throw new ValidationException("Пересекается время рейса с текущими рейсами на маршруте");
            //}
        }
        public async Task <PlanedRouteTrain> AddTrainToPlanedRouteTrains(PlanedRouteTrain input)
        {
            using (var transaction = new TransactionScope(asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
            {
                var sqlRTrips                    = new TripsRepository(_logger);
                var sqlRStations                 = new StantionOnTripsRepository(_logger);
                var sqlRInspectionOnRoutes       = new InspectionRoutesRepository(_logger);
                var sqlRPlanedInspectionOnRoutes = new PlanedInspectionRoutesRepository(_logger);

                var sqlRPlaneStations     = new PlanedStationOnTripsRepository(_logger);
                var sqlRPlanedRouteTrains = new PlanedRouteTrainsRepository(_logger);

                //Валидация Хуяция.
                //TODO поменять на sql
                var trainPlaneRoutes = await sqlRPlanedRouteTrains.ByTrainId(input.TrainId);

                if (trainPlaneRoutes.Any(x => x.Date.Date.Equals(input.Date.Date)))
                {
                    throw new ValidationException(Error.AlreadyAdd);
                }

                var result = await sqlRPlanedRouteTrains.Add(input);

                var trips = await sqlRTrips.GetTripsByRouteId(input.RouteId);

                //var tripsStationsDictionary = new Dictionary<Trip, List<StantionOnTrip>>();
                foreach (var trip in trips)
                {
                    var stations = await sqlRStations.ByTripId(trip.Id);

                    foreach (var station in stations)
                    {
                        var toAdd = _mapper.Map <StantionOnTrip, PlaneStantionOnTrip>(station);
                        toAdd.PlanedRouteTrainId = result.Id;
                        var newInTime = toAdd.InTime - DateTime.MinValue;
                        toAdd.InTime = input.Date.Date.Add(newInTime);

                        var newOutTime = toAdd.OutTime - DateTime.MinValue;
                        toAdd.OutTime = input.Date.Date.Add(newOutTime);

                        await sqlRPlaneStations.Add(toAdd);
                    }

                    //tripsStationsDictionary.Add(trip, stations);
                }

                //И тут я узнал что надо инспекции скопировать ебать их в рот
                var inspections = await sqlRInspectionOnRoutes.GetByRouteId(input.RouteId);

                foreach (var inspection in inspections)
                {
                    var toAdd = new PlanedInspectionRoute
                    {
                        CheckListType      = inspection.CheckListType,
                        PlanedRouteTrainId = result.Id,
                    };
                    var newInTime = inspection.Start - inspection.Start.Date;
                    toAdd.Start = input.Date.Date.Add(newInTime);
                    var newOutTime = inspection.End - inspection.End.Date;
                    toAdd.End = input.Date.Date.Add(newOutTime);
                    await sqlRPlanedInspectionOnRoutes.Add(toAdd);
                }


                transaction.Complete();
                return(result);
            }
        }
        /*public async Task<DictionaryCrudResponse> ParkingCrud(DictionaryCrudRequest input)
         * {
         *  var data = input.Parking;
         *  if (data == null && input.IdToDelete == null)
         *      throw new ValidationException("Не распарсилось");
         *
         *  var sqlR = new ParkingRepository(_logger);
         *  if (input?.IdToDelete != null)
         *  {
         *      await sqlR.Delete((int)input.IdToDelete);
         *      return new DictionaryCrudResponse { IsDeleted = true, Parking = data };
         *  }
         *
         *  var all = await sqlR.GetAll();
         *  if (data?.Id == 0 &&
         *      all.Any(x => x.Name.Equals(input.Parking.Name)))
         *      throw new ValidationException(Error.AlreadyAddWithThisName);
         *
         *  if (data?.Id == 0)
         *  {
         *      var item = await sqlR.Add(data);
         *      return new DictionaryCrudResponse { IsAdd = true, Parking = item };
         *  }
         *  else
         *  {
         *      var item = await sqlR.Update(data);
         *      return new DictionaryCrudResponse { IsUpdated = true, Parking = item };
         *  }
         * }*/

        /// <summary>
        /// Справочник рейсов с днями
        /// </summary>
        private static async Task <ReportResponse> GetTripsWithDaysTable(ReportRequest input, ILogger logger)
        {
            var sqlR               = new TripsRepository(logger);
            var sqlRTripDays       = new DayOfTripsRepoisitory(logger);
            var sqlRStationOnTrips = new StantionOnTripsRepository(logger);
            var sqlRStations       = new StantionsRepository(logger);
            var result             = new ReportResponse {
                Rows = new List <Row>()
            };

            var data = await sqlR.GetAll();

            result.Columns = new List <Column>
            {
                new Column("col0", "Имя", "string", disableEdit: false),
                new Column("col1", "Дни", "string"),
                new Column("col2", "Время отправления", "string"),
                new Column("col3", "Время прибытия", "string")
            };

            foreach (var item in data)
            {
                var stantionOnTrips = await sqlRStationOnTrips.ByTripId(item.Id);

                DateTime?startTime  = null;
                DateTime?endTime    = null;
                var      days       = (await sqlRTripDays.DaysByTripId(item.Id)).Select(x => x.Day).ToList();
                string   stringDays = null;
                if (days.Any())
                {
                    foreach (var day in days)
                    {
                        if (stringDays == null)
                        {
                            stringDays = GetStringDayOfWeekShort(day);
                        }
                        else
                        {
                            stringDays = stringDays + ", " + GetStringDayOfWeekShort(day);
                        }
                    }
                }

                if (stantionOnTrips.Count >= 2)
                {
                    stantionOnTrips = stantionOnTrips.OrderBy(x => x.OutTime).ToList();
                    startTime       = stantionOnTrips.First().OutTime;
                    endTime         = stantionOnTrips.Last().InTime;
                }

                var row = new Row
                {
                    Id       = new RowId(item.Id, 1),
                    HasItems = false.ToString(),
                    ParentId = null,
                    //Имя
                    Col0 = item.Name,
                    //Дни
                    Col1 = stringDays,
                    //"Время отправления
                    Col2 = startTime?.ToStringTimeOnly(),
                    //Время прибытия
                    Col3 = endTime?.ToStringTimeOnly(),
                    AdditionalProperty = new AdditionalProperty {
                        StantionsWithTime = new List <StantionWithTimeSimple>()
                    }
                };
                foreach (var stantionOnTrip in stantionOnTrips)
                {
                    var stationName = (await sqlRStations.ById(stantionOnTrip.StantionId))?.Name;
                    row.AdditionalProperty.StantionsWithTime.Add(
                        new StantionWithTimeSimple
                    {
                        StantionId   = stantionOnTrip.StantionId,
                        StantionName = stationName,
                        InTime       = stantionOnTrip.InTime,
                        OutTime      = stantionOnTrip.OutTime
                    });
                }

                result.Rows.Add(row);
            }

            return(result);
        }
        /// <summary>
        /// Обновить Хуету
        /// </summary>
        public async Task <TripOnRouteWithStationsDto> UpdateTripOnRoute(TripOnRouteWithStationsDto input)
        {
            await CompareDaysFromTurnover(input);

            //Начинаем транзакцию
            using (var transaction = new TransactionScope(asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
            {
                var sqlRStationOnTrip = new StantionOnTripsRepository(_logger);
                var sqlRDaysOfTrip    = new DayOfTripsRepoisitory(_logger);
                //var sqlRStationOnTripNoTransaction = new StantionOnTripsRepository(_logger);
                //Удаляем лишние станции нахуй, если есть
                var stations = await sqlRStationOnTrip.ByTripId(input.TripWithDateTimeStations.Id);

                foreach (var station in stations)
                {
                    if (input.TripWithDateTimeStations.StantionOnTripsWithStringTime.Any(e => e.Id == station.Id))
                    {
                        continue;
                    }
                    sqlRStationOnTrip.Delete(station.Id);
                }

                var currentDaysOfTrip = await sqlRDaysOfTrip.DaysByTripId(input.TripId);

                var currentDays = currentDaysOfTrip.Select(x => x.Day).ToList();
                foreach (var day in input.Days)
                {
                    if (currentDays.Contains(day))
                    {
                        await sqlRDaysOfTrip.Add(new DayOfTrip { TripId = input.TripId, Day = day });

                        currentDays.Remove(day);
                    }
                }
                if (currentDays.Count > 0)
                {
                    foreach (var currentDay in currentDays)
                    {
                        var toRemove = currentDaysOfTrip.FirstOrDefault(x => x.Day.Equals(currentDay));
                        await sqlRDaysOfTrip.Delete(toRemove.Id);
                    }
                }

                var sqlRTripOnRoute = new TripsOnRouteRepository(_logger);

                var newTripOnRoute =
                    await sqlRTripOnRoute.Update(_mapper.Map <TripOnRouteWithStationsDto, TripOnRoute>(input));

                var result = _mapper.Map <TripOnRoute, TripOnRouteWithStationsDto>(newTripOnRoute);
                result.TripWithDateTimeStations = new TripWithDateTimeStations
                {
                    StantionOnTripsWithStringTime = new List <StationOnTripWithStringDateTime>()
                };

                foreach (var item in input.TripWithDateTimeStations.StantionOnTripsWithStringTime)
                {
                    var stationOnTrip =
                        await sqlRStationOnTrip.Update(
                            _mapper.Map <StationOnTripWithStringDateTime, StantionOnTrip>(item));

                    result.TripWithDateTimeStations.StantionOnTripsWithStringTime.Add(
                        _mapper.Map <StantionOnTrip, StationOnTripWithStringDateTime>(item));
                }

                transaction.Complete();
                return(result);
            }
        }
        /// <summary>
        /// Добавить хуету
        /// </summary>
        public async Task <TripOnRouteWithStationsDto> AddTripOnRoute(TripOnRouteWithStationsDto input)
        {
            if (input.TripWithDateTimeStations.Id != 0)
            {
                if (!await CompareDaysFromTurnover(input))
                {
                    throw new ValidationException("Не совпадают дни графика оборота и рейса");
                }
            }

            using (var transaction = new TransactionScope(asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
            {
                //var sqlRTripOnRoute = new TripsOnRouteRepository(_logger);
                var sqlRTrip          = new TripsRepository(_logger);
                var sqlRStationOnTrip = new StantionOnTripsRepository(_logger);
                var sqlRDaysOfTrip    = new DayOfTripsRepoisitory(_logger);
                var all = await sqlRTrip.GetAll();

                if (input.TripWithDateTimeStations.Id == 0 &&
                    all.Any(x => x.Name.Equals(input.TripWithDateTimeStations.Name)))
                {
                    throw new ValidationException(Error.AlreadyAddWithThisName);
                }
                var result = new TripOnRouteWithStationsDto
                {
                    Days = new List <DayOfWeek>(),
                    TripWithDateTimeStations = new TripWithDateTimeStations
                    {
                        StantionOnTrips = new List <StantionOnTrip>(),
                        StantionOnTripsWithStringTime = new List <StationOnTripWithStringDateTime>()
                    }
                };

                if (input.TripWithDateTimeStations.Id == 0)
                {
                    var newTrip =
                        await sqlRTrip.Add(_mapper.Map <TripWithDateTimeStations, Trip>(input.TripWithDateTimeStations));

                    result.TripWithDateTimeStations.Id          = newTrip.Id;
                    result.TripWithDateTimeStations.Name        = newTrip.Name;
                    result.TripWithDateTimeStations.Description = newTrip.Description;
                    result.TripId = newTrip.Id;
                }

                foreach (var day in input.Days)
                {
                    var addedDay = await sqlRDaysOfTrip.Add(new DayOfTrip { TripId = result.TripId, Day = day });

                    result.Days.Add(addedDay.Day);
                }

                foreach (var item in input.TripWithDateTimeStations.StantionOnTripsWithStringTime)
                {
                    var toAdd = _mapper.Map <StationOnTripWithStringDateTime, StantionOnTrip>(item);
                    if (toAdd.InTime > toAdd.OutTime)
                    {
                        throw new ValidationException(Error.IncorrectTimeRange);
                    }
                    toAdd.TripId = result.TripWithDateTimeStations.Id;
                    var stationOnTrip = await sqlRStationOnTrip.Add(toAdd);

                    result.TripWithDateTimeStations.StantionOnTripsWithStringTime.Add(
                        _mapper.Map <StantionOnTrip, StationOnTripWithStringDateTime>(stationOnTrip));
                }

                //await CheckTimelineUsing(input.RouteId, input.TripId);

                transaction.Complete();
                return(result);
            }
        }
        public async Task <List <TripWithStartEndTimeAndDays> > GetTripsByTurnoverIdAndDays(int turnoverId, int routeId)
        {
            var sqlRTripOnRoute    = new TripsOnRouteRepository(_logger);
            var sqlRRoute          = new RoutesRepository(_logger);
            var sqlRDaysOfRoutes   = new DayOfRoutesRepoisitory(_logger);
            var sqlRTrips          = new TripsRepository(_logger);
            var sqlRStationOnTrips = new StantionOnTripsRepository(_logger);
            var sqlRStation        = new StantionsRepository(_logger);
            var sqlRDayOfTrips     = new DayOfTripsRepoisitory(_logger);
            //Получаем дни циклового графика
            var daysTurnoverObj = await sqlRDaysOfRoutes.DaysByTurnoverId(turnoverId);

            var daysTurnover = daysTurnoverObj.Select(x => x.Day).ToList();

            daysTurnover.Sort();
            //Надо найти трипсы с аналогичными днями.
            var trips = await sqlRTrips.GetAll();

            var result = new List <TripWithStartEndTimeAndDays>();


            var route = await sqlRRoute.ById(routeId);

            foreach (var trip in trips)
            {
                if (await sqlRTripOnRoute.ByRouteIdAndTripId(route.Id, trip.Id) != null)
                {
                    continue;
                }

                var currentTripDaysObj = await sqlRDayOfTrips.DaysByTripId(trip.Id);

                var currentTripDays = currentTripDaysObj.Select(x => x.Day).ToList();
                currentTripDays.Sort();

                var isGoodTrip = true;
                foreach (var d in daysTurnover)
                {
                    if (!currentTripDays.Any(x => x.Equals(d)))
                    {
                        isGoodTrip = false;
                    }
                }
                if (!isGoodTrip)
                {
                    continue;
                }
                {
                    string days = null;
                    foreach (var day in currentTripDays)
                    {
                        if (days == null)
                        {
                            days = GetStringDayOfWeekShort(day);
                        }
                        else
                        {
                            days = days + ", " + GetStringDayOfWeekShort(day);
                        }
                    }
                    var tripStations = await sqlRStationOnTrips.ByTripId(trip.Id);

                    tripStations = tripStations.OrderBy(x => x.OutTime).ToList();
                    var startStation = tripStations.First();
                    var endStation   = tripStations.Last();

                    var tripExtended = _mapper.Map <Trip, TripWithStartEndTimeAndDays>(trip);
                    tripExtended.Days             = currentTripDays;
                    tripExtended.StartTime        = startStation.OutTime.ToStringTimeOnly();
                    tripExtended.EndTime          = endStation.InTime.ToStringTimeOnly();
                    tripExtended.StartStationName = (await sqlRStation.ById(startStation.StantionId)).Name;
                    tripExtended.EndStationName   = (await sqlRStation.ById(endStation.StantionId)).Name;
                    result.Add(tripExtended);
                }
            }

            return(result);
        }
        public async Task <RoutesWithTripsAndToPaging> GetRoutesWithTripsAndToByTurnoverId(int turnoverId, int skip, int limit, int?routeId = null)
        {
            var sqlRRoute            = new RoutesRepository(_logger);
            var sqlRTripsOnRoute     = new TripsOnRouteRepository(_logger);
            var sqlRTrips            = new TripsRepository(_logger);
            var sqlRStationOnTrips   = new StantionOnTripsRepository(_logger);
            var sqlRInspectionRoutes = new InspectionRoutesRepository(_logger);

            var routes = new List <Route>();
            var total  = 0;

            if (routeId == null)
            {
                var paging = await sqlRRoute.GetByTurnoverIdPaging(turnoverId, skip, limit);

                routes.AddRange(paging.Data);
                total = paging.Total;
            }
            else
            {
                routes.Add(await sqlRRoute.ById(routeId.Value));
            }

            var result = new RoutesWithTripsAndToPaging {
                Data = new List <RoutesWithTripsAndTo>(), Total = total
            };


            foreach (var route in routes)
            {
                var data = new RoutesWithTripsAndTo
                {
                    Id               = route.Id,
                    Name             = route.Name,
                    Mileage          = route.Mileage,
                    Description      = route.Description,
                    TurnoverId       = route.TurnoverId,
                    InspectionRoutes = await sqlRInspectionRoutes.GetByRouteId(route.Id)
                };
                var tripsOnRoute = await sqlRTripsOnRoute.ByRouteId(route.Id);

                var trips = new List <TripWithTripOnRouteId>();
                foreach (var tripOnRoute in tripsOnRoute)
                {
                    var trip = await sqlRTrips.ById(tripOnRoute.TripId);

                    var toAdd = _mapper.Map <Trip, TripWithTripOnRouteId>(trip);
                    toAdd.TripOnRouteId = tripOnRoute.Id;
                    trips.Add(toAdd);
                }

                data.Trips = trips;


                foreach (var trip in data.Trips)
                {
                    trip.StantionOnTrips = new List <StantionOnTrip>();
                    var stationsOnTrip = await sqlRStationOnTrips.ByTripId(trip.Id);

                    foreach (var stationOnTrip in stationsOnTrip)
                    {
                        trip.StantionOnTrips.Add(stationOnTrip);
                    }
                }

                result.Data.Add(data);
            }

            return(result);
        }