예제 #1
0
        public CounterpartyOrderViewModel(Counterparty client,
                                          IUnitOfWorkFactory unitOfWorkFactory,
                                          ITdiCompatibilityNavigation tdinavigation,
                                          IRouteListRepository routedListRepository,
                                          MangoManager mangoManager,
                                          IOrderParametersProvider orderParametersProvider,
                                          IEmployeeJournalFactory employeeJournalFactory,
                                          ICounterpartyJournalFactory counterpartyJournalFactory,
                                          INomenclatureRepository nomenclatureRepository,
                                          IParametersProvider parametersProvider,
                                          IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
                                          int count = 5)
        {
            Client                           = client;
            tdiNavigation                    = tdinavigation;
            _routedListRepository            = routedListRepository;
            MangoManager                     = mangoManager;
            _orderParametersProvider         = orderParametersProvider ?? throw new ArgumentNullException(nameof(orderParametersProvider));
            _employeeJournalFactory          = employeeJournalFactory ?? throw new ArgumentNullException(nameof(employeeJournalFactory));
            _counterpartyJournalFactory      = counterpartyJournalFactory ?? throw new ArgumentNullException(nameof(counterpartyJournalFactory));
            _nomenclatureRepository          = nomenclatureRepository ?? throw new ArgumentNullException(nameof(nomenclatureRepository));
            _parametersProvider              = parametersProvider ?? throw new ArgumentNullException(nameof(parametersProvider));
            _deliveryRulesParametersProvider = deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
            UoW         = unitOfWorkFactory.CreateWithoutRoot();
            LatestOrder = _orderRepository.GetLatestOrdersForCounterparty(UoW, client, count).ToList();

            RefreshOrders = _RefreshOrders;
            NotifyConfiguration.Instance.BatchSubscribe(_RefreshCounterparty)
            .IfEntity <Counterparty>()
            .AndWhere(c => c.Id == client.Id)
            .Or.IfEntity <DeliveryPoint>()
            .AndWhere(d => client.DeliveryPoints.Any(cd => cd.Id == d.Id));
        }
예제 #2
0
        public SelfDeliveriesJournalViewModel(
            OrderJournalFilterViewModel filterViewModel,
            IUnitOfWorkFactory unitOfWorkFactory,
            ICommonServices commonServices,
            CallTaskWorker callTaskWorker,
            OrderPaymentSettings orderPaymentSettings,
            OrderParametersProvider orderParametersProvider,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
            IEmployeeService employeeService)
            : base(filterViewModel, unitOfWorkFactory, commonServices)
        {
            _callTaskWorker                  = callTaskWorker ?? throw new ArgumentNullException(nameof(callTaskWorker));
            _orderPaymentSettings            = orderPaymentSettings ?? throw new ArgumentNullException(nameof(orderPaymentSettings));
            _orderParametersProvider         = orderParametersProvider ?? throw new ArgumentNullException(nameof(orderParametersProvider));
            _deliveryRulesParametersProvider = deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
            _currentEmployee                 =
                (employeeService ?? throw new ArgumentNullException(nameof(employeeService))).GetEmployeeForUser(
                    UoW,
                    commonServices.UserService.CurrentUserId);

            TabName = "Журнал самовывозов";
            SetOrder(x => x.Date, true);
            UpdateOnChanges(
                typeof(VodovozOrder),
                typeof(OrderItem)
                );
            _userCanChangePayTypeToByCard = commonServices.CurrentPermissionService.ValidatePresetPermission("allow_load_selfdelivery");
        }
        public DistrictsSetJournalViewModel(
            DistrictsSetJournalFilterViewModel filterViewModel,
            IUnitOfWorkFactory unitOfWorkFactory,
            ICommonServices commonServices,
            IEmployeeRepository employeeRepository,
            IEntityDeleteWorker entityDeleteWorker,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
            bool hideJournalForOpenDialog   = false,
            bool hideJournalForCreateDialog = false)
            : base(filterViewModel, unitOfWorkFactory, commonServices, hideJournalForOpenDialog, hideJournalForCreateDialog)
        {
            this.entityDeleteWorker          = entityDeleteWorker ?? throw new ArgumentNullException(nameof(entityDeleteWorker));
            this.unitOfWorkFactory           = unitOfWorkFactory ?? throw new ArgumentNullException(nameof(unitOfWorkFactory));
            this.employeeRepository          = employeeRepository ?? throw new ArgumentNullException(nameof(employeeRepository));
            _deliveryRulesParametersProvider =
                deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));

            canActivateDistrictsSet = commonServices.CurrentPermissionService.ValidatePresetPermission("can_activate_districts_set");
            var permissionResult = commonServices.CurrentPermissionService.ValidateEntityPermission(typeof(DistrictsSet));

            canCreate = permissionResult.CanCreate;
            canUpdate = permissionResult.CanUpdate;
            _сanChangeOnlineDeliveriesToday =
                commonServices.CurrentPermissionService.ValidatePresetPermission("can_change_online_deliveries_today");

            TabName = "Журнал версий районов";
            UpdateOnChanges(typeof(DistrictsSet));
            SetIsStoppedOnlineDeliveriesToday();
        }
예제 #4
0
        public AdditionalLoadingSettingsViewModel(
            ILifetimeScope scope,
            IUnitOfWorkFactory unitOfWorkFactory,
            INavigationManager navigation,
            ICommonServices commonServices,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider)
            : base(unitOfWorkFactory, navigation)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }
            if (commonServices == null)
            {
                throw new ArgumentNullException(nameof(commonServices));
            }
            _deliveryRulesParametersProvider = deliveryRulesParametersProvider ??
                                               throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
            _interactiveService          = commonServices.InteractiveService;
            _nomenclatureSelectorFactory = scope.Resolve <INomenclatureJournalFactory>();

            CanEdit = commonServices.CurrentPermissionService
                      .ValidateEntityPermission(typeof(AdditionalLoadingNomenclatureDistribution)).CanUpdate;

            BottlesCount            = _deliveryRulesParametersProvider.BottlesCountForFlyer;
            FastDeliveryMaxDistance = _deliveryRulesParametersProvider.MaxDistanceToLatestTrackPointKm;
            FlyerAdditionEnabled    = _deliveryRulesParametersProvider.AdditionalLoadingFlyerAdditionEnabled;

            Initialize();
        }
 public AdditionalLoadingModel(IEmployeeRepository employeeRepository, IFlyerRepository flyerRepository,
                               IDeliveryRulesParametersProvider deliveryRulesParametersProvider, IStockRepository stockRepository)
 {
     _employeeRepository = employeeRepository ?? throw new ArgumentNullException(nameof(employeeRepository));
     _flyerRepository    = flyerRepository ?? throw new ArgumentNullException(nameof(flyerRepository));
     _deliveryRulesParametersProvider = deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
     _stockRepository = stockRepository ?? throw new ArgumentNullException(nameof(stockRepository));
 }
 public DeliveryRulesInstanceProvider(
     IDeliveryRepository deliveryRepository,
     IBackupDistrictService backupDistrictService,
     IDeliveryRulesParametersProvider deliveryRulesParametersProvider)
 {
     this.deliveryRepository    = deliveryRepository ?? throw new ArgumentNullException(nameof(deliveryRepository));
     this.backupDistrictService = backupDistrictService ?? throw new ArgumentNullException(nameof(backupDistrictService));
     _deliveryRulesParameters   = deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
 }
예제 #7
0
        public CounterpartyTalkViewModel(
            INavigationManager navigation,
            ITdiCompatibilityNavigation tdinavigation,
            IUnitOfWorkFactory unitOfWorkFactory,
            IRouteListRepository routedListRepository,
            IInteractiveService interactiveService,
            IOrderParametersProvider orderParametersProvider,
            MangoManager manager,
            IEmployeeJournalFactory employeeJournalFactory,
            ICounterpartyJournalFactory counterpartyJournalFactory,
            INomenclatureRepository nomenclatureRepository,
            IOrderRepository orderRepository,
            IParametersProvider parametersProvider,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
            IDeliveryPointJournalFactory deliveryPointJournalFactory) : base(navigation, manager)
        {
            NavigationManager = navigation ?? throw new ArgumentNullException(nameof(navigation));
            _tdiNavigation    = tdinavigation ?? throw new ArgumentNullException(nameof(navigation));

            _routedListRepository            = routedListRepository;
            _interactiveService              = interactiveService ?? throw new ArgumentNullException(nameof(interactiveService));
            _orderParametersProvider         = orderParametersProvider ?? throw new ArgumentNullException(nameof(orderParametersProvider));
            _employeeJournalFactory          = employeeJournalFactory ?? throw new ArgumentNullException(nameof(employeeJournalFactory));
            _counterpartyJournalFactory      = counterpartyJournalFactory ?? throw new ArgumentNullException(nameof(counterpartyJournalFactory));
            _nomenclatureRepository          = nomenclatureRepository ?? throw new ArgumentNullException(nameof(nomenclatureRepository));
            _orderRepository                 = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
            _parametersProvider              = parametersProvider ?? throw new ArgumentNullException(nameof(parametersProvider));
            _deliveryRulesParametersProvider = deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
            _uow = unitOfWorkFactory.CreateWithoutRoot();
            _deliveryPointJournalFactory =
                deliveryPointJournalFactory ?? throw new ArgumentNullException(nameof(deliveryPointJournalFactory));

            if (ActiveCall.CounterpartyIds.Any())
            {
                var clients = _uow.GetById <Counterparty>(ActiveCall.CounterpartyIds);

                foreach (Counterparty client in clients)
                {
                    CounterpartyOrderViewModel model = new CounterpartyOrderViewModel(
                        client, unitOfWorkFactory, tdinavigation, routedListRepository, MangoManager, _orderParametersProvider,
                        _employeeJournalFactory, _counterpartyJournalFactory, _nomenclatureRepository, _parametersProvider,
                        _deliveryRulesParametersProvider);
                    CounterpartyOrdersViewModels.Add(model);
                }

                currentCounterparty = CounterpartyOrdersViewModels.FirstOrDefault().Client;
            }
            else
            {
                throw new InvalidProgramException("Открыт диалог разговора с имеющимся контрагентом, но ни одного id контрагента не найдено.");
            }
        }
        public DeliveryRulesService(
            IDeliveryRepository deliveryRepository,
            IBackupDistrictService backupDistrictService,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider)
        {
            _deliveryRepository              = deliveryRepository ?? throw new ArgumentNullException(nameof(deliveryRepository));
            _backupDistrictService           = backupDistrictService ?? throw new ArgumentNullException(nameof(backupDistrictService));
            _deliveryRulesParametersProvider =
                deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));

            using (var uow = UnitOfWorkFactory.CreateWithoutRoot("Получение графика быстрой доставки"))
            {
                _fastDeliverySchedule = uow.GetById <DeliverySchedule>(deliveryRulesParametersProvider.FastDeliveryScheduleId);
            }
        }
        public PaymentByCardViewModel(
            IEntityUoWBuilder uowBuilder,
            IUnitOfWorkFactory unitOfWorkFactory,
            ICommonServices commonServices,
            CallTaskWorker callTaskWorker,
            IOrderPaymentSettings orderPaymentSettings,
            IOrderParametersProvider orderParametersProvider,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
            Employee currentEmployee) : base(uowBuilder, unitOfWorkFactory, commonServices)
        {
            if (orderPaymentSettings == null)
            {
                throw new ArgumentNullException(nameof(orderPaymentSettings));
            }

            if (orderParametersProvider == null)
            {
                throw new ArgumentNullException(nameof(orderParametersProvider));
            }
            if (deliveryRulesParametersProvider == null)
            {
                throw new ArgumentNullException(nameof(deliveryRulesParametersProvider));
            }

            _callTaskWorker  = callTaskWorker ?? throw new ArgumentNullException(nameof(callTaskWorker));
            _currentEmployee = currentEmployee;

            TabName = "Оплата по карте";

            ItemsList = UoW.GetAll <PaymentFrom>().ToList();

            if (PaymentByCardFrom == null)
            {
                PaymentByCardFrom = ItemsList.FirstOrDefault(p => p.Id == orderPaymentSettings.DefaultSelfDeliveryPaymentFromId);
            }

            Entity.PropertyChanged += Entity_PropertyChanged;

            ValidationContext.ServiceContainer.AddService(orderParametersProvider);
            ValidationContext.ServiceContainer.AddService(deliveryRulesParametersProvider);
        }
예제 #10
0
        public RouteListTrackDlg(IEmployeeRepository employeeRepository, IChatRepository chatRepository, ITrackRepository trackRepository,
                                 IRouteListRepository routeListRepository, IScheduleRestrictionRepository scheduleRestrictionRepository,
                                 IDeliveryRulesParametersProvider deliveryRulesParametersProvider, IUnitOfWorkFactory unitOfWorkFactory, ICommonServices commonServices)
        {
            _employeeRepository            = employeeRepository ?? throw new ArgumentNullException(nameof(employeeRepository));
            _chatRepository                = chatRepository ?? throw new ArgumentNullException(nameof(chatRepository));
            _trackRepository               = trackRepository ?? throw new ArgumentNullException(nameof(trackRepository));
            _routeListRepository           = routeListRepository ?? throw new ArgumentNullException(nameof(routeListRepository));
            _scheduleRestrictionRepository = scheduleRestrictionRepository ?? throw new ArgumentNullException(nameof(scheduleRestrictionRepository));
            _fastDeliveryTime              =
                (deliveryRulesParametersProvider ?? throw new ArgumentNullException(nameof(deliveryRulesParametersProvider)))
                .MaxTimeForFastDelivery;
            _fastDeliveryMaxDistanceKm = deliveryRulesParametersProvider.MaxDistanceToLatestTrackPointKm;
            _commonServices            = commonServices ?? throw new ArgumentNullException(nameof(commonServices));
            _unitOfWorkFactory         = unitOfWorkFactory ?? throw new ArgumentNullException(nameof(unitOfWorkFactory));
            Build();
            TabName = "Мониторинг";
            yTreeViewDrivers.RepresentationModel = new WorkingDriversVM(uow, routelisttrackfilterview1.FilterViewModel);
            yTreeViewDrivers.Selection.Mode      = Gtk.SelectionMode.Multiple;
            yTreeViewDrivers.Selection.Changed  += OnSelectionChanged;

            routelisttrackfilterview1.FilterViewModel.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(routelisttrackfilterview1.FilterViewModel.IsFastDeliveryOnly))
                {
                    Application.Invoke((s, a) => UpdateCarPosition());
                }
                if (args.PropertyName == nameof(routelisttrackfilterview1.FilterViewModel.ShowFastDeliveryCircle))
                {
                    _districtsOverlay.IsVisibile = routelisttrackfilterview1.FilterViewModel.ShowFastDeliveryCircle;
                    Application.Invoke((s, a) => UpdateCarPosition());
                }
            };

            buttonChat.Visible = buttonSendMessage.Visible = false;
            _currentEmployee   = employeeRepository.GetEmployeeForCurrentUser(uow);

            if (_currentEmployee == null)
            {
                MessageDialogHelper.RunErrorDialog("Ваш пользователь не привязан к сотруднику. Чат не будет работать.");
            }

            //Configure map
            gmapWidget.MapProvider   = GMapProviders.GoogleMap;
            gmapWidget.Position      = new PointLatLng(59.93900, 30.31646);
            gmapWidget.HeightRequest = 150;
            //MapWidget.HasFrame = true;
            gmapWidget.Overlays.Add(_districtsOverlay);
            gmapWidget.Overlays.Add(carsOverlay);
            gmapWidget.Overlays.Add(tracksOverlay);
            gmapWidget.Overlays.Add(_fastDeliveryOverlay);
            gmapWidget.ExposeEvent   += GmapWidget_ExposeEvent;
            gmapWidget.OnMarkerEnter += GmapWidgetOnMarkerEnter;
            UpdateCarPosition();
            timerId = GLib.Timeout.Add(carRefreshInterval, new GLib.TimeoutHandler(UpdateCarPosition));
            yenumcomboMapType.ItemsEnum    = typeof(MapProviders);
            yenumcomboMapType.TooltipText  = "Если карта отображается некорректно или не отображается вовсе - смените тип карты";
            yenumcomboMapType.SelectedItem = MapProviders.GoogleMap;

            LoadFastDeliveryDistrictsGeometry();
        }
        public FastDeliveryAvailabilityHistory GetRouteListsForFastDelivery(
            IUnitOfWork uow,
            double latitude,
            double longitude,
            bool isGetClosestByRoute,
            IDeliveryRulesParametersProvider deliveryRulesParametersProvider,
            IEnumerable <NomenclatureAmountNode> nomenclatureNodes,
            Order fastDeliveryOrder = null)
        {
            var maxDistanceToTrackPoint      = deliveryRulesParametersProvider.MaxDistanceToLatestTrackPointKm;
            var driverGoodWeightLiftPerHand  = deliveryRulesParametersProvider.DriverGoodWeightLiftPerHandInKg;
            var maxFastOrdersPerSpecificTime = deliveryRulesParametersProvider.MaxFastOrdersPerSpecificTime;

            var maxTimeForFastDeliveryTimespan = deliveryRulesParametersProvider.MaxTimeForFastDelivery;

            //Переводим всё в минуты
            var trackPointTimeOffset           = (int)deliveryRulesParametersProvider.MaxTimeOffsetForLatestTrackPoint.TotalMinutes;
            var maxTimeForFastDelivery         = (int)maxTimeForFastDeliveryTimespan.TotalMinutes;
            var minTimeForNewOrder             = (int)deliveryRulesParametersProvider.MinTimeForNewFastDeliveryOrder.TotalMinutes;
            var driverUnloadTime               = (int)deliveryRulesParametersProvider.DriverUnloadTime.TotalMinutes;
            var specificTimeForFastOrdersCount = (int)deliveryRulesParametersProvider.SpecificTimeForMaxFastOrdersCount.TotalMinutes;

            var fastDeliveryAvailabilityHistory = new FastDeliveryAvailabilityHistory
            {
                IsGetClosestByRoute = isGetClosestByRoute,
                Order = fastDeliveryOrder,
                MaxDistanceToLatestTrackPointKm = maxDistanceToTrackPoint,
                DriverGoodWeightLiftPerHandInKg = driverGoodWeightLiftPerHand,
                MaxFastOrdersPerSpecificTime    = maxFastOrdersPerSpecificTime,
                MaxTimeForFastDelivery          = maxTimeForFastDeliveryTimespan,
                MinTimeForNewFastDeliveryOrder  = deliveryRulesParametersProvider.MinTimeForNewFastDeliveryOrder,
                DriverUnloadTime = deliveryRulesParametersProvider.DriverUnloadTime,
                SpecificTimeForMaxFastOrdersCount = deliveryRulesParametersProvider.SpecificTimeForMaxFastOrdersCount,
            };

            var order = fastDeliveryAvailabilityHistory.Order;

            if (order != null)
            {
                fastDeliveryAvailabilityHistory.Order         = order.Id == 0 ? null : order;
                fastDeliveryAvailabilityHistory.Author        = order.Author;
                fastDeliveryAvailabilityHistory.DeliveryPoint = order.DeliveryPoint;
                fastDeliveryAvailabilityHistory.District      = order.DeliveryPoint.District;
                fastDeliveryAvailabilityHistory.Counterparty  = order.Client;
            }

            var fastDeliveryHistoryConverter = new FastDeliveryHistoryConverter();

            if (nomenclatureNodes != null)
            {
                fastDeliveryAvailabilityHistory.OrderItemsHistory =
                    fastDeliveryHistoryConverter.ConvertNomenclatureAmountNodesToOrderItemsHistory(nomenclatureNodes, fastDeliveryAvailabilityHistory);
            }

            var distributions = uow.GetAll <AdditionalLoadingNomenclatureDistribution>();

            fastDeliveryAvailabilityHistory.NomenclatureDistributionHistoryItems =
                fastDeliveryHistoryConverter.ConvertNomenclatureDistributionToDistributionHistory(distributions, fastDeliveryAvailabilityHistory);

            var district = GetDistrict(uow, (decimal)latitude, (decimal)longitude);

            if (district?.TariffZone == null || !district.TariffZone.IsFastDeliveryAvailableAtCurrentTime)
            {
                fastDeliveryAvailabilityHistory.AdditionalInformation =
                    new List <string> {
                    "Не найден район, у района отсутствует тарифная зона, либо недоступна экспресс-доставка в текущее время."
                };

                return(fastDeliveryAvailabilityHistory);
            }

            var neededNomenclatures = nomenclatureNodes.ToDictionary(x => x.NomenclatureId, x => x.Amount);

            Track      t       = null;
            TrackPoint tp      = null;
            RouteList  rl      = null;
            TrackPoint tpInner = null;
            FastDeliveryVerificationDetailsNode result = null;
            Employee e = null;

            RouteListItem       rla           = null;
            RouteListItem       rlaTransfered = null;
            Order               o             = null;
            OrderItem           oi            = null;
            OrderEquipment      oe            = null;
            CarLoadDocument     scld          = null;
            CarLoadDocumentItem scldi         = null;
            CountUnclosedFastDeliveryAddressesNode countUnclosedFastDeliveryAddressesAlias = null;

            RouteListNomenclatureAmount ordersAmountAlias        = null;
            RouteListNomenclatureAmount loadDocumentsAmountAlias = null;

            var lastTimeTrackQuery = QueryOver.Of(() => tpInner)
                                     .Where(() => tpInner.Track.Id == t.Id)
                                     .Select(Projections.Max(() => tpInner.TimeStamp));

            //МЛ только в пути и с погруженным запасом
            var routeListNodes = uow.Session.QueryOver(() => rl)
                                 .JoinEntityAlias(() => t, () => t.RouteList.Id == rl.Id)
                                 .Inner.JoinAlias(() => t.TrackPoints, () => tp)
                                 .Inner.JoinAlias(() => rl.Driver, () => e)
                                 .WithSubquery.WhereProperty(() => tp.TimeStamp).Eq(lastTimeTrackQuery)
                                 .And(() => rl.Status == RouteListStatus.EnRoute)
                                 .And(() => rl.AdditionalLoadingDocument.Id != null) // только с погруженным запасом
                                 .SelectList(list => list
                                             .Select(() => tp.TimeStamp).WithAlias(() => result.TimeStamp)
                                             .Select(() => tp.Latitude).WithAlias(() => result.Latitude)
                                             .Select(() => tp.Longitude).WithAlias(() => result.Longitude)
                                             .Select(Projections.Entity(() => rl)).WithAlias(() => result.RouteList))
                                 .TransformUsing(Transformers.AliasToBean <FastDeliveryVerificationDetailsNode>())
                                 .List <FastDeliveryVerificationDetailsNode>();

            //Последняя координата в указанном радиусе
            foreach (var node in routeListNodes)
            {
                var distance      = DistanceHelper.GetDistanceKm(node.Latitude, node.Longitude, latitude, longitude);
                var deliveryPoint = new PointOnEarth(latitude, longitude);
                var proposedRoute = OsrmClientFactory.Instance
                                    .GetRoute(new List <PointOnEarth> {
                    new PointOnEarth(node.Latitude, node.Longitude), deliveryPoint
                }, false, GeometryOverview.False, _globalSettings.ExcludeToll)?.Routes?
                                    .FirstOrDefault();

                node.DistanceByLineToClient.ParameterValue = (decimal)distance;
                node.DistanceByRoadToClient.ParameterValue = decimal.Round((decimal)(proposedRoute?.TotalDistance ?? int.MaxValue) / 1000, 2);
                if (distance < maxDistanceToTrackPoint)
                {
                    node.DistanceByLineToClient.IsValidParameter = node.DistanceByRoadToClient.IsValidParameter = true;
                }
                else
                {
                    node.DistanceByLineToClient.IsValidParameter = node.DistanceByRoadToClient.IsValidParameter = false;
                    node.IsValidRLToFastDelivery = false;
                }

                //Выставляем время последней координаты

                var timeSpan = DateTime.Now - node.TimeStamp;
                node.LastCoordinateTime.ParameterValue = timeSpan.TotalHours > 838 ? new TimeSpan(838, 0, 0) : timeSpan;

                if (node.LastCoordinateTime.ParameterValue.TotalMinutes <= trackPointTimeOffset)
                {
                    node.LastCoordinateTime.IsValidParameter = true;
                }
                else
                {
                    node.LastCoordinateTime.IsValidParameter = false;
                    node.IsValidRLToFastDelivery             = false;
                }
            }

            routeListNodes = routeListNodes
                             .OrderBy(x => isGetClosestByRoute ? x.DistanceByRoadToClient.ParameterValue : x.DistanceByLineToClient.ParameterValue)
                             .ToList();

            //Не более определённого кол-ва заказов с быстрой доставкой в определённый промежуток времени
            var addressCountSubquery = QueryOver.Of(() => rla)
                                       .Inner.JoinAlias(() => rla.Order, () => o)
                                       .Where(() => rla.RouteList.Id == rl.Id)
                                       .And(() => rla.Status == RouteListItemStatus.EnRoute)
                                       .And(() => o.IsFastDelivery)
                                       .And(Restrictions.GtProperty(
                                                Projections.Property(() => rla.CreationDate),
                                                Projections.SqlFunction(
                                                    new SQLFunctionTemplate(NHibernateUtil.DateTime,
                                                                            $"TIMESTAMPADD(MINUTE, -{specificTimeForFastOrdersCount}, CURRENT_TIMESTAMP)"),
                                                    NHibernateUtil.DateTime)))
                                       .Select(Projections.Count(() => rla.Id));

            var routeListsWithCountUnclosedFastDeliveries = uow.Session.QueryOver(() => rl)
                                                            .WhereRestrictionOn(() => rl.Id).IsInG(routeListNodes.Select(x => x.RouteList.Id))
                                                            .SelectList(list => list
                                                                        .Select(() => rl.Id).WithAlias(() => countUnclosedFastDeliveryAddressesAlias.RouteListId)
                                                                        .SelectSubQuery(addressCountSubquery).WithAlias(() => countUnclosedFastDeliveryAddressesAlias.UnclosedFastDeliveryAddresses))
                                                            .TransformUsing(Transformers.AliasToBean <CountUnclosedFastDeliveryAddressesNode>())
                                                            .List <CountUnclosedFastDeliveryAddressesNode>();

            var rlsWithCountUnclosedFastDeliveries =
                routeListsWithCountUnclosedFastDeliveries.ToDictionary(x => x.RouteListId, x => x.UnclosedFastDeliveryAddresses);

            foreach (var node in routeListNodes)
            {
                var countUnclosedFastDeliveryAddresses = rlsWithCountUnclosedFastDeliveries[node.RouteList.Id];
                node.UnClosedFastDeliveries.ParameterValue = countUnclosedFastDeliveryAddresses;
                if (countUnclosedFastDeliveryAddresses < maxFastOrdersPerSpecificTime)
                {
                    node.UnClosedFastDeliveries.IsValidParameter = true;
                }
                else
                {
                    node.UnClosedFastDeliveries.IsValidParameter = false;
                    node.IsValidRLToFastDelivery = false;
                }
            }

            //Время доставки следующего (текущего) заказа позволяет взять быструю доставку
            foreach (var routeListNode in routeListNodes)
            {
                RouteListItem latestAddress = null;

                var orderedEnRouteAddresses = routeListNode.RouteList.Addresses
                                              .Where(x => x.Status == RouteListItemStatus.EnRoute).OrderBy(x => x.IndexInRoute).ToList();

                var orderedCompletedAddresses = routeListNode.RouteList.Addresses
                                                .Where(x => x.Status == RouteListItemStatus.Completed).OrderBy(x => x.IndexInRoute).ToList();

                var latestCompletedAddress = orderedCompletedAddresses.OrderByDescending(x => x.StatusLastUpdate).FirstOrDefault();

                if (latestCompletedAddress != null)
                {
                    latestAddress = orderedEnRouteAddresses.FirstOrDefault(x => x.IndexInRoute > latestCompletedAddress.IndexInRoute);
                }
                if (latestAddress == null)
                {
                    latestAddress = orderedEnRouteAddresses.FirstOrDefault();
                }

                if (latestAddress != null)
                {
                    var neededTime1 = maxTimeForFastDelivery - latestAddress.Order.DeliveryPoint.MinutesToUnload;
                    if (neededTime1 < minTimeForNewOrder)
                    {
                        routeListNode.RemainingTimeForShipmentNewOrder.ParameterValue   = new TimeSpan(0, neededTime1, 0);
                        routeListNode.RemainingTimeForShipmentNewOrder.IsValidParameter = false;
                        routeListNode.IsValidRLToFastDelivery = false;
                        continue;
                    }

                    var water19Count = latestAddress.Order.OrderItems
                                       .Where(x => x.Nomenclature.TareVolume == TareVolume.Vol19L && x.Nomenclature.Category == NomenclatureCategory.water)
                                       .Sum(x => x.Count);

                    var orderItemsSummaryWeight = latestAddress.Order.OrderItems
                                                  .Where(x => x.Nomenclature.TareVolume != TareVolume.Vol19L || x.Nomenclature.Category != NomenclatureCategory.water)
                                                  .Sum(x => x.Nomenclature.Weight * x.Count);

                    var orderEquipmentsSummaryWeight = latestAddress.Order.OrderEquipments
                                                       .Where(x => x.Direction == Direction.Deliver)
                                                       .Sum(x => x.Nomenclature.Weight * x.Count);

                    var goodsSummaryWeight = orderItemsSummaryWeight + orderEquipmentsSummaryWeight;

                    //Время выгрузки след. заказа:
                    //(Суммарный вес прочих товаров / кол-во кг, которое водитель может унести в одной руке + кол-во 19л) / 2 руки * время выгрузки в 2 руках 2 бутылей или товара
                    var unloadTime  = (goodsSummaryWeight / driverGoodWeightLiftPerHand + water19Count) / 2 * driverUnloadTime;
                    var neededTime2 = maxTimeForFastDelivery - (int)unloadTime;

                    if (neededTime2 < minTimeForNewOrder)
                    {
                        routeListNode.RemainingTimeForShipmentNewOrder.ParameterValue   = new TimeSpan(0, neededTime2, 0);
                        routeListNode.RemainingTimeForShipmentNewOrder.IsValidParameter = false;
                        routeListNode.IsValidRLToFastDelivery = false;
                    }
                    else
                    {
                        routeListNode.RemainingTimeForShipmentNewOrder.ParameterValue   = new TimeSpan(0, neededTime2, 0);
                        routeListNode.RemainingTimeForShipmentNewOrder.IsValidParameter = true;
                    }
                }
                else
                {
                    routeListNode.RemainingTimeForShipmentNewOrder.ParameterValue   = maxTimeForFastDeliveryTimespan;
                    routeListNode.RemainingTimeForShipmentNewOrder.IsValidParameter = true;
                }
            }

            var rlIds = routeListNodes.Select(x => x.RouteList.Id).ToArray();

            //OrderItems
            var orderItemsToDeliver = uow.Session.QueryOver <RouteListItem>(() => rla)
                                      .Inner.JoinAlias(() => rla.Order, () => o)
                                      .Inner.JoinAlias(() => o.OrderItems, () => oi)
                                      .Left.JoinAlias(() => rla.TransferedTo, () => rlaTransfered)
                                      .WhereRestrictionOn(() => rla.RouteList.Id).IsIn(rlIds)
                                      .WhereRestrictionOn(() => oi.Nomenclature.Id).IsIn(neededNomenclatures.Keys)
                                      .Where(() =>
                                             //не отменённые и не недовозы
                                             rla.Status != RouteListItemStatus.Canceled && rla.Status != RouteListItemStatus.Overdue
                                             // и не перенесённые к водителю; либо перенесённые с погрузкой; либо перенесённые и это экспресс-доставка (всегда без погрузки)
                                             && (!rla.WasTransfered || rla.NeedToReload || o.IsFastDelivery)
                                             // и не перенесённые от водителя; либо перенесённые и не нужна погрузка и не экспресс-доставка (остатки по экспресс-доставке не переносятся)
                                             && (rla.Status != RouteListItemStatus.Transfered || (!rlaTransfered.NeedToReload && !o.IsFastDelivery)))
                                      .SelectList(list => list
                                                  .SelectGroup(() => rla.RouteList.Id).WithAlias(() => ordersAmountAlias.RouteListId)
                                                  .SelectGroup(() => oi.Nomenclature.Id).WithAlias(() => ordersAmountAlias.NomenclatureId)
                                                  .SelectSum(() => oi.Count).WithAlias(() => ordersAmountAlias.Amount))
                                      .TransformUsing(Transformers.AliasToBean <RouteListNomenclatureAmount>())
                                      .Future <RouteListNomenclatureAmount>();

            //OrderEquipments
            var orderEquipmentsToDeliver = uow.Session.QueryOver <RouteListItem>(() => rla)
                                           .Inner.JoinAlias(() => rla.Order, () => o)
                                           .Inner.JoinAlias(() => o.OrderEquipments, () => oe)
                                           .Left.JoinAlias(() => rla.TransferedTo, () => rlaTransfered)
                                           .WhereRestrictionOn(() => rla.RouteList.Id).IsIn(rlIds)
                                           .WhereRestrictionOn(() => oe.Nomenclature.Id).IsIn(neededNomenclatures.Keys)
                                           .Where(() =>
                                                  //не отменённые и не недовозы
                                                  rla.Status != RouteListItemStatus.Canceled && rla.Status != RouteListItemStatus.Overdue
                                                  // и не перенесённые к водителю; либо перенесённые с погрузкой; либо перенесённые и это экспресс-доставка (всегда без погрузки)
                                                  && (!rla.WasTransfered || rla.NeedToReload || o.IsFastDelivery)
                                                  // и не перенесённые от водителя; либо перенесённые и не нужна погрузка и не экспресс-доставка (остатки по экспресс-доставке не переносятся)
                                                  && (rla.Status != RouteListItemStatus.Transfered || (!rlaTransfered.NeedToReload && !o.IsFastDelivery)))
                                           .And(() => oe.Direction == Direction.Deliver)
                                           .SelectList(list => list
                                                       .SelectGroup(() => rla.RouteList.Id).WithAlias(() => ordersAmountAlias.RouteListId)
                                                       .SelectGroup(() => oe.Nomenclature.Id).WithAlias(() => ordersAmountAlias.NomenclatureId)
                                                       .Select(Projections.Sum(Projections.Cast(NHibernateUtil.Decimal, Projections.Property(() => oe.Count)))
                                                               ).WithAlias(() => ordersAmountAlias.Amount))
                                           .TransformUsing(Transformers.AliasToBean <RouteListNomenclatureAmount>())
                                           .Future <RouteListNomenclatureAmount>();

            //CarLoadDocuments
            var allLoaded = uow.Session.QueryOver <CarLoadDocument>(() => scld)
                            .Inner.JoinAlias(() => scld.Items, () => scldi)
                            .WhereRestrictionOn(() => scld.RouteList.Id).IsIn(rlIds)
                            .WhereRestrictionOn(() => scldi.Nomenclature.Id).IsIn(neededNomenclatures.Keys)
                            .SelectList(list => list
                                        .SelectGroup(() => scld.RouteList.Id).WithAlias(() => loadDocumentsAmountAlias.RouteListId)
                                        .SelectGroup(() => scldi.Nomenclature.Id).WithAlias(() => loadDocumentsAmountAlias.NomenclatureId)
                                        .SelectSum(() => scldi.Amount).WithAlias(() => loadDocumentsAmountAlias.Amount))
                            .TransformUsing(Transformers.AliasToBean <RouteListNomenclatureAmount>())
                            .Future <RouteListNomenclatureAmount>();

            var allToDeliver = orderItemsToDeliver
                               .Union(orderEquipmentsToDeliver)
                               .GroupBy(x => new { x.RouteListId, x.NomenclatureId })
                               .Select(group => new RouteListNomenclatureAmount
            {
                RouteListId    = group.Key.RouteListId,
                NomenclatureId = group.Key.NomenclatureId,
                Amount         = group.Sum(x => x.Amount)
            })
                               .ToList();

            //Выбираем МЛ, в котором хватает запаса номенклатур на поступивший быстрый заказ
            foreach (var routeListNode in routeListNodes)
            {
                var toDeliverForRL = allToDeliver.Where(x => x.RouteListId == routeListNode.RouteList.Id).ToList();
                var loadedForRL    = allLoaded.Where(x => x.RouteListId == routeListNode.RouteList.Id).ToList();

                foreach (var need in neededNomenclatures)
                {
                    var toDeliver = toDeliverForRL.FirstOrDefault(x => x.NomenclatureId == need.Key)?.Amount ?? 0;
                    var loaded    = loadedForRL.FirstOrDefault(x => x.NomenclatureId == need.Key)?.Amount ?? 0;

                    var onBoard = loaded - toDeliver;
                    if (onBoard < need.Value)
                    {
                        routeListNode.IsGoodsEnough.ParameterValue   = false;
                        routeListNode.IsGoodsEnough.IsValidParameter = false;
                        routeListNode.IsValidRLToFastDelivery        = false;
                        break;
                    }
                }
            }

            if (routeListNodes != null)
            {
                fastDeliveryAvailabilityHistory.Items = fastDeliveryHistoryConverter
                                                        .ConvertVerificationDetailsNodesToAvailabilityHistoryItems(routeListNodes, fastDeliveryAvailabilityHistory);
            }

            return(fastDeliveryAvailabilityHistory);
        }