Viewing: dashSFilho.py
#SFilho ( '1', '3' ) #http://162.214.65.39:8505/ #nohup python3 -m streamlit run dashSFilho.py --server.port 8505 --server.address 0.0.0.0 > dashSFilho.log 2>&1 & import streamlit as st import cx_Oracle import pandas as pd import plotly.express as px import plotly.graph_objects as go import plotly.figure_factory as ff import datetime import numpy as np import altair as alt import locale import random import duckdb import base64 from Crypto.Cipher import AES from Crypto.Protocol.KDF import PBKDF2 from sqlalchemy import create_engine, text from streamlit_option_menu import option_menu # Definir a localidade para o Brasil #locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8') #logomarca logo_path = '/home/grupo692/appstigrupobig/10CIA.png' MASTER_PASSWORD = "MinhaSenhaMestra123!" SALT = b"SaltFixo12345678" ITERATIONS = 10000 try: locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8') except locale.Error: locale.setlocale(locale.LC_ALL, 'C') # Função para formatar o valor com o padrão de moeda brasileiro def formatar_moeda(valor): try: # Formatação manual para garantir que os números usem ponto como separador de milhar e vírgula como decimal valor_formatado = "{:,.2f}".format(valor) # Substituindo ponto por vírgula para o separador decimal e vírgula por ponto para milhar valor_formatado = valor_formatado.replace(",", "X").replace(".", ",").replace("X", ".") return f"R$ {valor_formatado}" except ValueError: return f"R${valor:,.2f}" # Fallback, caso o valor não seja formatável # Configuração do Streamlit st.set_page_config( page_title="10&Cia SFilho+TNeves", page_icon="📊", layout="wide" ) alt.themes.enable("dark") def generate_key_iv(): key_iv = PBKDF2( MASTER_PASSWORD.encode("utf-8"), SALT, dkLen=48, # 32 bytes key + 16 bytes IV count=ITERATIONS ) return key_iv[:32], key_iv[32:] def decrypt(cipher_text: str) -> str: key, iv = generate_key_iv() cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(base64.b64decode(cipher_text)) # Remove PKCS7 padding pad_len = decrypted[-1] text = decrypted[:-pad_len].decode("utf-8", errors="ignore") # Remove BOM (se existir) return text.lstrip("\ufeff") # Conectar ao banco de dados Oracle def conectar_banco(): try: #cx_Oracle.init_oracle_client(lib_dir=r"C:\\Oracle\\instantclient_21_13") #cx_Oracle.init_oracle_client(lib_dir=r"/Applications/oracle/client/instantclient_19-3") _pass = decrypt("+ivGpR7n9D4zKHONh/3W2A==") connection = cx_Oracle.connect( user="EDIUSER", password=_pass, #GrupoBig #dsn="187.109.221.38:1521/PROTON" #Av7 dsn="cc210e3b6c47.sn.mynetname.net:1521/DBPROD" ) #engine = create_engine('oracle+cx_Oracle://', creator=lambda: connection) engine = create_engine(f'oracle+cx_oracle://EDIUSER:{_pass}@cc210e3b6c47.sn.mynetname.net:1521/DBPROD') #engine = create_engine('oracle+cx_oracle://EDIUSER:EDIUSER@187.109.221.38:1521/PROTON') return connection, engine except cx_Oracle.DatabaseError as e: st.error("Erro ao conectar com o banco de dados.") st.stop() connection, engine = conectar_banco() def creds_entered(login, senha): """Verifica se as credenciais do usuário são válidas.""" if not login or not senha: st.warning("Insira o login e a senha.") return query = """ SELECT BIG_USUARIOS.USU_USUARIO_FK_PK, TSYS_USUARIO.TSYS_NOME, BIG_USUARIOS.USU_ADMIN, BIG_USUARIOS.USU_SENHA, LISTAGG ( BIG_USUARIOS_ACESSOS.USU_COD_UNIDADE, ', ' ) WITHIN GROUP ( ORDER BY BIG_USUARIOS_ACESSOS.USU_COD_UNIDADE ) AS USU_COD_UNIDADE, BIG_USUARIOS.USU_DIRETORIA FROM DBAUSER.BIG_USUARIOS LEFT JOIN DBAUSER.BIG_USUARIOS_ACESSOS ON BIG_USUARIOS_ACESSOS.USU_USUARIO_FK_PK = BIG_USUARIOS.USU_USUARIO_FK_PK LEFT JOIN TSYS_USUARIO ON TSYS_USUARIO.TSYS_USUARIO_PK = BIG_USUARIOS.USU_USUARIO_FK_PK WHERE BIG_USUARIOS.USU_USUARIO_FK_PK = :usuario AND BIG_USUARIOS.USU_SENHA = :senha AND BIG_USUARIOS.USU_DIRETORIA = 'S' GROUP BY BIG_USUARIOS.USU_USUARIO_FK_PK, TSYS_USUARIO.TSYS_NOME, BIG_USUARIOS.USU_ADMIN, BIG_USUARIOS.USU_SENHA, BIG_USUARIOS.USU_DIRETORIA """ with connection.cursor() as cursor: cursor.execute(query, usuario=login, senha=senha) result = cursor.fetchall() if result: st.session_state["authenticated"] = True st.rerun() else: st.session_state["authenticated"] = False st.error("Usuário e senha inválidos") def authenticate_user(): """Autentica o usuário baseado nas credenciais inseridas.""" if "authenticated" in st.session_state: return st.session_state["authenticated"] login = st.number_input(label="Login:", value=None, key="user", step=1, min_value=1) senha = st.text_input(label="Senha:", value=None, key="pass", type="password") if st.button("Login"): creds_entered(login, senha) return False if not authenticate_user(): st.stop() def main(): if authenticate_user(): EXAMPLE_NO = 1 # Menu lateral com as opções def streamlit_menu(example=1): if example == 1: st.sidebar.image(logo_path) with st.sidebar: selected = option_menu( menu_title="10&Cia SFilho+TNeves.", options=["Vendas por Unidade", "Vendas por Grupo Merc", "Vendas por Fornecedor", "Vendas por Operador", "Top 100 Merc."], icons=["house", "box-seam-fill", "truck", "person", "cart3"], menu_icon="cast", default_index=0, ) return selected selected = streamlit_menu(example=EXAMPLE_NO) # ---------------------------------------------------------- # Rotina Ranking Vendas if selected == "Vendas por Unidade": def espera_selecionar_datas(): while True: selected_dates = st.date_input( 'Selecione o intervalo de datas:', [datetime.datetime.now().replace(day=1), datetime.datetime.now()], format="DD/MM/YYYY" ) if len(selected_dates) == 2: return selected_dates[0], selected_dates[1] else: st.warning("Por favor, selecione as duas datas.") start_date, end_date = espera_selecionar_datas() rerun_button = st.button("Atualizar") if rerun_button: st.rerun() #Consulta meta query = """ SELECT COD_UND, UNIDADE, QNTD_PEDIDOS, VALOR_TOTAL, NVL(MTA_META, 0) AS MTA_META, NVL(MTA_BIG_META, 0) AS MTA_BIG_META, NVL(ROUND( VALOR_TOTAL / QNTD_PEDIDOS, 2), 0) AS TKT_MEDIO, NVL(MTA_META_TKT_MEDIO, 0) AS MTA_META_TKT_MEDIO FROM ( SELECT TPED_UNIDADE_FK_PK AS cod_und, TUND_UNIDADE.TUND_FANTASIA AS unidade, SUM( QTD ) AS qntd_pedidos, SUM( TPED_VALOR_TOTAL_PEDIDO ) - NVL( ( SELECT SUM( TMOV_VALOR_TOTAL ) FROM TMOV_EXTRA WHERE TMOV_EXTRA.TMOV_UNIDADE_FK = TPED_UNIDADE_FK_PK AND TMOV_EXTRA.TMOV_NATUREZA_MOVIMENTACAO = 'DC' AND TMOV_ESTADO_MOVIMENTACAO = 'CL' AND TMOV_APENAS_IMPRESSAO = 'N' AND TMOV_EXTRA.TMOV_DATA_DOCUMENTO BETWEEN :start_date AND :end_date ), 0 ) AS valor_total, BIG_METAS.MTA_META, BIG_METAS.MTA_BIG_META, BIG_METAS.MTA_META_TKT_MEDIO FROM ( SELECT TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK, TPED_DATA_EMISSAO, COUNT( TPED_PEDIDO_VENDA.TPED_NUMERO_PEDIDO_PK ) AS QTD, SUM( TPED_PEDIDO_VENDA.TPED_VALOR_TOTAL_PEDIDO ) AS TPED_VALOR_TOTAL_PEDIDO FROM TPED_PEDIDO_VENDA WHERE TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_PEDIDO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' GROUP BY TPED_UNIDADE_FK_PK, TPED_DATA_EMISSAO UNION ALL SELECT TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK, TPED_DATA_EMISSAO, COUNT( TPED_HISTORICO_VENDA.TPED_NUMERO_PEDIDO_PK ) AS QTD, SUM( TPED_HISTORICO_VENDA.TPED_VALOR_TOTAL_PEDIDO ) AS TPED_VALOR_TOTAL_PEDIDO FROM TPED_HISTORICO_VENDA WHERE TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_HISTORICO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' GROUP BY TPED_UNIDADE_FK_PK, TPED_DATA_EMISSAO ) LEFT JOIN TUND_UNIDADE ON TUND_UNIDADE.TUND_UNIDADE_PK = TPED_UNIDADE_FK_PK LEFT JOIN DBAUSER.BIG_METAS ON DBAUSER.BIG_METAS.MTA_UNIDADE_FK_PK = TPED_UNIDADE_FK_PK AND TO_CHAR(TRUNC(DBAUSER.BIG_METAS.MTA_MES_ANO, 'MM'), 'MMYYYY') = TO_CHAR(TRUNC(:start_date , 'MM'), 'MMYYYY') GROUP BY TPED_UNIDADE_FK_PK, TUND_UNIDADE.TUND_FANTASIA, BIG_METAS.MTA_META, BIG_METAS.MTA_BIG_META, BIG_METAS.MTA_META_TKT_MEDIO ) ORDER BY VALOR_TOTAL DESC """ df = pd.read_sql(query, engine, params={"start_date": start_date, "end_date": end_date}) ############################################################################################## ####################################### # VISUALIZATION METHODS ####################################### def plot_metric(label, value, prefix="", suffix="", show_graph=False, color_graph=""): fig = go.Figure() fig.add_trace( go.Indicator( value=str(formatar_moeda(value)), gauge={"axis": {"visible": False}}, number={ "prefix": prefix, "suffix": suffix, "font.size": 28, }, title={ "text": label, "font": {"size": 24}, }, ) ) if show_graph: fig.add_trace( go.Scatter( y=random.sample(range(0, 101), 30), hoverinfo="skip", fill="tozeroy", fillcolor=color_graph, line={ "color": color_graph, }, ) ) fig.update_xaxes(visible=False, fixedrange=True) fig.update_yaxes(visible=False, fixedrange=True) fig.update_layout( # paper_bgcolor="lightgrey", margin=dict(t=30, b=0), showlegend=False, plot_bgcolor="white", height=100, ) st.plotly_chart(fig, use_container_width=True) def plot_gauge( indicator_number, indicator_color, indicator_suffix, indicator_title, max_bound, Meta, bigMeta ): # Criação do gráfico Gauge fig = go.Figure(go.Indicator( mode="gauge+number", value=indicator_number, title={"text": indicator_title, "font": {"size": 23}}, #subtitle={'text': "Subtítulo"}, domain={'x': [0, 1], 'y': [0, 1]}, number={ "prefix": indicator_suffix, #str(formatar_moeda(indicator_suffix)) #"suffix": indicator_suffix, "font.size": 35, "valueformat": ",.2f" }, gauge={'axis': {'range': [None, bigMeta + bigMeta*0.05]}, 'bar': {'color': indicator_color}, 'steps': [ {'range': [0, Meta], 'color': "#6196ee"}, {'range': [Meta, bigMeta + bigMeta*0.05], 'color': "#59bb71"}], #'threshold': { 'line': {'color': indicator_color, 'width': 4}, 'thickness': 0.75, 'value': indicator_number} } )) fig.add_annotation( x=0.5, y=0.4, xref='paper',yref='paper', text= 'Meta: ' + str(formatar_moeda(Meta)), font=dict(size=12), showarrow=False ) fig.add_annotation( x=0.5, y=0.24, xref='paper',yref='paper', text= 'BiG Meta: ' + str(formatar_moeda(bigMeta)), font=dict(size=12), showarrow=False ) fig.update_layout( #paper_bgcolor="#262730", height=200, margin=dict(l=10, r=10, t=50, b=10, pad=8), ) st.plotly_chart(fig, use_container_width=True) st.markdown("---") def plot_top_right(): sales_data = duckdb.sql( f""" WITH sales_data AS ( UNPIVOT ( SELECT Scenario, business_unit, {','.join(all_months)} FROM df WHERE Year='2023' AND Account='Sales' ) ON {','.join(all_months)} INTO NAME month VALUE sales ), aggregated_sales AS ( SELECT Scenario, business_unit, SUM(sales) AS sales FROM sales_data GROUP BY Scenario, business_unit ) SELECT * FROM aggregated_sales """ ).df() fig = px.bar( sales_data, x="business_unit", y="sales", color="Scenario", barmode="group", text_auto=".2s", title="Sales for Year 2023", height=400, ) fig.update_traces( textfont_size=12, textangle=0, textposition="outside", cliponaxis=False ) st.plotly_chart(fig, use_container_width=True) def plot_bottom_left(): sales_data = duckdb.sql( f""" WITH sales_data AS ( SELECT Scenario,{','.join(all_months)} FROM df WHERE Year='2023' AND Account='Sales' AND business_unit='Software' ) UNPIVOT sales_data ON {','.join(all_months)} INTO NAME month VALUE sales """ ).df() fig = px.line( sales_data, x="month", y="sales", color="Scenario", markers=True, text="sales", title="Monthly Budget vs Forecast 2023", ) fig.update_traces(textposition="top center") st.plotly_chart(fig, use_container_width=True) def plot_bottom_right(): sales_data = duckdb.sql( f""" WITH sales_data AS ( UNPIVOT ( SELECT Account,Year,{','.join([f'ABS({month}) AS {month}' for month in all_months])} FROM df WHERE Scenario='Actuals' AND Account!='Sales' ) ON {','.join(all_months)} INTO NAME year VALUE sales ), aggregated_sales AS ( SELECT Account, Year, SUM(sales) AS sales FROM sales_data GROUP BY Account, Year ) SELECT * FROM aggregated_sales """ ).df() fig = px.bar( sales_data, x="Year", y="sales", color="Account", title="Actual Yearly Sales Per Account", ) st.plotly_chart(fig, use_container_width=True) ############################################################################################## ####################### # Dashboard Main Panel st.title('Vendas Totalizador') # Exibindo o componente de métrica com o valor formatado st.metric(label="Total Geral", value=formatar_moeda(df['valor_total'].sum()), delta="Meta: " + formatar_moeda(df['mta_meta'].sum()) + " - BigMeta: " + formatar_moeda(df['mta_big_meta'].sum())) #Ordenando o dataframe df = df.sort_values(by='cod_und', ascending=True) st.markdown('#### Ranking' ) df_selected_year_sorted = df.sort_values(by="valor_total", ascending=False) df_selected_year_sorted['valor_total_formatado'] = df_selected_year_sorted['valor_total'].apply(formatar_moeda) df_selected_year_sorted['mta_meta_formatado'] = df_selected_year_sorted['mta_meta'].apply(formatar_moeda) df_selected_year_sorted['mta_big_meta_formatado'] = df_selected_year_sorted['mta_big_meta'].apply(formatar_moeda) df_selected_year_sorted['tkt_medio_formatado'] = df_selected_year_sorted['tkt_medio'].apply(formatar_moeda) df_selected_year_sorted['mta_tkt_medio_formatado'] = df_selected_year_sorted['mta_meta_tkt_medio'].apply(formatar_moeda) st.dataframe(df_selected_year_sorted, column_order=("unidade", "qntd_pedidos", "valor_total_formatado", "valor_total", "mta_meta_formatado", "mta_big_meta_formatado", "tkt_medio_formatado", "mta_tkt_medio_formatado" ), hide_index=True, width=None, column_config= { "unidade": st.column_config.TextColumn( "Unidade", ), "qntd_pedidos": st.column_config.ProgressColumn( "Qntd", format="%f", min_value=0, max_value=max(df_selected_year_sorted.qntd_pedidos), width=100, ), "valor_total_formatado": st.column_config.TextColumn( "Valor Total", ), "valor_total": st.column_config.ProgressColumn( "Ranking Vendas", format=" ", min_value=0, max_value=max(df_selected_year_sorted.valor_total), ), "mta_meta_formatado": st.column_config.TextColumn( "Meta", ), "mta_big_meta_formatado": st.column_config.TextColumn( "BiG Meta", ), "tkt_medio_formatado": st.column_config.TextColumn( "Tkt Médio", ), "mta_tkt_medio_formatado": st.column_config.TextColumn( "Meta Tkt Médio", ), } ) #Gráicos de vendas # Iterando sobre as linhas for index, row in df.iterrows(): # Extrair valores do DataFrame codUnidade = row['cod_und'] Unidade = row['unidade'] ValorVendido = row['valor_total'] MetaMes = row['mta_meta'] plot_gauge(ValorVendido, "#262626", "R$", str(Unidade) , row['mta_meta'], row['mta_meta'], row['mta_big_meta']) #str(formatar_moeda(ValorVendido)) # ---------------------------------------------------------- # Rotina Vendas por Grupo elif selected == "Vendas por Grupo Merc": def selecionar_periodo(): while True: selected_dates = st.date_input( 'Selecione o intervalo de datas:', [datetime.datetime.now(), datetime.datetime.now()], #format="YYYY/MM/DD" format="DD/MM/YYYY" ) if len(selected_dates) == 2: return selected_dates[0], selected_dates[1] else: st.warning("Por favor, selecione as duas datas.") start_date, end_date = selecionar_periodo() rerun_button = st.button("Atualizar") if rerun_button: st.rerun() query_grupo = """ SELECT * FROM ( SELECT COD || ' - ' || GRUPO AS GRUPO, SUM( VALOR ) AS VALOR FROM ( SELECT SUM( TPED_PEDIDO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR, TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK AS COD, TMER_GRUPO_MERCADORIA.TMER_DESCRICAO AS GRUPO FROM TPED_PEDIDO_VENDA_ITEM LEFT JOIN TPED_PEDIDO_VENDA ON TPED_PEDIDO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_PEDIDO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_PEDIDO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK LEFT JOIN TMER_GRUPO_MERCADORIA ON TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK = TMER_MERCADORIA.TMER_GRUPO_MERCADORIA_FK WHERE TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_PEDIDO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK = TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TMER_GRUPO_MERCADORIA.TMER_DESCRICAO, TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK UNION ALL SELECT SUM( TPED_HISTORICO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR, TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK AS COD, TMER_GRUPO_MERCADORIA.TMER_DESCRICAO AS GRUPO FROM TPED_HISTORICO_VENDA_ITEM LEFT JOIN TPED_HISTORICO_VENDA ON TPED_HISTORICO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_HISTORICO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_HISTORICO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK LEFT JOIN TMER_GRUPO_MERCADORIA ON TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK = TMER_MERCADORIA.TMER_GRUPO_MERCADORIA_FK WHERE TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_HISTORICO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK = TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TMER_GRUPO_MERCADORIA.TMER_DESCRICAO, TMER_GRUPO_MERCADORIA.TMER_GRUPO_MERCADORIA_PK ) GROUP BY COD || ' - ' || GRUPO ORDER BY 2 DESC ) WHERE ROWNUM <= 10 """ df_grupo = pd.read_sql(query_grupo, engine, params={"start_date": start_date, "end_date": end_date}) #value = formatar_moeda(df_grupo['VALOR'].sum()) st.markdown("## Top 10 - Grupo de Mercadorias") #st.title('Top 10 - Grupo de Mercadorias') # Criando os dados do gráfico grupos = df_grupo["grupo"].tolist() valores = df_grupo["valor"].tolist() valores_formatados = [formatar_moeda(v) for v in valores] # Criando versão formatada para exibição # Criando um gráfico de barras com rótulos formatados fig = go.Figure() # Inicializando a figura trace = go.Bar( x=grupos, y=valores, xaxis='x2', yaxis='y2', marker=dict(color='#0099ff'), name='Valores', text=valores_formatados, # Exibir valores formatados nos rótulos textposition='auto' # Exibir rótulos automaticamente ) # Adicionando o gráfico à figura fig.add_trace(trace) # Configurando layout para o gráfico fig.update_layout( yaxis2=dict(domain=[0, 1], anchor='x2', title='Valor'), # Ajustando a posição do gráfico xaxis2=dict(anchor='y2'), #margin=dict(t=500, l=50, b=50), # Margens para o gráfico #title='Top 10 - Grupo de Mercadorias', height=500 # Ajustando a altura do gráfico ) # Exibindo a figura no Streamlit st.plotly_chart(fig, use_container_width=True) # Exibindo a tabela if not df_grupo.empty: # Aplicando a formatação de moeda na coluna VALOR df_grupo["valor"] = df_grupo["valor"].apply(formatar_moeda) # Ajustando o índice para começar em 1 e nomeando a coluna como "Ranking" df_grupo.index = df_grupo.index + 1 df_grupo.index.name = "Ranking" df_grupo.rename(columns={"grupo": "Grupo", "valor": "Valor Total"}, inplace=True) st.dataframe(df_grupo) else: st.warning("Não há dados para o período selecionado.") # ---------------------------------------------------------- # Rotina Vendas por Fornecedor elif selected == "Vendas por Fornecedor": def selecionar_periodo(): while True: selected_dates = st.date_input( 'Selecione o intervalo de datas:', [datetime.datetime.now(), datetime.datetime.now()], format="DD/MM/YYYY" ) if len(selected_dates) == 2: return selected_dates[0], selected_dates[1] else: st.warning("Por favor, selecione as duas datas.") start_date, end_date = selecionar_periodo() rerun_button = st.button("Atualizar") if rerun_button: st.rerun() query_fornecedor = """ SELECT TMER_FORNECEDOR_PRINCIPAL_FK || ' - ' || TFOR_FORNECEDOR.TFOR_NOME_RAZAO AS FORNECEDOR, SUM( VALOR ) AS VALOR FROM ( SELECT TMER_ESTOQUE.TMER_FORNECEDOR_PRINCIPAL_FK, SUM( TPED_PEDIDO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_PEDIDO_VENDA_ITEM LEFT JOIN TPED_PEDIDO_VENDA ON TPED_PEDIDO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_PEDIDO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_PEDIDO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK WHERE TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_PEDIDO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TMER_ESTOQUE.TMER_FORNECEDOR_PRINCIPAL_FK UNION ALL SELECT TMER_ESTOQUE.TMER_FORNECEDOR_PRINCIPAL_FK, SUM( TPED_HISTORICO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_HISTORICO_VENDA_ITEM LEFT JOIN TPED_HISTORICO_VENDA ON TPED_HISTORICO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_HISTORICO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_HISTORICO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK WHERE TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_HISTORICO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TMER_ESTOQUE.TMER_FORNECEDOR_PRINCIPAL_FK ) LEFT JOIN TFOR_FORNECEDOR ON TFOR_FORNECEDOR.TFOR_FORNECEDOR_PK = TMER_FORNECEDOR_PRINCIPAL_FK WHERE ROWNUM <= 20 GROUP BY TMER_FORNECEDOR_PRINCIPAL_FK || ' - ' || TFOR_FORNECEDOR.TFOR_NOME_RAZAO ORDER BY VALOR DESC """ df_fornecedor = pd.read_sql(query_fornecedor, engine, params={"start_date": start_date, "end_date": end_date}) st.markdown("## Top 20 - Fornecedores") # Criando os dados do gráfico grupos = df_fornecedor["fornecedor"].tolist() valores = df_fornecedor["valor"].tolist() valores_formatados = [formatar_moeda(v) for v in valores] # Criando versão formatada para exibição # Criando um gráfico de barras com rótulos formatados fig = go.Figure() # Inicializando a figura trace = go.Bar( x=grupos, y=valores, xaxis='x2', yaxis='y2', marker=dict(color='#0099ff'), name='Valores', text=valores_formatados, # Exibir valores formatados nos rótulos textposition='auto' # Exibir rótulos automaticamente ) # Adicionando o gráfico à figura fig.add_trace(trace) # Configurando layout para o gráfico fig.update_layout( yaxis2=dict(domain=[0, 1], anchor='x2', title='Valor'), # Ajustando a posição do gráfico xaxis2=dict(anchor='y2'), #margin=dict(t=500, l=50, b=50), # Margens para o gráfico #title='Top 20 Fornecedores', height=500 # Ajustando a altura do gráfico ) # Exibindo a figura no Streamlit st.plotly_chart(fig, use_container_width=True) # Exibindo a tabela if not df_fornecedor.empty: # Aplicando a formatação de moeda na coluna VALOR df_fornecedor["valor"] = df_fornecedor["valor"].apply(formatar_moeda) # Ajustando o índice para começar em 1 e nomeando a coluna como "Ranking" df_fornecedor.index = df_fornecedor.index + 1 df_fornecedor.index.name = "Ranking" df_fornecedor.rename(columns={"fornecedor": "Fornecedor", "valor": "Valor Total"}, inplace=True) st.dataframe(df_fornecedor) else: st.warning("Não há dados para o período selecionado.") # ---------------------------------------------------------- # Rotina Vendas por Operador elif selected == "Vendas por Operador": def selecionar_periodo(): while True: selected_dates = st.date_input( 'Selecione o intervalo de datas:', [datetime.datetime.now(), datetime.datetime.now()], format="DD/MM/YYYY" ) if len(selected_dates) == 2: return selected_dates[0], selected_dates[1] else: st.warning("Por favor, selecione as duas datas.") start_date, end_date = selecionar_periodo() rerun_button = st.button("Atualizar") if rerun_button: st.rerun() query_operador = """ SELECT TPED_UNIDADE_FK_PK AS UND, TPED_OPERADOR_VENDA_FKN || ' - ' || TSYS_USUARIO.TSYS_NOME AS OPERADOR, SUM( VALOR ) AS VALOR FROM ( SELECT TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK, TPED_PEDIDO_VENDA.TPED_OPERADOR_VENDA_FKN, SUM( TPED_PEDIDO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_PEDIDO_VENDA_ITEM LEFT JOIN TPED_PEDIDO_VENDA ON TPED_PEDIDO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_PEDIDO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_PEDIDO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK WHERE TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_PEDIDO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK, TPED_PEDIDO_VENDA.TPED_OPERADOR_VENDA_FKN UNION ALL SELECT TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK, TPED_HISTORICO_VENDA.TPED_OPERADOR_VENDA_FKN, SUM( TPED_HISTORICO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_HISTORICO_VENDA_ITEM LEFT JOIN TPED_HISTORICO_VENDA ON TPED_HISTORICO_VENDA.TPED_NUMERO_PEDIDO_PK = TPED_HISTORICO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK LEFT JOIN TMER_ESTOQUE ON TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK = TPED_HISTORICO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = TMER_ESTOQUE.TMER_CODIGO_PRI_FK_PK WHERE TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TMER_ESTOQUE.TMER_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_STATUS_PEDIDO = 'MA' AND TPED_HISTORICO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TMER_ESTOQUE.TMER_UNIDADE_FK_PK AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK GROUP BY TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK, TPED_HISTORICO_VENDA.TPED_OPERADOR_VENDA_FKN ) LEFT JOIN TSYS_USUARIO ON TSYS_USUARIO.TSYS_USUARIO_PK = TPED_OPERADOR_VENDA_FKN --WHERE ROWNUM <= 50 GROUP BY TPED_UNIDADE_FK_PK, TPED_OPERADOR_VENDA_FKN, TSYS_USUARIO.TSYS_NOME ORDER BY VALOR DESC """ query_operador = pd.read_sql(query_operador, engine, params={"start_date": start_date, "end_date": end_date}) # Criando os dados do gráfico grupos = query_operador["operador"].tolist() valores = query_operador["valor"].tolist() valores_formatados = [formatar_moeda(v) for v in valores] # Criando versão formatada para exibição # Criando um gráfico de barras com rótulos formatados fig = go.Figure() # Inicializando a figura trace = go.Bar( x=grupos, y=valores, xaxis='x2', yaxis='y2', marker=dict(color='#0099ff'), name='Valores', text=valores_formatados, # Exibir valores formatados nos rótulos textposition='auto' # Exibir rótulos automaticamente ) st.markdown("## Vendas por Operador") # Adicionando o gráfico à figura fig.add_trace(trace) # Configurando layout para o gráfico fig.update_layout( yaxis2=dict(domain=[0, 1], anchor='x2', title='Valor'), # Ajustando a posição do gráfico xaxis2=dict(anchor='y2'), #margin=dict(t=500, l=50, b=50), # Margens para o gráfico #title='Vendas por Operador', height=500 # Ajustando a altura do gráfico ) # Exibindo a figura no Streamlit st.plotly_chart(fig, use_container_width=True) if not query_operador.empty: # # Aplicando a formatação de moeda na coluna VALOR query_operador["valor"] = query_operador["valor"].apply(formatar_moeda) # Ajustando o índice para começar em 1 e nomeando a coluna como "Ranking" query_operador.index = query_operador.index + 1 query_operador.index.name = "Ranking" query_operador.rename(columns={"und": "Und", "operador": "Operador", "valor": "Valor"}, inplace=True) st.dataframe(query_operador) else: st.warning("Não há dados para o período selecionado.") # ---------------------------------------------------------- # Rotina Top 100 Merc. elif selected == "Top 100 Merc.": def selecionar_periodo(): while True: selected_dates = st.date_input( 'Selecione o intervalo de datas:', [datetime.datetime.now(), datetime.datetime.now()], format="DD/MM/YYYY" ) if len(selected_dates) == 2: return selected_dates[0], selected_dates[1] else: st.warning("Por favor, selecione as duas datas.") start_date, end_date = selecionar_periodo() rerun_button = st.button("Atualizar") if rerun_button: st.rerun() query_top100Merc = """ SELECT MERCADORIA, VALOR AS VALOR_TOTAL FROM ( SELECT COD || ' - ' || TMER_MERCADORIA.TMER_NOME AS MERCADORIA, VALOR FROM ( SELECT TPED_HISTORICO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK AS COD, SUM( TPED_HISTORICO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_HISTORICO_VENDA_ITEM LEFT JOIN TPED_HISTORICO_VENDA ON TPED_HISTORICO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK = TPED_HISTORICO_VENDA.TPED_NUMERO_PEDIDO_PK AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK = TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK WHERE TPED_HISTORICO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_HISTORICO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_HISTORICO_VENDA.TPED_STATUS_PEDIDO IN ( 'CL', 'MA' ) AND TPED_HISTORICO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' GROUP BY TPED_HISTORICO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK UNION ALL SELECT TPED_PEDIDO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK AS COD, SUM( TPED_PEDIDO_VENDA_ITEM.TPED_VALOR_LIQUIDO_ITEM ) AS VALOR FROM TPED_PEDIDO_VENDA_ITEM LEFT JOIN TPED_PEDIDO_VENDA ON TPED_PEDIDO_VENDA_ITEM.TPED_NUMERO_PEDIDO_FK_PK = TPED_PEDIDO_VENDA.TPED_NUMERO_PEDIDO_PK AND TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK = TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK WHERE TPED_PEDIDO_VENDA.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA_ITEM.TPED_UNIDADE_FK_PK IN ( '1', '3' ) AND TPED_PEDIDO_VENDA.TPED_DATA_EMISSAO BETWEEN :start_date AND :end_date AND TPED_PEDIDO_VENDA.TPED_STATUS_PEDIDO IN ( 'CL', 'MA' ) AND TPED_PEDIDO_VENDA.TPED_NATUREZA_MOVIMENTACAO = 'VM' GROUP BY TPED_PEDIDO_VENDA_ITEM.TPED_CODIGO_PRI_FK_PK ) LEFT JOIN TMER_MERCADORIA ON TMER_MERCADORIA.TMER_CODIGO_PRI_PK = COD ORDER BY VALOR DESC ) WHERE ROWNUM <= 100 """ query_top100Merc = pd.read_sql(query_top100Merc, engine, params={"start_date": start_date, "end_date": end_date}) if not query_top100Merc.empty: st.markdown("## Top 100 - Mercadorias") # Aplicando a formatação de moeda na coluna VALOR query_top100Merc["valor_total"] = query_top100Merc["valor_total"].apply(formatar_moeda) # Ajustando o índice para começar em 1 e nomeando a coluna como "Ranking" query_top100Merc.index = query_top100Merc.index + 1 query_top100Merc.index.name = "Ranking" query_top100Merc.rename(columns={"mercadoria": "Mercadoria", "valor_total": "Valor "}, inplace=True) # Exibindo a tabela com ajustes #st.dataframe(query_top100Merc, use_container_width=True, height=600) # Ajuste a altura conforme necessário st.dataframe(query_top100Merc, use_container_width=True) else: st.warning("Não há dados para o período selecionado.") if __name__ == "__main__": main()
Return