Viewing: app#
#Barreiras ( '1', '3' ) #nohup python3 -m streamlit run dashBarreiras.py --server.port 8504 --server.address 0.0.0.0 > dashBarreiras.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 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 = '10&CIA.png' 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 Barreiras", page_icon="📊", layout="wide" ) alt.themes.enable("dark") # 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") connection = cx_Oracle.connect( user="EDIUSER", password="EDIUSER", #GrupoBig #dsn="187.109.221.38:1521/PROTON" #Av7 dsn="177.234.171.14:1521/DBPROD" ) #engine = create_engine('oracle+cx_Oracle://', creator=lambda: connection) engine = create_engine('oracle+cx_oracle://EDIUSER:EDIUSER@177.234.171.14: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() #print(result) 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 Barreiras", 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