{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "59770f7e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import psycopg2\n",
    " \n",
    "# Conexão com o banco\n",
    "conn = psycopg2.connect(\n",
    "    host=\"10.77.77.29\",       # ou IP do servidor\n",
    "    port=\"5432\",            # padrão do PostgreSQL\n",
    "    database=\"ginseng\",\n",
    "    user=\"joaoherculano\",\n",
    "    password=\"Ginseng@\"\n",
    ")\n",
    " \n",
    "# Criar um cursor para executar comandos SQL\n",
    "cur = conn.cursor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "aca4b2c2",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_109208\\760475755.py:21: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.\n",
      "  df = pd.read_sql(query, conn)\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>loja_id</th>\n",
       "      <th>code</th>\n",
       "      <th>description</th>\n",
       "      <th>launch</th>\n",
       "      <th>deactivation</th>\n",
       "      <th>thirdtolastcyclesales</th>\n",
       "      <th>secondtolastcyclesales</th>\n",
       "      <th>lastcyclesales</th>\n",
       "      <th>currentcyclesales</th>\n",
       "      <th>nextcycleprojection</th>\n",
       "      <th>...</th>\n",
       "      <th>criticalitem_blockedwallet</th>\n",
       "      <th>criticalitem_iscritical</th>\n",
       "      <th>codsubcategory</th>\n",
       "      <th>isproductdeactivated</th>\n",
       "      <th>brandgroupcode</th>\n",
       "      <th>dayswithoutsales</th>\n",
       "      <th>coveragedays</th>\n",
       "      <th>hascoverage</th>\n",
       "      <th>status_venda</th>\n",
       "      <th>valor_estoque_parado</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20997</td>\n",
       "      <td>48359</td>\n",
       "      <td>ZAAD EDP 50ml V2</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>PERFUMARIA MASCULINA</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>54</td>\n",
       "      <td>20</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>168.09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20997</td>\n",
       "      <td>48789</td>\n",
       "      <td>THE BLEND DES ANTIT AER 75g/125ml V3</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>DESODORANTE MASCULINO</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>72</td>\n",
       "      <td>25</td>\n",
       "      <td>True</td>\n",
       "      <td>mais de 60 dias</td>\n",
       "      <td>12.37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>20997</td>\n",
       "      <td>70693</td>\n",
       "      <td>SOPHIE LOC HID CPO 200ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>CUIDADOS COM O CORPO</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>48</td>\n",
       "      <td>4</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>11.41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20997</td>\n",
       "      <td>75921</td>\n",
       "      <td>SOPHIE BATOM ROSA PINK 3,3g</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>MAQUIAGEM</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>53</td>\n",
       "      <td>15</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>16.58</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20997</td>\n",
       "      <td>53410</td>\n",
       "      <td>REF NSPA SAB LIQ CPO PERF AMEI/NEG 200ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>CORPO</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>135</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>acima de 100 dias</td>\n",
       "      <td>85.12</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 34 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "  loja_id   code                               description launch  \\\n",
       "0   20997  48359                          ZAAD EDP 50ml V2          \n",
       "1   20997  48789      THE BLEND DES ANTIT AER 75g/125ml V3          \n",
       "2   20997  70693                  SOPHIE LOC HID CPO 200ml          \n",
       "3   20997  75921               SOPHIE BATOM ROSA PINK 3,3g          \n",
       "4   20997  53410  REF NSPA SAB LIQ CPO PERF AMEI/NEG 200ml          \n",
       "\n",
       "  deactivation  thirdtolastcyclesales  secondtolastcyclesales  lastcyclesales  \\\n",
       "0                                   0                       1               0   \n",
       "1                                   1                       0               0   \n",
       "2                                   0                       2               0   \n",
       "3                                   1                       1               0   \n",
       "4                                   0                       0               0   \n",
       "\n",
       "   currentcyclesales  nextcycleprojection  ...  criticalitem_blockedwallet  \\\n",
       "0                  0                    2  ...                       False   \n",
       "1                  0                    1  ...                       False   \n",
       "2                  0                    3  ...                       False   \n",
       "3                  0                    3  ...                       False   \n",
       "4                  0                    6  ...                       False   \n",
       "\n",
       "   criticalitem_iscritical         codsubcategory  isproductdeactivated  \\\n",
       "0                    False   PERFUMARIA MASCULINA                 False   \n",
       "1                    False  DESODORANTE MASCULINO                 False   \n",
       "2                    False   CUIDADOS COM O CORPO                 False   \n",
       "3                    False              MAQUIAGEM                 False   \n",
       "4                    False                  CORPO                 False   \n",
       "\n",
       "   brandgroupcode  dayswithoutsales  coveragedays hascoverage  \\\n",
       "0             BOT                54            20       False   \n",
       "1             BOT                72            25        True   \n",
       "2             BOT                48             4       False   \n",
       "3             BOT                53            15       False   \n",
       "4             BOT               135            31        True   \n",
       "\n",
       "        status_venda valor_estoque_parado  \n",
       "0    mais de 40 dias               168.09  \n",
       "1    mais de 60 dias                12.37  \n",
       "2    mais de 40 dias                11.41  \n",
       "3    mais de 40 dias                16.58  \n",
       "4  acima de 100 dias                85.12  \n",
       "\n",
       "[5 rows x 34 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    " \n",
    "query = '''\n",
    "select\n",
    "\t*,\n",
    "\tCASE\n",
    "\t    WHEN dayswithoutsales BETWEEN 40 AND 59 THEN 'mais de 40 dias'\n",
    "\t    WHEN dayswithoutsales BETWEEN 60 AND 79 THEN 'mais de 60 dias'\n",
    "\t    WHEN dayswithoutsales BETWEEN 80 AND 99 THEN 'mais de 80 dias'\n",
    "\t    WHEN dayswithoutsales >= 100 THEN 'acima de 100 dias'\n",
    "    \tELSE 'menos de 40 dias' \n",
    "\tend as status_venda,\n",
    "\tpricesellin * (stock_actual + stock_intransit) AS valor_estoque_parado\n",
    "from \"public\".\"draft\"\n",
    "where dayswithoutsales > 40 \n",
    "and deactivation = '' \n",
    "and stock_actual > 0 \n",
    "and isproductdeactivated is not null \n",
    "and currentcyclesales = 0\n",
    "'''\n",
    "df = pd.read_sql(query, conn)\n",
    " \n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6b5a3633",
   "metadata": {},
   "outputs": [],
   "source": [
    "cur.close()\n",
    "conn.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "eec9748d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['loja_id', 'code', 'description', 'launch', 'deactivation',\n",
       "       'thirdtolastcyclesales', 'secondtolastcyclesales', 'lastcyclesales',\n",
       "       'currentcyclesales', 'nextcycleprojection',\n",
       "       'secondtonextcycleprojection', 'stock_actual', 'stock_intransit',\n",
       "       'purchasesuggestion', 'smartpurchase_purchasesuggestioncycle',\n",
       "       'smartpurchase_nextcyclepurchasesuggestion', 'pendingorder',\n",
       "       'salescurve', 'promotions_description', 'promotions_discountpercent',\n",
       "       'pricesellin', 'businessunit', 'codcategory',\n",
       "       'criticalitem_dtprovidedregularization', 'criticalitem_blockedwallet',\n",
       "       'criticalitem_iscritical', 'codsubcategory', 'isproductdeactivated',\n",
       "       'brandgroupcode', 'dayswithoutsales', 'coveragedays', 'hascoverage',\n",
       "       'status_venda', 'valor_estoque_parado'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5582a6f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4b58e424",
   "metadata": {},
   "outputs": [],
   "source": [
    "df['estoque futuro'] = df['stock_actual'] + df['stock_intransit']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "044a8e30",
   "metadata": {},
   "outputs": [],
   "source": [
    "pdvs = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C08\\arquivos pra gerar a previsão\\pdvs\\pdvs.xlsx\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "74cc2f69",
   "metadata": {},
   "outputs": [],
   "source": [
    "df['loja_id'] = df['loja_id'].astype('Int64')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cd1e2831",
   "metadata": {},
   "outputs": [],
   "source": [
    "pdvs['PDV'] = pdvs['PDV'].astype('Int64')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "94772f8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "df2= pd.merge(left=df,right=pdvs[['PDV','UF']],left_on='loja_id',right_on='PDV',how='inner')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "115f94d0",
   "metadata": {},
   "outputs": [
    {
     "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>loja_id</th>\n",
       "      <th>code</th>\n",
       "      <th>description</th>\n",
       "      <th>launch</th>\n",
       "      <th>deactivation</th>\n",
       "      <th>thirdtolastcyclesales</th>\n",
       "      <th>secondtolastcyclesales</th>\n",
       "      <th>lastcyclesales</th>\n",
       "      <th>currentcyclesales</th>\n",
       "      <th>nextcycleprojection</th>\n",
       "      <th>...</th>\n",
       "      <th>isproductdeactivated</th>\n",
       "      <th>brandgroupcode</th>\n",
       "      <th>dayswithoutsales</th>\n",
       "      <th>coveragedays</th>\n",
       "      <th>hascoverage</th>\n",
       "      <th>status_venda</th>\n",
       "      <th>valor_estoque_parado</th>\n",
       "      <th>estoque futuro</th>\n",
       "      <th>PDV</th>\n",
       "      <th>UF</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20997</td>\n",
       "      <td>48359</td>\n",
       "      <td>ZAAD EDP 50ml V2</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>54</td>\n",
       "      <td>20</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>168.09</td>\n",
       "      <td>3</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20997</td>\n",
       "      <td>48789</td>\n",
       "      <td>THE BLEND DES ANTIT AER 75g/125ml V3</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>72</td>\n",
       "      <td>25</td>\n",
       "      <td>True</td>\n",
       "      <td>mais de 60 dias</td>\n",
       "      <td>12.37</td>\n",
       "      <td>1</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>20997</td>\n",
       "      <td>70693</td>\n",
       "      <td>SOPHIE LOC HID CPO 200ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>48</td>\n",
       "      <td>4</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>11.41</td>\n",
       "      <td>1</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20997</td>\n",
       "      <td>75921</td>\n",
       "      <td>SOPHIE BATOM ROSA PINK 3,3g</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>53</td>\n",
       "      <td>15</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>16.58</td>\n",
       "      <td>2</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20997</td>\n",
       "      <td>53410</td>\n",
       "      <td>REF NSPA SAB LIQ CPO PERF AMEI/NEG 200ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>135</td>\n",
       "      <td>31</td>\n",
       "      <td>True</td>\n",
       "      <td>acima de 100 dias</td>\n",
       "      <td>85.12</td>\n",
       "      <td>7</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3437</th>\n",
       "      <td>20997</td>\n",
       "      <td>82845</td>\n",
       "      <td>MATCH COND LISO PROLONGADO 280ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>66</td>\n",
       "      <td>28</td>\n",
       "      <td>True</td>\n",
       "      <td>mais de 60 dias</td>\n",
       "      <td>42.48</td>\n",
       "      <td>3</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3438</th>\n",
       "      <td>20997</td>\n",
       "      <td>49093</td>\n",
       "      <td>MATCH AMP CAP PREENCHEDORA 9ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>66</td>\n",
       "      <td>18</td>\n",
       "      <td>False</td>\n",
       "      <td>mais de 60 dias</td>\n",
       "      <td>20.04</td>\n",
       "      <td>2</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3439</th>\n",
       "      <td>20997</td>\n",
       "      <td>50165</td>\n",
       "      <td>MALBEC SHW GEL CAB/CPO 75g</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>157</td>\n",
       "      <td>17</td>\n",
       "      <td>False</td>\n",
       "      <td>acima de 100 dias</td>\n",
       "      <td>9.08</td>\n",
       "      <td>1</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3440</th>\n",
       "      <td>20997</td>\n",
       "      <td>59017</td>\n",
       "      <td>MALBEC LOC DES HID CPO MATE 75ml</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>89</td>\n",
       "      <td>34</td>\n",
       "      <td>True</td>\n",
       "      <td>mais de 80 dias</td>\n",
       "      <td>21.02</td>\n",
       "      <td>2</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3441</th>\n",
       "      <td>20997</td>\n",
       "      <td>56000</td>\n",
       "      <td>PMPCK MEN CABELOS</td>\n",
       "      <td></td>\n",
       "      <td></td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>BOT</td>\n",
       "      <td>43</td>\n",
       "      <td>71</td>\n",
       "      <td>True</td>\n",
       "      <td>mais de 40 dias</td>\n",
       "      <td>94.48</td>\n",
       "      <td>4</td>\n",
       "      <td>20997</td>\n",
       "      <td>AL</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>3442 rows × 37 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "      loja_id   code                               description launch  \\\n",
       "0       20997  48359                          ZAAD EDP 50ml V2          \n",
       "1       20997  48789      THE BLEND DES ANTIT AER 75g/125ml V3          \n",
       "2       20997  70693                  SOPHIE LOC HID CPO 200ml          \n",
       "3       20997  75921               SOPHIE BATOM ROSA PINK 3,3g          \n",
       "4       20997  53410  REF NSPA SAB LIQ CPO PERF AMEI/NEG 200ml          \n",
       "...       ...    ...                                       ...    ...   \n",
       "3437    20997  82845          MATCH COND LISO PROLONGADO 280ml          \n",
       "3438    20997  49093            MATCH AMP CAP PREENCHEDORA 9ml          \n",
       "3439    20997  50165                MALBEC SHW GEL CAB/CPO 75g          \n",
       "3440    20997  59017          MALBEC LOC DES HID CPO MATE 75ml          \n",
       "3441    20997  56000                         PMPCK MEN CABELOS          \n",
       "\n",
       "     deactivation  thirdtolastcyclesales  secondtolastcyclesales  \\\n",
       "0                                      0                       1   \n",
       "1                                      1                       0   \n",
       "2                                      0                       2   \n",
       "3                                      1                       1   \n",
       "4                                      0                       0   \n",
       "...           ...                    ...                     ...   \n",
       "3437                                   3                       0   \n",
       "3438                                   1                       0   \n",
       "3439                                   0                       0   \n",
       "3440                                   0                       0   \n",
       "3441                                   1                       1   \n",
       "\n",
       "      lastcyclesales  currentcyclesales  nextcycleprojection  ...  \\\n",
       "0                  0                  0                    2  ...   \n",
       "1                  0                  0                    1  ...   \n",
       "2                  0                  0                    3  ...   \n",
       "3                  0                  0                    3  ...   \n",
       "4                  0                  0                    6  ...   \n",
       "...              ...                ...                  ...  ...   \n",
       "3437               0                  0                    2  ...   \n",
       "3438               0                  0                    1  ...   \n",
       "3439               0                  0                    1  ...   \n",
       "3440               0                  0                    1  ...   \n",
       "3441               0                  0                    1  ...   \n",
       "\n",
       "      isproductdeactivated  brandgroupcode  dayswithoutsales  coveragedays  \\\n",
       "0                    False             BOT                54            20   \n",
       "1                    False             BOT                72            25   \n",
       "2                    False             BOT                48             4   \n",
       "3                    False             BOT                53            15   \n",
       "4                    False             BOT               135            31   \n",
       "...                    ...             ...               ...           ...   \n",
       "3437                 False             BOT                66            28   \n",
       "3438                 False             BOT                66            18   \n",
       "3439                 False             BOT               157            17   \n",
       "3440                 False             BOT                89            34   \n",
       "3441                 False             BOT                43            71   \n",
       "\n",
       "      hascoverage       status_venda  valor_estoque_parado estoque futuro  \\\n",
       "0           False    mais de 40 dias                168.09              3   \n",
       "1            True    mais de 60 dias                 12.37              1   \n",
       "2           False    mais de 40 dias                 11.41              1   \n",
       "3           False    mais de 40 dias                 16.58              2   \n",
       "4            True  acima de 100 dias                 85.12              7   \n",
       "...           ...                ...                   ...            ...   \n",
       "3437         True    mais de 60 dias                 42.48              3   \n",
       "3438        False    mais de 60 dias                 20.04              2   \n",
       "3439        False  acima de 100 dias                  9.08              1   \n",
       "3440         True    mais de 80 dias                 21.02              2   \n",
       "3441         True    mais de 40 dias                 94.48              4   \n",
       "\n",
       "        PDV  UF  \n",
       "0     20997  AL  \n",
       "1     20997  AL  \n",
       "2     20997  AL  \n",
       "3     20997  AL  \n",
       "4     20997  AL  \n",
       "...     ...  ..  \n",
       "3437  20997  AL  \n",
       "3438  20997  AL  \n",
       "3439  20997  AL  \n",
       "3440  20997  AL  \n",
       "3441  20997  AL  \n",
       "\n",
       "[3442 rows x 37 columns]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "944f8d93",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 35196 characters]",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as mtick\n",
    "import seaborn as sns\n",
    "\n",
    "# Agrupa corretamente e transforma em DataFrame\n",
    "df_plot = df2.groupby('UF')['valor_estoque_parado'].sum().reset_index()\n",
    "\n",
    "plt.figure(figsize=(6, 4))\n",
    "ax = sns.barplot(data=df_plot, x='UF', y='valor_estoque_parado', errorbar=None)\n",
    "\n",
    "ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('R${x:,.2f}'))\n",
    "\n",
    "# Adiciona os valores no topo de cada barra\n",
    "for p in ax.patches:\n",
    "    valor = p.get_height()\n",
    "    ax.annotate(f'R$ {valor:,.2f}', (p.get_x() + p.get_width() / 2, valor),\n",
    "                ha='center', va='bottom', fontsize=9)\n",
    "\n",
    "plt.title(\"Estoque parado por UF\")\n",
    "plt.ylabel(\"Valor\")\n",
    "plt.xlabel(\"UF\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7134a0d6",
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'credenciais'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mKeyError\u001b[39m                                  Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[13]\u001b[39m\u001b[32m, line 19\u001b[39m\n\u001b[32m     16\u001b[39m config = configparser.ConfigParser()\n\u001b[32m     17\u001b[39m config.read(\u001b[33m\"\u001b[39m\u001b[33mconfig.ini\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m---> \u001b[39m\u001b[32m19\u001b[39m remetente = \u001b[43mconfig\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mcredenciais\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m]\u001b[49m[\u001b[33m'\u001b[39m\u001b[33mremetente\u001b[39m\u001b[33m'\u001b[39m]\n\u001b[32m     20\u001b[39m senha = config[\u001b[33m'\u001b[39m\u001b[33mcredenciais\u001b[39m\u001b[33m'\u001b[39m][\u001b[33m'\u001b[39m\u001b[33msenha\u001b[39m\u001b[33m'\u001b[39m]\n\u001b[32m     21\u001b[39m destinatarios = [email.strip() \u001b[38;5;28;01mfor\u001b[39;00m email \u001b[38;5;129;01min\u001b[39;00m config[\u001b[33m'\u001b[39m\u001b[33memail\u001b[39m\u001b[33m'\u001b[39m][\u001b[33m'\u001b[39m\u001b[33mdestinatarios\u001b[39m\u001b[33m'\u001b[39m].split(\u001b[33m'\u001b[39m\u001b[33m,\u001b[39m\u001b[33m'\u001b[39m)]\n",
      "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\joao.herculano\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\configparser.py:998\u001b[39m, in \u001b[36mRawConfigParser.__getitem__\u001b[39m\u001b[34m(self, key)\u001b[39m\n\u001b[32m    996\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, key):\n\u001b[32m    997\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m key != \u001b[38;5;28mself\u001b[39m.default_section \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m.has_section(key):\n\u001b[32m--> \u001b[39m\u001b[32m998\u001b[39m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key)\n\u001b[32m    999\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._proxies[key]\n",
      "\u001b[31mKeyError\u001b[39m: 'credenciais'"
     ]
    }
   ],
   "source": [
    "# enviar_email_excel.py\n",
    "\n",
    "import pandas as pd\n",
    "import smtplib\n",
    "import ssl\n",
    "from email.message import EmailMessage\n",
    "from email.utils import make_msgid\n",
    "from email.mime.image import MIMEImage\n",
    "from pathlib import Path\n",
    "import configparser\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as mtick\n",
    "import seaborn as sns\n",
    "\n",
    "# 0. Ler configurações do arquivo INI\n",
    "config = configparser.ConfigParser()\n",
    "config.read(\"config.ini\")\n",
    "\n",
    "remetente = config['credenciais']['remetente']\n",
    "senha = config['credenciais']['senha']\n",
    "destinatarios = [email.strip() for email in config['email']['destinatarios'].split(',')]\n",
    "assunto = config['email']['assunto']\n",
    "\n",
    "# 1. Criar dados fictícios e gerar Excel\n",
    "df = pd.DataFrame({\n",
    "    'Nome': ['Ana', 'Bruno', 'Carlos'],\n",
    "    'Idade': [28, 34, 45],\n",
    "    'Email': ['ana@example.com', 'bruno@example.com', 'carlos@example.com'],\n",
    "    'UF': ['SP', 'RJ', 'SP'],\n",
    "    'valor_estoque_parado': [12000, 8000, 15000]\n",
    "})\n",
    "\n",
    "excel_path = Path(\"relatorio.xlsx\")\n",
    "df.to_excel(excel_path, index=False)\n",
    "\n",
    "# 2. Criar e salvar gráfico\n",
    "plot_df = df.groupby('UF')['valor_estoque_parado'].sum().reset_index()\n",
    "plt.figure(figsize=(6, 4))\n",
    "ax = sns.barplot(data=plot_df, x='UF', y='valor_estoque_parado', errorbar=None)\n",
    "ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('R${x:,.2f}'))\n",
    "for p in ax.patches:\n",
    "    valor = p.get_height()\n",
    "    ax.annotate(f'R$ {valor:,.2f}', (p.get_x() + p.get_width() / 2, valor),\n",
    "                ha='center', va='bottom', fontsize=9)\n",
    "plt.title(\"Estoque parado por UF\")\n",
    "plt.ylabel(\"Valor em Reais\")\n",
    "plt.xlabel(\"UF\")\n",
    "plt.tight_layout()\n",
    "plt.savefig(\"grafico.png\")\n",
    "plt.close()\n",
    "\n",
    "# 3. Criar e-mail com imagem embutida\n",
    "grafico_cid = make_msgid()[1:-1]  # remove < >\n",
    "msg = EmailMessage()\n",
    "msg['From'] = remetente\n",
    "msg['To'] = ', '.join(destinatarios)\n",
    "msg['Subject'] = assunto\n",
    "\n",
    "html_email = f\"\"\"\n",
    "<html>\n",
    "  <body>\n",
    "    <p>Prezados,</p>\n",
    "    <p>Segue em anexo o relatório em Excel conforme solicitado.</p>\n",
    "    <p><b>Resumo gráfico:</b></p>\n",
    "    <img src=\"cid:{grafico_cid}\"><br>\n",
    "    <p>Atenciosamente,<br>Equipe de Dados</p>\n",
    "  </body>\n",
    "</html>\n",
    "\"\"\"\n",
    "\n",
    "msg.set_content(\"Seu e-mail precisa de um visualizador HTML.\")\n",
    "msg.add_alternative(html_email, subtype='html')\n",
    "\n",
    "# 4. Anexar gráfico inline\n",
    "with open(\"grafico.png\", 'rb') as img:\n",
    "    msg.get_payload()[1].add_related(img.read(), 'image', 'png', cid=grafico_cid)\n",
    "\n",
    "# 5. Anexar o Excel\n",
    "with open(excel_path, 'rb') as f:\n",
    "    msg.add_attachment(\n",
    "        f.read(),\n",
    "        maintype='application',\n",
    "        subtype='vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n",
    "        filename=excel_path.name\n",
    "    )\n",
    "\n",
    "# 6. Enviar o e-mail via SMTP Outlook com configurações fornecidas\n",
    "with smtplib.SMTP('smtp-mail.outlook.com', 587) as smtp:\n",
    "    smtp.ehlo()\n",
    "    smtp.starttls(context=ssl.create_default_context())\n",
    "    smtp.login(remetente, senha)\n",
    "    smtp.send_message(msg)\n",
    "\n",
    "print(\"E-mail enviado com sucesso.\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27f8eff0",
   "metadata": {},
   "outputs": [],
   "source": [
    "df2['valor_estoque_parado']"
   ]
  }
 ],
 "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
}
