Projeto Python: Automação para Batida de Ponto
Na última empresa em que trabalhei, os colaboradores deveriam realizar a batida de ponto através de uma ferramenta na web, um processo oneroso de ter que se autenticar no website, clicar na data, escrever uma justificativa (e.g. Horário de trabalho), digitar a hora da entrada 1, depois digitar a hora da saída 1 (para o horário de almoço), e por fim digitar as horas da entrada 2 e saída 2. Tudo isso para cada dia do mês.
Pensando nisso, resolvi desenvolver um script de automação em Python que acesse o website, preencha automaticamente os horários de ponto a partir de uma planilha Excel, e por fim mostre o resultado da operação.
Para este projeto, foram utilizadas as seguintes bibliotecas:
- selenium: Para interação com o website;
- openpyxl: Para manipulação de planilha Excel;
- tkinter: Para criação da janela de login do usuário;
- os: Para manipulação do arquivo config.txt;
- datetime: Para manipulação e cálculo de horas;
- glob: Para verificar se pdf de holerite já existe no diretório;
- time: Para adicionar tempo de espera ao baixar o pdf de holerite.
Verificação de arquivo de configuração
Nesta primeira parte, a primeira ação do script é verificar se o arquivo de configuração (config.txt) existe no mesmo local do script, caso negativo, ele o cria. Este arquivo contém três parâmetros:
download_path: caminho do diretório que conterá os holerites baixados;
username: nome do usuário para fazer login;
password: senha do usuário para fazer login.
Os valores destes três parâmetros do config.txt poderão ser editados pelo usuário.
Janela de Login
A função login monta e apresenta uma janela de login para o usuário, com a opção de baixar demonstrativo de pagamento (holerite) selecionada. Os campos Usuario e Senha são importados do arquivo config.txt.
Planilha de Marcação de Ponto
A planilha sheet.xlsx contem todos os dias do ano e os horários de expediente já preenchidos. Note que na sexta-feira fiz uma hora extra, portanto atualizei a célula da SAIDA 2 com 18:30. Caso eu tivesse trabalho apenas por meio período em determinado dia, bastaria apagar as células da ENTRADA 2 e SAIDA 2, deixando-as em branco. A célula TOTAL será preenchida pelo script com o total de horas trabalhadas. A célula EXTRA será preenchida pelo script com o total de horas extras. A célula PONTO será preenchida pelo script com OK (ponto marcado), DSR (Descanso Semanal Remunerado) para os domingos, FOLGA (para os sábados), FERIADO, ABONO ou qualquer outro status que esteja descrito no website daquela data. Caso o script verifique que a data no website possua o status FOLGA, DSR ou FERIADO, ele não fará a marcação e preencherá a célula da coluna PONTO daquele dia com algum destes status. Caso eu tenha trabalhado em algum feriado, será necessário preencher a célula da coluna PONTO com “MARCAR” (sem as aspas) para forçar a marcação do ponto no website. E para corrigir um ponto já marcado no website, será necessário preencher a célula da coluna PONTO com “DESFAZER” (sem as aspas) para que o script desfaça a marcação no website para aquela data e preencha a célula PONTO com “DESFEITO”.
Importante: O script só processará as linhas da planilha cujas células da coluna PONTO estejam em branco ou com as palavras “MARCAR” ou “DESFAZER” e cuja data seja passada (data do dia corrente ou datas futuras não serão processadas).
Função de Marcar Ponto
Os argumentos desta função são importados da planilha sheet.xlsx colunas DATA, ENTRADA, SAIDA, ENTRADA, SAIDA e PONTO. A função retorna “OK” para ponto marcado com sucesso, ou o status descrito para aquele dia no website.
Função de Controle
Esta função é responsável por efetivamente acessar o website, baixar o arquivo pdf de demonstrativo de pagamento, percorrer as linhas de data da planilha, manipular e calcular horas, chamar a função de Marcar Ponto para cada data, atualizar a planilha com os status, e apresentar o resultado do processo todo em formato de tabela no terminal. Devido a quantidade de verificações e tratamento de erros, e também por ser a função que controla todo o processo de batida de ponto, esta função possui a maior quantidade de linhas de código.
Ao final da execução do script, é apresentada a tabela no terminal com as datas processadas:
Ao conferir a planilha, podemos ver as células de status preenchidas pela automação:
A função de controle também captura informações de Banco de Horas, Horas em Folha, e Acumulado de Horas e preenche em uma tabela na mesma planilha, porém, o próprio website apagava essas informações assim que o mês virava, deixando as informações na tabela um tanto confusas caso não fossem atualizadas a tempo pelo script, então resolvi ignorar essas linhas e focar apenas nas horas totais trabalhadas e nas horas extras:
Conclusão
Considero este um dos projetos de automação que mais gostei de desenvolver, de ver o quão poderosa é a biblioteca Selenium, e como a linguagem de programação Python consegue lidar com inúmeras tarefas diferentes (interface de usuário, Web Scraping, planilhas, arquivos e diretórios) de maneira profissional e eficaz. O método element_to_be_clickable da biblioteca Selenium aguarda o elemento DOM ser carregado antes de realizar a ação, isto é algo excelente, pois já trabalhei com equipes de desenvolvimento de Automation Anywhere e observava o quanto eles sofriam com a falta de um método do tipo, pois tinham que encher o código com atrasos para que o objeto HTML fosse carregado antes das instruções continuarem, e muitas vezes o tempo era curto demais, ocasionando em erro de execução. O grande problema de adicionar atrasos (delays) no código, é que se o tempo definido for de dez segundos e o objeto carregar em dois segundos, a próxima instrução só será executada depois de decorridos os oito segundos restantes, ocasionando em uma automação demorada para concluir. Este problema não existe com o Selenium.