worker-automate-hub 0.5.829__py3-none-any.whl → 0.5.831__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.
@@ -15,9 +15,15 @@ import re
15
15
  import sys
16
16
  import os
17
17
 
18
- sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
18
+ sys.path.append(
19
+ os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
20
+ )
19
21
 
20
- from worker_automate_hub.api.client import get_config_by_name, send_file, get_notas_produtos
22
+ from worker_automate_hub.api.client import (
23
+ get_config_by_name,
24
+ send_file,
25
+ get_notas_produtos,
26
+ )
21
27
  from worker_automate_hub.models.dto.rpa_historico_request_dto import (
22
28
  RpaHistoricoStatusEnum,
23
29
  RpaRetornoProcessoDTO,
@@ -29,6 +35,7 @@ from worker_automate_hub.models.dto.rpa_processo_entrada_dto import (
29
35
  )
30
36
  from worker_automate_hub.utils.logger import logger
31
37
  from pywinauto.keyboard import send_keys
38
+
32
39
  # from worker_automate_hub.utils.toast import show_toast
33
40
  from worker_automate_hub.utils.util import (
34
41
  send_to_webhook,
@@ -52,15 +59,17 @@ console = Console()
52
59
  ASSETS_BASE_PATH = "assets/descartes_transferencias_images/"
53
60
  ALMOXARIFADO_DEFAULT = "50"
54
61
 
62
+
55
63
  def _parse_int_tolerante(val):
56
64
  if val is None:
57
65
  return 0
58
66
  if isinstance(val, int):
59
67
  return val
60
68
  s = str(val).replace("\u00a0", "").strip() # remove NBSP
61
- s = s.replace(".", "").replace(",", "") # remove separadores comuns
69
+ s = s.replace(".", "").replace(",", "") # remove separadores comuns
62
70
  return int(float(s or 0))
63
71
 
72
+
64
73
  def _coletar_itens_achatados(d: dict):
65
74
  descrs, qtds = {}, {}
66
75
  for k, v in d.items():
@@ -85,6 +94,7 @@ def _coletar_itens_achatados(d: dict):
85
94
  itens.append({"descricaoProduto": desc, "qtd": qtd})
86
95
  return itens
87
96
 
97
+
88
98
  def normalize_config_entrada(cfg: dict) -> dict:
89
99
  """
90
100
  Se vier com 'itens': mantém e normaliza qtd -> int.
@@ -111,10 +121,14 @@ def normalize_config_entrada(cfg: dict) -> dict:
111
121
  itens = _coletar_itens_achatados(cfg)
112
122
  cfg["itens"] = itens
113
123
  # remove chaves achatadas da saída (opcional)
114
- chaves_remover = [k for k in cfg.keys() if re.match(r"^(descricaoProduto|qtd)\d+$", k, flags=re.I)]
124
+ chaves_remover = [
125
+ k for k in cfg.keys() if re.match(r"^(descricaoProduto|qtd)\d+$", k, flags=re.I)
126
+ ]
115
127
  for k in chaves_remover:
116
128
  cfg.pop(k, None)
117
129
  return cfg
130
+
131
+
118
132
  # --- fim do normalizador ---
119
133
 
120
134
 
@@ -124,7 +138,6 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
124
138
  config = await get_config_by_name("login_emsys")
125
139
  console.print(task)
126
140
 
127
-
128
141
  # Seta config entrada na var nota para melhor entendimento (normalizando formatos)
129
142
  nota = normalize_config_entrada(task.configEntrada)
130
143
  itens = nota.get("itens", [])
@@ -186,13 +199,15 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
186
199
  # Acumula para a lista geral (será deduplicada depois)
187
200
  notas_encontradas.extend(notas_item)
188
201
 
189
- itens_ui.append({
190
- "codigo": cod,
191
- "quantidade": qtd,
192
- "valor_unitario": valor_unit,
193
- "valor_total_item": round(valor_unit * qtd, 2),
194
- "notas": notas_item, # mantém vínculo item↔notas
195
- })
202
+ itens_ui.append(
203
+ {
204
+ "codigo": cod,
205
+ "quantidade": qtd,
206
+ "valor_unitario": valor_unit,
207
+ "valor_total_item": round(valor_unit * qtd, 2),
208
+ "notas": notas_item, # mantém vínculo item↔notas
209
+ }
210
+ )
196
211
 
197
212
  # Deduplica notas preservando a ordem de aparição
198
213
  nf_ref = list(dict.fromkeys(notas_encontradas))
@@ -204,20 +219,19 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
204
219
  itens_por_nota[n].append(item)
205
220
 
206
221
  data = {
207
- "nf_referencia": nf_ref, # ex.: ['1418727', '1410744']
208
- "itens": itens_ui, # cada item com suas notas
222
+ "nf_referencia": nf_ref, # ex.: ['1418727', '1410744']
223
+ "itens": itens_ui, # cada item com suas notas
209
224
  "totais": {
210
225
  "valor_final": round(sum(i["valor_total_item"] for i in itens_ui), 2)
211
226
  },
212
- "itens_por_nota": itens_por_nota # para uso direto no fluxo de UI
227
+ "itens_por_nota": itens_por_nota, # para uso direto no fluxo de UI
213
228
  }
214
229
  # ========= FIM DA MONTAGEM DO DATA =========
215
230
 
216
-
217
231
  # Fecha a instancia do emsys - caso esteja aberta
218
232
  await kill_all_emsys()
219
233
 
220
- app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3.exe")
234
+ app = Application(backend="win32").start("C:\\Rezende\\EMSys3\\EMSys3_10.exe")
221
235
  warnings.filterwarnings(
222
236
  "ignore",
223
237
  category=UserWarning,
@@ -244,12 +258,18 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
244
258
  select_prevenda_type = app["Selecione o Tipo de Pré-Venda"]
245
259
 
246
260
  if select_prevenda_type.exists():
247
- tipo = select_prevenda_type.child_window(class_name="TComboBox", found_index=0)
261
+ tipo = select_prevenda_type.child_window(
262
+ class_name="TComboBox", found_index=0
263
+ )
248
264
  tipo.select("Orçamento")
249
- confirm = select_prevenda_type.child_window(class_name="TDBIBitBtn", found_index=1)
265
+ confirm = select_prevenda_type.child_window(
266
+ class_name="TDBIBitBtn", found_index=1
267
+ )
250
268
  confirm.click()
251
269
  except:
252
- console.print("Sem tela de selecionar modelo de pre venda", style="bold green")
270
+ console.print(
271
+ "Sem tela de selecionar modelo de pre venda", style="bold green"
272
+ )
253
273
  else:
254
274
  logger.info(f"\nError Message: {return_login.retorno}")
255
275
  console.print(f"\nError Message: {return_login.retorno}", style="bold red")
@@ -262,16 +282,22 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
262
282
  app = Application().connect(class_name="TFrmPreVenda")
263
283
  main_window = app["TFrmPreVenda"]
264
284
 
265
- condicao_field = main_window.child_window(class_name="TDBIComboBox", found_index=2)
285
+ condicao_field = main_window.child_window(
286
+ class_name="TDBIComboBox", found_index=2
287
+ )
266
288
  condicao_field.select("21 DIAS")
267
289
 
268
290
  # Código do fornecedor
269
- input_cod_fornecedor = main_window.child_window(class_name="TDBIEditNumber", found_index=2)
291
+ input_cod_fornecedor = main_window.child_window(
292
+ class_name="TDBIEditNumber", found_index=2
293
+ )
270
294
  input_cod_fornecedor.click_input()
271
295
  await worker_sleep(0.2)
272
296
  keyboard.send_keys("{END}+{HOME}{DEL}")
273
297
  await worker_sleep(0.2)
274
- input_cod_fornecedor.type_keys(str(cod_fornecedor), with_spaces=True, set_foreground=True)
298
+ input_cod_fornecedor.type_keys(
299
+ str(cod_fornecedor), with_spaces=True, set_foreground=True
300
+ )
275
301
  keyboard.send_keys("{TAB}")
276
302
  await worker_sleep(5)
277
303
 
@@ -281,13 +307,15 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
281
307
  app["TFrmSelecionaEndereco"].close()
282
308
  await worker_sleep(3)
283
309
  app = Application().connect(class_name="TMessageForm")
284
- app["TMessageForm"].child_window(class_name="TButton", found_index=0).click()
310
+ app["TMessageForm"].child_window(
311
+ class_name="TButton", found_index=0
312
+ ).click()
285
313
  except:
286
314
  pass
287
315
 
288
316
  app = Application().connect(class_name="TFrmPreVenda")
289
317
  main_window = app["TFrmPreVenda"]
290
- console.print("Verificar estado...")
318
+ console.print("Verificar estado...")
291
319
  if estado != "RS":
292
320
  modelo = "DEVOLUÇÃO DE COMPRA DE MERCADORIAS SC"
293
321
  else:
@@ -295,12 +323,15 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
295
323
 
296
324
  # Inserir modelo
297
325
  console.print("Inserir modelo...")
298
- select_modelo = main_window.child_window(class_name="TDBIComboBox", found_index=0)
326
+ select_modelo = main_window.child_window(
327
+ class_name="TDBIComboBox", found_index=0
328
+ )
299
329
  select_modelo.select(modelo)
300
330
  await worker_sleep(1)
301
331
 
302
332
  # Abrir guia de itens (por imagem)
303
- imagem_item = r"C:\Users\automatehub\Desktop\img_leo\itens.png"
333
+ # imagem_item = r"C:\Users\automatehub\Desktop\img_leo\itens.png"
334
+ imagem_item = "assets\\devolucao_produtos\\itens.png"
304
335
  for _ in range(10):
305
336
  pos = pyautogui.locateCenterOnScreen(imagem_item, confidence=0.9)
306
337
  if pos:
@@ -312,7 +343,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
312
343
  await worker_sleep(2)
313
344
 
314
345
  # Incluir item
315
- botao_incluir = main_window.child_window(title="Incluir", class_name="TDBIBitBtn").wrapper_object()
346
+ botao_incluir = main_window.child_window(
347
+ title="Incluir", class_name="TDBIBitBtn"
348
+ ).wrapper_object()
316
349
  botao_incluir.click_input()
317
350
  await worker_sleep(5)
318
351
 
@@ -324,15 +357,19 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
324
357
  # Abre tela de inclusão de item
325
358
  app_item = Application().connect(class_name="TFrmIncluiItemPreVenda")
326
359
  wnd_item = app_item["TFrmIncluiItemPreVenda"]
327
- input_almoxarifado = wnd_item.child_window(class_name="TDBIEditNumber", found_index=16)
360
+ input_almoxarifado = wnd_item.child_window(
361
+ class_name="TDBIEditNumber", found_index=16
362
+ )
328
363
  input_almoxarifado.click_input()
329
364
  await worker_sleep(1)
330
365
  keyboard.send_keys("{END}+{HOME}{DEL}")
331
366
  await worker_sleep(1)
332
- input_almoxarifado.type_keys(almoxarifado, with_spaces=True, set_foreground=True)
367
+ input_almoxarifado.type_keys(
368
+ almoxarifado, with_spaces=True, set_foreground=True
369
+ )
333
370
  keyboard.send_keys("{TAB}")
334
371
  await worker_sleep(1)
335
-
372
+
336
373
  # Dicionário para guardar os itens sem saldo / com saldo
337
374
  itens_sem_saldo = {}
338
375
  itens_com_saldo = {}
@@ -355,7 +392,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
355
392
 
356
393
  # --- Código ---
357
394
  console.print("Inserir código...")
358
- input_codigo = wnd_item.child_window(class_name="TDBIEditNumber", found_index=15)
395
+ input_codigo = wnd_item.child_window(
396
+ class_name="TDBIEditNumber", found_index=15
397
+ )
359
398
  input_codigo.click_input()
360
399
  await worker_sleep(1)
361
400
  keyboard.send_keys("{END}+{HOME}{DEL}")
@@ -380,7 +419,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
380
419
 
381
420
  # --- Quantidade ---
382
421
  console.print("Inserir quantidade...")
383
- wnd_item.child_window(class_name="TDBIEditNumber", found_index=8).click_input()
422
+ wnd_item.child_window(
423
+ class_name="TDBIEditNumber", found_index=8
424
+ ).click_input()
384
425
  await worker_sleep(1)
385
426
  keyboard.send_keys("{END}+{HOME}{DEL}")
386
427
  await worker_sleep(1)
@@ -390,7 +431,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
390
431
 
391
432
  # --- Valor Unitário via popup ---
392
433
  console.print("Inserir valor unitário...")
393
- wnd_item.child_window(class_name="TDBIEditNumber", found_index=6).click_input()
434
+ wnd_item.child_window(
435
+ class_name="TDBIEditNumber", found_index=6
436
+ ).click_input()
394
437
  await worker_sleep(1)
395
438
  keyboard.send_keys("{TAB}")
396
439
  await worker_sleep(1)
@@ -400,7 +443,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
400
443
  app_preco = Application().connect(class_name="TFrmInputBoxNumero")
401
444
  wnd_preco = app_preco["TFrmInputBoxNumero"]
402
445
 
403
- campo_preco = wnd_preco.child_window(class_name="TDBIEditNumber", found_index=0)
446
+ campo_preco = wnd_preco.child_window(
447
+ class_name="TDBIEditNumber", found_index=0
448
+ )
404
449
  campo_preco.click_input()
405
450
  await worker_sleep(1)
406
451
  keyboard.send_keys("{END}+{HOME}{DEL}")
@@ -414,7 +459,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
414
459
  console.print("Confirmar inclusão do item...")
415
460
  app_prevenda = Application().connect(class_name="TFrmIncluiItemPreVenda")
416
461
  wnd_prevenda = app_prevenda["TFrmIncluiItemPreVenda"]
417
- botao_incluir = wnd_prevenda.child_window(title="&Incluir", class_name="TDBIBitBtn").wrapper_object()
462
+ botao_incluir = wnd_prevenda.child_window(
463
+ title="&Incluir", class_name="TDBIBitBtn"
464
+ ).wrapper_object()
418
465
  botao_incluir.click_input()
419
466
 
420
467
  await worker_sleep(4)
@@ -424,30 +471,37 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
424
471
  had_saldo = True
425
472
  try:
426
473
  console.print("Verificar mensagem de saldo menor....")
427
- img_saldo = r"C:\Users\automatehub\Documents\GitHub\worker-assets\emsys\saldo_menor.png"
474
+ # img_saldo = r"C:\Users\automatehub\Documents\GitHub\worker-assets\emsys\saldo_menor.png"
475
+ img_saldo = "assets\\devolucao_produtos\\saldo_menor.png"
428
476
  img_saldo_bool = False
429
477
 
430
478
  for _ in range(10):
431
479
  pos = pyautogui.locateCenterOnScreen(img_saldo, confidence=0.9)
432
480
  if pos:
433
- console.print(f"Saldo disponível menor para o item {codigo}: {quantidade} x {val_unitario}")
481
+ console.print(
482
+ f"Saldo disponível menor para o item {codigo}: {quantidade} x {val_unitario}"
483
+ )
434
484
 
435
485
  # adiciona no dicionário de erros
436
486
  itens_sem_saldo[codigo] = {
437
487
  "quantidade": quantidade,
438
- "valor_unitario": val_unitario
488
+ "valor_unitario": val_unitario,
439
489
  }
440
490
 
441
491
  # fecha a mensagem
442
492
  app = Application().connect(class_name="TMessageForm")
443
493
  main_window_msg = app["TMessageForm"]
444
- btn_no = main_window_msg.child_window(title="&No", class_name="TButton")
494
+ btn_no = main_window_msg.child_window(
495
+ title="&No", class_name="TButton"
496
+ )
445
497
  btn_no.click_input()
446
498
 
447
499
  # clica em limpar
448
500
  app = Application().connect(class_name="TFrmIncluiItemPreVenda")
449
501
  main_window_limpa = app["TFrmIncluiItemPreVenda"]
450
- btn_limpa = main_window_limpa.child_window(title="&Limpa", class_name="TDBIBitBtn")
502
+ btn_limpa = main_window_limpa.child_window(
503
+ title="&Limpa", class_name="TDBIBitBtn"
504
+ )
451
505
  btn_limpa.click_input()
452
506
 
453
507
  img_saldo_bool = True
@@ -472,8 +526,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
472
526
  if had_saldo:
473
527
  console.print(f"Item {codigo} incluído com sucesso.")
474
528
  itens_com_saldo[codigo] = {
475
- "quantidade": quantidade,
476
- "valor_unitario": val_unitario
529
+ "quantidade": quantidade,
530
+ "valor_unitario": val_unitario,
477
531
  }
478
532
  for n in item_notas:
479
533
  notas_validas_set.add(str(n))
@@ -482,14 +536,15 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
482
536
  # Depois de processar todos os itens:
483
537
  if itens_sem_saldo and not itens_com_saldo:
484
538
  # Todos os itens ficaram sem saldo → para aqui
485
- log_msg = "Todos os itens estão com saldo menor que a quantidade:\n" + \
486
- "\n".join(f"- Código: {cod} | Quantidade: {dados['quantidade']} | Valor Unitário: {dados['valor_unitario']}"
487
- for cod, dados in itens_sem_saldo.items())
539
+ log_msg = "Todos os itens estão com saldo menor que a quantidade:\n" + "\n".join(
540
+ f"- Código: {cod} | Quantidade: {dados['quantidade']} | Valor Unitário: {dados['valor_unitario']}"
541
+ for cod, dados in itens_sem_saldo.items()
542
+ )
488
543
  return RpaRetornoProcessoDTO(
489
544
  sucesso=False,
490
545
  retorno=log_msg.strip(),
491
546
  status=RpaHistoricoStatusEnum.Falha,
492
- tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
547
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
493
548
  )
494
549
 
495
550
  # Caso contrário, existe pelo menos 1 com saldo → segue o fluxo
@@ -509,12 +564,13 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
509
564
 
510
565
  # Clicar em fechar
511
566
  wnd_prevenda.close()
512
-
567
+
513
568
  await worker_sleep(3)
514
-
569
+
515
570
  # Clicar em recebimentos
516
571
  console.print("Clicar em recebimentos...")
517
- imagem_item = r"C:\Users\automatehub\Desktop\img_leo\btn_recebimentos.png"
572
+ # imagem_item = r"C:\Users\automatehub\Desktop\img_leo\btn_recebimentos.png"
573
+ imagem_item = "assets\\devolucao_produtos\\btn_recebimentos.png"
518
574
  for _ in range(10):
519
575
  pos = pyautogui.locateCenterOnScreen(imagem_item, confidence=0.9)
520
576
  if pos:
@@ -523,12 +579,13 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
523
579
  await worker_sleep(1)
524
580
  else:
525
581
  print("Imagem do item não encontrada na tela.")
526
-
582
+
527
583
  await worker_sleep(3)
528
584
 
529
585
  # Clicar em Parcelamento
530
586
  console.print("Clicar em parcelamento...")
531
- imagem_parc = r"C:\Users\automatehub\Desktop\img_leo\btn_parcelamento.png"
587
+ # imagem_parc = r"C:\Users\automatehub\Desktop\img_leo\btn_parcelamento.png"
588
+ imagem_parc = "assets\\devolucao_produtos\\btn_parcelamento.png"
532
589
  for _ in range(10):
533
590
  pos = pyautogui.locateCenterOnScreen(imagem_parc, confidence=0.8)
534
591
  if pos:
@@ -537,7 +594,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
537
594
  await worker_sleep(1)
538
595
  else:
539
596
  print("Imagem do item não encontrada na tela.")
540
-
597
+
541
598
  await worker_sleep(3)
542
599
 
543
600
  # Volta pra janela de pre venda
@@ -546,12 +603,16 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
546
603
 
547
604
  # Condição de recebimento (boleto)
548
605
  console.print("Selecionar boleto...")
549
- condicao_field = main_window.child_window(class_name="TDBIComboBox", found_index=0)
606
+ condicao_field = main_window.child_window(
607
+ class_name="TDBIComboBox", found_index=0
608
+ )
550
609
  try:
551
610
  condicao_field.select("BANCO DO BRASIL BOLETO")
552
611
  print("Selecionado: BANCO DO BRASIL BOLETO")
553
612
  except Exception as e:
554
- print(f"Não foi possível selecionar 'BANCO DO BRASIL BOLETO' ({e}). Tentando 'BOLETO'...")
613
+ print(
614
+ f"Não foi possível selecionar 'BANCO DO BRASIL BOLETO' ({e}). Tentando 'BOLETO'..."
615
+ )
555
616
  try:
556
617
  condicao_field.select("BOLETO")
557
618
  print("Selecionado: BOLETO")
@@ -560,7 +621,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
560
621
 
561
622
  # Clicar em Incluir
562
623
  console.print("Incluir registro...")
563
- imagem_incluir = r"C:\Users\automatehub\Documents\GitHub\worker-automate-hub\assets\entrada_notas\IncluirRegistro.png"
624
+ # imagem_incluir = r"C:\Users\automatehub\Documents\GitHub\worker-automate-hub\assets\entrada_notas\IncluirRegistro.png"
625
+ imagem_incluir = "assets\\devolucao_produtos\\IncluirRegistro.png"
564
626
  for _ in range(10):
565
627
  pos = pyautogui.locateCenterOnScreen(imagem_incluir, confidence=0.8)
566
628
  if pos:
@@ -569,7 +631,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
569
631
  await worker_sleep(1)
570
632
  else:
571
633
  print("Imagem do item não encontrada na tela.")
572
-
634
+
573
635
  await worker_sleep(3)
574
636
 
575
637
  # Capturar número da pré-venda
@@ -586,14 +648,19 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
586
648
  win.set_focus()
587
649
 
588
650
  textos = []
589
- try: textos.append(win.window_text())
590
- except: pass
591
- try: textos += [t for t in win.wrapper_object().texts() if t]
592
- except: pass
651
+ try:
652
+ textos.append(win.window_text())
653
+ except:
654
+ pass
655
+ try:
656
+ textos += [t for t in win.wrapper_object().texts() if t]
657
+ except:
658
+ pass
593
659
  try:
594
660
  for st in win.children(class_name="Static"):
595
661
  textos += [t for t in st.texts() if t]
596
- except: pass
662
+ except:
663
+ pass
597
664
 
598
665
  texto = "\n".join([t for t in textos if t])
599
666
  if ("Venda inclu" in texto) or ("Pré" in texto) or ("Pr" in texto):
@@ -604,7 +671,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
604
671
  clicked = False
605
672
  for title in ("OK", "&OK"):
606
673
  try:
607
- win.child_window(title=title, class_name="TButton").click_input()
674
+ win.child_window(
675
+ title=title, class_name="TButton"
676
+ ).click_input()
608
677
  clicked = True
609
678
  break
610
679
  except:
@@ -632,7 +701,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
632
701
  # Botão confirma
633
702
  app = Application().connect(class_name="TFrmPreVenda")
634
703
  main_window = app["TFrmPreVenda"]
635
- btn_confirmar = main_window.child_window(title="&Confirma", class_name="TBitBtn")
704
+ btn_confirmar = main_window.child_window(
705
+ title="&Confirma", class_name="TBitBtn"
706
+ )
636
707
  btn_confirmar.click_input()
637
708
  await worker_sleep(4)
638
709
 
@@ -646,7 +717,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
646
717
  # Fechar "Informação"
647
718
  for _ in range(10):
648
719
  try:
649
- dlg = Desktop(backend="win32").window(title_re="Informação", class_name="#32770")
720
+ dlg = Desktop(backend="win32").window(
721
+ title_re="Informação", class_name="#32770"
722
+ )
650
723
  if dlg.exists(timeout=1):
651
724
  dlg.child_window(title="OK").click_input()
652
725
  print("✅ Fechou janela 'Informação'.")
@@ -677,19 +750,22 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
677
750
 
678
751
  for _ in range(10):
679
752
  try:
680
- dlg = Desktop(backend="win32").window(title_re="Parcelas - Nota Fiscal Sa", class_name="#32770")
753
+ dlg = Desktop(backend="win32").window(
754
+ title_re="Parcelas - Nota Fiscal Sa", class_name="#32770"
755
+ )
681
756
  if dlg.exists(timeout=1):
682
757
  dlg.child_window(title="&Não").click_input()
683
758
  print("Clicou em Não")
684
759
  break
685
760
  except:
686
761
  pass
687
-
762
+
688
763
  await worker_sleep(10)
689
764
 
690
765
  # Notas referenciadas
691
766
  console.print("CLicar em notas referenciadas...")
692
- imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\notas_referenciadas.png"
767
+ # imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\notas_referenciadas.png"
768
+ imagem_notas_ref = "assets\\devolucao_produtos\\notas_referenciadas.png"
693
769
  for _ in range(20):
694
770
  pos = pyautogui.locateCenterOnScreen(imagem_notas_ref, confidence=0.8)
695
771
  if pos:
@@ -698,7 +774,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
698
774
  await worker_sleep(1)
699
775
  else:
700
776
  print("Imagem do item não encontrada na tela.")
701
-
777
+
702
778
  await worker_sleep(2)
703
779
 
704
780
  # Faturamento Pré-venda
@@ -707,7 +783,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
707
783
  main_window.set_focus()
708
784
 
709
785
  # Radio Entrada
710
- main_window.child_window(title="Entrada", class_name="TDBIRadioButton").click_input()
786
+ main_window.child_window(
787
+ title="Entrada", class_name="TDBIRadioButton"
788
+ ).click_input()
711
789
  console.print("Clicado em 'Entrada'")
712
790
  await worker_sleep(4)
713
791
 
@@ -716,16 +794,24 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
716
794
  notas_validas_ordenadas = [n for n in todas_as_notas if n in notas_validas_set]
717
795
  notas_descartadas = [n for n in todas_as_notas if n not in notas_validas_set]
718
796
 
719
- console.print(f"[green]Notas a referenciar (itens com saldo): {notas_validas_ordenadas}[/]")
797
+ console.print(
798
+ f"[green]Notas a referenciar (itens com saldo): {notas_validas_ordenadas}[/]"
799
+ )
720
800
  if notas_descartadas:
721
- console.print(f"[yellow]Notas descartadas (apenas itens sem saldo): {notas_descartadas}[/]")
801
+ console.print(
802
+ f"[yellow]Notas descartadas (apenas itens sem saldo): {notas_descartadas}[/]"
803
+ )
722
804
 
723
805
  # >>> NOVO: nota_arquivo (primeira válida; fallback: pré-venda ou timestamp) - SEM extract_nf_number
724
806
  if notas_validas_ordenadas:
725
- nota_arquivo = re.sub(r"\D+", "", str(notas_validas_ordenadas[0])) or str(notas_validas_ordenadas[0])
807
+ nota_arquivo = re.sub(r"\D+", "", str(notas_validas_ordenadas[0])) or str(
808
+ notas_validas_ordenadas[0]
809
+ )
726
810
  else:
727
811
  if numero_pre_venda:
728
- nota_arquivo = re.sub(r"\D+", "", str(numero_pre_venda)) or str(numero_pre_venda)
812
+ nota_arquivo = re.sub(r"\D+", "", str(numero_pre_venda)) or str(
813
+ numero_pre_venda
814
+ )
729
815
  else:
730
816
  nota_arquivo = datetime.now().strftime("%Y%m%d%H%M%S")
731
817
 
@@ -733,7 +819,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
733
819
  for nf_ref_atual in notas_validas_ordenadas:
734
820
  itens_da_nota = data.get("itens_por_nota", {}).get(nf_ref_atual, [])
735
821
  if not itens_da_nota:
736
- console.print(f"[amarelo]Nenhum item associado à nota {nf_ref_atual}. Pulando...[/]")
822
+ console.print(
823
+ f"[amarelo]Nenhum item associado à nota {nf_ref_atual}. Pulando...[/]"
824
+ )
737
825
  continue
738
826
 
739
827
  console.print(f"[cyan]Processando nota {nf_ref_atual}...[/]")
@@ -749,7 +837,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
749
837
  await worker_sleep(0.4)
750
838
 
751
839
  # 2) Digitar a nota e confirmar
752
- input_num_nota.type_keys(str(nf_ref_atual), with_spaces=True, set_foreground=True)
840
+ input_num_nota.type_keys(
841
+ str(nf_ref_atual), with_spaces=True, set_foreground=True
842
+ )
753
843
  await worker_sleep(0.6)
754
844
  keyboard.send_keys("{ENTER}")
755
845
  await worker_sleep(0.6)
@@ -759,14 +849,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
759
849
  main_window = app["TFrmDadosFaturamentoPreVenda"]
760
850
 
761
851
  # Clica no botão identificado como TDBIBitBtn2 (control_id 918912)
762
- main_window.child_window(class_name="TDBIBitBtn", found_index=1).click_input()
852
+ main_window.child_window(
853
+ class_name="TDBIBitBtn", found_index=1
854
+ ).click_input()
763
855
 
764
856
  print("Botão clicado com sucesso!")
765
857
  console.print(f"Incluindo itens vinculados à nota {nf_ref_atual}...")
766
858
 
767
859
  # Aba mensagens
768
860
  console.print("Clicar em mensagens...")
769
- imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\aba_mensagem.png"
861
+ # imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\aba_mensagem.png"
862
+ imagem_notas_ref = "assets\\devolucao_produtos\\aba_mensagem.png"
770
863
  for _ in range(10):
771
864
  pos = pyautogui.locateCenterOnScreen(imagem_notas_ref, confidence=0.9)
772
865
  if pos:
@@ -778,7 +871,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
778
871
  await worker_sleep(5)
779
872
 
780
873
  # Mensagem interna
781
- imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\mensagem_interna.png"
874
+ # imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\mensagem_interna.png"
875
+ imagem_notas_ref = "assets\\devolucao_produtos\\mensagem_interna.png"
782
876
  for _ in range(10):
783
877
  pos = pyautogui.locateCenterOnScreen(imagem_notas_ref, confidence=0.8)
784
878
  if pos:
@@ -793,12 +887,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
793
887
  console.print("Inserir mensagem...")
794
888
  fornecedor = "Disbal"
795
889
  lista_fornecedores = ["Disbal", "Pepsico", "Punta Balena"]
796
- mensagem = "PRODUTOS VENCIDOS" if fornecedor in lista_fornecedores else "ACORDO COMERCIAL"
890
+ mensagem = (
891
+ "PRODUTOS VENCIDOS"
892
+ if fornecedor in lista_fornecedores
893
+ else "ACORDO COMERCIAL"
894
+ )
797
895
  input_mensagem = main_window.child_window(class_name="TDBIMemo", found_index=0)
798
896
  input_mensagem.type_keys(mensagem, with_spaces=True, set_foreground=True)
799
897
 
800
898
  # Aba itens
801
- imagem_itens = r"C:\Users\automatehub\Desktop\img_leo\aba_itens.png"
899
+ # imagem_itens = r"C:\Users\automatehub\Desktop\img_leo\aba_itens.png"
900
+ imagem_itens = "assets\\devolucao_produtos\\aba_itens.png"
802
901
  for _ in range(10):
803
902
  pos = pyautogui.locateCenterOnScreen(imagem_itens, confidence=0.9)
804
903
  if pos:
@@ -812,7 +911,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
812
911
 
813
912
  # Corrige tributação
814
913
  console.print("Corrigir tributação...")
815
- imagem_itens = r"C:\Users\automatehub\Desktop\img_leo\corrige_tributacao.png"
914
+ # imagem_itens = r"C:\Users\automatehub\Desktop\img_leo\corrige_tributacao.png"
915
+ imagem_itens = "assets\\devolucao_produtos\\corrige_tributacao.png"
816
916
  for _ in range(10):
817
917
  pos = pyautogui.locateCenterOnScreen(imagem_itens, confidence=0.9)
818
918
  if pos:
@@ -854,7 +954,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
854
954
  await worker_sleep(1)
855
955
 
856
956
  # Aba principal
857
- imagem_principal = r"C:\Users\automatehub\Desktop\img_leo\aba_principal.png"
957
+ # imagem_principal = r"C:\Users\automatehub\Desktop\img_leo\aba_principal.png"
958
+ imagem_principal = "assets\\devolucao_produtos\\aba_principal.png"
858
959
  for _ in range(10):
859
960
  pos = pyautogui.locateCenterOnScreen(imagem_principal, confidence=0.9)
860
961
  if pos:
@@ -867,39 +968,45 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
867
968
  await worker_sleep(5)
868
969
 
869
970
  # DANFE 077
870
- console.print("Selecionar NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077...")
971
+ console.print(
972
+ "Selecionar NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077..."
973
+ )
871
974
  app = Application().connect(class_name="TFrmDadosFaturamentoPreVenda")
872
975
  main_window = app["TFrmDadosFaturamentoPreVenda"]
873
- select_danfe = main_window.child_window(class_name="TDBIComboBox", found_index=1)
976
+ select_danfe = main_window.child_window(
977
+ class_name="TDBIComboBox", found_index=1
978
+ )
874
979
  select_danfe.select("NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077")
875
-
980
+
876
981
  await worker_sleep(2)
877
982
 
878
983
  # OK
879
984
  main_window.child_window(title="&OK", class_name="TBitBtn").click_input()
880
-
985
+
881
986
  await worker_sleep(3)
882
987
 
883
988
  # Faturar pré-venda (Yes)
884
989
  app = Application().connect(class_name="TMessageForm")
885
990
  main_window = app["TMessageForm"]
886
991
  main_window.child_window(class_name="TButton", found_index=1).click()
887
-
992
+
888
993
  await worker_sleep(5)
889
994
 
890
995
  # Faturar pré-venda (Yes)
891
996
  app = Application().connect(class_name="TMessageForm")
892
997
  main_window = app["TMessageForm"]
893
- main_window.child_window(title="Transmitir e &Imprimir", class_name="TButton").click_input()
998
+ main_window.child_window(
999
+ title="Transmitir e &Imprimir", class_name="TButton"
1000
+ ).click_input()
894
1001
 
895
1002
  await worker_sleep(10)
896
-
1003
+
897
1004
  # Diálogo impressão
898
1005
  console.print("Confirmar impressão...")
899
1006
  app = Application().connect(class_name="TppPrintDialog")
900
1007
  main_window = app["TppPrintDialog"]
901
1008
  main_window.child_window(title="OK", class_name="TButton").click()
902
-
1009
+
903
1010
  await worker_sleep(5)
904
1011
 
905
1012
  console.print(f"NAVEGANDO NA TELA DE SALVAR RELATORIO\n")
@@ -911,7 +1018,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
911
1018
 
912
1019
  console.print("Interagindo com a tela 'Salvar'...\n")
913
1020
  username = getpass.getuser()
914
-
1021
+
915
1022
  # Preenche o nome do arquivo - SOMENTE número da nota
916
1023
  path_to_txt = f"C:\\Users\\{username}\\Downloads\\devolucao_nf_{estado}_{nota_arquivo}"
917
1024
 
@@ -927,15 +1034,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
927
1034
  sucesso=False,
928
1035
  retorno=retorno,
929
1036
  status=RpaHistoricoStatusEnum.Falha,
930
- tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
1037
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)],
931
1038
  )
932
1039
 
933
- with open(f"{path_to_txt}.pdf", 'rb') as file:
1040
+ with open(f"{path_to_txt}.pdf", "rb") as file:
934
1041
  file_bytes = io.BytesIO(file.read())
935
1042
 
936
1043
  desArquivo = f"devolucao_nf_{estado}_{nota_arquivo}.pdf"
937
1044
  try:
938
- await send_file(historico_id, desArquivo, "pdf", file_bytes, file_extension="pdf")
1045
+ await send_file(
1046
+ historico_id, desArquivo, "pdf", file_bytes, file_extension="pdf"
1047
+ )
939
1048
  os.remove(f"{path_to_txt}.pdf")
940
1049
  except Exception as e:
941
1050
  result = (
@@ -947,14 +1056,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
947
1056
  sucesso=False,
948
1057
  retorno=result,
949
1058
  status=RpaHistoricoStatusEnum.Falha,
950
- tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
1059
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)],
951
1060
  )
952
1061
 
953
1062
  except Exception as ex:
954
1063
  log_msg = f"Error: {ex}"
955
1064
  print(ex)
956
1065
  return RpaRetornoProcessoDTO(
957
- sucesso=False, retorno=log_msg, status=RpaHistoricoStatusEnum.Falha, tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
1066
+ sucesso=False,
1067
+ retorno=log_msg,
1068
+ status=RpaHistoricoStatusEnum.Falha,
1069
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
958
1070
  )
959
1071
 
960
1072
  # ============== RESUMO FINAL ==============
@@ -965,27 +1077,35 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
965
1077
 
966
1078
  if itens_com_saldo:
967
1079
  lista_ok = "\n".join(_fmt_linha(c, d) for c, d in list(itens_com_saldo.items()))
968
- resumo_partes.append("✅ Itens incluídos:\n" + (lista_ok if lista_ok else "(vazio)"))
1080
+ resumo_partes.append(
1081
+ "✅ Itens incluídos:\n" + (lista_ok if lista_ok else "(vazio)")
1082
+ )
969
1083
 
970
1084
  if itens_sem_saldo:
971
- lista_sem = "\n".join(_fmt_linha(c, d) for c, d in list(itens_sem_saldo.items()))
972
- resumo_partes.append("⚠️ Itens sem saldo:\n" + (lista_sem if lista_sem else "(vazio)"))
1085
+ lista_sem = "\n".join(
1086
+ _fmt_linha(c, d) for c, d in list(itens_sem_saldo.items())
1087
+ )
1088
+ resumo_partes.append(
1089
+ "⚠️ Itens sem saldo:\n" + (lista_sem if lista_sem else "(vazio)")
1090
+ )
973
1091
 
974
1092
  # (Opcional) resumo sobre notas válidas/descartadas
975
1093
  try:
976
1094
  resumo_partes.append(
977
- "🧾 Notas referenciadas: " + ", ".join(sorted(list(notas_validas_set))) if notas_validas_set else "🧾 Notas referenciadas: (nenhuma)"
1095
+ "🧾 Notas referenciadas: " + ", ".join(sorted(list(notas_validas_set)))
1096
+ if notas_validas_set
1097
+ else "🧾 Notas referenciadas: (nenhuma)"
978
1098
  )
979
1099
  except:
980
1100
  pass
981
1101
 
982
- resumo_txt = "\n\n".join(resumo_partes) if resumo_partes else "Nenhum item processado."
1102
+ resumo_txt = (
1103
+ "\n\n".join(resumo_partes) if resumo_partes else "Nenhum item processado."
1104
+ )
983
1105
 
984
1106
  return RpaRetornoProcessoDTO(
985
1107
  sucesso=True,
986
1108
  retorno=f"Processo concluído.\n\n{resumo_txt}",
987
1109
  status=RpaHistoricoStatusEnum.Sucesso,
988
- tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
1110
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
989
1111
  )
990
-
991
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: worker-automate-hub
3
- Version: 0.5.829
3
+ Version: 0.5.831
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
@@ -45,7 +45,7 @@ worker_automate_hub/tasks/jobs/descartes.py,sha256=wIi8n4vZrNE-03C5_lr4FmxuKoWSY
45
45
  worker_automate_hub/tasks/jobs/devolucao_ctf.py,sha256=7tdUihaDqjIf7POjM79EqKG0w-qqXbhC6jq6hteavkw,250822
46
46
  worker_automate_hub/tasks/jobs/devolucao_ctf_35.py,sha256=e9t5k2mtZcUcEGKPWysbWzsH_gqrK-6aBXjWe2jWfTg,253948
47
47
  worker_automate_hub/tasks/jobs/devolucao_prazo_a_faturar.py,sha256=kzPJazDRbz2CLn8tKja2Lg1N4UzTRF1V4Nc1elIqTGY,272145
48
- worker_automate_hub/tasks/jobs/devolucao_produtos.py,sha256=PDqS4kPtYWbsbIy0AiG05CtWQFRowEfhfHpiZsaKySg,40975
48
+ worker_automate_hub/tasks/jobs/devolucao_produtos.py,sha256=vL-bSlfQkT860EfeHgeXl5bXo5pSMu8KAQhyy9LxYAg,43342
49
49
  worker_automate_hub/tasks/jobs/ecac_estadual_go.py,sha256=dKkf22nH5gp3RErq5u0UzRsKyJ81fc6ZZ4vLtUuMwHA,21002
50
50
  worker_automate_hub/tasks/jobs/ecac_estadual_main.py,sha256=8WmKe4-MRtzHobXz2S4YBDNN8alfawkC-BBlRY-mn1g,1726
51
51
  worker_automate_hub/tasks/jobs/ecac_estadual_mt.py,sha256=C26zmpGQGUq6sP9lU9nanM3Fje-rkyx5tjwmRy4lyL8,25300
@@ -105,7 +105,7 @@ worker_automate_hub/utils/updater.py,sha256=en2FCGhI8aZ-JNP3LQm64NJDc4awCNW7UhbV
105
105
  worker_automate_hub/utils/util.py,sha256=rDp5h36I_kMfaCDD9xgcxibRXe5AYaImlXKhGbQ7DHE,211273
106
106
  worker_automate_hub/utils/utils_nfe_entrada.py,sha256=F7jk95LpDwl5WfaQXahCA5yDdnySnWdctDqczHXwGqE,38195
107
107
  worker_automate_hub/worker.py,sha256=zEnYUrm5kY2cHbbee15QJkwkx4euD2SB2zRvUIbjS90,6850
108
- worker_automate_hub-0.5.829.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
109
- worker_automate_hub-0.5.829.dist-info/METADATA,sha256=p2nNX9hVoMfEnfrA9bnxcuuwijv7yii2MprLtwB9JIU,3142
110
- worker_automate_hub-0.5.829.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
111
- worker_automate_hub-0.5.829.dist-info/RECORD,,
108
+ worker_automate_hub-0.5.831.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
109
+ worker_automate_hub-0.5.831.dist-info/METADATA,sha256=6pNtOIHZoutHosQh1yS12DN5KZpKB3sHCwqMMRFGTYg,3142
110
+ worker_automate_hub-0.5.831.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
111
+ worker_automate_hub-0.5.831.dist-info/RECORD,,