diff --git a/Dimensao.csv b/Dimensao.csv new file mode 100644 index 0000000..1067448 --- /dev/null +++ b/Dimensao.csv @@ -0,0 +1,57 @@ +codigo,descricao,cpf_gr,gerencia,cpf_sup,sup,gerencia_loja,estado +3546,SAM'S CLUB FAROL,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Carla Lima,ALAGOAS +4560,MCZ SH. TERREO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Rosilane Pagamonha,ALAGOAS +5699,MOREIRA LIMA,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Solange Bezerra,ALAGOAS +12522,MCZ SH. EXP.,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Betina Melo,ALAGOAS +12817,SH. PATIO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Pamella Barbosa,ALAGOAS +12818,GB. SERRARIA,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +12820,ATACADÃO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Pamella Barbosa,ALAGOAS +12823,PONTA VERDE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Felipe Barros,ALAGOAS +12824,GB. TABULEIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +12826,ASSAÍ MANGABEIRAS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Grasiele Oliveira,ALAGOAS +12828,GB. STELLA MARIS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Grasiele Oliveira,ALAGOAS +12829,JACINTINHO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Manoela Araújo,ALAGOAS +12830,LIVRAMENTO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Solange Bezerra,ALAGOAS +12838,RIO LARGO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Maria Jucelia,ALAGOAS +13427,SHOPPING CIDADE,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Thiana Melo,ALAGOAS +14617,PARQUE SHOPPING,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Synara Morais,ALAGOAS +19103,UNICOMPRA,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Felipe Barros,ALAGOAS +20858,SUPER GIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Rayzha Moreira,ALAGOAS +20969,MAR. DEODORO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Maria Gabriela,ALAGOAS +20991,CAMPO ALEGRE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Daliane Santos,ALAGOAS +21647,CARAJAS,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Betina Melo,ALAGOAS +21624,MIX MATEUS,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Rayzha Moreira,ALAGOAS +910173,QDB PARQUE,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Débora Araújo,ALAGOAS +910291,QDB MACEIO,64774937487,Raquel Tenório,1009194488,Efigênia Herculano,Débora Araújo,ALAGOAS +21007,TÔ QUE TÔ,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Thiana Melo,ALAGOAS +20998,CD TABULEIRO,64774937487,Raquel Tenório,2522564412,Anna Schelly,----,ALAGOAS +20005,CANDEIAS CIMA,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Juliana Cerqueira,BAHIA +20006,SÃO SEBASTIÃO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +20009,CANDEIAS BAIXO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Juliana Cerqueira,BAHIA +20056,SIMÕES FILHO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +20057,CONC. DO COITE,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Vanuzia,BAHIA +20986,OLINDINA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Aniele Souza,BAHIA +20988,QUEIMADAS,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Genivia,BAHIA +20989,ENTRE RIOS,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Ione de Souza,BAHIA +20999,ESPLANADA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Ione de Souza,BAHIA +21000,SANTALUZ,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Jessica,BAHIA +21001,RIO REAL,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,Aniele Souza,BAHIA +21068,ATAKAREJO,1819238580,Arianne Sodré,88708365504,Fernanda Vieira,Laiane Martins,BAHIA +21375,IPIRA,1819238580,Arianne Sodré,79215424504,Cláudia Fontes,----,BAHIA +21381,CAPIM GROSSO,1819238580,Arianne Sodré,81834993504,Juliana Vasconcelos,VR Mirlane,BAHIA +20441,LAGARTO,1472167538,Luciana Amaral,3961945594,Taciana,Damila Matos,SERGIPE +20968,ITABAIANINHA,1472167538,Luciana Amaral,3961945594,Taciana,Verônica Abril,SERGIPE +21277,GB. SOCORRO,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +21296,SH. PRM. SOCORRO,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +21495,B. COQUEIROS,1472167538,Luciana Amaral,736514511,Carla Melo,Patrícia Maria,SERGIPE +23475,MIX TABULEIRO,64774937487,Raquel Tenório,910362408,Maxwell Vieira,Laura Ruiz,ALAGOAS +23702,PANVICON,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23701,9 DE NOVEMBRO,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23665,SHOPPING BOULEVARD,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23709,SHOPPING CONQUISTA SUL,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23712,CANDIDO SALES,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23713,ZEFERINO CORREIA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23707,BAIRRO BRASIL,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23705,SHOPPING CONQUISTA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC +23708,BARRA DO CHOÇA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Camilla Oliveira,VDC +23706,ASSAI VITÓRIA DA CONQUISTA,1819238580,Arianne Sodré,1819238580,Arianne Sodré,Lucimara Ferreira,VDC diff --git a/README.md b/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/busca_pdv.py b/busca_pdv.py new file mode 100644 index 0000000..5ef59b0 --- /dev/null +++ b/busca_pdv.py @@ -0,0 +1,21 @@ +import pandas as pd + +def extract_data(file): + consultoras = pd.read_excel(f"{file}", sheet_name="PDV") + consultoras.drop(index=1, inplace=True) + consultoras.columns = consultoras.iloc[0] + consultoras.drop(index=0, inplace=True) + consultoras= consultoras.iloc[:,[0,2,3,8,9]] + consultoras.columns = ['PDV','GMV ATUAL', 'VAR GMV', 'BOLETO MEDIO', 'VAR BOL'] + return consultoras + +def busca_realizado(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + dados = extract_data("consultoras.xlsx") + pdv_filtrados = dados[dados['PDV'].isin(codigos_correspondentes)] + receita_gmv = pdv_filtrados["GMV ATUAL"].sum() + return int(receita_gmv) + + diff --git a/consultoras.py b/consultoras.py new file mode 100644 index 0000000..41c19cb --- /dev/null +++ b/consultoras.py @@ -0,0 +1,49 @@ +import requests + +def consultoras (access_token, data_inicial, data_final): + # Defina o endpoint e os headers + url = "https://backend-dashboards.prd.franqueado.grupoboticario.digital/store-indicators" + headers = { + "authorization": f"Bearer {access_token}", # Substitua pelo token real + "dash-view-name": "store-view/general", + "x-api-key": "8V5pUI1u1y3dFASezqZYY6iZvkUXDHZO6Ol66ja5", + "revenue-type": "gmv-revenue", + "cp-code": "10269", + "Accept": "application/json, text/plain, */*", + # Outros cabeçalhos podem ser adicionados aqui + } + + # Parâmetros da URL + params = { + "orderBy": "revenueCurrentPeriodValue", + "aggregation": "consultant", + "order": "DESC", + "years": "2025", + "pillars": "Todos", + "startCurrentDate": {data_inicial}, + "endCurrentDate": {data_final}, + "startPreviousDate": "2024-01-03", + "endPreviousDate": "2024-01-21", + "calendarType": "calendar", + "previousPeriodCycleType": "retail-year", + "previousPeriodCalendarType": "retail-year", + "hour": "00:00 - 23:00", + "separationType": "businessDays", + "download": "true", + "channels": "LOJ", + } + + # Envie a requisição GET + response = requests.get(url, headers=headers, params=params) + + # Verifique a resposta + if response.status_code == 200: + print("Requisição bem-sucedida!") + response_json = response.json() + file_url = response_json.get("data", "") + + else: + print(f"Erro: {response.status_code}") + print(response.text) + return file_url + diff --git a/consultoras.xlsx b/consultoras.xlsx new file mode 100644 index 0000000..6763637 Binary files /dev/null and b/consultoras.xlsx differ diff --git a/data_handler.py b/data_handler.py new file mode 100644 index 0000000..b76bdbe --- /dev/null +++ b/data_handler.py @@ -0,0 +1,58 @@ +from datetime import datetime +import gerentes_erp as gerp +import pandas as pd +import login as GI +dimensao = pd.read_csv('Dimensao.csv') +# Dicionário para armazenar o estado dos usuários +user_states = {} + +def extract_message_data(data): + """ + Função que extrai o número, nome e mensagem do JSON recebido. + """ + try: + # Extrair número, nome e mensagem + number = data['data']['key']['remoteJid'].split('@')[0] # Extrai o número antes de @ + name = data['data']['pushName'] # Extrai o nome do remetente + message = data['data']['message']['conversation'] # Extrai a mensagem enviada + + # Verificar o estado do usuário + if message.lower() == "iniciar": + # Configurar o estado do usuário como "aguardando nome" + user_states[number] = "aguardando_nome" + resposta = f"Olá, {name}! Você iniciou o Consultme. Por favor, digite o seu cpf para obter o menu." + print("Bot aguardando nome da consultora.") + + elif number in user_states and user_states[number] == "aguardando_nome": + # Usuário enviou o nome da consultora, processar a consulta + cpf = message.strip() + cpf = int(cpf) + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + gerp.log_pdv(cpf) + + if cpf in dimensao['cpf_gr'].values or cpf in dimensao['cpf_sup'].values: + # Executa a consulta no sistema ERP + dados = GI.main() + mensagem = gerp.exec(cpf, primeiro_dia_formatado, hoje_formatado) + resposta = f"Olá, {name} " + mensagem + else: + mensagem = "Seu cpf não está cadastrado." + resposta = mensagem + + # Limpar o estado do usuário após responder + del user_states[number] + print(f"Consulta realizada com sucesso para {cpf}.") + + else: + # Caso o usuário envie outra mensagem sem iniciar + resposta = "Por favor, digite 'iniciar' para começar o Consultme." + print("Bot pediu ao usuário para iniciar.") + + # Retorna as informações extraídas + return number, name, message, resposta + + except KeyError as e: + raise ValueError(f"Erro ao extrair dados: {e}") diff --git a/datas.py b/datas.py new file mode 100644 index 0000000..46b49eb --- /dev/null +++ b/datas.py @@ -0,0 +1,28 @@ +#teste +from datetime import datetime +#Fazer as funções de calendário varejo + +def acumulado_mes_atual(): + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + return primeiro_dia_formatado, hoje_formatado + +def acumulado_ano_atual(): + hoje = datetime.today() + primeiro_dia_mes = hoje.replace(day=1, month=1) + hoje_formatado = hoje.strftime('%Y-%m-%d') + primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') + return primeiro_dia_formatado, hoje_formatado + +def acumulado_do_dia_atual(): + hoje = datetime.today() + hoje_formatado = hoje.strftime('%Y-%m-%d') + return hoje_formatado, hoje_formatado + +def data_hora_atual(): + data_hora_atual = datetime.now() + data_hora_formatada = data_hora_atual.strftime("%Y-%m-%d_%H-%M-%S") + return data_hora_formatada + diff --git a/gerentes_erp.py b/gerentes_erp.py new file mode 100644 index 0000000..e759606 --- /dev/null +++ b/gerentes_erp.py @@ -0,0 +1,429 @@ +import csv +import http.client +import time +from io import StringIO +import requests +import xml.etree.ElementTree as ET +from datetime import date +import pandas as pd +from datetime import date +import datetime +import os +from datetime import datetime + +dimensao = pd.read_csv('Dimensao.csv') +def busca_pdv(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + + unidades_dict = {'3546': 'aef41e8b-2a07-49eb-90ff-13b4a5ce6b65', + '4494': '804cb2f5-be0e-46ea-81cf-5faa1bfb59f2', + '4560': '2fb956b7-14ca-4320-b748-d7f3a9ea8e08', + '5699': 'b215bb37-3d30-4684-8d63-006a543bf9b4', + '11111': '01c5e9d5-fda9-4a7b-a57a-cf4ace4a0571', + '12522': '64ea8dd9-ffde-495b-9f86-3108fab1a203', + '12817': '56a47735-92e7-4317-9a86-0fcc35676a80', + '12818': '32af600c-4823-487b-b254-981666086329', + '12819': 'f20e7ffe-9d87-4fbc-b0ec-c49da6f43f33', + '12820': '54ba626b-eee9-4e4b-8a99-cbc15c9e3490', + '12823': '0c59fa2c-54d4-4f00-8952-38c9e9cda3d0', + '12824': 'ff5b50cb-3268-4653-968e-293f5155b938', + '12826': 'a15b0b35-bf09-4afa-8243-0469447d0ecd', + '12828': '0ec5b446-bbd8-438b-ba7c-d89eb1867c9d', + '12829': 'f3635215-5641-425f-80fa-44bc3041815e', + '12830': '00c76705-008e-41ab-b731-f7db638b81cc', + '12838': '35de9486-db2c-4449-8640-9e6e6e717c15', + '13427': 'decb5cb6-1e33-4c28-a2a9-945ff520b733', + '14617': '8b264cc0-cf93-4d8c-96d4-4dfb43fa5a4e', + '14668': '9439d248-6ca7-49b0-8bec-365741bd1518', + '19103': 'ea75000b-2d75-4eaa-af5f-37592b31c510', + '20005': 'ba3c5825-bd75-471d-81be-e59dc9bdb765', + '20006': 'f0169aed-0a07-4050-8952-114b1adafb50', + '20007': '1a28d239-8a39-4205-ae71-305dd47a3f67', + '20009': '4cd5cf69-82fd-472c-ade9-8cd924682dca', + '20056': '9188a0fe-5672-4e94-abb1-7cd5564566ff', + '20057': '8b2dae02-0d67-48d3-8a39-552769786b41', + '20441': 'ac31866e-1106-4c41-85dd-61ab3f782a1f', + '20858': '2189b870-51ab-4b5f-bf8d-2ed20324bfa2', + '20968': '6462b005-be0a-4065-968c-8308ff97389d', + '20969': '4c6eb12f-f16d-452f-808a-daa3d44c3cd0', + '20970': '550d82e1-ab5c-496e-88dd-0a4d4174b039', + '20986': 'd4c1f35b-0458-415c-ba02-e5a4a0e545e1', + '20988': '72921848-e9a3-4837-9941-9fccf9ca1beb', + '20989': '5b13795e-3062-4208-97de-27ed4642d097', + '20991': '9939bb4a-3d8b-43c6-857d-7c2efd6541cc', + '20992': '12148415-fb86-431e-89cd-7b17b27a345b', + '20993': '4aeac823-6b09-4582-acb4-22f0e72735d8', + '20994': '7860f680-bcc9-4d21-bf11-9dde76e2b1f1', + '20995': 'a3e122bc-2060-4f80-94f5-f43be99fb7a2', + '20996': '8676f6f8-a5b0-44cf-8220-06d41289fc34', + '20997': '680f71f3-1d4a-4263-a91f-6fb2a08b2dda', + '20998': '03cf8f3a-950c-43da-8b57-c498395fae5c', + '20999': '58691507-093a-4197-a696-81367eff33ff', + '21000': 'abcd6221-a26d-47bb-95e1-488602f76d51', + '21001': 'eadb3fa2-36ec-4936-b840-fb9597cadbac', + '21068': 'bdb2958d-7895-4c08-8dc6-7c724c1ae9c6', + '21277': '6a448c7d-fe7c-41e4-b8eb-5433ac52693b', + '21278': 'aedf2a6d-d982-4111-b3a4-117e46f5e9d5', + '21279': 'af5f4861-581a-4d45-aeb9-c90e44f30a50', + '21296': 'bbc66aa3-5d74-4405-8f58-d1b739c6a1ba', + '21375': '57ff2d4a-3945-48ca-a227-533c402e3060', + '21381': '2b030fe9-9285-45ef-97fb-b896337c739f', + '21382': 'f0f4884b-c190-4868-85c3-8cb64872ca84', + '21383': '0d9f481a-de26-47e6-8171-14f09643df57', + '21495': 'f7b321d8-b043-48f2-8555-3496630e9e83', + '21624': '22607a28-33a2-4cb4-a456-71054bda3755', + '21647': 'd4bb9aba-30e8-44f3-a83e-d44e6f87ce37', + '22448': 'e2778279-5fc4-4257-add4-3f196535e989', + '22541': 'e6a71600-0e5e-4806-8d6f-8dbe013da6e5', + '23156': "ace15a69-2af4-4f8d-8101-92c9e5201c84", + '23156': 'ace15a69-2af4-4f8d-8101-92c9e5201c84', + '23475': '4b149b33-33c0-4b95-9a7f-716dbd557b4a', + '23665': '5495e224-9b18-4b28-9d92-2f335e238dee', + '23701': '4e501dc2-c417-4bb4-bc97-3ba167360578', + '23702': 'ca93d092-b461-4446-bc78-7b9c717bb553', + '23703': '4d132cdc-0763-4e1f-8b4b-6a38a1280f81', + '23704': '9c4ec32d-38e2-46c7-9450-624f8f083ded', + '23705': '71badcb2-1043-431a-99b1-0bd11a9754a5', + '23706': 'c06de6a6-7b03-47ea-80a7-68d4a1f3dd04', + '23707': '9db686c8-5119-4eb1-9dd5-363d91db2513', + '23708': '3887a770-2b44-45d0-ab08-6cf03ec0e3d8', + '23709': 'a0e9e003-144e-4543-ac50-e4bf6894e6a2', + '23710': '3e4fc9f9-2716-4c03-b814-4fea06392757', + '23711': 'ab746a88-dbf2-4fb1-80f0-4e20a9c945f6', + '23712': '5b995c5e-563e-4dee-b408-78243fff8ec0', + '23713': 'fe02eab3-620c-402d-ae1d-ad564876b9af' + } + + concatenated_string = "" + json_data = unidades_dict + for codigo in codigos_correspondentes: + if str(codigo) in json_data: # Verificar se o código existe no JSON + concatenated_string += json_data[str(codigo)] # Concatenar o valor com um espaço + print(codigo) + # Remover o espaço extra no final (opcional) + concatenated_string = concatenated_string.strip() + return concatenated_string + +def log_pdv(codigo_pesquisar): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + + unidades_dict = {'3546': 'aef41e8b-2a07-49eb-90ff-13b4a5ce6b65', + '4494': '804cb2f5-be0e-46ea-81cf-5faa1bfb59f2', + '4560': '2fb956b7-14ca-4320-b748-d7f3a9ea8e08', + '5699': 'b215bb37-3d30-4684-8d63-006a543bf9b4', + '11111': '01c5e9d5-fda9-4a7b-a57a-cf4ace4a0571', + '12522': '64ea8dd9-ffde-495b-9f86-3108fab1a203', + '12817': '56a47735-92e7-4317-9a86-0fcc35676a80', + '12818': '32af600c-4823-487b-b254-981666086329', + '12819': 'f20e7ffe-9d87-4fbc-b0ec-c49da6f43f33', + '12820': '54ba626b-eee9-4e4b-8a99-cbc15c9e3490', + '12823': '0c59fa2c-54d4-4f00-8952-38c9e9cda3d0', + '12824': 'ff5b50cb-3268-4653-968e-293f5155b938', + '12826': 'a15b0b35-bf09-4afa-8243-0469447d0ecd', + '12828': '0ec5b446-bbd8-438b-ba7c-d89eb1867c9d', + '12829': 'f3635215-5641-425f-80fa-44bc3041815e', + '12830': '00c76705-008e-41ab-b731-f7db638b81cc', + '12838': '35de9486-db2c-4449-8640-9e6e6e717c15', + '13427': 'decb5cb6-1e33-4c28-a2a9-945ff520b733', + '14617': '8b264cc0-cf93-4d8c-96d4-4dfb43fa5a4e', + '14668': '9439d248-6ca7-49b0-8bec-365741bd1518', + '19103': 'ea75000b-2d75-4eaa-af5f-37592b31c510', + '20005': 'ba3c5825-bd75-471d-81be-e59dc9bdb765', + '20006': 'f0169aed-0a07-4050-8952-114b1adafb50', + '20007': '1a28d239-8a39-4205-ae71-305dd47a3f67', + '20009': '4cd5cf69-82fd-472c-ade9-8cd924682dca', + '20056': '9188a0fe-5672-4e94-abb1-7cd5564566ff', + '20057': '8b2dae02-0d67-48d3-8a39-552769786b41', + '20441': 'ac31866e-1106-4c41-85dd-61ab3f782a1f', + '20858': '2189b870-51ab-4b5f-bf8d-2ed20324bfa2', + '20968': '6462b005-be0a-4065-968c-8308ff97389d', + '20969': '4c6eb12f-f16d-452f-808a-daa3d44c3cd0', + '20970': '550d82e1-ab5c-496e-88dd-0a4d4174b039', + '20986': 'd4c1f35b-0458-415c-ba02-e5a4a0e545e1', + '20988': '72921848-e9a3-4837-9941-9fccf9ca1beb', + '20989': '5b13795e-3062-4208-97de-27ed4642d097', + '20991': '9939bb4a-3d8b-43c6-857d-7c2efd6541cc', + '20992': '12148415-fb86-431e-89cd-7b17b27a345b', + '20993': '4aeac823-6b09-4582-acb4-22f0e72735d8', + '20994': '7860f680-bcc9-4d21-bf11-9dde76e2b1f1', + '20995': 'a3e122bc-2060-4f80-94f5-f43be99fb7a2', + '20996': '8676f6f8-a5b0-44cf-8220-06d41289fc34', + '20997': '680f71f3-1d4a-4263-a91f-6fb2a08b2dda', + '20998': '03cf8f3a-950c-43da-8b57-c498395fae5c', + '20999': '58691507-093a-4197-a696-81367eff33ff', + '21000': 'abcd6221-a26d-47bb-95e1-488602f76d51', + '21001': 'eadb3fa2-36ec-4936-b840-fb9597cadbac', + '21068': 'bdb2958d-7895-4c08-8dc6-7c724c1ae9c6', + '21277': '6a448c7d-fe7c-41e4-b8eb-5433ac52693b', + '21278': 'aedf2a6d-d982-4111-b3a4-117e46f5e9d5', + '21279': 'af5f4861-581a-4d45-aeb9-c90e44f30a50', + '21296': 'bbc66aa3-5d74-4405-8f58-d1b739c6a1ba', + '21375': '57ff2d4a-3945-48ca-a227-533c402e3060', + '21381': '2b030fe9-9285-45ef-97fb-b896337c739f', + '21382': 'f0f4884b-c190-4868-85c3-8cb64872ca84', + '21383': '0d9f481a-de26-47e6-8171-14f09643df57', + '21495': 'f7b321d8-b043-48f2-8555-3496630e9e83', + '21624': '22607a28-33a2-4cb4-a456-71054bda3755', + '21647': 'd4bb9aba-30e8-44f3-a83e-d44e6f87ce37', + '22448': 'e2778279-5fc4-4257-add4-3f196535e989', + '22541': 'e6a71600-0e5e-4806-8d6f-8dbe013da6e5', + '23156': "ace15a69-2af4-4f8d-8101-92c9e5201c84", + '23156': 'ace15a69-2af4-4f8d-8101-92c9e5201c84', + '23475': '4b149b33-33c0-4b95-9a7f-716dbd557b4a', + '23665': '5495e224-9b18-4b28-9d92-2f335e238dee', + '23701': '4e501dc2-c417-4bb4-bc97-3ba167360578', + '23702': 'ca93d092-b461-4446-bc78-7b9c717bb553', + '23703': '4d132cdc-0763-4e1f-8b4b-6a38a1280f81', + '23704': '9c4ec32d-38e2-46c7-9450-624f8f083ded', + '23705': '71badcb2-1043-431a-99b1-0bd11a9754a5', + '23706': 'c06de6a6-7b03-47ea-80a7-68d4a1f3dd04', + '23707': '9db686c8-5119-4eb1-9dd5-363d91db2513', + '23708': '3887a770-2b44-45d0-ab08-6cf03ec0e3d8', + '23709': 'a0e9e003-144e-4543-ac50-e4bf6894e6a2', + '23710': '3e4fc9f9-2716-4c03-b814-4fea06392757', + '23711': 'ab746a88-dbf2-4fb1-80f0-4e20a9c945f6', + '23712': '5b995c5e-563e-4dee-b408-78243fff8ec0', + '23713': 'fe02eab3-620c-402d-ae1d-ad564876b9af' + } + + concatenated_string = "" + json_data = unidades_dict + for codigo in codigos_correspondentes: + if str(codigo) in json_data: # Verificar se o código existe no JSON + concatenated_string += json_data[str(codigo)] # Concatenar o valor com um espaço + print(codigo) + + +def encode_url(texto): + return ''.join('%{:02X}'.format(ord(char)) if char not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-' else char for char in texto) + +def gerar_session_id(marca, relatorio): + # URL do endpoint + url = '', '' + if marca == 'BOT': + url = 'https://livers.e-boticario.com.br/ReportServer/ReportExecution2005.asmx' + + payload = f''' + + + {relatorio} + + + ''' + + headers = { + "Content-Type": "text/xml; charset=utf-8", + "SOAPAction": "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/LoadReport", + "Authorization": "Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=" + } + + response = requests.request("POST", url, data=payload, headers=headers) + + if response.status_code == 200: + response_xml = response.text + # Analisar o XML + root = ET.fromstring(response_xml) + + # Encontrar o elemento ExecutionID + execution_id_element = root.find( + './/{http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices}ExecutionID') + + # Obter o valor do elemento ExecutionID + execution_id = execution_id_element.text + + # print("ExecutionID:", execution_id) + print(f'gerar sessão: {response.status_code} - {execution_id}') + # print(response.text) + return execution_id + else: + return + + + +def carregar_relatorio(marca, execution_id, cpf, data_inicial, data_final): + pdvs = busca_pdv(cpf) + url, host = '', '' + if marca == 'QDB': + # url = 'http://rs.quemdisseberenice.com.br/ReportServer/ReportExecution2005.asmx' + url = 'rs.quemdisseberenice.com.br' + owner_id = 'ea16f59c-ddec-4e6e-aea1-a220cbf0eaba' + elif marca == 'BOT': + # url = 'http://livers.e-boticario.com.br/ReportServer/ReportExecution2005.asmx' + url = 'livers.e-boticario.com.br' + owner_id = '3861c9c1-600b-4f7a-86b1-9bf685a6d041' + + endpoint = '/ReportServer/ReportExecution2005.asmx' + payload = f''' +
+ + {execution_id} + +
+ + + + + tipo + 3 + + + situacao + -1 + + + interesse + 2 + + + titulorelatorio + Resumo de Vendas + + + filtrorelatorio + de 15/01/2025 até 15/01/2025; Lojas: 4494-COMERCIO-PONTA VERDE-MACEIO, 4560-COMERCIO-MACEIO SHOP TERREO-AL, 5699-COMERCIO -MOREIRA LIMA; Produtos: Todos; Vendedor: Todos; Tipo Relatório: Por Vendedor; Situação: Todos; Interesse: Todos; Classificadores: Todos; + + + lojarelatorio + CENTRAL 9004494 + + + unidadesnegocio + {pdvs} + + + datainicial + {data_inicial} 00:00:00 + + + datafinal + {data_final} 23:59:59 + + + ownerid + 3861c9c1-600b-4f7a-86b1-9bf685a6d041 + + + pt-BR + + +
+ ''' + + headers = { + "Content-Type": "text/xml; charset=utf-8", + "SOAPAction": 'http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/SetExecutionParameters', + "Authorization": "Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=", + } + + # Enable debugging for http.client + # http.client.HTTPSConnection.debuglevel = 1 + + # connection = http.client.HTTPSConnection(url) + connection = http.client.HTTPSConnection(url) + connection.request("POST", endpoint, body=payload, headers=headers) + response = connection.getresponse() + + # Enable debugging for http.client + # http.client.HTTPSConnection.debuglevel = 0 + + print(f'setar parametros: {response.status}') + + + +def gerar_csv(marca, execution_id, relatorio, cpf): + url, host = '', '' + if marca == 'QDB': + url = 'http://rs.quemdisseberenice.com.br/ReportServer?' + host = 'rs.quemdisseberenice.com.br' + elif marca == 'BOT': + url = 'https://livers.e-boticario.com.br/ReportServer?' + host = 'livers.e-boticario.com.br' + + querystring = f'{encode_url(relatorio)}&rs:SessionID={execution_id}&rs:command=Render&rs:Format=CSV&rc:Toolbar=false&rs:ErrorResponseAsXml=true&rs:AllowNewSessions=false%20HTTP/1.1' + + headers = { + 'Accept-Language': 'pt-BR', + 'Authorization': 'Basic ZG16XExpdmVSZXBvcnQ6MUVrd1BPRC9VMURrL0YxS2YrVVM=', + 'Host': f'{host}' + } + + response = requests.request("GET", f'{url}{querystring}', headers=headers) + + # print(url, querystring, sep='') + # print(f'gerar csv: {response.status_code}') + response_data = response.text + # print(response_data[:100]) + + # Separar mês e ano da string de data + # inicio = data_inicial.find('-') + 1 + # fim = data_inicial.find('-', inicio) + #ano = datetime.today().date().strftime('%Y') + #numero_mes = datetime.today().date().strftime('%m') + + csv_file = StringIO(response_data) + reader = csv.reader(csv_file) + # output_file = fr'../csv_base/brindes/{numero_mes}.{numero_ano}_{cod_unidade}_brindes_{marca}.csv' + # output_file = fr'../csv_base/posicao_de_estoque_na_data/posicao estoque_{data}_{cod_unidade}.csv' + output_file = fr'temp\{cpf}.csv' + + # output_file = fr'../csv_base/brindes/{numero_mes}.csv' + # Escrever os dados no arquivo CSV + with open(output_file, mode='w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + + # Escrever o cabeçalho + writer.writerow(next(reader)) + + # Escrever as linhas de dados + for row in reader: + writer.writerow(row) + + print(f'Dados foram gravados em "{output_file}"') + + + +def exec (cpf, data_inicial, data_final): + relatorio = '/Vendas/vendas14ResumoVendas' + exec_id = gerar_session_id('BOT', relatorio) + MAX_RETRIES = 10 + retry_count = 0 + while True: # Loop para tentar novamente em caso de falha + try: + carregar_relatorio('BOT', exec_id, cpf, data_inicial, data_final) + gerar_csv('BOT', exec_id, relatorio, cpf) + # print(cod_unidade, unidade, sep='\t') + break # Se chegou até aqui sem lançar exceções, pode sair do loop + except requests.exceptions.ConnectionError as e: + if retry_count == MAX_RETRIES: + raise e + else: + print(f"Erro de conexão: {e}") + time.sleep(5) + retry_count += 1 + except ConnectionResetError as e: + if retry_count == MAX_RETRIES: + raise e + else: + print(f"Erro de conexão: {e}") + time.sleep(5) + retry_count += 1 + + consulta = pd.read_csv(fr'temp\{cpf}.csv', encoding='ISO-8859-1') + realizado_formatado = consulta['textbox56'] + boleto_medio = consulta['textbox86'] + realizado = (float(realizado_formatado.iloc[0].replace('.', '').replace(',', '.'))) + boleto_formato = (float(boleto_medio.iloc[0].replace('.', '').replace(',', '.'))) + mensagem = f"Aqui está o seu realizado deste mês: R$ {realizado} e o boleto médio foi R$ {boleto_formato}" + return mensagem +''' +hoje = datetime.today() +primeiro_dia_mes = hoje.replace(day=1) +hoje_formatado = hoje.strftime('%Y-%m-%d') +primeiro_dia_formatado = primeiro_dia_mes.strftime('%Y-%m-%d') +realizado = exec(736514511, primeiro_dia_formatado, hoje_formatado) +print(hoje) +''' \ No newline at end of file diff --git a/login.py b/login.py new file mode 100644 index 0000000..f7b9c66 --- /dev/null +++ b/login.py @@ -0,0 +1,259 @@ +import os +import hashlib +import base64 +import requests +import re +import json +import consultoras as c +import datas as d +import pandas as pd + +def generate_code_verifier(): + """Gera um code_verifier aleatório.""" + return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip("=") + +def generate_code_challenge(code_verifier): + """Gera o code_challenge usando SHA-256.""" + sha256_hash = hashlib.sha256(code_verifier.encode('utf-8')).digest() + return base64.urlsafe_b64encode(sha256_hash).decode('utf-8').rstrip("=") + +def send_authorization_request(session, code_challenge): + """Envia uma requisição GET para a página de login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD", + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "response_type": "code", + "scope": "openid email https://gboticariob2c.onmicrosoft.com/a6cd4fe6-3d71-455a-b99d-f458a07cc0d1/extranet.api offline_access", + "state": "15d9d7f95f8648d1941426f4665aa383", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "response_mode": "query" + } + + response = session.get(url, params=params) + if response.status_code == 200: + print("Página de login carregada com sucesso.") + return response.text # Retorna o HTML + else: + print(f"Erro ao acessar a página de login: {response.status_code}") + print("Resposta de erro:", response.text) + return None + +def extract_tokens(html_content): + """Extrai o CSRF Token e StateProperties do conteúdo HTML.""" + csrf_token = None + state_properties = None + + if html_content: + csrf_match = re.search(r'"csrf":"(.*?)"', html_content) + csrf_token = csrf_match.group(1) if csrf_match else None + + state_properties_match = re.search(r'"transId":"StateProperties=(.*?)"', html_content) + state_properties = state_properties_match.group(1) if state_properties_match else None + + return csrf_token, state_properties + +def send_login_request(session, csrf_token, state_properties, username, password): + """Envia uma requisição POST para realizar o login usando a sessão.""" + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/SelfAsserted" + + params = { + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FEDCorp_APIGEE_PRD" + } + + headers = { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-CSRF-TOKEN": csrf_token, + "X-Requested-With": "XMLHttpRequest", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "application/json, text/javascript, */*; q=0.01", + "Origin": "https://login.extranet.grupoboticario.com.br", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + data = { + "request_type": "RESPONSE", + "signInName": username, + "password": password + } + + response = session.post(url, params=params, headers=headers, data=data) + if response.status_code == 200: + print("Login realizado com sucesso!") + return response.text + else: + print(f"Erro ao realizar login: {response.status_code}") + return None + +def send_final_request(session, csrf_token, state_properties): + """ + Envia a última requisição GET para obter a página HTML. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD/api/CombinedSigninAndSignup/confirmed" + + params = { + "rememberMe": "false", + "csrf_token": csrf_token, + "tx": f"StateProperties={state_properties}", + "p": "B2C_1A_JIT_SignUpOrSignin_FedCorp_APIGEE_PRD" + } + + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Referer": "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/authorize" + } + + response = session.get(url, headers=headers, params=params, allow_redirects=False) + if response.status_code == 200: + print("Requisição final bem-sucedida!") + return response.text # Retorna o HTML + else: + print(f"Erro na requisição final: {response.status_code}") + return response.text + +def extract_code_from_html(html_content): + """ + Extrai o valor do parâmetro `code` da URL no HTML fornecido. + + :param html_content: O conteúdo HTML como string. + :return: O valor do código ou None, se não encontrado. + """ + # Regex para encontrar o parâmetro `code` na URL do atributo `href` + match = re.search(r'href="[^"]*?code=([^&"]+)', html_content) + if match: + return match.group(1) # Captura o valor do parâmetro `code` + return match + +def send_token_request(code, code_verifier): + """ + Envia uma requisição POST para obter o token usando o código e o code_verifier. + + :param code: O código extraído da etapa anterior. + :param code_verifier: O code_verifier usado no início do fluxo. + :return: A resposta do servidor. + """ + url = "https://login.extranet.grupoboticario.com.br/1e6392bd-5377-48f0-9a8e-467f5b381b18/oauth2/v2.0/token" + params = { + "p": "B2C_1A_JIT_SIGNUPORSIGNIN_FEDCORP_APIGEE_PRD" + } + + headers = { + "Host": "login.extranet.grupoboticario.com.br", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0", + "Accept": "*/*", + "Origin": "https://extranet.grupoboticario.com.br", + "Sec-Fetch-Site": "same-site", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Dest": "empty", + "Referer": "https://extranet.grupoboticario.com.br/", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + } + + data = { + "client_id": "b3001e60-a8e0-4da8-82ba-c3a701405f08", + "code": code, + "redirect_uri": "https://extranet.grupoboticario.com.br/auth/callback", + "code_verifier": code_verifier, + "grant_type": "authorization_code" + } + + response = requests.post(url, params=params, headers=headers, data=data) + return response.text + + +def extract_tokens_2(response_1): + response = json.loads(response_1) + try: + access_token = response.get("access_token") + id_token = response.get("id_token") + refresh_token = response.get("refresh_token") + + return { + "access_token": access_token, + "id_token": id_token, + "refresh_token": refresh_token + } + except Exception as e: + print(f"Erro ao extrair tokens: {e}") + return None + +def extract_data(file): + consultoras = pd.read_excel(f"{file}", sheet_name="PDV") + consultoras.drop(index=1, inplace=True) + consultoras.columns = consultoras.iloc[0] + consultoras.drop(index=0, inplace=True) + consultoras= consultoras.iloc[:,[0,2,3,8,9]] + consultoras.columns = ['PDV','GMV ATUAL', 'VAR GMV', 'BOLETO MEDIO', 'VAR BOL'] + return consultoras + +def busca_realizado(codigo_pesquisar, file): + dimensao = pd.read_csv('Dimensao.csv',encoding='utf-8') + df = dimensao + codigos_correspondentes = df[(df['cpf_gr'] == codigo_pesquisar) | (df['cpf_sup'] == codigo_pesquisar)]['codigo'].tolist() + dados = extract_data(f"{file}") + pdv_filtrados = dados[dados['PDV'].isin(codigos_correspondentes)] + receita_gmv = pdv_filtrados["GMV ATUAL"].sum() + return int(receita_gmv) + +# Processo principal +def main(): + session = requests.Session() # Iniciar uma sessão persistente + + code_verifier = generate_code_verifier() + code_challenge = generate_code_challenge(code_verifier) + print(f"Code Verifier: {code_verifier}") + print(f"Code Challenge: {code_challenge}") + + # Enviar requisição GET para obter tokens + html_content = send_authorization_request(session, code_challenge) + csrf_token, state_properties = extract_tokens(html_content) + + if not csrf_token or not state_properties: + print("Falha ao extrair CSRF Token ou StateProperties.") + else: + print("CSRF Token:", csrf_token) + print("StateProperties:", state_properties) + + # Dados de login + username = "andressa.santos4" + password = "Admufal@202" + + # Enviar requisição POST para login + login_response = send_login_request(session, csrf_token, state_properties, username, password) + + if login_response: + print("Resposta do servidor:", login_response) + + # Enviar requisição final + final_page_html = send_final_request(session, csrf_token, state_properties) + code = extract_code_from_html(final_page_html) + token = send_token_request(code, code_verifier) + +# Carregar o JSON do arquivo texto + tokens = extract_tokens_2(token) + if tokens: + Access = tokens["access_token"] + #print("ID Token:", tokens["id_token"]) + #print("Refresh Token:", tokens["refresh_token"]) + else: + print("Falha ao carregar ou processar o JSON.") + + url = c.consultoras(Access, d.acumulado_do_dia_atual()[0], d.acumulado_do_dia_atual()[1]) + baixar = requests.get(url) + file_name = f"consultoras{d.data_hora_atual()}.xlsx" + if baixar.status_code == 200: + # Salvar o conteúdo do arquivo + with open(file_name, "wb") as file: + file.write(baixar.content) + dados = extract_data(file_name) + print(f"Arquivo salvo com sucesso como {file_name}.") + else: + print(f"Erro ao acessar o arquivo. Código de status: {baixar.status_code}") + return dados \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..fee49d9 --- /dev/null +++ b/main.py @@ -0,0 +1,59 @@ +from flask import Flask, request, jsonify +from data_handler import extract_message_data +import requests +import gerentes_erp as gerp +import login as lg + +# URL do endpoint +url = "http://localhost:8081/message/sendText/Consultme" + +# Cabeçalhos com token de autenticação +headers = { + 'apikey': "429683C4C977415CAAFCCE10F7D57E11", # Substitua SEU_TOKEN_AQUI pelo token correto + "Content-Type": "application/json" +} + + +app = Flask(__name__) + +@app.route('/webhook', methods=['POST']) +def receive_message(): + try: + # Recebe os dados da requisição como JSON + data = request.json + + # Verificar se a mensagem foi enviada pelo próprio bot (fromMe == True) + if data['data']['key'].get('fromMe', False): + print("Mensagem enviada pelo bot, ignorando.") + return jsonify({"status": "ignored"}), 200 + + # Extrair as informações usando a função importada + number, name, message, resposta = extract_message_data(data) + + # Log das informações extraídas + print(f"Número: {number}, Nome: {name}, Mensagem: {message}") + # Responder apenas se a mensagem foi enviada pelo usuário + if number.startswith("5582") and len(number) == 12: + number = number[:4] + "9" + number[4:] + + # JSON de resposta a ser enviado para a Evolution API + response_data = { + "number": str(number), + "text": resposta + } + response = requests.post(url, json=response_data, headers=headers) + print("Status Code:", response.status_code) + print("Response Body:", response.text) + + # Retorna a resposta confirmando o recebimento + return jsonify({"status": "received", "number": number, "name": name, "message": message, "resposta": resposta}), 200 + + except ValueError as e: + print("Erro ao processar a mensagem:", e) + return jsonify({"status": "error", "message": str(e)}), 400 + except Exception as e: + print("Erro inesperado:", e) + return jsonify({"status": "error", "message": "Erro inesperado"}), 500 + +if __name__ == '__main__': + app.run(port=5000, debug=True)