Modal Para Envio de Relatórios Por E-mail
Introdução
Habilita um modal que permite o envio de relatórios por e-mail na tela de CRUD. Quando configurado, um botão é exibido tanto na listagem dos registros quanto na tela de edição. Ao interagir com o botão o modal é aberto, onde é possível selecionar e-mails destinatários em uma lista, adicionar novos e-mails como destinatários, e selecionar o relatório a ser enviado.
Configuração
A configuração desta feature é realizada através da tabela nfs_entrypoint, proporcionando alta flexibilidade e personalização. Essa estrutura baseada em Entrypoints permite que a configuração de cada cliente ou tela seja dinâmica, garantindo total liberdade para os desenvolvedores construírem lógicas complexas e obterem as informações exatas para a renderização do modal e envio do e-mail.
A feature é composta por dois Entrypoints pertencentes ao mesmo domínio (FILE_OR_DOMAIN = 'REPORTS_EMAIL_LIST'), sendo um obrigatório para a construção do modal e um opcional para a personalização da mensagem. Ambos exigem o preenchimento da coluna TABELA com o nome da tabela do CRUD onde o botão será exibido.
1. Configuração do Modal (Entrypoint Obrigatório)
Este Entrypoint dita as regras de exibição do modal, a origem dos e-mails e quais relatórios estarão disponíveis.
- FILE_OR_DOMAIN: REPORTS_EMAIL_LIST
- ACTION: config_modal
- CODETYPE: JSON
- TABELA: Nome da tabela do CRUD (ex: APONTAMENTO_ATIVIDADE_ESPECIFICA)
O campo CODE deve conter um JSON com a seguinte estrutura:
{
"filters": {
"STATUS_APONTAMENTO": 2
},
"email_list": {
"table": "USUARIO_EMAIL",
"columns": [
"EMAIL"
],
"hasFilterByCrud": false
},
"reports": [
{
"display_name": "Periculosidade [TXT]",
"action":"periculosidade_link",
"export_format": "txt"
},
{
"display_name": "Periculosidade [PDF]",
"action":"periculosidade",
"export_format": "pdf"
}
]
}
-
filters: Parâmetro opcional que filtra para quais registros o botão de envio de relatório poderá ser exibido. Define-se a coluna e o valor esperado. No exemplo abaixo, o botão somente será exibido para os registros cujo valor de STATUS_APONTAMENTO seja igual a 2.
-
email_list: Define a origem dos e-mails para receberem o relatório.
- table: Nome da tabela onde que contem os e-mails de destinatários.
- columns: Qual/quais colunas da tabela contêm os e-mails
- hasFilterByCrud: A flag que indica se os dados da tabela de e-mails devem ser filtrados pelo registro da tabela CRUD atual.
-
reports: Lista de relatórios associados à tela que se deseja enviar.
- display_name: Nome que será exibido no modal.
- action: Identificador (name) deste relatório na tabela nfs_reports.
- export_format: Define o formato do arquivo em anexo ('txt', 'pdf', 'pdfNative' ou 'excel'). É recomendado utilizar o formato padrão configurado para o relatório na tabela nfs_reports evitando bugs de conversão.
Exemplo de SQL para inserção (JSON):
INSERT INTO nfs_homol_atlascopco_smartos.nfs_entry_point
(SEQ_DB, FILE_OR_DOMAIN, `ACTION`, XMOVA_INSTALLCODE, XMOVA_INSTALLCODE_VERSION, EMPRESA, FILIAL, `LOCAL`, TABELA, ENTRY_NUM, CODE, VERSION, BUILD, ATIVO, CODETYPE, FIELD, DESCRIPTION, INS_DH, UPD_DH, NFS_USER, DB_USER)
VALUES(791, 'REPORTS_EMAIL_LIST', 'config_modal', NULL, NULL, 4, 9999, 9999, 'APONTAMENTO_ATIVIDADE_ESPECIFICA', NULL, '{
"filters": {
"STATUS_APONTAMENTO": 2
},
"email_list": {
"table": "USUARIO_EMAIL",
"columns": [
"EMAIL"
],
"hasFilterByCrud": false
},
"reports": [
{
"display_name": "Periculosidade [TXT]",
"action":"periculosidade_link",
"export_format": "txt"
},
{
"display_name": "Periculosidade [PDF]",
"action":"periculosidade",
"export_format": "pdf"
}
]
}', 1, 9, 1, 'JSON', NULL, NULL, '2025-02-19 12:35:11', '2026-03-25 16:00:10', 'Simova Admin', 'nfs.lucas.costa@179.130.224.154');
2. Personalização do Título e Corpo do E-mail (Entrypoint Opcional)
Este Entrypoint permite o uso de código PHP para criar lógicas dinâmicas que personalizam o e-mail que chegará na caixa de entrada do destinatário. Caso este Entrypoint não seja configurado, o CORE assumirá valores padrões para o título e o corpo do e-mail.
- FILE_OR_DOMAIN: REPORTS_EMAIL_LIST
- ACTION: config_email
- CODETYPE: PHP
- TABELA: Nome da tabela do CRUD (ex: APONTAMENTO_ATIVIDADE_ESPECIFICA)
Segue exemplo, configurado para o clinete 'Atlascopco', onde o título e o corpo do E-mail foram personalizados para indicar o período de dados considerado na geração do relatório:
// $seq_db => Variável default contendo SeqDb do registro onde o modal foi ativado.
$aptSeqDb = $seq_db;
// Busca a data do apontamento específico informado
$apontamentoInfo = Dao::table('apontamento_atividade_especifica', 'aae')
->select(['aae.INI_DH as data_inicio', 'aae.FIM_DH as data_fim'])
->whereIn('aae.SEQ_DB', $aptSeqDb)
->first();
if (empty($apontamentoInfo)) {
$emailBody = 'Apontamentos não encontrados';
}
$dataReferenciaStr = !empty($apontamentoInfo['data_fim']) ? $apontamentoInfo['data_fim'] : $apontamentoInfo['data_inicio'];
if (empty($dataReferenciaStr)) {
$emailTitle = "Relatório de Periculosidade";
}
// Converte a data do apontamento para DateTime
$dataReferencia = \DateTime::createFromFormat('Y-m-d H:i:s', $dataReferenciaStr);
// Extrai mês e ano do apontamento
$anoReferencia = (int)$dataReferencia->format('Y');
$mesReferencia = (int)$dataReferencia->format('m');
// Calcula período (do dia 11 do mês anterior ao dia 10 do mês atual)
$mesAnterior = $mesReferencia == 1 ? 12 : $mesReferencia - 1;
$anoAnterior = $mesReferencia == 1 ? $anoReferencia - 1 : $anoReferencia;
// Datas no formato Y-m-d (sem horas)
$inicioIniDb = sprintf('%04d-%02d-11', $anoAnterior, $mesAnterior);
$fimFimDb = sprintf('%04d-%02d-10', $anoReferencia, $mesReferencia);
// Converte para DateTime usando apenas a data (sem horas)
$dataInicio = \DateTime::createFromFormat('Y-m-d', $inicioIniDb);
$dataFim = \DateTime::createFromFormat('Y-m-d', $fimFimDb);
// Formata para exibição no padrão brasileiro (dia/mês/ano)
$dataInicioBr = $dataInicio->format('d/m/Y');
$dataFimBr = $dataFim->format('d/m/Y');
$emailTitle = "Relatório de Periculosidade de " . $dataInicioBr . " à " . $dataFimBr;
$emailBody = "Relatório de Periculosidade para os períodos " . $dataInicioBr . " à " . $dataFimBr;
$this->outputValues = [
'emailTitle' => $emailTitle,
'emailBody' => $emailBody
];
Observações importantes para o desenvolvimento do script PHP:
- Variável Injetada ($seq_db): O CORE disponibiliza nativamente a variável $seq_db dentro do escopo deste Entrypoint. Ela contém o ID do registro exato onde o modal foi ativado, permitindo buscar dados de contexto no banco de dados.
- Saída Obrigatória ($this->outputValues): O script deve obrigatoriamente popular o array $this->outputValues com as chaves emailTitle e emailBody para que o sistema capture os textos personalizados.
Exemplo de SQL para inserção (PHP):
INSERT INTO nfs_homol_atlascopco_smartos.nfs_entry_point
(SEQ_DB, FILE_OR_DOMAIN, `ACTION`, XMOVA_INSTALLCODE, XMOVA_INSTALLCODE_VERSION, EMPRESA, FILIAL, `LOCAL`, TABELA, ENTRY_NUM, CODE, VERSION, BUILD, ATIVO, CODETYPE, FIELD, DESCRIPTION, INS_DH, UPD_DH, NFS_USER, DB_USER)
VALUES(793, 'REPORTS_EMAIL_LIST', 'config_email', NULL, NULL, 4, 9999, 9999, 'APONTAMENTO_ATIVIDADE_ESPECIFICA', NULL, '// $seq_db => Variável default contendo SeqDb do registro onde o modal foi ativado.
$aptSeqDb = $seq_db;
// Busca a data do apontamento específico informado
$apontamentoInfo = Dao::table(''apontamento_atividade_especifica'', ''aae'')
->select([''aae.INI_DH as data_inicio'', ''aae.FIM_DH as data_fim''])
->whereIn(''aae.SEQ_DB'', $aptSeqDb)
->first();
if (empty($apontamentoInfo)) {
$emailBody = ''Apontamentos não encontrados'';
}
$dataReferenciaStr = !empty($apontamentoInfo[''data_fim'']) ? $apontamentoInfo[''data_fim''] : $apontamentoInfo[''data_inicio''];
if (empty($dataReferenciaStr)) {
$emailTitle = "Relatório de Periculosidade";
}
// Converte a data do apontamento para DateTime
$dataReferencia = \\DateTime::createFromFormat(''Y-m-d H:i:s'', $dataReferenciaStr);
// Extrai mês e ano do apontamento
$anoReferencia = (int)$dataReferencia->format(''Y'');
$mesReferencia = (int)$dataReferencia->format(''m'');
// Calcula período (do dia 11 do mês anterior ao dia 10 do mês atual)
$mesAnterior = $mesReferencia == 1 ? 12 : $mesReferencia - 1;
$anoAnterior = $mesReferencia == 1 ? $anoReferencia - 1 : $anoReferencia;
// Datas no formato Y-m-d (sem horas)
$inicioIniDb = sprintf(''%04d-%02d-11'', $anoAnterior, $mesAnterior);
$fimFimDb = sprintf(''%04d-%02d-10'', $anoReferencia, $mesReferencia);
// Converte para DateTime usando apenas a data (sem horas)
$dataInicio = \\DateTime::createFromFormat(''Y-m-d'', $inicioIniDb);
$dataFim = \\DateTime::createFromFormat(''Y-m-d'', $fimFimDb);
// Formata para exibição no padrão brasileiro (dia/mês/ano)
$dataInicioBr = $dataInicio->format(''d/m/Y'');
$dataFimBr = $dataFim->format(''d/m/Y'');
$emailTitle = "Relatório de Periculosidade de " . $dataInicioBr . " à " . $dataFimBr;
$emailBody = "Relatório de Periculosidade para os períodos " . $dataInicioBr . " à " . $dataFimBr;
$this->outputValues = [
''emailTitle'' => $emailTitle,
''emailBody'' => $emailBody
];', 1, 30, 1, 'PHP', NULL, NULL, '2025-02-19 12:35:11', '2026-03-30 09:36:24', 'Simova Admin', 'guilherme.carvalho@187.106.168.133');
Restrição
Esta opção de envio de relatório por e-mail só é visível para usuários com permissão de edição em telas de CRUD.