public static DivergenciaPernoite Processar(Rota rota, IEnumerable <Infra.Ocorrencia> ocorrenciasRepouso, IEnumerable <Deposito> depositos)
        {
            DivergenciaPernoite divergenciaPernoite = new DivergenciaPernoite();
            int quantidadeRealizada = DivergenciaDiariaOcorrencia.Processar(rota).QuantidadeDiariaRealizada - 1;
            int quantidadePrevista  = DivergenciaDiariaOcorrencia.Processar(rota).QuantidadeDiariaPrevista - 1;

            var pernoites = ObtemPernoites(ocorrenciasRepouso);

            foreach (var pernoite in pernoites)
            {
                decimal latInicioRepouso = pernoite.GetCoordenadasInicioRepouso().lat;
                decimal lonInicioRepouso = pernoite.GetCoordenadasInicioRepouso().lon;

                decimal latFimRepouso = pernoite.GetCoordenadasFimRepouso().lat;
                decimal lonFimRepouso = pernoite.GetCoordenadasFimRepouso().lon;

                foreach (var deposito in depositos)
                {
                    if (deposito.PontoInteresse != null)
                    {
                        int metrosRaioDeposito = deposito.PontoInteresse.QtMetrosRaio;

                        decimal latDeposito = deposito.PontoInteresse.NrLatitude;
                        decimal lonDeposito = deposito.PontoInteresse.NrLongitude;

                        (double distInicioRepousoAoDeposito, _) = Coordenada.DistanciaLinhaReta(latInicioRepouso, lonInicioRepouso, latDeposito, lonDeposito);
                        (double distFimRepousoAoDeposito, _)    = Coordenada.DistanciaLinhaReta(latFimRepouso, lonFimRepouso, latDeposito, lonDeposito);

                        // Se o motorista estiver dentro do raio de algum dos CDs
                        // (ou seja, dormiu em um CD),
                        // então é desconsiderada a pernoite referente a esse repouso.
                        if (distInicioRepousoAoDeposito <= metrosRaioDeposito || distFimRepousoAoDeposito <= metrosRaioDeposito)
                        {
                            quantidadeRealizada--;
                            break;
                        }
                    }
                }
            }

            divergenciaPernoite.QuantidadeRealizada = quantidadeRealizada < 0 ? 0 : quantidadeRealizada;
            divergenciaPernoite.QuantidadePrevista  = quantidadePrevista < 0 ? 0 : quantidadePrevista;

            // Não envia o indicador ao WS quando os dias realizados estiverem dentro do previsto
            if (divergenciaPernoite.QuantidadeRealizada <= divergenciaPernoite.QuantidadePrevista)
            {
                divergenciaPernoite.SetExibirOcorrenciaNoXml(false);
            }

            return(divergenciaPernoite);
        }
        public static AdicionalMeiaPernoite Processar(IEnumerable <Infra.Ocorrencia> ocorrencias,
                                                      IEnumerable <Infra.Deposito> depositos,
                                                      Rota rota)
        {
            _adicionalMeiaPernoite = new AdicionalMeiaPernoite();

            if (rota.UnidadeNegocio != null &&
                rota.UnidadeNegocio.DtHoraLimRestanteRetorno.HasValue &&
                rota.UnidadeNegocio.QtQuilometroRestante.HasValue)
            {
                bool   validacaoDistanciaMotoristaDeposito = true;
                double qtMetrosRestante = Convert.ToDouble(rota.UnidadeNegocio.QtQuilometroRestante.Value * 1000);

                var ultimaOcorrenciaAntesDoHorarioLimite = ocorrencias
                                                           .Where(ocorrencia => ocorrencia.IdOcorrencia != (short)TipoOcorrencia.ChegadaRevenda && ocorrencia.DtInclusao.TimeOfDay <= rota.UnidadeNegocio.DtHoraLimRestanteRetorno.Value.TimeOfDay)
                                                           .OrderByDescending(ocorrencia => ocorrencia.DtInclusao)
                                                           .First();

                foreach (var deposito in depositos)
                {
                    (double distanciaMetros, int tempo) = Coordenada.Distancia(Convert.ToDouble(ultimaOcorrenciaAntesDoHorarioLimite.NrLatitude),
                                                                               Convert.ToDouble(ultimaOcorrenciaAntesDoHorarioLimite.NrLongitude),
                                                                               Convert.ToDouble(deposito.PontoInteresse.NrLatitude),
                                                                               Convert.ToDouble(deposito.PontoInteresse.NrLongitude));

                    if (deposito.IdAtivo && distanciaMetros <= qtMetrosRestante)
                    {
                        validacaoDistanciaMotoristaDeposito = false;
                        break;
                    }
                }

                var divergenciaDiaria = DivergenciaDiariaOcorrencia.Processar(rota);

                _adicionalMeiaPernoite.HouveDivergencia = Convert.ToInt16(validacaoDistanciaMotoristaDeposito && divergenciaDiaria.QuantidadeDiariaRealizada > 0);
            }

            return(_adicionalMeiaPernoite);
        }