├── .gitignore ├── dsEnviarEmailComAnexos ├── processo-exemplo01 │ ├── forms │ │ └── enviarEmailComAnexos │ │ │ ├── events │ │ │ ├── atividades.js │ │ │ ├── enableFields.js │ │ │ ├── displayFields.js │ │ │ └── validateForm.js │ │ │ ├── custom.js │ │ │ └── enviarEmailComAnexos.html │ ├── imagem_formulario.png │ ├── workflow │ │ ├── .resources │ │ │ ├── enviarEmailComAnexos.png │ │ │ ├── enviarEmailComAnexos.processimage.svg │ │ │ └── enviarEmailComAnexos.ecm30.xml │ │ └── scripts │ │ │ └── enviarEmailComAnexos.servicetask4.js │ ├── .settings │ │ └── .jsdtscope │ ├── .project │ └── README.md ├── exemplo_01.png ├── processo-exemplo02 │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ └── .jsdtscope │ ├── imagem_formulario.png │ ├── workflow │ │ ├── scripts │ │ │ ├── enviarEmailComAnexos.atividades.js │ │ │ ├── enviarEmailComAnexos.funcoes.js │ │ │ ├── enviarEmailComAnexos.beforeStateEntry.js │ │ │ └── enviarEmailComAnexos.servicetask4.js │ │ └── .resources │ │ │ ├── enviarEmailComAnexos.png │ │ │ ├── enviarEmailComAnexos.processimage.svg │ │ │ └── enviarEmailComAnexos.ecm30.xml │ ├── forms │ │ └── 12 - Enviar e-mail com anexos │ │ │ ├── events │ │ │ ├── atividades.js │ │ │ ├── displayFields.js │ │ │ ├── enableFields.js │ │ │ └── validateForm.js │ │ │ ├── style.css │ │ │ ├── custom.js │ │ │ ├── enviarEmailComAnexos.html │ │ │ └── anexos.js │ ├── README.md │ └── .project ├── dsEnviarEmail.js ├── README.md └── dsEnviarEmailComAnexos.js ├── dsMetaListName ├── esquema.png ├── README.md └── dsMetaListName.js ├── dsConsultaCEP ├── tela_servico.png ├── README.md └── dsConsultaCEP.js ├── gerarPdfTemplateEmail ├── Lista_de_Estados.jpg ├── Lista_de_Estados.pdf ├── print_cadastro_template.png ├── README.md ├── templateTeste.html └── gerarPdfTemplateEmail.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .metadata 2 | Local.ws.cache -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/events/atividades.js: -------------------------------------------------------------------------------- 1 | var INICIO = 1; -------------------------------------------------------------------------------- /dsMetaListName/esquema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsMetaListName/esquema.png -------------------------------------------------------------------------------- /dsConsultaCEP/tela_servico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsConsultaCEP/tela_servico.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/exemplo_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsEnviarEmailComAnexos/exemplo_01.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/Lista_de_Estados.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/gerarPdfTemplateEmail/Lista_de_Estados.jpg -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/Lista_de_Estados.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/gerarPdfTemplateEmail/Lista_de_Estados.pdf -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/print_cadastro_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/gerarPdfTemplateEmail/print_cadastro_template.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/imagem_formulario.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsEnviarEmailComAnexos/processo-exemplo01/imagem_formulario.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/imagem_formulario.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsEnviarEmailComAnexos/processo-exemplo02/imagem_formulario.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/scripts/enviarEmailComAnexos.atividades.js: -------------------------------------------------------------------------------- 1 | var INICIO = 1; 2 | var APROVACAO_2 = 2; 3 | var ENVIAR_EMAIL_4 = 4; 4 | var TRATAR_ERRO_10 = 10; 5 | var FINALIZADO_8 = 8; -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/events/atividades.js: -------------------------------------------------------------------------------- 1 | var INICIO = 1; 2 | var APROVACAO_2 = 2; 3 | var ENVIAR_EMAIL_4 = 4; 4 | var TRATAR_ERRO_10 = 10; 5 | var FINALIZADO_8 = 8; -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/workflow/.resources/enviarEmailComAnexos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsEnviarEmailComAnexos/processo-exemplo01/workflow/.resources/enviarEmailComAnexos.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/.resources/enviarEmailComAnexos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergiomachadosilva/fluig-datasets/HEAD/dsEnviarEmailComAnexos/processo-exemplo02/workflow/.resources/enviarEmailComAnexos.png -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/events/enableFields.js: -------------------------------------------------------------------------------- 1 | function enableFields(form) { 2 | 3 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 4 | 5 | 6 | if (ATIVIDADE != INICIO) { 7 | form.setEnabled("emailDestinatario", false); 8 | form.setEnabled("assuntoEmail", false); 9 | } 10 | 11 | } 12 | 13 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/README.md: -------------------------------------------------------------------------------- 1 | Projeto de exemplo de como enviar anexos enviados através do componente de anexos. 2 | 3 | ## Formulário 4 | 5 | ![Formulário](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsEnviarEmailComAnexos/processo-exemplo02/imagem_formulario.png) 6 | 7 | ## Diagrama do processo 8 | 9 | ![Diagrama](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsEnviarEmailComAnexos/processo-exemplo02/workflow/.resources/enviarEmailComAnexos.processimage.svg) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Datasets Fluig 2 | 3 | Fala aí pessoal, tudo bem? 4 | Aqui consta uma lista de alguns datasets que disponibilizei pra vocês, espero que possa ser útil tanto para estudos quanto para uso em projetos. 5 | 6 | - [Consultar CEP](dsConsultaCEP/README.md) 7 | - [Retorna nome da tabela do formulário no banco de dados](dsMetaListName/README.md) 8 | - [Enviar e-mail com anexos no Fluig](dsEnviarEmailComAnexos/README.md) 9 | - [Gerando um arquivo PDF a partir de um template de e-mail no Fluig](gerarPdfTemplateEmail/README.md) 10 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | emailComAnexos 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.validation.validationbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.wst.jsdt.core.jsNature 16 | com.totvs.tds.ecm.designer.nature 17 | 18 | 19 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | LOCAL-emailComAnexos 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.validation.validationbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.wst.jsdt.core.jsNature 16 | com.totvs.tds.ecm.designer.nature 17 | 18 | 19 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/events/displayFields.js: -------------------------------------------------------------------------------- 1 | function displayFields(form, customHTML) { 2 | form.setShowDisabledFields(true); 3 | form.setHidePrintLink(true); 4 | 5 | try { 6 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 7 | var MODO = form.getFormMode(); 8 | var customJS = "" 14 | customHTML.append(customJS) 15 | 16 | 17 | } catch (err) { 18 | throw "function " + arguments.callee.name + " => " + err.toString(); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/events/displayFields.js: -------------------------------------------------------------------------------- 1 | function displayFields(form, customHTML) { 2 | form.setShowDisabledFields(true); 3 | form.setHidePrintLink(true); 4 | 5 | try { 6 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 7 | var MODO = form.getFormMode(); 8 | var customJS = "" 14 | customHTML.append(customJS) 15 | 16 | 17 | } catch (err) { 18 | throw "function " + arguments.callee.name + " => " + err.toString(); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/README.md: -------------------------------------------------------------------------------- 1 | Neste processo você poderá consultar como é realizado o envio do e-mail com anexos através de um evento de processo. Passando as informações dos campos do formulário para o dataset. 2 | 3 | E também poderá formatar o conteúdo do corpo do e-mail com o componente [Rich Editor](https://style.fluig.com/miscellaneous.html#rich-editor). 4 | 5 | ## Formulário 6 | 7 | ![Formulário](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsEnviarEmailComAnexos/processo-exemplo01/imagem_formulario.png) 8 | 9 | ## Diagrama do processo 10 | 11 | ![Diagrama](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsEnviarEmailComAnexos/processo-exemplo01/workflow/.resources/enviarEmailComAnexos.processimage.svg) 12 | -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/README.md: -------------------------------------------------------------------------------- 1 | # Gerando um arquivo PDF a partir de um template de e-mail no Fluig 2 | 3 | Este dataset demonstra como é possível gerar um arquivo PDF a partir de um template de e-mail cadastrado no Fluig e salvá-lo em uma pasta específica no GED. Para este exemplo, utilizaremos o template "[templateTeste.html](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/gerarPdfTemplateEmail/templateTeste.html)", que deverá ser cadastrado no Fluig acessando o menu "Painel de Controle => Templates de E-mails". 4 | 5 | Caso tenha cadastrado um código diferente do apresentado abaixo ou selecionado outro idioma que não seja o português, é necessário alterar as variáveis correspondentes no dataset. Além disso, é importante informar o ID da pasta no GED onde o PDF será salvo. 6 | 7 | ![Cadastro](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/gerarPdfTemplateEmail/print_cadastro_template.png) 8 | 9 | ## Resultado 10 | Após cadastrar o template e informar as variáveis necessárias, execute o dataset. Ele deverá retornar o ID do documento criado no GED e o PDF gerado deverá ser exatamente como o apresentado abaixo: 11 | 12 | ![Imagem do PDF gerado](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/gerarPdfTemplateEmail/Lista_de_Estados.jpg) 13 | 14 | 15 | [Código do dataset](gerarPdfTemplateEmail.js) 16 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/events/enableFields.js: -------------------------------------------------------------------------------- 1 | function enableFields(form) { 2 | 3 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 4 | 5 | 6 | if (ATIVIDADE != INICIO) { 7 | form.setEnabled("emailDestinatario", false); 8 | form.setEnabled("assuntoEmail", false); 9 | form.setEnabled("formatEmail", false); 10 | 11 | // Anexo Registro de Nascimento 12 | form.setEnabled("fdRegistroNascimento", false); 13 | form.setEnabled("fnRegistroNascimento", false); 14 | 15 | // Anexo CPF 16 | form.setEnabled("fdCpf", false); 17 | form.setEnabled("fnCpf", false); 18 | 19 | // Anexo Foto 20 | form.setEnabled("fdFoto", false); 21 | form.setEnabled("fnFoto", false); 22 | 23 | // Bloqueia os campos da tabela pai e filho 24 | disableInputTable(form) 25 | } 26 | 27 | } 28 | 29 | /** 30 | * Bloqueia os campos da tabela pai e filho 31 | * @param {object} form Parâmetro obrigatório, formController 32 | * @return {void} 33 | * @author Sérgio Machado 34 | */ 35 | function disableInputTable(form) { 36 | var indexes = form.getChildrenIndexes("tblDocumentos"); 37 | for (var i = 0; i < indexes.length; i++) { 38 | form.setEnabled(("documentoDesc___" + indexes[i]), false); 39 | form.setEnabled(("fdDocumento___" + indexes[i]), false); 40 | form.setEnabled(("fnDocumento___" + indexes[i]), false); 41 | form.setEnabled(("documentoEmail___" + indexes[i]), false); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/custom.js: -------------------------------------------------------------------------------- 1 | var INICIO = 1; 2 | 3 | $(document).ready(function() { 4 | 5 | initRichEditor("corpoEmail", INICIO); 6 | 7 | }) 8 | 9 | 10 | 11 | /** 12 | * Inicializa o componente Rich Editor 13 | * @param {string} inputId Parâmetro obrigatório, Id do textarea onde o componente será inicializado 14 | * @param {string|Number} atividade Parâmetro obrigatório, código da atividade em que o componente será habilitado para edição 15 | * @return {void} 16 | * @author Sérgio Machado 17 | */ 18 | function initRichEditor(inputId, atividade) { 19 | 20 | // Variável com valor true ou false, indicando se o Rich Editor será inicializado bloqueado ou não 21 | const readOnly = !((getAtividade() == atividade) && (getMode() != "VIEW")); 22 | 23 | // Configurações 24 | var settings = { 25 | removePlugins: 'fluigimage,fluigvideo', 26 | resize_enabled: false, 27 | height: "300px", 28 | readOnly 29 | }; 30 | 31 | // Inicializa o componente recebendo o id do campo e as configurações 32 | var editor = FLUIGC.richeditor(inputId, settings); 33 | 34 | // Pega a string html que esta armazenada no campo, caso tenha valor gravado 35 | var htmlString = (document.getElementById(inputId).value || document.getElementById(inputId).textContent); 36 | 37 | // Seta a string html no componente 38 | editor.setData(htmlString); 39 | 40 | // Grava a string html no campo a cada alteração de conteúdo do componente 41 | editor.on('change', function() { 42 | document.getElementById(inputId).value = editor.getData(); 43 | }); 44 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/workflow/scripts/enviarEmailComAnexos.servicetask4.js: -------------------------------------------------------------------------------- 1 | function servicetask4(attempt, message) { 2 | 3 | try { 4 | 5 | var constraints = []; 6 | var anexos = []; 7 | var destinatario = hAPI.getCardValue("emailDestinatario"); 8 | var assunto = hAPI.getCardValue("assuntoEmail"); 9 | var conteudo = hAPI.getCardValue("corpoEmail"); 10 | 11 | // Lista com os anexos presentes na solicitação 12 | var docs = hAPI.listAttachments(); 13 | 14 | for (var i = 0; i < docs.size(); i++) { 15 | var doc = docs.get(i); 16 | anexos.push({ id: Number(doc.getDocumentId()), versao: Number(doc.getVersion()), nomeArquivo: String(doc.getPhisicalFile())}); 17 | } 18 | 19 | constraints.push(DatasetFactory.createConstraint("nomeRemetente", "Empresa XPTO", null, ConstraintType.MUST)); 20 | constraints.push(DatasetFactory.createConstraint("destinatario", destinatario, null, ConstraintType.MUST)); 21 | constraints.push(DatasetFactory.createConstraint("assunto", assunto, null, ConstraintType.MUST)); 22 | constraints.push(DatasetFactory.createConstraint("conteudo", conteudo, null, ConstraintType.MUST)); 23 | constraints.push(DatasetFactory.createConstraint("anexos", JSON.stringify(anexos), null, ConstraintType.MUST)); 24 | 25 | var dataset = DatasetFactory.getDataset("dsEnviarEmailComAnexos", null, constraints, null); 26 | 27 | var retorno = dataset.getValue(0, "STATUS"); 28 | 29 | if(retorno != "OK"){ 30 | throw retorno; 31 | } 32 | 33 | } catch (err) { 34 | throw ("function " + arguments.callee.name + " => " + err.toString()); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/scripts/enviarEmailComAnexos.funcoes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retorna as propriedades de um documento 3 | * @param {string} fileDescription Parâmetro obrigatório, descrição do documento 4 | * @return {boolean|object} Caso o documento exista, retorna um objeto com as propriedades {id, versao, nomeArquivo}, 5 | caso não exista, retorna falso 6 | * @author Sérgio Machado 7 | */ 8 | function documentoDto(fileDescription) { 9 | var docs = hAPI.listAttachments(); 10 | for (var i = 0; i < docs.size(); i++) { 11 | var doc = docs.get(i); 12 | if (fileDescription == doc.getDocumentDescription()) { 13 | return { id: String(doc.getDocumentId()), versao: String(doc.getVersion()), nomeArquivo: String(doc.getPhisicalFile())}; 14 | } 15 | } 16 | return false; 17 | } 18 | 19 | 20 | /** 21 | * Retorna a extensão de um arquivo 22 | * @param {string} phisicalFile Parâmetro obrigatório, nome físico do arquivo 23 | * @return {string} 24 | * @author Sérgio Machado 25 | */ 26 | function obterExtensao(phisicalFile){ 27 | var extensao = "." + phisicalFile.split(".").pop(); 28 | return extensao; 29 | } 30 | 31 | 32 | /** 33 | * Verifica se existe todos os documentos inseridos na tabela pai e filho na aba de anexos 34 | * @param {string[]} erros Parâmetro obrigatório, array com os erros 35 | * @return {void} 36 | * @author Sérgio Machado 37 | */ 38 | function documentosTabelaExiste(erros) { 39 | var indexes = hAPI.getChildrenIndexes("tblDocumentos"); 40 | for (var i = 0; i < indexes.length; i++) { 41 | var fileName = String(hAPI.getCardValue("fnDocumento___" + indexes[i])); 42 | var fileDescription = String(hAPI.getCardValue("fdDocumento___" + indexes[i])); 43 | 44 | if (fileName) { 45 | if (!documentoDto(fileDescription)) { 46 | erros.push("Não foi encontrado o anexo " + fileName + " da linha " + (i+1)); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/style.css: -------------------------------------------------------------------------------- 1 | .componentAnexo{ 2 | display: flex; 3 | align-items: center; 4 | flex-wrap: nowrap; 5 | } 6 | 7 | .componentAnexo .input-group{ 8 | flex-grow: 1; 9 | position: relative; 10 | } 11 | 12 | .componentAnexo .inputAnexo{ 13 | color: blue!important; 14 | border-radius: 0!important; 15 | } 16 | 17 | .componentAnexo .icones{ 18 | display: flex; 19 | align-items: center; 20 | justify-content: flex-end; 21 | } 22 | 23 | .componentAnexo .icones .btn{ 24 | outline: none!important; 25 | outline-offset: unset!important; 26 | border-radius: 0; 27 | padding-left: 7px; 28 | padding-right: 7px; 29 | margin-left: 3px; 30 | } 31 | 32 | .componentAnexo .icones .btn-default, 33 | .componentAnexo .icones .btn-default:focus, 34 | .componentAnexo .icones .btn-default:active, 35 | .componentAnexo .icones .btn-default:hover{ 36 | border: solid 2px #58595b!important; 37 | } 38 | 39 | .componentAnexo .icones .btn-primary, 40 | .componentAnexo .icones .btn-primary:focus, 41 | .componentAnexo .icones .btn-primary:active, 42 | .componentAnexo .icones .btn-primary:hover{ 43 | border: solid 2px #58595b!important; 44 | } 45 | 46 | .componentAnexo .icones .btn-success, 47 | .componentAnexo .icones .btn-success:focus, 48 | .componentAnexo .icones .btn-success:active, 49 | .componentAnexo .icones .btn-success:hover{ 50 | border: solid 2px #1ab83f!important; 51 | } 52 | 53 | .componentAnexo .icones .btn-info, 54 | .componentAnexo .icones .btn-info:focus, 55 | .componentAnexo .icones .btn-info:active, 56 | .componentAnexo .icones .btn-info:hover{ 57 | border: solid 2px #1eaad9!important; 58 | } 59 | .componentAnexo .icones .btn-warning, 60 | .componentAnexo .icones .btn-warning:focus, 61 | .componentAnexo .icones .btn-warning:active, 62 | .componentAnexo .icones .btn-warning:hover{ 63 | border: solid 2px #e3b420!important; 64 | } 65 | 66 | .componentAnexo .icones .btn-danger, 67 | .componentAnexo .icones .btn-danger:focus, 68 | .componentAnexo .icones .btn-danger:active, 69 | .componentAnexo .icones .btn-danger:hover{ 70 | border: solid 2px #cc3d3d!important; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/scripts/enviarEmailComAnexos.beforeStateEntry.js: -------------------------------------------------------------------------------- 1 | function beforeStateEntry(sequenceId) { 2 | 3 | try { 4 | var erros = []; 5 | 6 | if (sequenceId == APROVACAO_2) { 7 | 8 | var anexoRegNascFile = String(hAPI.getCardValue("fnRegistroNascimento")); 9 | var anexoRegNascDesc = String(hAPI.getCardValue("fdRegistroNascimento")); 10 | 11 | var anexoCpfFile = String(hAPI.getCardValue("fnCpf")); 12 | var anexoCpfDesc = String(hAPI.getCardValue("fdCpf")); 13 | 14 | var anexoFotoFile = String(hAPI.getCardValue("fnFoto")); 15 | var anexoFotoDesc = String(hAPI.getCardValue("fdFoto")); 16 | 17 | if (anexoRegNascFile) { 18 | if (!documentoDto(anexoRegNascDesc)) { 19 | erros.push("Não foi encontrado o anexo " + anexoRegNascFile + ""); 20 | } 21 | } 22 | 23 | if (anexoCpfFile) { 24 | if (!documentoDto(anexoCpfDesc)) { 25 | erros.push("Não foi encontrado o anexo " + anexoCpfFile + ""); 26 | } 27 | } 28 | 29 | if (anexoFotoFile) { 30 | if (!documentoDto(anexoFotoDesc)) { 31 | erros.push("Não foi encontrado o anexo " + anexoFotoFile + ""); 32 | } 33 | } 34 | 35 | // Valida os documentos inseridos na tabela pai e filho se eles existem na aba de anexos 36 | documentosTabelaExiste(erros); 37 | } 38 | 39 | // Se existir alguma mensagem no array de erros, lança uma exceção 40 | if (erros.length) { 41 | throw formatarErros(erros); 42 | } 43 | 44 | } catch (err) { 45 | throw ("
function " + arguments.callee.name + " => " + err.toString()); 46 | } 47 | } 48 | 49 | /** 50 | * Formata os erros 51 | * @param {String[]} erros Parâmetro obrigatório, array com os erros 52 | * @returns {String} - Retorna uma string contendo todos os erros dentro de uma tag ul 53 | * @author Sérgio Machado 54 | */ 55 | function formatarErros(erros) { 56 | var strErros = ''; 57 | for (var i = 0; i < erros.length; i++) { 58 | strErros += '
  • ' + erros[i] + '
  • '; 59 | } 60 | var listErros = '
    '; 61 | return 'Favor informar os anexos obrigatórios:

    ' + listErros; 62 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/enviarEmailComAnexos.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 | 17 | 18 | 21 | 22 |
    23 |
    24 |

    25 | Detalhes do email 26 |

    27 |
    28 |
    29 |
    30 |
    31 |
    32 | 33 | 34 |
    35 |
    36 |
    37 |
    38 | 39 | 40 |
    41 |
    42 |
    43 |
    44 |
    45 |
    46 | 47 | 48 |
    49 |
    50 |
    51 |
    52 |
    53 |
    54 |
    55 | 56 | -------------------------------------------------------------------------------- /dsMetaListName/README.md: -------------------------------------------------------------------------------- 1 | # Retorna nome da tabela do formulário no banco de dados 2 | 3 | Este dataset tem como objetivo retornar o nome da tabela no banco de dados de um formulário. 4 | 5 | _"Um formulário configurado para armazenar seus dados em tabelas múltiplas, quando exportado criará uma nova tabela no banco de dados cujo nome seguirá o padrão MLEEELLL, onde EEE representa o código da empresa precedido por zeros e LLL representa o código da lista (gerado de forma sequencial pela plataforma) também precedido por zeros."_ 6 | 7 | ![Esquema](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsMetaListName/esquema.png) 8 | 9 | Para mais detalhes acesse os link abaixo: 10 | 11 | - [Modelos de Armazenamento de Formulários](https://tdn.totvs.com/pages/releaseview.action?pageId=244716710) 12 | 13 | - [Parâmetros em eventos de Processos](https://tdn.totvs.com/pages/releaseview.action?pageId=270919174) 14 | 15 | - [FormController ](https://tdn.totvs.com/pages/releaseview.action?pageId=662892312) 16 | 17 | Veja também este vídeo onde demonstro na prática: https://youtu.be/CLeEvKn0Syo 18 | 19 | ## Chamando o dataset em um arquivo js do formulário 20 | 21 | Vale ressaltar que por se tratar de um dataset, você tem a liberdade para chamar em qualquer lugar, como js do formulário, eventos de processo, eventos de formulário, outros datasets, etc. 22 | 23 | | Constraint | Valor | Obrigatório | 24 | | ---------- | ----- | ----------- | 25 | | CODIGO | 3765 | Sim | 26 | 27 | A constraint CODIGO, corresponde ao id do formulário, cuidado para não confundir com o id de registro do formulário. 28 | 29 | ```js 30 | const cCodigo = DatasetFactory.createConstraint( 31 | "CODIGO", 32 | "3765", 33 | null, 34 | ConstraintType.MUST 35 | ); 36 | 37 | //Busca dados do dataset 38 | const dataset = DatasetFactory.getDataset( 39 | "dsMetaListName", 40 | null, 41 | [cCodigo], 42 | null 43 | ); 44 | const data = dataset.values; 45 | if (!data[0].ERROR) { 46 | console.log(data[0].TABELA); // Imprime no console o nome da tabela 47 | } else { 48 | console.error(data[0].ERROR); 49 | } 50 | ``` 51 | 52 | ## Retorno em caso de sucesso 53 | 54 | Caso não ocorra nenhum erro o dataset irá retornar as seguinte colunas: 55 | 56 | | CODIGO | TABELA | 57 | | ------ | -------- | 58 | | 3765 | ML001021 | 59 | 60 | ## Retorno em caso de erro 61 | 62 | | CODIGO | ERROR | 63 | | ------ | ------------------------------ | 64 | | null | Id do formulário não informado | 65 | 66 | [Veja aqui o código do dataset](dsMetaListName.js) 67 | -------------------------------------------------------------------------------- /dsConsultaCEP/README.md: -------------------------------------------------------------------------------- 1 | # Retorna informações de endereço com base no CEP 2 | 3 | Para utilizar este dataset primeiro terá que cadastrar o serviço no Fluig, em Paninel de Controle > Serviços. 4 | Clique o botão "Novo serviço" na tela seguinte no campo Serviço, selecione a opção REST. E informe os dados conforme abaixo: 5 | 6 | ## Cadastro 7 | 8 | | Campo | Valor | Obrigatório | 9 | | ------------------------- | --------------------------------------------------------------- | ----------- | 10 | | Nome | wsViaCEP | Sim | 11 | | Descrição | Webservice para consultar Códigos de Endereçamento Postal (CEP) | Sim | 12 | | Domínio | https://viacep.com.br | Sim | 13 | | Tipo de Autenticação | None | Sim | 14 | | URL para teste de Serviço | /ws/70150900/json/ | Opcional | 15 | 16 | ## Imagem 17 | 18 | ![Tela Serviço](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsConsultaCEP/tela_servico.png) 19 | 20 | ## Chamando o dataset em um arquivo js do formulário 21 | 22 | | Constraint | Valor | Obrigatório | 23 | | ---------- | -------- | ----------- | 24 | | CEP | 70150900 | Sim | 25 | 26 | _Você está livre para informar o valor do CEP formatado ou não, o dataset se encarregará de remover tudo o que não for número._ 27 | 28 | ```js 29 | const cCep = DatasetFactory.createConstraint( 30 | "CEP", 31 | "70150900", 32 | null, 33 | ConstraintType.MUST 34 | ); 35 | 36 | //Busca dados do dataset 37 | const dataset = DatasetFactory.getDataset("dsConsultaCEP", null, [cCep], null); 38 | const data = dataset.values; 39 | if (!data[0].ERROR) { 40 | console.log(dataset); 41 | } else { 42 | console.error(data[0].ERROR); 43 | } 44 | ``` 45 | 46 | ## Retorno em caso de sucesso 47 | 48 | Caso o CEP informado seja encontrado, o dataset irá retornar as seguinte colunas: 49 | 50 | | CEP | ENDERECO | COMPLEMENTO | BAIRRO | CIDADE | ESTADO | DDD | IBGE | SIAFI | 51 | | -------- | ---------------------- | ----------- | -------------------------- | -------- | ------ | --- | ------- | ----- | 52 | | 70150900 | Praça dos Três Poderes | | Zona Cívico-Administrativa | Brasília | DF | 61 | 5300108 | 9701 | 53 | 54 | ## Retorno em caso de erro 55 | 56 | | ERROR | 57 | | ------------------ | 58 | | CEP não encontrado | 59 | 60 | [Veja aqui o código do dataset](dsConsultaCEP.js) 61 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/dsEnviarEmail.js: -------------------------------------------------------------------------------- 1 | function createDataset(fields, constraints, sortFields) { 2 | 3 | var dataset = DatasetBuilder.newDataset(); 4 | 5 | dataset.addColumn("STATUS"); 6 | 7 | try { 8 | 9 | var constraints = []; 10 | var copia = []; 11 | var copiaOculta = []; 12 | var anexos = []; 13 | 14 | // Adiciona os e-mails que receberão uma cópia 15 | copia.push("emailcopia01@hotmail.com"); 16 | copia.push("emailcopia01@hotmail.com"); 17 | 18 | // Adiciona os e-mails que receberão uma cópia de forma oculta 19 | copiaOculta.push("emailcopiaoculta01@hotmail.com"); 20 | copiaOculta.push("emailcopiaoculta01@hotmail.com"); 21 | 22 | // Adiciona os anexos que serão enviados no e-mail 23 | anexos.push({ id: 2635, versao: 1000, nomeArquivo: "arquivo.pdf", descArquivo: "Meu Arquivo.pdf" }); 24 | anexos.push({ id: 2649, versao: 1000, nomeArquivo: "image_01.png" }); 25 | 26 | constraints.push(DatasetFactory.createConstraint("nomeRemetente", "Empresa XPTO", null, ConstraintType.MUST)); 27 | constraints.push(DatasetFactory.createConstraint("assunto", "Envio de e-mail com anexos", null, ConstraintType.MUST)); 28 | constraints.push(DatasetFactory.createConstraint("conteudo", "

    Olá.!! Este é um teste de envio de e-mail com anexos no Fluig

    ", null, ConstraintType.MUST)); 29 | constraints.push(DatasetFactory.createConstraint("destinatario", "sergiojfjfjf@hotmail.com", null, ConstraintType.MUST)); 30 | constraints.push(DatasetFactory.createConstraint("textoPlano", "true", null, ConstraintType.MUST)); 31 | constraints.push(DatasetFactory.createConstraint("responderPara", "sergiojfjfjf@gmail.com", null, ConstraintType.MUST)); 32 | constraints.push(DatasetFactory.createConstraint("copia", JSON.stringify(copia), null, ConstraintType.MUST)); 33 | constraints.push(DatasetFactory.createConstraint("copiaOculta", JSON.stringify(copiaOculta), null, ConstraintType.MUST)); 34 | constraints.push(DatasetFactory.createConstraint("anexos", JSON.stringify(anexos), null, ConstraintType.MUST)); 35 | 36 | // Chama o dataset passando as constraints por parâmetro 37 | var dataset = DatasetFactory.getDataset("dsEnviarEmailComAnexos", null, constraints, null); 38 | 39 | var retorno = dataset.getValue(0, "STATUS"); 40 | 41 | if (retorno != "OK") { 42 | throw retorno; 43 | } 44 | 45 | dataset.addRow(new Array("SUCESSO")); 46 | 47 | } catch (err) { 48 | dataset.addRow(new Array("dsEnviarEmail => function " + arguments.callee.name + " => " + err.toString())); 49 | } 50 | 51 | return dataset; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /dsConsultaCEP/dsConsultaCEP.js: -------------------------------------------------------------------------------- 1 | function createDataset(fields, constraints, sortFields) { 2 | 3 | var dataset = DatasetBuilder.newDataset(); 4 | 5 | //Cria as colunas 6 | dataset.addColumn("CEP"); 7 | dataset.addColumn("ENDERECO"); 8 | dataset.addColumn("COMPLEMENTO"); 9 | dataset.addColumn("BAIRRO"); 10 | dataset.addColumn("CIDADE"); 11 | dataset.addColumn("ESTADO"); 12 | dataset.addColumn("DDD"); 13 | dataset.addColumn("IBGE"); 14 | dataset.addColumn("SIAFI"); 15 | 16 | try { 17 | 18 | var cepStr = new java.lang.String(obterParametro(constraints, "CEP")); 19 | if (cepStr == "") { 20 | throw "CEP não informado"; 21 | } 22 | 23 | // Remove tudo o que não for número 24 | var CEP = cepStr.replaceAll("[^\\d]", ""); 25 | 26 | var clientService = fluigAPI.getAuthorizeClientService(); 27 | var data = { 28 | companyId: String(fluigAPI.getSecurityService().getCurrentTenantId()), 29 | serviceCode: 'wsViaCEP', 30 | endpoint: '/ws/' + CEP + '/json/', 31 | method: 'get', 32 | timeoutService: '100' 33 | } 34 | 35 | try { 36 | 37 | var vo = clientService.invoke(JSON.stringify(data)); 38 | var retorno = JSON.parse(vo.getResult()); 39 | 40 | if (!retorno.erro) { 41 | dataset.addRow(new Array( 42 | CEP, 43 | retorno.logradouro, 44 | retorno.complemento, 45 | retorno.bairro, 46 | retorno.localidade, 47 | retorno.uf, 48 | retorno.ddd, 49 | retorno.ibge, 50 | retorno.siafi 51 | )); 52 | } else { 53 | throw "CEP não encontrado"; 54 | } 55 | 56 | } catch (e) { 57 | throw "CEP não encontrado"; 58 | } 59 | 60 | } catch (err) { 61 | dataset = DatasetBuilder.newDataset(); 62 | dataset.addColumn("ERROR"); 63 | dataset.addRow(new Array(err.toString())); 64 | } 65 | 66 | return dataset; 67 | } 68 | 69 | 70 | /** 71 | * Retorna o valor initialValue de uma determinada constraint 72 | * @param {object} constraints Parâmetro obrigatório, constraints recebidas no dataset 73 | * @param {String} campo Parâmetro obrigatório, constraint que deseja obter o valor 74 | * @return {String} 75 | */ 76 | function obterParametro(constraints, campo) { 77 | var valor = ""; 78 | if ((constraints != null) && (constraints.length > 0)) { 79 | for (i in constraints) { 80 | var constraint = constraints[i] 81 | if (constraint.getFieldName().trim().toUpperCase() == campo.trim().toUpperCase()) { 82 | valor = constraint.getInitialValue(); 83 | break; 84 | } 85 | } 86 | } 87 | return valor; 88 | } -------------------------------------------------------------------------------- /dsMetaListName/dsMetaListName.js: -------------------------------------------------------------------------------- 1 | function createDataset(fields, constraints, sortFields) { 2 | 3 | var dataset = DatasetBuilder.newDataset(); 4 | 5 | //Cria as colunas 6 | dataset.addColumn("CODIGO"); 7 | dataset.addColumn("TABELA"); 8 | 9 | try { 10 | 11 | var cardIndexId = obterParametro(constraints, "CODIGO"); //Id do formulário 12 | if (cardIndexId == "") { 13 | throw "Id do formulário não informado"; 14 | } 15 | 16 | var companyId = java.lang.Integer(fluigAPI.getSecurityService().getCurrentTenantId()); 17 | var metaListId = java.lang.Integer(getMetaListId(companyId, cardIndexId)); 18 | 19 | var codigoEmpresa = java.lang.String.format("%03d", companyId); 20 | var codigoMetaListId = java.lang.String.format("%03d", metaListId); 21 | 22 | var tabela = "ML" + codigoEmpresa + codigoMetaListId; 23 | 24 | dataset.addRow(new Array(cardIndexId, tabela)); 25 | 26 | } catch (err) { 27 | dataset = DatasetBuilder.newDataset(); 28 | dataset.addColumn("CODIGO"); 29 | dataset.addColumn("ERROR"); 30 | dataset.addRow(new Array(null, err.toString())); 31 | } 32 | 33 | return dataset; 34 | } 35 | 36 | 37 | /** 38 | * Obtém a metaListId com base no id do formulário e id da empresa 39 | * @param {Number} companyId Parâmetro obrigatório, id da empresa 40 | * @param {Number|String} cardIndexId Parâmetro obrigatório, id do formulário 41 | * @returns {Number} Retorna a metaListId do formulário 42 | * @author Sérgio Machado 43 | */ 44 | function getMetaListId(companyId, cardIndexId) { 45 | var c1 = DatasetFactory.createConstraint("documentPK.companyId", companyId, companyId, ConstraintType.MUST); 46 | var c2 = DatasetFactory.createConstraint("documentPK.documentId", cardIndexId, cardIndexId, ConstraintType.MUST); 47 | var c3 = DatasetFactory.createConstraint("activeVersion", true, true, ConstraintType.MUST); 48 | var dataset = DatasetFactory.getDataset("document", null, new Array(c1, c2, c3), null); 49 | 50 | if (dataset.getRowsCount() > 0) { 51 | return String(dataset.getValue(0, "metaListId")); 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | 58 | /** 59 | * Retorna o valor initialValue de uma determinada constraint 60 | * @param {object} constraints Parâmetro obrigatório, constraints recebidas no dataset 61 | * @param {String} campo Parâmetro obrigatório, constraint que deseja obter o valor 62 | * @return {String} 63 | */ 64 | function obterParametro(constraints, campo) { 65 | var valor = 0; 66 | if ((constraints != null) && (constraints.length > 0)) { 67 | for (i in constraints) { 68 | var constraint = constraints[i] 69 | if (constraint.getFieldName().trim().toUpperCase() == campo.trim().toUpperCase()) { 70 | valor = constraint.getInitialValue(); 71 | break; 72 | } 73 | } 74 | } 75 | return valor; 76 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/forms/enviarEmailComAnexos/events/validateForm.js: -------------------------------------------------------------------------------- 1 | function validateForm(form) { 2 | 3 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 4 | var PROX_ATIVIDADE = Number(getValue("WKNextState")) 5 | var TAREFA_COMPLETA = (getValue("WKCompletTask") == "true"); 6 | 7 | if (!TAREFA_COMPLETA || ATIVIDADE == PROX_ATIVIDADE) { 8 | return; 9 | } 10 | 11 | 12 | try { 13 | 14 | var erros = []; 15 | 16 | if (ATIVIDADE == INICIO) { 17 | var emailDestinatario = String(form.getValue("emailDestinatario")); 18 | var assunto = String(form.getValue("assuntoEmail")); 19 | var corpoEmail = org.jsoup.Jsoup.parse(String(form.getValue("corpoEmail"))); 20 | var body = String(corpoEmail.body().text()); // Pega somente o conteúdo texto da tag body 21 | 22 | if (!validarEmail(emailDestinatario)) { 23 | erros.push("Informe um e-mail válido para o destinatário"); 24 | } 25 | 26 | if (!assunto) { 27 | erros.push("Informe o assunto do e-mail"); 28 | } else if (assunto.length < 10) { 29 | erros.push("O assunto do e-mail deve conter no mínimo 10 caracteres"); 30 | } 31 | 32 | if (!body) { 33 | erros.push("Informe o conteúdo para o corpo do e-mail"); 34 | } else if (body.length < 30) { 35 | erros.push("O corpo do e-mail deve conter no mínimo 30 caracteres"); 36 | } 37 | } 38 | 39 | // Se existir alguma mensagem no array de erros, lança uma exceção 40 | if (erros.length) { 41 | throw formatarErros(erros); 42 | } 43 | 44 | } catch (e) { 45 | throw e 46 | } 47 | } 48 | 49 | /** 50 | * Verifica se um endereço de e-mail é válido 51 | * @param {string} email Parâmetro obrigatório, endereço de email 52 | * @return {boolean} Retorna verdadeiro coso o e-mail seja válido, caso contrário, retorna falso 53 | * @author Sérgio Machado 54 | */ 55 | function validarEmail(email) { 56 | var er = new RegExp(/^[A-Za-z0-9_\-\.]+@[A-Za-z0-9_\-\.]{2,}\.[A-Za-z0-9]{2,}(\.[A-Za-z0-9])?/); 57 | if (email == '' || !er.test(email)) { 58 | return false; 59 | } else { 60 | return true 61 | } 62 | } 63 | 64 | 65 | /** 66 | * Formata os erros 67 | * @param {String[]} erros Parâmetro obrigatório, array com os erros 68 | * @returns {String} - Retorna uma string contendo todos os erros dentro de uma tag li 69 | * @author Sérgio Machado 70 | */ 71 | function formatarErros(erros) { 72 | var strErros = ""; 73 | for (var i = 0; i < erros.length; i++) { 74 | strErros += "
  • " + erros[i] + "
  • "; 75 | } 76 | var listErros = "
    "; 77 | return "Favor informar os campos obrigatórios:

    " + listErros; 78 | } 79 | 80 | 81 | function campoVazio(form, fieldname) { 82 | if ((form.getValue(fieldname) == null) || (form.getValue(fieldname) == undefined) || (form.getValue(fieldname).trim() == "")) { 83 | return true; 84 | } 85 | return false; 86 | } -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/templateTeste.html: -------------------------------------------------------------------------------- 1 | <#compress> 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | <#assign thead = "border:solid 1px #ccc; font-weight:bold; padding:10px 5px 10px 5px;"> 14 | <#assign td = "border:solid 1px #ccc; padding:5px;font-size: .9em;"> 15 | <#assign zebra_odd = ""> 16 | <#assign zebra_even = "background-color: #f6f6f6;"> 17 | 18 | 19 | 20 | 21 | 22 | 32 | 33 | 34 | 49 | 50 | 51 | 71 | 72 | 73 | 85 | 86 |
    23 | 24 | 25 | 28 | 29 | 30 |
    26 | 27 |
     
    31 |
    35 | 36 | 37 | 40 | 41 | 42 | 45 | 46 | 47 |
    38 |

    Estados do Brasil

    39 |
    43 |

    O Brasil, um vasto país sul-americano, estende-se da Bacia Amazônica, no norte, até os vinhedos e as gigantescas Cataratas do Iguaçu, no sul. O Rio de Janeiro, simbolizado pela sua estátua de 38 metros de altura do Cristo Redentor, situada no topo do Corcovado, é famoso pelas movimentadas praias de Copacabana e Ipanema, bem como pelo imenso e animado Carnaval, com desfiles de carros alegóricos, fantasias extravagantes e samba. ― Google

    44 |
     
    48 |
    52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | <#list estados as estado> 62 | style="${zebra_even}"<#else>style="${zebra_odd}"> 63 | 64 | 65 | 66 | 67 | 68 | 69 |
    #NomeSigla
    ${estado?index + 1}${estado.nome!''} ${estado.sigla!''}
    70 |
    74 | 75 | 76 | 77 | 78 | 81 | 82 | 83 |
     
    79 | Desenvolvido por: ${nome!''} ${sobrenome!''} 80 |
    84 |
    87 | 88 | 89 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/scripts/enviarEmailComAnexos.servicetask4.js: -------------------------------------------------------------------------------- 1 | function servicetask4(attempt, message) { 2 | 3 | try { 4 | 5 | var constraints = []; 6 | var anexos = []; 7 | var destinatario = hAPI.getCardValue("emailDestinatario"); 8 | var assunto = hAPI.getCardValue("assuntoEmail"); 9 | var conteudo = hAPI.getCardValue("corpoEmail"); 10 | var textoPlano = hAPI.getCardValue("formatEmail") == "on" ? true : false; 11 | 12 | 13 | 14 | // Adiciona anexo Registro de nascimento 15 | var anexoRegNascFile = String(hAPI.getCardValue("fnRegistroNascimento")); 16 | var anexoRegNascDesc = String(hAPI.getCardValue("fdRegistroNascimento")); 17 | 18 | // Verifica se o campo esta preenchido 19 | if (anexoRegNascFile) { 20 | var objetoAnexo = documentoDto(anexoRegNascDesc) 21 | // Verifica se o documento existe 22 | if (objetoAnexo) { 23 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 24 | objetoAnexo.descArquivo = "Registro de Nascimento" + obterExtensao(objetoAnexo.nomeArquivo); 25 | anexos.push(objetoAnexo) 26 | } 27 | } 28 | 29 | 30 | // Adiciona anexo CPF 31 | var anexoCpfFile = String(hAPI.getCardValue("fnCpf")); 32 | var anexoCpfDesc = String(hAPI.getCardValue("fdCpf")); 33 | 34 | // Verifica se o campo esta preenchido 35 | if (anexoCpfFile) { 36 | var objetoAnexo = documentoDto(anexoCpfDesc) 37 | // Verifica se o documento existe 38 | if (objetoAnexo) { 39 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 40 | objetoAnexo.descArquivo = "CPF" + obterExtensao(objetoAnexo.nomeArquivo); 41 | anexos.push(objetoAnexo) 42 | } 43 | } 44 | 45 | 46 | // Adiciona anexo Foto 47 | var anexoFotoFile = String(hAPI.getCardValue("fnFoto")); 48 | var anexoFotoDesc = String(hAPI.getCardValue("fdFoto")); 49 | 50 | // Verifica se o campo esta preenchido 51 | if (anexoFotoFile) { 52 | var objetoAnexo = documentoDto(anexoFotoDesc) 53 | // Verifica se o documento existe 54 | if (objetoAnexo) { 55 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 56 | objetoAnexo.descArquivo = "Foto" + obterExtensao(objetoAnexo.nomeArquivo); 57 | anexos.push(objetoAnexo) 58 | } 59 | } 60 | 61 | 62 | // Percorre a tabela pai e filho 63 | var indexes = hAPI.getChildrenIndexes("tblDocumentos"); 64 | 65 | for (var i = 0; i < indexes.length; i++) { 66 | var enviarEmailArquivo = String(hAPI.getCardValue("documentoEmail___" + indexes[i])); 67 | var anexoDesc = String(hAPI.getCardValue("fdDocumento___" + indexes[i])); 68 | var descricao = String(hAPI.getCardValue("documentoDesc___" + indexes[i])); 69 | 70 | // Verifica se o campo checkbox da tabela pai e filho esta marcado 71 | if(enviarEmailArquivo){ 72 | var objetoAnexo = documentoDto(anexoDesc) 73 | // Verifica se o documento existe 74 | if (objetoAnexo) { 75 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 76 | objetoAnexo.descArquivo = (descricao + obterExtensao(objetoAnexo.nomeArquivo)); 77 | anexos.push(objetoAnexo) 78 | } 79 | } 80 | } 81 | 82 | 83 | constraints.push(DatasetFactory.createConstraint("nomeRemetente", "Empresa XPTO", null, ConstraintType.MUST)); 84 | constraints.push(DatasetFactory.createConstraint("destinatario", destinatario, null, ConstraintType.MUST)); 85 | constraints.push(DatasetFactory.createConstraint("assunto", assunto, null, ConstraintType.MUST)); 86 | constraints.push(DatasetFactory.createConstraint("conteudo", conteudo, null, ConstraintType.MUST)); 87 | constraints.push(DatasetFactory.createConstraint("textoPlano", textoPlano, null, ConstraintType.MUST)); 88 | constraints.push(DatasetFactory.createConstraint("anexos", JSON.stringify(anexos), null, ConstraintType.MUST)); 89 | 90 | var dataset = DatasetFactory.getDataset("dsEnviarEmailComAnexos", null, constraints, null); 91 | 92 | var retorno = dataset.getValue(0, "STATUS"); 93 | 94 | if(retorno != "OK"){ 95 | throw retorno; 96 | } 97 | 98 | } catch (err) { 99 | throw ("function " + arguments.callee.name + " => " + err.toString()); 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/events/validateForm.js: -------------------------------------------------------------------------------- 1 | function validateForm(form) { 2 | 3 | var ATIVIDADE = Number(getValue("WKNumState")) ? Number(getValue("WKNumState")) : INICIO; 4 | var PROX_ATIVIDADE = Number(getValue("WKNextState")) 5 | var TAREFA_COMPLETA = (getValue("WKCompletTask") == "true"); 6 | 7 | if (!TAREFA_COMPLETA || ATIVIDADE == PROX_ATIVIDADE) { 8 | return; 9 | } 10 | 11 | 12 | try { 13 | 14 | var erros = []; 15 | 16 | if (ATIVIDADE == INICIO) { 17 | var emailDestinatario = String(form.getValue("emailDestinatario")); 18 | var assunto = String(form.getValue("assuntoEmail")); 19 | var corpoEmail = org.jsoup.Jsoup.parse(String(form.getValue("corpoEmail"))); 20 | var body = String(corpoEmail.body().text()); // Pega somente o conteúdo texto da tag body 21 | var anexoRegNasc = String(form.getValue("fnRegistroNascimento")) 22 | 23 | 24 | if (!validarEmail(emailDestinatario)) { 25 | erros.push("Informe um e-mail válido para o destinatário"); 26 | } 27 | 28 | if (!assunto) { 29 | erros.push("Informe o assunto do e-mail"); 30 | }else if(assunto.length < 10){ 31 | erros.push("O assunto do e-mail deve conter no mínimo 10 caracteres"); 32 | } 33 | 34 | if (!body) { 35 | erros.push("Informe o conteúdo para o corpo do e-mail"); 36 | } else if(body.length < 10){ 37 | erros.push("O corpo do e-mail deve conter no mínimo 10 caracteres"); 38 | } 39 | 40 | if(!anexoRegNasc){ 41 | erros.push("Informe o anexo Registro de Nascimento"); 42 | } 43 | 44 | // Valida a tabela pai e filho 45 | validarInputsTable(form, erros) 46 | } 47 | 48 | 49 | // Se existir alguma mensagem no array de erros, lança uma exceção 50 | if (erros.length) { 51 | throw formatarErros(erros); 52 | } 53 | 54 | } catch (err) { 55 | throw err 56 | } 57 | } 58 | 59 | /** 60 | * Verifica se um endereço de e-mail é válido 61 | * @param {string} email Parâmetro obrigatório, endereço de email 62 | * @return {boolean} Retorna verdadeiro caso o e-mail seja válido, caso contrário, retorna falso 63 | * @author Sérgio Machado 64 | */ 65 | function validarEmail(email) { 66 | var er = new RegExp(/^[A-Za-z0-9_\-\.]+@[A-Za-z0-9_\-\.]{2,}\.[A-Za-z0-9]{2,}(\.[A-Za-z0-9])?/); 67 | if (email == '' || !er.test(email)) { 68 | return false; 69 | } else { 70 | return true 71 | } 72 | } 73 | 74 | /** 75 | * Valida os campos da tabela pai e filho 76 | * @param {object} form Parâmetro obrigatório, formController 77 | * @param {String[]} erros Parâmetro obrigatório, array com os erros 78 | * @return {void} 79 | * @author Sérgio Machado 80 | */ 81 | function validarInputsTable(form, erros) { 82 | var indexes = form.getChildrenIndexes("tblDocumentos"); 83 | for (var i = 0; i < indexes.length; i++) { 84 | var documentoDesc = String(form.getValue("documentoDesc___" + indexes[i])); 85 | 86 | if(!documentoDesc){ 87 | erros.push("Informe o campo Descrição na linha " + (i+1)); 88 | }else if(descRepetida(form, indexes[i], documentoDesc)){ 89 | erros.push("Descrição duplicada na linha " + (i+1)); 90 | } 91 | 92 | if(campoVazio(form, ("fnDocumento___" + indexes[i]))){ 93 | erros.push("Informe o campo Documento na linha " + (i+1)); 94 | } 95 | } 96 | } 97 | 98 | 99 | /** 100 | * Verifica se a descrição esta repetido na tabela Pai e Filho 101 | * @param {object} form Parâmetro obrigatório, objeto formController 102 | * @param {(String|Number)} row Parâmetro obrigatório, índice da tabela pai e filho 103 | * @param {String} descricao Parâmetro obrigatório 104 | * @returns {number} Retorna o índice da tabela que tem a descrição repetida 105 | * @author Sérgio Machado 106 | */ 107 | function descRepetida(form, row, descricao) { 108 | var indexes = form.getChildrenIndexes("tblDocumentos"); 109 | for (var i = 0; i < indexes.length; i++) { 110 | var rowDesc = String(form.getValue("documentoDesc___" + indexes[i])); 111 | if ((descricao == rowDesc) && (row != indexes[i])) { 112 | return Number(indexes[i]); 113 | } 114 | } 115 | } 116 | 117 | /** 118 | * Formata os erros 119 | * @param {String[]} erros Parâmetro obrigatório, array com os erros 120 | * @returns {String} - Retorna uma string contendo todos os erros dentro de uma tag ul 121 | * @author Sérgio Machado 122 | */ 123 | function formatarErros(erros) { 124 | var strErros = ""; 125 | for (var i = 0; i < erros.length; i++) { 126 | strErros += "
  • " + erros[i] + "
  • "; 127 | } 128 | var listErros = "
    "; 129 | return "Favor informar os campos obrigatórios:

    " + listErros; 130 | } 131 | 132 | 133 | function campoVazio(form, fieldname) { 134 | if ((form.getValue(fieldname) == null) || (form.getValue(fieldname) == undefined) || (form.getValue(fieldname).trim() == "")) { 135 | return true; 136 | } 137 | return false; 138 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/custom.js: -------------------------------------------------------------------------------- 1 | var INICIO = 1; 2 | 3 | $(document).ready(function() { 4 | 5 | displayBtnFiles(); 6 | tableLineCount(); 7 | 8 | if((getMode() == "VIEW") || (getAtividade() != INICIO)){ 9 | $('.btnAddNewRow').remove(); 10 | $('.tdDeleteRow').remove(); 11 | } 12 | 13 | if(getAtividade() != INICIO){ 14 | invisibleBtnUpload("fnRegistroNascimento"); 15 | invisibleBtnUpload("fnCpf"); 16 | invisibleBtnUpload("fnFoto"); 17 | invisibleBtnUploadTable("tblDocumentos"); 18 | } 19 | 20 | initRichEditor("corpoEmail", INICIO); 21 | 22 | }) 23 | 24 | 25 | 26 | /** 27 | * Inicializa o componente Rich Editor 28 | * @param {string} inputId Parâmetro obrigatório, Id do textarea onde o componente será inicializado 29 | * @param {string|Number} atividade Parâmetro obrigatório, código da atividade em que o componente será habilitado para edição 30 | * @return {void} 31 | * @author Sérgio Machado 32 | */ 33 | function initRichEditor(inputId, atividade) { 34 | 35 | // Variável com valor true ou false, indicando se o Rich Editor será inicializado bloqueado ou não 36 | const readOnly = !((getAtividade() == atividade) && (getMode() != "VIEW")); 37 | 38 | // Configurações 39 | var settings = { 40 | removePlugins: 'fluigimage,fluigvideo', 41 | resize_enabled: false, 42 | height: "300px", 43 | readOnly 44 | }; 45 | 46 | // Inicializa o componente recebendo o id do campo e as configurações 47 | var editor = FLUIGC.richeditor(inputId, settings); 48 | 49 | // Pega a string html que esta armazenada no campo, caso tenha valor gravado 50 | var htmlString = (document.getElementById(inputId).value || document.getElementById(inputId).textContent); 51 | 52 | // Seta a string html no componente 53 | editor.setData(htmlString); 54 | 55 | // Grava a string html no campo a cada alteração de conteúdo do componente 56 | editor.on('change', function() { 57 | document.getElementById(inputId).value = editor.getData(); 58 | }); 59 | } 60 | 61 | 62 | /** 63 | * Adiciona uma nova linha na tabela pai e filho 64 | * @return {void} 65 | * @author Sérgio Machado 66 | */ 67 | function addNewRow() { 68 | try { 69 | const tablename = "tblDocumentos" 70 | const idByTimestamp = (new Date().getTime()).toString(32); 71 | const indice = wdkAddChild(tablename); 72 | $(`#fdDocumento___${indice}`).val(`anexo_${idByTimestamp}`); 73 | tableLineCount(tablename) 74 | } catch (err) { 75 | console.error("function " + arguments.callee.name + " => " + err) 76 | } 77 | } 78 | 79 | 80 | /** 81 | * Delete uma linha da tabela pai e filho e remove o anexo caso exista 82 | * @return {void} 83 | * @author Sérgio Machado 84 | */ 85 | function destroyRow(event) { 86 | try { 87 | const tabela = $(event).closest('table')[0]; 88 | const tablename = tabela.getAttribute("tablename"); 89 | const inputFileName = $(event).closest('tr').find(".inputAnexo").val(); 90 | const inputFileDesc = $(event).closest('tr').find(".descAnexo").val(); 91 | FLUIGC.message.confirm({ 92 | message: `Deseja remover o documento ${inputFileName}?`, 93 | title: 'Confirmação', 94 | labelYes: 'Sim, quero remover', 95 | labelNo: 'Não, quero cancelar', 96 | }, function(result) { 97 | if (result) { 98 | fnWdkRemoveChild(event) 99 | if(inputFileName && inputFileDesc){ 100 | removeFile(inputFileDesc) 101 | } 102 | tableLineCount(tablename) 103 | } 104 | }); 105 | } catch (e) { 106 | console.error("function " + arguments.callee.name + " => " + err) 107 | } 108 | } 109 | 110 | 111 | /** 112 | * Desabilita o botão de upload dos anexos de uma tabela pai e filho 113 | * @param {String} tablename Parâmetro obrigatório, tablename da tabela pai e filho. 114 | * @return {String} - Retorna string de erros caso apresente erros 115 | * @author Sérgio Machado 116 | */ 117 | function invisibleBtnUploadTable(tablename){ 118 | try { 119 | const countRows = $(`[tablename='${tablename}']`).find('tbody tr').not(':first'); 120 | for(let i = 0; i < countRows.length; i++){ 121 | let idInput = countRows.eq(i).find(".inputAnexo")[0].id; 122 | invisibleBtnUpload(idInput); 123 | } 124 | 125 | } catch (err) { 126 | console.error("function " + arguments.callee.name + " => " + err) 127 | } 128 | } 129 | 130 | /** 131 | * Insere a numeração correspondente a cada linha da tabela pai e filho de forma automática. 132 | * @param {String} tablename Parâmetro obrigatório, tablename da tabela pai e filho. 133 | * Quando informado um valor válido para tablename, o script irá percorre apenas as linhas da própia tabela. 134 | * Se informar o valor false para o parâmetro tablename, o script irá percorrer todas as tabelas. Recomendado apenas para o carregamento do formulário. 135 | * @return {void} 136 | * @author Sérgio Machado 137 | */ 138 | function tableLineCount(tablename) { 139 | try { 140 | let atributo = "[tablename]"; 141 | if(tablename){ 142 | atributo = `[tablename='${tablename}']` 143 | } 144 | $.each($(atributo), function(index) { 145 | const tabelaRow = $(this).find('tbody tr').not(':first'); 146 | tabelaRow.each(function(i) { 147 | tabelaRow.eq(i).find('td.count').html(`${i + 1}`); 148 | }); 149 | }); 150 | } catch (e) { 151 | console.error("function " + arguments.callee.name + " => " + err) 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/README.md: -------------------------------------------------------------------------------- 1 | # Envio de e-mail com anexos no Fluig 2 | 3 | ## Problema 4 | 5 | Em muitas situações é necessário que os envolvidos em um determinados processo, recebam determinados anexos em suas caixas de entradas. 6 | Quando o Fluig esta disponível para acesso externo, este problema pode ser facilmente resolvido enviando apenas o link público do arquivo atráves do método padrão de envios de e-mails, a função [notifier.notify](https://tdn.totvs.com/pages/releaseview.action?pageId=183730587#Personaliza%C3%A7%C3%A3odeemail-EnviodeE-mailPersonalizado). 7 | 8 | No entanto, dependendo da regra de negócio, será obrigatório que os envolvido recebam o arquivo físico em seu e-mail, e não somente o link dele. 9 | 10 | E aí nesta situação começam os problemas, pois não existe nenhuma configuração para a função notifier.notify que seja possível adicionar anexos. Com isso você deverá fazer o uso de APIs de terceiros. Ou então, como eu já fiz, desenvolver sua própria API utilizando alguma linguagem de programação onde seja possível realizar o envio de e-mail com anexos e consumir esta API dentro do Fluig. 11 | 12 | ## Solução 13 | 14 | Com este dataset será possível realizar o envio de e-mail com anexos sem depender de serviços de terceiros, abaixo vou listar alguns vantagens e desvantagens em relação a função padrão notifier.notify. 15 | 16 | ### Vantagens 17 | 18 | - É possível configurar um nome do remetente diferente para cada envio; 19 | - É possível definir um e-mail para receber a resposta do destinatário; 20 | - É possível enviar e-mails com cópias e/ou cópias ocultas; 21 | - É possível enviar e-mails com vários anexos; 22 | - É possível verificar se o e-mail foi enviado com sucesso. 23 | 24 | ### Desvantagens 25 | 26 | - Não é possível utilizar os templates de e-mails do Fluig, neste caso terá que montar o corpo do e-mail na mão. _(Mais adiante irei mostrar como resolver isso com outro dataset)_; 27 | - Obrigatório informar o e-mail e senha para autenticação. _(Neste caso poderá construir um outro dataset para obter as configurações do servidor de e-mail acessando diretamente no banco de dados do Fluig)_ 28 | - Não é possível utilizar a matrícula do usuário como destinatário, o dataset aceita apenas endereço de e-mails válidos. 29 | 30 | ## Configurações iniciais 31 | 32 | Para que você consiga realizar o envio do e-mail através deste dataset, você deverá antes e tudo, informar as configurações do seu servidor de e-mail para autenticação, como usuário, senha, host, porta, etc. 33 | 34 | Essas configurações fican logo no início da função _enviarEmail_. E caso seu servidor necessite de outras propriedades, basta procurar no google por _Java Mail Properties_, que irá encontrar vários links com toda a lista. 35 | 36 | ## Chamando o dataset 37 | 38 | Para realizar o envio do e-mail com anexos, você deverá chamar o dataset passando as contraints. Algumas são obrigatórias e outras são opcionais, confira na lista abaixo: 39 | 40 | | Constraint | Descrição | Valor Padrão | Obrigatório | 41 | | ------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------- | 42 | | nomeRemetente | Nome do remetente | "" | Sim | 43 | | assunto | Assunto do e-mail | "" | Sim | 44 | | conteudo | Corpo do e-mail escrito em HTML ou texto plano | "" | Sim | 45 | | destinatario | E-mail do destinatário principal | "" | Sim | 46 | | textoPlano | Se verdadeiro, indica que o corpo do e-mail será enviado como texto plano | false | Não | 47 | | responderPara | E-mail que será configurado como ReplyTo | Caso não informado assumirá como valor, o e-mail que foi configurado para realizar os envios | Não | 48 | | copia | Array de string com os e-mails que serão enviados como cópia | [] | Não | 49 | | copiaOculta | Array de string com os e-mails que serão enviados como cópias ocultas | [] | Não | 50 | | anexos | Array de objetos com informações dos anexos a serem enviados no e-mail | [] | Não | 51 | 52 | ### Constraint anexos 53 | 54 | A constraint anexos receberá um array de objetos, onde cada objeto deverá conter as seguintes propriedades: 55 | 56 | | Propriedade | Descrição | Formato | Obrigatório | 57 | | ----------- | ------------------------------------------------------ | ---------------- | ----------- | 58 | | id | Id do arquivo | Number ou String | Sim | 59 | | versao | Versão do arquivo | Number ou String | Sim | 60 | | nomeArquivo | Nome físico do arquivo | String | Sim | 61 | | descArquivo | Nome do arquivo com a extensão que aparecerá no e-mail | String | Não | 62 | 63 | ### Adicionando um anexo a partir de um base64 64 | 65 | Para adicionar um arquivo que esteja em base64, o objeto deverá conter as seguintes propriedades: 66 | 67 | | Propriedade | Descrição | Formato | Obrigatório | 68 | | ------------ | ------------------------------ | ------- | ----------- | 69 | | stringBase64 | Base64 do arquivo | String | Sim | 70 | | nomeArquivo | Nome do arquivo com a extensão | String | Sim | 71 | | tipo | Deve ser igual a "base64" | String | Sim | 72 | 73 | Na imagem abaixo esta um exemplo da chamada do dataset, lembrando que o array de cópia e cópia oculta, deverão ser informados nas constraints no formato string, dessa forma deverá utilizar _JSON.stringify()_. 74 | 75 | ![Exemplo](https://github.com/sergiomachadosilva/fluig-datasets/blob/master/dsEnviarEmailComAnexos/exemplo_01.png) 76 | 77 | ## Retorno em caso de sucesso 78 | 79 | Caso não ocorra nenhum erro e o e-mail seja enviado com sucesso, o dataset irá retornar seguinte coluna e valor: 80 | 81 | | STATUS | 82 | | ------ | 83 | | OK | 84 | 85 | ## Retorno em caso de erro 86 | 87 | | STATUS | 88 | | ---------------- | 89 | | Mensagem do erro | 90 | 91 | [Veja aqui o código completo do dataset](dsEnviarEmailComAnexos.js) 92 | 93 | ## Exemplos completos 94 | 95 | Veja abaixo alguns exemplos de utilizanção deste dataset, onde fiz a chamada através de outro dataset 96 | 97 | - [Chamando através de outro dataset](dsEnviarEmail.js) 98 | - [Processo com rich editor](processo-exemplo01/) 99 | - [Processo com rich editor, componente de anexos e tabela pai e filho](processo-exemplo02/) 100 | 101 | ### Créditos 102 | 103 | **Este dataset foi criado a patir de uma solução disponibilizada pela comunidade [Fluiggers](https://fluiggers.com.br/t/envio-de-e-mail-com-anexos/545).** 104 | 105 | - [Igor Rodrigues](https://www.linkedin.com/in/igorgoesrodrigues/) 106 | - [Vinicius Silveira](https://www.linkedin.com/in/igorgoesrodrigues/) 107 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/.resources/enviarEmailComAnexos.processimage.svg: -------------------------------------------------------------------------------- 1 | 2 | AprovaçãoEnviar e-mailTratar Erro 3 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/workflow/.resources/enviarEmailComAnexos.processimage.svg: -------------------------------------------------------------------------------- 1 | 2 | AprovaçãoEnviar e-mailTratar Erro 3 | -------------------------------------------------------------------------------- /gerarPdfTemplateEmail/gerarPdfTemplateEmail.js: -------------------------------------------------------------------------------- 1 | function createDataset(fields, constraints, sortFields) { 2 | 3 | var dataset = DatasetBuilder.newDataset(); 4 | 5 | try { 6 | 7 | dataset.addColumn('documentId'); 8 | 9 | var templateCodigo = "PDF_meuTemplate"; // Código do template de E-Mail que foi cadastrado no Fluig 10 | var templateArquivo = "templateTeste.html"; // Arquivo HTML do template 11 | var pastaGed = 201; // ID da pasta no GED onde será armazenado o PDF gerado 12 | var nomeArquivoGed = "Lista_de_Estados.pdf"; // Nome do arquivo que será salvo 13 | 14 | 15 | // Obtém a lista de parâmetros 16 | var parametros = getParametros(); 17 | 18 | // Passa a lista de parâmetros para a função responsável por renderizar o template de E-mail 19 | var strHtml = renderizarTemplateEmail(parametros, templateCodigo, null, templateArquivo); 20 | 21 | // Passa a string do HTML para a função criar o PDF e retornar seu base64 22 | var strBase64 = gerarPdf(strHtml); 23 | 24 | // Passa a string base64 para a função abaixo salvar no GED 25 | var documentId = salvarArquivo(strBase64, nomeArquivoGed, pastaGed); 26 | 27 | // Retorna Id do documento que foi salvo 28 | dataset.addRow([documentId]); 29 | 30 | } catch (ex) { 31 | dataset = DatasetBuilder.newDataset(); 32 | dataset.addColumn('ERRO'); 33 | dataset.addRow([("function " + arguments.callee.name + " => " + ex.toString())]); 34 | log.error(ex.toString()) 35 | } finally { 36 | return dataset; 37 | } 38 | } 39 | 40 | 41 | /** 42 | * Monta lista de parâmetros a serem renderizados no no template 43 | * @return {hashMap} 44 | * @author Sérgio Machado 45 | */ 46 | function getParametros(){ 47 | try { 48 | //Monta mapa com parâmetros do template 49 | var parametros = new java.util.HashMap(); 50 | parametros.put("logo", diretorioFluig()+"/repository/wcmdir/wcm/tenants/wcm/custom/assets/head_background.gif"); 51 | 52 | var estados = new java.util.ArrayList(); 53 | estados.add({nome: "Acre", sigla: "AC"}); 54 | estados.add({nome: "Alagoas", sigla: "AL"}); 55 | estados.add({nome: "Amapá", sigla: "AP"}); 56 | estados.add({nome: "Amazonas", sigla: "AM"}); 57 | estados.add({nome: "Bahia", sigla: "BA"}); 58 | estados.add({nome: "Ceará", sigla: "CE"}); 59 | estados.add({nome: "Distrito Federal", sigla: "DF"}); 60 | estados.add({nome: "Espírito Santo", sigla: "ES"}); 61 | estados.add({nome: "Goiás", sigla: "GO"}); 62 | estados.add({nome: "Maranhão", sigla: "MA"}); 63 | estados.add({nome: "Mato Grosso", sigla: "MT"}); 64 | estados.add({nome: "Mato Grosso do Sul", sigla: "MS"}); 65 | estados.add({nome: "Minas Gerais", sigla: "MG"}); 66 | estados.add({nome: "Pará", sigla: "PA"}); 67 | estados.add({nome: "Paraíba", sigla: "PB"}); 68 | estados.add({nome: "Paraná", sigla: "PR"}); 69 | estados.add({nome: "Pernambuco", sigla: "PE"}); 70 | estados.add({nome: "Piauí", sigla: "PI"}); 71 | estados.add({nome: "Rio de Janeiro", sigla: "RJ"}); 72 | estados.add({nome: "Rio Grande do Norte", sigla: "RN"}); 73 | estados.add({nome: "Rio Grande do Sul", sigla: "RS"}); 74 | estados.add({nome: "Rondônia", sigla: "RO"}); 75 | estados.add({nome: "Roraima", sigla: "RR"}); 76 | estados.add({nome: "Santa Catarina", sigla: "SC"}); 77 | estados.add({nome: "São Paulo", sigla: "SP"}); 78 | estados.add({nome: "Sergipe", sigla: "SE"}); 79 | estados.add({nome: "Tocantins", sigla: "TO"}); 80 | parametros.put("estados", estados); 81 | 82 | parametros.put("nome", "Sérgio"); 83 | parametros.put("sobrenome", "Machado"); 84 | 85 | return parametros; 86 | 87 | } catch (ex) { 88 | throw "function " + arguments.callee.name + " => " + ex.toString() 89 | } 90 | } 91 | 92 | 93 | /** 94 | * Processa template de E-Mail 95 | * @param {hashMap} parametros Parâmetro obrigatório, lista de parâmetros 96 | * @param {string} tplCodigo Parâmetro obrigatório, Código do template 97 | * @param {?string} tplIdioma Parâmetro opcional, Idioma do template, caso não informado o valor padrão será 'pt_BR' 98 | * @param {string} tplArquivo Parâmetro obrigatório, Nome do arquivo html do template com a extesão 99 | * @return {string} Retorna a string do HTML renserizado 100 | * @author Sérgio Machado 101 | */ 102 | function renderizarTemplateEmail(parametros, tplCodigo, tplIdioma, tplArquivo) { 103 | try { 104 | 105 | if(!tplIdioma){ 106 | tplIdioma = "pt_BR" 107 | } 108 | 109 | // Importa class da biblioteca Freemarker 110 | importClass(Packages.freemarker.template.Template); 111 | 112 | // Diretório padrão da empresa 113 | var diretorioPadrao = fluigAPI.getTenantService().getTenantData(["dirDefault"]).get("dirDefault") 114 | var templateCaminho = diretorioPadrao + "/templates/tplmail/" + tplCodigo + "/" + tplIdioma + "/" + tplArquivo; 115 | var templateHtml = new java.io.File(templateCaminho) 116 | 117 | // Ler o arquivo HTML a partir do objeto 'templateHtml'. 118 | var reader = new java.io.FileReader(templateHtml) 119 | 120 | // Objeto que representa o HTML que será preenchido com dados dinâmicos 121 | var template = new Template(null, reader) 122 | 123 | // Variável usada para capturar o resultado do processamento do modelo HTML 124 | var writer = new java.io.StringWriter(); 125 | 126 | /* Executa método process, passando o mapa parametros e o writer como parâmetros 127 | * Isso processa o modelo HTML, preenchendo-o com os valores do mapa parametros 128 | */ 129 | template.process(parametros, writer); 130 | 131 | /* O retorno será o resultado do processamento do modelo HTML 132 | * que contém uma string que representa o HTML final com todos os valores preenchidos 133 | */ 134 | return writer.toString(); 135 | 136 | } catch (ex) { 137 | throw "function " + arguments.callee.name + " => " + ex.toString() 138 | } 139 | } 140 | 141 | 142 | 143 | /** 144 | * Converte string html em um arquivo PDF usando a bibloteca itextpdf 145 | * @param {string} strHtml Parâmetro obrigatório, string do html 146 | * @return {string} Retorna base64 do pdf 147 | * @author Sérgio Machado 148 | */ 149 | function gerarPdf(strHtml) { 150 | try { 151 | // Importa as classes 152 | importClass(Packages.com.itextpdf.text.Document); 153 | importClass(Packages.com.itextpdf.text.PageSize); 154 | importClass(Packages.com.itextpdf.text.Rectangle); 155 | importClass(Packages.com.itextpdf.text.pdf.PdfWriter); 156 | importClass(Packages.com.itextpdf.tool.xml.XMLWorkerHelper); 157 | importClass(Packages.java.io.ByteArrayOutputStream); 158 | importClass(Packages.java.util.Base64); 159 | 160 | // Define as dimensões da página para o tamanho A4 161 | var pageSize = new Rectangle(PageSize.A4); 162 | 163 | // Cria um novo documento com as dimensões da página A4 e margens de 36 pontos 164 | var document = new Document(pageSize, 36, 36, 36, 36); 165 | 166 | // Cria um novo stream de saída para capturar o conteúdo do PDF 167 | var byteArrayOutputStream = new ByteArrayOutputStream(); 168 | 169 | // Cria o arquivo PDF 170 | var writer = PdfWriter.getInstance(document, byteArrayOutputStream); 171 | 172 | // Abre o documento para escrita 173 | document.open(); 174 | 175 | // Converte a string HTML em um array de bytes 176 | var is = new java.io.ByteArrayInputStream(new java.lang.String(strHtml).getBytes()); 177 | 178 | // Converter o HTML em PDF 179 | XMLWorkerHelper.getInstance().parseXHtml(writer, document, is); 180 | 181 | // Fecha o documento 182 | document.close(); 183 | 184 | // Codifica o conteúdo do PDF em base64 e o retorna como uma string 185 | var pdfAsBase64 = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()); 186 | 187 | return pdfAsBase64; 188 | 189 | } catch (ex) { 190 | throw "function " + arguments.callee.name + " => " + ex.toString() 191 | } 192 | } 193 | 194 | 195 | /** 196 | * Salva o documento no GED 197 | * @param {string} stringBase64 Parâmetro obrigatório, base64 do arquivo 198 | * @param {string} description Parâmetro obrigatório, descrição do arquivo com a extensão 199 | * @param {number} ParentDocumentId Parâmetro obrigatório, Id da pasta onde será salvo o arquivo 200 | * @return {number} Retorna o id do documento que foi criado no GED 201 | * @author Sérgio Machado 202 | */ 203 | function salvarArquivo(stringBase64, description, parentDocumentId) { 204 | try { 205 | 206 | var docDto = docAPI.newDocumentDto(); 207 | docDto.setParentDocumentId(parentDocumentId); 208 | docDto.setDocumentTypeId(""); 209 | docDto.setDocumentDescription(description); 210 | docDto.setVersion(1000); 211 | 212 | var attachArray = new java.util.ArrayList(); 213 | var attach = docAPI.newAttachment(); 214 | 215 | // Tranforma a string base64 em um byteArray 216 | var byteArray = java.util.Base64.getDecoder().decode(new String(stringBase64)); 217 | 218 | //Arquivo físico do documento 219 | attach.setFileName(description); 220 | attach.setFilecontent(byteArray); 221 | attach.setPrincipal(true); 222 | attach.setAttach(false); 223 | 224 | // Adiciona o arquivo físico ao array de anexos 225 | attachArray.add(attach); 226 | 227 | var doc = docAPI.createDocument(docDto, attachArray, null, null, null); 228 | 229 | return doc.getDocumentId() 230 | 231 | } catch (ex) { 232 | throw "function " + arguments.callee.name + " => " + ex.toString() 233 | } 234 | } 235 | 236 | 237 | /** 238 | * Retorna caminho do diretório de instalação do fluig 239 | * @return {string} 240 | * @author Sérgio Machado 241 | */ 242 | function diretorioFluig(){ 243 | try { 244 | // Retorna o caminho [PASTA DE INSTALAÇÃO]\appserver 245 | var diretorioAtual = new java.io.File(".").getCanonicalFile(); 246 | 247 | // Retrocede um nível na estrutura de pastas 248 | var diretorioAtualParent = diretorioAtual.getParentFile(); 249 | 250 | // Retorna o caminho completo da pasta onde foi instalado o Fluig 251 | return diretorioAtualParent.getAbsolutePath(); 252 | } catch (ex) { 253 | throw ex 254 | } 255 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/enviarEmailComAnexos.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 |
    18 | 19 | 20 | 23 | 24 |
    25 |
    26 |

    27 | Detalhes do email 28 |

    29 |
    30 |
    31 |
    32 |
    33 |
    34 | 35 | 36 |
    37 |
    38 |
    39 |
    40 | 41 | 42 |
    43 |
    44 |
    45 |
    46 |
    47 | 48 |
    49 |
    50 |
    51 |
    52 |
    53 |
    54 |
    55 | 56 |
    57 |
    58 | 59 | 60 |
    61 |
    62 | 65 | 68 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 | 78 |
    79 |
    80 | 81 | 82 |
    83 |
    84 | 87 | 90 | 93 |
    94 |
    95 |
    96 |
    97 |
    98 |
    99 | 100 |
    101 |
    102 | 103 | 104 |
    105 |
    106 | 109 | 112 | 115 |
    116 |
    117 |
    118 |
    119 |
    120 |
    121 |
    122 |

    Outros documentos

    123 |
    124 |
    125 |
    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 176 | 181 | 182 | 183 |
    138 |
    139 |
    140 |
    141 | 142 | 143 |
    144 |
    145 |
    146 |
    147 | 148 |
    149 |
    150 | 151 | 152 |
    153 |
    154 | 157 | 160 | 163 |
    164 |
    165 |
    166 |
    167 |
    168 |
    169 |
    170 | 171 |
    172 |
    173 |
    174 |
    175 |
    177 |
    178 | 179 |
    180 |
    184 |
    185 |
    186 |
    187 | 188 |
    189 |
    190 |
    191 |
    192 |
    193 | 194 | 195 |
    196 |
    197 |
    198 |
    199 |
    200 |
    201 |
    202 | 203 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/dsEnviarEmailComAnexos.js: -------------------------------------------------------------------------------- 1 | function createDataset(fields, constraints, sortFields) { 2 | 3 | var dataset = DatasetBuilder.newDataset(); 4 | 5 | dataset.addColumn("STATUS"); 6 | 7 | try { 8 | 9 | var nomeRemetente = String(obterParametro(constraints, "nomeRemetente")); 10 | var assunto = String(obterParametro(constraints, "assunto")); 11 | var conteudo = String(obterParametro(constraints, "conteudo")); 12 | var textoPlano = String(obterParametro(constraints, "textoPlano")) == "true"; 13 | var destinatario = String(obterParametro(constraints, "destinatario")); 14 | var responderPara = String(obterParametro(constraints, "responderPara")); 15 | var copia = obterParametro(constraints, "copia") ? JSON.parse(obterParametro(constraints, "copia")) : []; 16 | var copiaOculta = obterParametro(constraints, "copiaOculta") ? JSON.parse(obterParametro(constraints, "copiaOculta")) : []; 17 | var anexos = obterParametro(constraints, "anexos") ? JSON.parse(obterParametro(constraints, "anexos")) : []; 18 | 19 | 20 | if ((!nomeRemetente) || (nomeRemetente == "null")) { 21 | throw "Nome do remetente não informado"; 22 | } 23 | 24 | if ((!assunto) || (assunto == "null")) { 25 | throw "Assunto não informado"; 26 | } 27 | 28 | if ((!conteudo) || (conteudo == "null")) { 29 | throw "Conteúdo do corpo do e-mail não informado"; 30 | } 31 | 32 | if (!validarEmail(destinatario)) { 33 | throw "E-mail do destinatário inválido ou não informado"; 34 | } 35 | 36 | if ((responderPara) && (!validarEmail(responderPara))) { 37 | throw "E-mail de ReplyTo é inválido"; 38 | } 39 | 40 | for (var i = 0; i < copia.length; i++) { 41 | if (!validarEmail(copia[i])) { 42 | throw "O e-mail " + copia[i] + " é inválido"; 43 | } 44 | } 45 | 46 | for (var i = 0; i < copiaOculta.length; i++) { 47 | if (!validarEmail(copiaOculta[i])) { 48 | throw "O e-mail " + copiaOculta[i] + " é inválido"; 49 | } 50 | } 51 | 52 | try { 53 | 54 | enviarEmail(nomeRemetente, assunto, conteudo, textoPlano, destinatario, responderPara, copia, copiaOculta, anexos); 55 | dataset.addRow(new Array("OK")); 56 | 57 | } catch (err) { 58 | throw err.toString(); 59 | } 60 | 61 | } catch (err) { 62 | dataset.addRow(new Array("dsEnviarEmailComAnexos => function " + arguments.callee.name + " => " + err.toString())); 63 | } 64 | 65 | return dataset; 66 | } 67 | 68 | 69 | /** 70 | * Função para enviar email com Anexos 71 | * @param {string} nomeRemetente Parâmetro obrigatório, Nome do remetente 72 | * @param {string} assunto Parâmetro obrigatório, Assunto do e-mail 73 | * @param {string} conteudo Parâmetro obrigatório, Corpo do e-mail escrito em HTML ou texto plano 74 | * @param {?boolean} textoPlano Parâmetro opcional, Se verdadeiro, indica que o corpo do e-mail será enviado como texto plano 75 | * @param {string} destinatario Parâmetro obrigatório, E-mail do destinatário principal 76 | * @param {?string} responderPara Parâmetro opcional, E-mail que será configurado como ReplyTo 77 | * @param {?string[]} copia Parâmetro opcional, Array de string com os e-mails que serão enviados como cópia 78 | * @param {?string[]} copiaOculta Parâmetro opcional, Array de string com os e-mails que serão enviados como cópias ocultas 79 | * @param {?object[]} anexos Parâmetro opcional, Array de objetos com informações dos anexos a serem enviados no e-mail 80 | * @return {void} 81 | */ 82 | function enviarEmail(nomeRemetente, assunto, conteudo, textoPlano, destinatario, responderPara, copia, copiaOculta, anexos) { 83 | 84 | try { 85 | 86 | // Altere as informações abaixo de acordo com seu servidor de e-mails 87 | var emailRemetente = "E-MAIL"; 88 | var senha = "SUA_SENHA"; 89 | var servidor = "SERVIDOR_DE_EMAIL"; 90 | var porta = "PORTA"; 91 | 92 | // Indica se o formato de texto será texto ou html 93 | var formatConteudo = textoPlano ? "text/plain" : "text/html"; 94 | var replyTo = responderPara ? responderPara : emailRemetente; 95 | 96 | //Cria as propriedades necessarias para o envio de email 97 | var props = new java.util.Properties(); 98 | props.put("mail.smtp.auth", "true"); 99 | props.put("mail.smtp.host", servidor); 100 | props.put("mail.smtp.port", porta); 101 | //props.put("mail.debug", "true"); 102 | 103 | // Cria a sessao passando as propriedades 104 | var session = javax.mail.Session.getInstance(props); 105 | var message = new javax.mail.internet.MimeMessage(session); 106 | 107 | // Cria o objeto que recebe o texto do corpo do e-mail 108 | var messageBodyPart = new javax.mail.internet.MimeBodyPart(); 109 | var multipart = new javax.mail.internet.MimeMultipart("mixed"); 110 | 111 | // Objeto encarregado de enviar os dados para o email 112 | var transport = session.getTransport(); 113 | 114 | // Define o e-mail e nome do remetente 115 | message.setFrom(new javax.mail.internet.InternetAddress(emailRemetente, nomeRemetente)); 116 | message.setReplyTo(new javax.mail.internet.InternetAddress.parse(replyTo, false)); 117 | 118 | // Seta o assunto do e-mail e sua codificação 119 | message.setSubject(assunto, "UTF-8"); 120 | 121 | // Adiciona o destinatário principal 122 | message.addRecipient( 123 | javax.mail.Message.RecipientType.TO, 124 | new javax.mail.internet.InternetAddress(destinatario) 125 | ); 126 | 127 | 128 | // Seta os destinatários que receberão uma cópia do e-mail 129 | if (copia && copia.length) { 130 | for (var i in copia) { 131 | message.addRecipient( 132 | javax.mail.Message.RecipientType.CC, 133 | new javax.mail.internet.InternetAddress(copia[i]) 134 | ); 135 | } 136 | } 137 | 138 | // Seta os destinatários que receberão uma cópia oculta 139 | if (copiaOculta && copiaOculta.length) { 140 | for (var j in copiaOculta) { 141 | message.addRecipient( 142 | javax.mail.Message.RecipientType.BCC, 143 | new javax.mail.internet.InternetAddress(copiaOculta[j]) 144 | ); 145 | } 146 | } 147 | 148 | // Seta o conteúdo do corpo do e-mail e sua codificação 149 | messageBodyPart.setContent(conteudo, (formatConteudo + "; charset=utf-8")); 150 | 151 | // Adiciona os anexos que serão enviados no e-mail 152 | for (var i = 0; i < anexos.length; i++) { 153 | var anexo = anexos[i]; 154 | if (anexos[i].tipo == "base64") { 155 | adicionaAnexoBase64(multipart, anexo.stringBase64, anexo.nomeArquivo); 156 | } else { 157 | adicionaAnexo(multipart, anexo.id, anexo.versao, anexo.nomeArquivo, anexo.descArquivo); 158 | } 159 | } 160 | 161 | 162 | multipart.addBodyPart(messageBodyPart); 163 | message.setContent(multipart); 164 | 165 | try { 166 | 167 | // Método para se autenticar ao servidor 168 | transport.connect(servidor, emailRemetente, senha); 169 | 170 | // Método para enviar a mensagem criada 171 | transport.sendMessage(message, message.getAllRecipients()); 172 | 173 | } catch (err) { 174 | throw err.toString(); 175 | } 176 | finally { 177 | transport.close(); 178 | } 179 | 180 | } catch (err) { 181 | throw ("function " + arguments.callee.name + " => " + err.toString()); 182 | } 183 | } 184 | 185 | /** 186 | * Adiciona anexos no email que será disparado. Esta função ler os arquivos a partir do volume padrão do Fluig 187 | * @param {object} multipart Parâmetro obrigatório 188 | * @param {Number|string} id Parâmetro obrigatório, Id do arquivo que está no GED 189 | * @param {Number|string} versao Parâmetro obrigatório, Versão do arquivo que está no GED 190 | * @param {string} nomeArquivo Parâmetro obrigatório, Nome do arquivo com a extensão que esta armazenado no GED 191 | * @param {?string} descArquivo Parâmetro opcional, Nome do arquivo com a extensão que aparecerá no email. 192 | * Caso não informado o valor padrão será nomeArquivo 193 | * @return {void} 194 | * @author Sérgio Machado 195 | */ 196 | function adicionaAnexo(multipart, id, versao, nomeArquivo, descArquivo) { 197 | try { 198 | 199 | var dirDefault = fluigAPI.getTenantService().getTenantData(["dirDefault"]).get("dirDefault"); 200 | var arquivo = new java.io.File(dirDefault + "\\public\\" + id + "\\" + versao + "\\" + nomeArquivo); 201 | 202 | var attachment = new javax.mail.internet.MimeBodyPart(); 203 | attachment.setDataHandler(new javax.activation.DataHandler(new javax.activation.FileDataSource(arquivo))); 204 | attachment.setDisposition(javax.mail.internet.MimeBodyPart.ATTACHMENT); 205 | attachment.setFileName(descArquivo ? descArquivo : nomeArquivo); 206 | multipart.addBodyPart(attachment); 207 | 208 | } catch (err) { 209 | throw ("function " + arguments.callee.name + " => " + err.toString()); 210 | } 211 | } 212 | 213 | /** 214 | * Adiciona anexo ao email a partir de uma string base64 215 | * @param {object} multipart Parâmetro obrigatório 216 | * @param {string} stringBase64 Parâmetro obrigatório, Base64 do arquivo 217 | * @param {string} nomeArquivo Parâmetro obrigatório, Nome do arquivo com a extensão 218 | * @return {void} 219 | * @author Sérgio Machado 220 | */ 221 | function adicionaAnexoBase64(multipart, stringBase64, nomeArquivo) { 222 | try { 223 | var byteArray = java.util.Base64.getDecoder().decode(new String(stringBase64)); 224 | var attachment = new javax.mail.internet.MimeBodyPart(); 225 | attachment.setDataHandler(new javax.activation.DataHandler(new javax.mail.util.ByteArrayDataSource(byteArray, "application/octet-stream"))); 226 | attachment.setDisposition(javax.mail.internet.MimeBodyPart.ATTACHMENT); 227 | attachment.setFileName(nomeArquivo); 228 | multipart.addBodyPart(attachment); 229 | } catch (err) { 230 | throw ("function " + arguments.callee.name + " => " + err.toString()); 231 | } 232 | } 233 | 234 | 235 | /** 236 | * Verifica se um endereço de e-mail é válido 237 | * @param {string} email Parâmetro obrigatório, endereço de email 238 | * @return {boolean} Retorna verdadeiro coso o e-mail seja válido, caso contrário, retorna falso 239 | * @author Sérgio Machado 240 | */ 241 | function validarEmail(email) { 242 | var er = new RegExp(/^[A-Za-z0-9_\-\.]+@[A-Za-z0-9_\-\.]{2,}\.[A-Za-z0-9]{2,}(\.[A-Za-z0-9])?/); 243 | if (email == '' || !er.test(email)) { 244 | return false; 245 | } else { 246 | return true 247 | } 248 | } 249 | 250 | 251 | /** 252 | * Retorna o valor initialValue de uma determinada constraint 253 | * @param {object} constraints Parâmetro obrigatório, constraints recebidas no dataset 254 | * @param {string} campo Parâmetro obrigatório, constraint que deseja obter o valor 255 | * @return {string} 256 | */ 257 | function obterParametro(constraints, campo) { 258 | var valor = ""; 259 | if ((constraints != null) && (constraints.length > 0)) { 260 | for (i in constraints) { 261 | var constraint = constraints[i] 262 | if (constraint.getFieldName().trim().toUpperCase() == campo.trim().toUpperCase()) { 263 | valor = constraint.getInitialValue(); 264 | break; 265 | } 266 | } 267 | } 268 | return valor; 269 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/forms/12 - Enviar e-mail com anexos/anexos.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Toda a lógica para o correto funcionamento desse componente foi feito em cima das classes abaixo: 3 | * .componentAnexo, .descAnexo, .inputAnexo, .btnUpFile, .btnViewerFile, .btnDownloadFile e o atributo data-acao 4 | * Sem elas o código não irá funcionar, então se por acaso você quiser alterar os nomes dessas classes 5 | * lembre-se de alterar nas funções desse arquivo e também no css 6 | */ 7 | 8 | /** 9 | * Direciona para cada função correspondente ao valor que esta no atributo data-acao do botão 10 | * @param {object} event Parâmetro obrigatório, o própio elemento que sofreu o evento click 11 | * @return {void} 12 | * @author Sérgio Machado 13 | */ 14 | function anexo(event){ 15 | try{ 16 | const acao = event.currentTarget.getAttribute("data-acao"); 17 | const inputFile = $(event.currentTarget).parent().parent().find(".inputAnexo")[0] 18 | const fileDescription = $(event.currentTarget).parent().parent().find(".descAnexo").val() 19 | if(acao == "upload"){ 20 | uploadFile(fileDescription, inputFile.id) 21 | } 22 | if(acao == "viewer"){ 23 | viewerFile(fileDescription) 24 | } 25 | if(acao == "download"){ 26 | downloadFile(fileDescription, inputFile.id) 27 | } 28 | if(acao == "delete"){ 29 | removeFileConfirm(fileDescription, inputFile.id) 30 | } 31 | }catch(e){ 32 | console.error("Houve um erro inesperado na função anexo") 33 | console.error(e) 34 | } 35 | } 36 | 37 | 38 | /** 39 | * Envia arquivos para a aba Anexos do Fluig 40 | * Função adaptada por Sérgio Machado 41 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que ficará na aba anexos do Fluig 42 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 43 | * @return {void} 44 | */ 45 | function uploadFile(fileDescription, idInput) { 46 | try{ 47 | var tabAttachments = parent.document.getElementById("tab-attachments"); 48 | if (tabAttachments) { 49 | //Verifica se o navegador é o Ie9 para realizar o devido tratamento 50 | if (parent.WCMAPI.isIe9()) { 51 | $(".ecm-navigation-silverlight", parent.document).show("fade").css("top", 0); 52 | $("#ecm-navigation-silverlight", parent.document).attr({ 53 | "data-on-camera": "true", "data-file-name-camera": fileDescription, "data-inputNameFile": idInput 54 | }); 55 | $(parent.document).on("keyup", this.actionKeyup) 56 | } else { 57 | var element = parent.document.getElementById("ecm-navigation-inputFile-clone"); 58 | if (element && document.createEvent) { 59 | element.setAttribute("data-on-camera", "true"); 60 | if (fileDescription && idInput) { 61 | element.setAttribute("data-file-name-camera", fileDescription) 62 | element.setAttribute("data-inputNameFile", idInput) 63 | } 64 | //Realiza o click no botão "Carregar arquivos" que tem na aba de anexos 65 | element.click(); 66 | } 67 | } 68 | } 69 | }catch(e){ 70 | console.error("Houve um erro inesperado na função uploadFile") 71 | console.error(e) 72 | } 73 | } 74 | 75 | 76 | 77 | /** 78 | * Função executada após a escolha do arquivo a ser enviado para o Fluig. 79 | * Verifica se o anexo já existe, seta o valor do arquivo fisico no campo e altera o estado dos botões 80 | * @return {void} 81 | */ 82 | $(function(){ 83 | try{ 84 | window.parent.$("#ecm-navigation-inputFile-clone").on('change', function(e) { 85 | const inputNameFile = this.getAttribute("data-inputNameFile"); 86 | const fileDescription = this.getAttribute("data-file-name-camera"); 87 | const filePhisical = this.files[0].name; 88 | if(fileDescription && fileDescription){ 89 | /** 90 | * O trecho de código abaixo percorre os anexos do Fluig e caso já exista um anexo com a mesma descrição, ele será removido. 91 | * Em seguida limpa o campo onde é armazenado o nome fisico do arquivo 92 | */ 93 | $.each(parent.ECM.attachmentTable.getData(), function(i, attachment) { 94 | var descricao = attachment.description; 95 | if (fileDescription == descricao) { 96 | parent.WKFViewAttachment.removeAttach([i]); 97 | setFilePhisicalName(inputNameFile, ""); 98 | } 99 | }); 100 | setFilePhisicalName(inputNameFile, filePhisical) 101 | if(getMode() == "ADD"){ 102 | btnState(inputNameFile, 'delete', 'download'); 103 | } 104 | if(getMode() == "MOD"){ 105 | btnState(inputNameFile, 'delete', 'viewer'); 106 | } 107 | } 108 | }); 109 | }catch(e){ 110 | console.error("Houve um erro inesperado ao selecionar o arquivo") 111 | console.error(e) 112 | } 113 | }); 114 | 115 | 116 | /** 117 | * Visualizar arquivos que esta na aba Anexos do Fluig 118 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do anexo 119 | * @return {void} 120 | */ 121 | function viewerFile(fileDescription) { 122 | try{ 123 | if(hasFileFluig(fileDescription)){ 124 | const anexos = parent.ECM.attachmentTable.getData(); 125 | for(let i = 0; i < anexos.length; i++){ 126 | var descricao = anexos[i].description; 127 | if (fileDescription == descricao) { 128 | parent.WKFViewAttachment.openAttachmentView('adm', anexos[i].documentId); 129 | return 130 | } 131 | } 132 | }else{ 133 | FLUIGC.toast({ 134 | title: "Atenção", 135 | message: "Anexo não encontrado", 136 | type: "warning" 137 | }); 138 | } 139 | }catch(e){ 140 | console.error("Houve um erro inesperado na função viewerFile") 141 | console.error(e) 142 | } 143 | } 144 | 145 | 146 | /** 147 | * Realiza o download do arquivo que esta na aba Anexos do Fluig 148 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 149 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig 150 | * @return {void} 151 | */ 152 | function downloadFile(fileDescription, idInput) { 153 | try{ 154 | const filename = getMode() == "VIEW" ? $(`#${idInput}`).text() : $(`#${idInput}`).val() 155 | FLUIGC.message.confirm({ 156 | message: `Deseja baixar o anexo ${filename}?`, 157 | title: 'Confirmação', 158 | labelYes: 'Sim, quero baixar', 159 | labelNo: 'Não, quero cancelar', 160 | }, function(result) { 161 | if (result) { 162 | $.each(parent.ECM.attachmentTable.getData(), function(i, attachment) { 163 | var descricao = attachment.description; 164 | if (fileDescription == descricao) { 165 | parent.WKFViewAttachment.downloadAttach([i]); 166 | } 167 | }); 168 | } 169 | }); 170 | }catch(e){ 171 | console.error("Houve um erro inesperado na função downloadFile") 172 | console.error(e) 173 | } 174 | } 175 | 176 | /** 177 | * Confirmação para Remove arquivo que esta na aba Anexos do Fluig 178 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 179 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig 180 | * @return {void} 181 | * @author Sérgio Machado 182 | */ 183 | function removeFileConfirm(fileDescription, idInput) { 184 | try{ 185 | const filename = $(`#${idInput}`).val() 186 | FLUIGC.message.confirm({ 187 | message: `Deseja remover o anexo ${filename}?`, 188 | title: 'Confirmação', 189 | labelYes: 'Sim, quero remover', 190 | labelNo: 'Não, quero cancelar', 191 | }, function(result) { 192 | if (result) { 193 | removeFile(fileDescription) 194 | setFilePhisicalName(idInput, "") 195 | btnState(idInput, "upload", "download") 196 | } 197 | }); 198 | }catch(e){ 199 | console.error("Houve um erro inesperado na função removeFileConfirm") 200 | console.error(e) 201 | } 202 | } 203 | 204 | /** 205 | * Remove arquivo que esta na aba Anexos do Fluig 206 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig 207 | * @return {void} 208 | * @author Sérgio Machado 209 | */ 210 | function removeFile(fileDescription) { 211 | try{ 212 | $.each(parent.ECM.attachmentTable.getData(), function(i, attachment) { 213 | if (attachment.description == fileDescription) { 214 | parent.WKFViewAttachment.removeAttach([i]); 215 | } 216 | }); 217 | }catch(e){ 218 | console.error("Houve um erro inesperado na função removeFile") 219 | console.error(e) 220 | } 221 | } 222 | 223 | 224 | /** 225 | * Seta o nome do arquivo fisico no campo e realiza tratativa caso o campo esteja bloqueado pelo enableFields 226 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 227 | * @param {String} filePhisical Parâmetro obrigatório, nome do arquivo fisico 228 | * @return {void} 229 | * @author Sérgio Machado 230 | */ 231 | function setFilePhisicalName(idInput, filePhisical){ 232 | try{ 233 | if(idInput.indexOf("_") == 0){ 234 | $("#" + idInput.substring(1)).val(filePhisical); 235 | } 236 | $("#" + idInput).val(filePhisical); 237 | }catch(e){ 238 | console.error("Houve um erro inesperado na função setFilePhisicalName") 239 | console.error(e) 240 | } 241 | } 242 | 243 | 244 | /** 245 | * Altera o estado e visibilidade dos botões de anexos 246 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 247 | * @param {String} acao Parâmetro obrigatório, ação para ser executada no momento do click, se é delete ou upload 248 | * @param {String} btn Parâmetro obrigatório, botão secundário que deve sofrer ação de ficar visível ou não. Botão de Download ou Viewer 249 | * @return {void} 250 | * @author Sérgio Machado 251 | */ 252 | function btnState(idInput, acao, btn){ 253 | try{ 254 | let btnUpFile = $(`#${idInput}`).parent().parent().find(".btnUpFile"); 255 | let btnDownloadFile = $(`#${idInput}`).parent().parent().find(".btnDownloadFile"); 256 | let btnViewerFile = $(`#${idInput}`).parent().parent().find(".btnViewerFile"); 257 | if(acao == "delete"){ 258 | btnUpFile.removeClass("btn-success").addClass("btn-danger"); 259 | btnUpFile.attr({'data-acao': acao, 'title': 'Excluir'}); 260 | btnUpFile.find("i").removeClass("fluigicon-file-upload").addClass("fluigicon-trash"); 261 | if(btn == "download"){ 262 | btnDownloadFile.prop("disabled", false); 263 | btnDownloadFile.show() 264 | } 265 | if(btn == "viewer"){ 266 | btnViewerFile.prop("disabled", false); 267 | btnViewerFile.show() 268 | } 269 | } 270 | if(acao == "upload"){ 271 | btnUpFile.removeClass("btn-danger").addClass("btn-success"); 272 | btnUpFile.attr({'data-acao': acao, 'title': 'Selecionar'}); 273 | btnUpFile.find("i").removeClass("fluigicon-trash").addClass("fluigicon-file-upload"); 274 | btnDownloadFile.prop("disabled", true); 275 | btnDownloadFile.hide() 276 | btnViewerFile.prop("disabled", true); 277 | btnViewerFile.hide() 278 | } 279 | }catch(e){ 280 | console.error("Houve um erro inesperado na função btnState") 281 | console.error(e) 282 | } 283 | } 284 | 285 | 286 | /** 287 | * Faz tratativa nos botões do anexos percorrente cada class .componentAnexo 288 | * Em modo de visualização o botão de upload é removido, e caso tenha anexo, habilita o botão de visualização do anexo 289 | * Se em modo de edição e conter anexo o botão de upload é alterado para o botão de deletar anexos e habilita o botão de visualização 290 | * @return {void} 291 | * @author Sérgio Machado 292 | */ 293 | function displayBtnFiles(){ 294 | try{ 295 | $('.componentAnexo').each(function(i, element) { 296 | let inputFile = $(element).find(".inputAnexo") 297 | let btnUpFile = $(element).find(".btnUpFile"); 298 | let btnViewerFile = $(element).find(".btnViewerFile"); 299 | if(getMode() == "VIEW"){ 300 | btnUpFile.remove(); 301 | if(inputFile.val() != ""){ 302 | btnViewerFile.prop("disabled", false); 303 | btnViewerFile.show() 304 | } 305 | } 306 | if(getMode() == "MOD" && inputFile.val() != ""){ 307 | btnState(inputFile[0].id, "delete", "viewer") 308 | } 309 | }); 310 | }catch(e){ 311 | console.error("Houve um erro inesperado na função displayBtnFiles") 312 | console.error(e) 313 | } 314 | } 315 | 316 | 317 | /** 318 | * Remove o botão de upload/delete 319 | * @param {String} inputFile Parâmetro obrigatório, Id do campo 320 | * @return {void} 321 | * @author Sérgio Machado 322 | */ 323 | function invisibleBtnUpload(inputFile){ 324 | try{ 325 | if(getMode() == "MOD" || getMode() == "ADD"){ 326 | if($(`#_${inputFile}`).length){ 327 | let btnUpFile = $(`#_${inputFile}`).parent().parent().find(".btnUpFile"); 328 | btnUpFile.remove(); 329 | } else{ 330 | let btnUpFile = $(`#${inputFile}`).parent().parent().find(".btnUpFile"); 331 | btnUpFile.remove(); 332 | } 333 | } 334 | if($(`#_${inputFile}`).length){ 335 | if($(`#_${inputFile}`).val() == ""){ 336 | $(`#_${inputFile}`).attr({placeholder:"Nenhum anexo selecionado"}); 337 | } 338 | } else{ 339 | if($(`#${inputFile}`).val() == ""){ 340 | $(`#${inputFile}`).attr({placeholder:"Nenhum anexo selecionado"}); 341 | } 342 | } 343 | }catch(e){ 344 | console.error("Houve um erro inesperado na função invisibleBtnUpload") 345 | console.error(e) 346 | } 347 | } 348 | 349 | 350 | /** 351 | * Verifica se os campos do anexo de uma tabela pai e filho esta preenchido, 352 | * caso esteja, ele verifica se o anexo esta presente na aba de anexos do Fluig 353 | * @param {String} tablename Parâmetro obrigatório, tablename da tabela pai e filho. 354 | * @param {String} idInput Parâmetro obrigatório, Id do campo de anexo que deseja verificar 355 | * @return {String} - Retorna string de erros caso apresente erros 356 | * @author Sérgio Machado 357 | */ 358 | function invalidFilesTable(tablename, idInput){ 359 | try { 360 | let errors = ""; 361 | const countRows = $(`[tablename='${tablename}']`).find('tbody tr').not(':first'); 362 | for(let i = 0; i < countRows.length; i++){ 363 | let indice = getIndice(countRows.eq(i).find("input")[0].id); 364 | let inputNameFile = $(`#_${idInput}___${indice}`).length ? $(`#_${idInput}___${indice}`) : $(`#${idInput}___${indice}`) 365 | let fileDescription = inputNameFile.parent().find(".descAnexo").val() 366 | if(inputNameFile.val() && !hasFileFluig(fileDescription)){ 367 | errors += `
  • O anexo ${inputNameFile.val()} da linha ${i+1} não foi encontrado
  • ` 368 | } 369 | } 370 | return errors 371 | } catch (e) { 372 | console.error('Houve um erro inesperado na função invalidFileTable') 373 | console.error(e) 374 | } 375 | } 376 | 377 | /** 378 | * Verifica se o campo do anexo esta preenchido, caso esteja, ele verifica se o anexo esta válido 379 | * @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado 380 | * @return {Boolean} 381 | * @author Sérgio Machado 382 | */ 383 | function invalidFile(idInput){ 384 | try { 385 | const inputNameFile = $(`#${idInput}`).val() 386 | if(inputNameFile){ 387 | if($(`#_${idInput}`).length){ 388 | let fileDescription = $(`#_${idInput}`).parent().find(".descAnexo").val() 389 | return !hasFileFluig(fileDescription) 390 | } else{ 391 | let fileDescription = $(`#${idInput}`).parent().find(".descAnexo").val() 392 | return !hasFileFluig(fileDescription) 393 | } 394 | }else{ 395 | return false 396 | } 397 | } catch (e) { 398 | console.error('Houve um erro inesperado na função invalidFile') 399 | console.error(e) 400 | } 401 | } 402 | 403 | 404 | /** 405 | * Verifica se o anexo existe na aba de anexos do Fluig 406 | * @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo 407 | * @return {Boolean} - Retorna verdadeiro caso o arquivo exista 408 | * @author Sérgio Machado 409 | */ 410 | function hasFileFluig(fileDescription){ 411 | try { 412 | const anexos = parent.ECM.attachmentTable.getData(); 413 | for(let i = 0; i < anexos.length; i++){ 414 | var descricao = anexos[i].description; 415 | if (fileDescription == descricao) { 416 | return true 417 | } 418 | } 419 | return false 420 | } catch (e) { 421 | console.error('Houve um erro inesperado na função hasFileFluig') 422 | console.error(e) 423 | } 424 | } -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo01/workflow/.resources/enviarEmailComAnexos.ecm30.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | enviarEmailComAnexos 6 | 7 | Enviar e-mail com anexos 8 | 9 | true 10 | false 11 | Default 12 | Serviço de Email 13 | 14 | 0 15 | 0 16 | 0 17 | Default 18 | true 19 | 20 | 1 21 | true 22 | false 23 | 0 24 | 0 25 | true 26 | 27 | 28 | 29 | 1 30 | Enviar e-mail com anexos 31 | 16 32 | 33 | 34 | 3532 35 | true 36 | false 37 | false 38 | true 39 | false 40 | false 41 | 0 42 | 2 43 | 44 | false 45 | false 46 | false 47 | 48 | 49 | 50 | 51 | 1 52 | enviarEmailComAnexos 53 | 1 54 | 1 55 | 56 | Início 57 | Início 58 | 59 | 0 60 | false 61 | 0 62 | 63 | 64 | 1 65 | true 66 | true 67 | false 68 | 3600 69 | 3600 70 | 0 71 | 0 72 | false 73 | 74 | 0 75 | false 76 | false 77 | false 78 | 130 79 | 120 80 | 0 81 | 0 82 | false 83 | false 84 | 0 85 | 0 86 | false 87 | 88 | 0 89 | 10 90 | 0 91 | false 92 | 0 93 | 0 94 | 0 95 | 0 96 | 97 | false 98 | 99 | 100 | 101 | 1 102 | enviarEmailComAnexos 103 | 1 104 | 2 105 | 106 | Aprovação 107 | Aprovação 108 | 109 | 0 110 | 111 | false 112 | 0 113 | Usuário 114 | <AssignmentController><User>sergio.machado</User></AssignmentController> 115 | 1 116 | false 117 | true 118 | false 119 | 3600 120 | 3600 121 | 0 122 | 0 123 | false 124 | 125 | 0 126 | true 127 | false 128 | false 129 | 260 130 | 107 131 | 0 132 | 0 133 | false 134 | false 135 | 0 136 | 0 137 | false 138 | 139 | 0 140 | 80 141 | 0 142 | false 143 | 0 144 | 0 145 | 0 146 | 0 147 | 148 | false 149 | 0 150 | 151 | 152 | 153 | 1 154 | enviarEmailComAnexos 155 | 1 156 | 4 157 | 158 | Enviar e-mail 159 | Enviar e-mail 160 | 161 | 0 162 | 163 | false 164 | 0 165 | 1 166 | false 167 | true 168 | false 169 | 3600 170 | 3600 171 | 0 172 | 0 173 | false 174 | 175 | 0 176 | true 177 | false 178 | false 179 | 460 180 | 107 181 | 0 182 | 0 183 | false 184 | false 185 | 0 186 | 0 187 | false 188 | 189 | 0 190 | 82 191 | 0 192 | false 193 | 0 194 | 0 195 | 0 196 | 0 197 | 198 | false 199 | 1 200 | 201 | 202 | 203 | 1 204 | enviarEmailComAnexos 205 | 1 206 | 10 207 | 208 | Tratar Erro 209 | Tratar Erro 210 | 211 | 0 212 | 213 | false 214 | 0 215 | Usuário 216 | <AssignmentController><User>sergio.machado</User></AssignmentController> 217 | 1 218 | false 219 | true 220 | false 221 | 3600 222 | 3600 223 | 0 224 | 0 225 | false 226 | 227 | 0 228 | true 229 | false 230 | false 231 | 460 232 | 300 233 | 0 234 | 0 235 | false 236 | false 237 | 0 238 | 0 239 | false 240 | 241 | 0 242 | 80 243 | 0 244 | false 245 | 0 246 | 0 247 | 0 248 | 0 249 | 250 | false 251 | 0 252 | 253 | 254 | 255 | 1 256 | enviarEmailComAnexos 257 | 1 258 | 9 259 | 260 | Intermediário 261 | Intermediário 262 | Evento intermediário do processo 263 | 0 264 | false 265 | 0 266 | 267 | 268 | 0 269 | false 270 | true 271 | false 272 | 1 273 | 1 274 | 0 275 | 0 276 | false 277 | 278 | 0 279 | true 280 | false 281 | false 282 | 560 283 | 157 284 | 0 285 | 0 286 | false 287 | false 288 | 0 289 | false 290 | 291 | 0 292 | 43 293 | 0 294 | false 295 | 0 296 | 297 | false 298 | 4 299 | 300 | 301 | 302 | 1 303 | enviarEmailComAnexos 304 | 1 305 | 8 306 | 307 | Fim 308 | Fim 309 | Esta atividade indica que o processo terminado e que não ocorrerá nenhum tipo de pós processamento. 310 | 0 311 | false 312 | 0 313 | 314 | 315 | 0 316 | false 317 | false 318 | false 319 | 0 320 | 1 321 | 0 322 | 0 323 | false 324 | 325 | 0 326 | false 327 | false 328 | false 329 | 680 330 | 120 331 | 0 332 | 0 333 | false 334 | false 335 | 0 336 | 0 337 | false 338 | 339 | 0 340 | 68 341 | 0 342 | false 343 | 0 344 | 345 | false 346 | 347 | 348 | 349 | 350 | 351 | 352 | 1 353 | enviarEmailComAnexos 354 | 1 355 | 3 356 | 357 | 358 | false 359 | 1 360 | 2 361 | 362 | 363 | false 364 | false 365 | 0 366 | 367 | 368 | 369 | 1 370 | enviarEmailComAnexos 371 | 1 372 | 5 373 | 374 | 375 | false 376 | 2 377 | 4 378 | 379 | 380 | false 381 | false 382 | 0 383 | 384 | 385 | 386 | 1 387 | enviarEmailComAnexos 388 | 1 389 | 7 390 | 391 | 392 | false 393 | 4 394 | 8 395 | 396 | 397 | false 398 | false 399 | 0 400 | 401 | 402 | 403 | 1 404 | enviarEmailComAnexos 405 | 1 406 | 11 407 | 408 | 409 | false 410 | 9 411 | 10 412 | 413 | 414 | false 415 | false 416 | 0 417 | 418 | 419 | 420 | 1 421 | enviarEmailComAnexos 422 | 1 423 | 12 424 | 425 | 426 | false 427 | 10 428 | 4 429 | 430 | 431 | false 432 | false 433 | 0 434 | 435 | 436 | 437 | 438 | 439 | 440 | 1 441 | servicetask4 442 | enviarEmailComAnexos 443 | 1 444 | 445 | function servicetask4(attempt, message) { 446 | 447 | try { 448 | 449 | var constraints = []; 450 | var anexos = []; 451 | var destinatario = hAPI.getCardValue("emailDestinatario"); 452 | var assunto = hAPI.getCardValue("assuntoEmail"); 453 | var conteudo = hAPI.getCardValue("corpoEmail"); 454 | 455 | // Lista com os anexos presentes na solicitação 456 | var docs = hAPI.listAttachments(); 457 | 458 | for (var i = 0; i < docs.size(); i++) { 459 | var doc = docs.get(i); 460 | anexos.push({ id: Number(doc.getDocumentId()), versao: Number(doc.getVersion()), nomeArquivo: String(doc.getPhisicalFile())}); 461 | } 462 | 463 | constraints.push(DatasetFactory.createConstraint("nomeRemetente", "Empresa XPTO", null, ConstraintType.MUST)); 464 | constraints.push(DatasetFactory.createConstraint("destinatario", destinatario, null, ConstraintType.MUST)); 465 | constraints.push(DatasetFactory.createConstraint("assunto", assunto, null, ConstraintType.MUST)); 466 | constraints.push(DatasetFactory.createConstraint("conteudo", conteudo, null, ConstraintType.MUST)); 467 | constraints.push(DatasetFactory.createConstraint("anexos", JSON.stringify(anexos), null, ConstraintType.MUST)); 468 | 469 | var dataset = DatasetFactory.getDataset("dsEnviarEmailComAnexos", null, constraints, null); 470 | 471 | var retorno = dataset.getValue(0, "STATUS"); 472 | 473 | if(retorno != "OK"){ 474 | throw retorno; 475 | } 476 | 477 | 478 | } catch (err) { 479 | throw ("function " + arguments.callee.name + " => " + err.toString()); 480 | } 481 | 482 | } 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 1 496 | enviarEmailComAnexos 497 | 1 498 | 4 499 | 0 500 | Integração executada com sucesso 501 | 502 | 1 503 | 0 504 | 505 | 506 | 507 | 508 | 509 | 510 | -------------------------------------------------------------------------------- /dsEnviarEmailComAnexos/processo-exemplo02/workflow/.resources/enviarEmailComAnexos.ecm30.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | enviarEmailComAnexos 6 | 7 | Enviar e-mail com anexos 8 | 9 | true 10 | false 11 | Default 12 | Meus 13 | Papel 14 | <AssignmentController><Role>admin</Role></AssignmentController> 15 | 0 16 | 0 17 | 0 18 | Default 19 | true 20 | 21 | 1 22 | true 23 | false 24 | 0 25 | 0 26 | true 27 | 28 | 29 | 30 | 1 31 | Enviar e-mail com anexos 32 | 32 33 | 34 | 35 | 12 36 | true 37 | false 38 | false 39 | true 40 | false 41 | false 42 | 0 43 | 2 44 | 45 | false 46 | false 47 | false 48 | 49 | 50 | 51 | 52 | 1 53 | enviarEmailComAnexos 54 | 1 55 | 1 56 | 57 | Início 58 | Início 59 | 60 | 0 61 | false 62 | 0 63 | 64 | 65 | 1 66 | true 67 | true 68 | false 69 | 3600 70 | 3600 71 | 0 72 | 0 73 | false 74 | 75 | 0 76 | false 77 | false 78 | false 79 | 130 80 | 120 81 | 0 82 | 0 83 | false 84 | false 85 | 0 86 | 0 87 | false 88 | 89 | 0 90 | 10 91 | 0 92 | false 93 | 0 94 | 0 95 | 0 96 | 0 97 | 98 | false 99 | 100 | 101 | 102 | 1 103 | enviarEmailComAnexos 104 | 1 105 | 2 106 | 107 | Aprovação 108 | Aprovação 109 | 110 | 0 111 | 112 | false 113 | 0 114 | Usuário 115 | <AssignmentController><User>sergio.machado</User></AssignmentController> 116 | 1 117 | false 118 | true 119 | false 120 | 3600 121 | 3600 122 | 0 123 | 0 124 | false 125 | 126 | 0 127 | true 128 | false 129 | false 130 | 260 131 | 107 132 | 0 133 | 0 134 | false 135 | false 136 | 0 137 | 0 138 | false 139 | 140 | 0 141 | 80 142 | 0 143 | false 144 | 0 145 | 0 146 | 0 147 | 0 148 | 149 | false 150 | 0 151 | 152 | 153 | 154 | 1 155 | enviarEmailComAnexos 156 | 1 157 | 4 158 | 159 | Enviar e-mail 160 | Enviar e-mail 161 | 162 | 0 163 | 164 | false 165 | 0 166 | 1 167 | false 168 | true 169 | false 170 | 3600 171 | 3600 172 | 0 173 | 0 174 | false 175 | 176 | 0 177 | true 178 | false 179 | false 180 | 460 181 | 107 182 | 0 183 | 0 184 | false 185 | false 186 | 0 187 | 0 188 | false 189 | 190 | 0 191 | 82 192 | 0 193 | false 194 | 0 195 | 0 196 | 0 197 | 0 198 | 199 | false 200 | 1 201 | 202 | 203 | 204 | 1 205 | enviarEmailComAnexos 206 | 1 207 | 10 208 | 209 | Tratar Erro 210 | Tratar Erro 211 | 212 | 0 213 | 214 | false 215 | 0 216 | Usuário 217 | <AssignmentController><User>sergio.machado</User></AssignmentController> 218 | 1 219 | false 220 | true 221 | false 222 | 3600 223 | 3600 224 | 0 225 | 0 226 | false 227 | 228 | 0 229 | true 230 | false 231 | false 232 | 460 233 | 300 234 | 0 235 | 0 236 | false 237 | false 238 | 0 239 | 0 240 | false 241 | 242 | 0 243 | 80 244 | 0 245 | false 246 | 0 247 | 0 248 | 0 249 | 0 250 | 251 | false 252 | 0 253 | 254 | 255 | 256 | 1 257 | enviarEmailComAnexos 258 | 1 259 | 9 260 | 261 | Intermediário 262 | Intermediário 263 | Evento intermediário do processo 264 | 0 265 | false 266 | 0 267 | 268 | 269 | 0 270 | false 271 | true 272 | false 273 | 1 274 | 1 275 | 0 276 | 0 277 | false 278 | 279 | 0 280 | true 281 | false 282 | false 283 | 560 284 | 157 285 | 0 286 | 0 287 | false 288 | false 289 | 0 290 | false 291 | 292 | 0 293 | 43 294 | 0 295 | false 296 | 0 297 | 298 | false 299 | 4 300 | 301 | 302 | 303 | 1 304 | enviarEmailComAnexos 305 | 1 306 | 8 307 | 308 | Fim 309 | Fim 310 | Esta atividade indica que o processo terminado e que não ocorrerá nenhum tipo de pós processamento. 311 | 0 312 | false 313 | 0 314 | 315 | 316 | 0 317 | false 318 | false 319 | false 320 | 0 321 | 1 322 | 0 323 | 0 324 | false 325 | 326 | 0 327 | false 328 | false 329 | false 330 | 680 331 | 120 332 | 0 333 | 0 334 | false 335 | false 336 | 0 337 | 0 338 | false 339 | 340 | 0 341 | 68 342 | 0 343 | false 344 | 0 345 | 346 | false 347 | 348 | 349 | 350 | 351 | 352 | 353 | 1 354 | enviarEmailComAnexos 355 | 1 356 | 3 357 | 358 | 359 | false 360 | 1 361 | 2 362 | 363 | 364 | false 365 | false 366 | 0 367 | 368 | 369 | 370 | 1 371 | enviarEmailComAnexos 372 | 1 373 | 5 374 | 375 | 376 | false 377 | 2 378 | 4 379 | 380 | 381 | false 382 | false 383 | 0 384 | 385 | 386 | 387 | 1 388 | enviarEmailComAnexos 389 | 1 390 | 7 391 | 392 | 393 | false 394 | 4 395 | 8 396 | 397 | 398 | false 399 | false 400 | 0 401 | 402 | 403 | 404 | 1 405 | enviarEmailComAnexos 406 | 1 407 | 11 408 | 409 | 410 | false 411 | 9 412 | 10 413 | 414 | 415 | false 416 | false 417 | 0 418 | 419 | 420 | 421 | 1 422 | enviarEmailComAnexos 423 | 1 424 | 12 425 | 426 | 427 | false 428 | 10 429 | 4 430 | 431 | 432 | false 433 | false 434 | 0 435 | 436 | 437 | 438 | 439 | 440 | 441 | 1 442 | atividades 443 | enviarEmailComAnexos 444 | 1 445 | 446 | var INICIO = 1; 447 | var APROVACAO_2 = 2; 448 | var ENVIAR_EMAIL_4 = 4; 449 | var TRATAR_ERRO_10 = 10; 450 | var FINALIZADO_8 = 8; 451 | 452 | 453 | 454 | 1 455 | funcoes 456 | enviarEmailComAnexos 457 | 1 458 | 459 | /** 460 | * Retorna as propriedades de um documento 461 | * @param {string} fileDescription Parâmetro obrigatório, descrição do documento 462 | * @return {boolean|object} Caso o documento exista, retorna um objeto com as propriedades {id, versao, nomeArquivo}, 463 | caso não exista, retorna falso 464 | * @author Sérgio Machado 465 | */ 466 | function documentoDto(fileDescription) { 467 | var docs = hAPI.listAttachments(); 468 | for (var i = 0; i < docs.size(); i++) { 469 | var doc = docs.get(i); 470 | if (fileDescription == doc.getDocumentDescription()) { 471 | return { id: String(doc.getDocumentId()), versao: String(doc.getVersion()), nomeArquivo: String(doc.getPhisicalFile())}; 472 | } 473 | } 474 | return false; 475 | } 476 | 477 | 478 | /** 479 | * Retorna a extensão de um arquivo 480 | * @param {string} phisicalFile Parâmetro obrigatório, nome físico do arquivo 481 | * @return {string} 482 | * @author Sérgio Machado 483 | */ 484 | function obterExtensao(phisicalFile){ 485 | var extensao = "." + phisicalFile.split(".").pop(); 486 | return extensao; 487 | } 488 | 489 | 490 | /** 491 | * Verifica se existe todos os documentos inseridos na tabela pai e filho na aba de anexos 492 | * @param {string[]} erros Parâmetro obrigatório, array com os erros 493 | * @return {void} 494 | * @author Sérgio Machado 495 | */ 496 | function documentosTabelaExiste(erros) { 497 | var indexes = hAPI.getChildrenIndexes("tblDocumentos"); 498 | for (var i = 0; i < indexes.length; i++) { 499 | var fileName = String(hAPI.getCardValue("fnDocumento___" + indexes[i])); 500 | var fileDescription = String(hAPI.getCardValue("fdDocumento___" + indexes[i])); 501 | 502 | if (fileName) { 503 | if (!documentoDto(fileDescription)) { 504 | erros.push("Não foi encontrado o anexo <b>" + fileName + "</b> da linha " + (i+1)); 505 | } 506 | } 507 | } 508 | } 509 | 510 | 511 | 512 | 513 | 1 514 | beforeStateEntry 515 | enviarEmailComAnexos 516 | 1 517 | 518 | function beforeStateEntry(sequenceId) { 519 | 520 | try { 521 | var erros = []; 522 | 523 | if (sequenceId == APROVACAO_2) { 524 | 525 | var anexoRegNascFile = String(hAPI.getCardValue("fnRegistroNascimento")); 526 | var anexoRegNascDesc = String(hAPI.getCardValue("fdRegistroNascimento")); 527 | 528 | var anexoCpfFile = String(hAPI.getCardValue("fnCpf")); 529 | var anexoCpfDesc = String(hAPI.getCardValue("fdCpf")); 530 | 531 | var anexoFotoFile = String(hAPI.getCardValue("fnFoto")); 532 | var anexoFotoDesc = String(hAPI.getCardValue("fdFoto")); 533 | 534 | if (anexoRegNascFile) { 535 | if (!documentoDto(anexoRegNascDesc)) { 536 | erros.push("Não foi encontrado o anexo <b>" + anexoRegNascFile + "</b>"); 537 | } 538 | } 539 | 540 | if (anexoCpfFile) { 541 | if (!documentoDto(anexoCpfDesc)) { 542 | erros.push("Não foi encontrado o anexo <b>" + anexoCpfFile + "</b>"); 543 | } 544 | } 545 | 546 | if (anexoFotoFile) { 547 | if (!documentoDto(anexoFotoDesc)) { 548 | erros.push("Não foi encontrado o anexo <b>" + anexoFotoFile + "</b>"); 549 | } 550 | } 551 | 552 | // Valida os documentos inseridos na tabela pai e filho se eles existem na aba de anexos 553 | documentosTabelaExiste(erros); 554 | } 555 | 556 | // Se existir alguma mensagem no array de erros, lança uma exceção 557 | if (erros.length) { 558 | throw formatarErros(erros); 559 | } 560 | 561 | } catch (err) { 562 | throw ("<br/> function <b>" + arguments.callee.name + "</b> => " + err.toString()); 563 | } 564 | } 565 | 566 | /** 567 | * Formata os erros 568 | * @param {String[]} erros Parâmetro obrigatório, array com os erros 569 | * @returns {String} - Retorna uma string contendo todos os erros dentro de uma tag ul 570 | * @author Sérgio Machado 571 | */ 572 | function formatarErros(erros) { 573 | var strErros = ''; 574 | for (var i = 0; i < erros.length; i++) { 575 | strErros += '<li style="margin-bottom: 10px;">' + erros[i] + '</li>'; 576 | } 577 | var listErros = '<ul style="padding-left: 17px;color: red;list-style: disc;">' + strErros + '</ul><br/>'; 578 | return 'Favor informar os anexos obrigatórios:<br/><br/>' + listErros; 579 | } 580 | 581 | 582 | 583 | 1 584 | servicetask4 585 | enviarEmailComAnexos 586 | 1 587 | 588 | function servicetask4(attempt, message) { 589 | 590 | try { 591 | 592 | var constraints = []; 593 | var anexos = []; 594 | var destinatario = hAPI.getCardValue("emailDestinatario"); 595 | var assunto = hAPI.getCardValue("assuntoEmail"); 596 | var conteudo = hAPI.getCardValue("corpoEmail"); 597 | var textoPlano = hAPI.getCardValue("formatEmail") == "on" ? true : false; 598 | 599 | 600 | 601 | // Adiciona anexo Registro de nascimento 602 | var anexoRegNascFile = String(hAPI.getCardValue("fnRegistroNascimento")); 603 | var anexoRegNascDesc = String(hAPI.getCardValue("fdRegistroNascimento")); 604 | 605 | // Verifica se o campo esta preenchido 606 | if (anexoRegNascFile) { 607 | var objetoAnexo = documentoDto(anexoRegNascDesc) 608 | // Verifica se o documento existe 609 | if (objetoAnexo) { 610 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 611 | objetoAnexo.descArquivo = "Registro de Nascimento" + obterExtensao(objetoAnexo.nomeArquivo); 612 | anexos.push(objetoAnexo) 613 | } 614 | } 615 | 616 | 617 | // Adiciona anexo CPF 618 | var anexoCpfFile = String(hAPI.getCardValue("fnCpf")); 619 | var anexoCpfDesc = String(hAPI.getCardValue("fdCpf")); 620 | 621 | // Verifica se o campo esta preenchido 622 | if (anexoCpfFile) { 623 | var objetoAnexo = documentoDto(anexoCpfDesc) 624 | // Verifica se o documento existe 625 | if (objetoAnexo) { 626 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 627 | objetoAnexo.descArquivo = "CPF" + obterExtensao(objetoAnexo.nomeArquivo); 628 | anexos.push(objetoAnexo) 629 | } 630 | } 631 | 632 | 633 | // Adiciona anexo Foto 634 | var anexoFotoFile = String(hAPI.getCardValue("fnFoto")); 635 | var anexoFotoDesc = String(hAPI.getCardValue("fdFoto")); 636 | 637 | // Verifica se o campo esta preenchido 638 | if (anexoFotoFile) { 639 | var objetoAnexo = documentoDto(anexoFotoDesc) 640 | // Verifica se o documento existe 641 | if (objetoAnexo) { 642 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 643 | objetoAnexo.descArquivo = "Foto" + obterExtensao(objetoAnexo.nomeArquivo); 644 | anexos.push(objetoAnexo) 645 | } 646 | } 647 | 648 | 649 | // Percorre a tabela pai e filho 650 | var indexes = hAPI.getChildrenIndexes("tblDocumentos"); 651 | 652 | for (var i = 0; i < indexes.length; i++) { 653 | var enviarEmailArquivo = String(hAPI.getCardValue("documentoEmail___" + indexes[i])); 654 | var anexoDesc = String(hAPI.getCardValue("fdDocumento___" + indexes[i])); 655 | var descricao = String(hAPI.getCardValue("documentoDesc___" + indexes[i])); 656 | 657 | // Verifica se o campo checkbox da tabela pai e filho esta marcado 658 | if(enviarEmailArquivo){ 659 | var objetoAnexo = documentoDto(anexoDesc) 660 | // Verifica se o documento existe 661 | if (objetoAnexo) { 662 | // Se existir, adiciona a propriedade descArquivo e adiciona o objeto no array de anexos 663 | objetoAnexo.descArquivo = (descricao + obterExtensao(objetoAnexo.nomeArquivo)); 664 | anexos.push(objetoAnexo) 665 | } 666 | } 667 | } 668 | 669 | 670 | constraints.push(DatasetFactory.createConstraint("nomeRemetente", "Empresa XPTO", null, ConstraintType.MUST)); 671 | constraints.push(DatasetFactory.createConstraint("destinatario", destinatario, null, ConstraintType.MUST)); 672 | constraints.push(DatasetFactory.createConstraint("assunto", assunto, null, ConstraintType.MUST)); 673 | constraints.push(DatasetFactory.createConstraint("conteudo", conteudo, null, ConstraintType.MUST)); 674 | constraints.push(DatasetFactory.createConstraint("textoPlano", textoPlano, null, ConstraintType.MUST)); 675 | constraints.push(DatasetFactory.createConstraint("anexos", JSON.stringify(anexos), null, ConstraintType.MUST)); 676 | 677 | var dataset = DatasetFactory.getDataset("dsEnviarEmailComAnexos", null, constraints, null); 678 | 679 | var retorno = dataset.getValue(0, "STATUS"); 680 | 681 | if(retorno != "OK"){ 682 | throw retorno; 683 | } 684 | 685 | } catch (err) { 686 | throw ("function " + arguments.callee.name + " => " + err.toString()); 687 | } 688 | } 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 1 704 | enviarEmailComAnexos 705 | 1 706 | 4 707 | 0 708 | Integração executada com sucesso 709 | 710 | 1 711 | 0 712 | 713 | 714 | 715 | 716 | 717 | 718 | --------------------------------------------------------------------------------