worker-automate-hub 0.5.762__tar.gz → 0.5.763__tar.gz

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.
Files changed (106) hide show
  1. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/PKG-INFO +1 -1
  2. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/pyproject.toml +1 -1
  3. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py +105 -51
  4. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/README.md +0 -0
  5. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/__init__.py +0 -0
  6. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/__init__.py +0 -0
  7. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/ahead_service.py +0 -0
  8. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/client.py +0 -0
  9. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/datalake_service.py +0 -0
  10. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/helpers/__init__.py +0 -0
  11. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/helpers/api_helpers.py +0 -0
  12. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/rdp_service.py +0 -0
  13. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/rpa_fila_service.py +0 -0
  14. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/rpa_historico_service.py +0 -0
  15. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/api/webhook_service.py +0 -0
  16. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/cli.py +0 -0
  17. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/config/__init__.py +0 -0
  18. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/config/settings.py +0 -0
  19. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/config.py +0 -0
  20. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/core/so_manipulation.py +0 -0
  21. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/__init__.py +0 -0
  22. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/deprecation.py +0 -0
  23. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/rate_limit.py +0 -0
  24. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/repeat.py +0 -0
  25. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/retry.py +0 -0
  26. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/singleton.py +0 -0
  27. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/decorators/timeit.py +0 -0
  28. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/__init__.py +0 -0
  29. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/__init__.py +0 -0
  30. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/rpa_configuracao.py +0 -0
  31. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/rpa_fila.py +0 -0
  32. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/rpa_historico.py +0 -0
  33. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/rpa_processo.py +0 -0
  34. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dao/rpa_robo.py +0 -0
  35. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/__init__.py +0 -0
  36. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/rpa_historico_request_dto.py +0 -0
  37. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/rpa_processo_entrada_dto.py +0 -0
  38. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/rpa_processo_rdp_dto.py +0 -0
  39. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/rpa_sap_dto.py +0 -0
  40. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/models/dto/rpa_sistema_dto.py +0 -0
  41. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/__init__.py +0 -0
  42. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/__init__.py +0 -0
  43. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +0 -0
  44. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/coleta_dje_process.py +0 -0
  45. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/conexao_rdp.py +0 -0
  46. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/cte_manual.py +0 -0
  47. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/cte_xml.py +0 -0
  48. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/descartes.py +0 -0
  49. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/devolucao_ctf.py +0 -0
  50. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/devolucao_ctf_35.py +0 -0
  51. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/devolucao_prazo_a_faturar.py +0 -0
  52. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_estadual_go.py +0 -0
  53. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_estadual_main.py +0 -0
  54. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_estadual_mt.py +0 -0
  55. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_estadual_sc.py +0 -0
  56. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_estadual_sp.py +0 -0
  57. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/ecac_federal.py +0 -0
  58. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_cte_1353.py +0 -0
  59. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_cte_333.py +0 -0
  60. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_15.py +0 -0
  61. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_16.py +0 -0
  62. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_207.py +0 -0
  63. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_32.py +0 -0
  64. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_33.py +0 -0
  65. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_34.py +0 -0
  66. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_36.py +0 -0
  67. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_39.py +0 -0
  68. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_500.py +0 -0
  69. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_503.py +0 -0
  70. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_505.py +0 -0
  71. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_7139.py +0 -0
  72. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_9.py +0 -0
  73. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/entrada_de_notas_9000.py +0 -0
  74. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/exemplo_processo.py +0 -0
  75. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/extracao_fechamento_contabil.py +0 -0
  76. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/extracao_fechamento_emsys.py +0 -0
  77. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/extracao_saldo_estoque.py +0 -0
  78. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/fechar_conexao_rdp.py +0 -0
  79. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/fidc_exportacao_docs_portal_b2b.py +0 -0
  80. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py +0 -0
  81. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/fidc_remessa_cobranca_cnab240.py +0 -0
  82. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/fidc_retorno_cobranca.py +0 -0
  83. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/geracao_aprovacao_pedidos.py +0 -0
  84. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/geracao_aprovacao_pedidos_novo.py +0 -0
  85. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/integracao_contabil.py +0 -0
  86. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/integracao_contabil_generica.py +0 -0
  87. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/lancamento_pis_cofins.py +0 -0
  88. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/lancamento_rateio.py +0 -0
  89. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/login_emsys.py +0 -0
  90. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/login_emsys_versao_especifica.py +0 -0
  91. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/notas_faturamento_sap.py +0 -0
  92. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/opex_capex.py +0 -0
  93. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/playground.py +0 -0
  94. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/sped_fiscal.py +0 -0
  95. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/jobs/transferencias.py +0 -0
  96. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/task_definitions.py +0 -0
  97. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/tasks/task_executor.py +0 -0
  98. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/__init__.py +0 -0
  99. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/env.py +0 -0
  100. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/get_creds_gworkspace.py +0 -0
  101. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/logger.py +0 -0
  102. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/toast.py +0 -0
  103. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/updater.py +0 -0
  104. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/util.py +0 -0
  105. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/utils/utils_nfe_entrada.py +0 -0
  106. {worker_automate_hub-0.5.762 → worker_automate_hub-0.5.763}/worker_automate_hub/worker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: worker-automate-hub
3
- Version: 0.5.762
3
+ Version: 0.5.763
4
4
  Summary: Worker Automate HUB é uma aplicação para automatizar rotinas de RPA nos ambientes Argenta.
5
5
  Author: Joel Paim
6
6
  Requires-Python: >=3.12,<4.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "worker-automate-hub"
3
- version = "0.5.762"
3
+ version = "0.5.763"
4
4
  description = "Worker Automate HUB é uma aplicação para automatizar rotinas de RPA nos ambientes Argenta."
5
5
  authors = ["Joel Paim"]
6
6
  readme = "README.md"
@@ -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 de formatos pelo botão (imagem)
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 "Excel" na janela TFrmRelatorioFormato
311
+ # 2) Selecionar formato Excel (desambiguando múltiplas TFrmRelatorioFormato)
308
312
  console.print("Selecionando formato Excel...", style="bold cyan")
309
313
  try:
310
- app_fmt = Application().connect(class_name="TFrmRelatorioFormato", timeout=10)
311
- win_fmt = app_fmt["TFrmRelatorioFormato"]
312
- win_fmt.wait("visible", timeout=10)
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
- # Se souber o índice correto, mantenha. Caso contrário, tente por texto contendo 'Excel'
360
+ # Seleção por índice conhecido; fallback por texto
319
361
  try:
320
362
  combo.select(8)
321
363
  except Exception:
322
- alvo = None
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
- alvo = i
367
+ alvo_idx = i
326
368
  break
327
- if alvo is not None:
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
- # Botão OK/Confirmar na janela de formato
338
- win_fmt.child_window(class_name="TBitBtn", found_index=1).wait("enabled", timeout=5)
339
- win_fmt.child_window(class_name="TBitBtn", found_index=1).click_input()
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
- win_save = app_save.window(title_re="Salvar para arquivo")
353
- win_save.wait("visible", timeout=30)
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
- # Caminho do arquivo a salvar
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
- # Campo "Nome" (Edit, control_id=1148)
373
- campo_nome = win_save.child_window(class_name="Edit", control_id=1148).wrapper_object()
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
- # Botão Salvar (primeiro Button)
389
- btn_salvar = win_save.child_window(class_name="Button", found_index=0)
390
- btn_salvar.wait("enabled", timeout=10)
391
- btn_salvar.click_input()
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.1) Tratar confirmação de sobrescrita, se aparecer
460
+ # 3.3) Confirmar sobrescrita (se houver)
401
461
  try:
402
- # Pode vir em PT/EN dependendo do SO
403
- # Título comum: "Confirm Save As" (EN) ou "Confirmar Salvar Como" (PT)
404
- try:
405
- app_conf = Application().connect(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As", timeout=3)
406
- win_conf = app_conf.window(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As")
407
- win_conf.wait("visible", timeout=3)
408
- # Botões costumam ser "Sim"/"Yes" como class_name="Button"
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 o processamento/Printing encerrar
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
- win_print = app_print.window(title_re="Printing")
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
- win_print.wait_not("visible", timeout=60)
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)