worker-automate-hub 0.5.796__py3-none-any.whl → 0.5.798__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.
Potentially problematic release.
This version of worker-automate-hub might be problematic. Click here for more details.
- worker_automate_hub/tasks/jobs/entrada_de_notas_22.py +833 -0
- worker_automate_hub/tasks/jobs/entrada_de_notas_9.py +10 -12
- worker_automate_hub/tasks/task_definitions.py +5 -1
- {worker_automate_hub-0.5.796.dist-info → worker_automate_hub-0.5.798.dist-info}/METADATA +1 -1
- {worker_automate_hub-0.5.796.dist-info → worker_automate_hub-0.5.798.dist-info}/RECORD +7 -6
- {worker_automate_hub-0.5.796.dist-info → worker_automate_hub-0.5.798.dist-info}/WHEEL +1 -1
- {worker_automate_hub-0.5.796.dist-info → worker_automate_hub-0.5.798.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
import difflib
|
|
2
|
+
import getpass
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import warnings
|
|
6
|
+
import time
|
|
7
|
+
import uuid
|
|
8
|
+
import asyncio
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
import pyautogui
|
|
11
|
+
import pytesseract
|
|
12
|
+
import win32clipboard
|
|
13
|
+
from PIL import Image, ImageEnhance
|
|
14
|
+
from pywinauto.application import Application
|
|
15
|
+
from pywinauto import Desktop
|
|
16
|
+
from pywinauto.findwindows import ElementNotFoundError
|
|
17
|
+
from pywinauto.keyboard import send_keys
|
|
18
|
+
from pywinauto.timings import wait_until
|
|
19
|
+
from pywinauto_recorder.player import set_combobox
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
from decimal import Decimal, InvalidOperation
|
|
22
|
+
from typing import Any, Dict, List
|
|
23
|
+
import sys
|
|
24
|
+
# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")))
|
|
25
|
+
from worker_automate_hub.api.ahead_service import save_xml_to_downloads
|
|
26
|
+
from worker_automate_hub.api.client import (
|
|
27
|
+
get_config_by_name,
|
|
28
|
+
get_status_nf_emsys,
|
|
29
|
+
)
|
|
30
|
+
from worker_automate_hub.models.dto.rpa_historico_request_dto import (
|
|
31
|
+
RpaHistoricoStatusEnum,
|
|
32
|
+
RpaRetornoProcessoDTO,
|
|
33
|
+
RpaTagDTO,
|
|
34
|
+
RpaTagEnum,
|
|
35
|
+
)
|
|
36
|
+
from worker_automate_hub.models.dto.rpa_processo_entrada_dto import (
|
|
37
|
+
RpaProcessoEntradaDTO,
|
|
38
|
+
)
|
|
39
|
+
from worker_automate_hub.utils.logger import logger
|
|
40
|
+
from worker_automate_hub.utils.util import (
|
|
41
|
+
cod_icms,
|
|
42
|
+
delete_xml,
|
|
43
|
+
error_after_xml_imported,
|
|
44
|
+
get_xml,
|
|
45
|
+
import_nfe,
|
|
46
|
+
incluir_registro,
|
|
47
|
+
is_window_open,
|
|
48
|
+
is_window_open_by_class,
|
|
49
|
+
itens_not_found_supplier,
|
|
50
|
+
kill_all_emsys,
|
|
51
|
+
login_emsys,
|
|
52
|
+
rateio_despesa,
|
|
53
|
+
select_documento_type,
|
|
54
|
+
set_variable,
|
|
55
|
+
tipo_despesa,
|
|
56
|
+
type_text_into_field,
|
|
57
|
+
warnings_after_xml_imported,
|
|
58
|
+
worker_sleep,
|
|
59
|
+
zerar_icms,
|
|
60
|
+
check_nota_importada,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
pyautogui.PAUSE = 0.5
|
|
64
|
+
pyautogui.FAILSAFE = False
|
|
65
|
+
console = Console()
|
|
66
|
+
|
|
67
|
+
# limite permitido (<= 5.89 pode seguir)
|
|
68
|
+
VALOR_UNITARIO_MAX = Decimal("5.89")
|
|
69
|
+
|
|
70
|
+
def _to_decimal(valor: Any, default: Decimal = Decimal("0")) -> Decimal:
|
|
71
|
+
"""
|
|
72
|
+
Converte valores como '5,89', '5.89', 5.89, None para Decimal com segurança.
|
|
73
|
+
"""
|
|
74
|
+
if valor is None:
|
|
75
|
+
return default
|
|
76
|
+
if isinstance(valor, (int, float, Decimal)):
|
|
77
|
+
return Decimal(str(valor))
|
|
78
|
+
s = str(valor).strip().replace(",", ".")
|
|
79
|
+
try:
|
|
80
|
+
return Decimal(s)
|
|
81
|
+
except (InvalidOperation, ValueError):
|
|
82
|
+
return default
|
|
83
|
+
|
|
84
|
+
async def entrada_de_notas_22(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoDTO:
|
|
85
|
+
"""
|
|
86
|
+
Executa o processo de entrada de notas.
|
|
87
|
+
Regra de negócio: se QUALQUER item tiver valorUnitario > 5,89, retornar erro imediatamente.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
cfg: Dict[str, Any] = getattr(task, "configEntrada", {}) or {}
|
|
91
|
+
itens: List[Dict[str, Any]] = cfg.get("itens", []) or []
|
|
92
|
+
|
|
93
|
+
# --- Validação de valorUnitario ---
|
|
94
|
+
acima_limite = []
|
|
95
|
+
for idx, item in enumerate(itens, start=1):
|
|
96
|
+
valor_unit = _to_decimal(item.get("valorUnitario"))
|
|
97
|
+
if valor_unit > VALOR_UNITARIO_MAX:
|
|
98
|
+
acima_limite.append({
|
|
99
|
+
"idx": idx,
|
|
100
|
+
"codigoProduto": item.get("codigoProduto"),
|
|
101
|
+
"descricaoProduto": item.get("descricaoProduto"),
|
|
102
|
+
"valorUnitario": str(valor_unit)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
if acima_limite:
|
|
106
|
+
# Monta mensagem amigável com os itens fora da regra
|
|
107
|
+
detalhes = "; ".join(
|
|
108
|
+
f"item {x['idx']} (cód. {x.get('codigoProduto') or 's/ código'}): "
|
|
109
|
+
f"valorUnitario={x['valorUnitario']} (> {VALOR_UNITARIO_MAX})"
|
|
110
|
+
for x in acima_limite
|
|
111
|
+
)
|
|
112
|
+
observacao = (
|
|
113
|
+
"Erro Processo Entrada de Notas: Foi identificado ao menos um item com "
|
|
114
|
+
f"valorUnitario acima do permitido ({VALOR_UNITARIO_MAX}). Detalhes: {detalhes}"
|
|
115
|
+
)
|
|
116
|
+
logger.error(observacao)
|
|
117
|
+
console.print(observacao, style="bold red")
|
|
118
|
+
return RpaRetornoProcessoDTO(
|
|
119
|
+
sucesso=False,
|
|
120
|
+
retorno=observacao,
|
|
121
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
122
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
123
|
+
)
|
|
124
|
+
try:
|
|
125
|
+
# Get config from BOF
|
|
126
|
+
config = await get_config_by_name("login_emsys")
|
|
127
|
+
console.print(task)
|
|
128
|
+
|
|
129
|
+
# Seta config entrada na var nota
|
|
130
|
+
nota = task.configEntrada
|
|
131
|
+
# conversão no formato certo: dd/mm/yyyy
|
|
132
|
+
data_vencimento = datetime.strptime(nota['dataVencimento'], "%d/%m/%Y").date()
|
|
133
|
+
hoje = datetime.today().date()
|
|
134
|
+
|
|
135
|
+
if data_vencimento <= hoje:
|
|
136
|
+
data_vencimento = hoje + timedelta(days=1)
|
|
137
|
+
while data_vencimento.weekday() >= 5: # 5 = sábado, 6 = domingo
|
|
138
|
+
data_vencimento += timedelta(days=1)
|
|
139
|
+
|
|
140
|
+
data_vencimento = data_vencimento.strftime("%d/%m/%Y")
|
|
141
|
+
print("Data ajustada:", data_vencimento)
|
|
142
|
+
valor_nota = nota['valorNota']
|
|
143
|
+
multiplicador_timeout = int(float(task.sistemas[0].timeout))
|
|
144
|
+
set_variable("timeout_multiplicador", multiplicador_timeout)
|
|
145
|
+
|
|
146
|
+
# Fecha a instancia do emsys - caso esteja aberta
|
|
147
|
+
await kill_all_emsys()
|
|
148
|
+
|
|
149
|
+
# Download XML
|
|
150
|
+
console.log("Realizando o download do XML..\n")
|
|
151
|
+
await save_xml_to_downloads(nota["nfe"])
|
|
152
|
+
|
|
153
|
+
app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_10.exe")
|
|
154
|
+
warnings.filterwarnings(
|
|
155
|
+
"ignore",
|
|
156
|
+
category=UserWarning,
|
|
157
|
+
message="32-bit application should be automated using 32-bit Python",
|
|
158
|
+
)
|
|
159
|
+
console.print("\nEMSys iniciando...", style="bold green")
|
|
160
|
+
return_login = await login_emsys(config.conConfiguracao, app, task)
|
|
161
|
+
|
|
162
|
+
if return_login.sucesso == True:
|
|
163
|
+
type_text_into_field(
|
|
164
|
+
"Nota Fiscal de Entrada", app["TFrmMenuPrincipal"]["Edit"], True, "50"
|
|
165
|
+
)
|
|
166
|
+
pyautogui.press("enter")
|
|
167
|
+
await worker_sleep(2)
|
|
168
|
+
pyautogui.press("enter")
|
|
169
|
+
console.print(
|
|
170
|
+
f"\nPesquisa: 'Nota Fiscal de Entrada' realizada com sucesso",
|
|
171
|
+
style="bold green",
|
|
172
|
+
)
|
|
173
|
+
else:
|
|
174
|
+
logger.info(f"\nError Message: {return_login.retorno}")
|
|
175
|
+
console.print(f"\nError Message: {return_login.retorno}", style="bold red")
|
|
176
|
+
return return_login
|
|
177
|
+
|
|
178
|
+
await worker_sleep(6)
|
|
179
|
+
|
|
180
|
+
# Procura campo documento
|
|
181
|
+
console.print("Navegando pela Janela de Nota Fiscal de Entrada...\n")
|
|
182
|
+
document_type = await select_documento_type(
|
|
183
|
+
"NOTA FISCAL DE ENTRADA ELETRONICA - DANFE"
|
|
184
|
+
)
|
|
185
|
+
if document_type.sucesso == True:
|
|
186
|
+
console.log(document_type.retorno, style="bold green")
|
|
187
|
+
else:
|
|
188
|
+
return RpaRetornoProcessoDTO(
|
|
189
|
+
sucesso=False,
|
|
190
|
+
retorno=document_type.retorno,
|
|
191
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
192
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
await worker_sleep(4)
|
|
196
|
+
|
|
197
|
+
# Clica em 'Importar-Nfe'
|
|
198
|
+
imported_nfe = await import_nfe()
|
|
199
|
+
if imported_nfe.sucesso == True:
|
|
200
|
+
console.log(imported_nfe.retorno, style="bold green")
|
|
201
|
+
else:
|
|
202
|
+
return RpaRetornoProcessoDTO(
|
|
203
|
+
sucesso=False,
|
|
204
|
+
retorno=imported_nfe.retorno,
|
|
205
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
206
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
await worker_sleep(5)
|
|
210
|
+
|
|
211
|
+
await get_xml(nota.get("nfe"))
|
|
212
|
+
await worker_sleep(3)
|
|
213
|
+
|
|
214
|
+
# VERIFICANDO A EXISTENCIA DE WARNINGS
|
|
215
|
+
warning_pop_up = await is_window_open("Warning")
|
|
216
|
+
if warning_pop_up["IsOpened"] == True:
|
|
217
|
+
warning_work = await warnings_after_xml_imported()
|
|
218
|
+
if warning_work.sucesso == True:
|
|
219
|
+
console.log(warning_work.retorno, style="bold green")
|
|
220
|
+
else:
|
|
221
|
+
return RpaRetornoProcessoDTO(
|
|
222
|
+
sucesso=False,
|
|
223
|
+
retorno=warning_work.retorno,
|
|
224
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
225
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# VERIFICANDO A EXISTENCIA DE ERRO
|
|
229
|
+
erro_pop_up = await is_window_open("Erro")
|
|
230
|
+
if erro_pop_up["IsOpened"] == True:
|
|
231
|
+
error_work = await error_after_xml_imported()
|
|
232
|
+
return RpaRetornoProcessoDTO(
|
|
233
|
+
sucesso=error_work.sucesso,
|
|
234
|
+
retorno=error_work.retorno,
|
|
235
|
+
status=error_work.status,
|
|
236
|
+
tags=error_work.tags
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
app = Application().connect(
|
|
240
|
+
title="Informações para importação da Nota Fiscal Eletrônica"
|
|
241
|
+
)
|
|
242
|
+
main_window = app["Informações para importação da Nota Fiscal Eletrônica"]
|
|
243
|
+
|
|
244
|
+
# INTERAGINDO COM A DATA DE ENTRADA
|
|
245
|
+
await worker_sleep(2)
|
|
246
|
+
try:
|
|
247
|
+
recebimento_fisico = nota.get("recebimentoFisico", None)
|
|
248
|
+
if recebimento_fisico:
|
|
249
|
+
recebimento_fisico = nota["recebimentoFisico"].split(" ")
|
|
250
|
+
pyautogui.write(recebimento_fisico[0])
|
|
251
|
+
await worker_sleep(2)
|
|
252
|
+
except:
|
|
253
|
+
console.print(
|
|
254
|
+
f"A chave recebimentoFisico não está presente na config de entrada...\n"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
from pywinauto import Desktop
|
|
259
|
+
from pywinauto.keyboard import send_keys
|
|
260
|
+
from pywinauto.timings import wait_until_passes
|
|
261
|
+
|
|
262
|
+
# === INTERAGINDO COM A NATUREZA DA OPERACAO (somente navegação) ===
|
|
263
|
+
cfop = str(int(nota.get("cfop")))
|
|
264
|
+
console.print(f"Inserindo a informação da CFOP: {cfop} ...\n")
|
|
265
|
+
|
|
266
|
+
combo_box = main_window.child_window(class_name="TDBIComboBox", found_index=0)
|
|
267
|
+
|
|
268
|
+
# Definir alvo conforme regra
|
|
269
|
+
if cfop == "5656":
|
|
270
|
+
alvo_texto = "1652-COMPRA DE MERCADORIAS - 1.652 S/ESTOQUE"
|
|
271
|
+
elif cfop.startswith("6"):
|
|
272
|
+
alvo_texto = "2556-COMPRA DE MERCADORIAS SEM ESTOQUE- 2.556"
|
|
273
|
+
elif cfop.startswith("5"):
|
|
274
|
+
alvo_texto = "1556-COMPRA DE MERCADORIAS SEM ESTOQUE- 1.556"
|
|
275
|
+
else:
|
|
276
|
+
console.print("Erro mapeado, CFOP não corresponde. Necessário ajuste manual.\n")
|
|
277
|
+
return RpaRetornoProcessoDTO(
|
|
278
|
+
sucesso=False,
|
|
279
|
+
retorno=f"Erro mapeado, CFOP {cfop} não corresponde às regras.",
|
|
280
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
281
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# 1) Clica no combo e abre a lista
|
|
285
|
+
combo_box.click_input()
|
|
286
|
+
await worker_sleep(0.3)
|
|
287
|
+
send_keys("%{DOWN}") # Alt+Down abre a lista (pode testar só {DOWN} se não funcionar)
|
|
288
|
+
|
|
289
|
+
# 2) Aguardar lista suspensa
|
|
290
|
+
try:
|
|
291
|
+
listbox = wait_until_passes(
|
|
292
|
+
timeout=5,
|
|
293
|
+
retry_interval=0.2,
|
|
294
|
+
func=lambda: Desktop(backend="win32").window(class_name="ComboLBox")
|
|
295
|
+
)
|
|
296
|
+
except Exception:
|
|
297
|
+
listbox = None
|
|
298
|
+
console.print("⚠️ Lista suspensa não localizada, tentando mesmo assim...\n")
|
|
299
|
+
|
|
300
|
+
# 3) Percorrer até encontrar alvo
|
|
301
|
+
encontrou = False
|
|
302
|
+
for _ in range(200): # limite p/ evitar loop infinito
|
|
303
|
+
texto_sel = None
|
|
304
|
+
if listbox:
|
|
305
|
+
try:
|
|
306
|
+
sel = listbox.get_selection()
|
|
307
|
+
if sel:
|
|
308
|
+
texto_sel = sel[0].window_text().strip()
|
|
309
|
+
except Exception:
|
|
310
|
+
pass
|
|
311
|
+
|
|
312
|
+
if not texto_sel:
|
|
313
|
+
try:
|
|
314
|
+
texto_sel = combo_box.window_text().strip()
|
|
315
|
+
except Exception:
|
|
316
|
+
texto_sel = ""
|
|
317
|
+
|
|
318
|
+
if texto_sel and alvo_texto in texto_sel:
|
|
319
|
+
encontrou = True
|
|
320
|
+
break
|
|
321
|
+
|
|
322
|
+
send_keys("{DOWN}")
|
|
323
|
+
await worker_sleep(0.05)
|
|
324
|
+
|
|
325
|
+
# 4) Confirmar ou falhar
|
|
326
|
+
if encontrou:
|
|
327
|
+
send_keys("{ENTER}")
|
|
328
|
+
console.print(f"✅ Selecionado: {alvo_texto}\n")
|
|
329
|
+
else:
|
|
330
|
+
console.print(f"❌ Não encontrei '{alvo_texto}' na lista.\n")
|
|
331
|
+
return RpaRetornoProcessoDTO(
|
|
332
|
+
sucesso=False,
|
|
333
|
+
retorno=f"Não encontrei '{alvo_texto}' no combo.",
|
|
334
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
335
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
await worker_sleep(3)
|
|
340
|
+
|
|
341
|
+
# INTERAGINDO COM O CAMPO ALMOXARIFADO
|
|
342
|
+
fornecedor = nota.get("nomeFornecedor")
|
|
343
|
+
filialEmpresaOrigem = nota.get("filialEmpresaOrigem")
|
|
344
|
+
console.print(
|
|
345
|
+
f"Inserindo a informação do Almoxarifado {filialEmpresaOrigem} ...\n"
|
|
346
|
+
)
|
|
347
|
+
try:
|
|
348
|
+
new_app = Application(backend="uia").connect(
|
|
349
|
+
title="Informações para importação da Nota Fiscal Eletrônica"
|
|
350
|
+
)
|
|
351
|
+
window = new_app["Informações para importação da Nota Fiscal Eletrônica"]
|
|
352
|
+
edit = window.child_window(
|
|
353
|
+
class_name="TDBIEditCode", found_index=3, control_type="Edit"
|
|
354
|
+
)
|
|
355
|
+
if filialEmpresaOrigem != "1":
|
|
356
|
+
valor_almoxarifado = filialEmpresaOrigem + "50"
|
|
357
|
+
else:
|
|
358
|
+
valor_almoxarifado = filialEmpresaOrigem + "60"
|
|
359
|
+
edit.set_edit_text(valor_almoxarifado)
|
|
360
|
+
edit.type_keys("{TAB}")
|
|
361
|
+
except Exception as e:
|
|
362
|
+
console.print(f"Erro ao iterar itens de almoxarifado: {e}")
|
|
363
|
+
return RpaRetornoProcessoDTO(
|
|
364
|
+
sucesso=False,
|
|
365
|
+
retorno=f"Erro ao iterar itens de almoxarifado: {e}",
|
|
366
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
367
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
await worker_sleep(1)
|
|
371
|
+
despesa = '298'
|
|
372
|
+
|
|
373
|
+
tipo_despesa_work = await tipo_despesa(despesa)
|
|
374
|
+
if tipo_despesa_work.sucesso == True:
|
|
375
|
+
console.log(tipo_despesa_work.retorno, style="bold green")
|
|
376
|
+
else:
|
|
377
|
+
return RpaRetornoProcessoDTO(
|
|
378
|
+
sucesso=False,
|
|
379
|
+
retorno=tipo_despesa_work.retorno,
|
|
380
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
381
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
# INTERAGINDO COM O CHECKBOX ZERAR ICMS
|
|
385
|
+
checkbox_zerar_icms = await zerar_icms()
|
|
386
|
+
if checkbox_zerar_icms.sucesso == True:
|
|
387
|
+
console.log(checkbox_zerar_icms.retorno, style="bold green")
|
|
388
|
+
else:
|
|
389
|
+
return RpaRetornoProcessoDTO(
|
|
390
|
+
sucesso=False,
|
|
391
|
+
retorno=checkbox_zerar_icms.retorno,
|
|
392
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
393
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
# INTERAGINDO COM O CAMPO DE CODIGO DO ICMS
|
|
397
|
+
cod_icms_work = await cod_icms("20")
|
|
398
|
+
if cod_icms_work.sucesso == True:
|
|
399
|
+
console.log(cod_icms_work.retorno, style="bold green")
|
|
400
|
+
else:
|
|
401
|
+
return RpaRetornoProcessoDTO(
|
|
402
|
+
sucesso=False,
|
|
403
|
+
retorno=cod_icms_work.retorno,
|
|
404
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
405
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
# INTERAGINDO COM O CAMPO Manter Natureza de Operação selecionada
|
|
409
|
+
console.print(
|
|
410
|
+
f"Selecionando a opção 'Manter Natureza de Operação selecionada'...\n"
|
|
411
|
+
)
|
|
412
|
+
checkbox = window.child_window(
|
|
413
|
+
title="Manter Natureza de Operação selecionada",
|
|
414
|
+
class_name="TDBICheckBox",
|
|
415
|
+
)
|
|
416
|
+
if not checkbox.get_toggle_state() == 1:
|
|
417
|
+
checkbox.click()
|
|
418
|
+
console.print(
|
|
419
|
+
"A opção 'Manter Natureza de Operação selecionada' selecionado com sucesso... \n"
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
await worker_sleep(2)
|
|
423
|
+
console.print("Clicando em OK... \n")
|
|
424
|
+
|
|
425
|
+
max_attempts = 3
|
|
426
|
+
i = 0
|
|
427
|
+
while i < max_attempts:
|
|
428
|
+
console.print("Clicando no botão de OK...\n")
|
|
429
|
+
try:
|
|
430
|
+
try:
|
|
431
|
+
btn_ok = main_window.child_window(title="Ok")
|
|
432
|
+
btn_ok.click()
|
|
433
|
+
except:
|
|
434
|
+
btn_ok = main_window.child_window(title="&Ok")
|
|
435
|
+
btn_ok.click()
|
|
436
|
+
except:
|
|
437
|
+
console.print("Não foi possivel clicar no Botão OK... \n")
|
|
438
|
+
|
|
439
|
+
await worker_sleep(3)
|
|
440
|
+
|
|
441
|
+
console.print(
|
|
442
|
+
"Verificando a existencia da tela Informações para importação da Nota Fiscal Eletrônica...\n"
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
try:
|
|
446
|
+
informacao_nf_eletronica = await is_window_open(
|
|
447
|
+
"Informações para importação da Nota Fiscal Eletrônica"
|
|
448
|
+
)
|
|
449
|
+
if not informacao_nf_eletronica["IsOpened"]:
|
|
450
|
+
console.print(
|
|
451
|
+
"Tela Informações para importação da Nota Fiscal Eletrônica fechada, seguindo com o processo"
|
|
452
|
+
)
|
|
453
|
+
break
|
|
454
|
+
except Exception as e:
|
|
455
|
+
console.print(
|
|
456
|
+
f"Tela Informações para importação da Nota Fiscal Eletrônica encontrada. Tentativa {i + 1}/{max_attempts}."
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
i += 1
|
|
460
|
+
|
|
461
|
+
if i == max_attempts:
|
|
462
|
+
return RpaRetornoProcessoDTO(
|
|
463
|
+
sucesso=False,
|
|
464
|
+
retorno="Número máximo de tentativas atingido, Não foi possivel finalizar os trabalhos na tela de Informações para importação da Nota Fiscal Eletrônica",
|
|
465
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
466
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
await worker_sleep(5)
|
|
470
|
+
try:
|
|
471
|
+
##### Janela Information #####
|
|
472
|
+
app = Application(backend="win32").connect(title_re="Information")
|
|
473
|
+
|
|
474
|
+
# Seleciona a janela pelo título
|
|
475
|
+
dlg = app.window(title_re="Information")
|
|
476
|
+
|
|
477
|
+
# Clica no botão "Não"
|
|
478
|
+
dlg['&No'].click_input()
|
|
479
|
+
|
|
480
|
+
console.print("Clique em NÃO realizado com sucesso!")
|
|
481
|
+
except:
|
|
482
|
+
pass
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
await worker_sleep(2)
|
|
486
|
+
console.print("Navegando pela Janela de Nota Fiscal de Entrada...\n")
|
|
487
|
+
app = Application().connect(class_name="TFrmNotaFiscalEntrada")
|
|
488
|
+
main_window = app["TFrmNotaFiscalEntrada"]
|
|
489
|
+
|
|
490
|
+
pyautogui.click(621, 359)
|
|
491
|
+
|
|
492
|
+
await worker_sleep(5)
|
|
493
|
+
|
|
494
|
+
try:
|
|
495
|
+
# Verificar se já existe parcela
|
|
496
|
+
console.print("Verificar se já existe parcela")
|
|
497
|
+
main_window.child_window(class_name="TDBIBitBtn", found_index=0).click_input()
|
|
498
|
+
console.print("Parcelas encontradas, removendo para inserir data atual")
|
|
499
|
+
|
|
500
|
+
await worker_sleep(3)
|
|
501
|
+
|
|
502
|
+
# conecta no dialog "Confirm"
|
|
503
|
+
app = Application(backend="win32").connect(title="Confirm")
|
|
504
|
+
dlg = app.window(title="Confirm", class_name="TMessageForm")
|
|
505
|
+
|
|
506
|
+
# clica no botão Yes
|
|
507
|
+
dlg.child_window(title="&Yes", class_name="TButton").click_input()
|
|
508
|
+
print("Clique em 'Yes' na janela de confirmação.")
|
|
509
|
+
except:
|
|
510
|
+
console.print("Parcela não encontrada")
|
|
511
|
+
|
|
512
|
+
app = Application().connect(class_name="TFrmNotaFiscalEntrada")
|
|
513
|
+
main_window = app["TFrmNotaFiscalEntrada"]
|
|
514
|
+
|
|
515
|
+
main_window.set_focus()
|
|
516
|
+
|
|
517
|
+
panel_TPage = main_window.child_window(class_name="TPage", title="Formulario")
|
|
518
|
+
panel_TTabSheet = panel_TPage.child_window(class_name="TPageControl")
|
|
519
|
+
|
|
520
|
+
panel_TabPagamento = panel_TTabSheet.child_window(title="Pagamento")
|
|
521
|
+
|
|
522
|
+
input_dt_vencimento = panel_TPage = main_window.child_window(class_name="TDBIEditDate", found_index=0).click()
|
|
523
|
+
send_keys(data_vencimento)
|
|
524
|
+
|
|
525
|
+
input_valor = panel_TPage = main_window.child_window(class_name="TDBIEditNumber", found_index=3).click()
|
|
526
|
+
send_keys('{RIGHT}')
|
|
527
|
+
send_keys('^a{BACKSPACE}')
|
|
528
|
+
await worker_sleep(1)
|
|
529
|
+
send_keys(valor_nota)
|
|
530
|
+
|
|
531
|
+
# === INTERAGINDO COM O TIPO DE COBRANCA ===
|
|
532
|
+
tipo_cobranca = panel_TTabSheet.child_window(
|
|
533
|
+
class_name="TDBIComboBox", found_index=0
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
# Opções de fallback
|
|
537
|
+
alvos = ["BANCO DO BRASIL BOLETO", "BOLETO"]
|
|
538
|
+
|
|
539
|
+
# 1) Clica no combo e abre a lista
|
|
540
|
+
tipo_cobranca.click_input()
|
|
541
|
+
await worker_sleep(0.3)
|
|
542
|
+
send_keys("%{DOWN}") # abre o dropdown (pode ser só {DOWN} dependendo da janela)
|
|
543
|
+
await worker_sleep(0.3)
|
|
544
|
+
|
|
545
|
+
# 2) Aguarda lista suspensa
|
|
546
|
+
try:
|
|
547
|
+
listbox = wait_until_passes(
|
|
548
|
+
timeout=5,
|
|
549
|
+
retry_interval=0.2,
|
|
550
|
+
func=lambda: Desktop(backend="win32").window(class_name="ComboLBox")
|
|
551
|
+
)
|
|
552
|
+
except Exception:
|
|
553
|
+
listbox = None
|
|
554
|
+
console.print("⚠️ Lista suspensa não localizada, tentando mesmo assim...\n")
|
|
555
|
+
|
|
556
|
+
# 3) Percorrer tentando encontrar o primeiro alvo válido
|
|
557
|
+
encontrou = False
|
|
558
|
+
alvo_escolhido = None
|
|
559
|
+
|
|
560
|
+
for alvo_texto in alvos: # tenta em ordem BANCO... depois BOLETO
|
|
561
|
+
for _ in range(200):
|
|
562
|
+
texto_sel = None
|
|
563
|
+
if listbox:
|
|
564
|
+
try:
|
|
565
|
+
sel = listbox.get_selection()
|
|
566
|
+
if sel:
|
|
567
|
+
texto_sel = sel[0].window_text().strip()
|
|
568
|
+
except Exception:
|
|
569
|
+
pass
|
|
570
|
+
|
|
571
|
+
if not texto_sel:
|
|
572
|
+
try:
|
|
573
|
+
texto_sel = tipo_cobranca.window_text().strip()
|
|
574
|
+
except Exception:
|
|
575
|
+
texto_sel = ""
|
|
576
|
+
|
|
577
|
+
if texto_sel and alvo_texto in texto_sel:
|
|
578
|
+
encontrou = True
|
|
579
|
+
alvo_escolhido = alvo_texto
|
|
580
|
+
break
|
|
581
|
+
|
|
582
|
+
send_keys("{DOWN}")
|
|
583
|
+
await worker_sleep(0.05)
|
|
584
|
+
|
|
585
|
+
if encontrou:
|
|
586
|
+
break
|
|
587
|
+
|
|
588
|
+
# 4) Confirmar ou falhar
|
|
589
|
+
if encontrou:
|
|
590
|
+
send_keys("{ENTER}")
|
|
591
|
+
console.print(f"Selecionado: {alvo_escolhido}\n")
|
|
592
|
+
else:
|
|
593
|
+
console.print("Não encontrei nenhuma das opções na lista.\n")
|
|
594
|
+
return RpaRetornoProcessoDTO(
|
|
595
|
+
sucesso=False,
|
|
596
|
+
retorno="Não encontrei opção de cobrança válida.",
|
|
597
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
598
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
await worker_sleep(2)
|
|
602
|
+
|
|
603
|
+
# Clicar em incluir registro
|
|
604
|
+
pyautogui.click(1289, 530)
|
|
605
|
+
|
|
606
|
+
await worker_sleep(3)
|
|
607
|
+
|
|
608
|
+
console.print(f"Incluindo registro...\n")
|
|
609
|
+
try:
|
|
610
|
+
ASSETS_PATH = "assets"
|
|
611
|
+
inserir_registro = pyautogui.locateOnScreen(
|
|
612
|
+
"assets\\entrada_notas\\IncluirRegistro.png", confidence=0.8
|
|
613
|
+
)
|
|
614
|
+
pyautogui.click(inserir_registro)
|
|
615
|
+
except Exception as e:
|
|
616
|
+
console.print(
|
|
617
|
+
f"Não foi possivel incluir o registro utilizando reconhecimento de imagem, Error: {e}...\n tentando inserir via posição...\n"
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
await worker_sleep(5)
|
|
621
|
+
|
|
622
|
+
console.print(
|
|
623
|
+
"Verificando a existencia de POP-UP de Itens que Ultrapassam a Variação Máxima de Custo ...\n"
|
|
624
|
+
)
|
|
625
|
+
itens_variacao_maxima = await is_window_open_by_class(
|
|
626
|
+
"TFrmTelaSelecao", "TFrmTelaSelecao"
|
|
627
|
+
)
|
|
628
|
+
if itens_variacao_maxima["IsOpened"] == True:
|
|
629
|
+
app = Application().connect(class_name="TFrmTelaSelecao")
|
|
630
|
+
main_window = app["TFrmTelaSelecao"]
|
|
631
|
+
send_keys("%o")
|
|
632
|
+
|
|
633
|
+
await worker_sleep(5)
|
|
634
|
+
|
|
635
|
+
console.print(
|
|
636
|
+
"Verificando a existencia de Warning informando que a Soma dos pagamentos não bate com o valor da nota. ...\n"
|
|
637
|
+
)
|
|
638
|
+
app = Application().connect(class_name="TFrmNotaFiscalEntrada")
|
|
639
|
+
main_window = app["TFrmNotaFiscalEntrada"]
|
|
640
|
+
|
|
641
|
+
# --- Verificação do pop-up "TMessageForm" ---
|
|
642
|
+
warning_existe = False
|
|
643
|
+
try:
|
|
644
|
+
# tenta conectar na janela do aviso
|
|
645
|
+
app = Application().connect(class_name="TMessageForm", timeout=3)
|
|
646
|
+
dlg = app.window(class_name="TMessageForm")
|
|
647
|
+
|
|
648
|
+
# confirma se a janela realmente existe/está visível
|
|
649
|
+
if dlg.exists(timeout=1):
|
|
650
|
+
warning_existe = True
|
|
651
|
+
|
|
652
|
+
except (ElementNotFoundError, Exception):
|
|
653
|
+
warning_existe = False
|
|
654
|
+
|
|
655
|
+
if warning_existe:
|
|
656
|
+
console.print(
|
|
657
|
+
"Erro: Warning informando que a Soma dos pagamentos não bate com o valor da nota. ...\n"
|
|
658
|
+
)
|
|
659
|
+
return RpaRetornoProcessoDTO(
|
|
660
|
+
sucesso=False,
|
|
661
|
+
retorno="A soma dos pagamentos não bate com o valor da nota.",
|
|
662
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
663
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
664
|
+
)
|
|
665
|
+
else:
|
|
666
|
+
console.print(
|
|
667
|
+
"Warning informando que a Soma dos pagamentos não bate com o valor da nota não existe ...\n"
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
max_attempts = 7
|
|
671
|
+
i = 0
|
|
672
|
+
aguarde_rateio_despesa = True
|
|
673
|
+
|
|
674
|
+
while i < max_attempts:
|
|
675
|
+
await worker_sleep(3)
|
|
676
|
+
|
|
677
|
+
from pywinauto import Desktop
|
|
678
|
+
|
|
679
|
+
for window in Desktop(backend="uia").windows():
|
|
680
|
+
if "Rateio" in window.window_text():
|
|
681
|
+
aguarde_rateio_despesa = False
|
|
682
|
+
console.print(
|
|
683
|
+
"A janela 'Rateio da Despesas' foi encontrada. Continuando para andamento do processo...\n"
|
|
684
|
+
)
|
|
685
|
+
break
|
|
686
|
+
|
|
687
|
+
if not aguarde_rateio_despesa:
|
|
688
|
+
break
|
|
689
|
+
|
|
690
|
+
i += 1
|
|
691
|
+
|
|
692
|
+
if aguarde_rateio_despesa:
|
|
693
|
+
return RpaRetornoProcessoDTO(
|
|
694
|
+
sucesso=False,
|
|
695
|
+
retorno=f"Número máximo de tentativas atingido. A tela para Rateio da Despesa não foi encontrada.",
|
|
696
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
697
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
despesa_rateio_work = await rateio_despesa(filialEmpresaOrigem)
|
|
701
|
+
if despesa_rateio_work.sucesso == True:
|
|
702
|
+
console.log(despesa_rateio_work.retorno, style="bold green")
|
|
703
|
+
else:
|
|
704
|
+
return RpaRetornoProcessoDTO(
|
|
705
|
+
sucesso=False,
|
|
706
|
+
retorno=despesa_rateio_work.retorno,
|
|
707
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
708
|
+
tags=despesa_rateio_work.tags
|
|
709
|
+
)
|
|
710
|
+
|
|
711
|
+
await worker_sleep(5)
|
|
712
|
+
|
|
713
|
+
try:
|
|
714
|
+
# Localiza a janela Warning (pode ser Warning, Aviso, etc)
|
|
715
|
+
warning_win = Desktop(backend="win32").window(title_re=".*[Ww]arning.*")
|
|
716
|
+
|
|
717
|
+
if warning_win.exists(timeout=3):
|
|
718
|
+
console.print("⚠️ Janela Warning encontrada. Clicando em YES...\n")
|
|
719
|
+
|
|
720
|
+
# Busca pelo botão Yes (tem variações: &Yes, YesButton)
|
|
721
|
+
btn_yes = warning_win.child_window(
|
|
722
|
+
title_re=".*Yes.*", class_name="TButton"
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
btn_yes.click_input()
|
|
726
|
+
await worker_sleep(0.5)
|
|
727
|
+
|
|
728
|
+
else:
|
|
729
|
+
console.print("Nenhuma janela Warning apareceu.\n")
|
|
730
|
+
|
|
731
|
+
except Exception as e:
|
|
732
|
+
console.print(f"Erro ao clicar em YES: {e}\n")
|
|
733
|
+
# Verifica se a info 'Nota fiscal incluida' está na tela
|
|
734
|
+
await worker_sleep(15)
|
|
735
|
+
warning_pop_up = await is_window_open("Warning")
|
|
736
|
+
if warning_pop_up["IsOpened"] == True:
|
|
737
|
+
app = Application().connect(title="Warning")
|
|
738
|
+
main_window = app["Warning"]
|
|
739
|
+
main_window.set_focus()
|
|
740
|
+
|
|
741
|
+
console.print(f"Obtendo texto do Warning...\n")
|
|
742
|
+
console.print(f"Tirando print da janela do warning para realização do OCR...\n")
|
|
743
|
+
|
|
744
|
+
window_rect = main_window.rectangle()
|
|
745
|
+
screenshot = pyautogui.screenshot(
|
|
746
|
+
region=(
|
|
747
|
+
window_rect.left,
|
|
748
|
+
window_rect.top,
|
|
749
|
+
window_rect.width(),
|
|
750
|
+
window_rect.height(),
|
|
751
|
+
)
|
|
752
|
+
)
|
|
753
|
+
username = getpass.getuser()
|
|
754
|
+
path_to_png = f"C:\\Users\\{username}\\Downloads\\warning_popup_{nota.get("nfe")}.png"
|
|
755
|
+
screenshot.save(path_to_png)
|
|
756
|
+
console.print(f"Print salvo em {path_to_png}...\n")
|
|
757
|
+
|
|
758
|
+
console.print(
|
|
759
|
+
f"Preparando a imagem para maior resolução e assertividade no OCR...\n"
|
|
760
|
+
)
|
|
761
|
+
image = Image.open(path_to_png)
|
|
762
|
+
image = image.convert("L")
|
|
763
|
+
enhancer = ImageEnhance.Contrast(image)
|
|
764
|
+
image = enhancer.enhance(2.0)
|
|
765
|
+
image.save(path_to_png)
|
|
766
|
+
console.print(f"Imagem preparada com sucesso...\n")
|
|
767
|
+
console.print(f"Realizando OCR...\n")
|
|
768
|
+
captured_text = pytesseract.image_to_string(Image.open(path_to_png))
|
|
769
|
+
console.print(
|
|
770
|
+
f"Texto Full capturado {captured_text}...\n"
|
|
771
|
+
)
|
|
772
|
+
os.remove(path_to_png)
|
|
773
|
+
if 'movimento não permitido' in captured_text.lower():
|
|
774
|
+
return RpaRetornoProcessoDTO(
|
|
775
|
+
sucesso=False,
|
|
776
|
+
retorno=f"Filial: {filialEmpresaOrigem} está com o livro fechado ou encerrado, verificar com o setor fiscal",
|
|
777
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
778
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
779
|
+
)
|
|
780
|
+
else:
|
|
781
|
+
return RpaRetornoProcessoDTO(
|
|
782
|
+
sucesso=False,
|
|
783
|
+
retorno=f"Warning não mapeado para seguimento do robo, mensagem: {captured_text}",
|
|
784
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
785
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
786
|
+
)
|
|
787
|
+
|
|
788
|
+
await worker_sleep(3)
|
|
789
|
+
nf_imported = await check_nota_importada(nota.get("nfe"))
|
|
790
|
+
if nf_imported.sucesso == True:
|
|
791
|
+
await worker_sleep(3)
|
|
792
|
+
console.print("\nVerifica se a nota ja foi lançada...")
|
|
793
|
+
nf_chave_acesso = int(nota.get("nfe"))
|
|
794
|
+
status_nf_emsys = await get_status_nf_emsys(nf_chave_acesso)
|
|
795
|
+
if status_nf_emsys.get("status") == "Lançada":
|
|
796
|
+
console.print("\nNota lançada com sucesso, processo finalizado...", style="bold green")
|
|
797
|
+
return RpaRetornoProcessoDTO(
|
|
798
|
+
sucesso=True,
|
|
799
|
+
retorno="Nota Lançada com sucesso!",
|
|
800
|
+
status=RpaHistoricoStatusEnum.Sucesso,
|
|
801
|
+
)
|
|
802
|
+
else:
|
|
803
|
+
console.print("Erro ao lançar nota", style="bold red")
|
|
804
|
+
return RpaRetornoProcessoDTO(
|
|
805
|
+
sucesso=False,
|
|
806
|
+
retorno=f"Pop-up nota incluida encontrada, porém nota encontrada como 'já lançada' trazendo as seguintes informações: {nf_imported.retorno} - {error_work}",
|
|
807
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
808
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
|
|
809
|
+
)
|
|
810
|
+
else:
|
|
811
|
+
console.print("Erro ao lançar nota", style="bold red")
|
|
812
|
+
return RpaRetornoProcessoDTO(
|
|
813
|
+
sucesso=False,
|
|
814
|
+
retorno=f"Erro ao lançar nota, erro: {nf_imported.retorno}",
|
|
815
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
816
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
except Exception as ex:
|
|
820
|
+
observacao = f"Erro Processo Entrada de Notas: {str(ex)}"
|
|
821
|
+
logger.error(observacao)
|
|
822
|
+
console.print(observacao, style="bold red")
|
|
823
|
+
return RpaRetornoProcessoDTO(
|
|
824
|
+
sucesso=False,
|
|
825
|
+
retorno=observacao,
|
|
826
|
+
status=RpaHistoricoStatusEnum.Falha,
|
|
827
|
+
tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
|
|
828
|
+
)
|
|
829
|
+
|
|
830
|
+
finally:
|
|
831
|
+
# Deleta o xml
|
|
832
|
+
await delete_xml(nota.get("nfe"))
|
|
833
|
+
|
|
@@ -605,7 +605,7 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
605
605
|
console.print(f"Tanque a ser distribuido: {info_distribuicao_obs}... \n")
|
|
606
606
|
send_keys("^({HOME})")
|
|
607
607
|
await worker_sleep(1)
|
|
608
|
-
send_keys("{DOWN " + str(index_tanque) + "}", pause=0.
|
|
608
|
+
send_keys("{DOWN " + str(index_tanque) + "}", pause=0.5)
|
|
609
609
|
await worker_sleep(1)
|
|
610
610
|
#Copiar e extrai o Seq Item XML
|
|
611
611
|
send_keys("^c")
|
|
@@ -617,7 +617,7 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
617
617
|
item_executado = seq_item
|
|
618
618
|
else:
|
|
619
619
|
while seq_item == item_executado:
|
|
620
|
-
send_keys("{DOWN}", pause=0.
|
|
620
|
+
send_keys("{DOWN}", pause=0.5)
|
|
621
621
|
index_tanque += 1
|
|
622
622
|
send_keys("^c")
|
|
623
623
|
copiado = pyperclip.paste()
|
|
@@ -626,12 +626,11 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
626
626
|
seq_item = colunas[0]
|
|
627
627
|
|
|
628
628
|
send_keys("+{F10}")
|
|
629
|
-
await worker_sleep(
|
|
629
|
+
await worker_sleep(2)
|
|
630
630
|
send_keys("{DOWN 6}")
|
|
631
|
-
await worker_sleep(
|
|
631
|
+
await worker_sleep(2)
|
|
632
632
|
send_keys("{ENTER}")
|
|
633
633
|
await worker_sleep(4)
|
|
634
|
-
|
|
635
634
|
|
|
636
635
|
max_attempts = 5
|
|
637
636
|
i = 0
|
|
@@ -640,7 +639,6 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
640
639
|
if distribuir_item_window["IsOpened"] == True:
|
|
641
640
|
app = Application().connect(title="Distribui Item Tanque")
|
|
642
641
|
main_window = app["Distribui Item Tanque"]
|
|
643
|
-
|
|
644
642
|
main_window.set_focus()
|
|
645
643
|
break
|
|
646
644
|
else:
|
|
@@ -665,11 +663,11 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
665
663
|
center_y = (grid_rect.top + grid_rect.bottom) // 2
|
|
666
664
|
|
|
667
665
|
pyautogui.click(center_x, center_y)
|
|
668
|
-
await worker_sleep(
|
|
666
|
+
await worker_sleep(4)
|
|
669
667
|
send_keys("^({HOME})")
|
|
670
|
-
await worker_sleep(
|
|
668
|
+
await worker_sleep(4)
|
|
671
669
|
send_keys("{LEFT 3}")
|
|
672
|
-
await worker_sleep(
|
|
670
|
+
await worker_sleep(4)
|
|
673
671
|
|
|
674
672
|
distribuiu_algo = False
|
|
675
673
|
distribuicao_atual = []
|
|
@@ -714,11 +712,11 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
714
712
|
quantidade_combustivel = re.findall(r'\((.*?)\)', second_info_distribuicao_obs)[0].replace('.', '')
|
|
715
713
|
|
|
716
714
|
send_keys("{LEFT 3}")
|
|
717
|
-
await worker_sleep(
|
|
715
|
+
await worker_sleep(2)
|
|
718
716
|
send_keys("{RIGHT 3}")
|
|
719
717
|
|
|
720
718
|
pyautogui.press('enter')
|
|
721
|
-
await worker_sleep(
|
|
719
|
+
await worker_sleep(2)
|
|
722
720
|
pyautogui.write(quantidade_combustivel)
|
|
723
721
|
pyautogui.press('enter')
|
|
724
722
|
list_tanques_distribuidos.append(second_info_distribuicao_obs)
|
|
@@ -1372,4 +1370,4 @@ async def entrada_de_notas_9(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
|
|
|
1372
1370
|
|
|
1373
1371
|
finally:
|
|
1374
1372
|
# Deleta o xml
|
|
1375
|
-
await delete_xml(nota["nfe"])
|
|
1373
|
+
await delete_xml(nota["nfe"])
|
|
@@ -102,6 +102,9 @@ from worker_automate_hub.tasks.jobs.extracao_fechamento_emsys import (
|
|
|
102
102
|
from worker_automate_hub.tasks.jobs.opex_capex import (
|
|
103
103
|
opex_capex,
|
|
104
104
|
)
|
|
105
|
+
from worker_automate_hub.tasks.jobs.entrada_de_notas_22 import (
|
|
106
|
+
entrada_de_notas_22,
|
|
107
|
+
)
|
|
105
108
|
|
|
106
109
|
|
|
107
110
|
task_definitions = {
|
|
@@ -208,7 +211,8 @@ task_definitions = {
|
|
|
208
211
|
"8c28726d-458d-4119-afa0-202695b79a8f": extracao_fechamento_emsys,
|
|
209
212
|
"16debe45-3520-4f63-acfe-ef0e8784fcab": extracao_saldo_estoque,
|
|
210
213
|
"9cbc6016-7c0e-4a3a-8ee9-fb9dc4b35e33": extracao_saldo_estoque_fiscal,
|
|
211
|
-
"07072711-c9d0-49e4-b180-530cecbe0728": opex_capex
|
|
214
|
+
"07072711-c9d0-49e4-b180-530cecbe0728": opex_capex,
|
|
215
|
+
"98bc6679-2e6b-4757-9fdc-b27eebd98f54": entrada_de_notas_22
|
|
212
216
|
}
|
|
213
217
|
|
|
214
218
|
|
|
@@ -56,6 +56,7 @@ worker_automate_hub/tasks/jobs/entrada_cte_333.py,sha256=FvpU_bsdPB2ANQ_i63Jlkdo
|
|
|
56
56
|
worker_automate_hub/tasks/jobs/entrada_de_notas_15.py,sha256=DZ06Kbiu4Cg0LeHNIUeXtVqrWmCeXvuL4YuL3vo32EM,28703
|
|
57
57
|
worker_automate_hub/tasks/jobs/entrada_de_notas_16.py,sha256=XgCaZTn0lTxio9yLTYIf0J-PA8e80dSDa7wsUnZiffI,37783
|
|
58
58
|
worker_automate_hub/tasks/jobs/entrada_de_notas_207.py,sha256=A5HM2Eh2bGZueVefnQL9KiCWW95j8zX1v2MslgbDcUE,36871
|
|
59
|
+
worker_automate_hub/tasks/jobs/entrada_de_notas_22.py,sha256=eLPsuVj6b5djh6I6fRVT_2TMC8zy92Z8VfefFgbG_sg,32473
|
|
59
60
|
worker_automate_hub/tasks/jobs/entrada_de_notas_32.py,sha256=lku233FqwOknXF14HHC6fZ75WubE69Jp32bAUhKPtGQ,34575
|
|
60
61
|
worker_automate_hub/tasks/jobs/entrada_de_notas_33.py,sha256=ODp82BkWaiF40t6uZLJYxG2nGGnvDyeQBHhkkh9ZgPI,35994
|
|
61
62
|
worker_automate_hub/tasks/jobs/entrada_de_notas_34.py,sha256=AXUL8DakrDeTxWW8dn36W830XfIuO47MFUusbUkrnUc,33586
|
|
@@ -66,7 +67,7 @@ worker_automate_hub/tasks/jobs/entrada_de_notas_500.py,sha256=WBsCRbH7ANiCjEn0aE
|
|
|
66
67
|
worker_automate_hub/tasks/jobs/entrada_de_notas_503.py,sha256=bcNKy6X1aaVe6lxW-TMyUKJ_GXzHEK-8V6x9SOzOshw,48365
|
|
67
68
|
worker_automate_hub/tasks/jobs/entrada_de_notas_505.py,sha256=xXeNipdXTSll8yAtAmN7v0sjN3oMlWU4THu30mKDddc,30339
|
|
68
69
|
worker_automate_hub/tasks/jobs/entrada_de_notas_7139.py,sha256=7POfKc7nisc8-ysgqazrK8kT7kmFIq8irGwCMixPAE0,37948
|
|
69
|
-
worker_automate_hub/tasks/jobs/entrada_de_notas_9.py,sha256=
|
|
70
|
+
worker_automate_hub/tasks/jobs/entrada_de_notas_9.py,sha256=tayKjzymLS96a46st3PTSGEUO7Tm3Et5zZB237apZBs,67507
|
|
70
71
|
worker_automate_hub/tasks/jobs/entrada_de_notas_9000.py,sha256=0mOmS28tQKF5m7vMzInblDuWH48_qIgrohOU5UwYZ10,65498
|
|
71
72
|
worker_automate_hub/tasks/jobs/exemplo_processo.py,sha256=nV0iLoip2FH2-FhLmhX3nPqsfl_MPufZ3E5Q5krJvdc,3544
|
|
72
73
|
worker_automate_hub/tasks/jobs/extracao_fechamento_contabil.py,sha256=6Kr5DKjKLqtFvGzyiXtt7xrQsuU898l8pQXDq9C6AX8,19567
|
|
@@ -91,7 +92,7 @@ worker_automate_hub/tasks/jobs/opex_capex.py,sha256=mZvPrjlD-bcHP6zwrSUaNf7-bHYD
|
|
|
91
92
|
worker_automate_hub/tasks/jobs/playground.py,sha256=7vWDg9DwToHwGJ6_XOa8TQ6LmfRV5Qz2TaOV3q3P9sA,1918
|
|
92
93
|
worker_automate_hub/tasks/jobs/sped_fiscal.py,sha256=Zsq-IwKxA0b2tikO6Rri4WXVj10jK-Jd0-gxk8yVBH0,31064
|
|
93
94
|
worker_automate_hub/tasks/jobs/transferencias.py,sha256=5TIktufkvUPnVTR2gf7GFQJ5KQP6PWnmoWiE08WiVDQ,46191
|
|
94
|
-
worker_automate_hub/tasks/task_definitions.py,sha256=
|
|
95
|
+
worker_automate_hub/tasks/task_definitions.py,sha256=AKzuSb5CiNu97-9V_Ykb2jmXXNenOLiTFeBT3Pw9chI,12815
|
|
95
96
|
worker_automate_hub/tasks/task_executor.py,sha256=F5ngJLGz7vbUrX-batUlt3FFwiCE8denFmtTTLaE77I,6044
|
|
96
97
|
worker_automate_hub/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
98
|
worker_automate_hub/utils/env.py,sha256=TacQjGRO7PUNpttrhTAc5Gnegaiysl2Knsv1P8qfkfs,57
|
|
@@ -102,7 +103,7 @@ worker_automate_hub/utils/updater.py,sha256=en2FCGhI8aZ-JNP3LQm64NJDc4awCNW7UhbV
|
|
|
102
103
|
worker_automate_hub/utils/util.py,sha256=noQRUSAjRnoDb1c4iMZ5eoyrNp59a8T9K78MHhalASw,210255
|
|
103
104
|
worker_automate_hub/utils/utils_nfe_entrada.py,sha256=F7jk95LpDwl5WfaQXahCA5yDdnySnWdctDqczHXwGqE,38195
|
|
104
105
|
worker_automate_hub/worker.py,sha256=zEnYUrm5kY2cHbbee15QJkwkx4euD2SB2zRvUIbjS90,6850
|
|
105
|
-
worker_automate_hub-0.5.
|
|
106
|
-
worker_automate_hub-0.5.
|
|
107
|
-
worker_automate_hub-0.5.
|
|
108
|
-
worker_automate_hub-0.5.
|
|
106
|
+
worker_automate_hub-0.5.798.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
|
|
107
|
+
worker_automate_hub-0.5.798.dist-info/METADATA,sha256=DQr2GxX6UmfeOed1127hRVOOim_n7NsU-aJ0kwbrijI,3100
|
|
108
|
+
worker_automate_hub-0.5.798.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
109
|
+
worker_automate_hub-0.5.798.dist-info/RECORD,,
|
{worker_automate_hub-0.5.796.dist-info → worker_automate_hub-0.5.798.dist-info}/entry_points.txt
RENAMED
|
File without changes
|