Example #1
0
        /// <summary>
        ///     <para>Completes the response with schedule information, considering that the client informed the <see cref="Door2DoorCore.Types.Door2DoorRequest.D2dRequestTripDateKind"/> attributes as the departing dates.</para>
        ///     <para>This method also takes into account any external flight option that might have been informed in the request.</para>
        /// </summary>
        /// <param name="route">
        ///     Route: <see cref="Door2DoorCore.Types.Door2DoorResponse.Route"/>.
        /// </param>
        /// <param name="departureDateTime">
        ///     Desired departure date.
        /// </param>
        /// <param name="flightChosen">
        ///     If an external flight was informed for this route. <see cref="Door2DoorCore.Types.Door2DoorRequest.OuterFlightOption"/>
        /// </param>
        /// <param name="legIndex">
        ///     Whether this is the inbound(0) or outbound(1) leg of the trip
        /// </param>
        private void BuildItineraryScheduleDepartingAt(ref Route route, DateTime departureDateTime, bool flightChosen, int legIndex)
        {
            if (route.Segments != null && route.Segments.Length > 0)
            {
                // resumo com totais de tempo e precos da rota atual
                route.RouteTotals = new RouteTotals();
                decimal routePrice = 0;
                int weeklyFrequency = 0;
                TimeSpan frequency = new TimeSpan(0, 0, 0);

                DateTime departureDateCurrent = new DateTime(departureDateTime.Ticks);
                route.Segments[0].DepartureDateTime = departureDateCurrent;

                for (int i = 0; i < route.Segments.Length; i++)
                {
                    Segment seg = route.Segments[i];

                    if (seg.Kind.ToLower().Equals("flight"))
                    {
                        bool achouVoo = false;
                        ItineraryDates itineraryDates = new ItineraryDates();
                        seg.ChosenItinerary = null; //escolhido automaticamente

                        if (flightChosen) // é uma alteração de itinerario, um voo foi alterado
                        {
                            if (_req.chosenRoute[legIndex].segmentIndex == i)
                            {
                                // a opcao de voo escolhida tem que bater com o horario do schedule
                                if (_req.chosenRoute[legIndex].flightSegment.flightLegs[0].departureDate >= departureDateCurrent)
                                {
                                    achouVoo = true;

                                    BuildINewtinFromChosenRoute(ref seg, legIndex);

                                    seg.DepartureDateTime = _req.chosenRoute[legIndex].flightSegment.flightLegs[0].departureDate;
                                    seg.ArrivalDateTime = _req.chosenRoute[legIndex].flightSegment.flightLegs[_req.chosenRoute[legIndex].flightSegment.flightLegs.Length - 1].arrivalDate;

                                    TimeSpan nextDepTime = new TimeSpan(departureDateCurrent.Hour, departureDateCurrent.Minute, 0);
                                    for (int j = 0; j < seg.Itineraries.Length - 1; j++)
                                    {
                                        int hour = int.Parse(seg.Itineraries[j].Legs[0].Hops[seg.Itineraries[j].Legs[0].Hops.Length - 1].STime.Substring(0, 2));
                                        int min = int.Parse(seg.Itineraries[j].Legs[0].Hops[seg.Itineraries[j].Legs[0].Hops.Length - 1].STime.Substring(3, 2));

                                        TimeSpan hopArrivalTime = new TimeSpan(hour, min, 0);
                                        route.Segments[i].Itineraries[j].ValidForSchedule = hopArrivalTime >= nextDepTime;
                                    }
                                    departureDateCurrent = seg.ArrivalDateTime.Value.AddMinutes(_minutesAfterFlight);
                                }
                            }
                        }
                        else
                        {
                            DateTime originalDepDate = departureDateCurrent.AddMinutes(_flightAntecipation);//duas horas de antecedencia no aeroporto -> melhorar
                            DateTime lastDepDate = departureDateCurrent.AddMinutes(_flightAntecipation);//duas horas de antecedencia no aeroporto -> melhorar
                            for (int j = 0; j < seg.Itineraries.Length; j++)
                            {
                                Itinerary itinerary = seg.Itineraries[j];
                                Leg leg = itinerary.Legs[0];

                                // hora de partida do primeiro voo da opcao atual
                                string[] sTime = leg.Hops[0].STime.Split(':');
                                //hora de chegada do ultimo voo da opcao atual
                                string[] tTime = leg.Hops[leg.Hops.Length - 1].TTime.Split(':');
                                DateTime tempDepDate = new DateTime(originalDepDate.Year, originalDepDate.Month, originalDepDate.Day, int.Parse(sTime[0]), int.Parse(sTime[1]), 0);
                                itinerary.ValidForSchedule = tempDepDate >= originalDepDate; // valido para horario de chegada informado?

                                if ((!achouVoo && tempDepDate >= originalDepDate) || (achouVoo && tempDepDate < lastDepDate && tempDepDate >= originalDepDate))
                                {
                                    achouVoo = true; // sei q pelo menos um voo é valido

                                    if (!seg.DepartureDateTime.HasValue || tempDepDate < seg.DepartureDateTime.Value)
                                    {
                                        lastDepDate = tempDepDate;
                                        seg.DepartureDateTime = tempDepDate;
                                        seg.ChosenItinerary = j;
                                        int dayChange = 0;
                                        for (int k = 0; k < leg.Hops.Length; k++)
                                        {
                                            if (leg.Hops[k].DayChange.HasValue)
                                            {
                                                dayChange += leg.Hops[k].DayChange.Value;
                                            }
                                        }
                                        DateTime tempArrDate = new DateTime(originalDepDate.Year, originalDepDate.Month, originalDepDate.Day, int.Parse(tTime[0]), int.Parse(tTime[1]), 0);
                                        //eu peguei um erro na api,
                                        //em raros casos ele coloca a data de chegada antes da de saida mas nao acrescenta valor ao dayChange :-s
                                        if (tempArrDate <= tempDepDate && dayChange == 0)
                                        {
                                            dayChange = 1;
                                        }
                                        tempArrDate = tempArrDate.AddDays(dayChange);
                                        seg.ArrivalDateTime = tempArrDate;
                                        departureDateCurrent = tempArrDate.AddMinutes(_minutesAfterFlight); // tempo para sair do aeroporto;
                                    }
                                }
                            }
                        }

                        if (!achouVoo)
                        {
                            DateTime originalDepDate = departureDateCurrent.AddMinutes(_flightAntecipation);
                            if (originalDepDate.Day == departureDateCurrent.Day)
                            {
                                originalDepDate = new DateTime(departureDateCurrent.Year, departureDateCurrent.Month, departureDateCurrent.Day, 0, 0, 0);
                                originalDepDate = originalDepDate.AddDays(1);
                                //originalDepDate = departureDateCurrent.Date;
                            }
                            DateTime lastDepDate = originalDepDate.Date;
                            for (int j = 0; j < seg.Itineraries.Length; j++)
                            {
                                Itinerary itinerary = seg.Itineraries[j];
                                Leg leg = itinerary.Legs[0];

                                itinerary.ValidForSchedule = true; // valido para horario de chegada informado?

                                // hora de partida do primeiro voo da opcao atual
                                string[] sTime = leg.Hops[0].STime.Split(':');
                                //hora de chegada do ultimo voo da opcao atual
                                string[] tTime = leg.Hops[leg.Hops.Length - 1].TTime.Split(':');

                                DateTime tempDepDate = new DateTime(originalDepDate.Year, originalDepDate.Month, originalDepDate.Day, int.Parse(sTime[0]), int.Parse(sTime[1]), 0);
                                if (j == 0 || tempDepDate < lastDepDate)
                                {
                                    itinerary.ValidForSchedule = true;
                                    achouVoo = true; // sei q pelo menos um voo é valido
                                    lastDepDate = tempDepDate;
                                    seg.DepartureDateTime = tempDepDate;
                                    seg.ChosenItinerary = j;
                                    int dayChange = 0;
                                    for (int k = 0; k < leg.Hops.Length; k++)
                                    {
                                        if (leg.Hops[k].DayChange.HasValue)
                                        {
                                            dayChange += leg.Hops[k].DayChange.Value;
                                        }
                                    }
                                    DateTime tempArrDate = new DateTime(originalDepDate.Year, originalDepDate.Month, originalDepDate.Day, int.Parse(tTime[0]), int.Parse(tTime[1]), 0);
                                    //eu peguei um erro na api,
                                    //em raros casos ele coloca a data de chegada antes da de saida mas nao acrescenta valor ao dayChange :-s
                                    if (tempArrDate <= tempDepDate && dayChange == 0)
                                    {
                                        dayChange = 1;
                                    }
                                    tempArrDate = tempArrDate.AddDays(dayChange);
                                    seg.ArrivalDateTime = tempArrDate;
                                    departureDateCurrent = tempArrDate.AddMinutes(_minutesAfterFlight); // tempo para sair do aeroporto
                                }
                            }
                        }

                        // calcula o preco do segmento
                        if (seg.IndicativePrice != null)
                        {
                            if (seg.Itineraries[seg.ChosenItinerary.Value].Legs[0].IndicativePrice != null)
                            {
                                routePrice += seg.Itineraries[seg.ChosenItinerary.Value].Legs[0].IndicativePrice.Price;
                            }
                        }
                    }
                    else
                    {
                        //  A API tem um bug, as vezes manda caminhar, 50 minutos, as vezes mais de uma hora
                        //  Eles ficaram de resolver, mas até lá, eu desconstruí a conta de taxi e caminhada deles.
                        //  Se for caminhada e tiver mais que x minutos, eu transformo em Taxi ;)
                        if (seg.Kind.ToLower().Equals("walk") && seg.Duration > _maxWalkingMinutes && route.Segments.Length > 1)
                        {
                            WalkIntoTaxiTransformation(ref seg);
                        }

                        //faz o calculo do preco
                        if (seg.IndicativePrice != null)
                        {
                            routePrice += seg.IndicativePrice.Price;
                        }
                        //calcula frequencia semanal
                        weeklyFrequency = GetWeeklyFrequency(seg);
                        //calcula a frequencia total do segmento em horas e minutos
                        frequency = CalcFrequency(weeklyFrequency);

                        seg.Frequency = GetSegmentFrequency(seg);

                        //duracao total em minutos, somando frequencia
                        int duration = seg.Duration + frequency.Minutes + (frequency.Hours * 60);

                        //pega data do prox ponto (i + 1) ou do ponto de chegada
                        DateTime departureDate = departureDateCurrent;
                        departureDateCurrent = departureDateCurrent.AddMinutes(duration);
                        DateTime arrivalDate = departureDateCurrent;

                        seg.DepartureDateTime = departureDate;
                        seg.ArrivalDateTime = arrivalDate;
                    }

                    // calcula o resumo da rota atual
                    CalcRouteTotals(ref route, i, true);
                }
                route.IndicativePrice.Price = routePrice;
            }
        }
Example #2
0
        /// <summary>
        ///     Total times and costs fo the informed segment
        /// </summary>
        /// <param name="route">
        ///      <see cref="Door2DoorCore.Types.Door2DoorResponse.Route"/>
        /// </param>
        /// <param name="segmentIndex">
        ///     Which segment of the informed route.
        /// </param>
        /// <param name="departingAt">
        ///     Is this a <see cref="Door2DoorCore.Types.Door2DoorRequest.D2dRequestTripDateKind"/> indicating a departure date or not?
        /// </param>
        private void CalcRouteTotals(ref Route route, int segmentIndex, bool departingAt)
        {
            Segment segment = route.Segments[segmentIndex];

            route.RouteTotals.TotalDistance += segment.Distance;

            if (departingAt)
            {
                if (segmentIndex > 0) // não for o primeiro segmento
                {
                    if (route.Segments[segmentIndex - 1].ArrivalDateTime.HasValue && segment.DepartureDateTime.HasValue)
                    {
                        route.RouteTotals.TotalTimeWaiting = route.RouteTotals.TotalTimeWaiting.Add(segment.DepartureDateTime.Value - route.Segments[segmentIndex - 1].ArrivalDateTime.Value);
                    }
                }
            }
            else
            {
                if (segmentIndex < route.Segments.Length - 1) // não for o ultimo segmento
                {
                    if (route.Segments[segmentIndex + 1].DepartureDateTime.HasValue && segment.ArrivalDateTime.HasValue)
                    {
                        route.RouteTotals.TotalTimeWaiting = route.RouteTotals.TotalTimeWaiting.Add(route.Segments[segmentIndex + 1].DepartureDateTime.Value - segment.ArrivalDateTime.Value);
                    }
                }
            }

            switch (segment.Kind.ToLower())
            {
                case "flight":
                    if (segment.ChosenItinerary.HasValue)
                    {
                        route.RouteTotals.TotalPriceOfFlight += segment.Itineraries[segment.ChosenItinerary.Value].Legs[0].IndicativePrice.Price;
                        int totalDuration = segment.Itineraries[segment.ChosenItinerary.Value].Legs[0].Hops.Sum(e => e.Duration);
                        route.RouteTotals.TotalTimeOnFlight = route.RouteTotals.TotalTimeOnFlight.Add(new TimeSpan(0, totalDuration, 0));
                    }

                    break;
                case "bus":
                    if (segment.IndicativePrice != null)
                    {
                        route.RouteTotals.TotalPriceOfBus += segment.IndicativePrice.Price;
                    }
                    route.RouteTotals.TotalTimeOnBus = route.RouteTotals.TotalTimeOnBus.Add(new TimeSpan(0, segment.Duration, 0));

                    break;
                case "walk":
                    route.RouteTotals.TotalTimeOnWalk = route.RouteTotals.TotalTimeOnWalk.Add(new TimeSpan(0, segment.Duration, 0));

                    break;
                case "car":
                    if (segment.IndicativePrice != null)
                    {
                        route.RouteTotals.TotalPriceOfCar += segment.IndicativePrice.Price;
                    }
                    route.RouteTotals.TotalTimeOnCar = route.RouteTotals.TotalTimeOnCar.Add(new TimeSpan(0, segment.Duration, 0));

                    break;
                case "train":
                    if (segment.IndicativePrice != null)
                    {
                        route.RouteTotals.TotalPriceOfTrain += segment.IndicativePrice.Price;
                    }
                    route.RouteTotals.TotalTimeOnTrain = route.RouteTotals.TotalTimeOnTrain.Add(new TimeSpan(0, segment.Duration, 0));

                    break;
                default:
                    break;
            }
        }
Example #3
0
        /// <summary>
        ///     <para>Completes the response with schedule information, considering that the client informed the <see cref="Door2DoorCore.Types.Door2DoorRequest.D2dRequestTripDateKind"/> attributes as the arrival dates.</para>
        ///     <para>This method also takes into account any external flight option that might have been informed in the request.</para>
        /// </summary>
        /// <param name="route">
        ///     Route: <see cref="Door2DoorCore.Types.Door2DoorResponse.Route"/>
        /// </param>
        /// <param name="arrivalDateTime">
        ///     Desired arrival date at destination
        /// </param>
        /// <param name="flightChosen">
        ///     If an external flight was informed for this route. <see cref="Door2DoorCore.Types.Door2DoorRequest.OuterFlightOption"/>
        /// </param>
        /// <param name="legIndex">
        ///     Whether this is the inbound(0) or outbound(1) leg of the trip
        /// </param>
        private void BuildItineraryScheduleArrivingAt(ref Route route, DateTime arrivalDateTime, bool flightChosen, int legIndex)
        {
            if (route.Segments != null && route.Segments.Length > 0)
            {
                // resumo com totais de tempo e precos da rota atual
                route.RouteTotals = new RouteTotals();

                // diferenca entre a data da viagem e agora
                // irá ajudar no calculo do tempo para sair da origem
                int weeklyFrequency = 0;
                TimeSpan frequency = new TimeSpan(0, 0, 0);
                decimal routePrice = 0;

                //adiciona data de chegada ao destino final
                route.Segments[route.Segments.Length - 1].ArrivalDateTime = null;
                route.Segments[route.Segments.Length - 1].DepartureDateTime = null;

                for (int i = route.Segments.Length - 1; i >= 0; i--)
                {
                    //pega data do prox ponto (i + 1) ou do ponto de chegada
                    DateTime arrivalDateNextStop = new DateTime();
                    arrivalDateNextStop = i == route.Segments.Length - 1 ? arrivalDateTime : route.Segments[i + 1].DepartureDateTime.Value;

                    //route.Segments[i].Subkind = _path;

                    // Se for voo procura um voo que possibilite chegada no horário
                    // no futuro devera pegar de uma fonte externa
            /*voo*/             if (route.Segments[i].Kind.ToLower().Equals("flight"))
                    {
                        bool achouVoo = false;
                        ItineraryDates itineraryDates = new ItineraryDates();
                        route.Segments[i].ChosenItinerary = null; //escolhido automaticamente

                        if (flightChosen) // é uma alteração de itinerario, um voo foi alterado
                        {
                            if (_req.chosenRoute[legIndex].segmentIndex == i)
                            {
                                // a opcao de voo escolhida tem que bater com o horario do schedule
                                if (_req.chosenRoute[legIndex].flightSegment.flightLegs[_req.chosenRoute[legIndex].flightSegment.flightLegs.Length - 1].arrivalDate <= arrivalDateNextStop)
                                {
                                    achouVoo = true;

                                    BuildINewtinFromChosenRoute(ref route.Segments[i], legIndex);

                                    itineraryDates.departureDateTime = _req.chosenRoute[legIndex].flightSegment.flightLegs[0].departureDate;
                                    itineraryDates.arrivalDateTime = _req.chosenRoute[legIndex].flightSegment.flightLegs[_req.chosenRoute[legIndex].flightSegment.flightLegs.Length - 1].arrivalDate;

                                    TimeSpan nextArrivalTime = new TimeSpan(arrivalDateNextStop.Hour, arrivalDateNextStop.Minute, 0);
                                    for (int j = 0; j < route.Segments[i].Itineraries.Length - 1; j++)
                                    {
                                        int hour = int.Parse(route.Segments[i].Itineraries[j].Legs[0].Hops[route.Segments[i].Itineraries[j].Legs[0].Hops.Length - 1].TTime.Substring(0, 2));
                                        int min = int.Parse(route.Segments[i].Itineraries[j].Legs[0].Hops[route.Segments[i].Itineraries[j].Legs[0].Hops.Length - 1].TTime.Substring(3, 2));

                                        TimeSpan hopArrivalTime = new TimeSpan(hour, min, 0);
                                        route.Segments[i].Itineraries[j].ValidForSchedule = hopArrivalTime <= nextArrivalTime;
                                    }
                                }
                            }
                        }
                        else
                        {
                            // para cada opcao de voo
                            for (int j = 0; j < route.Segments[i].Itineraries.Length; j++)
                            {
                                route.Segments[i].Itineraries[j].ValidForSchedule = false; // valido para horario de chegada informado?

                                Leg itinerary = route.Segments[i].Itineraries[j].Legs[0];
                                //verifica se itinerario atual bate com o horario do proximo segmento
                                ItineraryDates currentItineraryDates = MatchflightToSchedule(itinerary, arrivalDateNextStop);

                                // pode ter ou nao voo chegando no dia para chegar no horario
                                if (currentItineraryDates.arrivalDateTime != null)
                                {
                                    achouVoo = true;
                                    route.Segments[i].Itineraries[j].ValidForSchedule = true;// valido para horario de chegada informado?
                                    if (itineraryDates.arrivalDateTime == null)
                                    {
                                        itineraryDates = currentItineraryDates;
                                        route.Segments[i].ChosenItinerary = j;//indice do itinerario escolhido automatico
                                    }
                                    else
                                    {
                                        if (currentItineraryDates.arrivalDateTime > itineraryDates.arrivalDateTime)
                                        {
                                            itineraryDates = currentItineraryDates;
                                            route.Segments[i].ChosenItinerary = j; //indice do itinerario escolhido automatico
                                        }
                                    }
                                }
                            }

                            if (!achouVoo)// Nao tinha nenhum voo que chegaria no horario naquele dia, pegar o voo com maior horario de chegada e determinar que é no dia anterior
                            {
                                // acha o itinerario que tem a hora de chegada maior
                                Leg latestItinerary = FindLatestItinerary(ref route.Segments[i]);

                                itineraryDates = CalcItineraryArrivalDates(latestItinerary, arrivalDateNextStop);
                            }
                        }

                        // seta segmento com datas de chegada e partida
                        route.Segments[i].DepartureDateTime = itineraryDates.departureDateTime;
                        route.Segments[i].ArrivalDateTime = itineraryDates.arrivalDateTime;

                        // calcula o preco do segmento
                        if (route.Segments[i].IndicativePrice != null)
                        {
                            if (route.Segments[i].Itineraries[route.Segments[i].ChosenItinerary.Value].Legs[0].IndicativePrice != null)
                            {
                                routePrice += route.Segments[i].Itineraries[route.Segments[i].ChosenItinerary.Value].Legs[0].IndicativePrice.Price;
                            }
                        }
                    }
            /*nao voo*/         else
                    {
                        //  A API tem um bug, as vezes manda caminhar, 50 minutos, as vezes mais de uma hora.
                        //  Eles ficaram de resolver, mas até lá, eu desconstruí a conta de taxi e caminhada deles.
                        //  Se for caminhada e tiver mais que x minutos, eu transformo em Taxi ;)
                        if (route.Segments[i].Kind.ToLower().Equals("walk") && route.Segments[i].Duration > _maxWalkingMinutes && route.Segments.Length > 1)
                        {
                            WalkIntoTaxiTransformation(ref route.Segments[i]);
                        }

                        //faz o calculo do preco
                        if (route.Segments[i].IndicativePrice != null)
                        {
                            routePrice += route.Segments[i].IndicativePrice.Price;
                        }

                        //calcula frequencia semanal
                        weeklyFrequency = GetWeeklyFrequency(route.Segments[i]);
                        //calcula a frequencia total do segmento em horas e minutos
                        frequency = CalcFrequency(weeklyFrequency);

                        route.Segments[i].Frequency = GetSegmentFrequency(route.Segments[i]);

                        //duracao total em minutos, somando frequencia
                        int duration = route.Segments[i].Duration + frequency.Minutes + (frequency.Hours * 60);

                        int anticipation = 0; // em minutos
                        // se o proximo segmento é voo, calcular chegada com antecipacao
                        if (i < route.Segments.Length - 1 && route.Segments[i + 1].Kind.ToLower().Equals("flight"))
                        {
                            anticipation = _flightAntecipation;
                        }

                        //pega data do prox ponto (i + 1) ou do ponto de chegada
                        DateTime departureDate = arrivalDateNextStop.AddMinutes(-duration);
                        DateTime arrivalDate = departureDate.AddMinutes(duration);
                        departureDate = departureDate.AddMinutes(-anticipation);
                        arrivalDate = arrivalDate.AddMinutes(-anticipation);

                        route.Segments[i].DepartureDateTime = departureDate;
                        route.Segments[i].ArrivalDateTime = arrivalDate;
                    }

                    // calcula o resumo da rota atual
                CalcRouteTotals(ref route, i, false);
                }
                route.IndicativePrice.Price = routePrice;
            }
        }