publicando mudanças
This commit is contained in:
parent
05e7958878
commit
846c8e83e6
231
Lançamentos/COMPILADOR DE ARQUIVOS EM XLSX.ipynb
Normal file
231
Lançamentos/COMPILADOR DE ARQUIVOS EM XLSX.ipynb
Normal file
@ -0,0 +1,231 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e9ac37de",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total de linhas: 875\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>UN</th>\n",
|
||||
" <th>PDV</th>\n",
|
||||
" <th>CIDADE</th>\n",
|
||||
" <th>LOCAL DO PDV</th>\n",
|
||||
" <th>RECEITA PERÍODO ANTERIOR</th>\n",
|
||||
" <th>RECEITA PERÍODO ATUAL</th>\n",
|
||||
" <th>META PEF</th>\n",
|
||||
" <th>GAP ACORDADO (R$)</th>\n",
|
||||
" <th>GAP ACORDADO (%)</th>\n",
|
||||
" <th>REALIZADO</th>\n",
|
||||
" <th>arquivo_base</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>Quem Disse Berenice</td>\n",
|
||||
" <td>910173</td>\n",
|
||||
" <td>Maceio</td>\n",
|
||||
" <td>Shopping</td>\n",
|
||||
" <td>173913.81</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>167464.53</td>\n",
|
||||
" <td>-167464.53</td>\n",
|
||||
" <td>-1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>O Boticário</td>\n",
|
||||
" <td>21381</td>\n",
|
||||
" <td>Capim Grosso</td>\n",
|
||||
" <td>Rua</td>\n",
|
||||
" <td>120594.40</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>155346.60</td>\n",
|
||||
" <td>-155346.60</td>\n",
|
||||
" <td>-1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>O Boticário</td>\n",
|
||||
" <td>23707</td>\n",
|
||||
" <td>Vitoria Da Conquista</td>\n",
|
||||
" <td>Rua</td>\n",
|
||||
" <td>131055.70</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>159139.40</td>\n",
|
||||
" <td>-159139.40</td>\n",
|
||||
" <td>-1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>O Boticário</td>\n",
|
||||
" <td>21068</td>\n",
|
||||
" <td>Simoes Filho</td>\n",
|
||||
" <td>Cash & Carry</td>\n",
|
||||
" <td>146448.38</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>144695.45</td>\n",
|
||||
" <td>-144695.45</td>\n",
|
||||
" <td>-1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>O Boticário</td>\n",
|
||||
" <td>20441</td>\n",
|
||||
" <td>Lagarto</td>\n",
|
||||
" <td>Rua</td>\n",
|
||||
" <td>225341.32</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>311878.51</td>\n",
|
||||
" <td>-311878.51</td>\n",
|
||||
" <td>-1</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên...</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" UN PDV CIDADE LOCAL DO PDV \\\n",
|
||||
"0 Quem Disse Berenice 910173 Maceio Shopping \n",
|
||||
"1 O Boticário 21381 Capim Grosso Rua \n",
|
||||
"2 O Boticário 23707 Vitoria Da Conquista Rua \n",
|
||||
"3 O Boticário 21068 Simoes Filho Cash & Carry \n",
|
||||
"4 O Boticário 20441 Lagarto Rua \n",
|
||||
"\n",
|
||||
" RECEITA PERÍODO ANTERIOR RECEITA PERÍODO ATUAL META PEF \\\n",
|
||||
"0 173913.81 0 167464.53 \n",
|
||||
"1 120594.40 0 155346.60 \n",
|
||||
"2 131055.70 0 159139.40 \n",
|
||||
"3 146448.38 0 144695.45 \n",
|
||||
"4 225341.32 0 311878.51 \n",
|
||||
"\n",
|
||||
" GAP ACORDADO (R$) GAP ACORDADO (%) REALIZADO \\\n",
|
||||
"0 -167464.53 -1 0 \n",
|
||||
"1 -155346.60 -1 0 \n",
|
||||
"2 -159139.40 -1 0 \n",
|
||||
"3 -144695.45 -1 0 \n",
|
||||
"4 -311878.51 -1 0 \n",
|
||||
"\n",
|
||||
" arquivo_base \n",
|
||||
"0 C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên... \n",
|
||||
"1 C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên... \n",
|
||||
"2 C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên... \n",
|
||||
"3 C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên... \n",
|
||||
"4 C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistên... "
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import pandas as pd\n",
|
||||
"import glob\n",
|
||||
"\n",
|
||||
"# Caminho da pasta onde estão os arquivos\n",
|
||||
"pasta = r'C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_ORÇAMENTO FIANCEIRO\\meta pef baixada hj'\n",
|
||||
"\n",
|
||||
"# Lista todos os arquivos .xlsx no diretório\n",
|
||||
"arquivos_xlsx = glob.glob(os.path.join(pasta, '*.xlsx'))\n",
|
||||
"\n",
|
||||
"# Lista para armazenar os DataFrames\n",
|
||||
"dfs = []\n",
|
||||
"\n",
|
||||
"# Loop pelos arquivos encontrados\n",
|
||||
"for arquivo in arquivos_xlsx:\n",
|
||||
" try:\n",
|
||||
" df = pd.read_excel(arquivo, sheet_name='PERFORMANCE POR PDV', skiprows=2)\n",
|
||||
" df['arquivo_base'] = arquivo\n",
|
||||
" dfs.append(df)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Erro ao ler {arquivo}: {e}\")\n",
|
||||
"\n",
|
||||
"# Concatena todos os DataFrames\n",
|
||||
"compilado_pef = pd.concat(dfs, ignore_index=True)\n",
|
||||
"\n",
|
||||
"# Exibe informações do DataFrame final\n",
|
||||
"print(f\"Total de linhas: {len(compilado_pef)}\")\n",
|
||||
"compilado_pef.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "40a4ace1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"compilado_pef.to_excel(r'C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_ORÇAMENTO FIANCEIRO\\PEF_ATUALIZADA.xlsx',index=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "949b7fdc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
901
Lançamentos/EUD_script_lançamentos.ipynb
Normal file
901
Lançamentos/EUD_script_lançamentos.ipynb
Normal file
@ -0,0 +1,901 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4dda0350",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np \n",
|
||||
"import glob\n",
|
||||
"import os "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4d6a9919",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Caminho onde estão as subpastas com os arquivos CSV\n",
|
||||
"\n",
|
||||
"# Set the path to the folder containing CSV files\n",
|
||||
"folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\draft\" # arquivo dos drafts\n",
|
||||
"\n",
|
||||
"# Pattern to match all CSV files\n",
|
||||
"csv_files = glob.glob(os.path.join(folder_path, '*.csv'))\n",
|
||||
"\n",
|
||||
"# Read and concat all CSVs\n",
|
||||
"df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n",
|
||||
"\n",
|
||||
"df_draft['match'] = 1 \n",
|
||||
"\n",
|
||||
"df_draft.shape\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aa56ee52",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"# Caminho onde estão as subpastas com os arquivos CSV\n",
|
||||
"pasta_entrada = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\estoque\"\n",
|
||||
"\n",
|
||||
"# Lista todas as subpastas dentro de \"ESTOQUE\"\n",
|
||||
"subpastas = [os.path.join(pasta_entrada, d) for d in os.listdir(pasta_entrada) if os.path.isdir(os.path.join(pasta_entrada, d))]\n",
|
||||
"\n",
|
||||
"df_list = []\n",
|
||||
"\n",
|
||||
"# Percorre todas as subpastas\n",
|
||||
"for subpasta in subpastas:\n",
|
||||
" arquivos = [f for f in os.listdir(subpasta) if f.endswith(\".csv\")]\n",
|
||||
" nome_pasta = os.path.basename(subpasta) # Obtém o nome da pasta\n",
|
||||
"\n",
|
||||
" for arquivo in arquivos:\n",
|
||||
" caminho_arquivo = os.path.join(subpasta, arquivo)\n",
|
||||
" try:\n",
|
||||
" df = pd.read_csv(caminho_arquivo, encoding=\"utf-8\", low_memory=False) # Melhor para grandes volumes de dados\n",
|
||||
" df[\"Arquivo_Origem\"] = arquivo # Adiciona o nome do arquivo de origem\n",
|
||||
" df[\"Pasta_Origem\"] = nome_pasta # Adiciona o nome da pasta de origem\n",
|
||||
" df_list.append(df)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Erro ao ler o arquivo {arquivo}: {e}\")\n",
|
||||
"\n",
|
||||
"if df_list:\n",
|
||||
" df_estoque = pd.concat(df_list, ignore_index=True)\n",
|
||||
"\n",
|
||||
"df_estoque['PDV'] = df_estoque['PDV'].astype(str)\n",
|
||||
"\n",
|
||||
"df_estoque['SKU_FINAL'] = np.where(df_estoque['SKU_PARA'] == \"-\", df_estoque['SKU'], df_estoque['SKU_PARA'])\n",
|
||||
"\n",
|
||||
"df_estoque['SKU_FINAL']=df_estoque['SKU_FINAL'].astype(str)\n",
|
||||
"\n",
|
||||
"df_estoque = df_estoque[df_estoque['Arquivo_Origem']== \"EUD.csv\"]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "db3b7495",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\data (1).xlsx\")\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ultimos2'] = df_bi_vendas['Ciclo'].str.rsplit('.', n=1).str[-1]\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ano'] = df_bi_vendas['Ciclo'].str.rsplit('.', n=1).str[0]\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ano'] = df_bi_vendas['Ciclo_ano'].str.replace(\"C\",\"\")\n",
|
||||
"\n",
|
||||
"df_bi_vendas['CICLO_FINAL'] = 'C20' + df_bi_vendas['Ciclo_ano'].astype(str) + df_bi_vendas['Ciclo_ultimos2'].astype(str)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dbd61b6a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\EUDORA\\PDV\\DB_PDV.xlsx\",sheet_name='Export')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "29504e7c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv = df_pdv.rename(columns={'DESCRIÇÃO':'DESCRIÇÃO PDV'})\n",
|
||||
"\n",
|
||||
"df_pdv = df_pdv.drop(columns=['REGIÃO', 'ESTADO','CIDADE','GESTÃO'])\n",
|
||||
"\n",
|
||||
"df_pdv['PDV'] = df_pdv['PDV DESC'].str.split(\"-\").str[0].str.strip()\n",
|
||||
"\n",
|
||||
"df_pdv['UF'] = np.where(df_pdv['UF'] == 'VDC','BA',df_pdv['UF'])\n",
|
||||
"\n",
|
||||
"#ignorando a PDV que ainda não está online\n",
|
||||
"df_pdv = df_pdv[df_pdv['DESCRIÇÃO PDV'] != '23813-COMERCIO-HIB VALENTE']\n",
|
||||
"df_pdv = df_pdv[df_pdv['STATUS'] == 'ATIVO']\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae39bc1e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"calendario = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\EUDORA\\CALENDARIO_CICLO\\Ciclo_Expandido_com_Datas.xlsx\")\n",
|
||||
"\n",
|
||||
"calendario['Date'] = pd.to_datetime(calendario['Date'])\n",
|
||||
"\n",
|
||||
"# Get today (normalized to midnight)\n",
|
||||
"today = pd.Timestamp(\"today\").normalize()\n",
|
||||
"\n",
|
||||
"calendario['NUM_CICLO'] = calendario['Ciclo'].str[-2:].astype(int)\n",
|
||||
"\n",
|
||||
"calendario['ANO_CICLO'] = calendario['Ciclo'].str[0:5]\n",
|
||||
"\n",
|
||||
"calendario = calendario[calendario['MARCA'] == \"EUDORA\"]\n",
|
||||
"\n",
|
||||
"calendario['CICLOMAIS2'] = calendario['ANO_CICLO'].astype(str) + (calendario['NUM_CICLO'].astype(int) + 3).astype(str).str.zfill(2) #<<< MUDAR O \"4\" (CICLO ATUAL + 4 PARA ACHAR O CICLO DA SUGESTÃO) EX: C202505 -> C202509\n",
|
||||
"ciclo_mais2 = calendario[calendario['Date'].dt.normalize() == today]['CICLOMAIS2'].iloc[0]\n",
|
||||
"\n",
|
||||
"# Filter rows where date matches today\n",
|
||||
"filtered_calendario = calendario[calendario['Ciclo'] == ciclo_mais2][:1]\n",
|
||||
"\n",
|
||||
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['INICIO CICLO'].iloc[0] - today\n",
|
||||
"\n",
|
||||
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['dias_ate_inicio'].dt.days.astype(int)\n",
|
||||
"\n",
|
||||
"filtered_calendario['match'] = 1\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5ac3914a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\EUDORA\\TABELA_PEDIDO\\Pedidos Semanais Especiais - GKD - 202509.xlsx\")\n",
|
||||
"\n",
|
||||
"#df_tabela = df_tabela[df_tabela['Região'] == 'NNE'] \n",
|
||||
"\n",
|
||||
"#df_tabela = df_tabela[(df_tabela['Canal'] != 'Ecomm') | (df_tabela['Canal'] != 'Ecomm | VD') | (df_tabela['Canal'] != 'Ecomm | Loja')] #perguntar se isso aqui é vdd\n",
|
||||
"\n",
|
||||
"#df_tabela['Canal'] = np.where((df_tabela['Canal'] == \"Loja\") | (df_tabela['Canal'] == \"Todos\") | (df_tabela['Canal'] == \"Loja | VD\"),\"TODOS\",\"VD\")\n",
|
||||
"\n",
|
||||
"#df_tabela = df_tabela[df_tabela['Tipo de promoção'].str.contains('Lançamentos', na=False)]#"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f8ea9d1a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\Tabela-de-Promos_C10-1746728296536.xlsx (1).xlsx\")\n",
|
||||
"\n",
|
||||
"df_tabela = df_tabela[['Código do Item','Descrição do Item','Chamada Promocional','Valor do Guia','Preço Promocionado','% de Desconto']]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1a338b98",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\PRODUTOS SIMILARES.xlsx\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "39ddc830",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares = pd.merge(left=df_similares,right=calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO']], how= 'left', left_on = 'CICLO SIMILAR',right_on = 'Ciclo' )\n",
|
||||
"\n",
|
||||
"df_similares = df_similares.drop(columns=['INICIO DO CICLO SIMILAR','FIM DO CICLO SIMILAR', 'DURAÇÃO DO CICLO DO SIMILAR','Ciclo','DESCRIÇÃO SIMILAR'])\n",
|
||||
"\n",
|
||||
"df_similares = df_similares.rename(columns={'INICIO CICLO':'INICIO CICLO SIMILAR','FIM CICLO':'FIM CICLO SIMILAR','DURAÇÃO':'DURAÇÃO CICLO SIMILAR'})\n",
|
||||
"df_similares.drop_duplicates(inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2eb0975",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft = df_draft.rename(columns={'Descrição':'DESCRIÇÃO SIMILAR'})\n",
|
||||
"\n",
|
||||
"df_draft = df_draft.drop(columns=['Categoria','Subcategoria', 'Lançamento', 'Desativação',\n",
|
||||
" 'Dias sem venda','Projeção Próximo Ciclo', 'Projeção Próximo Ciclo + 1',\n",
|
||||
" 'Promoção Próximo Ciclo', 'Promoção Próximo Ciclo + 1','Compra inteligente semanal/Sugestão de compra',\n",
|
||||
" 'Compra inteligente Próximo Ciclo',\n",
|
||||
" 'Compra inteligente Próximo Ciclo + 1', 'Item Desativado',\n",
|
||||
" 'Data Prevista Regularização', 'Carteira Bloqueada Para Novos Pedidos',\n",
|
||||
" 'Planograma', 'Quantidade por caixa', 'Preço Sell In','Item analisado', 'Histórico de Vendas do Ciclo 202505'])\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c6d00ef5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"caminho_pasta = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\EUDORA\\C10\\venda_pratico\"\n",
|
||||
"\n",
|
||||
"# Lista todos os arquivos Excel na pasta\n",
|
||||
"arquivos_excel = [\n",
|
||||
" f for f in os.listdir(caminho_pasta)\n",
|
||||
" if f.lower().endswith(('.xlsx', '.xls'))\n",
|
||||
"]\n",
|
||||
"caminho_arquivo = os.path.join(caminho_pasta, arquivos_excel[0])\n",
|
||||
"\n",
|
||||
"df_venda_diaria = pd.read_excel(caminho_arquivo)\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a82629ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_diaria['PDV'] = df_venda_diaria['Unidade de Negócio'].str.split(\"-\").str[0].str.strip()\n",
|
||||
"\n",
|
||||
"df_venda_diaria['Dia'] = pd.to_datetime(df_venda_diaria['Dia'], format='%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_venda_diaria = pd.merge(left=df_venda_diaria,right=calendario[['Ciclo','Date']],left_on='Dia',right_on='Date',how='inner')\n",
|
||||
"\n",
|
||||
"df_venda_diaria = df_venda_diaria.drop(columns='Date')\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4cd37229",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_diaria = df_venda_diaria.drop_duplicates()\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15773282",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_agrupado = df_venda_diaria.groupby(['PDV', 'Código do Produto','Ciclo'])['Quantidade'].sum().reset_index()\n",
|
||||
"df_venda_agrupado['Quantidade'].value_counts()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "11a29a22",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv['match'] = 1\n",
|
||||
"\n",
|
||||
"df_similares['match'] = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7f9ff38f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge(left=df_similares,right=df_pdv, on='match',how='inner')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "63c52601",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft['PDV'] = df_draft['PDV'].astype(str)\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_draft,right_on=['SKU','PDV'],left_on=['PRODUTO SIMILAR','PDV'],how='left')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6dcc2058",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares['MATCH'] = 1 \n",
|
||||
"df_pdv['MATCH'] = 1\n",
|
||||
"\n",
|
||||
"df_temp = pd.merge(right=df_similares[['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO','MATCH']],left=df_pdv, on= 'MATCH',how='inner')\n",
|
||||
"df_temp = df_temp.drop_duplicates()\n",
|
||||
"\n",
|
||||
"df_temp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "90a54c84",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['match'] = 1\n",
|
||||
"df_final['match'] = df_final['match'].astype(int)\n",
|
||||
"df_final = pd.merge(left=df_final, right=filtered_calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO','match','dias_ate_inicio']], right_on='match',left_on='match',how='inner')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15b16b69",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#df_final['PDV'] = df_final['PDV'].astype(str)\n",
|
||||
"\n",
|
||||
"#df_final = pd.merge(left=df_final,right=df_pdv[['PDV', 'CANAL', 'DESCRIÇÃO PDV', 'PDV DESC','UF','ANALISTA','SUPERVISOR']],on = 'PDV',how='inner')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6a453dc4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas = df_bi_vendas.rename(columns={'Quantidade':'Vendas Ciclo Lançamento'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a2a92cc7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas['PDV'] = df_bi_vendas['PDV'].astype(str) \n",
|
||||
"df_bi_vendas['SKU2'] = df_bi_vendas['SKU2'].astype(str) \n",
|
||||
"\n",
|
||||
"df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final['SKU'] = df_final['SKU'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_bi_vendas,right_on=['PDV','SKU2','CICLO_FINAL'],left_on=['PDV','PRODUTO SIMILAR','CICLO SIMILAR'],how='left')\n",
|
||||
"df_final.shape "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b8cf0aa0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns='Quantidade') "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "085cde87",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['SKU','match',\n",
|
||||
" 'Ciclo_y',\n",
|
||||
" 'SKU1', 'SKU2', 'Campanha','TOTAL PV',\n",
|
||||
" 'Ciclo_ultimos2', 'Ciclo_ano', 'CICLO_FINAL'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "57d4871f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['CANAL'] = np.where((df_final['CANAL'] == 'LJ') | (df_final['CANAL'] == 'HIB'), \"TODOS\" , np.where((df_final['CANAL'] == 'CD') | (df_final['CANAL'] == 'VD'), \"VD\", df_final['CANAL']))\n",
|
||||
"\n",
|
||||
"df_final['CANAL'].value_counts()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e4e5868e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_tabela['Código do Item'] = df_tabela['Código do Item'].astype(str).str.replace('.0','',regex=False)\n",
|
||||
"df_final['PRODUTO LANÇAMENTO'] = df_final['PRODUTO LANÇAMENTO'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_tabela,right_on=['Código do Item'],left_on=['PRODUTO LANÇAMENTO'],how='left')\n",
|
||||
"df_final.shape "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d6b65a39",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_estoque = df_estoque.rename(columns={'SKU_FINAL':'SKU_PARA_VALIDACAO'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aaa90522",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge( left= df_final, right = df_estoque[['SKU_PARA_VALIDACAO','Arquivo_Origem','PDV']], left_on= ['PRODUTO SIMILAR','PDV'], right_on=['SKU_PARA_VALIDACAO','PDV'], how='left')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "94f1a76f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=[\n",
|
||||
"'SKU_PARA_VALIDACAO'\n",
|
||||
"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "efa6b757",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['PDV_SKU'] = df_final['PDV'].astype(str) + df_final['PRODUTO SIMILAR'].astype(str) \n",
|
||||
"\n",
|
||||
"df_final['UFPRODUTO'] = df_final['UF'].astype(str) + df_final['PRODUTO SIMILAR'].astype(str)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"VENDA_SIMILAR_6_MESES= df_final.columns[22:28]\n",
|
||||
"\n",
|
||||
"df_final['Pico Vendas Similar Ultimos 6 ciclos'] = df_final[VENDA_SIMILAR_6_MESES].max(axis=1)\n",
|
||||
"\n",
|
||||
"df_final = df_final.drop_duplicates()\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f10b3982",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_agrupado['Código do Produto'] = df_venda_agrupado['Código do Produto'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_venda_agrupado,right_on=['PDV','Código do Produto','Ciclo'],left_on=['PDV','PRODUTO SIMILAR','CICLO SIMILAR'],how='left')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8f96e45b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['Ciclo','Código do Produto','Vendas Ciclo Lançamento'])\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'Quantidade':'Vendas Ciclo Lançamento'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "596cd352",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[24:41]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "41c64323",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n",
|
||||
"colunas_mensais = df_final.columns[24:41]\n",
|
||||
"\n",
|
||||
"# Passo 1: Soma todas as linhas (itens) por mês → resultado: total por mês\n",
|
||||
"soma_mensal = df_final[colunas_mensais].sum()\n",
|
||||
"\n",
|
||||
"# Passo 2: Calcula a variação percentual de um mês para o outro\n",
|
||||
"variacao_mensal = soma_mensal.pct_change()\n",
|
||||
"\n",
|
||||
"# Passo 3: Calcula a média da variação (ignorando o primeiro NaN)\n",
|
||||
"media_variacao = variacao_mensal[1:].mean()\n",
|
||||
"\n",
|
||||
"# Calcula média e desvio padrão\n",
|
||||
"media = variacao_mensal.mean()\n",
|
||||
"desvio = variacao_mensal.std()\n",
|
||||
"\n",
|
||||
"# Define limite (ex: 2 desvios padrão)\n",
|
||||
"limite_superior = media + 2 * desvio\n",
|
||||
"limite_inferior = media - 2 * desvio\n",
|
||||
"\n",
|
||||
"# Filtra dados dentro do limite\n",
|
||||
"filtro = variacao_mensal.between(limite_inferior, limite_superior)\n",
|
||||
"df_filtrado = variacao_mensal[filtro]\n",
|
||||
"CRESCIMENTO = round(df_filtrado.mean(),4)\n",
|
||||
"\n",
|
||||
"df_final['CRESCIMENTO'] = CRESCIMENTO\n",
|
||||
"\n",
|
||||
"CRESCIMENTO\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f32d8326",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[28:29]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3c027cfc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"venda_similar_mesmo_ciclo_ano_passado = df_final.columns[28:29] #<<<<<<< CICLO ATUAL É [10:11]\n",
|
||||
"ciclo_ano_passado = df_final.columns[18:19].str.split(\" \")[0][-1]\n",
|
||||
"df_final[ciclo_ano_passado] = df_final[venda_similar_mesmo_ciclo_ano_passado]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "28f74b58",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['Vendas Ciclo Lançamento'] = df_final['Vendas Ciclo Lançamento'].fillna(0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "58642d77",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vendas_todos_historicos = df_final.columns[24:40]\n",
|
||||
"\n",
|
||||
"df_final['MEDIANA DO HISTÓRICO'] = df_final[vendas_todos_historicos].median(axis=1)\n",
|
||||
"\n",
|
||||
"df_final['MEDIANA DO HISTÓRICO'] = np.where((df_final['MEDIANA DO HISTÓRICO']<1) & (df_final['MEDIANA DO HISTÓRICO'] >0),1,df_final['MEDIANA DO HISTÓRICO'] )#validar se foi\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "69473155",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"crescimento = df_final['CRESCIMENTO']\n",
|
||||
"vendas_lanc = df_final['Vendas Ciclo Lançamento']\n",
|
||||
"pico_similar = df_final['Pico Vendas Similar Ultimos 6 ciclos']\n",
|
||||
"mediana_hist = df_final['MEDIANA DO HISTÓRICO']\n",
|
||||
"\n",
|
||||
"# Primeiro cálculo intermediário\n",
|
||||
"calc_lanc = crescimento * vendas_lanc + vendas_lanc\n",
|
||||
"calc_pico = crescimento * pico_similar + pico_similar\n",
|
||||
"\n",
|
||||
"df_final['PV GINSENG'] = np.where(\n",
|
||||
" calc_lanc != 0,\n",
|
||||
" round(calc_lanc, 0),\n",
|
||||
" np.where(\n",
|
||||
" mediana_hist > 0,\n",
|
||||
" round(crescimento * mediana_hist + mediana_hist,0),\n",
|
||||
" round(calc_pico/2, 0)\n",
|
||||
" )\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ea512a48",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[39]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3cf3efe7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.rename(columns={df_final.columns[36]: \"C-4\", df_final.columns[37]: \"C-3\",df_final.columns[38]: \"C-2\",df_final.columns[39]: \"C-1\"})\n",
|
||||
"\n",
|
||||
"df_final.drop(columns=df_final.columns[28:35], inplace=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2b8b3551",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"marca_promo = df_estoque['Arquivo_Origem'].iloc[0].replace('.csv','')\n",
|
||||
"\n",
|
||||
"df_final['INICIO CICLO'] = pd.to_datetime(df_final['INICIO CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['FIM CICLO'] = pd.to_datetime(df_final['FIM CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['INICIO CICLO SIMILAR'] = pd.to_datetime(df_final['INICIO CICLO SIMILAR'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['FIM CICLO SIMILAR'] = pd.to_datetime(df_final['FIM CICLO SIMILAR'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'Ciclo_x': 'Ciclo'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "93b589d9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "43f96709",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['CRESCIMENTO','dias_ate_inicio','UFPRODUTO','Arquivo_Origem','UFPRODUTO','Código do Item','PDV_SKU',\n",
|
||||
" 'FIM DO CICLO','INICIO DO CICLO','DURAÇÃO CICLO'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "edd78734",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge(left=df_final,right=df_pdv[['PDV','CANAL','UF']],how='inner',on='PDV')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7ac9e24c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c4cbae7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['CANAL_x'])\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'CANAL_y':'CANAL', 'UF_y':'UF'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7d904672",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Columns to bring up front\n",
|
||||
"priority_cols = [\n",
|
||||
" 'Ciclo','INICIO CICLO','FIM CICLO','ANALISTA','SUPERVISOR','UF','CANAL','PDV', 'DESCRIÇÃO PDV','DURAÇÃO',\t\n",
|
||||
" 'PRODUTO LANÇAMENTO','DESCRIÇÃO DO LANÇAMENTO',\n",
|
||||
" 'PRODUTO SIMILAR','DESCRIÇÃO SIMILAR','CICLO SIMILAR','INICIO CICLO SIMILAR','FIM CICLO SIMILAR','Estoque Atual',\n",
|
||||
" 'Estoque em Transito',\t'Pedido Pendente',\n",
|
||||
"\t'C-4',\t'C-3',\t'C-2',\t'C-1'\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# All remaining columns\n",
|
||||
"other_cols = [col for col in df_final.columns if col not in priority_cols]\n",
|
||||
"\n",
|
||||
"# Reorder\n",
|
||||
"df_final = df_final[priority_cols + other_cols]\n",
|
||||
"\n",
|
||||
"df_final['SUGESTÃO ABTASTECIMENTO'] = ''\n",
|
||||
"\n",
|
||||
"df_final['VENDAS R$ ABASTECIMENTO'] = ''\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9d817ecd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"colunas_usadas = ['PDV', 'PRODUTO LANÇAMENTO', '% de Desconto', 'Chamada Promocional']\n",
|
||||
"df_temp = df_final[[col for col in colunas_usadas if col in df_final.columns]].copy()\n",
|
||||
"\n",
|
||||
"# Agrupa por PDV e PRODUTO LANÇAMENTO\n",
|
||||
"agrupado = df_temp.groupby(['PDV', 'PRODUTO LANÇAMENTO'], dropna=False).agg({\n",
|
||||
" '% de Desconto': lambda x: list(pd.unique(x.dropna())),\n",
|
||||
" 'Chamada Promocional': lambda x: list(pd.unique(x.dropna())),\n",
|
||||
"}).reset_index()\n",
|
||||
"\n",
|
||||
"# Expande para colunas fixas com nomes novos e valores em branco se vazio\n",
|
||||
"for i in range(4):\n",
|
||||
" agrupado[f'% de desconto_{i+1}'] = agrupado['% de Desconto'].apply(lambda x: x[i] if len(x) > i else '')\n",
|
||||
" agrupado[f'Mecanica de desconto_{i+1}'] = agrupado['Chamada Promocional'].apply(lambda x: x[i] if len(x) > i else '')\n",
|
||||
"\n",
|
||||
"# Remove as colunas de lista original\n",
|
||||
"agrupado = agrupado.drop(columns=['% de Desconto', 'Chamada Promocional'])\n",
|
||||
"\n",
|
||||
"# Junta ao df_final\n",
|
||||
"colunas_merge = ['PDV', 'PRODUTO LANÇAMENTO']\n",
|
||||
"df_final = df_final.merge(agrupado, on=colunas_merge, how='left')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "446d0d5b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['Chamada Promocional','Preço Promocionado','% de Desconto','Descrição do Item','TIPO PRODUTO'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "922d2af3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop_duplicates()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "92d051d8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "08faefd9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"from openpyxl import load_workbook\n",
|
||||
"from openpyxl.styles import PatternFill, Font\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Export to Excel\n",
|
||||
"output_file = f'C:\\\\Users\\\\joao.herculano\\\\Documents\\\\Lançamento_{marca_promo}_{ciclo_mais2}COMPLEMENTO.xlsx'\n",
|
||||
"with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n",
|
||||
" df_final.to_excel(writer, index=False, sheet_name='Sheet1')\n",
|
||||
"\n",
|
||||
"# Apply styles\n",
|
||||
"wb = load_workbook(output_file)\n",
|
||||
"ws = wb['Sheet1']\n",
|
||||
"\n",
|
||||
"# Style header\n",
|
||||
"header_fill = PatternFill(start_color='ADD8E6', end_color='ADD8E6', fill_type='solid') # Light Blue\n",
|
||||
"header_font = Font(color='FFFFFF', bold=True) # White & Bold\n",
|
||||
"\n",
|
||||
"for cell in ws[1]:\n",
|
||||
" cell.fill = header_fill\n",
|
||||
" cell.font = header_font\n",
|
||||
"\n",
|
||||
"# Style rows: gray/white alternating\n",
|
||||
"gray_fill = PatternFill(start_color='DDDDDD', end_color='DDDDDD', fill_type='solid') # Light gray\n",
|
||||
"\n",
|
||||
"for i, row in enumerate(ws.iter_rows(min_row=2, max_row=ws.max_row), start=2):\n",
|
||||
" if i % 2 == 0:\n",
|
||||
" for cell in row:\n",
|
||||
" cell.fill = gray_fill\n",
|
||||
"\n",
|
||||
"# Save styled workbook\n",
|
||||
"wb.save(output_file)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
949
Lançamentos/boti_script_lançamentos.ipynb
Normal file
949
Lançamentos/boti_script_lançamentos.ipynb
Normal file
@ -0,0 +1,949 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4dda0350",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np \n",
|
||||
"import glob\n",
|
||||
"import os "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4d6a9919",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Caminho onde estão as subpastas com os arquivos CSV\n",
|
||||
"\n",
|
||||
"# Set the path to the folder containing CSV files\n",
|
||||
"folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\DRAFT_HISTÓRICO DE VENDAS_MAR\" # arquivo dos drafts\n",
|
||||
"\n",
|
||||
"# Pattern to match all CSV files\n",
|
||||
"csv_files = glob.glob(os.path.join(folder_path, '*.csv'))\n",
|
||||
"\n",
|
||||
"# Read and concat all CSVs\n",
|
||||
"df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n",
|
||||
"\n",
|
||||
"df_draft['match'] = 1 \n",
|
||||
"\n",
|
||||
"df_draft.shape\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9fdbd4df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e72bee99",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#df_draft = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\DRAFT_HISTÓRICO DE VENDAS_MAR\\pegou em excel\\DRAFT_PDVS_SEM_23701-20992_20250423090756.xlsx\",sheet_name='BOTICARIO')\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#df_draft['match'] = 1 \n",
|
||||
"\n",
|
||||
"#df_draft.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7d0f7992",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft = df_draft.drop(columns='Quantidade')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aa56ee52",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"# Caminho onde estão as subpastas com os arquivos CSV\n",
|
||||
"pasta_entrada = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\ESTOQUE_ATUAL\"\n",
|
||||
"\n",
|
||||
"# Lista todas as subpastas dentro de \"ESTOQUE\"\n",
|
||||
"subpastas = [os.path.join(pasta_entrada, d) for d in os.listdir(pasta_entrada) if os.path.isdir(os.path.join(pasta_entrada, d))]\n",
|
||||
"\n",
|
||||
"df_list = []\n",
|
||||
"\n",
|
||||
"# Percorre todas as subpastas\n",
|
||||
"for subpasta in subpastas:\n",
|
||||
" arquivos = [f for f in os.listdir(subpasta) if f.endswith(\".csv\")]\n",
|
||||
" nome_pasta = os.path.basename(subpasta) # Obtém o nome da pasta\n",
|
||||
"\n",
|
||||
" for arquivo in arquivos:\n",
|
||||
" caminho_arquivo = os.path.join(subpasta, arquivo)\n",
|
||||
" try:\n",
|
||||
" df = pd.read_csv(caminho_arquivo, encoding=\"utf-8\", low_memory=False) # Melhor para grandes volumes de dados\n",
|
||||
" df[\"Arquivo_Origem\"] = arquivo # Adiciona o nome do arquivo de origem\n",
|
||||
" df[\"Pasta_Origem\"] = nome_pasta # Adiciona o nome da pasta de origem\n",
|
||||
" df_list.append(df)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Erro ao ler o arquivo {arquivo}: {e}\")\n",
|
||||
"\n",
|
||||
"if df_list:\n",
|
||||
" df_estoque = pd.concat(df_list, ignore_index=True)\n",
|
||||
"\n",
|
||||
"df_estoque['PDV'] = df_estoque['PDV'].astype(str)\n",
|
||||
"\n",
|
||||
"df_estoque['SKU_FINAL'] = np.where(df_estoque['SKU_PARA'] == \"-\", df_estoque['SKU'], df_estoque['SKU_PARA'])\n",
|
||||
"\n",
|
||||
"df_estoque['SKU_FINAL']=df_estoque['SKU_FINAL'].astype(str)\n",
|
||||
"\n",
|
||||
"df_estoque = df_estoque[df_estoque['Arquivo_Origem']== \"BOT.csv\"]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "db3b7495",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\VENDAS BI\\data (1).xlsx\")\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ultimos2'] = df_bi_vendas['Ciclo'].str.rsplit('.', n=1).str[-1]\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ano'] = df_bi_vendas['Ciclo'].str.rsplit('.', n=1).str[0]\n",
|
||||
"\n",
|
||||
"df_bi_vendas['Ciclo_ano'] = df_bi_vendas['Ciclo_ano'].str.replace(\"C\",\"\")\n",
|
||||
"\n",
|
||||
"df_bi_vendas['CICLO_FINAL'] = 'C20' + df_bi_vendas['Ciclo_ano'].astype(str) + df_bi_vendas['Ciclo_ultimos2'].astype(str)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "113a3032",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "29504e7c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\PDV\\PDV_ATT.xlsx\")\n",
|
||||
"\n",
|
||||
"df_pdv_origi = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\PDV\\PDV_ATT.xlsx\")\n",
|
||||
"\n",
|
||||
"df_pdv = df_pdv.rename(columns={'DESCRIÇÃO':'DESCRIÇÃO PDV'})\n",
|
||||
"\n",
|
||||
"df_pdv = df_pdv.drop(columns=['REGIÃO', 'ESTADO','CIDADE','GESTÃO', 'status'])\n",
|
||||
"\n",
|
||||
"df_pdv['PDV'] = df_pdv['PDV DESC'].str.split(\"-\").str[0].str.strip()\n",
|
||||
"\n",
|
||||
"df_pdv['UF'] = np.where(df_pdv['UF'] == 'VDC','BA',df_pdv['UF'])\n",
|
||||
"\n",
|
||||
"#ignorando a PDV que ainda não está online\n",
|
||||
"df_pdv = df_pdv[df_pdv['DESCRIÇÃO PDV'] != '23813-COMERCIO-HIB VALENTE']\n",
|
||||
"\n",
|
||||
"df_pdv = df_pdv[df_pdv['SUPERVISOR'] != \"Inativa\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7c7c8be1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv['PDV'] = df_pdv['PDV'].fillna(0).astype('int64')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae39bc1e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"calendario = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\CICLO 9\\CALENDARIO_CICLO\\Ciclo_Expandido_com_Datas.xlsx\")\n",
|
||||
"\n",
|
||||
"calendario['Date'] = pd.to_datetime(calendario['Date'])\n",
|
||||
"\n",
|
||||
"# Get today (normalized to midnight)\n",
|
||||
"today = pd.Timestamp(\"today\").normalize()\n",
|
||||
"\n",
|
||||
"calendario['NUM_CICLO'] = calendario['Ciclo'].str[-2:].astype(int)\n",
|
||||
"\n",
|
||||
"calendario['ANO_CICLO'] = calendario['Ciclo'].str[0:5]\n",
|
||||
"\n",
|
||||
"calendario = calendario[calendario['MARCA'] == \"BOTICARIO\"]\n",
|
||||
"\n",
|
||||
"calendario['CICLOMAIS2'] = calendario['ANO_CICLO'].astype(str) + (calendario['NUM_CICLO'].astype(int) + 3).astype(str).str.zfill(2) #<<< MUDAR O \"4\" (CICLO ATUAL + 4 PARA ACHAR O CICLO DA SUGESTÃO) EX: C202505 -> C202509\n",
|
||||
"ciclo_mais2 = calendario[calendario['Date'].dt.normalize() == today]['CICLOMAIS2'].iloc[0]\n",
|
||||
"\n",
|
||||
"# Filter rows where date matches today\n",
|
||||
"filtered_calendario = calendario[calendario['Ciclo'] == ciclo_mais2][:1]\n",
|
||||
"\n",
|
||||
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['INICIO CICLO'].iloc[0] - today\n",
|
||||
"\n",
|
||||
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['dias_ate_inicio'].dt.days.astype(int)\n",
|
||||
"\n",
|
||||
"filtered_calendario['match'] = 1\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5589e67c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"filtered_calendario"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5ac3914a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\TABELA_PEDIDO\\Pedidos Semanais Especiais - BOT - 202510 (2).xlsx\")\n",
|
||||
"\n",
|
||||
"df_tabela = df_tabela[df_tabela['Região'] == 'NNE'] \n",
|
||||
"\n",
|
||||
"df_tabela = df_tabela[(df_tabela['Canal'] != 'Ecomm') | (df_tabela['Canal'] != 'Ecomm | VD') | (df_tabela['Canal'] != 'Ecomm | Loja')] #perguntar se isso aqui é vdd\n",
|
||||
"\n",
|
||||
"df_tabela['Canal'] = np.where((df_tabela['Canal'] == \"Loja\") | (df_tabela['Canal'] == \"Todos\") | (df_tabela['Canal'] == \"Loja | VD\"),\"TODOS\",\"VD\")\n",
|
||||
"\n",
|
||||
"df_tabela = df_tabela[df_tabela['Tipo de promoção'].str.contains('Lançamentos', na=False)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "af3d5a5c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_tabela['Tipo de promoção'].value_counts()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1a338b98",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\PRODUTO_SIMILAR\\PRODUTOS SIMILARES.xlsx\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "39ddc830",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares = pd.merge(left=df_similares,right=calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO']], how= 'left', left_on = 'CICLO SIMILAR',right_on = 'Ciclo' )\n",
|
||||
"\n",
|
||||
"df_similares = df_similares.drop(columns=['INICIO DO CICLO SIMILAR','FIM DO CICLO SIMILAR', 'DURAÇÃO DO CICLO DO SIMILAR','Ciclo','DESCRIÇÃO SIMILAR'])\n",
|
||||
"\n",
|
||||
"df_similares = df_similares.rename(columns={'INICIO CICLO':'INICIO CICLO SIMILAR','FIM CICLO':'FIM CICLO SIMILAR','DURAÇÃO':'DURAÇÃO CICLO SIMILAR'})\n",
|
||||
"df_similares.drop_duplicates(inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2eb0975",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft = df_draft.rename(columns={'Descrição':'DESCRIÇÃO SIMILAR'})\n",
|
||||
"\n",
|
||||
"df_draft = df_draft.drop(columns=['Subcategoria', 'Lançamento', 'Desativação',\n",
|
||||
" 'Dias sem venda',\n",
|
||||
" 'Promoção Próximo Ciclo', 'Promoção Próximo Ciclo + 1','Compra inteligente semanal/Sugestão de compra',\n",
|
||||
" 'Compra inteligente Próximo Ciclo',\n",
|
||||
" 'Compra inteligente Próximo Ciclo + 1', 'Item Desativado',\n",
|
||||
" 'Data Prevista Regularização', 'Carteira Bloqueada Para Novos Pedidos',\n",
|
||||
" 'Planograma', 'Quantidade por caixa', 'Preço Sell In','Item analisado', 'Histórico de Vendas do Ciclo 202505'])\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2390c5b2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_draft['PROJEÇÃO DE VENDAS CICLO'] = df_draft['Projeção Próximo Ciclo + 1'] - df_draft['Projeção Próximo Ciclo']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c6d00ef5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_diaria = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\VENDAS_PRATICO\\VENDAS SIMI C10 - FormFiltroConsultaVendaSintetica_09_05_2025_11_30_54.xls\")\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a82629ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_diaria['PDV'] = df_venda_diaria['Unidade de Negócio'].str.split(\"-\").str[0].str.strip()\n",
|
||||
"\n",
|
||||
"df_venda_diaria['Dia'] = pd.to_datetime(df_venda_diaria['Dia'], format='%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_venda_diaria = pd.merge(left=df_venda_diaria,right=calendario[['Ciclo','Date']],left_on='Dia',right_on='Date',how='inner')\n",
|
||||
"\n",
|
||||
"df_venda_diaria = df_venda_diaria.drop(columns='Date')\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4cd37229",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_diaria = df_venda_diaria.drop_duplicates()\n",
|
||||
"\n",
|
||||
"df_venda_diaria.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15773282",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_agrupado = df_venda_diaria.groupby(['PDV', 'Código do Produto','Ciclo'])['Quantidade'].sum().reset_index()\n",
|
||||
"df_venda_agrupado"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6dad6151",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_pdv['MATCH'] = 1\n",
|
||||
"\n",
|
||||
"df_similares['MATCH'] = 1\n",
|
||||
"\n",
|
||||
"df_similares = pd.merge(left=df_similares,right=df_pdv,right_on=['MATCH'],left_on=['MATCH'],how='inner')\n",
|
||||
"\n",
|
||||
"df_similares = df_similares.drop_duplicates()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2b33a11",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_similares.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "63c52601",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge(left=df_similares,right=df_draft,right_on=['SKU','PDV'],left_on=['PRODUTO SIMILAR','PDV'],how='left')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "90a54c84",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge(left=df_final, right=filtered_calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO','match','dias_ate_inicio']], on='match',how='left')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15b16b69",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"#df_final = pd.merge(left=df_final,right=df_pdv[['PDV', 'CANAL', 'DESCRIÇÃO PDV', 'PDV DESC','UF','ANALISTA','SUPERVISOR']],on = 'PDV',how='inner')\n",
|
||||
"df_final.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6a453dc4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_bi_vendas = df_bi_vendas.rename(columns={'Quantidade':'Vendas Ciclo Lançamento'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a2a92cc7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"df_bi_vendas['SKU2'] = df_bi_vendas['SKU2'].astype(str) \n",
|
||||
"\n",
|
||||
"df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype(str)\n",
|
||||
"\n",
|
||||
"df_bi_vendas['PDV'] = df_bi_vendas['PDV'].astype('Int64') \n",
|
||||
"\n",
|
||||
"df_final['SKU'] = df_final['SKU'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_bi_vendas,right_on=['PDV','SKU2','CICLO_FINAL'],left_on=['PDV','PRODUTO SIMILAR','CICLO SIMILAR'],how='left')\n",
|
||||
"df_final.shape "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2f11abcb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "085cde87",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['SKU','match',\n",
|
||||
" 'Ciclo_y',\n",
|
||||
" 'SKU1', 'SKU2', 'Campanha','TOTAL PV',\n",
|
||||
" 'Ciclo_ultimos2', 'Ciclo_ano', 'CICLO_FINAL'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "57d4871f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['CANAL'] = np.where((df_final['CANAL'] == 'LJ') | (df_final['CANAL'] == 'HIB'), \"TODOS\" , np.where((df_final['CANAL'] == 'CD') | (df_final['CANAL'] == 'VD'), \"VD\", df_final['CANAL']))\n",
|
||||
"\n",
|
||||
"df_final['CANAL'].value_counts()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e4e5868e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_tabela['Código'] = df_tabela['Código'].astype(str)\n",
|
||||
"df_final['PRODUTO LANÇAMENTO'] = df_final['PRODUTO LANÇAMENTO'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_tabela[['Canal', 'Código','Ação consumidor','IAF','Foco','Marca','Categoria',\n",
|
||||
" 'Percentual de desconto consumidor', 'Ação revendedor',\n",
|
||||
" 'Percentual de desconto revendedor','Tipo de promoção']],right_on=['Código'],left_on=['PRODUTO LANÇAMENTO'],how='left')\n",
|
||||
"df_final.shape "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d6b65a39",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_estoque = df_estoque.rename(columns={'SKU_FINAL':'SKU_PARA_VALIDACAO'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aaa90522",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_estoque['PDV'] = df_estoque['PDV'].astype('int64')\n",
|
||||
"\n",
|
||||
"df_final = pd.merge( left= df_final, right = df_estoque[['SKU_PARA_VALIDACAO','Arquivo_Origem','PDV']], left_on= ['PRODUTO SIMILAR','PDV'], right_on=['SKU_PARA_VALIDACAO','PDV'], how='left')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "94f1a76f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=[\n",
|
||||
"'SKU_PARA_VALIDACAO'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c3395775",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e5f7cefc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[35:41]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "efa6b757",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['PDV_SKU'] = df_final['PDV'].astype(str) + df_final['PRODUTO SIMILAR'].astype(str) \n",
|
||||
"\n",
|
||||
"df_final['UFPRODUTO'] = df_final['UF'].astype(str) + df_final['PRODUTO SIMILAR'].astype(str)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"VENDA_SIMILAR_6_MESES= df_final.columns[35:41]\n",
|
||||
"\n",
|
||||
"df_final['Pico Vendas Similar Ultimos 6 ciclos'] = df_final[VENDA_SIMILAR_6_MESES].max(axis=1)\n",
|
||||
"\n",
|
||||
"df_final = df_final.drop_duplicates()\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f10b3982",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_venda_agrupado['PDV'] = df_venda_agrupado['PDV'].astype('int64')\n",
|
||||
"\n",
|
||||
"df_final['CICLO SIMILAR'] = df_final['CICLO SIMILAR'].astype(str)\n",
|
||||
"\n",
|
||||
"df_venda_agrupado['Código do Produto'] = df_venda_agrupado['Código do Produto'].astype(str)\n",
|
||||
"\n",
|
||||
"df_final = pd.merge(left=df_final,right=df_venda_agrupado,right_on=['PDV','Código do Produto','Ciclo'],left_on=['PDV','PRODUTO SIMILAR','CICLO SIMILAR'],how='left')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8f96e45b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['Ciclo','Código do Produto','Vendas Ciclo Lançamento'])\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'Quantidade':'Vendas Ciclo Lançamento'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5801d05b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[25:41]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "41c64323",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n",
|
||||
"colunas_mensais = df_final.columns[25:41]\n",
|
||||
"\n",
|
||||
"# Passo 1: Soma todas as linhas (itens) por mês → resultado: total por mês\n",
|
||||
"soma_mensal = df_final[colunas_mensais].sum()\n",
|
||||
"\n",
|
||||
"# Passo 2: Calcula a variação percentual de um mês para o outro\n",
|
||||
"variacao_mensal = soma_mensal.pct_change()\n",
|
||||
"variacao_mensal = variacao_mensal.dropna()\n",
|
||||
"\n",
|
||||
"variacao_mensal = variacao_mensal[np.isfinite(variacao_mensal)]\n",
|
||||
"\n",
|
||||
"# Passo 3: Calcula a média da variação (ignorando o primeiro NaN)\n",
|
||||
"media_variacao = variacao_mensal[1:].mean()\n",
|
||||
"\n",
|
||||
"# Calcula média e desvio padrão\n",
|
||||
"media = variacao_mensal.mean()\n",
|
||||
"desvio = variacao_mensal.std()\n",
|
||||
"\n",
|
||||
"# Define limite (ex: 2 desvios padrão)\n",
|
||||
"limite_superior = media + 2 * desvio\n",
|
||||
"limite_inferior = media - 2 * desvio\n",
|
||||
"\n",
|
||||
"# Filtra dados dentro do limite\n",
|
||||
"filtro = variacao_mensal.between(limite_inferior, limite_superior)\n",
|
||||
"df_filtrado = variacao_mensal[filtro]\n",
|
||||
"CRESCIMENTO = round(df_filtrado.mean(),4)\n",
|
||||
"\n",
|
||||
"df_final['CRESCIMENTO'] = CRESCIMENTO\n",
|
||||
"\n",
|
||||
"CRESCIMENTO\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "02565655",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"variacao_mensal.info"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "137f5531",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[27:28]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3c027cfc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"venda_similar_mesmo_ciclo_ano_passado = df_final.columns[27:28] #<<<<<<< CICLO ATUAL É [37:38]\n",
|
||||
"ciclo_ano_passado = df_final.columns[27:28].str.split(\" \")[0][-1]\n",
|
||||
"df_final[ciclo_ano_passado] = df_final[venda_similar_mesmo_ciclo_ano_passado]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "28f74b58",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['Vendas Ciclo Lançamento'] = df_final['Vendas Ciclo Lançamento'].fillna(0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "58642d77",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vendas_todos_historicos = df_final.columns[25:41]\n",
|
||||
"\n",
|
||||
"df_final['MEDIANA DO HISTÓRICO'] = df_final[vendas_todos_historicos].dropna().median(axis=1)\n",
|
||||
"\n",
|
||||
"df_final['MEDIA DO HISTÓRICO'] = df_final[vendas_todos_historicos].dropna().mean(axis=1)\n",
|
||||
"\n",
|
||||
"df_final['MEDIANA DO HISTÓRICO'] = np.where(df_final['MEDIANA DO HISTÓRICO'] > 0, df_final['MEDIANA DO HISTÓRICO'], df_final['MEDIA DO HISTÓRICO'] )#validar se foi\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "69473155",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"crescimento = df_final['CRESCIMENTO']\n",
|
||||
"vendas_lanc = df_final['Vendas Ciclo Lançamento']\n",
|
||||
"pico_similar = df_final['Pico Vendas Similar Ultimos 6 ciclos']\n",
|
||||
"mediana_hist = df_final['MEDIANA DO HISTÓRICO']\n",
|
||||
"\n",
|
||||
"# Primeiro cálculo intermediário\n",
|
||||
"df_final['PV GINSENG'] = np.where(df_final['CRESCIMENTO'] * df_final[ciclo_ano_passado] + df_final[ciclo_ano_passado] < df_final['MEDIANA DO HISTÓRICO'],\n",
|
||||
" round(df_final['CRESCIMENTO'] * df_final['MEDIANA DO HISTÓRICO']+ df_final['MEDIANA DO HISTÓRICO'],0), \n",
|
||||
" round(df_final['CRESCIMENTO']*df_final[ciclo_ano_passado]+df_final[ciclo_ano_passado],0))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d29a3365",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns[25:38]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3cf3efe7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.rename(columns={df_final.columns[38]: \"C-4\", df_final.columns[39]: \"C-3\",df_final.columns[40]: \"C-2\",df_final.columns[41]: \"C-1\"})\n",
|
||||
"\n",
|
||||
"df_final.drop(columns=df_final.columns[25:38], inplace=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "303291c9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2b8b3551",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"marca_promo = df_estoque['Arquivo_Origem'].iloc[0].replace('.csv','')\n",
|
||||
"\n",
|
||||
"df_final['INICIO CICLO'] = pd.to_datetime(df_final['INICIO CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['FIM CICLO'] = pd.to_datetime(df_final['FIM CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['INICIO CICLO SIMILAR'] = pd.to_datetime(df_final['INICIO CICLO SIMILAR'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"df_final['FIM CICLO SIMILAR'] = pd.to_datetime(df_final['FIM CICLO SIMILAR'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'Ciclo_x': 'Ciclo'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3900ec24",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.merge(left=df_final,right=df_pdv_origi[['PDV','CANAL','UF']],how='inner',on='PDV')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f8ba376a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['CANAL_x','UF_x','Categoria_y'])\n",
|
||||
"\n",
|
||||
"df_final = df_final.rename(columns={'CANAL_y':'CANAL', 'UF_y':'UF','MARCA_x':'MARCA','Categoria_x':'Categoria'})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7d904672",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Columns to bring up front\n",
|
||||
"priority_cols = [\n",
|
||||
" 'Ciclo','INICIO CICLO','FIM CICLO','ANALISTA','SUPERVISOR','UF','CANAL','PDV', 'DESCRIÇÃO PDV','DURAÇÃO',\t\n",
|
||||
" 'Classe','PRODUTO LANÇAMENTO','DESCRIÇÃO DO LANÇAMENTO','MARCA','Foco',\n",
|
||||
" 'PRODUTO SIMILAR','DESCRIÇÃO SIMILAR','CICLO SIMILAR','INICIO CICLO SIMILAR','FIM CICLO SIMILAR','DURAÇÃO CICLO SIMILAR',\n",
|
||||
" 'Ação consumidor',\t'Percentual de desconto consumidor','Ação revendedor','Percentual de desconto revendedor','Estoque Atual',\n",
|
||||
" 'Estoque em Transito',\t'Pedido Pendente','DESCRIÇÃO SIMILAR', 'Histórico de Vendas do Ciclo Atual',\n",
|
||||
"\t'C-4',\t'C-3',\t'C-2',\t'C-1'\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# All remaining columns\n",
|
||||
"other_cols = [col for col in df_final.columns if col not in priority_cols]\n",
|
||||
"\n",
|
||||
"# Reorder\n",
|
||||
"df_final = df_final[priority_cols + other_cols]\n",
|
||||
"\n",
|
||||
"df_final['SUGESTÃO ABTASTECIMENTO'] = ''\n",
|
||||
"\n",
|
||||
"df_final['SUGESTÃO COMERCIAL'] = ''\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "43f96709",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = df_final.drop(columns=['Marca','CRESCIMENTO','Canal','Código','Tipo de promoção','dias_ate_inicio','PDV DESC','UFPRODUTO','Arquivo_Origem','UFPRODUTO',\n",
|
||||
" 'PDV_SKU','MEDIANA DO HISTÓRICO','MEDIA DO HISTÓRICO'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "23d6fe59",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final['chave'] = df_final['PDV'].astype(str) + df_final['PRODUTO LANÇAMENTO'].astype(str)\n",
|
||||
"\n",
|
||||
"chaves_duplicadas = (\n",
|
||||
" df_final.groupby('chave')['Percentual de desconto consumidor']\n",
|
||||
" .count()\n",
|
||||
" .loc[lambda x: x == 2]\n",
|
||||
" .index\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Selecionar essas linhas\n",
|
||||
"duplicadas = df_final[df_final['chave'].isin(chaves_duplicadas)]\n",
|
||||
"\n",
|
||||
"# Filtrar apenas os grupos onde pelo menos uma linha tem 0.0\n",
|
||||
"grupos_com_zero = duplicadas.groupby('chave').filter(\n",
|
||||
" lambda g: (g['Percentual de desconto consumidor'] == \"0,00\").any()\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Remover apenas as linhas com 0.0 dessas chaves\n",
|
||||
"limpos = grupos_com_zero[grupos_com_zero['Percentual de desconto consumidor'] != \"0,00\"]\n",
|
||||
"\n",
|
||||
"# Concatenar com o restante do dataframe que não foi afetado\n",
|
||||
"resto = df_final[~df_final['chave'].isin(grupos_com_zero['chave'])]\n",
|
||||
"df_final = pd.concat([resto, limpos], ignore_index=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "08faefd9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"from openpyxl import load_workbook\n",
|
||||
"from openpyxl.styles import PatternFill, Font\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Export to Excel\n",
|
||||
"output_file = f'C:\\\\Users\\\\joao.herculano\\\\Documents\\\\Lançamento!!!_{marca_promo}_{ciclo_mais2}_20.05!!.xlsx'\n",
|
||||
"with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n",
|
||||
" df_final.to_excel(writer, index=False, sheet_name='Sheet1')\n",
|
||||
"\n",
|
||||
"# Apply styles\n",
|
||||
"wb = load_workbook(output_file)\n",
|
||||
"ws = wb['Sheet1']\n",
|
||||
"\n",
|
||||
"# Style header\n",
|
||||
"header_fill = PatternFill(start_color='ADD8E6', end_color='ADD8E6', fill_type='solid') # Light Blue\n",
|
||||
"header_font = Font(color='FFFFFF', bold=True) # White & Bold\n",
|
||||
"\n",
|
||||
"for cell in ws[1]:\n",
|
||||
" cell.fill = header_fill\n",
|
||||
" cell.font = header_font\n",
|
||||
"\n",
|
||||
"# Style rows: gray/white alternating\n",
|
||||
"gray_fill = PatternFill(start_color='DDDDDD', end_color='DDDDDD', fill_type='solid') # Light gray\n",
|
||||
"\n",
|
||||
"for i, row in enumerate(ws.iter_rows(min_row=2, max_row=ws.max_row), start=2):\n",
|
||||
" if i % 2 == 0:\n",
|
||||
" for cell in row:\n",
|
||||
" cell.fill = gray_fill\n",
|
||||
"\n",
|
||||
"# Save styled workbook\n",
|
||||
"wb.save(output_file)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f039df31",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
993
promoção/SQL no python.ipynb
Normal file
993
promoção/SQL no python.ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
promoção/__pycache__/compilador_estoque.cpython-313.pyc
Normal file
BIN
promoção/__pycache__/compilador_estoque.cpython-313.pyc
Normal file
Binary file not shown.
155
promoção/compilador de promo_analistas.ipynb
Normal file
155
promoção/compilador de promo_analistas.ipynb
Normal file
@ -0,0 +1,155 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "fd67cc1a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"c:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\openpyxl\\worksheet\\_reader.py:329: UserWarning: Unknown extension is not supported and will be removed\n",
|
||||
" warn(msg)\n",
|
||||
"c:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\openpyxl\\worksheet\\_reader.py:329: UserWarning: Unknown extension is not supported and will be removed\n",
|
||||
" warn(msg)\n",
|
||||
"c:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\openpyxl\\worksheet\\_reader.py:329: UserWarning: Unknown extension is not supported and will be removed\n",
|
||||
" warn(msg)\n",
|
||||
"c:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\openpyxl\\worksheet\\_reader.py:329: UserWarning: Unknown extension is not supported and will be removed\n",
|
||||
" warn(msg)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import glob\n",
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"# Directory path\n",
|
||||
"folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\Bot - C13\\LANÇAMENTOS\\devolutiva comercial\"\n",
|
||||
"# Collect files\n",
|
||||
"file_paths = glob.glob(os.path.join(folder_path, \"*.xls\")) + glob.glob(os.path.join(folder_path, \"*.xlsx\"))\n",
|
||||
"\n",
|
||||
"# Required columns\n",
|
||||
"required_columns = [\"PDV\", \"PRODUTO LANÇAMENTO\", \"SUGESTÃO COMERCIAL\"]\n",
|
||||
"\n",
|
||||
"# Load files\n",
|
||||
"dfs = []\n",
|
||||
"for file_path in file_paths:\n",
|
||||
" try:\n",
|
||||
" df = pd.read_excel(file_path,sheet_name='Sheet1')\n",
|
||||
" \n",
|
||||
" missing = [col for col in required_columns if col not in df.columns]\n",
|
||||
" \n",
|
||||
" if missing:\n",
|
||||
" print(f\"Missing columns {missing} ins file: {file_path}\")\n",
|
||||
" continue # Skip file with missing columns\n",
|
||||
"\n",
|
||||
" df[\"source_file\"] = os.path.basename(file_path)\n",
|
||||
" dfs.append(df)\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"Failed to read {file_path}: {e}\")\n",
|
||||
"\n",
|
||||
"# Combine\n",
|
||||
"if dfs:\n",
|
||||
" combined_df = pd.concat(dfs, ignore_index=True)\n",
|
||||
"else:\n",
|
||||
" print(\"No valid files loaded.\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "c4c50096",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"np.int64(82418)"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"combined_df['SUGESTÃO COMERCIAL'].isna().sum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "3e1ada65",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"combined_df = combined_df.drop_duplicates()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "f5968d9a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"combined_df['chavers'] = combined_df['PDV'].astype('str') + combined_df['PRODUTO LANÇAMENTO'].astype('str')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "fd6a08e7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"combined_df['chavers'] = combined_df['chavers'].str.replace('.','')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "b6eee60e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"combined_df.to_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\Bot - C13\\LANÇAMENTOS\\compilado_comercial_BOTI!!!.xlsx\",index=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "84f989f7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
51
promoção/compilador_estoque.py
Normal file
51
promoção/compilador_estoque.py
Normal file
@ -0,0 +1,51 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import os
|
||||
from datetime import date
|
||||
|
||||
def unificador_estoque(pasta_entrada):
|
||||
hoje = date.today().isoformat()
|
||||
caminho_saida = os.path.join(pasta_entrada, f"compilado_estoque_{hoje}.xlsx")
|
||||
print("Salvando em:", caminho_saida)
|
||||
|
||||
subpastas = [
|
||||
os.path.join(pasta_entrada, d)
|
||||
for d in os.listdir(pasta_entrada)
|
||||
if os.path.isdir(os.path.join(pasta_entrada, d))
|
||||
]
|
||||
|
||||
df_list = []
|
||||
|
||||
for subpasta in subpastas:
|
||||
arquivos = [f for f in os.listdir(subpasta) if f.endswith(".csv")]
|
||||
nome_pasta = os.path.basename(subpasta)
|
||||
|
||||
for arquivo in arquivos:
|
||||
caminho_arquivo = os.path.join(subpasta, arquivo)
|
||||
try:
|
||||
df = pd.read_csv(caminho_arquivo, encoding="utf-8", low_memory=False)
|
||||
df["Arquivo_Origem"] = arquivo
|
||||
df["Pasta_Origem"] = nome_pasta
|
||||
df_list.append(df)
|
||||
except Exception as e:
|
||||
print(f"Erro ao ler o arquivo {arquivo}: {e}")
|
||||
|
||||
if not df_list:
|
||||
raise ValueError("Nenhum arquivo CSV válido foi encontrado.")
|
||||
|
||||
df_estoque = pd.concat(df_list, ignore_index=True)
|
||||
|
||||
df_estoque["PDV"] = df_estoque["PDV"].astype(str)
|
||||
|
||||
df_estoque["SKU_FINAL"] = np.where(
|
||||
df_estoque["SKU_PARA"] == "-",
|
||||
df_estoque["SKU"],
|
||||
df_estoque["SKU_PARA"]
|
||||
).astype(str)
|
||||
|
||||
try:
|
||||
df_estoque.to_excel(caminho_saida, index=False)
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Erro ao salvar o arquivo Excel: {e}")
|
||||
|
||||
return caminho_saida
|
||||
71
promoção/importador_teste.ipynb
Normal file
71
promoção/importador_teste.ipynb
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "eba7e63d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from compilador_estoque import unificador_estoque\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "b59cf803",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Salvando em: C:/Users/joao.herculano/OneDrive - GRUPO GINSENG/Documentos/estoque EUD 14.05\\compilado_estoque_2025-05-14.xlsx\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'C:/Users/joao.herculano/OneDrive - GRUPO GINSENG/Documentos/estoque EUD 14.05\\\\compilado_estoque_2025-05-14.xlsx'"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"unificador_estoque('C:/Users/joao.herculano/OneDrive - GRUPO GINSENG/Documentos/estoque EUD 14.05')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7b91d6db",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
67
promoção/pensamentos de att do painel 40 d.ipynb
Normal file
67
promoção/pensamentos de att do painel 40 d.ipynb
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "967a68c6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import date"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "04e89b60",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with open(r\"C:\\Users\\joao.herculano\\OneDrive - GRUPO GINSENG\\Ambiente de Trabalho\\acompanhamento improdutivo.csv\",mode='a',newline='',encoding='utf8') as f:\n",
|
||||
" f.write('DATA;TOTAL_IMPRODUTIVO\\n')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "7ef5065f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"hoje = date.today()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "93c54816",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with open(r\"C:\\Users\\joao.herculano\\OneDrive - GRUPO GINSENG\\Ambiente de Trabalho\\acompanhamento improdutivo.csv\",mode='a',newline='',encoding='utf8') as f:\n",
|
||||
" f.write(f'{hoje};2.931.906,29')"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
relatorio_ruptura/PDV_ATT.xlsx
Normal file
BIN
relatorio_ruptura/PDV_ATT.xlsx
Normal file
Binary file not shown.
BIN
relatorio_ruptura/grafico.png
Normal file
BIN
relatorio_ruptura/grafico.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
relatorio_ruptura/grafico2.png
Normal file
BIN
relatorio_ruptura/grafico2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
relatorio_ruptura/relatorio.xlsx
Normal file
BIN
relatorio_ruptura/relatorio.xlsx
Normal file
Binary file not shown.
@ -71,7 +71,7 @@ df.columns = df.columns.str.lower()
|
||||
|
||||
filtered_calendario.columns = filtered_calendario.columns.str.lower()
|
||||
df['ddv'] = df['pv_mar'] / filtered_calendario['duração'].values[0]
|
||||
df['estoque_seguranca'] = np.ceil((df['media_vendas']/20)*11 - (df['ddv']*11)).astype(int) #media de vendas realizada+projetada
|
||||
df['estoque_seguranca'] = np.ceil((df['media_vendas']/20)*14 - (df['ddv']*14)).astype(int) #media de vendas realizada+projetada
|
||||
df['estoque_seguranca'] = np.where(df['estoque_seguranca'] <1,1,df['estoque_seguranca'])
|
||||
df['risco_ruptura'] = np.where(df['estoque_seguranca'] > df['estoque'], "SIM", "NÃO")
|
||||
df['quantidade_ruptura'] = df['estoque_seguranca'] - df['estoque']
|
||||
@ -84,7 +84,7 @@ assunto = config['email_ruptura']['assunto']
|
||||
|
||||
df_rpt = pd.read_excel(r"C:\Users\joao.herculano\Downloads\Ruptura Cliente CP GINSENG - 09.06.xlsx")
|
||||
df_rpt.columns = df_rpt.columns.str.lower()
|
||||
print(df_rpt.columns)
|
||||
|
||||
|
||||
df['pdv'] = df['pdv'].astype('Int64')
|
||||
df['sku'] = df['sku'].astype('Int64')
|
||||
@ -109,7 +109,7 @@ df2 = df2.join(pdvs_maior_excesso, on=['uf', 'sku'])
|
||||
df2['maior excesso na uf'] = df2['maior_excesso_por_uf'].apply(lambda x: 'não tem excesso no uf' if x == 0 else None)
|
||||
df2['maior excesso na uf'] = df2['maior excesso na uf'].combine_first(df2['pdv_maior_excesso'])
|
||||
df2['quantidade_ruptura'] = df2['quantidade_ruptura'].clip(lower=0)
|
||||
print(df2[['uf', 'sku', 'excesso', 'maior_excesso_por_uf', 'maior excesso na uf']].head())
|
||||
|
||||
df2.drop(columns=['pdv_maior_excesso','sku1'], inplace=True)
|
||||
|
||||
df2['estoque livre?'] = np.where(
|
||||
@ -218,7 +218,7 @@ plt.close()
|
||||
with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
|
||||
df2.to_excel(writer, sheet_name='Detalhado', index=False)
|
||||
df3.to_excel(writer, sheet_name='Resumo', index=False)
|
||||
print(excel_path)
|
||||
|
||||
ruptura_total = df2['quantidade_ruptura'].sum()
|
||||
ruptura_por_uf_pct = (
|
||||
df2.groupby('uf')['quantidade_ruptura'].sum()
|
||||
@ -254,6 +254,7 @@ html_email = f"""
|
||||
<body>
|
||||
<p>{boa}</p>
|
||||
<p>Compartilhamos o relatório de ruptura projetada, com o objetivo de monitorar os itens com maior risco de ruptura nos próximos dias.</p>
|
||||
<p><strong>Atualizamos o relatório, e agora mandaremos diariamente às 10:00 automaticamente. Pedimos paciência nessa etapa e contamos com o feedback de vocês.</strong></p>
|
||||
<p>O relatório a seguir apresenta as seguintes informações:</p>
|
||||
<ul>
|
||||
<li>Estoque atual;</li>
|
||||
BIN
relatório_cobertura/PDV_ATT.xlsx
Normal file
BIN
relatório_cobertura/PDV_ATT.xlsx
Normal file
Binary file not shown.
BIN
relatório_cobertura/acompanhamento40DSV.xlsx
Normal file
BIN
relatório_cobertura/acompanhamento40DSV.xlsx
Normal file
Binary file not shown.
BIN
relatório_cobertura/relatorio.xlsx
Normal file
BIN
relatório_cobertura/relatorio.xlsx
Normal file
Binary file not shown.
212
relatório_cobertura/relatório_cobertura.py
Normal file
212
relatório_cobertura/relatório_cobertura.py
Normal file
@ -0,0 +1,212 @@
|
||||
# enviar_email_excel.py
|
||||
|
||||
import smtplib
|
||||
import ssl
|
||||
import pyodbc
|
||||
import configparser
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
import matplotlib.ticker as mtick
|
||||
import seaborn as sns
|
||||
from email.message import EmailMessage
|
||||
from email.utils import make_msgid
|
||||
from email.mime.image import MIMEImage
|
||||
from pathlib import Path
|
||||
from datetime import datetime, time
|
||||
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(r"credenciais.ini")
|
||||
|
||||
excel_path = Path("relatorio.xlsx")
|
||||
print(config['banco']['host'],config['banco']['user'],config['banco']['password'])
|
||||
|
||||
# Conexão com o banco
|
||||
conn = pyodbc.connect(
|
||||
f"DRIVER={{SQL Server}};"
|
||||
f"SERVER={config['banco']['host']},1433;"
|
||||
f"DATABASE=GINSENG;"
|
||||
f"UID={config['banco']['user']};"
|
||||
f"PWD={config['banco']['password']}")
|
||||
|
||||
# 1. Criar dados fictícios e gerar Excel
|
||||
query = '''
|
||||
WITH CTE_Estoque AS (
|
||||
SELECT
|
||||
em.ORIGEM,
|
||||
em.PDV,
|
||||
CONCAT(em.PDV, em.ORIGEM) AS PDV_Origem, -- Coluna unificada
|
||||
CASE
|
||||
WHEN em.SKU_PARA IS NULL THEN em.SKU
|
||||
ELSE em.SKU_PARA
|
||||
END AS SKU_FINAL,
|
||||
em.DESCRICAO,
|
||||
em.CATEGORIA,
|
||||
em.CLASSE,
|
||||
CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT) AS [ESTOQUE ATUAL],
|
||||
CAST(REPLACE(em.[ESTOQUE EM TRANSITO], ',', '.') AS FLOAT) AS [ESTOQUE EM TRANSITO],
|
||||
CAST(REPLACE(em.[PEDIDO PENDENTE], ',', '.') AS FLOAT) AS [PEDIDO PENDENTE],
|
||||
CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT) AS [DDV PREVISTO],
|
||||
ROUND(
|
||||
CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT)
|
||||
/ NULLIF(CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT), 0), 0
|
||||
) AS [Cobertura Atual],
|
||||
ROUND(
|
||||
(CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT)
|
||||
+ CAST(REPLACE(em.[ESTOQUE EM TRANSITO], ',', '.') AS FLOAT)
|
||||
+ CAST(REPLACE(em.[PEDIDO PENDENTE], ',', '.') AS FLOAT))
|
||||
/ NULLIF(CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT), 0), 0
|
||||
) AS [Cobertura Projetada],
|
||||
d.preco_Compra,
|
||||
d.Dias_sem_Vendas,
|
||||
pr.ATUAL_PROMO ,
|
||||
pr.PROX_PROMO
|
||||
FROM estoque_mar em
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
d.loja_id AS PDV,
|
||||
d.code AS SKU,
|
||||
d.description AS Descricao,
|
||||
d.pricesellin AS preco_Compra,
|
||||
d.dayswithoutsales as Dias_sem_Vendas
|
||||
FROM draft d) d ON em.PDV = d.PDV
|
||||
AND (CASE WHEN em.SKU_PARA IS NULL THEN em.SKU ELSE em.SKU_PARA END) = CAST( d.SKU AS INT)
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
p.loja_id AS PDV,
|
||||
p.code AS SKU,
|
||||
CASE
|
||||
WHEN STRING_AGG(p.currentCycle_description, ', ') IS NULL OR LTRIM(RTRIM( STRING_AGG(p.currentCycle_description, ', '))) = ''
|
||||
THEN 'Regular'
|
||||
ELSE 'Promocao'
|
||||
END AS ATUAL_PROMO,
|
||||
CASE
|
||||
WHEN STRING_AGG(p.nextCycle_description, ', ') IS NULL OR LTRIM(RTRIM(STRING_AGG(p.nextCycle_description, ', '))) = ''
|
||||
THEN 'Regular'
|
||||
ELSE 'Promocao'
|
||||
END AS PROX_PROMO
|
||||
FROM promo p
|
||||
WHERE P.created_at >= CAST(GETDATE() AS DATE)
|
||||
AND P.created_at < DATEADD(DAY, 1, CAST(GETDATE() AS DATE))
|
||||
GROUP BY
|
||||
p.loja_id,
|
||||
p.code
|
||||
) pr ON em.PDV = pr.PDV
|
||||
AND (CASE WHEN em.SKU_PARA IS NULL THEN em.SKU ELSE em.SKU_PARA END) = CAST(pr.SKU AS INT)
|
||||
WHERE em.CATEGORIA NOT IN ('SUPORTE À VENDA', 'EMBALAGENS')
|
||||
)
|
||||
SELECT
|
||||
bpm.DESCRICAO AS DESCRICAO_PDV,
|
||||
bpm.UF,
|
||||
bpm.ANALISTA,
|
||||
cte.*
|
||||
FROM CTE_Estoque cte
|
||||
LEFT JOIN base_pdvs_marca bpm
|
||||
ON cte.PDV_Origem = bpm.PDV_MARCA -- agora join pelo unificado
|
||||
WHERE [Cobertura Atual] > 60;
|
||||
'''
|
||||
df = pd.read_sql(query, conn)
|
||||
|
||||
df.to_excel(excel_path,index=False)
|
||||
conn.close()
|
||||
print(df.columns)
|
||||
remetente = config['credenciais']['remetente']
|
||||
senha = config['credenciais']['senha']
|
||||
destinatarios = [email.strip() for email in config['email_cobertura']['destinatarios'].split(',')]
|
||||
assunto = config['email_cobertura']['assunto']
|
||||
|
||||
print(remetente,senha,destinatarios,assunto)
|
||||
|
||||
|
||||
# Obtém a hora atual
|
||||
agora = datetime.now().time()
|
||||
hoje = datetime.today().strftime("%d/%m/%Y")
|
||||
# Define os intervalos de tempo
|
||||
manhã_inicio = time(5, 0)
|
||||
manhã_fim = time(12, 0)
|
||||
tarde_inicio = time(12, 1)
|
||||
tarde_fim = time(18, 0)
|
||||
# noite é dividida em dois intervalos por causa da virada do dia
|
||||
noite_inicio = time(18, 1)
|
||||
noite_fim = time(4, 59)
|
||||
# Verifica em qual intervalo a hora atual está
|
||||
if manhã_inicio <= agora <= manhã_fim:
|
||||
boa = "Bom dia!"
|
||||
elif tarde_inicio <= agora <= tarde_fim:
|
||||
boa = "Boa tarde!"
|
||||
else:
|
||||
boa = "Boa noite!"
|
||||
|
||||
|
||||
# 3. Criar e-mail com imagem embutida
|
||||
|
||||
msg = EmailMessage()
|
||||
msg['From'] = remetente
|
||||
msg['To'] = ', '.join(destinatarios)
|
||||
msg['Subject'] = assunto
|
||||
|
||||
# 4. Conteúdo do e-mail
|
||||
html_email = f"""
|
||||
<html>
|
||||
<body>
|
||||
<p>{boa}</p>
|
||||
|
||||
<p>
|
||||
Segue o relatório semanal de Cobertura referente às regiões de
|
||||
Alagoas (AL), Bahia (BA), Sergipe (SE), Conquista (VDC), Bahia3(BA3).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Este relatório contempla exclusivamente os itens com cobertura superior à 60 dias.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
O objetivo é trazer visibilidade para os produtos parados e reforçar a importância
|
||||
de ações para estimular a sua saída, contribuindo assim para a redução da cobertura
|
||||
de estoque e otimização dos recursos.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Contamos com o apoio de todos para análise e tratativa dos itens listados.
|
||||
Sugestões de ações como campanhas, transferências ou ajustes de sortimento são
|
||||
bem-vindas para acelerar a movimentação dos produtos.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Importante destacar que este relatório ainda não contempla as transferências realizadas internamente, uma vez que estamos trabalhando para viabilizar a inclusão dessas informações no banco de dados.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Para mais informações, favor consultar a planilha em anexo.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
msg.set_content("Seu e-mail precisa de um visualizador HTML.")
|
||||
msg.add_alternative(html_email, subtype='html')
|
||||
|
||||
|
||||
|
||||
# 5. Anexar o arquivo Excel
|
||||
with open(excel_path, 'rb') as f:
|
||||
msg.add_attachment(
|
||||
f.read(),
|
||||
maintype='application',
|
||||
subtype='vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
filename=excel_path.name
|
||||
)
|
||||
|
||||
# 6. Enviar o e-mail via SMTP Outlook com configurações fornecidas
|
||||
with smtplib.SMTP('smtp-mail.outlook.com', 587) as smtp:
|
||||
smtp.ehlo()
|
||||
smtp.starttls(context=ssl.create_default_context())
|
||||
smtp.login(remetente, senha)
|
||||
smtp.send_message(msg)
|
||||
|
||||
|
||||
|
||||
print("E-mail enviado com sucesso.")
|
||||
BIN
relatório_improdutivo/PDV_ATT.xlsx
Normal file
BIN
relatório_improdutivo/PDV_ATT.xlsx
Normal file
Binary file not shown.
BIN
relatório_improdutivo/acompanhamento40DSV.xlsx
Normal file
BIN
relatório_improdutivo/acompanhamento40DSV.xlsx
Normal file
Binary file not shown.
18
relatório_improdutivo/credenciais.ini
Normal file
18
relatório_improdutivo/credenciais.ini
Normal file
@ -0,0 +1,18 @@
|
||||
[credenciais]
|
||||
remetente=joao.herculano@grupoginseng.com.br
|
||||
senha=Cecigaming@21
|
||||
|
||||
[email]
|
||||
assunto = ACOMPANHAMENTO IMPRODUTIVOS
|
||||
destinatarios=lucas.Barbosa@grupoginseng.com.br,Andressa.Rocha@grupoginseng.com.br,Lais.Santos@grupoginseng.com.br,Daniel.Rodrigues@grupoginseng.com.br,Darlin.Cunha@grupoginseng.com.br,Dielly.Gomes@grupoginseng.com.br,Haryadne.Gomes@grupoginseng.com.br,Lucas.Bento@grupoginseng.com.br,Marcyara.Batista@grupoginseng.com.br,Pedro.Horgos@grupoginseng.com.br,Thayllan.Santos@grupoginseng.com.br,Jefferson.Ferreira@grupoginseng.com.br,Luan.Omena@grupoginseng.com.br,vinicius.souza@grupoginseng.com.br
|
||||
|
||||
[email_ruptura]
|
||||
assunto = ACOMPANHAMENTO DE RUPTURA PROJETADA
|
||||
destinatarios=Lucas.Barbosa@grupoginseng.com.br,Andressa.Rocha@grupoginseng.com.br,Lais.Santos@grupoginseng.com.br,Daniel.Rodrigues@grupoginseng.com.br,Darlin.Cunha@grupoginseng.com.br,Dielly.Gomes@grupoginseng.com.br,Haryadne.Gomes@grupoginseng.com.br,Lucas.Bento@grupoginseng.com.br,Marcyara.Batista@grupoginseng.com.br,Pedro.Horgos@grupoginseng.com.br,Thayllan.Santos@grupoginseng.com.br,Jefferson.Ferreira@grupoginseng.com.br,Luan.Omena@grupoginseng.com.br,vinicius.souza@grupoginseng.com.br
|
||||
|
||||
|
||||
[banco]
|
||||
host = 10.77.77.10
|
||||
user = hubsupply
|
||||
password = =c6#94sE&(v2
|
||||
|
||||
@ -6,6 +6,7 @@ import pyodbc
|
||||
import configparser
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
import matplotlib.ticker as mtick
|
||||
import seaborn as sns
|
||||
from email.message import EmailMessage
|
||||
@ -16,7 +17,7 @@ from datetime import datetime, time
|
||||
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(r"C:\Users\joao.herculano\Documents\Enviador de email\credenciais.ini")
|
||||
config.read(r"relatório_improdutivo\credenciais.ini")
|
||||
|
||||
print(config['banco']['host'],config['banco']['user'],config['banco']['password'])
|
||||
|
||||
@ -57,7 +58,9 @@ assunto = config['email']['assunto']
|
||||
|
||||
print(remetente,senha,destinatarios,assunto)
|
||||
|
||||
pdvs = pd.read_excel(r"C:\Users\joao.herculano\Documents\PDV_ATT.xlsx")
|
||||
pdvs = pd.read_excel(r"relatório_improdutivo\PDV_ATT.xlsx")
|
||||
|
||||
|
||||
|
||||
df['loja_id'] = df['loja_id'].astype('Int64')
|
||||
pdvs['PDV'] = pdvs['PDV'].astype('Int64')
|
||||
@ -108,22 +111,45 @@ excel_path = Path("relatorio.xlsx")
|
||||
df2.to_excel(excel_path, index=False)
|
||||
|
||||
|
||||
# 2. Criar e salvar gráfico
|
||||
# Gerar gráfico melhorado - Estoque parado por UF
|
||||
plot_df = df2.groupby('UF')['valor_estoque_parado'].sum().reset_index()
|
||||
plt.figure(figsize=(6, 4))
|
||||
ax = sns.barplot(data=plot_df, x='UF', y='valor_estoque_parado', errorbar=None)
|
||||
|
||||
sns.set_theme(style="whitegrid")
|
||||
|
||||
plt.figure(figsize=(12, 7))
|
||||
ax = sns.barplot(
|
||||
data=plot_df,
|
||||
x='UF',
|
||||
y='valor_estoque_parado',
|
||||
palette='crest',
|
||||
errorbar=None
|
||||
)
|
||||
|
||||
ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('R${x:,.2f}'))
|
||||
|
||||
# Anotar valores em cima das barras
|
||||
for p in ax.patches:
|
||||
valor = p.get_height()
|
||||
ax.annotate(f'R$ {valor:,.2f}', (p.get_x() + p.get_width() / 2, valor),
|
||||
ha='center', va='bottom', fontsize=9)
|
||||
plt.title("Estoque parado por UF")
|
||||
plt.ylabel("Valor em Reais")
|
||||
plt.xlabel("UF")
|
||||
ax.annotate(
|
||||
f'R$ {valor:,.2f}',
|
||||
(p.get_x() + p.get_width() / 2, valor),
|
||||
ha='center', va='bottom',
|
||||
fontsize=10,
|
||||
fontweight='bold'
|
||||
)
|
||||
|
||||
plt.title("Estoque Parado por UF", fontsize=18, fontweight='bold')
|
||||
plt.ylabel("Valor em Reais", fontsize=13)
|
||||
plt.xlabel("UF", fontsize=13)
|
||||
plt.xticks(fontsize=11)
|
||||
plt.yticks(fontsize=11)
|
||||
|
||||
sns.despine()
|
||||
plt.tight_layout()
|
||||
plt.savefig("grafico.png")
|
||||
plt.close()
|
||||
|
||||
|
||||
# Obtém a hora atual
|
||||
agora = datetime.now().time()
|
||||
hoje = datetime.today().strftime("%d/%m/%Y")
|
||||
@ -147,7 +173,7 @@ df2['DATA'] = hoje
|
||||
|
||||
df3 = df2.groupby('DATA', as_index=False)['valor_estoque_parado'].sum()
|
||||
|
||||
path2 = r'C:\Users\joao.herculano\OneDrive - GRUPO GINSENG\Documentos\acompanhamentos\40D sem Venda\acompanhamento40DSV.xlsx'
|
||||
path2 = r'relatório_improdutivo\acompanhamento40DSV.xlsx'
|
||||
|
||||
# Tenta abrir e escrever com append
|
||||
with pd.ExcelWriter(path2, mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer:
|
||||
@ -159,8 +185,47 @@ with pd.ExcelWriter(path2, mode='a', engine='openpyxl', if_sheet_exists='overlay
|
||||
# Escreve sem cabeçalho se não for a primeira linha
|
||||
df3.to_excel(writer, index=False, header=not start_row > 1, startrow=start_row)
|
||||
|
||||
de_effi = pd.read_excel(r'relatório_improdutivo\acompanhamento40DSV.xlsx')
|
||||
|
||||
de_effi['Data'] = pd.to_datetime(de_effi['Data'], errors='coerce')
|
||||
|
||||
# Step 2: Group and sort
|
||||
grouped = (
|
||||
de_effi.groupby('Data')['Valor']
|
||||
.sum()
|
||||
.sort_index()
|
||||
)
|
||||
|
||||
# Step 3: Plot
|
||||
plt.figure(figsize=(12, 6))
|
||||
plt.plot(grouped.index, grouped.values, marker='o', linestyle='-', color='cornflowerblue', linewidth=2)
|
||||
|
||||
# Step 4: Format numbers with dot ('.') separator, no decimals
|
||||
for x, y in zip(grouped.index, grouped.values):
|
||||
label = f"{y:,.0f}".replace(",", ".") # format like 75.063
|
||||
plt.text(x, y + max(grouped.values) * 0.015, label, ha='center', fontsize=9)
|
||||
|
||||
# Step 5: Format chart
|
||||
plt.title('Evolução de Estoque Improdutivo por Data', fontsize=14)
|
||||
plt.xlabel('Data', fontsize=8)
|
||||
plt.ylabel('Estoque Improdutivo', fontsize=12)
|
||||
plt.grid(True, linestyle='--', alpha=0.6)
|
||||
|
||||
# ✅ Set xticks to match the actual data points
|
||||
ax = plt.gca()
|
||||
ax.set_xticks(grouped.index)
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y'))
|
||||
plt.xticks(rotation=45)
|
||||
|
||||
# Format x-axis as dd/mm/yyyy
|
||||
plt.gca().set_xticklabels([d.strftime('%d/%m/%Y') for d in grouped.index])
|
||||
plt.tight_layout()
|
||||
plt.savefig("grafico2.png")
|
||||
plt.close()
|
||||
|
||||
# 3. Criar e-mail com imagem embutida
|
||||
grafico_cid = make_msgid()[1:-1] # remove < >
|
||||
grafico2_cid = make_msgid()[1:-1]
|
||||
msg = EmailMessage()
|
||||
msg['From'] = remetente
|
||||
msg['To'] = ', '.join(destinatarios)
|
||||
@ -175,7 +240,7 @@ html_email = f"""
|
||||
|
||||
<p>
|
||||
Segue o relatório semanal de estoque improdutivo referente às regiões de
|
||||
Alagoas (AL), Bahia (BA), Sergipe (SE), Vitória da Conquista (VDC) e Iracê.
|
||||
Alagoas (AL), Bahia (BA), Sergipe (SE), Vitória da Conquista (VDC), Jacobina e Iracê.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -200,7 +265,8 @@ html_email = f"""
|
||||
</p>
|
||||
|
||||
<p><b>Segue resumo:</b></p>
|
||||
<img src="cid:{grafico_cid}">
|
||||
<p><img src="cid:{grafico_cid}"></p>
|
||||
<p><img src="cid:{grafico2_cid}"></p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
@ -213,6 +279,9 @@ msg.add_alternative(html_email, subtype='html')
|
||||
with open("grafico.png", 'rb') as img:
|
||||
msg.get_payload()[1].add_related(img.read(), 'image', 'png', cid=grafico_cid)
|
||||
|
||||
with open("grafico2.png", 'rb') as img2:
|
||||
msg.get_payload()[1].add_related(img2.read(), 'image', 'png', cid=grafico2_cid)
|
||||
|
||||
|
||||
# 5. Anexar o arquivo Excel
|
||||
with open(excel_path, 'rb') as f:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user