Esempio n. 1
0
        /// <summary>
        ///     Calculate departure and arrival dates of a valid itinerary
        /// </summary>
        /// <param name="itinerary">
        ///     Itinerary
        /// </param>
        /// <param name="arrivalDateNextStop">
        ///     Arrival date for the next itinerary
        /// </param>
        /// <returns>
        ///     Arrival and Departure dates
        /// </returns>
        private ItineraryDates CalcItineraryArrivalDates(Leg itinerary, DateTime arrivalDateNextStop)
        {
            ItineraryDates itinerarySchedule = new ItineraryDates();
            // hora de partida do primeiro voo da opcao atual
            string[] sTime = itinerary.Hops[0].STime.Split(':');
            //hora de chegada do ultimo voo da opcao atual
            string[] tTime = itinerary.Hops[itinerary.Hops.Length - 1].TTime.Split(':');

            int arrDayChange = 0;
            DateTime tempArrivalDate = new DateTime(arrivalDateNextStop.Year, arrivalDateNextStop.Month, arrivalDateNextStop.Day, int.Parse(tTime[0]), int.Parse(tTime[1]), 0);
            if (tempArrivalDate >= arrivalDateNextStop)//tem que ser no dia anterior
            {
                arrDayChange = 1;
            }

            int depDayChange = arrDayChange;
            for (int j = 0; j < itinerary.Hops.Length; j++)
            {
                if (itinerary.Hops[j].DayChange.HasValue)
                {
                    depDayChange += itinerary.Hops[j].DayChange.Value;
                }
            }

            tempArrivalDate = tempArrivalDate.AddDays(-arrDayChange);

            itinerarySchedule.arrivalDateTime = tempArrivalDate;
            itinerarySchedule.departureDateTime = new DateTime(arrivalDateNextStop.Year, arrivalDateNextStop.Month, arrivalDateNextStop.Day, int.Parse(sTime[0]), int.Parse(sTime[1]), 0).AddDays(-depDayChange);

            return itinerarySchedule;
        }
Esempio n. 2
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;
            }
        }
Esempio n. 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 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;
            }
        }
Esempio n. 4
0
        /// <summary>
        ///     Tries to Match the given Itinerary to the desired Arrival Date at the destination.
        ///     Return an empty object if the itinerary does not match.
        /// </summary>
        /// <param name="itinerary">
        ///     Itinerary desired to be matched
        /// </param>
        /// <param name="arrivalDateNextStop">
        ///     DateTime to match
        /// </param>
        /// <returns>
        ///     <see cref="Door2DoorCore.Types.Door2DoorResponse"/> indicating Arrival and Departure dates. Both 'null' if not valid.
        /// </returns>
        private ItineraryDates MatchflightToSchedule(Leg itinerary, DateTime arrivalDateNextStop)
        {
            ItineraryDates flightOption = new ItineraryDates();

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

            DateTime tempArrivalDate = new DateTime(arrivalDateNextStop.Year, arrivalDateNextStop.Month, arrivalDateNextStop.Day, int.Parse(tTime[0]), int.Parse(tTime[1]), 0);

            if (tempArrivalDate <= arrivalDateNextStop)
            {
                //Achou um voo que chega antes do proximo segmento da viagem

                int dayChange = 0;
                for (int i = 0; i < itinerary.Hops.Length; i++)
                {
                    if (itinerary.Hops[i].DayChange.HasValue)
                    {
                        dayChange += itinerary.Hops[i].DayChange.Value;
                    }
                }

                DateTime departureDate = new DateTime(arrivalDateNextStop.Year, arrivalDateNextStop.Month, arrivalDateNextStop.Day, int.Parse(sTime[0]), int.Parse(sTime[1]), 0).AddDays(-dayChange);

                flightOption.departureDateTime = departureDate;
                flightOption.arrivalDateTime = tempArrivalDate;
            }
            return flightOption;
        }