worker-automate-hub 0.5.762__py3-none-any.whl → 0.5.763__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/extracao_saldo_estoque_fiscal.py +105 -51
- {worker_automate_hub-0.5.762.dist-info → worker_automate_hub-0.5.763.dist-info}/METADATA +1 -1
- {worker_automate_hub-0.5.762.dist-info → worker_automate_hub-0.5.763.dist-info}/RECORD +5 -5
- {worker_automate_hub-0.5.762.dist-info → worker_automate_hub-0.5.763.dist-info}/WHEEL +0 -0
- {worker_automate_hub-0.5.762.dist-info → worker_automate_hub-0.5.763.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
import asyncio
|
2
2
|
import os
|
3
3
|
from datetime import datetime
|
4
|
-
from pywinauto import Application, timings, findwindows, keyboard
|
4
|
+
from pywinauto import Application, timings, findwindows, keyboard, Desktop
|
5
5
|
import sys
|
6
6
|
import io
|
7
|
-
|
7
|
+
import win32gui
|
8
8
|
# sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
|
9
9
|
|
10
10
|
from worker_automate_hub.models.dto.rpa_historico_request_dto import (
|
@@ -282,14 +282,18 @@ async def extracao_saldo_estoque_fiscal(
|
|
282
282
|
|
283
283
|
await worker_sleep(2)
|
284
284
|
|
285
|
+
|
285
286
|
max_tentativas = 5
|
286
287
|
tentativa = 1
|
287
288
|
sucesso = False
|
288
289
|
|
290
|
+
# defina caminho_arquivo ANTES para não ficar indefinido
|
291
|
+
caminho_arquivo = rf"C:\Users\automatehub\Downloads\saldo_estoque_fiscal_{periodo_format}_{filial}.xlsx"
|
292
|
+
|
289
293
|
while tentativa <= max_tentativas and not sucesso:
|
290
294
|
console.print(f"Tentativa {tentativa} de {max_tentativas}", style="bold cyan")
|
291
295
|
|
292
|
-
# 1) Abrir o picker
|
296
|
+
# 1) Abrir o picker pelo botão (imagem)
|
293
297
|
console.print("Procurando botão de salvar (imagem)...", style="bold cyan")
|
294
298
|
caminho_img = r'assets\\extracao_relatorios\\btn_salvar.png'
|
295
299
|
if os.path.isfile(caminho_img):
|
@@ -304,39 +308,92 @@ async def extracao_saldo_estoque_fiscal(
|
|
304
308
|
|
305
309
|
await worker_sleep(8)
|
306
310
|
|
307
|
-
# 2) Selecionar formato
|
311
|
+
# 2) Selecionar formato Excel (desambiguando múltiplas TFrmRelatorioFormato)
|
308
312
|
console.print("Selecionando formato Excel...", style="bold cyan")
|
309
313
|
try:
|
310
|
-
|
311
|
-
|
312
|
-
|
314
|
+
desktop = Desktop(backend="win32")
|
315
|
+
|
316
|
+
# Liste todas as visíveis
|
317
|
+
wins_visiveis = desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True)
|
318
|
+
if not wins_visiveis:
|
319
|
+
raise RuntimeError("Janela de formato não apareceu.")
|
320
|
+
|
321
|
+
# 2.1) Tente a janela em foco (foreground)
|
322
|
+
h_fore = win32gui.GetForegroundWindow()
|
323
|
+
alvo = None
|
324
|
+
for w in wins_visiveis:
|
325
|
+
if w.handle == h_fore:
|
326
|
+
alvo = w
|
327
|
+
break
|
328
|
+
|
329
|
+
# 2.2) Se não estiver em foco, pegue a que contém um TComboBox (a 'Configuração para Salvar arq...')
|
330
|
+
if alvo is None:
|
331
|
+
candidatos = []
|
332
|
+
for w in wins_visiveis:
|
333
|
+
try:
|
334
|
+
if w.child_window(class_name="TComboBox").exists(timeout=0.8):
|
335
|
+
candidatos.append(w)
|
336
|
+
except Exception:
|
337
|
+
pass
|
338
|
+
if candidatos:
|
339
|
+
alvo = candidatos[-1] # a mais recente
|
340
|
+
else:
|
341
|
+
alvo = wins_visiveis[-1] # fallback
|
342
|
+
|
343
|
+
# Trabalhe via WindowSpecification
|
344
|
+
spec_fmt = desktop.window(handle=alvo.handle)
|
345
|
+
spec_fmt.wait("visible", timeout=10)
|
346
|
+
win_fmt = spec_fmt.wrapper_object()
|
347
|
+
win_fmt.set_focus()
|
348
|
+
|
349
|
+
# Acessar o ComboBox
|
350
|
+
try:
|
351
|
+
combo_spec = spec_fmt.child_window(class_name="TComboBox")
|
352
|
+
except Exception:
|
353
|
+
combo_spec = spec_fmt.child_window(control_type="ComboBox")
|
354
|
+
combo_spec.wait("exists enabled", timeout=10)
|
355
|
+
combo = combo_spec.wrapper_object()
|
313
356
|
|
314
|
-
combo = win_fmt.ComboBox
|
315
357
|
textos = combo.texts()
|
316
358
|
console.print(f"Itens do ComboBox: {textos}", style="bold yellow")
|
317
359
|
|
318
|
-
#
|
360
|
+
# Seleção por índice conhecido; fallback por texto
|
319
361
|
try:
|
320
362
|
combo.select(8)
|
321
363
|
except Exception:
|
322
|
-
|
364
|
+
alvo_idx = None
|
323
365
|
for i, t in enumerate(textos):
|
324
366
|
if "EXCEL" in str(t).upper() or "XLSX" in str(t).upper():
|
325
|
-
|
367
|
+
alvo_idx = i
|
326
368
|
break
|
327
|
-
if
|
328
|
-
combo.select(alvo)
|
329
|
-
else:
|
369
|
+
if alvo_idx is None:
|
330
370
|
console.print("Não foi possível localizar a opção de Excel no ComboBox.", style="bold red")
|
331
371
|
tentativa += 1
|
332
372
|
await worker_sleep(2)
|
333
373
|
continue
|
374
|
+
combo.select(alvo_idx)
|
334
375
|
|
335
376
|
await worker_sleep(1)
|
336
377
|
|
337
|
-
#
|
338
|
-
|
339
|
-
|
378
|
+
# Clique em OK
|
379
|
+
btn_ok_spec = spec_fmt.child_window(class_name="TBitBtn", found_index=1)
|
380
|
+
btn_ok_spec.wait("enabled", timeout=5)
|
381
|
+
btn_ok_spec.click_input()
|
382
|
+
|
383
|
+
# Aguarde a janela de formato desaparecer
|
384
|
+
try:
|
385
|
+
spec_fmt.wait_not("visible", timeout=10)
|
386
|
+
except Exception:
|
387
|
+
pass
|
388
|
+
|
389
|
+
# Feche possíveis duplicatas remanescentes (defensivo)
|
390
|
+
for w in desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True):
|
391
|
+
if w.handle != alvo.handle:
|
392
|
+
try:
|
393
|
+
w.close()
|
394
|
+
except Exception:
|
395
|
+
pass
|
396
|
+
|
340
397
|
except Exception as e:
|
341
398
|
console.print(f"Falha ao selecionar formato: {e}", style="bold red")
|
342
399
|
tentativa += 1
|
@@ -348,19 +405,17 @@ async def extracao_saldo_estoque_fiscal(
|
|
348
405
|
# 3) Janela "Salvar para arquivo"
|
349
406
|
console.print("Abrindo janela de salvar arquivo...", style="bold cyan")
|
350
407
|
try:
|
351
|
-
app_save = Application().connect(title_re="Salvar para arquivo", timeout=30)
|
352
|
-
|
353
|
-
|
408
|
+
app_save = Application(backend="win32").connect(title_re="Salvar para arquivo|Salvar como|Save As", timeout=30)
|
409
|
+
spec_save = app_save.window(title_re="Salvar para arquivo|Salvar como|Save As")
|
410
|
+
spec_save.wait("visible", timeout=30)
|
411
|
+
win_save = spec_save.wrapper_object()
|
354
412
|
except Exception as e:
|
355
413
|
console.print(f"Não achou a janela 'Salvar para arquivo': {e}", style="bold red")
|
356
414
|
tentativa += 1
|
357
415
|
await worker_sleep(3)
|
358
416
|
continue
|
359
417
|
|
360
|
-
#
|
361
|
-
caminho_arquivo = rf"C:\Users\automatehub\Downloads\saldo_estoque_fiscal_{periodo_format}_{filial}.xlsx"
|
362
|
-
|
363
|
-
# Se já existe, removemos para evitar pop-up de confirmação
|
418
|
+
# 3.1) Remover arquivo pré-existente
|
364
419
|
if os.path.exists(caminho_arquivo):
|
365
420
|
try:
|
366
421
|
os.remove(caminho_arquivo)
|
@@ -368,27 +423,32 @@ async def extracao_saldo_estoque_fiscal(
|
|
368
423
|
except Exception as e:
|
369
424
|
console.print(f"Não foi possível remover o arquivo existente: {e}", style="bold red")
|
370
425
|
|
426
|
+
# 3.2) Preencher nome e salvar
|
371
427
|
try:
|
372
|
-
|
373
|
-
|
428
|
+
campo_spec = spec_save.child_window(class_name="Edit", control_id=1148)
|
429
|
+
campo_spec.wait("exists enabled visible", timeout=10)
|
430
|
+
campo_nome = campo_spec.wrapper_object()
|
374
431
|
campo_nome.set_focus()
|
375
|
-
# limpa conteúdo
|
376
432
|
try:
|
377
433
|
campo_nome.set_edit_text("")
|
378
434
|
except Exception:
|
379
|
-
# fallback limpando com Ctrl+A + Delete
|
380
435
|
campo_nome.type_keys("^a{DELETE}", pause=0.02)
|
381
436
|
|
382
|
-
# digita caminho
|
383
437
|
campo_nome.type_keys(caminho_arquivo, with_spaces=True, pause=0.01)
|
384
438
|
console.print(f"Arquivo configurado para: {caminho_arquivo}", style="bold green")
|
385
439
|
|
386
440
|
await worker_sleep(1)
|
387
441
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
442
|
+
btn_salvar_spec = spec_save.child_window(class_name="Button", found_index=0)
|
443
|
+
btn_salvar_spec.wait("enabled", timeout=10)
|
444
|
+
btn_salvar_spec.click_input()
|
445
|
+
|
446
|
+
# Esperar a janela sumir
|
447
|
+
try:
|
448
|
+
spec_save.wait_not("visible", timeout=15)
|
449
|
+
except Exception:
|
450
|
+
pass
|
451
|
+
|
392
452
|
except Exception as e:
|
393
453
|
console.print(f"Erro ao confirmar salvar: {e}", style="bold red")
|
394
454
|
tentativa += 1
|
@@ -397,32 +457,27 @@ async def extracao_saldo_estoque_fiscal(
|
|
397
457
|
|
398
458
|
await worker_sleep(2)
|
399
459
|
|
400
|
-
# 3.
|
460
|
+
# 3.3) Confirmar sobrescrita (se houver)
|
401
461
|
try:
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
# Tente o primeiro botão (Yes/Sim)
|
410
|
-
win_conf.child_window(class_name="Button", found_index=0).click_input()
|
411
|
-
console.print("Confirmação de sobrescrita respondida.", style="bold yellow")
|
412
|
-
except Exception:
|
413
|
-
pass
|
462
|
+
app_conf = Application(backend="win32").connect(
|
463
|
+
title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As", timeout=3
|
464
|
+
)
|
465
|
+
spec_conf = app_conf.window(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As")
|
466
|
+
spec_conf.wait("visible", timeout=3)
|
467
|
+
spec_conf.child_window(class_name="Button", found_index=0).click_input()
|
468
|
+
console.print("Confirmação de sobrescrita respondida.", style="bold yellow")
|
414
469
|
except Exception:
|
415
470
|
pass
|
416
471
|
|
417
472
|
await worker_sleep(2)
|
418
473
|
|
419
|
-
# 4) Aguardar
|
474
|
+
# 4) Aguardar 'Printing' (se existir)
|
420
475
|
console.print("Aguardando finalização do processo de impressão/salvamento...", style="bold cyan")
|
421
476
|
try:
|
422
|
-
app_print = Application().connect(title_re="Printing", timeout=5)
|
423
|
-
|
477
|
+
app_print = Application(backend="win32").connect(title_re="Printing", timeout=5)
|
478
|
+
spec_print = app_print.window(title_re="Printing")
|
424
479
|
try:
|
425
|
-
|
480
|
+
spec_print.wait_not("visible", timeout=60)
|
426
481
|
console.print("Janela 'Printing' fechada.", style="bold green")
|
427
482
|
except Exception:
|
428
483
|
console.print("Janela 'Printing' não fechou no tempo esperado. Seguindo.", style="bold yellow")
|
@@ -445,7 +500,6 @@ async def extracao_saldo_estoque_fiscal(
|
|
445
500
|
if not sucesso:
|
446
501
|
console.print("Falha após 5 tentativas. Arquivo não foi gerado.", style="bold red")
|
447
502
|
|
448
|
-
|
449
503
|
nome_com_extensao = f"saldo_estoque_fiscal_{periodo_format}_{filial}.xlsx"
|
450
504
|
# lê o arquivo
|
451
505
|
print(caminho_arquivo)
|
@@ -71,7 +71,7 @@ worker_automate_hub/tasks/jobs/exemplo_processo.py,sha256=nV0iLoip2FH2-FhLmhX3nP
|
|
71
71
|
worker_automate_hub/tasks/jobs/extracao_fechamento_contabil.py,sha256=6Kr5DKjKLqtFvGzyiXtt7xrQsuU898l8pQXDq9C6AX8,19567
|
72
72
|
worker_automate_hub/tasks/jobs/extracao_fechamento_emsys.py,sha256=-T2nZUDiFrUGm_KLxJd_4qcrageDxVpWW3KAAniLFC4,21448
|
73
73
|
worker_automate_hub/tasks/jobs/extracao_saldo_estoque.py,sha256=_tmKYCKqd05xueln-nfd3yVhwpkpsflNQY1BDtyzEZQ,13726
|
74
|
-
worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py,sha256=
|
74
|
+
worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py,sha256=VGvWV0r3yr-e0l2EbCG2ki00Bsc2OhArvjUH-jE2GI4,22112
|
75
75
|
worker_automate_hub/tasks/jobs/fechar_conexao_rdp.py,sha256=UWAKCS2dbfgDlSQOBdjmVJXfD1MMuUrOi3weDgB0CAc,5718
|
76
76
|
worker_automate_hub/tasks/jobs/fidc_exportacao_docs_portal_b2b.py,sha256=tWUmYy3Zhi3JEt8AoqTsWpU-wbf5-OxhCrTOooh1WH4,15616
|
77
77
|
worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py,sha256=FAmcCqKVjedf7wIped8XRLIZ9S3oWc6fakF-r1Zm0kg,12637
|
@@ -101,7 +101,7 @@ worker_automate_hub/utils/updater.py,sha256=en2FCGhI8aZ-JNP3LQm64NJDc4awCNW7UhbV
|
|
101
101
|
worker_automate_hub/utils/util.py,sha256=V2WtWoETdTrAtGA8UgeqAAVphUj9KkGSZFzYsHJFATA,210055
|
102
102
|
worker_automate_hub/utils/utils_nfe_entrada.py,sha256=TOXKSHOPxy8N3-ROpTGjNIHstX0i2b8qekcj1tRvjG8,38174
|
103
103
|
worker_automate_hub/worker.py,sha256=uhZ3f-iaQ1i8cANbljp50vkYl-Xm0_sHtjwwF_2y72o,7191
|
104
|
-
worker_automate_hub-0.5.
|
105
|
-
worker_automate_hub-0.5.
|
106
|
-
worker_automate_hub-0.5.
|
107
|
-
worker_automate_hub-0.5.
|
104
|
+
worker_automate_hub-0.5.763.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
|
105
|
+
worker_automate_hub-0.5.763.dist-info/METADATA,sha256=ZpVTgCTIi-xVpIgVoqBSFJWPu7R8lHncIl37JUCOA3E,3049
|
106
|
+
worker_automate_hub-0.5.763.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
107
|
+
worker_automate_hub-0.5.763.dist-info/RECORD,,
|
File without changes
|
{worker_automate_hub-0.5.762.dist-info → worker_automate_hub-0.5.763.dist-info}/entry_points.txt
RENAMED
File without changes
|