diff --git a/Lançamentos/Script_lançamento_boti_v2.ipynb b/Lançamentos/Script_lançamento_boti_v2.ipynb index 6aa17d9..49623c8 100644 --- a/Lançamentos/Script_lançamento_boti_v2.ipynb +++ b/Lançamentos/Script_lançamento_boti_v2.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "6ad35669", "metadata": {}, "outputs": [], @@ -10,12 +10,23 @@ "import pandas as pd\n", "import numpy as np \n", "import glob\n", - "import os " + "import os \n", + "from datetime import datetime" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, + "id": "fa16d50c", + "metadata": {}, + "outputs": [], + "source": [ + "hoje = datetime.today().strftime('%Y-%m-%d')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "id": "9fcdc77a", "metadata": {}, "outputs": [], @@ -48,17 +59,83 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "bbec229d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CicloINICIO CICLOFIM CICLODURAÇÃOMARCADateNUM_CICLOANO_CICLOCICLOMAIS2dias_ate_iniciomatch
2241C2025112025-07-212025-08-1021BOTICARIO2025-07-2111C2025C202514491
\n", + "
" + ], + "text/plain": [ + " Ciclo INICIO CICLO FIM CICLO DURAÇÃO MARCA Date \\\n", + "2241 C202511 2025-07-21 2025-08-10 21 BOTICARIO 2025-07-21 \n", + "\n", + " NUM_CICLO ANO_CICLO CICLOMAIS2 dias_ate_inicio match \n", + "2241 11 C2025 C202514 49 1 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "filtered_calendario" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "61ffc777", "metadata": {}, "outputs": [], @@ -80,17 +157,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "99ea95e6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n", + " 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n", + " 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n", + " 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH'],\n", + " dtype='object')" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_similares.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "fe922f62", "metadata": {}, "outputs": [], @@ -108,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "a3a045d9", "metadata": {}, "outputs": [], @@ -139,17 +231,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "849d5297", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['PDV', 'CANAL', 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA',\n", + " 'SUPERVISOR', 'status', 'MATCH'],\n", + " dtype='object')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_pdv.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "df04a501", "metadata": {}, "outputs": [], @@ -161,15 +266,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "0da911af", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_26024\\1835738500.py:10: DtypeWarning: Columns (7) have mixed types. Specify dtype option on import or set low_memory=False.\n", + " df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n" + ] + }, + { + "data": { + "text/plain": [ + "(114430, 47)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "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\\BOT\\BOT - C11\\arquivos para geração da sugestão\\DRAFT\" # arquivo dos drafts\n", + "folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C11\\atualização\\DRAFT_\" # arquivo dos drafts\n", "\n", "# Pattern to match all CSV files\n", "csv_files = glob.glob(os.path.join(folder_path, '*.csv'))\n", @@ -184,7 +308,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "0c8c7493", "metadata": {}, "outputs": [], @@ -194,20 +318,58 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "91298cde", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202408',\n", + " 'Histórico de Vendas do Ciclo 202409',\n", + " 'Histórico de Vendas do Ciclo 202410',\n", + " 'Histórico de Vendas do Ciclo 202411',\n", + " 'Histórico de Vendas do Ciclo 202412',\n", + " 'Histórico de Vendas do Ciclo 202413',\n", + " 'Histórico de Vendas do Ciclo 202414',\n", + " 'Histórico de Vendas do Ciclo 202415',\n", + " 'Histórico de Vendas do Ciclo 202416',\n", + " 'Histórico de Vendas do Ciclo 202417',\n", + " 'Histórico de Vendas do Ciclo 202501',\n", + " 'Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_draft.columns[7:25]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "34e179cb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_26024\\1463083786.py:24: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n", + " crescimento_por_pdv = df_draft.groupby('PDV').apply(calcular_crescimento)\n" + ] + } + ], "source": [ "# Define as colunas mensais\n", "colunas_mensais = df_draft.columns[7:25]\n", @@ -240,7 +402,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "4bc8c2b4", "metadata": {}, "outputs": [], @@ -252,10 +414,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "c1451562", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(5459, 14)" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_venda_diaria = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C11\\arquivos para geração da sugestão\\VENDAS_DIARIAS\\FormFiltroConsultaVendaSintetica_22_05_2025_16_26_17.xls\")\n", "\n", @@ -264,20 +437,46 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "882e68aa", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Unidade de Negócio', 'Ano', 'Mês', 'Dia', 'Código do Produto',\n", + " 'Descrição do Produto', 'Quantidade', 'Valor Bruto', 'Valor Desconto',\n", + " 'Valor Líquido', 'Valor Vale Troca', 'Líquido - Troca', 'Estoque Atual',\n", + " 'Estoque Mínimo'],\n", + " dtype='object')" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_venda_diaria.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "id": "c7ddaf20", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(5459, 16)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_venda_diaria['PDV'] = df_venda_diaria['Unidade de Negócio'].str.split(\"-\").str[0].str.strip()\n", "\n", @@ -292,10 +491,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "7119556a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(5459, 17)" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# 'Dia' já está em formato datetime, então renomeamos para 'Data' diretamente\n", "# ou apenas usamos 'Dia' como referência de data\n", @@ -315,10 +525,142 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "id": "c707a1b6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PDVCódigo do ProdutoCicloQuantidade Acumulada
01252248617C2022101
11252248617C2022112
21252248617C2022125
31252248617C2022137
41252248617C2022148
...............
1398569986825C2024101
1399569986825C2024112
1400569986825C2024123
1401569986825C2024154
1402569986825C2024175
\n", + "

1403 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " PDV Código do Produto Ciclo Quantidade Acumulada\n", + "0 12522 48617 C202210 1\n", + "1 12522 48617 C202211 2\n", + "2 12522 48617 C202212 5\n", + "3 12522 48617 C202213 7\n", + "4 12522 48617 C202214 8\n", + "... ... ... ... ...\n", + "1398 5699 86825 C202410 1\n", + "1399 5699 86825 C202411 2\n", + "1400 5699 86825 C202412 3\n", + "1401 5699 86825 C202415 4\n", + "1402 5699 86825 C202417 5\n", + "\n", + "[1403 rows x 4 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_venda_diaria = df_venda_diaria.drop_duplicates()\n", "\n", @@ -328,10 +670,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "id": "dc452c72", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(816, 75)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "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='left')\n", "df_final.shape" @@ -339,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "id": "c260e0e3", "metadata": {}, "outputs": [], @@ -349,7 +702,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "id": "8a05450c", "metadata": {}, "outputs": [], @@ -362,7 +715,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "id": "cc65edab", "metadata": {}, "outputs": [], @@ -373,7 +726,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "id": "c5cd5f42", "metadata": {}, "outputs": [], @@ -389,30 +742,80 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "id": "69c88d20", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.int64(12)" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['PDV'].value_counts().min()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "id": "f5206f50", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202408',\n", + " 'Histórico de Vendas do Ciclo 202409',\n", + " 'Histórico de Vendas do Ciclo 202410',\n", + " 'Histórico de Vendas do Ciclo 202411',\n", + " 'Histórico de Vendas do Ciclo 202412',\n", + " 'Histórico de Vendas do Ciclo 202413',\n", + " 'Histórico de Vendas do Ciclo 202414',\n", + " 'Histórico de Vendas do Ciclo 202415',\n", + " 'Histórico de Vendas do Ciclo 202416',\n", + " 'Histórico de Vendas do Ciclo 202417',\n", + " 'Histórico de Vendas do Ciclo 202501',\n", + " 'Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507'],\n", + " dtype='object')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[29:46]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "id": "0a1bb832", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(0.3797)" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n", "colunas_mensais = df_final.columns[29:46]\n", @@ -449,7 +852,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "a9647c32", "metadata": {}, "outputs": [], @@ -462,17 +865,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "b107e519", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[40:47]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "8290853c", "metadata": {}, "outputs": [], @@ -489,10 +910,73 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "id": "07f043f2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CANALmed_por_canal
0CD44.0
1HIB9.0
2LJ11.0
3VD28.0
\n", + "
" + ], + "text/plain": [ + " CANAL med_por_canal\n", + "0 CD 44.0\n", + "1 HIB 9.0\n", + "2 LJ 11.0\n", + "3 VD 28.0" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "medi = df_final.groupby(['CANAL'])['MEDIANA DO HISTÓRICO'].max().reset_index()\n", "medi = medi.rename(columns={'MEDIANA DO HISTÓRICO':'med_por_canal'})\n", @@ -501,7 +985,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "id": "94abddce", "metadata": {}, "outputs": [], @@ -511,7 +995,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "id": "09cc2f82", "metadata": {}, "outputs": [], @@ -538,10 +1022,91 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "id": "5a827c08", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PDVDEPARA.PracticoCódigoCiclo vdcQuantidade Acumulada vdc
02370148617C2022126
12370148617C2022138
22370148617C20221410
32370148617C20221512
42370148617C20221622
\n", + "
" + ], + "text/plain": [ + " PDVDEPARA.Practico Código Ciclo vdc Quantidade Acumulada vdc\n", + "0 23701 48617 C202212 6\n", + "1 23701 48617 C202213 8\n", + "2 23701 48617 C202214 10\n", + "3 23701 48617 C202215 12\n", + "4 23701 48617 C202216 22" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_vdc = pd.merge(left=df_vdc,right=calendario[['Date','Ciclo']],left_on='DATA VENDA',right_on='Date',how='inner')\n", "\n", @@ -555,7 +1120,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "id": "8ec14143", "metadata": {}, "outputs": [], @@ -576,10 +1141,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "id": "1a625e69", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(816, 89)" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['CRESCIMENTO_FINAL'] = df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'] #crescimento do pdv\n", "\n", @@ -587,8 +1163,7 @@ "\n", "df_final['CRESCIMENTO_FINAL'] = np.where(df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO']<0,0,df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'])\n", "\n", - "df_final['MEDIANA DO HISTÓRICO'] = np.where(df_final['MEDIANA DO HISTÓRICO']==0, df_final['' \\\n", - "'or_canal'],df_final['MEDIANA DO HISTÓRICO'])\n", + "df_final['MEDIANA DO HISTÓRICO'] = np.where(df_final['MEDIANA DO HISTÓRICO']==0, df_final['med_por_canal'],df_final['MEDIANA DO HISTÓRICO'])\n", "\n", "# Primeiro cálculo intermediário\n", "df_final['PV GINSENG'] = np.where(df_final['CRESCIMENTO_FINAL'] * df_final['Vendas Ciclo Lançamento'] + df_final['Vendas Ciclo Lançamento'] < df_final['MEDIANA DO HISTÓRICO'],\n", @@ -602,7 +1177,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "id": "ad10c069", "metadata": {}, "outputs": [], @@ -612,20 +1187,82 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "id": "f9bddbb1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n", + " 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n", + " 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n", + " 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH', 'PDV', 'CANAL',\n", + " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR', 'status',\n", + " 'Classe', 'SKU', 'Descrição', 'Subcategoria', 'Lançamento',\n", + " 'Desativação', 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual', 'Dias sem venda',\n", + " 'Projeção Próximo Ciclo', 'Projeção Próximo Ciclo + 1',\n", + " 'Promoção Próximo Ciclo', 'Promoção Próximo Ciclo + 1', 'Estoque Atual',\n", + " 'Estoque em Transito', 'Pedido Pendente',\n", + " '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', 'Quantidade',\n", + " 'Item analisado', 'Histórico de Vendas do Ciclo 202407', 'match_x',\n", + " 'CRESCIMENTO', 'Ciclo', 'INICIO CICLO', 'FIM CICLO', 'DURAÇÃO',\n", + " 'match_y', 'dias_ate_inicio', 'INICIO CICLO SIMILAR',\n", + " 'FIM CICLO SIMILAR', 'DURAÇÃO CICLO SIMILAR', 'Código do Produto',\n", + " 'Ciclo', 'Vendas Ciclo Lançamento', 'CRESCIMENTO_GERAL',\n", + " 'Pico Vendas Similar Ultimos 6 ciclos', 'MEDIANA DO HISTÓRICO',\n", + " 'med_por_canal', 'PDVDEPARA.Practico', 'Código', 'CRESCIMENTO_FINAL',\n", + " 'PV GINSENG'],\n", + " dtype='object')" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "id": "fe73c93e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n", + " 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n", + " 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n", + " 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH', 'PDV', 'CANAL',\n", + " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR',\n", + " 'Descrição', 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual',\n", + " 'Histórico de Vendas do Ciclo 202407', 'Vendas Ciclo Lançamento',\n", + " 'Pico Vendas Similar Ultimos 6 ciclos', 'MEDIANA DO HISTÓRICO',\n", + " 'PDVDEPARA.Practico', 'Código', 'PV GINSENG'],\n", + " dtype='object')" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "\n", "df_final.drop(columns=['status', 'Classe', 'SKU', 'Subcategoria', 'Lançamento',\n", @@ -647,17 +1284,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "id": "66772a9a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[23:28]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "id": "15b7149f", "metadata": {}, "outputs": [], @@ -667,10 +1320,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "id": "9333bc77", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n", + " 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n", + " 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n", + " 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH', 'PDV', 'CANAL',\n", + " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR',\n", + " 'DESCRIÇÃO', 'C-4', 'C-3', 'C-2', 'C-1', 'VENDAS CICLO ATUAL',\n", + " 'VENDAS CICLO LANÇAMENTO', 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n", + " 'MEDIANA DO HISTÓRICO', 'PDVDEPARA.PRACTICO', 'CÓDIGO', 'PV GINSENG'],\n", + " dtype='object')" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns = df_final.columns.str.upper()\n", "\n", @@ -681,7 +1353,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "id": "5abd4bae", "metadata": {}, "outputs": [], @@ -691,17 +1363,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 51, "id": "62ce5c62", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(816, 32)" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.shape" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "id": "25cbff26", "metadata": {}, "outputs": [], @@ -740,7 +1423,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "id": "a3e80cb4", "metadata": {}, "outputs": [], @@ -752,12 +1435,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 54, "id": "2df3e2e9", "metadata": {}, "outputs": [], "source": [ - "df_final.to_excel(r'C:\\Users\\joao.herculano\\Documents\\sugest.xlsx',index=False)" + "df_final.to_excel(f'C:/Users/joao.herculano/Documents/sugest{hoje}.xlsx',index=False)" ] } ], diff --git a/Ruptura_Projetada/ruptura projetada 23.05.py b/Ruptura_Projetada/ruptura projetada 23.05.py deleted file mode 100644 index a7be12b..0000000 --- a/Ruptura_Projetada/ruptura projetada 23.05.py +++ /dev/null @@ -1,221 +0,0 @@ -import smtplib -import ssl -import psycopg2 -import configparser -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt -import seaborn as sns -from email.message import EmailMessage -from email.utils import make_msgid -from pathlib import Path -from datetime import datetime, time - -from email.mime.image import MIMEImage - -config = configparser.ConfigParser() -config.read(r"C:\Users\joao.herculano\Documents\Enviador de email\credenciais.ini") - -conn = psycopg2.connect( - host=config['banco']['host'], - port="5432", - database="ginseng", - user=config['banco']['user'], - password=config['banco']['password'] -) - -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") -calendario.columns = calendario.columns.str.lower() -calendario['date'] = pd.to_datetime(calendario['date']) -today = pd.Timestamp("today").normalize() -calendario = calendario[calendario['marca'] == "BOTICARIO"] -calendario['num_ciclo'] = calendario['ciclo'].str[-2:].astype(int) -calendario['ano_ciclo'] = calendario['ciclo'].str[0:5] -calendario['ciclomais2'] = calendario['ano_ciclo'].astype(str) + (calendario['num_ciclo'] + 0).astype(str).str.zfill(2) -ciclo_mais2 = calendario[calendario['date'].dt.normalize() == today]['ciclomais2'].iloc[0] -filtered_calendario = calendario[calendario['ciclo'] == ciclo_mais2][:1].copy() -filtered_calendario['dias_ate_fim'] = (filtered_calendario['fim ciclo'].iloc[0] - today).days -print(filtered_calendario[['duração', 'dias_ate_fim']]) - -query = ''' -SELECT - businessunit AS marca, - codcategory AS categoria, - loja_id AS pdv, - code AS sku, - description AS descricao_produto, - salescurve AS curva, - CASE WHEN promotions_description = '' THEN 'REGULAR' ELSE 'PROMOÇÃO' END AS tipo_promocao, - COALESCE(stock_actual, 0) AS estoque, - stock_intransit AS transito, - nextcycleprojection AS pv_mar, - currentcyclesales AS venda_atual, - CASE WHEN criticalitem_iscritical = false THEN 'REGULAR' ELSE 'CRITICO' END AS status_item -FROM Draft -WHERE isproductdeactivated = false AND codcategory NOT IN ('SUPORTE A VENDA','EMBALAGENS') -''' -df = pd.read_sql(query, conn) -conn.close() -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['pv_mar'] + (15 * df['ddv'])).astype(int) -df['risco_ruptura'] = np.where(df['ddv'] * filtered_calendario['dias_ate_fim'].max() >= df['estoque'], "SIM", "NÃO") -df['quantidade_ruptura'] = np.ceil(df['ddv'] * filtered_calendario['dias_ate_fim'].max() - df['estoque']) -df['excesso'] = np.where(df['estoque'] - df['estoque_seguranca'] > 0, df['estoque'] - df['estoque_seguranca'], 0) - -remetente = config['credenciais']['remetente'] -senha = config['credenciais']['senha'] -destinatarios = [email.strip() for email in config['email_ruptura']['destinatarios'].split(',')] -assunto = config['email_ruptura']['assunto'] - -df_rpt = pd.read_excel(r"C:\Users\joao.herculano\Downloads\Ruptura Cliente CP GINSENG (1).xlsx") -df_rpt.columns = df_rpt.columns.str.lower() - -df['pdv'] = df['pdv'].astype('Int64') -df['sku'] = df['sku'].astype('Int64') - -df_rpt['cod_pdv'] = df_rpt['cod_pdv'].astype('Int64') -df_rpt['sku1'] = df_rpt['sku1'].astype('Int64') - -df = pd.merge(df, df_rpt[['sku1','cod_pdv','estoque livre?']], left_on=['pdv','sku'], right_on=['cod_pdv','sku1'], how='left') -df.drop(columns=['cod_pdv'], inplace=True) - -pdvs = pd.read_excel(r"C:\Users\joao.herculano\Documents\PDV_ATT.xlsx") -pdvs.columns = pdvs.columns.str.lower() -df['pdv'] = df['pdv'].astype('Int64') -pdvs['pdv'] = pdvs['pdv'].astype('Int64') -df2 = pd.merge(df, pdvs[['pdv','uf','canal','analista']], on='pdv', how='inner') - -idx = df2.groupby(['uf', 'sku'])['excesso'].idxmax() -pdvs_maior_excesso = df2.loc[idx, ['uf', 'sku', 'pdv', 'excesso']].copy() -pdvs_maior_excesso.columns = ['uf', 'sku', 'pdv_maior_excesso', 'maior_excesso_por_uf'] -pdvs_maior_excesso.set_index(['uf', 'sku'], inplace=True) -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( - df2['estoque livre?'].isna() & (df2['status_item'] == 'CRITICO'), - 'Não', - df2['estoque livre?'] -) - -df2['estoque livre?'] = np.where( - df2['estoque livre?'].isna() & (df2['status_item'] == 'REGULAR'), - 'Sim', - df2['estoque livre?'] -) - -excel_path = Path("relatorio.xlsx") - -colunas_ordenadas = [ - 'uf', - 'canal', - 'analista', - 'marca', - 'categoria', - 'pdv', - 'sku', - 'descricao_produto', - 'curva', - 'tipo_promocao', - 'estoque', - 'transito', - 'pv_mar', - 'venda_atual', - 'status_item', - 'ddv', - 'estoque_seguranca', - 'risco_ruptura', - 'quantidade_ruptura', - 'excesso', - 'estoque livre?', - 'maior_excesso_por_uf', - 'maior excesso na uf' -] - -df2 = df2[colunas_ordenadas] - -df3 = df2[df2['canal'] != "LJ"] - -df3 = df3.groupby(['uf', 'canal','pdv'])['quantidade_ruptura'].sum().sort_values(ascending=False).reset_index() - -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) - -ruptura_total = df2['quantidade_ruptura'].sum() -ruptura_por_uf_pct = ( - df2.groupby('uf')['quantidade_ruptura'].sum() - .sort_values(ascending=True) - .apply(lambda x: (x / ruptura_total) * 100) -) -print(ruptura_por_uf_pct) -ax = ruptura_por_uf_pct.plot(kind='barh', figsize=(10, 6), color='skyblue') -for i, v in enumerate(ruptura_por_uf_pct): - ax.text(v + 0.3, i, f"{v:.1f}%", va='center') -plt.xlabel('% da ruptura total') -plt.title('Distribuição percentual de ruptura projetada por UF') -plt.tight_layout() -plt.savefig("grafico.png") -plt.close() - -agora = datetime.now().time() -if time(5, 0) <= agora <= time(12, 0): - boa = "Bom dia!" -elif time(12, 1) <= agora <= time(18, 0): - boa = "Boa tarde!" -else: - boa = "Boa noite!" - -grafico_cid = make_msgid()[1:-1] -msg = EmailMessage() -msg['From'] = remetente -msg['To'] = ', '.join(destinatarios) -msg['Subject'] = assunto -html_email = f""" - - -

{boa}

-

Compartilhamos o relatório de ruptura projetada, com o objetivo de monitorar os itens com maior risco de ruptura nos próximos dias.

-

O relatório a seguir apresenta as seguintes informações:

- -

Além disso, o material destaca as VDs com maior criticidade, permitindo uma atuação direcionada para mitigar impactos e priorizar ações de abastecimento e transferência.

-

Importante: O relatório está em processo de desenvolvimento e pode sofrer mudanças futuras no layout. Ficamos à disposição para esclarecer quaisquer dúvidas.

- - - - - -""" -msg.set_content("Seu e-mail precisa de um visualizador HTML.") -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(excel_path, 'rb') as f: - msg.add_attachment( - f.read(), - maintype='application', - subtype='vnd.openxmlformats-officedocument.spreadsheetml.sheet', - filename=excel_path.name - ) - -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.") \ No newline at end of file diff --git a/promoção/promoção_boti_ciclo07.ipynb b/promoção/promoção_boti_ciclo07.ipynb index 52c7b46..8e90a8e 100644 --- a/promoção/promoção_boti_ciclo07.ipynb +++ b/promoção/promoção_boti_ciclo07.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -10,15 +10,23 @@ "import numpy as np \n", "import glob\n", "import os \n", - "\n", - "\n", "from openpyxl import load_workbook\n", - "from openpyxl.styles import PatternFill, Font" + "from openpyxl.styles import PatternFill, Font\n", + "from datetime import datetime" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "hoje = datetime.today().strftime('%Y-%m-%d')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -36,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -68,25 +76,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Ciclo', 'Região', 'Canal', 'Código', 'Descrição', 'IAF',\n", + " 'Tipo de pedido', 'Foco', 'Unidade de negócio', 'Marca', 'Categoria',\n", + " 'Subcategoria', 'Quantidade por caixa', 'Tipo de promoção', 'Catálogo',\n", + " 'Tipo de produto', 'Ação consumidor',\n", + " 'Percentual de desconto consumidor', 'Ação revendedor',\n", + " 'Percentual de desconto revendedor', 'Sortimento P', 'Sortimento M',\n", + " 'Sortimento G', 'MATCH'],\n", + " dtype='object')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_tabela.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(702, 24)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_tabela.shape" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -112,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -121,14 +158,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37488\\4129764549.py:10: DtypeWarning: Columns (7) have mixed types. Specify dtype option on import or set low_memory=False.\n", + " df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n" + ] + }, + { + "data": { + "text/plain": [ + "(114430, 46)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "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\\DB_PROMOÇÕES\\BOTICARIO\\C10\\DRAFT_PDVS_SEM_\" # arquivo dos drafts\n", + "folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C11\\atualização\\DRAFT_\" # arquivo dos drafts\n", "\n", "# Pattern to match all CSV files\n", "csv_files = glob.glob(os.path.join(folder_path, '*.csv'))\n", @@ -141,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -155,14 +211,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "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\\DB_PROMOÇÕES\\BOTICARIO\\C10\\estoque\"\n", + "pasta_entrada = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C11\\atualização\\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", @@ -196,16 +252,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Ciclo', 'Região', 'Canal', 'Código', 'Descrição', 'IAF',\n", + " 'Tipo de pedido', 'Foco', 'Unidade de negócio', 'Marca', 'Categoria',\n", + " 'Subcategoria', 'Quantidade por caixa', 'Tipo de promoção', 'Catálogo',\n", + " 'Tipo de produto', 'Ação consumidor',\n", + " 'Percentual de desconto consumidor', 'Ação revendedor',\n", + " 'Percentual de desconto revendedor', 'Sortimento P', 'Sortimento M',\n", + " 'Sortimento G', 'MATCH'],\n", + " dtype='object')" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_tabela.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -219,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -231,18 +305,269 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SKUSKU_PARAPDVESTOQUE ATUALESTOQUE EM TRANSITOPEDIDO PENDENTEDDV PREVISTOCOBERTURA ATUALCOBERTURA ATUAL + TRANSITOArquivo_OrigemSKU_FINAL
090495-20005100.00.00.0NaNNaNNaNBOT.csv90495
190246-45600.0NaN0.0NaNNaNNaNBOT.csv90246
290246-56990.0NaN0.0NaNNaNNaNBOT.csv90246
390246-125220.0NaN0.0NaNNaNNaNBOT.csv90246
490246-128170.0NaN0.0NaNNaNNaNBOT.csv90246
....................................
4412161594-209950.00.00.0NaNNaNNaNQDB.csv1594
4412171594-209980.00.00.0NaNNaNNaNQDB.csv1594
4412181594-210010.00.00.0NaNNaNNaNQDB.csv1594
4412191594-212780.00.00.0NaNNaNNaNQDB.csv1594
4412201594-213830.00.00.0NaNNaNNaNQDB.csv1594
\n", + "

441221 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " SKU SKU_PARA PDV ESTOQUE ATUAL ESTOQUE EM TRANSITO \\\n", + "0 90495 - 20005 100.0 0.0 \n", + "1 90246 - 4560 0.0 NaN \n", + "2 90246 - 5699 0.0 NaN \n", + "3 90246 - 12522 0.0 NaN \n", + "4 90246 - 12817 0.0 NaN \n", + "... ... ... ... ... ... \n", + "441216 1594 - 20995 0.0 0.0 \n", + "441217 1594 - 20998 0.0 0.0 \n", + "441218 1594 - 21001 0.0 0.0 \n", + "441219 1594 - 21278 0.0 0.0 \n", + "441220 1594 - 21383 0.0 0.0 \n", + "\n", + " PEDIDO PENDENTE DDV PREVISTO COBERTURA ATUAL \\\n", + "0 0.0 NaN NaN \n", + "1 0.0 NaN NaN \n", + "2 0.0 NaN NaN \n", + "3 0.0 NaN NaN \n", + "4 0.0 NaN NaN \n", + "... ... ... ... \n", + "441216 0.0 NaN NaN \n", + "441217 0.0 NaN NaN \n", + "441218 0.0 NaN NaN \n", + "441219 0.0 NaN NaN \n", + "441220 0.0 NaN NaN \n", + "\n", + " COBERTURA ATUAL + TRANSITO Arquivo_Origem SKU_FINAL \n", + "0 NaN BOT.csv 90495 \n", + "1 NaN BOT.csv 90246 \n", + "2 NaN BOT.csv 90246 \n", + "3 NaN BOT.csv 90246 \n", + "4 NaN BOT.csv 90246 \n", + "... ... ... ... \n", + "441216 NaN QDB.csv 1594 \n", + "441217 NaN QDB.csv 1594 \n", + "441218 NaN QDB.csv 1594 \n", + "441219 NaN QDB.csv 1594 \n", + "441220 NaN QDB.csv 1594 \n", + "\n", + "[441221 rows x 11 columns]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_estoque" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\openpyxl\\styles\\stylesheet.py:237: UserWarning: Workbook contains no default style, apply openpyxl's default\n", + " warn(\"Workbook contains no default style, apply openpyxl's default\")\n" + ] + } + ], "source": [ "df_bi_preco = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C09\\arquivos pra gerar\\preços bi\\TABELA DE PREÇOS (4).xlsx\")\n", "\n", @@ -252,9 +577,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(44744, 31)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final = pd.merge(left=df_tabela,right=df_pdv,on='MATCH',how='inner')\n", "\n", @@ -265,9 +601,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(44744, 62)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['PDV'] = df_final['PDV'].astype('Int64')\n", "df_final['Código'] = df_final['Código'].astype('Int64')\n", @@ -279,16 +626,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "26447 2.0\n", + "Name: Histórico de Vendas do Ciclo 202505, dtype: float64" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final[(df_final['Código'] == 52023) & (df_final['PDV'] == 23712)]['Histórico de Vendas do Ciclo 202505']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -298,7 +657,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -307,7 +666,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -330,9 +689,71 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CicloINICIO CICLOFIM CICLODURAÇÃODateNUM_CICLOANO_CICLOCICLOMAIS2dias_ate_inicio
2199C2025102025-06-302025-07-20212025-06-3010C2025C20251228
\n", + "
" + ], + "text/plain": [ + " Ciclo INICIO CICLO FIM CICLO DURAÇÃO Date NUM_CICLO \\\n", + "2199 C202510 2025-06-30 2025-07-20 21 2025-06-30 10 \n", + "\n", + " ANO_CICLO CICLOMAIS2 dias_ate_inicio \n", + "2199 C2025 C202512 28 " + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "calendario['Date'] = pd.to_datetime(calendario['Date'])\n", "\n", @@ -365,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -374,7 +795,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -383,7 +804,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -392,7 +813,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -401,9 +822,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(44744, 62)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "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='inner')\n", "df_final.shape" @@ -411,9 +843,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(54425, 72)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['Código'] = df_final['Código'].astype('Int64') \n", "df_final['PDV'] = df_final['PDV'].astype('Int64') \n", @@ -427,9 +870,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(54425, 76)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['Código'] = df_final['Código'].astype('str')\n", "\n", @@ -441,9 +895,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(54514, 80)" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_bi_preco['SKU1'] = df_bi_preco['SKU1'].astype(str).str.replace('.0','',regex=False) \n", "\n", @@ -453,7 +918,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -465,9 +930,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "CANAL\n", + "TODOS 42336\n", + "VD 12178\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], "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", @@ -476,7 +955,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -491,7 +970,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -503,7 +982,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -512,7 +991,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -521,7 +1000,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -530,7 +1009,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -539,9 +1018,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.int64(0)" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final = df_final[~df_final['Marca'].isna()]\n", "df_final['Marca'].isna().sum()" @@ -549,9 +1039,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(54514, 74)" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final = df_final.drop_duplicates()\n", "df_final.shape" @@ -559,7 +1060,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ @@ -568,16 +1069,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202408',\n", + " 'Histórico de Vendas do Ciclo 202409',\n", + " 'Histórico de Vendas do Ciclo 202410',\n", + " 'Histórico de Vendas do Ciclo 202411',\n", + " 'Histórico de Vendas do Ciclo 202412',\n", + " 'Histórico de Vendas do Ciclo 202413',\n", + " 'Histórico de Vendas do Ciclo 202414',\n", + " 'Histórico de Vendas do Ciclo 202415',\n", + " 'Histórico de Vendas do Ciclo 202416',\n", + " 'Histórico de Vendas do Ciclo 202417',\n", + " 'Histórico de Vendas do Ciclo 202501',\n", + " 'Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[26:44]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -590,16 +1120,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[37:44]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -610,18 +1158,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503',\n", + " 'Histórico de Vendas do Ciclo 202504',\n", + " 'Histórico de Vendas do Ciclo 202505',\n", + " 'Histórico de Vendas do Ciclo 202506',\n", + " 'Histórico de Vendas do Ciclo 202507',\n", + " 'Histórico de Vendas do Ciclo Atual'],\n", + " dtype='object')" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[37:44]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37488\\2592201544.py:24: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n", + " crescimento_por_pdv = df_final.groupby('PDV').apply(calcular_crescimento)\n" + ] + } + ], "source": [ "# Define as colunas mensais\n", "colunas_mensais = df_final.columns[26:43]\n", @@ -654,9 +1229,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(0.0528)" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n", "colunas_mensais = df_final.columns[26:43]\n", @@ -693,9 +1279,60 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CANALmed_por_canal
0TODOS92.5
1VD715.0
\n", + "
" + ], + "text/plain": [ + " CANAL med_por_canal\n", + "0 TODOS 92.5\n", + "1 VD 715.0" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "vendas_todos_historicos = df_final.columns[26:44]\n", "\n", @@ -713,16 +1350,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 51, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'202410'" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[28:29].str.split(\" \")[0][-1]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "metadata": {}, "outputs": [], "source": [ @@ -733,9 +1381,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(54514, 84)" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final['CRESCIMENTO_FINAL'] = df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'] #crescimento do pdv\n", "\n", @@ -756,16 +1415,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 54, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Histórico de Vendas do Ciclo 202408',\n", + " 'Histórico de Vendas do Ciclo 202409',\n", + " 'Histórico de Vendas do Ciclo 202410',\n", + " 'Histórico de Vendas do Ciclo 202411',\n", + " 'Histórico de Vendas do Ciclo 202412',\n", + " 'Histórico de Vendas do Ciclo 202413',\n", + " 'Histórico de Vendas do Ciclo 202414',\n", + " 'Histórico de Vendas do Ciclo 202415',\n", + " 'Histórico de Vendas do Ciclo 202416',\n", + " 'Histórico de Vendas do Ciclo 202417',\n", + " 'Histórico de Vendas do Ciclo 202501',\n", + " 'Histórico de Vendas do Ciclo 202502',\n", + " 'Histórico de Vendas do Ciclo 202503'],\n", + " dtype='object')" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final.columns[26:39]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 55, "metadata": {}, "outputs": [], "source": [ @@ -774,7 +1457,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 56, "metadata": {}, "outputs": [], "source": [ @@ -783,7 +1466,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -801,7 +1484,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 58, "metadata": {}, "outputs": [], "source": [ @@ -810,16 +1493,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "158 2.0\n", + "159 1.0\n", + "160 0.0\n", + "327 0.0\n", + "328 0.0\n", + " ... \n", + "54257 18.0\n", + "54347 32.0\n", + "54440 0.0\n", + "54441 112.0\n", + "54509 694.0\n", + "Name: C-3, Length: 731, dtype: float64" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup[(df_final['PDV'] == 23712)]['C-3']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 60, "metadata": {}, "outputs": [], "source": [ @@ -832,16 +1537,47 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 61, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['202410', 'ANALISTA', 'Arquivo_Origem_x', 'Arquivo_Origem_y',\n", + " 'Ação consumidor', 'Ação revendedor', 'C-1', 'C-2', 'C-3', 'C-4',\n", + " 'CANAL', 'COBERTURA ATUAL + TRANSITO', 'CRESCIMENTO',\n", + " 'CRESCIMENTO_FINAL', 'CRESCIMENTO_GERAL', 'Canal', 'Categoria',\n", + " 'Catálogo', 'Ciclo_x', 'Ciclo_y', 'Classe', 'Código', 'DESCRIÇÃO PDV',\n", + " 'DURAÇÃO', 'Data Prevista Regularização', 'Descrição', 'Dias sem venda',\n", + " 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO', 'Estoque Atual',\n", + " 'Estoque em Transito', 'FIM CICLO', 'Foco',\n", + " 'Histórico de Vendas do Ciclo 202407',\n", + " 'Histórico de Vendas do Ciclo Atual', 'IAF', 'INICIO CICLO',\n", + " 'Item Desativado', 'MATCH', 'MEDIA DO HISTÓRICO',\n", + " 'MEDIANA DO HISTÓRICO', 'Marca', 'PDV', 'PEDIDO PENDENTE',\n", + " 'PICO DE VENDAS 2024', 'PRECO DE COMPRA', 'PRECO DE VENDA',\n", + " 'PV GINSENG', 'Pedido Pendente', 'Percentual de desconto consumidor',\n", + " 'Percentual de desconto revendedor', 'Pico Vendas Ultimos 6 ciclos',\n", + " 'Projeção Próximo Ciclo', 'Projeção Próximo Ciclo + 1',\n", + " 'Promoção Próximo Ciclo + 1', 'Região', 'SKU', 'SKU_FINAL', 'SKU_PARA',\n", + " 'SKU_PARA_VALIDACAO', 'SUPERVISOR', 'Tipo de pedido', 'Tipo de produto',\n", + " 'Tipo de promoção', 'UF', 'UFPRODUTO', 'Unidade de negócio',\n", + " 'dias_ate_inicio', 'med_por_canal', 'DDV PREVISTO', 'COBERTURA ATUAL'],\n", + " dtype='object')" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 62, "metadata": {}, "outputs": [], "source": [ @@ -850,7 +1586,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 63, "metadata": {}, "outputs": [], "source": [ @@ -859,7 +1595,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "metadata": {}, "outputs": [], "source": [ @@ -868,18 +1604,47 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 65, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['SKU', 'SKU_PARA', 'PDV', 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO',\n", + " 'PEDIDO PENDENTE', 'DDV PREVISTO', 'COBERTURA ATUAL',\n", + " 'COBERTURA ATUAL + TRANSITO', 'Arquivo_Origem', 'SKU_PARA_VALIDACAO'],\n", + " dtype='object')" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_estoque.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "('Ação consumidor',\n", + " 'Percentual de desconto consumidor',\n", + " 'Ação revendedor',\n", + " 'Percentual de desconto revendedor',\n", + " '202408')" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Columns to bring up front\n", "priority_cols = [\n", @@ -903,7 +1668,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "metadata": {}, "outputs": [], "source": [ @@ -912,7 +1677,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 68, "metadata": {}, "outputs": [], "source": [ @@ -921,7 +1686,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 69, "metadata": {}, "outputs": [], "source": [ @@ -933,7 +1698,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 70, "metadata": {}, "outputs": [], "source": [ @@ -942,7 +1707,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 71, "metadata": {}, "outputs": [], "source": [ @@ -952,7 +1717,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 72, "metadata": {}, "outputs": [], "source": [ @@ -961,7 +1726,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 73, "metadata": {}, "outputs": [], "source": [ @@ -970,9 +1735,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 74, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'BOT'" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "marca_promo = df_estoque['Arquivo_Origem'].iloc[0].replace('.csv','')\n", "marca_promo" @@ -980,7 +1756,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 75, "metadata": {}, "outputs": [], "source": [ @@ -991,7 +1767,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 76, "metadata": {}, "outputs": [], "source": [ @@ -1000,7 +1776,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 77, "metadata": {}, "outputs": [], "source": [ @@ -1013,7 +1789,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 78, "metadata": {}, "outputs": [], "source": [ @@ -1030,16 +1806,230 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 79, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
202410_xANALISTAArquivo_Origem_xArquivo_Origem_yAção consumidorAção revendedorC-1C-2C-3C-4...COBERTURA ATUALEST PROJE FINAL CICLO ATUALVENDAS R$ PV GINSENGRBV 202406COB PROJETADACANAL_yUF_yPDV GINSENGPRODUTO202410_y
00.0DANIELBOT.csvBOT.csvACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.0.00.00.00.0...45.07.0NaNNaN700.0LJVDCNaN<NA>0.0
10.0DANIELBOT.csvBOT.csvACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.0.00.00.00.0...45.04.0NaNNaN400.0VDVDC23703.0539012.0
20.0DANIELBOT.csvBOT.csvACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.0.00.00.02.0...0.00.075.90.050.0HIBALNaN<NA>0.0
30.0DANIELBOT.csvBOT.csvACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.0.01.00.00.0...50.00.00.00.00.0LJBANaN<NA>0.0
40.0DANIELBOT.csvBOT.csvACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO.3.00.00.01.0...260.012.075.90.0260.0LJBANaN<NA>0.0
\n", + "

5 rows × 76 columns

\n", + "
" + ], + "text/plain": [ + " 202410_x ANALISTA Arquivo_Origem_x Arquivo_Origem_y \\\n", + "0 0.0 DANIEL BOT.csv BOT.csv \n", + "1 0.0 DANIEL BOT.csv BOT.csv \n", + "2 0.0 DANIEL BOT.csv BOT.csv \n", + "3 0.0 DANIEL BOT.csv BOT.csv \n", + "4 0.0 DANIEL BOT.csv BOT.csv \n", + "\n", + " Ação consumidor \\\n", + "0 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. \n", + "1 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. \n", + "2 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. \n", + "3 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. \n", + "4 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. \n", + "\n", + " Ação revendedor C-1 C-2 C-3 C-4 ... \\\n", + "0 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. 0.0 0.0 0.0 0.0 ... \n", + "1 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. 0.0 0.0 0.0 0.0 ... \n", + "2 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. 0.0 0.0 0.0 2.0 ... \n", + "3 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. 0.0 1.0 0.0 0.0 ... \n", + "4 ACESSÓRIOS SELECIONADOS COM ATÉ 15% DE DESCONTO. 3.0 0.0 0.0 1.0 ... \n", + "\n", + " COBERTURA ATUAL EST PROJE FINAL CICLO ATUAL VENDAS R$ PV GINSENG \\\n", + "0 45.0 7.0 NaN \n", + "1 45.0 4.0 NaN \n", + "2 0.0 0.0 75.9 \n", + "3 50.0 0.0 0.0 \n", + "4 260.0 12.0 75.9 \n", + "\n", + " RBV 202406 COB PROJETADA CANAL_y UF_y PDV GINSENG PRODUTO 202410_y \n", + "0 NaN 700.0 LJ VDC NaN 0.0 \n", + "1 NaN 400.0 VD VDC 23703.0 53901 2.0 \n", + "2 0.0 50.0 HIB AL NaN 0.0 \n", + "3 0.0 0.0 LJ BA NaN 0.0 \n", + "4 0.0 260.0 LJ BA NaN 0.0 \n", + "\n", + "[5 rows x 76 columns]" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup.head()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 80, "metadata": {}, "outputs": [], "source": [ @@ -1048,7 +2038,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 81, "metadata": {}, "outputs": [], "source": [ @@ -1065,7 +2055,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 82, "metadata": {}, "outputs": [], "source": [ @@ -1074,25 +2064,68 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 83, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['202410', 'ANALISTA', 'Ação consumidor', 'Ação revendedor', 'C-1',\n", + " 'C-2', 'C-3', 'C-4', 'Categoria', 'Classe', 'Código', 'DESCRIÇÃO PDV',\n", + " 'Descrição', 'Dias sem venda', 'Estoque Atual', 'Estoque em Transito',\n", + " 'Histórico de Vendas do Ciclo 202407',\n", + " 'Histórico de Vendas do Ciclo Atual', 'MEDIANA DO HISTÓRICO', 'LINHA',\n", + " 'PDV', 'PICO DE VENDAS 2024', 'PRECO DE VENDA', 'PV GINSENG',\n", + " 'Pedido Pendente', 'Percentual de desconto consumidor',\n", + " 'Percentual de desconto revendedor', 'Pico Vendas Ultimos 6 ciclos',\n", + " 'Projeção Próximo Ciclo', 'Projeção Próximo Ciclo + 1',\n", + " 'Promoção Próximo Ciclo + 1', 'SUPERVISOR', 'CANAL', 'UF'],\n", + " dtype='object')" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 84, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "158 2.0\n", + "159 1.0\n", + "160 0.0\n", + "327 0.0\n", + "328 0.0\n", + " ... \n", + "54257 18.0\n", + "54347 32.0\n", + "54440 0.0\n", + "54441 112.0\n", + "54509 694.0\n", + "Name: C-3, Length: 731, dtype: float64" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup[(df_final['PDV'] == 23712)]['C-3']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 85, "metadata": {}, "outputs": [], "source": [ @@ -1112,7 +2145,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 86, "metadata": {}, "outputs": [], "source": [ @@ -1121,18 +2154,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 87, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(157499.0)" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup['PV GINSENG'].sum()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 88, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "np.int64(0)" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df_final_dedup[df_final_dedup['PDV'] == 23712]['PICO DE VENDAS 2024'].isna().sum()" ] @@ -1144,7 +2199,7 @@ "outputs": [], "source": [ "# Export to Excel\n", - "output_file = f'C:\\\\Users\\\\joao.herculano\\\\Documents\\\\promoção_{marca_promo}_{ciclo_mais2}28.05.xlsx'\n", + "output_file = f'C:\\\\Users\\\\joao.herculano\\\\Documents\\\\promoção_{marca_promo}_{ciclo_mais2}.{hoje}.xlsx'\n", "with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n", " df_final_dedup.to_excel(writer, index=False)\n", "\n",