public RelatorioPonto gerarRelatorio(Funcionario funcionario, DateTime inicio, DateTime fim)
        {
            Check.Require(fim >= inicio, "Período inválido. O início deve vir antes do fim!");
            Check.Require(funcionario != null, "O funcionário deve ser válido");

            var todosPontos = pontoRepository.findPontosNoIntervalo(funcionario, inicio, fim, false, false)
                              .GroupBy(x => x.Data)
                              .Select(group => group.First());
            var diasFaltando           = inicio.Range(fim).Except(todosPontos.Select(x => x.Data));
            var feriadosNaoTrabalhados = diasFaltando
                                         .Where(x => feriadoService.isFeriado(x));

            //Se é um feriado, não deve ser contado como falta
            diasFaltando = diasFaltando.Except(feriadosNaoTrabalhados);

            var todosDias = todosPontos
                            .Select(x => criarDia(x))
                            .Concat(
                diasFaltando.Select(x => criarDia(x))
                )
                            .Concat(feriadosNaoTrabalhados
                                    .Select(x =>
                                            criarDia(feriadoService.getFeriado(x))
                                            )
                                    )
                            .OrderBy(x => x.Data)
                            .ToList();

            return(new RelatorioPonto(funcionario, inicio, fim, jornadaAtiva, todosDias));
        }
        public DiaTrabalho criarDiaTrabalho(IDataHoraStrategy dataHoraStrategy, SessaoLogin sessaoLogin)
        {
            DateTime dt = dataHoraStrategy.getDataHoraAtual();

            if (repository.existePontoDia(sessaoLogin.UsuarioLogado as Funcionario, dt))
            {
                throw new PontoDiaJaExisteException(dt);
            }

            if (feriadoService.isFeriado(dt))
            {
                return(new DiaTrabalhoFeriado(feriadoService.getFeriado(dt), dt.TimeOfDay, sessaoLogin.UsuarioLogado as Funcionario));
            }

            return(new DiaTrabalhoComum(dt.Date, dt.TimeOfDay, sessaoLogin.UsuarioLogado as Funcionario));
        }