worker-automate-hub 0.5.763__tar.gz → 0.5.765__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.763 → worker_automate_hub-0.5.765}/PKG-INFO +1 -1
  2. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/pyproject.toml +1 -1
  3. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/descartes.py +1 -1
  4. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/extracao_saldo_estoque.py +104 -50
  5. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py +76 -29
  6. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/transferencias.py +1 -1
  7. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/README.md +0 -0
  8. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/__init__.py +0 -0
  9. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/__init__.py +0 -0
  10. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/ahead_service.py +0 -0
  11. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/client.py +0 -0
  12. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/datalake_service.py +0 -0
  13. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/helpers/__init__.py +0 -0
  14. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/helpers/api_helpers.py +0 -0
  15. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/rdp_service.py +0 -0
  16. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/rpa_fila_service.py +0 -0
  17. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/rpa_historico_service.py +0 -0
  18. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/api/webhook_service.py +0 -0
  19. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/cli.py +0 -0
  20. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/config/__init__.py +0 -0
  21. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/config/settings.py +0 -0
  22. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/config.py +0 -0
  23. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/core/so_manipulation.py +0 -0
  24. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/__init__.py +0 -0
  25. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/deprecation.py +0 -0
  26. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/rate_limit.py +0 -0
  27. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/repeat.py +0 -0
  28. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/retry.py +0 -0
  29. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/singleton.py +0 -0
  30. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/decorators/timeit.py +0 -0
  31. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/__init__.py +0 -0
  32. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/__init__.py +0 -0
  33. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/rpa_configuracao.py +0 -0
  34. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/rpa_fila.py +0 -0
  35. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/rpa_historico.py +0 -0
  36. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/rpa_processo.py +0 -0
  37. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dao/rpa_robo.py +0 -0
  38. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/__init__.py +0 -0
  39. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/rpa_historico_request_dto.py +0 -0
  40. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/rpa_processo_entrada_dto.py +0 -0
  41. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/rpa_processo_rdp_dto.py +0 -0
  42. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/rpa_sap_dto.py +0 -0
  43. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/models/dto/rpa_sistema_dto.py +0 -0
  44. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/__init__.py +0 -0
  45. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/__init__.py +0 -0
  46. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +0 -0
  47. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/coleta_dje_process.py +0 -0
  48. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/conexao_rdp.py +0 -0
  49. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/cte_manual.py +0 -0
  50. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/cte_xml.py +0 -0
  51. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/devolucao_ctf.py +0 -0
  52. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/devolucao_ctf_35.py +0 -0
  53. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/devolucao_prazo_a_faturar.py +0 -0
  54. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_estadual_go.py +0 -0
  55. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_estadual_main.py +0 -0
  56. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_estadual_mt.py +0 -0
  57. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_estadual_sc.py +0 -0
  58. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_estadual_sp.py +0 -0
  59. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/ecac_federal.py +0 -0
  60. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_cte_1353.py +0 -0
  61. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_cte_333.py +0 -0
  62. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_15.py +0 -0
  63. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_16.py +0 -0
  64. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_207.py +0 -0
  65. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_32.py +0 -0
  66. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_33.py +0 -0
  67. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_34.py +0 -0
  68. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_36.py +0 -0
  69. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_39.py +0 -0
  70. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_500.py +0 -0
  71. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_503.py +0 -0
  72. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_505.py +0 -0
  73. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_7139.py +0 -0
  74. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_9.py +0 -0
  75. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/entrada_de_notas_9000.py +0 -0
  76. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/exemplo_processo.py +0 -0
  77. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/extracao_fechamento_contabil.py +0 -0
  78. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/extracao_fechamento_emsys.py +0 -0
  79. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/fechar_conexao_rdp.py +0 -0
  80. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/fidc_exportacao_docs_portal_b2b.py +0 -0
  81. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py +0 -0
  82. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/fidc_remessa_cobranca_cnab240.py +0 -0
  83. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/fidc_retorno_cobranca.py +0 -0
  84. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/geracao_aprovacao_pedidos.py +0 -0
  85. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/geracao_aprovacao_pedidos_novo.py +0 -0
  86. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/integracao_contabil.py +0 -0
  87. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/integracao_contabil_generica.py +0 -0
  88. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/lancamento_pis_cofins.py +0 -0
  89. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/lancamento_rateio.py +0 -0
  90. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/login_emsys.py +0 -0
  91. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/login_emsys_versao_especifica.py +0 -0
  92. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/notas_faturamento_sap.py +0 -0
  93. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/opex_capex.py +0 -0
  94. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/playground.py +0 -0
  95. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/jobs/sped_fiscal.py +0 -0
  96. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/task_definitions.py +0 -0
  97. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/tasks/task_executor.py +0 -0
  98. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/__init__.py +0 -0
  99. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/env.py +0 -0
  100. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/get_creds_gworkspace.py +0 -0
  101. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/logger.py +0 -0
  102. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/toast.py +0 -0
  103. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/updater.py +0 -0
  104. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/util.py +0 -0
  105. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/worker_automate_hub/utils/utils_nfe_entrada.py +0 -0
  106. {worker_automate_hub-0.5.763 → worker_automate_hub-0.5.765}/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.763
3
+ Version: 0.5.765
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.763"
3
+ version = "0.5.765"
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"
@@ -65,7 +65,7 @@ async def descartes(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
65
65
 
66
66
  # Fecha a instancia do emsys - caso esteja aberta
67
67
  await kill_all_emsys()
68
- app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_38.exe")
68
+ app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_10.exe")
69
69
  warnings.filterwarnings(
70
70
  "ignore",
71
71
  category=UserWarning,
@@ -1,9 +1,10 @@
1
1
  import asyncio
2
2
  import os
3
3
  from datetime import datetime
4
- from pywinauto import Application, timings, findwindows
4
+ from pywinauto import Application, timings, findwindows, Desktop
5
5
  import sys
6
6
  import io
7
+ import win32gui
7
8
  # sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
8
9
 
9
10
  from worker_automate_hub.models.dto.rpa_historico_request_dto import (
@@ -114,10 +115,13 @@ async def extracao_saldo_estoque(task: RpaProcessoEntradaDTO):
114
115
  tentativa = 1
115
116
  sucesso = False
116
117
 
118
+ # defina caminho_arquivo ANTES para não ficar indefinido
119
+ caminho_arquivo = rf"C:\Users\automatehub\Downloads\saldo_estoque_{periodo_format}_{filial}.xlsx"
120
+
117
121
  while tentativa <= max_tentativas and not sucesso:
118
122
  console.print(f"Tentativa {tentativa} de {max_tentativas}", style="bold cyan")
119
123
 
120
- # 1) Abrir o picker de formatos pelo botão (imagem)
124
+ # 1) Abrir o picker pelo botão (imagem)
121
125
  console.print("Procurando botão de salvar (imagem)...", style="bold cyan")
122
126
  caminho_img = r'assets\\extracao_relatorios\\btn_salvar.png'
123
127
  if os.path.isfile(caminho_img):
@@ -132,40 +136,92 @@ async def extracao_saldo_estoque(task: RpaProcessoEntradaDTO):
132
136
 
133
137
  await worker_sleep(8)
134
138
 
135
- # 2) Selecionar formato "Excel" na janela TFrmRelatorioFormato
139
+ # 2) Selecionar formato Excel (desambiguando múltiplas TFrmRelatorioFormato)
136
140
  console.print("Selecionando formato Excel...", style="bold cyan")
137
141
  try:
138
- app_fmt = Application().connect(class_name="TFrmRelatorioFormato", timeout=10)
139
- win_fmt = app_fmt["TFrmRelatorioFormato"]
140
- win_fmt.wait("visible", timeout=10)
142
+ desktop = Desktop(backend="win32")
143
+
144
+ # Liste todas as visíveis
145
+ wins_visiveis = desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True)
146
+ if not wins_visiveis:
147
+ raise RuntimeError("Janela de formato não apareceu.")
148
+
149
+ # 2.1) Tente a janela em foco (foreground)
150
+ h_fore = win32gui.GetForegroundWindow()
151
+ alvo = None
152
+ for w in wins_visiveis:
153
+ if w.handle == h_fore:
154
+ alvo = w
155
+ break
156
+
157
+ # 2.2) Se não estiver em foco, pegue a que contém um TComboBox (a 'Configuração para Salvar arq...')
158
+ if alvo is None:
159
+ candidatos = []
160
+ for w in wins_visiveis:
161
+ try:
162
+ if w.child_window(class_name="TComboBox").exists(timeout=0.8):
163
+ candidatos.append(w)
164
+ except Exception:
165
+ pass
166
+ if candidatos:
167
+ alvo = candidatos[-1] # a mais recente
168
+ else:
169
+ alvo = wins_visiveis[-1] # fallback
170
+
171
+ # Trabalhe via WindowSpecification
172
+ spec_fmt = desktop.window(handle=alvo.handle)
173
+ spec_fmt.wait("visible", timeout=10)
174
+ win_fmt = spec_fmt.wrapper_object()
175
+ win_fmt.set_focus()
176
+
177
+ # Acessar o ComboBox
178
+ try:
179
+ combo_spec = spec_fmt.child_window(class_name="TComboBox")
180
+ except Exception:
181
+ combo_spec = spec_fmt.child_window(control_type="ComboBox")
182
+ combo_spec.wait("exists enabled", timeout=10)
183
+ combo = combo_spec.wrapper_object()
141
184
 
142
- combo = win_fmt.ComboBox
143
185
  textos = combo.texts()
144
186
  console.print(f"Itens do ComboBox: {textos}", style="bold yellow")
145
187
 
146
- # Se souber o índice correto, mantenha. Caso contrário, tente por texto contendo 'Excel'
188
+ # Seleção por índice conhecido; fallback por texto
147
189
  try:
148
190
  combo.select(8)
149
191
  except Exception:
150
- alvo = None
192
+ alvo_idx = None
151
193
  for i, t in enumerate(textos):
152
194
  if "EXCEL" in str(t).upper() or "XLSX" in str(t).upper():
153
- alvo = i
195
+ alvo_idx = i
154
196
  break
155
- if alvo is not None:
156
- combo.select(alvo)
157
- else:
197
+ if alvo_idx is None:
158
198
  console.print("Não foi possível localizar a opção de Excel no ComboBox.", style="bold red")
159
199
  tentativa += 1
160
200
  await worker_sleep(2)
161
201
  continue
202
+ combo.select(alvo_idx)
162
203
 
163
204
  await worker_sleep(1)
164
205
 
165
- # Botão OK/Confirmar na janela de formato
166
- # Em muitos Delphi VCL, TBitBtn com found_index=1 costuma ser OK.
167
- win_fmt.child_window(class_name="TBitBtn", found_index=1).wait("enabled", timeout=5)
168
- win_fmt.child_window(class_name="TBitBtn", found_index=1).click_input()
206
+ # Clique em OK
207
+ btn_ok_spec = spec_fmt.child_window(class_name="TBitBtn", found_index=1)
208
+ btn_ok_spec.wait("enabled", timeout=5)
209
+ btn_ok_spec.click_input()
210
+
211
+ # Aguarde a janela de formato desaparecer
212
+ try:
213
+ spec_fmt.wait_not("visible", timeout=10)
214
+ except Exception:
215
+ pass
216
+
217
+ # Feche possíveis duplicatas remanescentes (defensivo)
218
+ for w in desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True):
219
+ if w.handle != alvo.handle:
220
+ try:
221
+ w.close()
222
+ except Exception:
223
+ pass
224
+
169
225
  except Exception as e:
170
226
  console.print(f"Falha ao selecionar formato: {e}", style="bold red")
171
227
  tentativa += 1
@@ -177,19 +233,17 @@ async def extracao_saldo_estoque(task: RpaProcessoEntradaDTO):
177
233
  # 3) Janela "Salvar para arquivo"
178
234
  console.print("Abrindo janela de salvar arquivo...", style="bold cyan")
179
235
  try:
180
- app_save = Application().connect(title_re="Salvar para arquivo", timeout=30)
181
- win_save = app_save.window(title_re="Salvar para arquivo")
182
- win_save.wait("visible", timeout=30)
236
+ app_save = Application(backend="win32").connect(title_re="Salvar para arquivo|Salvar como|Save As", timeout=30)
237
+ spec_save = app_save.window(title_re="Salvar para arquivo|Salvar como|Save As")
238
+ spec_save.wait("visible", timeout=30)
239
+ win_save = spec_save.wrapper_object()
183
240
  except Exception as e:
184
241
  console.print(f"Não achou a janela 'Salvar para arquivo': {e}", style="bold red")
185
242
  tentativa += 1
186
243
  await worker_sleep(3)
187
244
  continue
188
245
 
189
- # Caminho do arquivo a salvar
190
- caminho_arquivo = rf"C:\Users\automatehub\Downloads\saldo_estoque_{periodo_format}_{filial}.xlsx"
191
-
192
- # Se já existe, removemos para evitar pop-up de confirmação
246
+ # 3.1) Remover arquivo pré-existente
193
247
  if os.path.exists(caminho_arquivo):
194
248
  try:
195
249
  os.remove(caminho_arquivo)
@@ -197,27 +251,32 @@ async def extracao_saldo_estoque(task: RpaProcessoEntradaDTO):
197
251
  except Exception as e:
198
252
  console.print(f"Não foi possível remover o arquivo existente: {e}", style="bold red")
199
253
 
254
+ # 3.2) Preencher nome e salvar
200
255
  try:
201
- # Campo "Nome" (Edit, control_id=1148)
202
- campo_nome = win_save.child_window(class_name="Edit", control_id=1148).wrapper_object()
256
+ campo_spec = spec_save.child_window(class_name="Edit", control_id=1148)
257
+ campo_spec.wait("exists enabled visible", timeout=10)
258
+ campo_nome = campo_spec.wrapper_object()
203
259
  campo_nome.set_focus()
204
- # limpa conteúdo
205
260
  try:
206
261
  campo_nome.set_edit_text("")
207
262
  except Exception:
208
- # fallback limpando com Ctrl+A + Delete
209
263
  campo_nome.type_keys("^a{DELETE}", pause=0.02)
210
264
 
211
- # digita caminho
212
265
  campo_nome.type_keys(caminho_arquivo, with_spaces=True, pause=0.01)
213
266
  console.print(f"Arquivo configurado para: {caminho_arquivo}", style="bold green")
214
267
 
215
268
  await worker_sleep(1)
216
269
 
217
- # Botão Salvar (primeiro Button)
218
- btn_salvar = win_save.child_window(class_name="Button", found_index=0)
219
- btn_salvar.wait("enabled", timeout=10)
220
- btn_salvar.click_input()
270
+ btn_salvar_spec = spec_save.child_window(class_name="Button", found_index=0)
271
+ btn_salvar_spec.wait("enabled", timeout=10)
272
+ btn_salvar_spec.click_input()
273
+
274
+ # Esperar a janela sumir
275
+ try:
276
+ spec_save.wait_not("visible", timeout=15)
277
+ except Exception:
278
+ pass
279
+
221
280
  except Exception as e:
222
281
  console.print(f"Erro ao confirmar salvar: {e}", style="bold red")
223
282
  tentativa += 1
@@ -226,32 +285,27 @@ async def extracao_saldo_estoque(task: RpaProcessoEntradaDTO):
226
285
 
227
286
  await worker_sleep(2)
228
287
 
229
- # 3.1) Tratar confirmação de sobrescrita, se aparecer
288
+ # 3.3) Confirmar sobrescrita (se houver)
230
289
  try:
231
- # Pode vir em PT/EN dependendo do SO
232
- # Título comum: "Confirm Save As" (EN) ou "Confirmar Salvar Como" (PT)
233
- try:
234
- app_conf = Application().connect(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As", timeout=3)
235
- win_conf = app_conf.window(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As")
236
- win_conf.wait("visible", timeout=3)
237
- # Botões costumam ser "Sim"/"Yes" como class_name="Button"
238
- # Tente o primeiro botão (Yes/Sim)
239
- win_conf.child_window(class_name="Button", found_index=0).click_input()
240
- console.print("Confirmação de sobrescrita respondida.", style="bold yellow")
241
- except Exception:
242
- pass
290
+ app_conf = Application(backend="win32").connect(
291
+ title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As", timeout=3
292
+ )
293
+ spec_conf = app_conf.window(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As")
294
+ spec_conf.wait("visible", timeout=3)
295
+ spec_conf.child_window(class_name="Button", found_index=0).click_input()
296
+ console.print("Confirmação de sobrescrita respondida.", style="bold yellow")
243
297
  except Exception:
244
298
  pass
245
299
 
246
300
  await worker_sleep(2)
247
301
 
248
- # 4) Aguardar o processamento/Printing encerrar
302
+ # 4) Aguardar 'Printing' (se existir)
249
303
  console.print("Aguardando finalização do processo de impressão/salvamento...", style="bold cyan")
250
304
  try:
251
- app_print = Application().connect(title_re="Printing", timeout=5)
252
- win_print = app_print.window(title_re="Printing")
305
+ app_print = Application(backend="win32").connect(title_re="Printing", timeout=5)
306
+ spec_print = app_print.window(title_re="Printing")
253
307
  try:
254
- win_print.wait_not("visible", timeout=60)
308
+ spec_print.wait_not("visible", timeout=60)
255
309
  console.print("Janela 'Printing' fechada.", style="bold green")
256
310
  except Exception:
257
311
  console.print("Janela 'Printing' não fechou no tempo esperado. Seguindo.", style="bold yellow")
@@ -5,6 +5,7 @@ from pywinauto import Application, timings, findwindows, keyboard, Desktop
5
5
  import sys
6
6
  import io
7
7
  import win32gui
8
+
8
9
  # sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
9
10
 
10
11
  from worker_automate_hub.models.dto.rpa_historico_request_dto import (
@@ -59,9 +60,7 @@ async def extracao_saldo_estoque_fiscal(
59
60
  # Fecha a instancia do emsys - caso esteja aberta
60
61
  await kill_all_emsys()
61
62
 
62
- app = Application(backend="win32").start(
63
- "C:\\Rezende\\EMSys3\\EMSysFiscal_39.exe"
64
- )
63
+ app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSysFiscal.exe")
65
64
  warnings.filterwarnings(
66
65
  "ignore",
67
66
  category=UserWarning,
@@ -282,7 +281,6 @@ async def extracao_saldo_estoque_fiscal(
282
281
 
283
282
  await worker_sleep(2)
284
283
 
285
-
286
284
  max_tentativas = 5
287
285
  tentativa = 1
288
286
  sucesso = False
@@ -291,18 +289,25 @@ async def extracao_saldo_estoque_fiscal(
291
289
  caminho_arquivo = rf"C:\Users\automatehub\Downloads\saldo_estoque_fiscal_{periodo_format}_{filial}.xlsx"
292
290
 
293
291
  while tentativa <= max_tentativas and not sucesso:
294
- console.print(f"Tentativa {tentativa} de {max_tentativas}", style="bold cyan")
292
+ console.print(
293
+ f"Tentativa {tentativa} de {max_tentativas}", style="bold cyan"
294
+ )
295
295
 
296
296
  # 1) Abrir o picker pelo botão (imagem)
297
297
  console.print("Procurando botão de salvar (imagem)...", style="bold cyan")
298
- caminho_img = r'assets\\extracao_relatorios\\btn_salvar.png'
298
+ caminho_img = r"assets\\extracao_relatorios\\btn_salvar.png"
299
299
  if os.path.isfile(caminho_img):
300
300
  pos = pyautogui.locateCenterOnScreen(caminho_img, confidence=0.9)
301
301
  if pos:
302
302
  pyautogui.click(pos)
303
- console.print("Clique realizado no botão salvar", style="bold green")
303
+ console.print(
304
+ "Clique realizado no botão salvar", style="bold green"
305
+ )
304
306
  else:
305
- console.print("Imagem encontrada mas não está visível na tela", style="bold yellow")
307
+ console.print(
308
+ "Imagem encontrada mas não está visível na tela",
309
+ style="bold yellow",
310
+ )
306
311
  else:
307
312
  console.print("Imagem do botão salvar NÃO existe", style="bold red")
308
313
 
@@ -314,7 +319,9 @@ async def extracao_saldo_estoque_fiscal(
314
319
  desktop = Desktop(backend="win32")
315
320
 
316
321
  # Liste todas as visíveis
317
- wins_visiveis = desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True)
322
+ wins_visiveis = desktop.windows(
323
+ class_name="TFrmRelatorioFormato", visible_only=True
324
+ )
318
325
  if not wins_visiveis:
319
326
  raise RuntimeError("Janela de formato não apareceu.")
320
327
 
@@ -331,12 +338,14 @@ async def extracao_saldo_estoque_fiscal(
331
338
  candidatos = []
332
339
  for w in wins_visiveis:
333
340
  try:
334
- if w.child_window(class_name="TComboBox").exists(timeout=0.8):
341
+ if w.child_window(class_name="TComboBox").exists(
342
+ timeout=0.8
343
+ ):
335
344
  candidatos.append(w)
336
345
  except Exception:
337
346
  pass
338
347
  if candidatos:
339
- alvo = candidatos[-1] # a mais recente
348
+ alvo = candidatos[-1] # a mais recente
340
349
  else:
341
350
  alvo = wins_visiveis[-1] # fallback
342
351
 
@@ -367,7 +376,10 @@ async def extracao_saldo_estoque_fiscal(
367
376
  alvo_idx = i
368
377
  break
369
378
  if alvo_idx is None:
370
- console.print("Não foi possível localizar a opção de Excel no ComboBox.", style="bold red")
379
+ console.print(
380
+ "Não foi possível localizar a opção de Excel no ComboBox.",
381
+ style="bold red",
382
+ )
371
383
  tentativa += 1
372
384
  await worker_sleep(2)
373
385
  continue
@@ -387,7 +399,9 @@ async def extracao_saldo_estoque_fiscal(
387
399
  pass
388
400
 
389
401
  # Feche possíveis duplicatas remanescentes (defensivo)
390
- for w in desktop.windows(class_name="TFrmRelatorioFormato", visible_only=True):
402
+ for w in desktop.windows(
403
+ class_name="TFrmRelatorioFormato", visible_only=True
404
+ ):
391
405
  if w.handle != alvo.handle:
392
406
  try:
393
407
  w.close()
@@ -405,12 +419,18 @@ async def extracao_saldo_estoque_fiscal(
405
419
  # 3) Janela "Salvar para arquivo"
406
420
  console.print("Abrindo janela de salvar arquivo...", style="bold cyan")
407
421
  try:
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")
422
+ app_save = Application(backend="win32").connect(
423
+ title_re="Salvar para arquivo|Salvar como|Save As", timeout=30
424
+ )
425
+ spec_save = app_save.window(
426
+ title_re="Salvar para arquivo|Salvar como|Save As"
427
+ )
410
428
  spec_save.wait("visible", timeout=30)
411
429
  win_save = spec_save.wrapper_object()
412
430
  except Exception as e:
413
- console.print(f"Não achou a janela 'Salvar para arquivo': {e}", style="bold red")
431
+ console.print(
432
+ f"Não achou a janela 'Salvar para arquivo': {e}", style="bold red"
433
+ )
414
434
  tentativa += 1
415
435
  await worker_sleep(3)
416
436
  continue
@@ -419,9 +439,15 @@ async def extracao_saldo_estoque_fiscal(
419
439
  if os.path.exists(caminho_arquivo):
420
440
  try:
421
441
  os.remove(caminho_arquivo)
422
- console.print("Arquivo existente removido para evitar prompt de sobrescrita.", style="bold yellow")
442
+ console.print(
443
+ "Arquivo existente removido para evitar prompt de sobrescrita.",
444
+ style="bold yellow",
445
+ )
423
446
  except Exception as e:
424
- console.print(f"Não foi possível remover o arquivo existente: {e}", style="bold red")
447
+ console.print(
448
+ f"Não foi possível remover o arquivo existente: {e}",
449
+ style="bold red",
450
+ )
425
451
 
426
452
  # 3.2) Preencher nome e salvar
427
453
  try:
@@ -435,11 +461,15 @@ async def extracao_saldo_estoque_fiscal(
435
461
  campo_nome.type_keys("^a{DELETE}", pause=0.02)
436
462
 
437
463
  campo_nome.type_keys(caminho_arquivo, with_spaces=True, pause=0.01)
438
- console.print(f"Arquivo configurado para: {caminho_arquivo}", style="bold green")
464
+ console.print(
465
+ f"Arquivo configurado para: {caminho_arquivo}", style="bold green"
466
+ )
439
467
 
440
468
  await worker_sleep(1)
441
469
 
442
- btn_salvar_spec = spec_save.child_window(class_name="Button", found_index=0)
470
+ btn_salvar_spec = spec_save.child_window(
471
+ class_name="Button", found_index=0
472
+ )
443
473
  btn_salvar_spec.wait("enabled", timeout=10)
444
474
  btn_salvar_spec.click_input()
445
475
 
@@ -462,25 +492,37 @@ async def extracao_saldo_estoque_fiscal(
462
492
  app_conf = Application(backend="win32").connect(
463
493
  title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As", timeout=3
464
494
  )
465
- spec_conf = app_conf.window(title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As")
495
+ spec_conf = app_conf.window(
496
+ title_re="Confirm(ar)?( )?Salvar( )?Como|Confirm Save As"
497
+ )
466
498
  spec_conf.wait("visible", timeout=3)
467
499
  spec_conf.child_window(class_name="Button", found_index=0).click_input()
468
- console.print("Confirmação de sobrescrita respondida.", style="bold yellow")
500
+ console.print(
501
+ "Confirmação de sobrescrita respondida.", style="bold yellow"
502
+ )
469
503
  except Exception:
470
504
  pass
471
505
 
472
506
  await worker_sleep(2)
473
507
 
474
508
  # 4) Aguardar 'Printing' (se existir)
475
- console.print("Aguardando finalização do processo de impressão/salvamento...", style="bold cyan")
509
+ console.print(
510
+ "Aguardando finalização do processo de impressão/salvamento...",
511
+ style="bold cyan",
512
+ )
476
513
  try:
477
- app_print = Application(backend="win32").connect(title_re="Printing", timeout=5)
514
+ app_print = Application(backend="win32").connect(
515
+ title_re="Printing", timeout=5
516
+ )
478
517
  spec_print = app_print.window(title_re="Printing")
479
518
  try:
480
519
  spec_print.wait_not("visible", timeout=60)
481
520
  console.print("Janela 'Printing' fechada.", style="bold green")
482
521
  except Exception:
483
- console.print("Janela 'Printing' não fechou no tempo esperado. Seguindo.", style="bold yellow")
522
+ console.print(
523
+ "Janela 'Printing' não fechou no tempo esperado. Seguindo.",
524
+ style="bold yellow",
525
+ )
484
526
  except findwindows.ElementNotFoundError:
485
527
  console.print("Janela 'Printing' não apareceu.", style="bold yellow")
486
528
  except Exception as e:
@@ -488,17 +530,23 @@ async def extracao_saldo_estoque_fiscal(
488
530
 
489
531
  # 5) Validar arquivo salvo
490
532
  if os.path.exists(caminho_arquivo):
491
- console.print(f"Arquivo encontrado: {caminho_arquivo}", style="bold green")
533
+ console.print(
534
+ f"Arquivo encontrado: {caminho_arquivo}", style="bold green"
535
+ )
492
536
  with open(caminho_arquivo, "rb") as f:
493
537
  file_bytes = io.BytesIO(f.read())
494
538
  sucesso = True
495
539
  else:
496
- console.print("Arquivo não encontrado, tentando novamente...", style="bold red")
540
+ console.print(
541
+ "Arquivo não encontrado, tentando novamente...", style="bold red"
542
+ )
497
543
  tentativa += 1
498
544
  await worker_sleep(3)
499
545
 
500
546
  if not sucesso:
501
- console.print("Falha após 5 tentativas. Arquivo não foi gerado.", style="bold red")
547
+ console.print(
548
+ "Falha após 5 tentativas. Arquivo não foi gerado.", style="bold red"
549
+ )
502
550
 
503
551
  nome_com_extensao = f"saldo_estoque_fiscal_{periodo_format}_{filial}.xlsx"
504
552
  # lê o arquivo
@@ -542,4 +590,3 @@ async def extracao_saldo_estoque_fiscal(
542
590
  status=RpaHistoricoStatusEnum.Falha,
543
591
  tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)],
544
592
  )
545
-
@@ -67,7 +67,7 @@ async def transferencias(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
67
67
 
68
68
  # Fecha a instancia do emsys - caso esteja aberta
69
69
  await kill_all_emsys()
70
- app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_38.exe")
70
+ app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_10.exe")
71
71
  warnings.filterwarnings(
72
72
  "ignore",
73
73
  category=UserWarning,