worker-automate-hub 0.5.805__py3-none-any.whl → 0.5.807__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +69 -86
- worker_automate_hub/tasks/jobs/opex_capex.py +98 -23
- {worker_automate_hub-0.5.805.dist-info → worker_automate_hub-0.5.807.dist-info}/METADATA +1 -1
- {worker_automate_hub-0.5.805.dist-info → worker_automate_hub-0.5.807.dist-info}/RECORD +6 -6
- {worker_automate_hub-0.5.805.dist-info → worker_automate_hub-0.5.807.dist-info}/WHEEL +0 -0
- {worker_automate_hub-0.5.805.dist-info → worker_automate_hub-0.5.807.dist-info}/entry_points.txt +0 -0
@@ -577,103 +577,86 @@ async def abertura_livros_fiscais(task: RpaProcessoEntradaDTO) -> RpaRetornoProc
|
|
577
577
|
|
578
578
|
await worker_sleep(2)
|
579
579
|
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
while
|
580
|
+
# flag para controlar se é a primeira vez
|
581
|
+
primeira_confirmacao = True
|
582
|
+
|
583
|
+
while True:
|
584
|
+
janela_aberta = False
|
585
|
+
|
586
|
+
# 1. Verifica se a imagem apareceu e clica em 'Sim' na janela "Informação"
|
584
587
|
try:
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
588
|
+
if pyautogui.locateOnScreen(imagem, confidence=0.9):
|
589
|
+
print("Imagem 'livros_incluidos' apareceu na tela.")
|
590
|
+
try:
|
591
|
+
app_info = Application().connect(title="Informação", timeout=5)
|
592
|
+
info_window = app_info["Informação"]
|
593
|
+
info_window.set_focus()
|
594
|
+
console.print("Clicando em 'Sim' na janela Informação...")
|
595
|
+
info_window.child_window(class_name="Button", found_index=0).click_input()
|
596
|
+
except Exception as e:
|
597
|
+
print(f"Erro ao clicar em 'Sim' na janela Informação: {e}")
|
598
|
+
except Exception as e:
|
599
|
+
print(f"[Erro ao procurar imagem]: {e}")
|
595
600
|
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
601
|
+
# Verifica se a janela TMsgBox de aviso está aberta
|
602
|
+
try:
|
603
|
+
app_msgbox = Application().connect(class_name="TMsgBox", timeout=10)
|
604
|
+
box = app_msgbox["TMsgBox"]
|
605
|
+
print("Janela 'TMsgBox' encontrada.")
|
606
|
+
box.set_focus()
|
607
|
+
box.child_window(class_name="TBitBtn", found_index=0).click_input()
|
608
|
+
print("Clicou no botão 'TBitBtn'.")
|
609
|
+
except ElementNotFoundError:
|
610
|
+
pass
|
611
|
+
except Exception as e:
|
612
|
+
print(f"[Erro ao procurar/clicar na TMsgBox]: {e}")
|
600
613
|
|
601
|
-
#
|
614
|
+
# 2. Verifica e trata janela de confirmação TMessageForm
|
602
615
|
try:
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
616
|
+
app_msg = Application().connect(class_name="TMessageForm", timeout=2)
|
617
|
+
form = app_msg["TMessageForm"]
|
618
|
+
console.print("Janela de confirmação 'TMessageForm' encontrada.")
|
619
|
+
form.set_focus()
|
620
|
+
|
621
|
+
idx = 1 if primeira_confirmacao else 0
|
622
|
+
try:
|
623
|
+
form.child_window(class_name="TButton", found_index=idx).click_input()
|
624
|
+
print(f"Clicou no botão de confirmação (found_index={idx}).")
|
625
|
+
primeira_confirmacao = False # nas próximas vezes será 0
|
626
|
+
except Exception as e:
|
627
|
+
print(f"[Falha ao clicar no botão found_index={idx}]: {e}")
|
628
|
+
|
629
|
+
except ElementNotFoundError:
|
630
|
+
pass
|
612
631
|
except Exception as e:
|
613
|
-
|
614
|
-
console.print(f"Falha ao salvar screenshot do 'Aviso': {e}")
|
632
|
+
print(f"[Erro ao procurar/clicar na TMessageForm]: {e}")
|
615
633
|
|
616
|
-
|
617
|
-
|
634
|
+
await worker_sleep(5)
|
635
|
+
|
636
|
+
# 3. Verifica se a janela do relatório está aberta
|
618
637
|
try:
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
except Exception:
|
626
|
-
pass
|
627
|
-
texto_aviso = " ".join(
|
628
|
-
dict.fromkeys(partes)
|
629
|
-
) # remove duplicados mantendo ordem
|
630
|
-
console.print(f"Texto do Aviso: {texto_aviso}")
|
638
|
+
app_report = Application().connect(class_name="TFrmPreviewRelatorio", timeout=2)
|
639
|
+
janela = app_report["TFrmPreviewRelatorio"]
|
640
|
+
print("Janela 'TFrmPreviewRelatorio' encontrada.")
|
641
|
+
janela_aberta = True
|
642
|
+
except ElementNotFoundError:
|
643
|
+
pass
|
631
644
|
except Exception as e:
|
632
|
-
|
645
|
+
print(f"[Erro ao procurar TFrmPreviewRelatorio]: {e}")
|
633
646
|
|
634
|
-
#
|
635
|
-
|
636
|
-
"
|
637
|
-
|
638
|
-
]
|
647
|
+
# Se encontrou a janela de relatório, sai
|
648
|
+
if janela_aberta:
|
649
|
+
print("Relatório carregado. Saindo do loop.")
|
650
|
+
break
|
639
651
|
|
640
|
-
|
641
|
-
|
642
|
-
|
652
|
+
# Verifica tempo limite
|
653
|
+
if time.time() - inicio > tempo_limite:
|
654
|
+
print("Tempo esgotado. Relatório não carregado.")
|
655
|
+
break
|
656
|
+
|
657
|
+
print("Aguardando janela de relatório... (verificando novas confirmações se houver)")
|
658
|
+
time.sleep(intervalo)
|
643
659
|
|
644
|
-
if contem_msg_erro:
|
645
|
-
console.print(
|
646
|
-
"Confirmação de erro pelo texto da janela 'Aviso'. Retornando falha."
|
647
|
-
)
|
648
|
-
retorno_msg = "Erro ao Incluir apuração."
|
649
|
-
if texto_aviso:
|
650
|
-
retorno_msg += f" Detalhe: {texto_aviso}"
|
651
|
-
if screenshot_path:
|
652
|
-
retorno_msg += f" | Print: {screenshot_path}"
|
653
|
-
|
654
|
-
return RpaRetornoProcessoDTO(
|
655
|
-
sucesso=False,
|
656
|
-
retorno=retorno_msg,
|
657
|
-
status=RpaHistoricoStatusEnum.Falha,
|
658
|
-
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
|
659
|
-
)
|
660
|
-
else:
|
661
|
-
console.print(
|
662
|
-
"Janela 'Aviso' não contém mensagem de erro mapeada. Seguindo fluxo."
|
663
|
-
)
|
664
|
-
# (Opcional) você pode clicar no 'OK' e continuar:
|
665
|
-
try:
|
666
|
-
# tenta clicar em botão OK se existir
|
667
|
-
for c in dlg.descendants():
|
668
|
-
try:
|
669
|
-
if c.window_text().strip().lower() in ("ok", "&ok"):
|
670
|
-
c.click_input()
|
671
|
-
break
|
672
|
-
except Exception:
|
673
|
-
pass
|
674
|
-
except Exception:
|
675
|
-
pass
|
676
|
-
# não retorna aqui; deixa seguir para sucesso
|
677
660
|
|
678
661
|
# === 5) Se não houve 'Aviso' com erro mapeado, considera sucesso ===
|
679
662
|
console.print("Nenhum erro confirmado. Fluxo OK.")
|
@@ -12,12 +12,12 @@ import win32clipboard
|
|
12
12
|
from PIL import Image, ImageEnhance
|
13
13
|
from pywinauto.application import Application
|
14
14
|
from pywinauto.keyboard import send_keys
|
15
|
-
from pywinauto.timings import wait_until
|
15
|
+
from pywinauto.timings import TimeoutError as PywTimeout, wait_until
|
16
16
|
from pywinauto_recorder.player import set_combobox
|
17
17
|
from rich.console import Console
|
18
18
|
import sys
|
19
19
|
import asyncio
|
20
|
-
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..","..","..")))
|
20
|
+
# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..","..","..")))
|
21
21
|
from worker_automate_hub.api.ahead_service import save_xml_to_downloads
|
22
22
|
from worker_automate_hub.api.client import (
|
23
23
|
get_config_by_name,
|
@@ -471,6 +471,7 @@ async def opex_capex(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
471
471
|
|
472
472
|
# Clicar em itens da nota
|
473
473
|
imagem = "assets\\entrada_notas\\itens_nota.png"
|
474
|
+
# imagem = r"C:\Users\automatehub\Documents\GitHub\worker-automate-hub\assets\entrada_notas\itens_nota.png"
|
474
475
|
|
475
476
|
# Tenta localizar a imagem na tela
|
476
477
|
while True:
|
@@ -547,6 +548,11 @@ async def opex_capex(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
547
548
|
send_keys("{ENTER}")
|
548
549
|
except Exception as e:
|
549
550
|
print(f"Erro ao selecionar opção: {e}")
|
551
|
+
# Localize o combobox pelo class_name
|
552
|
+
combo = main_window.child_window(class_name="TDBIComboBox", found_index=4)
|
553
|
+
|
554
|
+
# Seleciona diretamente o texto
|
555
|
+
combo.select("IPI 0%")
|
550
556
|
|
551
557
|
# Clicar em alterar
|
552
558
|
main_window.child_window(class_name="TDBIBitBtn", found_index=3).click()
|
@@ -585,27 +591,99 @@ async def opex_capex(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
585
591
|
|
586
592
|
panel_TabPagamento = panel_TTabSheet.child_window(title="Pagamento")
|
587
593
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
# Lista de opções em ordem de prioridade
|
594
|
+
# Combo alvo (ajuste found_index se precisar)
|
595
|
+
tipo_cobranca = panel_TTabSheet.child_window(class_name="TDBIComboBox", found_index=0)
|
596
|
+
|
597
|
+
# Ordem de preferência
|
593
598
|
opcoes = [
|
594
599
|
"BANCO DO BRASIL BOLETO FIDC",
|
595
600
|
"BANCO DO BRASIL BOLETO",
|
596
|
-
"BOLETO"
|
601
|
+
"BOLETO",
|
597
602
|
]
|
598
603
|
|
599
|
-
#
|
600
|
-
|
601
|
-
for
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
604
|
+
# 1) Tenta .select() direto (não digita nada)
|
605
|
+
selecionado = None
|
606
|
+
for alvo in opcoes:
|
607
|
+
try:
|
608
|
+
tipo_cobranca.select(alvo)
|
609
|
+
if tipo_cobranca.window_text().strip().lower() == alvo.lower():
|
610
|
+
selecionado = alvo
|
611
|
+
break
|
612
|
+
except Exception:
|
613
|
+
pass
|
614
|
+
|
615
|
+
# 2) Abre a LISTA e seleciona o item exato (sem digitar)
|
616
|
+
if not selecionado:
|
617
|
+
tipo_cobranca.set_focus()
|
618
|
+
tipo_cobranca.click_input()
|
619
|
+
send_keys('%{DOWN}') # ALT+DOWN para abrir o dropdown
|
620
|
+
# tenta achar a janela da lista (Delphi/Win32)
|
621
|
+
lista = None
|
622
|
+
app = tipo_cobranca.app
|
623
|
+
for crit in (dict(title="||List"), dict(class_name="ComboLBox"), dict(class_name_re=".*(List|Combo).*")):
|
624
|
+
try:
|
625
|
+
cand = app.window(**crit)
|
626
|
+
if cand.exists(timeout=0.5):
|
627
|
+
lista = cand
|
628
|
+
break
|
629
|
+
except Exception:
|
630
|
+
pass
|
631
|
+
|
632
|
+
if lista:
|
633
|
+
# tenta selecionar por índice (texto exato)
|
634
|
+
try:
|
635
|
+
itens = [t.strip() for t in lista.texts() if str(t).strip()]
|
636
|
+
except Exception:
|
637
|
+
itens = []
|
638
|
+
|
639
|
+
idx_alvo = -1
|
640
|
+
alvo_escolhido = None
|
641
|
+
for alvo in opcoes:
|
642
|
+
for i, t in enumerate(itens):
|
643
|
+
if t.lower() == alvo.lower():
|
644
|
+
idx_alvo = i
|
645
|
+
alvo_escolhido = alvo
|
646
|
+
break
|
647
|
+
if idx_alvo >= 0:
|
648
|
+
break
|
649
|
+
|
650
|
+
if idx_alvo >= 0:
|
651
|
+
try:
|
652
|
+
lista.select(idx_alvo)
|
653
|
+
except Exception:
|
654
|
+
# fallback por teclas sem digitar texto do item
|
655
|
+
send_keys('{HOME}')
|
656
|
+
for _ in range(idx_alvo):
|
657
|
+
send_keys('{DOWN}')
|
658
|
+
send_keys('{ENTER}')
|
659
|
+
try:
|
660
|
+
wait_until(2, 0.2, lambda: tipo_cobranca.window_text().strip() != "")
|
661
|
+
except PywTimeout:
|
662
|
+
pass
|
663
|
+
if tipo_cobranca.window_text().strip().lower() == alvo_escolhido.lower():
|
664
|
+
selecionado = alvo_escolhido
|
665
|
+
else:
|
666
|
+
# fallback só com setas (sem digitar): vai ao topo e desce checando
|
667
|
+
send_keys('{HOME}')
|
668
|
+
vistos = set()
|
669
|
+
for _ in range(60):
|
670
|
+
atual = tipo_cobranca.window_text().strip()
|
671
|
+
if atual.lower() in (o.lower() for o in opcoes):
|
672
|
+
send_keys('{ENTER}')
|
673
|
+
selecionado = atual
|
674
|
+
break
|
675
|
+
if atual.lower() in vistos:
|
676
|
+
# deu a volta
|
677
|
+
send_keys('{ESC}')
|
678
|
+
break
|
679
|
+
vistos.add(atual.lower())
|
680
|
+
send_keys('{DOWN}')
|
681
|
+
|
682
|
+
# (opcional) validação dura
|
683
|
+
if not selecionado or selecionado.lower() not in (o.lower() for o in opcoes):
|
684
|
+
raise RuntimeError(f"Não consegui selecionar uma opção válida. Ficou: '{tipo_cobranca.window_text().strip()}'")
|
685
|
+
|
686
|
+
print("Selecionado:", selecionado)
|
609
687
|
|
610
688
|
dt_vencimento_nota = nota.get("dataVencimento") # vem como '2025-09-26'
|
611
689
|
data_atual = datetime.now().date()
|
@@ -634,10 +712,8 @@ async def opex_capex(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
634
712
|
|
635
713
|
console.print(f"Incluindo registro...\n")
|
636
714
|
try:
|
637
|
-
|
638
|
-
inserir_registro = pyautogui.locateOnScreen(
|
639
|
-
"assets\\entrada_notas\\IncluirRegistro.png", confidence=0.8
|
640
|
-
)
|
715
|
+
inserir_registro = pyautogui.locateOnScreen("assets\entrada_notas\IncluirRegistro.png", confidence=0.8)
|
716
|
+
# inserir_registro = pyautogui.locateOnScreen(r"C:\Users\automatehub\Documents\GitHub\worker-automate-hub\assets\entrada_notas\IncluirRegistro.png", confidence=0.8)
|
641
717
|
pyautogui.click(inserir_registro)
|
642
718
|
except Exception as e:
|
643
719
|
console.print(
|
@@ -830,4 +906,3 @@ async def opex_capex(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
830
906
|
# Deleta o xml
|
831
907
|
await delete_xml(numero_nota)
|
832
908
|
|
833
|
-
|
@@ -36,7 +36,7 @@ worker_automate_hub/models/dto/rpa_sap_dto.py,sha256=eovdvKCtVIhRct3PL98KjsdlngL
|
|
36
36
|
worker_automate_hub/models/dto/rpa_sistema_dto.py,sha256=sLkmJei8x6sl-1-IXUKDmYQuKx0sotYQREPyhQqPmRg,161
|
37
37
|
worker_automate_hub/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
worker_automate_hub/tasks/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
-
worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py,sha256=
|
39
|
+
worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py,sha256=3455qiEsrjMSUZqsOOl-mCbjGv8M2t-x3EtXEzpiuls,27309
|
40
40
|
worker_automate_hub/tasks/jobs/coleta_dje_process.py,sha256=UkLWTC5Ub2qBb0yY-8IZ0DLLOVJOfNTq_z9krx_t25Q,29476
|
41
41
|
worker_automate_hub/tasks/jobs/conexao_rdp.py,sha256=S6QC4xhuo0pB5FjaUJZNMm1LIgEjpjifReCTBDqxH-U,11719
|
42
42
|
worker_automate_hub/tasks/jobs/cte_manual.py,sha256=JucHpRMjMiy-QEJ0wtFnytLpN53tKXgCDI05nGLGclU,603
|
@@ -88,7 +88,7 @@ worker_automate_hub/tasks/jobs/lancamento_rateio.py,sha256=0cvbpuJiHl5mca5gpZudX
|
|
88
88
|
worker_automate_hub/tasks/jobs/login_emsys.py,sha256=dO9S027qRTtjOfytF6IWO-m6hDld8kZqOVAsn91l1YA,5684
|
89
89
|
worker_automate_hub/tasks/jobs/login_emsys_versao_especifica.py,sha256=_6CFh79eaW9KdPGR6FMV01ASPjJzNzzBK1MvC_uiSOo,5625
|
90
90
|
worker_automate_hub/tasks/jobs/notas_faturamento_sap.py,sha256=p6tVE027FHHXBxt2sIDxqLInpf_0wS-8TcACnS34p7w,13961
|
91
|
-
worker_automate_hub/tasks/jobs/opex_capex.py,sha256=
|
91
|
+
worker_automate_hub/tasks/jobs/opex_capex.py,sha256=hp0B7QTTO1TTQR8xVyCxpYgwixglipx3CKT9ZDvA4ao,36879
|
92
92
|
worker_automate_hub/tasks/jobs/playground.py,sha256=7vWDg9DwToHwGJ6_XOa8TQ6LmfRV5Qz2TaOV3q3P9sA,1918
|
93
93
|
worker_automate_hub/tasks/jobs/sped_fiscal.py,sha256=Zsq-IwKxA0b2tikO6Rri4WXVj10jK-Jd0-gxk8yVBH0,31064
|
94
94
|
worker_automate_hub/tasks/jobs/transferencias.py,sha256=5TIktufkvUPnVTR2gf7GFQJ5KQP6PWnmoWiE08WiVDQ,46191
|
@@ -103,7 +103,7 @@ worker_automate_hub/utils/updater.py,sha256=en2FCGhI8aZ-JNP3LQm64NJDc4awCNW7UhbV
|
|
103
103
|
worker_automate_hub/utils/util.py,sha256=noQRUSAjRnoDb1c4iMZ5eoyrNp59a8T9K78MHhalASw,210255
|
104
104
|
worker_automate_hub/utils/utils_nfe_entrada.py,sha256=F7jk95LpDwl5WfaQXahCA5yDdnySnWdctDqczHXwGqE,38195
|
105
105
|
worker_automate_hub/worker.py,sha256=zEnYUrm5kY2cHbbee15QJkwkx4euD2SB2zRvUIbjS90,6850
|
106
|
-
worker_automate_hub-0.5.
|
107
|
-
worker_automate_hub-0.5.
|
108
|
-
worker_automate_hub-0.5.
|
109
|
-
worker_automate_hub-0.5.
|
106
|
+
worker_automate_hub-0.5.807.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
|
107
|
+
worker_automate_hub-0.5.807.dist-info/METADATA,sha256=NWOK6pfCQIyr7MK4SshrBxOwipy2sJhV3Gxo4hz23BY,3100
|
108
|
+
worker_automate_hub-0.5.807.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
109
|
+
worker_automate_hub-0.5.807.dist-info/RECORD,,
|
File without changes
|
{worker_automate_hub-0.5.805.dist-info → worker_automate_hub-0.5.807.dist-info}/entry_points.txt
RENAMED
File without changes
|