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.
orquestrador/app/services/integrations/templates.py

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