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,223 @@
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 date, 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_ipiranga(task: RpaRetornoProcessoDTO):
22
+ try:
23
+ config_entrada = task.configEntrada
24
+ await kill_all_emsys()
25
+ # Collect configs
26
+ config_entrada = task.configEntrada
27
+ config = await get_config_by_name("ConsultaPreco")
28
+ config = config.conConfiguracao
29
+ async with async_playwright() as p:
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
+
44
+ # Going to Main page
45
+ logger.print(f"Navigating to {config.get('url_ipiranga')}")
46
+ await page.goto(config.get("url_ipiranga"), wait_until="load")
47
+ # Wait page load
48
+ await page.wait_for_load_state('load')
49
+ # Wait for login
50
+ await page.wait_for_selector('[title="Login"]', timeout=90000)
51
+
52
+ # Login
53
+ logger.print(f"Logging")
54
+ login = config.get("login_ipiranga2") if config_entrada.get("cnpjEmpresa") == "07473735017661" else config.get("login_ipiranga")
55
+ await page.locator('[title="Login"]').type(login)
56
+ await page.locator('[type="password"]').type(config.get("pass_ipiranga"))
57
+ await page.locator('[type="submit"]').click()
58
+ try:
59
+ await asyncio.sleep(5)
60
+ warn = await page.wait_for_selector(
61
+ "//ul[contains(@style, '#ffd000')]/li[contains(text(), 'Usuário ou senha incorretos.')]",
62
+ timeout=10000,
63
+ )
64
+ if warn:
65
+ logger.print("Login failed. Verify username and password.")
66
+ await capture_and_send_screenshot(task.historico_id, "Erro")
67
+ raise Exception("Falha ao Logar no site.")
68
+ except:
69
+ logger.print("Login successful")
70
+
71
+ # Warn to change password
72
+ try:
73
+ await page.wait_for_selector(
74
+ '//*[@id="viewns_Z7_LA04H4G0POLN00QRBOJ72420P5_:form_lembrar:j_id_e"]',
75
+ timeout=5000,
76
+ )
77
+ await page.locator(
78
+ '//*[@id="viewns_Z7_LA04H4G0POLN00QRBOJ72420P5_:form_lembrar:j_id_e"]'
79
+ ).click()
80
+ except:
81
+ logger.print("No warning message.")
82
+
83
+ # Wait and accept cookies
84
+ logger.print("Identifiying cookies message")
85
+ await page.wait_for_selector("#onetrust-accept-btn-container")
86
+ try:
87
+ await page.locator("#onetrust-accept-btn-container").click()
88
+ except:
89
+ logger.print("Cookies already accepted.")
90
+ # Wait and close warning message
91
+ try:
92
+ await page.wait_for_selector(".newclose", timeout=10000)
93
+ await page.locator(".newclose").click()
94
+ except:
95
+ logger.print("No warning message.")
96
+
97
+ try:
98
+ await page.wait_for_selector("img.fechar", timeout=10000)
99
+ await page.locator("img.fechar").click()
100
+ except:
101
+ logger.print("No Ads message.")
102
+ cnpj_atual = await page.locator(".usuario_cnpj.mb-0").first.text_content()
103
+ if not config_entrada.get("cnpjEmpresa") in cnpj_atual:
104
+ # Select Gas Station
105
+ await page.wait_for_selector(".usuario_img", timeout=90000)
106
+ await page.locator(".usuario_img").first.click()
107
+ # Fill the station
108
+ logger.print("Selecting gas station")
109
+ change_station = page.locator('//*[@id="trocaMuitosPostosModal"]/div[2]/div/div')
110
+ await change_station.locator('[type="text"]').first.type(config_entrada.get("cnpjEmpresa"))
111
+ # cnpj = config_entrada.get("cnpjEmpresa")
112
+ # await page.locator(f'li[data-cdpessptoecli="{cnpj}"]').click()
113
+ await asyncio.sleep(3)
114
+ await change_station.get_by_text("Trocar", exact=True).locator("visible=true").click()
115
+
116
+
117
+ await asyncio.sleep(5)
118
+ logger.print("Going to order page")
119
+ await page.goto(
120
+ "https://www.redeipiranga.com.br/wps/myportal/redeipiranga/pedidos/combustivel/registrarpedido/",
121
+ wait_until="load",
122
+ )
123
+ await asyncio.sleep(5)
124
+ # Get Iframe to collect locators
125
+ iframe = page.frame_locator('//*[@id="ns_Z7_LA04H4G0P0FDB061C74LHG2G17__content-frame"]')
126
+ await asyncio.sleep(20)
127
+ bases = await get_config_by_name("ipirangaBasesValue")
128
+ bases = bases.conConfiguracao
129
+ # Change Base
130
+ try:
131
+ base = bases[config_entrada["baseNome"]]
132
+ # await page.locator('//*[@id="frmPedido"]/section[1]/div[3]/div[1]/select').select_option(value=base)
133
+ await iframe.locator("select[name='codigoDependencia']").select_option(value=base)
134
+ await asyncio.sleep(2)
135
+
136
+ except:
137
+ await capture_and_send_screenshot(task.historico_id, "Erro")
138
+ raise Exception("Base não encontrada")
139
+ # Fill Fuels
140
+ logger.print("Filling Fuels")
141
+ await asyncio.sleep(2)
142
+ combusutiveis_ids = await get_config_by_name("ConsultaPrecoCombustiveisIds")
143
+ combusutiveis_ids = combusutiveis_ids.conConfiguracao["CombustiveisIds"]
144
+ xpath_ids = await get_config_by_name("ipirangaXpathCombustiveis")
145
+ xpath_ids = xpath_ids.conConfiguracao
146
+ for combustivel in config_entrada["combustiveis"]:
147
+ for id in combusutiveis_ids:
148
+ if id["uuid"] == combustivel["uuidItem"]:
149
+ fuel = iframe.locator(
150
+ f'.combustivel_box.clTrProdutos:has-text("{id['descricaoIpiranga']}")'
151
+ )
152
+ try:
153
+ indisponivel = await fuel.locator(
154
+ ".texto-indisponivel", timemout=5000
155
+ ).text_content()
156
+ if indisponivel:
157
+ await capture_and_send_screenshot(task.historico_id, "Erro")
158
+ raise Exception(f"{indisponivel}")
159
+ except:
160
+ pass
161
+ await fuel.locator(f'input[name="quantidade"]').fill(
162
+ str(combustivel["quantidade"])
163
+ )
164
+ await fuel.locator(f'input[name="quantidade"]').press("Tab")
165
+ # Next
166
+ logger.print("Going to next page")
167
+ await iframe.locator(
168
+ 'a[href="javascript:avancar()"]:has-text("Avançar")'
169
+ ).click()
170
+ await asyncio.sleep(5)
171
+ # Finish Order
172
+ logger.print("Finishing order")
173
+ await page.wait_for_selector(
174
+ "iframe#ns_Z7_LA04H4G0P0FDB061C74LHG2G17__content-frame"
175
+ )
176
+ iframe_final = page.frame_locator(
177
+ "iframe#ns_Z7_LA04H4G0P0FDB061C74LHG2G17__content-frame"
178
+ )
179
+ btn_finish = iframe_final.locator('button:has-text("Finalizar pedido")')
180
+ await btn_finish.scroll_into_view_if_needed()
181
+ await btn_finish.click(force=True)
182
+
183
+ await asyncio.sleep(30)
184
+ finish_iframe = page.frame_locator(
185
+ '//*[@id="ns_Z7_LA04H4G0P0FDB061C74LHG2G17__content-frame"]'
186
+ )
187
+ element = finish_iframe.locator(".titulo.titulo-area")
188
+ await element.scroll_into_view_if_needed()
189
+ text = await element.text_content()
190
+ text = " ".join(text.split())
191
+ numero_pedido = re.findall(r"\d+", text)
192
+ date = config_entrada["dataRetirada"]
193
+ date = datetime.fromisoformat(date)
194
+ if "sucesso" in text:
195
+ bof = {
196
+ "numero_pedido": numero_pedido[0],
197
+ "cnpj": config_entrada["cnpjEmpresa"],
198
+ "data": date.strftime("%d/%m/%Y"),
199
+ }
200
+ await capture_and_send_screenshot(
201
+ task.historico_id, "Sucesso ao realizar pedido!"
202
+ )
203
+ return RpaRetornoProcessoDTO(
204
+ sucesso=True,
205
+ retorno=str(bof),
206
+ status=RpaHistoricoStatusEnum.Sucesso,
207
+ )
208
+ else:
209
+ await capture_and_send_screenshot(task.historico_id, "Erro")
210
+ raise Exception(f"Erro ao realizar pedido: {text}")
211
+ except Exception as e:
212
+ logger.print(f"An error occurred: {e}")
213
+ return RpaRetornoProcessoDTO(
214
+ sucesso=False,
215
+ retorno=f"An error occurred: {e}",
216
+ status=RpaHistoricoStatusEnum.Falha,
217
+ tags=[
218
+ RpaTagDTO(descricao=RpaTagEnum.Tecnico),
219
+ RpaTagDTO(descricao=RpaTagEnum.Negocio),
220
+ ],
221
+ )
222
+ finally:
223
+ await browser.close()
@@ -0,0 +1,187 @@
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 date, datetime
13
+ import re
14
+ from playwright.async_api import async_playwright
15
+ from worker_automate_hub.api.client import get_config_by_name, get_mfa_code
16
+ from worker_automate_hub.utils.util import capture_and_send_screenshot, kill_all_emsys
17
+
18
+ logger = Console()
19
+
20
+ async def inclusao_pedidos_raizen(task: RpaRetornoProcessoDTO):
21
+ try:
22
+ await kill_all_emsys()
23
+ config_entrada = task.configEntrada
24
+ #Collect configs
25
+ config = await get_config_by_name("ConsultaPreco")
26
+ config = config.conConfiguracao
27
+ async with async_playwright() as p:
28
+ browser = await p.chromium.launch(headless=False, args=[
29
+ "--disable-blink-features=AutomationControlled",
30
+ "--no-sandbox",
31
+ "--disable-dev-shm-usage",
32
+ "--disable-gpu",
33
+ "--disable-infobars",
34
+ "--window-size=1920,1080"])
35
+
36
+ page = await browser.new_page()
37
+ await page.set_viewport_size({"width": 1850, "height": 900})
38
+ #Going to Main page
39
+ logger.print(f"Navigating to {config.get('url_raizen')}")
40
+ await page.goto(config.get('url_raizen'), wait_until="networkidle")
41
+ await page.wait_for_load_state('load')
42
+ #Login
43
+ logger.print(f"Logging")
44
+ await page.locator("#signInName").type(config.get('login_raizen'))
45
+ await page.locator("#password").type(config.get('pass_raizen'))
46
+ await page.locator("#next").click()
47
+
48
+ logger.print("Waiting for verification code")
49
+ logger.print("Sending verification code")
50
+ await page.locator("#readOnlyEmail_ver_but_send").click()
51
+ await page.wait_for_load_state('load')
52
+ await asyncio.sleep(60)
53
+ #chamar endpoint com código retornado
54
+ code = await get_mfa_code('mfa-raizen')
55
+ if code['status_code'] == 200:
56
+ await page.locator('//*[@id="readOnlyEmail_ver_input"]').type(str(code['code']))
57
+ await page.locator('//*[@id="readOnlyEmail_ver_but_verify"]').click()
58
+ else:
59
+ await capture_and_send_screenshot(task.historico_id, "Erro MFA")
60
+ raise Exception("Failed to retrieve MFA code")
61
+
62
+ # Select Company
63
+ logger.print("Selecting company")
64
+ relacao_cod_raizen = await get_config_by_name("RelacaoCodigosRaizen")
65
+ relacao_cod_raizen = relacao_cod_raizen.conConfiguracao
66
+ await page.wait_for_load_state('load')
67
+ await page.wait_for_selector('//*[@id="api"]/div/form/div[2]/app-select/div/div', state="visible")
68
+ await page.locator('//*[@id="api"]/div/form/div[2]/app-select/div/div').click()
69
+ cod_cnpj = str(relacao_cod_raizen[config_entrada['cnpjEmpresa']]).lstrip('0')
70
+ element = page.locator(f'text="{cod_cnpj} - SIM REDE DE POSTOS LTDA"')
71
+ await element.scroll_into_view_if_needed()
72
+ await element.click()
73
+ await page.locator('//*[@id="undefined"]').click()
74
+ await page.wait_for_load_state('load')
75
+ try:
76
+ await asyncio.sleep(5)
77
+ await page.locator("label.cso-radio-option:has-text('Combustíveis Claros')").click()
78
+ await page.locator("button span:has-text('Acessar')").click()
79
+ except:
80
+ logger.print("Radio button already selected or not available")
81
+ await asyncio.sleep(10)
82
+
83
+ await asyncio.sleep(15)
84
+ try:
85
+ await page.locator(".messages__popup__button_ok").click()
86
+ except:
87
+ pass
88
+ logger.print("Navegating to orders page")
89
+ await page.goto('https://portal.csonline.com.br/#/ordersfuels', wait_until="load")
90
+ await asyncio.sleep(5)
91
+ #Select Liters
92
+ logger.print("Selecting Liters")
93
+ litro_radio = page.locator("#orders-fuels-input-radio-L")
94
+ await litro_radio.wait_for(state='visible')
95
+ if not await litro_radio.is_checked():
96
+ await litro_radio.click()
97
+ await page.wait_for_timeout(10000)
98
+ await page.locator('//*[@id="undefined"]').click()
99
+ # Base
100
+ try:
101
+ logger.print("Selecting base")
102
+ rel_base_raizen = await get_config_by_name("relacaoBaseRaizen")
103
+ rel_base_raizen = rel_base_raizen.conConfiguracao
104
+ base_nome = rel_base_raizen[config_entrada['baseNome']]
105
+ await page.locator('//*[@id="orders-fuels-div-dropdown-withdrawal-place"]').click()
106
+ await page.locator(f'//*[contains(text(), "{base_nome}")]').click()
107
+ except:
108
+ await capture_and_send_screenshot(task.historico_id, "Erro ao selecionar base")
109
+ raise Exception("Erro ao selecionar base")
110
+ # Date
111
+ try:
112
+ logger.print("Selecting date")
113
+ date = config_entrada['dataRetirada']
114
+ date = datetime.fromisoformat(date)
115
+ date = date.strftime("%d/%m/%Y")
116
+ input_elem = page.locator("#orders-fuels-div-calendar-datepicker")
117
+ await input_elem.evaluate("(el, value) => { el.removeAttribute('readonly'); el.value = value; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); }", date)
118
+ except:
119
+ await capture_and_send_screenshot(task.historico_id, "Erro ao realizar pedido!")
120
+ raise Exception("Erro ao selecionar data")
121
+ # Veichle Sign
122
+ try:
123
+ logger.print("Selecting vehicle sign")
124
+ await page.locator('//*[@id="orders-fuels-div-dropdown-plate-place-button"]').click()
125
+ await page.locator('//*[@id="orders-fuels-div-dropdown-plate-place-button"]').fill(config_entrada["placaVeiculo"].upper())
126
+ await page.locator(f'//*[contains(text(), "{config_entrada["placaVeiculo"]}")]').click()
127
+ except:
128
+ await capture_and_send_screenshot(task.historico_id, "Erro ao selecionar placa do veiculo")
129
+ raise Exception("Erro ao selecionar placa do veiculo")
130
+ #Fill Fuels
131
+ try:
132
+ logger.print("Filling Fuels")
133
+ combusutiveis_ids = await get_config_by_name('ConsultaPrecoCombustiveisIds')
134
+ combusutiveis_ids = combusutiveis_ids.conConfiguracao
135
+ xpath_ids = await get_config_by_name('raizenXpathCombustiveis')
136
+ xpath_ids = xpath_ids.conConfiguracao
137
+ for combustivel in config_entrada['combustiveis']:
138
+ combustivel_uuid = combustivel['uuidItem']
139
+ xpath = xpath_ids[combustivel_uuid]
140
+ await page.locator(xpath).fill(str(combustivel['quantidade']))
141
+ await page.locator(xpath).click()
142
+ except:
143
+ await capture_and_send_screenshot(task.historico_id, "Erro preenchendo combustiveis")
144
+ raise Exception("Erro ao preencher combustiveis")
145
+ # Save order
146
+ logger.print("Saving order")
147
+ await page.locator('//*[@id="orders-fuels-button-save"]').click()
148
+ await asyncio.sleep(10)
149
+ try:
150
+ logger.print("Confirming order")
151
+ await page.get_by_text("Continuar mesmo assim").click()
152
+ except:
153
+ pass
154
+ await page.wait_for_load_state('load')
155
+ #Get order number
156
+ await asyncio.sleep(10)
157
+ numero_elem = page.locator('//span[contains(@class, "status__order-number__value")]')
158
+ numero_pedido = ( await numero_elem.inner_text()).strip()
159
+ if not numero_pedido:
160
+ await capture_and_send_screenshot(task.historico_id,"Número do pedido não encontrado!")
161
+ raise Exception("Número do pedido não encontrado!")
162
+ date = config_entrada["dataRetirada"]
163
+ date = datetime.fromisoformat(date)
164
+ bof = {
165
+ "numero_pedido": numero_pedido,
166
+ "cnpj": config_entrada["cnpjEmpresa"],
167
+ "data": date.strftime("%d/%m/%Y"),
168
+ }
169
+ await capture_and_send_screenshot(task.historico_id, "Sucesso ao realizar pedido!")
170
+ return RpaRetornoProcessoDTO(
171
+ sucesso=True,
172
+ retorno=str(bof),
173
+ status=RpaHistoricoStatusEnum.Sucesso,
174
+ )
175
+ except Exception as e:
176
+ logger.print(f"An error occurred: {e}")
177
+ return RpaRetornoProcessoDTO(
178
+ sucesso=False,
179
+ retorno=f"An error occurred: {e}",
180
+ status=RpaHistoricoStatusEnum.Falha,
181
+ tags=[
182
+ RpaTagDTO(descricao=RpaTagEnum.Tecnico),
183
+ RpaTagDTO(descricao=RpaTagEnum.Negocio),
184
+ ],
185
+ )
186
+ finally:
187
+ await browser.close()