worker-automate-hub 0.5.820__py3-none-any.whl → 0.5.921__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.
Files changed (24) hide show
  1. worker_automate_hub/api/client.py +121 -10
  2. worker_automate_hub/api/rpa_historico_service.py +1 -0
  3. worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +11 -14
  4. worker_automate_hub/tasks/jobs/descartes.py +8 -8
  5. worker_automate_hub/tasks/jobs/devolucao_produtos.py +1386 -0
  6. worker_automate_hub/tasks/jobs/extracao_dados_nielsen.py +504 -0
  7. worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py +90 -11
  8. worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py +2 -2
  9. worker_automate_hub/tasks/jobs/fidc_remessa_cobranca_cnab240.py +24 -15
  10. worker_automate_hub/tasks/jobs/importacao_extratos.py +538 -0
  11. worker_automate_hub/tasks/jobs/importacao_extratos_748.py +800 -0
  12. worker_automate_hub/tasks/jobs/inclusao_pedidos_ipiranga.py +223 -0
  13. worker_automate_hub/tasks/jobs/inclusao_pedidos_raizen.py +187 -0
  14. worker_automate_hub/tasks/jobs/inclusao_pedidos_vibra.py +345 -0
  15. worker_automate_hub/tasks/jobs/lista_clientes_sap.py +631 -0
  16. worker_automate_hub/tasks/jobs/lista_devolucoes_sap.py +626 -0
  17. worker_automate_hub/tasks/jobs/notas_faturamento_sap.py +438 -157
  18. worker_automate_hub/tasks/jobs/opex_capex.py +523 -384
  19. worker_automate_hub/tasks/task_definitions.py +38 -2
  20. worker_automate_hub/utils/util.py +20 -10
  21. {worker_automate_hub-0.5.820.dist-info → worker_automate_hub-0.5.921.dist-info}/METADATA +2 -1
  22. {worker_automate_hub-0.5.820.dist-info → worker_automate_hub-0.5.921.dist-info}/RECORD +24 -15
  23. {worker_automate_hub-0.5.820.dist-info → worker_automate_hub-0.5.921.dist-info}/WHEEL +0 -0
  24. {worker_automate_hub-0.5.820.dist-info → worker_automate_hub-0.5.921.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,345 @@
1
+ from worker_automate_hub.models.dto.rpa_historico_request_dto import (
2
+ RpaHistoricoStatusEnum,
3
+ RpaRetornoProcessoDTO,
4
+ RpaTagDTO,
5
+ RpaTagEnum,
6
+ )
7
+ from worker_automate_hub.models.dto.rpa_processo_entrada_dto import (
8
+ RpaProcessoEntradaDTO,
9
+ )
10
+ from rich.console import Console
11
+ import asyncio
12
+ from datetime import datetime
13
+ import re
14
+ from playwright.async_api import async_playwright
15
+ from worker_automate_hub.api.client import get_config_by_name
16
+ from worker_automate_hub.utils.util import capture_and_send_screenshot, kill_all_emsys
17
+
18
+ logger = Console()
19
+
20
+
21
+ async def inclusao_pedidos_vibra(task: RpaProcessoEntradaDTO):
22
+ try:
23
+ await kill_all_emsys()
24
+ config_entrada = task.configEntrada
25
+ #Collect configs
26
+ config = await get_config_by_name("ConsultaPreco")
27
+ config = config.conConfiguracao
28
+ async with async_playwright() as p:
29
+ logger.print("Starting Browser")
30
+ browser = await p.chromium.launch(
31
+ headless=False,
32
+ args=[
33
+ "--disable-blink-features=AutomationControlled",
34
+ "--no-sandbox",
35
+ "--disable-dev-shm-usage",
36
+ "--disable-gpu",
37
+ "--disable-infobars",
38
+ "--window-size=1920,1080"
39
+ ]
40
+ )
41
+ page = await browser.new_page()
42
+ await page.set_viewport_size({"width": 1850, "height": 900})
43
+ await page.goto(config.get('url_vibra'), wait_until="load")
44
+ #Login
45
+ await page.wait_for_load_state('load')
46
+ try:
47
+ await page.locator('//*[@id="usuario"]').type(config.get('login_vibra'))
48
+ await page.locator('//*[@id="senha"]').type(config.get('pass_vibra'))
49
+ await page.locator('//*[@id="btn-acessar"]').click()
50
+ await asyncio.sleep(20)
51
+ except Exception as e:
52
+ raise Exception("An error occurred: Erro ao efetuar login")
53
+ await page.wait_for_load_state('load')
54
+ await page.wait_for_selector("#img-menu-open", timeout=50000)
55
+ selector = '.btn.btn-informativo'
56
+ counter = 0
57
+ count = await page.locator(selector).count()
58
+ while counter < count:
59
+ count = await page.locator(selector).count()
60
+ if count == 0:
61
+ break
62
+ for i in range(count):
63
+ try:
64
+ button = page.locator(selector).nth(i)
65
+ await button.scroll_into_view_if_needed(timeout=1000)
66
+ await button.click(force=True, timeout=1000)
67
+ await asyncio.sleep(1)
68
+ except Exception as e:
69
+ continue
70
+ counter += 1
71
+ await asyncio.sleep(1)
72
+
73
+ try:
74
+ try:
75
+ await page.locator('//*[@id="img-menu-open"]').click()
76
+ except:
77
+ await page.locator('//*[@id="btnMenu"]').click()
78
+ await asyncio.sleep(1)
79
+ await page.locator('//*[@id="menu"]/div/div[2]/ul/li[4]').hover()
80
+ await asyncio.sleep(1)
81
+ await page.locator('//*[@id="menu"]/div/div[2]/ul/li[4]/ul/li[5]/a').click()
82
+ except Exception as e:
83
+ await capture_and_send_screenshot(task.historico_id, "Erro")
84
+ raise Exception("An error occurred: Erro ao abrir menu")
85
+ await asyncio.sleep(20)
86
+ logger.print("Selecting company")
87
+ #Getting cod SAP
88
+ try:
89
+ cod_sap_relation = await get_config_by_name('vibraCodSapRelation')
90
+ cod_sap_relation = cod_sap_relation.conConfiguracao
91
+ cnpj = config_entrada.get('cnpjEmpresa')
92
+ #Selecting company by CodSAP
93
+ await page.wait_for_selector("select[name='filtroCodigoLogin']", state="visible", timeout=60000)
94
+ await page.select_option("select[name='filtroCodigoLogin']", cod_sap_relation[cnpj], timeout=60000)
95
+ except:
96
+ await capture_and_send_screenshot(task.historico_id, "Erro")
97
+ raise Exception("An error occurred: Erro ao selecionar empresa")
98
+ await page.locator('//*[@id="conteudo"]/div/form[1]/div/table[2]/tbody/tr/td/input').click()
99
+ await page.wait_for_selector('//*[@id="conteudo"]/div/form[2]/div/table[2]/tbody/tr[2]/td[1]/input[1]')
100
+ texto = await page.locator('tr td.result_bold').nth(0).inner_text()
101
+ await page.locator('//*[@id="conteudo"]/div/form[2]/div/table[2]/tbody/tr[2]/td[1]/input[1]').click()
102
+ await asyncio.sleep(1)
103
+ logger.print("Confirming")
104
+ await page.locator('//*[@id="conteudo"]/div/form[2]/div/table[1]/tbody/tr/td/input[1]').click()
105
+ texto_atual = await page.locator('span.info-cliente.hidden-xs').inner_text()
106
+ if texto not in texto_atual:
107
+ await capture_and_send_screenshot(task.historico_id, "Erro")
108
+ raise Exception("An error occurred: Não foi possivel selecionar a empresa para realizer pedido de combustivel.")
109
+ logger.print("Clicking Pedidos")
110
+ await page.locator('//*[@id="menuAcessoRevendedorPedidos"]').click()
111
+ await asyncio.sleep(10)
112
+ #Cleaning cart
113
+ try:
114
+ await page.goto("https://cn.vibraenergia.com.br/central-de-pedidos/#/meu-carrinho")
115
+ await asyncio.sleep(6)
116
+ #Cleaning cart
117
+ await page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-meu-carrinho/div/div[1]/app-carrinho/div/div[2]/div/button[2]/span[1]/mat-icon').click()
118
+ await asyncio.sleep(6)
119
+ except:
120
+ await page.goto('https://cn.vibraenergia.com.br/central-de-pedidos/#/vitrine')
121
+ await page.wait_for_load_state('load')
122
+ logger.print("Selecting Base")
123
+ base_ralation = await get_config_by_name("relacaoBaseVibra")
124
+ base_ralation = base_ralation.conConfiguracao
125
+ base = base_ralation[config_entrada['baseNome']]
126
+ try:
127
+ logger.print(f"{base}")
128
+ await page.wait_for_selector('input[formcontrolname="base"]', state="visible", timeout=60000)
129
+ await page.locator('input[formcontrolname="base"]').click()
130
+ await page.wait_for_load_state('load')
131
+ await asyncio.sleep(3)
132
+ await page.locator('.md-icons.adicionar-bases-icon').click()
133
+ await page.wait_for_load_state('load')
134
+ await asyncio.sleep(3)
135
+ base_selection = page.locator('.mat-option-text', has_text=base)
136
+ await base_selection.scroll_into_view_if_needed()
137
+ await asyncio.sleep(3)
138
+ await base_selection.click()
139
+ await page.wait_for_load_state('load')
140
+ await asyncio.sleep(4)
141
+ except:
142
+ await capture_and_send_screenshot(task.historico_id, "Erro")
143
+ raise Exception("An error occurred: Erro ao selecionar base")
144
+ logger.print("Getting configuration")
145
+ xpaths = await get_config_by_name('vibraXpathCombustiveis')
146
+ xpaths = xpaths.conConfiguracao
147
+ try:
148
+ for fuel in config_entrada['combustiveis']:
149
+ if fuel['uuidItem'] in xpaths:
150
+ try:
151
+ logger.print('Collecting Carrossel')
152
+ carrossel = page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]')
153
+ xpath = xpaths[fuel['uuidItem']]
154
+ fuel_card = carrossel.locator(xpath)
155
+ await fuel_card.scroll_into_view_if_needed()
156
+ try:
157
+ warning_msg = await fuel_card.locator('.warning', has_text="restrição").inner_text()
158
+ if 'restrição' in warning_msg:
159
+ await capture_and_send_screenshot(task.historico_id, "Erro")
160
+ return RpaRetornoProcessoDTO(
161
+ sucesso=False,
162
+ retorno=f"{warning_msg} | {fuel['descricaoProduto']}",
163
+ status=RpaHistoricoStatusEnum.Falha,
164
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico), RpaTagDTO(descricao=RpaTagEnum.Negocio)],
165
+ )
166
+ except:
167
+ pass
168
+ card = fuel_card.filter(has=page.locator('button:not([disabled])', has_text="Adicionar"))
169
+ await card.scroll_into_view_if_needed()
170
+ await card.locator('button:not([disabled])', has_text="Adicionar").click()
171
+ except:
172
+ try:
173
+ logger.print('Collecting Carrossel 2')
174
+ carrossel = page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]')
175
+ await carrossel.locator('mat-icon:has-text("chevron_right")').click()
176
+ carrossel = page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]')
177
+ fuel_card = carrossel.locator(xpath)
178
+ card = fuel_card.filter(has=page.locator('button:not([disabled])', has_text="Adicionar")).first
179
+ await card.scroll_into_view_if_needed()
180
+ await card.locator(
181
+ "button:not([disabled])", has_text="Adicionar"
182
+ ).click()
183
+ except:
184
+ try:
185
+ logger.print("Collecting Carrossel 2")
186
+ carrossel = page.locator(
187
+ '//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]'
188
+ )
189
+ await carrossel.locator(
190
+ 'mat-icon:has-text("chevron_right")'
191
+ ).click()
192
+ carrossel = page.locator(
193
+ '//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]'
194
+ )
195
+ fuel_card = carrossel.locator(xpath)
196
+ card = fuel_card.filter(
197
+ has=page.locator(
198
+ "button:not([disabled])",
199
+ has_text="Adicionar",
200
+ )
201
+ ).first
202
+ await card.scroll_into_view_if_needed()
203
+ await card.locator(
204
+ "button:not([disabled])", has_text="Adicionar"
205
+ ).click()
206
+ except:
207
+ logger.print('Collecting Carrossel 3')
208
+ carrossel = page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]')
209
+ await carrossel.locator('mat-icon:has-text("chevron_left")').click()
210
+ carrossel = page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-vitrine/div/div[3]/div[4]/div[2]/app-carrosel-produtos/div/div[1]')
211
+ fuel_card = carrossel.locator(xpath)
212
+ card = fuel_card.filter(has=page.locator('button:not([disabled])', has_text="Adicionar")).first
213
+ await card.scroll_into_view_if_needed()
214
+ await card.locator('button:not([disabled])', has_text="Adicionar").click()
215
+ except:
216
+ await capture_and_send_screenshot(task.historico_id, "Erro")
217
+ raise Exception("An error occurred: Nao foi possivel selecionar combustivel")
218
+ #Go to Cart
219
+ await asyncio.sleep(5)
220
+ await page.locator('//*[@id="user"]/app-root/div[1]/div[1]/cn-header/header/div/div[4]/div/i').click()
221
+ await asyncio.sleep(10)
222
+ #Fill Date
223
+ await page.get_by_role("button", name="Open calendar").click()
224
+ #Get Calendar
225
+ await asyncio.sleep(1)
226
+ await page.wait_for_selector(".cdk-overlay-pane mat-calendar")
227
+ date = config_entrada['dataRetirada']
228
+ date = datetime.fromisoformat(date)
229
+ date_day = str(date.day)
230
+ today = datetime.now()
231
+ if date.month > today.month:
232
+ #change month
233
+ await page.get_by_label("Next month").click()
234
+ await asyncio.sleep(1)
235
+ await page.locator(f".mat-calendar-body-cell-content:text-is('{date_day}')").click()
236
+ await page.keyboard.press("Escape")
237
+ await asyncio.sleep(10)
238
+ #Collect Cards in cart
239
+ items = page.locator("app-accordion-item-carrinho")
240
+ count = await items.count()
241
+ consulta_preco = await get_config_by_name('ConsultaPrecoCombustiveisIds')
242
+ consulta_preco = consulta_preco.conConfiguracao["CombustiveisIds"]
243
+ logger.print(f"Found {count} items in cart")
244
+ await asyncio.sleep(5)
245
+ for i in range(count):
246
+ logger.print(f"Collecting name of item {i}")
247
+ item = items.nth(i)
248
+ nome = (await item.locator(".produto-nome").inner_text()).strip()
249
+ logger.print(f"Collecting {nome}")
250
+ # Find config by fuel name
251
+ config_item = next((c for c in consulta_preco if c['descricaoVibra'].lower() == nome.lower()), None)
252
+ if not config_item:
253
+ continue
254
+ # Find fuel by UUID
255
+ fuel = next((f for f in config_entrada['combustiveis'] if f['uuidItem'] == config_item['uuid']), None)
256
+ if not fuel:
257
+ continue
258
+ await item.locator("input[formcontrolname='quantidade']").fill("")
259
+ await item.locator("input[formcontrolname='quantidade']").fill(str(fuel['quantidade']))
260
+ await item.locator("input[formcontrolname='quantidade']").press("Escape")
261
+ prazo_select_trigger = item.locator("mat-select[formcontrolname='prazo']")
262
+ await prazo_select_trigger.scroll_into_view_if_needed()
263
+ await prazo_select_trigger.click()
264
+ await asyncio.sleep(5)
265
+ await page.wait_for_selector("mat-option", timeout=5000)
266
+ try:
267
+ if config_entrada['diasFaturamento'] == 1:
268
+ option = page.locator("mat-option .mat-option-text", has_text="1 Dia").first
269
+ else:
270
+ option = page.locator("mat-option .mat-option-text", has_text=f"{str(config_entrada['diasFaturamento'])} Dias").first
271
+ except:
272
+ await capture_and_send_screenshot(task.historico_id, "Erro")
273
+ raise Exception(f"Opção de {str(config_entrada['diasFaturamento'])} Dia(s) não encontrada")
274
+ await option.scroll_into_view_if_needed()
275
+ # await option.click()
276
+ await option.evaluate("(el) => el.click()")
277
+ await asyncio.sleep(10)
278
+ #Confirm order
279
+ try:
280
+ msg = page.locator("text=Volume solicitado acima")
281
+ msg.scroll_into_view_if_needed()
282
+ if await msg.is_visible():
283
+ texto = await msg.inner_text()
284
+ await capture_and_send_screenshot(task.historico_id, "Erro")
285
+ raise Exception(texto)
286
+ except Exception as e:
287
+ raise Exception(e)
288
+ try:
289
+ await page.wait_for_selector('//*[@id="user"]/app-root/div[2]/div/div/app-meu-carrinho/div/div[1]/app-carrinho/div/div[2]/button')
290
+ await page.locator('//*[@id="user"]/app-root/div[2]/div/div/app-meu-carrinho/div/div[1]/app-carrinho/div/div[2]/button').click()
291
+ await asyncio.sleep(5)
292
+ except:
293
+ await capture_and_send_screenshot(task.historico_id, "Erro")
294
+ raise Exception("Falha ao confirmar pedido")
295
+ #Close Satisfaction Survey
296
+ try:
297
+ logger.print("Closing satisfaction survey")
298
+ await page.locator('//*[@id="mat-dialog-2"]/lib-cn-pesquisa-satisfacao/div/i', timeout=1000).click()
299
+ except:
300
+ logger.print("No satisfaction survey found")
301
+ pass
302
+ await asyncio.sleep(10)
303
+ #Collect order details
304
+ logger.print("Collecting order details")
305
+ numero_pedido = None
306
+ for _ in range(5):
307
+ try:
308
+ success_message = page.locator("div.sucesso span").first
309
+ success_message = await success_message.inner_text()
310
+ if "sucesso" in success_message:
311
+ success_message = success_message.strip()
312
+ logger.print(success_message)
313
+ numero_pedido = re.search(r"\d+", success_message).group()
314
+ break
315
+ else:
316
+ await capture_and_send_screenshot(task.historico_id, "Erro")
317
+ raise Exception(f"Site nao retornou sucesso ao realizar pedido: {str(success_message)}")
318
+ except Exception as e:
319
+ logger.print(f"An error occurred: {e}")
320
+ await asyncio.sleep(7)
321
+ continue
322
+ if not numero_pedido:
323
+ await capture_and_send_screenshot(task.historico_id, "Erro")
324
+ raise Exception("Erro ao coletar numero do pedido")
325
+ bof = {
326
+ 'numero_pedido' : numero_pedido,
327
+ 'cnpj': config_entrada["cnpjEmpresa"],
328
+ 'data': date.strftime('%d/%m/%Y')
329
+ }
330
+ await capture_and_send_screenshot(task.historico_id, "Sucesso ao realizar pedido!")
331
+ await browser.close()
332
+ return RpaRetornoProcessoDTO(
333
+ sucesso=True,
334
+ retorno=str(bof),
335
+ status=RpaHistoricoStatusEnum.Sucesso)
336
+ except Exception as e:
337
+ logger.print(f"An error occurred: {e}")
338
+ return RpaRetornoProcessoDTO(
339
+ sucesso=False,
340
+ retorno=f"An error occurred: {e}",
341
+ status=RpaHistoricoStatusEnum.Falha,
342
+ tags=[RpaTagDTO(descricao=RpaTagEnum.Tecnico), RpaTagDTO(descricao=RpaTagEnum.Negocio)],
343
+ )
344
+ finally:
345
+ await browser.close()