213 lines
6.5 KiB
Python
213 lines
6.5 KiB
Python
# enviar_email_excel.py
|
|
|
|
import smtplib
|
|
import ssl
|
|
import pyodbc
|
|
import configparser
|
|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.dates as mdates
|
|
import matplotlib.ticker as mtick
|
|
import seaborn as sns
|
|
from email.message import EmailMessage
|
|
from email.utils import make_msgid
|
|
from email.mime.image import MIMEImage
|
|
from pathlib import Path
|
|
from datetime import datetime, time
|
|
|
|
|
|
config = configparser.ConfigParser()
|
|
config.read(r"credenciais.ini")
|
|
|
|
excel_path = Path("relatorio.xlsx")
|
|
print(config['banco']['host'],config['banco']['user'],config['banco']['password'])
|
|
|
|
# Conexão com o banco
|
|
conn = pyodbc.connect(
|
|
f"DRIVER={{SQL Server}};"
|
|
f"SERVER={config['banco']['host']},1433;"
|
|
f"DATABASE=GINSENG;"
|
|
f"UID={config['banco']['user']};"
|
|
f"PWD={config['banco']['password']}")
|
|
|
|
# 1. Criar dados fictícios e gerar Excel
|
|
query = '''
|
|
WITH CTE_Estoque AS (
|
|
SELECT
|
|
em.ORIGEM,
|
|
em.PDV,
|
|
CONCAT(em.PDV, em.ORIGEM) AS PDV_Origem, -- Coluna unificada
|
|
CASE
|
|
WHEN em.SKU_PARA IS NULL THEN em.SKU
|
|
ELSE em.SKU_PARA
|
|
END AS SKU_FINAL,
|
|
em.DESCRICAO,
|
|
em.CATEGORIA,
|
|
em.CLASSE,
|
|
CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT) AS [ESTOQUE ATUAL],
|
|
CAST(REPLACE(em.[ESTOQUE EM TRANSITO], ',', '.') AS FLOAT) AS [ESTOQUE EM TRANSITO],
|
|
CAST(REPLACE(em.[PEDIDO PENDENTE], ',', '.') AS FLOAT) AS [PEDIDO PENDENTE],
|
|
CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT) AS [DDV PREVISTO],
|
|
ROUND(
|
|
CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT)
|
|
/ NULLIF(CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT), 0), 0
|
|
) AS [Cobertura Atual],
|
|
ROUND(
|
|
(CAST(REPLACE(em.[ESTOQUE ATUAL], ',', '.') AS FLOAT)
|
|
+ CAST(REPLACE(em.[ESTOQUE EM TRANSITO], ',', '.') AS FLOAT)
|
|
+ CAST(REPLACE(em.[PEDIDO PENDENTE], ',', '.') AS FLOAT))
|
|
/ NULLIF(CAST(REPLACE(em.[DDV PREVISTO], ',', '.') AS FLOAT), 0), 0
|
|
) AS [Cobertura Projetada],
|
|
d.preco_Compra,
|
|
d.Dias_sem_Vendas,
|
|
pr.ATUAL_PROMO ,
|
|
pr.PROX_PROMO
|
|
FROM estoque_mar em
|
|
LEFT JOIN (
|
|
SELECT
|
|
d.loja_id AS PDV,
|
|
d.code AS SKU,
|
|
d.description AS Descricao,
|
|
d.pricesellin AS preco_Compra,
|
|
d.dayswithoutsales as Dias_sem_Vendas
|
|
FROM draft d) d ON em.PDV = d.PDV
|
|
AND (CASE WHEN em.SKU_PARA IS NULL THEN em.SKU ELSE em.SKU_PARA END) = CAST( d.SKU AS INT)
|
|
LEFT JOIN (
|
|
SELECT
|
|
p.loja_id AS PDV,
|
|
p.code AS SKU,
|
|
CASE
|
|
WHEN STRING_AGG(p.currentCycle_description, ', ') IS NULL OR LTRIM(RTRIM( STRING_AGG(p.currentCycle_description, ', '))) = ''
|
|
THEN 'Regular'
|
|
ELSE 'Promocao'
|
|
END AS ATUAL_PROMO,
|
|
CASE
|
|
WHEN STRING_AGG(p.nextCycle_description, ', ') IS NULL OR LTRIM(RTRIM(STRING_AGG(p.nextCycle_description, ', '))) = ''
|
|
THEN 'Regular'
|
|
ELSE 'Promocao'
|
|
END AS PROX_PROMO
|
|
FROM promo p
|
|
WHERE P.created_at >= CAST(GETDATE() AS DATE)
|
|
AND P.created_at < DATEADD(DAY, 1, CAST(GETDATE() AS DATE))
|
|
GROUP BY
|
|
p.loja_id,
|
|
p.code
|
|
) pr ON em.PDV = pr.PDV
|
|
AND (CASE WHEN em.SKU_PARA IS NULL THEN em.SKU ELSE em.SKU_PARA END) = CAST(pr.SKU AS INT)
|
|
WHERE em.CATEGORIA NOT IN ('SUPORTE À VENDA', 'EMBALAGENS')
|
|
)
|
|
SELECT
|
|
bpm.DESCRICAO AS DESCRICAO_PDV,
|
|
bpm.UF,
|
|
bpm.ANALISTA,
|
|
cte.*
|
|
FROM CTE_Estoque cte
|
|
LEFT JOIN base_pdvs_marca bpm
|
|
ON cte.PDV_Origem = bpm.PDV_MARCA -- agora join pelo unificado
|
|
WHERE [Cobertura Atual] > 60;
|
|
'''
|
|
df = pd.read_sql(query, conn)
|
|
|
|
df.to_excel(excel_path,index=False)
|
|
conn.close()
|
|
print(df.columns)
|
|
remetente = config['credenciais']['remetente']
|
|
senha = config['credenciais']['senha']
|
|
destinatarios = [email.strip() for email in config['email_cobertura']['destinatarios'].split(',')]
|
|
assunto = config['email_cobertura']['assunto']
|
|
|
|
print(remetente,senha,destinatarios,assunto)
|
|
|
|
|
|
# Obtém a hora atual
|
|
agora = datetime.now().time()
|
|
hoje = datetime.today().strftime("%d/%m/%Y")
|
|
# Define os intervalos de tempo
|
|
manhã_inicio = time(5, 0)
|
|
manhã_fim = time(12, 0)
|
|
tarde_inicio = time(12, 1)
|
|
tarde_fim = time(18, 0)
|
|
# noite é dividida em dois intervalos por causa da virada do dia
|
|
noite_inicio = time(18, 1)
|
|
noite_fim = time(4, 59)
|
|
# Verifica em qual intervalo a hora atual está
|
|
if manhã_inicio <= agora <= manhã_fim:
|
|
boa = "Bom dia!"
|
|
elif tarde_inicio <= agora <= tarde_fim:
|
|
boa = "Boa tarde!"
|
|
else:
|
|
boa = "Boa noite!"
|
|
|
|
|
|
# 3. Criar e-mail com imagem embutida
|
|
|
|
msg = EmailMessage()
|
|
msg['From'] = remetente
|
|
msg['To'] = ', '.join(destinatarios)
|
|
msg['Subject'] = assunto
|
|
|
|
# 4. Conteúdo do e-mail
|
|
html_email = f"""
|
|
<html>
|
|
<body>
|
|
<p>{boa}</p>
|
|
|
|
<p>
|
|
Segue o relatório semanal de Cobertura referente às regiões de
|
|
Alagoas (AL), Bahia (BA), Sergipe (SE), Conquista (VDC), Bahia3(BA3).
|
|
</p>
|
|
|
|
<p>
|
|
Este relatório contempla exclusivamente os itens com cobertura superior à 60 dias.
|
|
</p>
|
|
|
|
<p>
|
|
O objetivo é trazer visibilidade para os produtos parados e reforçar a importância
|
|
de ações para estimular a sua saída, contribuindo assim para a redução da cobertura
|
|
de estoque e otimização dos recursos.
|
|
</p>
|
|
|
|
<p>
|
|
Contamos com o apoio de todos para análise e tratativa dos itens listados.
|
|
Sugestões de ações como campanhas, transferências ou ajustes de sortimento são
|
|
bem-vindas para acelerar a movimentação dos produtos.
|
|
</p>
|
|
|
|
<p>
|
|
Importante destacar que este relatório ainda não contempla as transferências realizadas internamente, uma vez que estamos trabalhando para viabilizar a inclusão dessas informações no banco de dados.
|
|
</p>
|
|
|
|
<p>
|
|
Para mais informações, favor consultar a planilha em anexo.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
|
|
msg.set_content("Seu e-mail precisa de um visualizador HTML.")
|
|
msg.add_alternative(html_email, subtype='html')
|
|
|
|
|
|
|
|
# 5. Anexar o arquivo Excel
|
|
with open(excel_path, 'rb') as f:
|
|
msg.add_attachment(
|
|
f.read(),
|
|
maintype='application',
|
|
subtype='vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
filename=excel_path.name
|
|
)
|
|
|
|
# 6. Enviar o e-mail via SMTP Outlook com configurações fornecidas
|
|
with smtplib.SMTP('smtp-mail.outlook.com', 587) as smtp:
|
|
smtp.ehlo()
|
|
smtp.starttls(context=ssl.create_default_context())
|
|
smtp.login(remetente, senha)
|
|
smtp.send_message(msg)
|
|
|
|
|
|
|
|
print("E-mail enviado com sucesso.")
|