Ir para o conteúdo

Lab 4: Desenvolvimento de automações Desktop

Cadastro de novos produtos no sistema Fakturama

Nesse workshop você construirá uma automação que cadastra novos produtos no sistema Fakturama.

Consiste em preencher os campos necessários e ao final salvar o produto no sistema.

Download do Fakturama

O Fakturama é um software de código aberto com diversas funcionalidades comerciais que opera em múltiplos sistemas operacionais, uma dessas funcionalidades é o cadastro de produtos, o qual utilizaremos nesse workshop.

O download do aplicativo pode ser feito através desse link.

Tela de download do fakturama

BotCity Studio

Extensão no Visual Studio Code

A extensão BotCity Studio para o Visual Studio Code permite que você crie automações com visão computacional diretamente no seu editor de código. Ele é um assistente de código que ajuda a interagir com elementos gráficos de aplicativos diversos, como desktop e web, faz o reconhecimento de elementos e gera o código automaticamente.

Instalação e login

Na barra de extensões do Visual Studio Code, procure por BotCity Studio e instale a extensão.

Após instalado, clique no ícone do BotCity Studio na barra lateral do VS Code e na aba Account faça o login com as mesmas credenciais do Orquestrador BotCity Maestro.

Extensão BotCity Studio

Iniciar o BotCity Studio

Na aba Services clique em Start para iniciar o BotCity Studio.

BotCity Studio

O BotCity Studio fará a autenticação e abrirá o assistente de código para visão computacional.

BotCity Studio

Carregue o projeto no BotCity Studio

Caso esteja usando outro editor de código, você pode carregar o projeto no BotCity Studio seguindo a documentação.

Executar o aplicativo Fakturama

Com o BotCity Studio configurado, o próximo passo é abrir o aplicativo Fakturama utilizando o caminho do executável que está instalado na máquina.

Busque no código do arquivo bot.py pelo comentário # Implement here your logic... e adicione o seguinte trecho abaixo dele:

...
import os
...
# Implement here your logic...
# Caminho onde está o executável Fakturama
path_fakturama = r"C:\Program Files\Fakturama2\Fakturama.exe"

if not os.path.exists(path_fakturama):
    raise FileNotFoundError(f"O caminho {path_fakturama} não existe.")

# Abre o aplicativo do Fakturama
bot.execute(path_fakturama)

Boa Prática

Neste trecho de código, utilizamos a função os.path.exists para verificar se o caminho especificado em path_fakturama existe. Se o caminho não existir, uma exceção FileNotFoundError é levantada com uma mensagem explicativa.

Isso garante que o caminho fornecido para o executável do aplicativo Fakturama existe antes de tentar utilizá-lo, prevenindo erros e falhas que poderiam ocorrer se o caminho não fosse válido ou se o arquivo não estivesse presente.

Além disso, está levantando uma exceção específica FileNotFoundError ajuda a identificar rapidamente o tipo de erro que ocorreu.

Nota

O caminho do executável pode variar conforme a instalação do aplicativo na máquina.

Ao executarmos a automação, o aplicativo Fakturama será aberto:

Acessando Fakturama

Nota

Lembre de retirar a linha de código bot.browse("http://www.botcity.dev") que está no template, pois não utilizaremos o navegador nesse projeto.

Definir o processo de automação

Com o aplicativo Fakturama aberto, defina o processo de cadastro de novos produtos:

  • Identificar e clicar no botão New product no menu lateral
  • Identificar e preencher os campos:
    • Item Number
    • Name
    • Category
    • GTIN
    • suplier code
    • Description
    • Price
    • Cost price
    • Allownace
    • Stock
  • Identificar e clicar no botão Save

Lista de produtos

Para facilitar o preenchimento dos campos, utilize uma lista de produtos fictícios. Nesse momento, inserira essa lista no código do arquivo bot.py, antes de carregar o aplicativo Fakturama:

# Lista de produtos
products = [
    {
        "Item Number": 1,
        "Name": "Laptop",
        "Category": "Eletrônico",
        "GTIN": "1234567890123",
        "Supplier Code": "SUP001",
        "Description": "Alto desempenho com as últimas especificações.",
        "Price": 999.99,
        "Cost Price": 799.99,
        "Allowance": 50,
        "Stock": 100
    },
    {
        "Item Number": 2,
        "Name": "Smartphone",
        "Category": "Eletrônico",
        "GTIN": "9876543210987",
        "Supplier Code": "SUP002",
        "Description": "Smartphone com recursos avançados de câmera e display.",
        "Price": 699.99,
        "Cost Price": 549.99,
        "Allowance": 30,
        "Stock": 150
    },
    {
        "Item Number": 3,
        "Name": "Tenis de corrida",
        "Category": "Esporte",
        "GTIN": "7654321098765",
        "Supplier Code": "SUP003",
        "Description": "Confortável e resistente, ideal para corridas.",
        "Price": 89.99,
        "Cost Price": 69.99,
        "Allowance": 20,
        "Stock": 200
    }
]

Para percorrer essa lista e preencher os campos no aplicativo Fakturama, vamos utilizar um laço de repetição for, dentro dele identificar e preencher os campos com os dados de cada produto.

Também crie uma variável success antes da repetição e incremente em +1 a cada novo cadastro, para contar quantos produtos foram cadastrados com sucesso.

# Abre o aplicativo do Fakturama
bot.execute(path_fakturama)

# Variável para contar os produtos cadastrados com sucesso
success = 0

# Repetição para cada produto
for product in products:
    ...
    success += 1

Identificar os elementos da tela

Nessa etapa, você identificará os elementos no aplicativo Fakturama e definirá as ações que serão realizadas.

Identificar o botão New product

Com a tela do aplicativo Fakturama aberta, faça uma captura de tela pressionando a tecla print screen no seu teclado. Isso fará com que a imagem da tela do Fakturama seja carregada no BotCity Studio.

Fakturama tela inicial

Nota

Certifique-se que o cursor está na linha correta no arquivo bot.py, onde o código será gerado automaticamente, antes de começar os recortes dos elementos.

Com a imagem carregada no BotCity Studio, faça um clique próximo ao botão New product para que a ferramenta aplique um zoom e faça o recorte o elemento:

Botão New product

O recorte é feito com o mouse, clicando e arrastando até selecionar dessa maneira:

Botão New product

Ao recortar o elemento, preencha os campos Name e Action da seguinte forma:

Botão New product

Ao clicar em Submit, o seguinte trecho de código será gerado pelo BotCity Studio, no arquivo bot.py:

...
# Repetição para cada produto
for product in products:

    # Identifica e clica no botão "New product"
    if not bot.find( "new-product", matching=0.97, waiting_time=10000):
        not_found("new-product")
    bot.click()
Nesse momento, execute no terminal, o comando python bot.py para testar a ação de clicar no botão New product no aplicativo Fakturama.

O aplicativo deve abrir 3 novas abas, pois há 3 produtos na lista:

Fakturama novo produto

Preencher os campos

Você pode manter apenas uma das abas abertas e atualizar a captura de tela no BotCity Studio, pressionando a tecla print screen no seu teclado, para assim identificar os campos que precisam ser preenchidos.

Começando pelo campo Item Number, faça o recorte do elemento de texto como anteriormente, porém dessa vez selecione a ação Click Relative para esse elemento:

Campo Item Number

Ao clicar em Submit, o clique relativo nos permite clicar qualquer lugar da tela, tendo como referência o elemento recortado. Nesse caso, clique no campo ao lado de Item Number para que o cursor seja posicionado dentro dele:

Campo Item Number

O seguinte trecho de código será gerado pelo BotCity Studio:

...
# Preenche o campo "Item Number"
if not bot.find( "item-number", matching=0.97, waiting_time=10000):
    not_found("item-number")
bot.click_relative(137, 8)
Nesse momento, preencha a informação desse campo mapeado, utilizando o método type_keys() da seguinte forma:
bot.type_keys(str(product["Item Number"]))

Nota

Atenção ao tipo de dado que é recebido, o método type_keys() espera uma string, utilize o método str() para converter o valor sempre que ele for diferente de string.

Dependendo do comportamento de cada aplicativo, você pode utilizar diferentes abordagens para o preenchimento dos campos. O Fakturama aceita o uso da tecla tab para avançar para o próximo campo, siga nessa abordagem.

...
# Avança e preenche o nome do produto
bot.tab()
bot.type_keys(product["Name"])

# Avança e preenche a categoria
bot.tab()
bot.type_keys(product["Category"])

# Avança e preenche o GTIN
bot.tab()
bot.type_keys(product["GTIN"])

# Avança e preenche o Supplier Code
bot.tab()
bot.type_keys(product["Supplier Code"])

# Avança e preenche a descrição
bot.tab()
bot.type_keys(product["Description"])

Nota

Verifique sempre o comportamento do aplicativo para garantir que a abordagem utilizada está correta.

Note que ao chegar no campo Price, já existe um valor preenchido, para isso é necessário limpar o campo antes de preencher, para que o valor fique correto.

Para isso, utilize o método ctrl_a() para selecionar todo o texto, depois preencher com o método type_keys(). O mesmo será feito para o campo Cost Price e Stock.

...
# Avança, seleciona tudo e preenche o campo Price
bot.tab()
bot.control_a()
bot.type_keys(str(product["Price"]))

# Avança, seleciona tudo e preenche o custo
bot.tab()
bot.control_a()
bot.type_keys(str(product["Cost Price"]))

# Avança e preenche a margem
bot.tab()
bot.type_keys(str(product["Allowance"]))

# Avança 2 vezes, seleciona tudo e preenche o estoque
bot.tab()
bot.tab()
bot.control_a()
bot.type_keys(str(product["Stock"]))

Para realizar um teste, execute o código no terminal com o comando python bot.py e verifique se os campos estão sendo preenchidos corretamente.

Salvar o produto

Notem que após o preenchimento dos campos, o botão Save fica disponível para ser clicado. Nessa etapa utilize a visão computacional novamente.

Com o aplicativo Fakturama aberto e os campos preenchidos, faça uma captura de tela pressionando a tecla print screen no seu teclado para atualizar a imagem de referência no BotCity Studio.

Fakturama campos preenchidos

Nota

Certifique-se que o cursor está na linha correta no arquivo bot.py, onde o código será gerado automaticamente, antes de começar os recortes dos elementos.

Faça o processo de clicar próximo ao botão Save onde o zoom será aplicado, recorte o elemento e selecione a ação Click:

Fakturama botão salvar

Ao clicar em Submit, o código gerado será:

...
# Clica no botão "Save"
if not bot.find("botao_save", matching=0.97, waiting_time=10000):
    not_found("botao_save")
bot.click()

Fechar a aba do produto

Para finalizar o laço de repetição, feche a aba do produto com o método control_w() após salvar o mesmo.

...
# Fecha a aba do produto
bot.control_w()
Agora execute o código no terminal com o comando python bot.py e verifique se os produtos serão salvos corretamente.

Os produtos aparecerão salvos na aba de produtos do aplicativo Fakturama:

Fakturama produtos salvos

Criando função para preencher formulário de produtos

Boas Práticas

O uso de funções em Python contribui para um código mais estruturado, fácil de entender e manter, promovendo eficiência no desenvolvimento e garantindo uma base sólida para futuras expansões, modificações e testes.

Após implementar e testar o fluxo para preencher o formulário de produtos, o próximo passo é criar uma função dedicada para isola-lo. Isso permitirá uma melhor organização e manutenibilidade do código. Nesse caso, podemos definir a função no arquivo bot.py.

Ao modularizar o fluxo, facilitamos a compreensão e o gerenciamento das responsabilidades do código, além de tornar a manutenção mais simples e eficiente. A nova função organizada e isolada irá garantir que o fluxo de preenchimento do formulário seja reutilizável e mais fácil de testar.

from typing import Dict, Any

...
def fill_product_form(bot: DesktopBot, product: Dict[str, any], success: int) -> None:
    try:
        # Identifica e clica no botão "New product"
        if not bot.find("new_product", matching=0.97, waiting_time=10000):
            not_found("new_product")
        bot.click()

        # Preenche o campo "Item Number"
        if not bot.find("item_number", matching=0.97, waiting_time=10000):
            not_found("item_number")
        bot.click_relative(137, 8)
        bot.type_keys(str(product["Item Number"]))

        # Avança e preenche o nome do produto
        bot.tab()
        bot.type_keys(product["Name"])

        # Avança e preenche a categoria
        bot.tab()
        bot.type_keys(product["Category"])

        # Avança e preenche o GTIN
        bot.tab()
        bot.type_keys(product["GTIN"])

        # Avança e preenche o Supplier Code
        bot.tab()
        bot.type_keys(product["Supplier Code"])

        # Avança e preenche a descrição
        bot.tab()
        bot.type_keys(product["Description"])

        # Avança, seleciona tudo e preenche o campo Price
        bot.tab()
        bot.control_a()
        bot.type_keys(str(product["Price"]))

        # Avança, seleciona tudo e preenche o custo
        bot.tab()
        bot.control_a()
        bot.type_keys(str(product["Cost Price"]))

        # Avança e preenche a margem
        bot.tab()
        bot.type_keys(str(product["Allowance"]))

        # Avança 2 vezes, seleciona tudo e preenche o estoque
        bot.tab()
        bot.tab()
        bot.control_a()
        bot.type_keys(str(product["Stock"]))

        # Clica no botão "Save"
        if not bot.find("botao_save", matching=0.97, waiting_time=10000):
            not_found("botao_save")
        bot.click()

        # Fecha a aba do produto
        bot.control_w()

        # Incrementa a variável de sucesso
        success += 1
    except Exception as e:
            print(f"Erro ao cadastrar produto: {product["Item Number"]} {product["Name"]}: {e}")

Estruturando função main

Boas Práticas

O uso de try, except e finally em Python é fundamental para a gestão de exceções e para garantir que o código seja robusto e confiável.

Usando-os com cuidado é possível lidar com erros de maneira eficaz, garantir que recursos sejam liberados e manter o código limpo e legível. Capturar exceções específicas e realizar a limpeza adequada são aspectos-chave para uma boa gestão de exceções.

Com a nossa função fill_product_form criada, agora basta estruturar a função main para executarmos nosso processo de forma completa, para isso incluíremos um bloco try/except/finally no código, como mostra abaixo:

# Variável para contar os produtos cadastrados com sucesso
success = 0

try:
    # Abre o aplicativo do Fakturama
    bot.execute(path_fakturama)

    # Preenche form com dados dos produtos
    for product in products:
        fill_product_form(bot, product, success)

except Exception as e:
    print(f"Erro inesperado: {e}")

finally:
    # Fecha o aplicativo do Fakturama
    bot.alt_f4()

Finalizar o processo

Para finalizar o processo, faça uma integração com o Orquestrador BotCity Maestro. Com o orquestrador, você pode agendar a execução da automação, monitorar o status e os logs de execução, além de receber notificações diversas sobre a execução.

Para finalizar tarefas de acordo com o bloco executado, incluíremos nos bloco try:

status = AutomationTaskFinishStatus.SUCCESS
message = f"Produtos cadastrados com sucesso!"
E no bloco except:
print(f"Erro inesperado: {e}")
status = AutomationTaskFinishStatus.FAILED
message = f"Erro inesperado: {e}"

E deixaremos que o bloco finally feche o Fakturama pressionando o alt_f4 e finalize a tarefa no Orquestrador passando status, message, Total de itens processado e Itens processados com sucesso como parâmetros.

...
# Fecha o aplicativo do Fakturama
bot.alt_f4()

# Descomente para marcar esta tarefa como finalizada no BotMaestro
maestro.finish_task(
    task_id=execution.task_id,
    status=status,
    message=message,
    total_items=len(products),
    processed_items=success
)

Desta forma, ao executar através do Orquestrador BotCity Maestro, a tarefa será marcada como finalizada com sucesso.