Skip to content

Instantly share code, notes, and snippets.

@brunogasparetto
Last active April 24, 2024 13:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brunogasparetto/a56010eaf4bf43e3d29b523ddca9ca0c to your computer and use it in GitHub Desktop.
Save brunogasparetto/a56010eaf4bf43e3d29b523ddca9ca0c to your computer and use it in GitHub Desktop.
Fluig: Exemplo de Notificações Personalizadas

Notificações Personalizadas

Recentemente precisei disparar algumas notificações aos usuários, mas não queria o simples envio por e-mail, então percebi que o Fluig possuí opções "ocultas" para criar notificações personalizadas.

Vou mostrar como fiz para disparar notificações referentes a vencimento de CNH.

Com a intenção de organização foi criado o módulo Personalizadas às notificações com o seguinte código:

fetch(URL_SERVIDOR + "/api/public/alert/module/create", {
    method: "POST",
    redirect: "follow",
    headers: {
        "Content-Type": "application/json;charset=utf-8",
    },
    body: JSON.stringify({
        moduleKey: "PERSONALIZADAS",
        descriptionKey: "Personalizadas"
    }),
});

Com o endpoint URL_SERVIDOR/api/public/alert/module/findVoList é possível visualizar o ID atribuído ao módulo. Com esse ID foram criadas as seguintes notificações:

  • CNH Vencida: Alerta Gestores de Frota que uma CNH está com validade vencida;
  • CNH Inativada: Alerta Gestores de Frota que uma CNH vencida há 30 dias foi inativada;

Os códigos para criar os eventos, considerando que o ID do módulo criado é 8, ficou assim:

fetch(URL_SERVIDOR + "/api/public/alert/event/createEvent", {
    method: "POST",
    redirect: "follow",
    headers: {
        "Content-Type": "application/json;charset=utf-8",
    },
    body: JSON.stringify({
        eventKey: "FROTA_CNH_VENCIDA",
        required: true,
        descriptionKey: "Frota: CNH Vencida",
        singleDescriptionKey: "A CNH está vencida.",
        groupDescriptionKey: "A CNH está vencida.",
        eventIcon: "/globalalertapi/resources/images/exclamation-sign.png",
        moduleId: 8,
        grouped: false,
        canRemove: false,
        removeAfterExecAction: true,
        onlyAdmin: false,
    }),
});

fetch(URL_SERVIDOR + "/api/public/alert/event/createEvent", {
    method: "POST",
    redirect: "follow",
    headers: {
        "Content-Type": "application/json;charset=utf-8",
    },
    body: JSON.stringify({
        eventKey: "FROTA_CNH_INATIVADA",
        required: true,
        descriptionKey: "Frota: CNH Inativada",
        singleDescriptionKey: "A CNH está vencida há 30 dias e foi inativada.",
        groupDescriptionKey: "A CNH está vencida há 30 dias e foi inativada.",
        eventIcon: "/globalalertapi/resources/images/exclamation-sign.png",
        moduleId: 8,
        grouped: false,
        canRemove: false,
        removeAfterExecAction: true,
        onlyAdmin: false,
    }),
});

Disparando as Notificações

Para disparar uma notificação personalizada você deve usar o seguinte código em algum script de backend do Fluig (dataset, evento de formulário ou processo):

var alertService = fluigAPI.getAlertService();

var objeto = new com.totvs.technology.foundation.alert.GenericAlertObject(
    -1,
    "FROTA_CNH_VENCIDA",
    "Nome do Motorista foi notificado por e-mail que está com a CNH Vencida!",
    null,
    null,
    null
);

alertService.sendNotification(
    "FROTA_CNH_VENCIDA",
    null,
    "login.usuario",
    objeto,
    null,
    null,
    null
);

Exemplo Prático do disparo diário

Para fazer um processo diário de disparo de notificações eu criei um dataset jornalizado, executado 1x por dia, pois é a quantidade de vezes necessárias para essa situação.

Meu formulário de CNH, vinculado ao dataset ds_frota_cnh, possuí um campo que informa a data de vencimento da CNH, um campo para marcar se o usuário já foi notificado sobre o vencimento e o campo de "status".

  • notificadoVencimento
  • dt_validade
  • situacao

Os campos notificadoVencimento e situacao me permitem não enviar notificações duplicadas.

Segue o exemplo do arquivo de dataset jornalizado:

/**
 * Dataset sincronizado para gestão das CNHs (Motoristas)
 *
 * Dataset envia notificações aos motoristas quando sua CNH
 * é considerada vencida. Notificando também os gestores da frota.
 *
 * Dataset inativa a CNH vencida há 30 dias, notificando o motorista
 * e notificando os gestores da frota.
 */


/**
 * Estrutura do Dataset
 */
function defineStructure() {
    addColumn("documentoId", DatasetFieldType.STRING);
    addColumn("nome", DatasetFieldType.STRING);
    addColumn("acao", DatasetFieldType.STRING);
    addColumn("data_execucao", DatasetFieldType.STRING);

    addIndex(["documentoId", "acao", "data_execucao"]);
}

/**
 * Sincroniza as informações do Dataset
 *
 * @param {number} lastSyncDate Timestamp em milissegundos
 * @returns {Dataset}
 */
function onSync(lastSyncDate) {
    var dataset = DatasetBuilder.newDataset();

    var motoristas = DatasetFactory.getDataset(
        "ds_frota_cnh",
        [
            "metadata#id",
            "notificadoVencimento",
            "nome",
            "email",
            "dt_validade"
        ],
        [
            DatasetFactory.createConstraint("userSecurityId", "admin", "admin", ConstraintType.MUST),
            DatasetFactory.createConstraint("metadata#active", true, true, ConstraintType.MUST),
            DatasetFactory.createConstraint("situacao", "Ativa", "Ativa", ConstraintType.MUST)
        ],
        null
    );

    if (!motoristas.rowsCount) {
        return dataset;
    }

    // Data de Execução para histórico do Dataset
    var todayDateFormatted = (new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new java.util.Date());

    var dateFormat = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm");
    var today = new java.util.Date();

    var calendar = java.util.Calendar.getInstance();
    calendar.setTime(today);
    calendar.add(java.util.Calendar.MONTH, -1);

    var lastMonth = calendar.getTime();

    var gestores = getFrotaUsers();

    for (var i = 0; i < motoristas.rowsCount; ++i) {
        var dataVencimento = dateFormat.parse(motoristas.getValue(i, "dt_validade") + " 00:00");

        // Inativa CNH
        if (dataVencimento.before(lastMonth)) {
            try {
                enviaEmailCnhInativa(motoristas.getValue(i, "nome"), motoristas.getValue(i, "email"));
                notificaGestoresCnhInativa(gestores, motoristas.getValue(i, "nome"));
                marcaMotoristaComoInativado(motoristas.getValue(i, "metadata#id"));

                dataset.addRow([
                    motoristas.getValue(i, "metadata#id"),
                    motoristas.getValue(i, "nome"),
                    "INATIVAÇÃO",
                    todayDateFormatted
                ]);
            } catch (err) {
                log.error(err);
            }
        }

        if (motoristas.getValue(i, "notificadoVencimento") == "1") {
            continue;
        }

        // CNH vencida
        if (dataVencimento.before(today)) {
            try {
                enviaEmailCnhVencida(motoristas.getValue(i, "nome"), motoristas.getValue(i, "email"));
                marcaMotoristaComoNotificado(motoristas.getValue(i, "metadata#id"));
                notificaGestoresCnhVencida(gestores, motoristas.getValue(i, "nome"));

                dataset.addRow([
                    motoristas.getValue(i, "metadata#id"),
                    motoristas.getValue(i, "nome"),
                    "VENCIMENTO",
                    todayDateFormatted
                ]);
            } catch (err) {
                log.error(err);
            }
        }
    }

    return dataset;
}

/**
 * Usuários ativos que pertencem ao grupo de gestores de frota
 *
 * @returns {java.util.List<string>}
 */
function getFrotaUsers() {
    var gestores = new java.util.ArrayList();

    var gestoresDs = DatasetFactory.getDataset(
        "ds_usuarios_ativos",
        ["login"],
        [
            DatasetFactory.createConstraint("groupId", "GestoresFrota", "GestoresFrota", ConstraintType.MUST)
        ],
        ["login"]
    );

    for (var i = 0; i < gestoresDs.rowsCount; ++i) {
        gestores.add(gestoresDs.getValue(i, "login"));
    }

    return gestores;
}

/**
 * Envia e-mail para o motorista informando do vencimento da CNH
 *
 * @param {string} nome
 * @param {string} email
 */
function enviaEmailCnhVencida(nome, email) {
    var destinatarios = new java.util.ArrayList();
    destinatarios.add(email);

    var parametros = new java.util.HashMap();
    parametros.put("subject", "A sua CNH está Vencida em nosso sistema");
    parametros.put("SERVER_URL", fluigAPI.getPageService().getServerURL());
    parametros.put("TENANT_ID", getValue("WKCompany"));
    parametros.put("MOTORISTA", nome);

    notifier.notify("admin", "Frota_CNH_Vencida", parametros, destinatarios, "text/html");
}

/**
 * Modifica o registro para informar que motorista recebeu notificação
 *
 * @param {number} documentid
 */
function marcaMotoristaComoNotificado(documentid) {
    var cardService = fluigAPI.getCardAPIService();
    var cardFieldVOs = new java.util.ArrayList();

    var notificadoVencimento = new com.fluig.sdk.api.cardindex.CardFieldVO();
    notificadoVencimento.setFieldId("notificadoVencimento");
    notificadoVencimento.setValue("1");

    cardFieldVOs.add(notificadoVencimento);

    cardService.edit(documentid, cardFieldVOs);
}

/**
 * Envia notificação de CNH vencida aos gestores da Frota
 *
 * @param {java.util.List<string>} gestores
 * @param {string} nomeMotorista
 */
function notificaGestoresCnhVencida(gestores, nomeMotorista) {
    if (gestores.isEmpty()) {
        return;
    }

    var alertService = fluigAPI.getAlertService();

    for (var i = 0; i < gestores.size(); ++i) {
        var objeto = new com.totvs.technology.foundation.alert.GenericAlertObject(
            -1,
            "FROTA_CNH_VENCIDA",
            nomeMotorista + " foi notificado por e-mail que está com a CNH Vencida!",
            null,
            null,
            null
        );

        alertService.sendNotification(
            "FROTA_CNH_VENCIDA",
            null,
            gestores.get(i),
            objeto,
            null,
            null,
            null
        );
    }
}


/**
 * Envia e-mail para o motorista informando que a CNH está inativa
 *
 * @param {string} nome
 * @param {string} email
 */
function enviaEmailCnhInativa(nome, email) {
    var destinatarios = new java.util.ArrayList();
    destinatarios.add(email);

    var parametros = new java.util.HashMap();
    parametros.put("subject", "A sua CNH está Inativa em nosso sistema");
    parametros.put("SERVER_URL", fluigAPI.getPageService().getServerURL());
    parametros.put("TENANT_ID", getValue("WKCompany"));
    parametros.put("MOTORISTA", nome);

    notifier.notify("admin", "Frota_CNH_Inativa", parametros, destinatarios, "text/html");
}

/**
 * Modifica o registro para Inativar o motorista
 *
 * @param {number} documentid
 */
function marcaMotoristaComoInativado(documentid) {
    var cardService = fluigAPI.getCardAPIService();
    var cardFieldVOs = new java.util.ArrayList();

    var situacao = new com.fluig.sdk.api.cardindex.CardFieldVO();
    situacao.setFieldId("situacao");
    situacao.setValue("Inativa");

    cardFieldVOs.add(situacao);

    cardService.edit(documentid, cardFieldVOs);
}

/**
 * Envia notificação de CNH Inativa aos gestores da Frota
 *
 * @param {java.util.List<string>} gestores
 * @param {string} nomeMotorista
 */
function notificaGestoresCnhInativa(gestores, nomeMotorista) {
    if (gestores.isEmpty()) {
        return;
    }

    var alertService = fluigAPI.getAlertService();

    for (var i = 0; i < gestores.size(); ++i) {
        var objeto = new com.totvs.technology.foundation.alert.GenericAlertObject(
            -1,
            "FROTA_CNH_INATIVADA",
            nomeMotorista + " foi notificado por e-mail que está com a CNH Inativada!",
            null,
            null,
            null
        );

        alertService.sendNotification(
            "FROTA_CNH_INATIVADA",
            null,
            gestores.get(i),
            objeto,
            null,
            null,
            null
        );
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment