worker-automate-hub 0.5.829__py3-none-any.whl → 0.5.830__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,7 +323,9 @@ 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
 
@@ -312,7 +342,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
312
342
  await worker_sleep(2)
313
343
 
314
344
  # Incluir item
315
- botao_incluir = main_window.child_window(title="Incluir", class_name="TDBIBitBtn").wrapper_object()
345
+ botao_incluir = main_window.child_window(
346
+ title="Incluir", class_name="TDBIBitBtn"
347
+ ).wrapper_object()
316
348
  botao_incluir.click_input()
317
349
  await worker_sleep(5)
318
350
 
@@ -324,15 +356,19 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
324
356
  # Abre tela de inclusão de item
325
357
  app_item = Application().connect(class_name="TFrmIncluiItemPreVenda")
326
358
  wnd_item = app_item["TFrmIncluiItemPreVenda"]
327
- input_almoxarifado = wnd_item.child_window(class_name="TDBIEditNumber", found_index=16)
359
+ input_almoxarifado = wnd_item.child_window(
360
+ class_name="TDBIEditNumber", found_index=16
361
+ )
328
362
  input_almoxarifado.click_input()
329
363
  await worker_sleep(1)
330
364
  keyboard.send_keys("{END}+{HOME}{DEL}")
331
365
  await worker_sleep(1)
332
- input_almoxarifado.type_keys(almoxarifado, with_spaces=True, set_foreground=True)
366
+ input_almoxarifado.type_keys(
367
+ almoxarifado, with_spaces=True, set_foreground=True
368
+ )
333
369
  keyboard.send_keys("{TAB}")
334
370
  await worker_sleep(1)
335
-
371
+
336
372
  # Dicionário para guardar os itens sem saldo / com saldo
337
373
  itens_sem_saldo = {}
338
374
  itens_com_saldo = {}
@@ -355,7 +391,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
355
391
 
356
392
  # --- Código ---
357
393
  console.print("Inserir código...")
358
- input_codigo = wnd_item.child_window(class_name="TDBIEditNumber", found_index=15)
394
+ input_codigo = wnd_item.child_window(
395
+ class_name="TDBIEditNumber", found_index=15
396
+ )
359
397
  input_codigo.click_input()
360
398
  await worker_sleep(1)
361
399
  keyboard.send_keys("{END}+{HOME}{DEL}")
@@ -380,7 +418,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
380
418
 
381
419
  # --- Quantidade ---
382
420
  console.print("Inserir quantidade...")
383
- wnd_item.child_window(class_name="TDBIEditNumber", found_index=8).click_input()
421
+ wnd_item.child_window(
422
+ class_name="TDBIEditNumber", found_index=8
423
+ ).click_input()
384
424
  await worker_sleep(1)
385
425
  keyboard.send_keys("{END}+{HOME}{DEL}")
386
426
  await worker_sleep(1)
@@ -390,7 +430,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
390
430
 
391
431
  # --- Valor Unitário via popup ---
392
432
  console.print("Inserir valor unitário...")
393
- wnd_item.child_window(class_name="TDBIEditNumber", found_index=6).click_input()
433
+ wnd_item.child_window(
434
+ class_name="TDBIEditNumber", found_index=6
435
+ ).click_input()
394
436
  await worker_sleep(1)
395
437
  keyboard.send_keys("{TAB}")
396
438
  await worker_sleep(1)
@@ -400,7 +442,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
400
442
  app_preco = Application().connect(class_name="TFrmInputBoxNumero")
401
443
  wnd_preco = app_preco["TFrmInputBoxNumero"]
402
444
 
403
- campo_preco = wnd_preco.child_window(class_name="TDBIEditNumber", found_index=0)
445
+ campo_preco = wnd_preco.child_window(
446
+ class_name="TDBIEditNumber", found_index=0
447
+ )
404
448
  campo_preco.click_input()
405
449
  await worker_sleep(1)
406
450
  keyboard.send_keys("{END}+{HOME}{DEL}")
@@ -414,7 +458,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
414
458
  console.print("Confirmar inclusão do item...")
415
459
  app_prevenda = Application().connect(class_name="TFrmIncluiItemPreVenda")
416
460
  wnd_prevenda = app_prevenda["TFrmIncluiItemPreVenda"]
417
- botao_incluir = wnd_prevenda.child_window(title="&Incluir", class_name="TDBIBitBtn").wrapper_object()
461
+ botao_incluir = wnd_prevenda.child_window(
462
+ title="&Incluir", class_name="TDBIBitBtn"
463
+ ).wrapper_object()
418
464
  botao_incluir.click_input()
419
465
 
420
466
  await worker_sleep(4)
@@ -430,24 +476,30 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
430
476
  for _ in range(10):
431
477
  pos = pyautogui.locateCenterOnScreen(img_saldo, confidence=0.9)
432
478
  if pos:
433
- console.print(f"Saldo disponível menor para o item {codigo}: {quantidade} x {val_unitario}")
479
+ console.print(
480
+ f"Saldo disponível menor para o item {codigo}: {quantidade} x {val_unitario}"
481
+ )
434
482
 
435
483
  # adiciona no dicionário de erros
436
484
  itens_sem_saldo[codigo] = {
437
485
  "quantidade": quantidade,
438
- "valor_unitario": val_unitario
486
+ "valor_unitario": val_unitario,
439
487
  }
440
488
 
441
489
  # fecha a mensagem
442
490
  app = Application().connect(class_name="TMessageForm")
443
491
  main_window_msg = app["TMessageForm"]
444
- btn_no = main_window_msg.child_window(title="&No", class_name="TButton")
492
+ btn_no = main_window_msg.child_window(
493
+ title="&No", class_name="TButton"
494
+ )
445
495
  btn_no.click_input()
446
496
 
447
497
  # clica em limpar
448
498
  app = Application().connect(class_name="TFrmIncluiItemPreVenda")
449
499
  main_window_limpa = app["TFrmIncluiItemPreVenda"]
450
- btn_limpa = main_window_limpa.child_window(title="&Limpa", class_name="TDBIBitBtn")
500
+ btn_limpa = main_window_limpa.child_window(
501
+ title="&Limpa", class_name="TDBIBitBtn"
502
+ )
451
503
  btn_limpa.click_input()
452
504
 
453
505
  img_saldo_bool = True
@@ -472,8 +524,8 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
472
524
  if had_saldo:
473
525
  console.print(f"Item {codigo} incluído com sucesso.")
474
526
  itens_com_saldo[codigo] = {
475
- "quantidade": quantidade,
476
- "valor_unitario": val_unitario
527
+ "quantidade": quantidade,
528
+ "valor_unitario": val_unitario,
477
529
  }
478
530
  for n in item_notas:
479
531
  notas_validas_set.add(str(n))
@@ -482,14 +534,15 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
482
534
  # Depois de processar todos os itens:
483
535
  if itens_sem_saldo and not itens_com_saldo:
484
536
  # 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())
537
+ log_msg = "Todos os itens estão com saldo menor que a quantidade:\n" + "\n".join(
538
+ f"- Código: {cod} | Quantidade: {dados['quantidade']} | Valor Unitário: {dados['valor_unitario']}"
539
+ for cod, dados in itens_sem_saldo.items()
540
+ )
488
541
  return RpaRetornoProcessoDTO(
489
542
  sucesso=False,
490
543
  retorno=log_msg.strip(),
491
544
  status=RpaHistoricoStatusEnum.Falha,
492
- tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
545
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
493
546
  )
494
547
 
495
548
  # Caso contrário, existe pelo menos 1 com saldo → segue o fluxo
@@ -509,9 +562,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
509
562
 
510
563
  # Clicar em fechar
511
564
  wnd_prevenda.close()
512
-
565
+
513
566
  await worker_sleep(3)
514
-
567
+
515
568
  # Clicar em recebimentos
516
569
  console.print("Clicar em recebimentos...")
517
570
  imagem_item = r"C:\Users\automatehub\Desktop\img_leo\btn_recebimentos.png"
@@ -523,7 +576,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
523
576
  await worker_sleep(1)
524
577
  else:
525
578
  print("Imagem do item não encontrada na tela.")
526
-
579
+
527
580
  await worker_sleep(3)
528
581
 
529
582
  # Clicar em Parcelamento
@@ -537,7 +590,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
537
590
  await worker_sleep(1)
538
591
  else:
539
592
  print("Imagem do item não encontrada na tela.")
540
-
593
+
541
594
  await worker_sleep(3)
542
595
 
543
596
  # Volta pra janela de pre venda
@@ -546,12 +599,16 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
546
599
 
547
600
  # Condição de recebimento (boleto)
548
601
  console.print("Selecionar boleto...")
549
- condicao_field = main_window.child_window(class_name="TDBIComboBox", found_index=0)
602
+ condicao_field = main_window.child_window(
603
+ class_name="TDBIComboBox", found_index=0
604
+ )
550
605
  try:
551
606
  condicao_field.select("BANCO DO BRASIL BOLETO")
552
607
  print("Selecionado: BANCO DO BRASIL BOLETO")
553
608
  except Exception as e:
554
- print(f"Não foi possível selecionar 'BANCO DO BRASIL BOLETO' ({e}). Tentando 'BOLETO'...")
609
+ print(
610
+ f"Não foi possível selecionar 'BANCO DO BRASIL BOLETO' ({e}). Tentando 'BOLETO'..."
611
+ )
555
612
  try:
556
613
  condicao_field.select("BOLETO")
557
614
  print("Selecionado: BOLETO")
@@ -569,7 +626,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
569
626
  await worker_sleep(1)
570
627
  else:
571
628
  print("Imagem do item não encontrada na tela.")
572
-
629
+
573
630
  await worker_sleep(3)
574
631
 
575
632
  # Capturar número da pré-venda
@@ -586,14 +643,19 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
586
643
  win.set_focus()
587
644
 
588
645
  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
646
+ try:
647
+ textos.append(win.window_text())
648
+ except:
649
+ pass
650
+ try:
651
+ textos += [t for t in win.wrapper_object().texts() if t]
652
+ except:
653
+ pass
593
654
  try:
594
655
  for st in win.children(class_name="Static"):
595
656
  textos += [t for t in st.texts() if t]
596
- except: pass
657
+ except:
658
+ pass
597
659
 
598
660
  texto = "\n".join([t for t in textos if t])
599
661
  if ("Venda inclu" in texto) or ("Pré" in texto) or ("Pr" in texto):
@@ -604,7 +666,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
604
666
  clicked = False
605
667
  for title in ("OK", "&OK"):
606
668
  try:
607
- win.child_window(title=title, class_name="TButton").click_input()
669
+ win.child_window(
670
+ title=title, class_name="TButton"
671
+ ).click_input()
608
672
  clicked = True
609
673
  break
610
674
  except:
@@ -632,7 +696,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
632
696
  # Botão confirma
633
697
  app = Application().connect(class_name="TFrmPreVenda")
634
698
  main_window = app["TFrmPreVenda"]
635
- btn_confirmar = main_window.child_window(title="&Confirma", class_name="TBitBtn")
699
+ btn_confirmar = main_window.child_window(
700
+ title="&Confirma", class_name="TBitBtn"
701
+ )
636
702
  btn_confirmar.click_input()
637
703
  await worker_sleep(4)
638
704
 
@@ -646,7 +712,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
646
712
  # Fechar "Informação"
647
713
  for _ in range(10):
648
714
  try:
649
- dlg = Desktop(backend="win32").window(title_re="Informação", class_name="#32770")
715
+ dlg = Desktop(backend="win32").window(
716
+ title_re="Informação", class_name="#32770"
717
+ )
650
718
  if dlg.exists(timeout=1):
651
719
  dlg.child_window(title="OK").click_input()
652
720
  print("✅ Fechou janela 'Informação'.")
@@ -677,19 +745,23 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
677
745
 
678
746
  for _ in range(10):
679
747
  try:
680
- dlg = Desktop(backend="win32").window(title_re="Parcelas - Nota Fiscal Sa", class_name="#32770")
748
+ dlg = Desktop(backend="win32").window(
749
+ title_re="Parcelas - Nota Fiscal Sa", class_name="#32770"
750
+ )
681
751
  if dlg.exists(timeout=1):
682
752
  dlg.child_window(title="&Não").click_input()
683
753
  print("Clicou em Não")
684
754
  break
685
755
  except:
686
756
  pass
687
-
757
+
688
758
  await worker_sleep(10)
689
759
 
690
760
  # Notas referenciadas
691
761
  console.print("CLicar em notas referenciadas...")
692
- imagem_notas_ref = r"C:\Users\automatehub\Desktop\img_leo\notas_referenciadas.png"
762
+ imagem_notas_ref = (
763
+ r"C:\Users\automatehub\Desktop\img_leo\notas_referenciadas.png"
764
+ )
693
765
  for _ in range(20):
694
766
  pos = pyautogui.locateCenterOnScreen(imagem_notas_ref, confidence=0.8)
695
767
  if pos:
@@ -698,7 +770,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
698
770
  await worker_sleep(1)
699
771
  else:
700
772
  print("Imagem do item não encontrada na tela.")
701
-
773
+
702
774
  await worker_sleep(2)
703
775
 
704
776
  # Faturamento Pré-venda
@@ -707,7 +779,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
707
779
  main_window.set_focus()
708
780
 
709
781
  # Radio Entrada
710
- main_window.child_window(title="Entrada", class_name="TDBIRadioButton").click_input()
782
+ main_window.child_window(
783
+ title="Entrada", class_name="TDBIRadioButton"
784
+ ).click_input()
711
785
  console.print("Clicado em 'Entrada'")
712
786
  await worker_sleep(4)
713
787
 
@@ -716,16 +790,24 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
716
790
  notas_validas_ordenadas = [n for n in todas_as_notas if n in notas_validas_set]
717
791
  notas_descartadas = [n for n in todas_as_notas if n not in notas_validas_set]
718
792
 
719
- console.print(f"[green]Notas a referenciar (itens com saldo): {notas_validas_ordenadas}[/]")
793
+ console.print(
794
+ f"[green]Notas a referenciar (itens com saldo): {notas_validas_ordenadas}[/]"
795
+ )
720
796
  if notas_descartadas:
721
- console.print(f"[yellow]Notas descartadas (apenas itens sem saldo): {notas_descartadas}[/]")
797
+ console.print(
798
+ f"[yellow]Notas descartadas (apenas itens sem saldo): {notas_descartadas}[/]"
799
+ )
722
800
 
723
801
  # >>> NOVO: nota_arquivo (primeira válida; fallback: pré-venda ou timestamp) - SEM extract_nf_number
724
802
  if notas_validas_ordenadas:
725
- nota_arquivo = re.sub(r"\D+", "", str(notas_validas_ordenadas[0])) or str(notas_validas_ordenadas[0])
803
+ nota_arquivo = re.sub(r"\D+", "", str(notas_validas_ordenadas[0])) or str(
804
+ notas_validas_ordenadas[0]
805
+ )
726
806
  else:
727
807
  if numero_pre_venda:
728
- nota_arquivo = re.sub(r"\D+", "", str(numero_pre_venda)) or str(numero_pre_venda)
808
+ nota_arquivo = re.sub(r"\D+", "", str(numero_pre_venda)) or str(
809
+ numero_pre_venda
810
+ )
729
811
  else:
730
812
  nota_arquivo = datetime.now().strftime("%Y%m%d%H%M%S")
731
813
 
@@ -733,7 +815,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
733
815
  for nf_ref_atual in notas_validas_ordenadas:
734
816
  itens_da_nota = data.get("itens_por_nota", {}).get(nf_ref_atual, [])
735
817
  if not itens_da_nota:
736
- console.print(f"[amarelo]Nenhum item associado à nota {nf_ref_atual}. Pulando...[/]")
818
+ console.print(
819
+ f"[amarelo]Nenhum item associado à nota {nf_ref_atual}. Pulando...[/]"
820
+ )
737
821
  continue
738
822
 
739
823
  console.print(f"[cyan]Processando nota {nf_ref_atual}...[/]")
@@ -749,7 +833,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
749
833
  await worker_sleep(0.4)
750
834
 
751
835
  # 2) Digitar a nota e confirmar
752
- input_num_nota.type_keys(str(nf_ref_atual), with_spaces=True, set_foreground=True)
836
+ input_num_nota.type_keys(
837
+ str(nf_ref_atual), with_spaces=True, set_foreground=True
838
+ )
753
839
  await worker_sleep(0.6)
754
840
  keyboard.send_keys("{ENTER}")
755
841
  await worker_sleep(0.6)
@@ -759,7 +845,9 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
759
845
  main_window = app["TFrmDadosFaturamentoPreVenda"]
760
846
 
761
847
  # Clica no botão identificado como TDBIBitBtn2 (control_id 918912)
762
- main_window.child_window(class_name="TDBIBitBtn", found_index=1).click_input()
848
+ main_window.child_window(
849
+ class_name="TDBIBitBtn", found_index=1
850
+ ).click_input()
763
851
 
764
852
  print("Botão clicado com sucesso!")
765
853
  console.print(f"Incluindo itens vinculados à nota {nf_ref_atual}...")
@@ -793,7 +881,11 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
793
881
  console.print("Inserir mensagem...")
794
882
  fornecedor = "Disbal"
795
883
  lista_fornecedores = ["Disbal", "Pepsico", "Punta Balena"]
796
- mensagem = "PRODUTOS VENCIDOS" if fornecedor in lista_fornecedores else "ACORDO COMERCIAL"
884
+ mensagem = (
885
+ "PRODUTOS VENCIDOS"
886
+ if fornecedor in lista_fornecedores
887
+ else "ACORDO COMERCIAL"
888
+ )
797
889
  input_mensagem = main_window.child_window(class_name="TDBIMemo", found_index=0)
798
890
  input_mensagem.type_keys(mensagem, with_spaces=True, set_foreground=True)
799
891
 
@@ -867,39 +959,45 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
867
959
  await worker_sleep(5)
868
960
 
869
961
  # DANFE 077
870
- console.print("Selecionar NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077...")
962
+ console.print(
963
+ "Selecionar NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077..."
964
+ )
871
965
  app = Application().connect(class_name="TFrmDadosFaturamentoPreVenda")
872
966
  main_window = app["TFrmDadosFaturamentoPreVenda"]
873
- select_danfe = main_window.child_window(class_name="TDBIComboBox", found_index=1)
967
+ select_danfe = main_window.child_window(
968
+ class_name="TDBIComboBox", found_index=1
969
+ )
874
970
  select_danfe.select("NFe - NOTA FISCAL ELETRONICA PROPRIA - DANFE SERIE 077")
875
-
971
+
876
972
  await worker_sleep(2)
877
973
 
878
974
  # OK
879
975
  main_window.child_window(title="&OK", class_name="TBitBtn").click_input()
880
-
976
+
881
977
  await worker_sleep(3)
882
978
 
883
979
  # Faturar pré-venda (Yes)
884
980
  app = Application().connect(class_name="TMessageForm")
885
981
  main_window = app["TMessageForm"]
886
982
  main_window.child_window(class_name="TButton", found_index=1).click()
887
-
983
+
888
984
  await worker_sleep(5)
889
985
 
890
986
  # Faturar pré-venda (Yes)
891
987
  app = Application().connect(class_name="TMessageForm")
892
988
  main_window = app["TMessageForm"]
893
- main_window.child_window(title="Transmitir e &Imprimir", class_name="TButton").click_input()
989
+ main_window.child_window(
990
+ title="Transmitir e &Imprimir", class_name="TButton"
991
+ ).click_input()
894
992
 
895
993
  await worker_sleep(10)
896
-
994
+
897
995
  # Diálogo impressão
898
996
  console.print("Confirmar impressão...")
899
997
  app = Application().connect(class_name="TppPrintDialog")
900
998
  main_window = app["TppPrintDialog"]
901
999
  main_window.child_window(title="OK", class_name="TButton").click()
902
-
1000
+
903
1001
  await worker_sleep(5)
904
1002
 
905
1003
  console.print(f"NAVEGANDO NA TELA DE SALVAR RELATORIO\n")
@@ -911,7 +1009,7 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
911
1009
 
912
1010
  console.print("Interagindo com a tela 'Salvar'...\n")
913
1011
  username = getpass.getuser()
914
-
1012
+
915
1013
  # Preenche o nome do arquivo - SOMENTE número da nota
916
1014
  path_to_txt = f"C:\\Users\\{username}\\Downloads\\devolucao_nf_{estado}_{nota_arquivo}"
917
1015
 
@@ -927,15 +1025,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
927
1025
  sucesso=False,
928
1026
  retorno=retorno,
929
1027
  status=RpaHistoricoStatusEnum.Falha,
930
- tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
1028
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)],
931
1029
  )
932
1030
 
933
- with open(f"{path_to_txt}.pdf", 'rb') as file:
1031
+ with open(f"{path_to_txt}.pdf", "rb") as file:
934
1032
  file_bytes = io.BytesIO(file.read())
935
1033
 
936
1034
  desArquivo = f"devolucao_nf_{estado}_{nota_arquivo}.pdf"
937
1035
  try:
938
- await send_file(historico_id, desArquivo, "pdf", file_bytes, file_extension="pdf")
1036
+ await send_file(
1037
+ historico_id, desArquivo, "pdf", file_bytes, file_extension="pdf"
1038
+ )
939
1039
  os.remove(f"{path_to_txt}.pdf")
940
1040
  except Exception as e:
941
1041
  result = (
@@ -947,14 +1047,17 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
947
1047
  sucesso=False,
948
1048
  retorno=result,
949
1049
  status=RpaHistoricoStatusEnum.Falha,
950
- tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)]
1050
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico)],
951
1051
  )
952
1052
 
953
1053
  except Exception as ex:
954
1054
  log_msg = f"Error: {ex}"
955
1055
  print(ex)
956
1056
  return RpaRetornoProcessoDTO(
957
- sucesso=False, retorno=log_msg, status=RpaHistoricoStatusEnum.Falha, tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
1057
+ sucesso=False,
1058
+ retorno=log_msg,
1059
+ status=RpaHistoricoStatusEnum.Falha,
1060
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
958
1061
  )
959
1062
 
960
1063
  # ============== RESUMO FINAL ==============
@@ -965,27 +1068,35 @@ async def devolucao_produtos(task: RpaProcessoEntradaDTO) -> RpaRetornoProcessoD
965
1068
 
966
1069
  if itens_com_saldo:
967
1070
  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)"))
1071
+ resumo_partes.append(
1072
+ "✅ Itens incluídos:\n" + (lista_ok if lista_ok else "(vazio)")
1073
+ )
969
1074
 
970
1075
  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)"))
1076
+ lista_sem = "\n".join(
1077
+ _fmt_linha(c, d) for c, d in list(itens_sem_saldo.items())
1078
+ )
1079
+ resumo_partes.append(
1080
+ "⚠️ Itens sem saldo:\n" + (lista_sem if lista_sem else "(vazio)")
1081
+ )
973
1082
 
974
1083
  # (Opcional) resumo sobre notas válidas/descartadas
975
1084
  try:
976
1085
  resumo_partes.append(
977
- "🧾 Notas referenciadas: " + ", ".join(sorted(list(notas_validas_set))) if notas_validas_set else "🧾 Notas referenciadas: (nenhuma)"
1086
+ "🧾 Notas referenciadas: " + ", ".join(sorted(list(notas_validas_set)))
1087
+ if notas_validas_set
1088
+ else "🧾 Notas referenciadas: (nenhuma)"
978
1089
  )
979
1090
  except:
980
1091
  pass
981
1092
 
982
- resumo_txt = "\n\n".join(resumo_partes) if resumo_partes else "Nenhum item processado."
1093
+ resumo_txt = (
1094
+ "\n\n".join(resumo_partes) if resumo_partes else "Nenhum item processado."
1095
+ )
983
1096
 
984
1097
  return RpaRetornoProcessoDTO(
985
1098
  sucesso=True,
986
1099
  retorno=f"Processo concluído.\n\n{resumo_txt}",
987
1100
  status=RpaHistoricoStatusEnum.Sucesso,
988
- tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)]
1101
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Negocio)],
989
1102
  )
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.830
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=ofVtWCAkkQgVZ_kxay4JgTUce6WZ_pHMWyeZ7mXuKHA,42527
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.830.dist-info/entry_points.txt,sha256=sddyhjx57I08RY8X7UxcTpdoOsWULAWNKN9Xr6pp_Kw,54
109
+ worker_automate_hub-0.5.830.dist-info/METADATA,sha256=rEXR81qIUb7EE-vhWUEjqxwGy56fnILKpc4wimF5gAU,3142
110
+ worker_automate_hub-0.5.830.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
111
+ worker_automate_hub-0.5.830.dist-info/RECORD,,