You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.6 KiB
Python
129 lines
3.6 KiB
Python
import json
|
|
from collections.abc import Mapping
|
|
from typing import Any
|
|
|
|
from app.services.integrations.events import (
|
|
ORDER_CANCELLED_EVENT,
|
|
ORDER_CREATED_EVENT,
|
|
RENTAL_OPENED_EVENT,
|
|
RENTAL_PAYMENT_REGISTERED_EVENT,
|
|
RENTAL_RETURN_REGISTERED_EVENT,
|
|
REVIEW_SCHEDULED_EVENT,
|
|
)
|
|
|
|
|
|
DEFAULT_EMAIL_TEMPLATES = {
|
|
ORDER_CREATED_EVENT: {
|
|
"subject": "[Orquestrador] Pedido criado {numero_pedido}",
|
|
"body": """Um pedido de veiculo foi criado com sucesso.
|
|
|
|
Numero: {numero_pedido}
|
|
Veiculo: {modelo_veiculo}
|
|
Valor: R$ {valor_veiculo}
|
|
CPF: {cpf}
|
|
Status: {status}
|
|
Status do veiculo: {status_veiculo}""",
|
|
},
|
|
ORDER_CANCELLED_EVENT: {
|
|
"subject": "[Orquestrador] Pedido cancelado {numero_pedido}",
|
|
"body": """Um pedido foi cancelado.
|
|
|
|
Numero: {numero_pedido}
|
|
Status: {status}
|
|
Motivo: {motivo}
|
|
Data cancelamento: {data_cancelamento}""",
|
|
},
|
|
REVIEW_SCHEDULED_EVENT: {
|
|
"subject": "[Orquestrador] Revisao agendada {protocolo}",
|
|
"body": """Uma revisao foi agendada.
|
|
|
|
Protocolo: {protocolo}
|
|
Placa: {placa}
|
|
Data e hora: {data_hora}
|
|
Modelo: {modelo}
|
|
Ano: {ano}
|
|
KM: {km}
|
|
Valor estimado: R$ {valor_revisao}""",
|
|
},
|
|
RENTAL_OPENED_EVENT: {
|
|
"subject": "[Orquestrador] Locacao aberta {contrato_numero}",
|
|
"body": """Uma locacao foi aberta.
|
|
|
|
Contrato: {contrato_numero}
|
|
Veiculo: {modelo_veiculo}
|
|
Placa: {placa}
|
|
Inicio: {data_inicio}
|
|
Devolucao prevista: {data_fim_prevista}
|
|
Diaria: R$ {valor_diaria}
|
|
Valor previsto: R$ {valor_previsto}
|
|
Status: {status}""",
|
|
},
|
|
RENTAL_PAYMENT_REGISTERED_EVENT: {
|
|
"subject": "[Orquestrador] Pagamento de aluguel {protocolo}",
|
|
"body": """Um pagamento de aluguel foi registrado.
|
|
|
|
Protocolo: {protocolo}
|
|
Contrato: {contrato_numero}
|
|
Placa: {placa}
|
|
Valor: R$ {valor}
|
|
Data pagamento: {data_pagamento}
|
|
Favorecido: {favorecido}""",
|
|
},
|
|
RENTAL_RETURN_REGISTERED_EVENT: {
|
|
"subject": "[Orquestrador] Devolucao registrada {contrato_numero}",
|
|
"body": """Uma devolucao de locacao foi registrada.
|
|
|
|
Contrato: {contrato_numero}
|
|
Veiculo: {modelo_veiculo}
|
|
Placa: {placa}
|
|
Data devolucao: {data_devolucao}
|
|
Valor previsto: R$ {valor_previsto}
|
|
Valor final: R$ {valor_final}
|
|
Status: {status}""",
|
|
},
|
|
}
|
|
|
|
|
|
class _SafeTemplateData(dict):
|
|
def __missing__(self, key: str) -> str:
|
|
return ""
|
|
|
|
|
|
def _normalize_template_value(value: Any) -> str:
|
|
if value is None:
|
|
return ""
|
|
if isinstance(value, bool):
|
|
return "sim" if value else "nao"
|
|
if isinstance(value, (list, tuple, dict)):
|
|
return json.dumps(value, ensure_ascii=True, default=str, sort_keys=True)
|
|
return str(value)
|
|
|
|
|
|
def build_template_context(payload: Mapping[str, Any] | None) -> dict[str, str]:
|
|
context = _SafeTemplateData()
|
|
for key, value in dict(payload or {}).items():
|
|
context[str(key)] = _normalize_template_value(value)
|
|
return context
|
|
|
|
|
|
def render_email_content(
|
|
*,
|
|
event_type: str,
|
|
payload: Mapping[str, Any] | None,
|
|
subject_template: str | None = None,
|
|
body_template: str | None = None,
|
|
) -> tuple[str, str]:
|
|
defaults = DEFAULT_EMAIL_TEMPLATES.get(
|
|
event_type,
|
|
{
|
|
"subject": "[Orquestrador] Evento {event_type}",
|
|
"body": "Payload do evento {event_type}:\n{payload_json}",
|
|
},
|
|
)
|
|
context = build_template_context(payload)
|
|
context.setdefault("event_type", event_type)
|
|
context.setdefault("payload_json", _normalize_template_value(payload))
|
|
subject = str(subject_template or defaults["subject"]).format_map(context).strip()
|
|
body = str(body_template or defaults["body"]).format_map(context).strip()
|
|
return subject, body
|